@@ -393,6 +393,147 @@ const list<CompatibilityTestCase> compatibilityTestCases = [
393393 inputs = ["{\"floatAsKey\": {\"16777216\": 1}}"],
394394 output = json5_test.Example{floatAsKey = {16777216.0: 1}},
395395 },
396+ CompatibilityTestCase{
397+ name = "IntegerNegativeZero",
398+ inputs = [
399+ "{\"i64Value\": -0}",
400+ "{\"i64Value\": \"-0\"}",
401+ "{\"i64Value\": -0x0}",
402+ ],
403+ output = json5_test.Example{i64Value = 0},
404+ },
405+ CompatibilityTestCase{
406+ name = "CommentAfterValue",
407+ inputs = [
408+ "{\"i64Value\": 1} // note",
409+ "{\"i64Value\": 1} /* note */",
410+ ],
411+ output = json5_test.Example{i64Value = 1},
412+ },
413+ // A null member is skipped before its name or id is checked.
414+ CompatibilityTestCase{
415+ name = "NullMembersAreNotResolved",
416+ inputs = ["{\"boolValue (31)\": null, \"NonExist (30)\": null}"],
417+ output = json5_test.Example{},
418+ },
419+ // Field id -32768 stands for "no id".
420+ CompatibilityTestCase{
421+ name = "FieldIdInt16MinMeansNoId",
422+ inputs = ["{\"boolValue (-32768)\": true}"],
423+ output = json5_test.Example{boolValue = true},
424+ },
425+ CompatibilityTestCase{
426+ name = "UnionWithOnlyUnknownField",
427+ inputs = ["{\"unionValue\": {\"unknown\": 1}}"],
428+ output = json5_test.Example{unionValue = json5_test.ExampleUnion{}},
429+ },
430+ CompatibilityTestCase{
431+ name = "SetDuplicateElements",
432+ inputs = [
433+ "{\"i32SetValue\": [2, 1, 2], \"setValue\": [{\"nested\": \"b\"}, {\"nested\": \"a\"}, {\"nested\": \"b\"}]}",
434+ ],
435+ output = json5_test.Example{
436+ i32SetValue = [1, 2],
437+ setValue = [json5_test.Nested{nested = "a"}, json5_test.Nested{nested = "b"}],
438+ },
439+ },
440+ CompatibilityTestCase{
441+ name = "MapDuplicateKeyLastWins",
442+ inputs = [
443+ "{\"i32AsKey\": [{\"key\": 1, \"value\": 2}, {\"key\": 1, \"value\": 3}]}",
444+ "{\"i32AsKey\": {\"1\": 2, \"0x1\": 3}}",
445+ ],
446+ output = json5_test.Example{i32AsKey = {1: 3}},
447+ },
448+ CompatibilityTestCase{
449+ name = "StructKeyDuplicateLastWins",
450+ inputs = [
451+ "{\"structAsKey\": [{\"key\": {\"nested\": \"k\"}, \"value\": {\"nested\": \"v\"}}, {\"key\": {\"nested\": \"k\"}, \"value\": {\"nested\": \"w\"}}]}",
452+ ],
453+ output = json5_test.Example{
454+ structAsKey = {json5_test.Nested{nested = "k"}: json5_test.Nested{nested = "w"}},
455+ },
456+ },
457+ CompatibilityTestCase{
458+ name = "SetAsKeyDuplicateElements",
459+ inputs = ["{\"setAsKey\": [{\"key\": [2, 1, 2], \"value\": 3}]}"],
460+ output = json5_test.Example{setAsKey = {[1, 2]: 3}},
461+ },
462+ CompatibilityTestCase{
463+ name = "FloatAsKeyFromString",
464+ inputs = [
465+ "{\"floatAsKey\": [{\"key\": 0.5, \"value\": 1}, {\"key\": \"16777216\", \"value\": 2}]}",
466+ ],
467+ output = json5_test.Example{floatAsKey = {0.5: 1, 16777216.0: 2}},
468+ },
469+ // Bare base64 strings: padding is optional, and nonzero trailing bits ("QR")
470+ // are ignored.
471+ CompatibilityTestCase{
472+ name = "BinaryBareBase64OneByte",
473+ inputs = [
474+ "{\"binaryValue\": \"QQ\"}",
475+ "{\"binaryValue\": \"QQ==\"}",
476+ "{\"binaryValue\": \"QR\"}",
477+ ],
478+ output = json5_test.Example{binaryValue = "A"},
479+ },
480+ CompatibilityTestCase{
481+ name = "BinaryBareBase64TwoBytes",
482+ inputs = ["{\"binaryValue\": \"QUI\"}", "{\"binaryValue\": \"QUI=\"}"],
483+ output = json5_test.Example{binaryValue = "AB"},
484+ },
485+ CompatibilityTestCase{
486+ name = "BinaryBareBase64ThreeBytes",
487+ inputs = ["{\"binaryValue\": \"QUJD\"}"],
488+ output = json5_test.Example{binaryValue = "ABC"},
489+ },
490+ CompatibilityTestCase{
491+ name = "BinaryBareBase64Empty",
492+ inputs = ["{\"binaryValue\": \"\"}"],
493+ output = json5_test.Example{binaryValue = ""},
494+ },
495+ // 1 + 2^-24 is exactly halfway between two binary32 values.
496+ CompatibilityTestCase{
497+ name = "FloatBinary32MidpointTiesToEven",
498+ inputs = ["{\"floatValue\": 1.000000059604644775390625}"],
499+ output = json5_test.Example{floatValue = 1.0},
500+ },
501+ // Above a binary32 midpoint whose exact decimal has 83 significant digits,
502+ // but below it rounded to 41 digits.
503+ CompatibilityTestCase{
504+ name = "FloatJustAboveLongBinary32Midpoint",
505+ inputs = ["{\"floatValue\": 7.03853100000000022281692450609677778769437e-26}"],
506+ output = json5_test.Example{
507+ floatValue = 0.0000000000000000000000000703853130814879132477466099505324860128273323223169199991389177739620208740234375,
508+ },
509+ },
510+ CompatibilityTestCase{
511+ name = "FloatJustBelowMidpointAfterFltMax",
512+ inputs = ["{\"floatValue\": 340282356779733661637539395458142568447.999999}"],
513+ output = json5_test.Example{
514+ floatValue = 340282346638528859811704183484516925440.0,
515+ },
516+ },
517+ CompatibilityTestCase{
518+ name = "FloatJustAboveHalfSmallestSubnormal",
519+ inputs = ["{\"floatValue\": 7.00649232162408535461864791644958065640130970938257885878534141944895541342930300743319094181060791015625000001e-46}"],
520+ output = json5_test.Example{
521+ floatValue = 0.000000000000000000000000000000000000000000001401298464324817070923729583289916131280261941876515771757068283889791082685860601486638188362121582031250,
522+ },
523+ },
524+ // Exactly halfway between the largest subnormal and DBL_MIN.
525+ CompatibilityTestCase{
526+ name = "DoubleSubnormalMidpointTiesToEven",
527+ inputs = ["{\"doubleValue\": 2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508791414915891303962110687008643869459464552765720740782062174337998814106326732925355228688137214901298112245145188984905722230728525513315575501591439747639798341180199932396254828901710708185069063066665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505108060994073026293712895895000358379996720725430436028407889577179615094551674824347103070260914462157228988025818254518032570701886087211312807951223342628836862232150377566662250398253433597456888442390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042756718644338377048603786162277173854562306587467901408672332763671875e-308}"],
528+ output = json5_test.Example{doubleValue = 2.2250738585072014e-308},
529+ },
530+ CompatibilityTestCase{
531+ name = "DoubleJustBelowSubnormalMidpoint",
532+ inputs = [
533+ "{\"doubleValue\": 2.225073858507201136057409796709131975934819546351645648e-308}",
534+ ],
535+ output = json5_test.Example{doubleValue = 2.225073858507201e-308},
536+ },
396537];
397538
398539// Values that thrift constants cannot express: NaN, the infinities and
@@ -553,6 +694,53 @@ const list<RoundTripTestCase> roundTripTestCases = [
553694 value: 2,
554695 },
555696 ],
697+ }",
698+ },
699+ RoundTripTestCase{
700+ name = "SignsOfZeroAndNaNInDoubleList",
701+ inputs = [
702+ "{\"doubleListValue\": [-0.0, -NaN, 0.0, NaN]}",
703+ "{\"doubleListValue\": [-0, \"-NaN\", 0, \"NaN\"]}",
704+ "{doubleListValue: [\"-0x0\", -NaN, \"0.0\", +NaN]}",
705+ ],
706+ json = "{
707+ \"doubleListValue\": [
708+ -0.0,
709+ \"-NaN\",
710+ 0.0,
711+ \"NaN\"
712+ ]
713+ }",
714+ json5 = "{
715+ doubleListValue: [
716+ -0.0,
717+ -NaN,
718+ 0.0,
719+ NaN,
720+ ],
721+ }",
722+ },
723+ RoundTripTestCase{
724+ name = "FloatNegativeNaN",
725+ inputs = ["{\"floatValue\": -NaN}", "{\"floatValue\": \"-NaN\"}"],
726+ json = "{
727+ \"floatValue\": \"-NaN\"
728+ }",
729+ json5 = "{
730+ floatValue: -NaN,
731+ }",
732+ },
733+ RoundTripTestCase{
734+ name = "FloatOverflowsToInfinity",
735+ inputs = [
736+ "{\"floatValue\": 1e39}",
737+ "{\"floatValue\": 340282356779733661637539395458142568448.000001}",
738+ ],
739+ json = "{
740+ \"floatValue\": \"Infinity\"
741+ }",
742+ json5 = "{
743+ floatValue: Infinity,
556744}",
557745 },
558746];
0 commit comments