Skip to content

Commit 808577a

Browse files
ydahbyroot
authored andcommitted
Sort RFC 8785 object properties by their keys
1 parent 193df55 commit 808577a

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

‎lib/json/ext.rb‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def shareable_lambda(block) # :nodoc:
9595
})
9696

9797
generator::State.rfc8785_sort_keys_proc = shareable_lambda(->(hash) {
98-
hash.sort_by { |k| k.to_s.encode(Encoding::UTF_16) }.to_h
98+
hash.sort_by { |k,| k.to_s.encode(Encoding::UTF_16) }.to_h
9999
})
100100

101101
JSON.generator = generator

‎test/json/json_generator_test.rb‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,36 @@ def test_large_depth_raises
12531253
end
12541254
end
12551255

1256+
def test_rfc8785_key_order
1257+
assert_rfc8785 '{"a":1,"a b":2}', { 'a' => 1, 'a b' => 2 }
1258+
assert_rfc8785 '{"a":2,"a!":1}', { 'a!' => 1, 'a' => 2 }
1259+
assert_rfc8785 '{"\n":1,"A":2}', { "\n" => 1, 'A' => 2 }
1260+
assert_rfc8785 '[{"a":1,"a b":2}]', [{ 'a b' => 2, 'a' => 1 }]
1261+
end
1262+
1263+
def test_rfc8785_mixed_key_order
1264+
assert_rfc8785 '{"10":2,"9":1}', { '9' => 1, 10 => 2 }
1265+
assert_rfc8785 '{"a":1,"b":2}', { a: 1, 'b' => 2 }
1266+
end
1267+
1268+
def test_rfc8785_key_order_with_default_external_encoding
1269+
# https://www.rfc-editor.org/rfc/rfc8785.html#section-3.2.3
1270+
hash = { "\u20ac" => 1, "\r" => 2, "\ufb33" => 3, '1' => 4,
1271+
"\u{1f600}" => 5, "\u0080" => 6, "\u00f6" => 7 }
1272+
expected = "{\"\\r\":2,\"1\":4,\"\u0080\":6,\"\u00f6\":7,\"\u20ac\":1,\"\u{1f600}\":5,\"\ufb33\":3}"
1273+
verbose = $VERBOSE
1274+
previous_encoding = Encoding.default_external
1275+
$VERBOSE = nil
1276+
outputs = [Encoding::UTF_8, Encoding::US_ASCII].map do |encoding|
1277+
Encoding.default_external = encoding
1278+
JSON.generate(hash, rfc8785: true)
1279+
end
1280+
assert_equal [expected, expected], outputs
1281+
ensure
1282+
Encoding.default_external = previous_encoding
1283+
$VERBOSE = verbose
1284+
end
1285+
12561286
def test_rfc8785_numbers
12571287
assert_rfc8785 '-9007199254740992', -9007199254740992
12581288
assert_rfc8785 '0', 0

0 commit comments

Comments
 (0)