abandoning branch for now, work is in intermediate state

This commit is contained in:
alisdair sullivan 2010-08-10 11:04:14 -07:00
parent bff9a38d39
commit 1617c878f5
46 changed files with 2040 additions and 97 deletions

View file

@ -11,7 +11,8 @@
jsx_utf32le, jsx_utf32le,
jsx_eep0018, jsx_eep0018,
jsx_format, jsx_format,
jsx_verify jsx_verify,
jsx_test
]}, ]},
{registered, []}, {registered, []},
{applications, [ {applications, [

View file

@ -38,7 +38,7 @@ to_abf(Backend) ->
end, end,
Name = to_modname(Backend), Name = to_modname(Backend),
{ok, _, ABF} = compile:file( {ok, _, ABF} = compile:file(
"priv/jsx_decoder.erl", "priv/jsx_decoder_template.erl",
[binary, 'P', {outdir, Out}, {d, list_to_atom(Backend)}, {d, name, Name}] [binary, 'P', {outdir, Out}, {d, list_to_atom(Backend)}, {d, name, Name}]
), ),
{Name, ABF}. {Name, ABF}.

View file

@ -35,6 +35,7 @@
-include("./include/jsx_types.hrl"). -include("./include/jsx_types.hrl").
-spec parse(JSON::json(), Opts::jsx_opts()) -> jsx_parser_result(). -spec parse(JSON::json(), Opts::jsx_opts()) -> jsx_parser_result().
parse(JSON, Opts) -> parse(JSON, Opts) ->

View file

@ -1,5 +1,4 @@
%% edit `path` value to change target directory for tests {eunit_compile_opts, [{d, test}]}.
{eunit_compile_opts, [{d, test}, {d, path, "./test/cases/"}]}.
%% uncomment to get verbose output from test suite %% uncomment to get verbose output from test suite
%% {eunit_opts, [verbose]}. {eunit_opts, [verbose]}.

View file

@ -31,10 +31,6 @@
-export([is_json/1, is_json/2]). -export([is_json/1, is_json/2]).
-export([format/1, format/2]). -export([format/1, format/2]).
%% if testing is enabled, export load_tests/1 so all modules may use it
-ifdef(test).
-export([load_tests/1]).
-endif.
%% types for function specifications %% types for function specifications
-include("./include/jsx_types.hrl"). -include("./include/jsx_types.hrl").
@ -218,10 +214,17 @@ detect_encoding(Bin, Opts) ->
end end
}. }.
%% eunit tests %% eunit tests
-ifdef(test). -ifdef(test).
jsx_decoder_test_() ->
lists:map(fun(Encoding) ->
decoder_tests(load_tests("./test/cases"), Encoding, [])
end,
[utf8, utf16, {utf16, little}, utf32, {utf32, little}]
).
load_tests(Path) -> load_tests(Path) ->
%% search the specified directory for any files with the .test ending %% search the specified directory for any files with the .test ending
TestSpecs = filelib:wildcard("*.test", Path), TestSpecs = filelib:wildcard("*.test", Path),
@ -234,7 +237,8 @@ load_tests([Test|Rest], Dir, Acc) ->
case file:consult(Dir ++ "/" ++ Test) of case file:consult(Dir ++ "/" ++ Test) of
{ok, TestSpec} -> {ok, TestSpec} ->
try try
load_tests(Rest, Dir, [parse_test(TestSpec, [])] ++ Acc) ParsedTest = parse_tests(TestSpec, Dir),
load_tests(Rest, Dir, [ParsedTest] ++ Acc)
catch _:_ -> catch _:_ ->
load_tests(Rest, Dir, Acc) load_tests(Rest, Dir, Acc)
end end
@ -243,17 +247,59 @@ load_tests([Test|Rest], Dir, Acc) ->
end. end.
%% if the json, eep0018 or jsx values are lists, assume they're a path to a file that should parse_tests(TestSpec, Dir) ->
%% be read with file:read_file/1 parse_tests(TestSpec, Dir, []).
parse_test([{Key, Path}|Rest], Test) when is_list(Path) ->
case lists:member(Key, [json, eep0018, jsx]) of parse_tests([{json, Path}|Rest], Dir, Acc) when is_list(Path) ->
true -> case file:read_file(Dir ++ "/" ++ Path) of
case file:read_file(Path) of {ok, Bin} -> parse_tests(Rest, Dir, [{json, Bin}] ++ Acc)
{ok, Bin} -> parse_test(Rest, [{Key, Bin}] ++ Test) ; _ -> erlang:error(badarg)
; {error, Reason} -> {error, Reason} end;
end parse_tests([KV|Rest], Dir, Acc) ->
; false -> parse_tests(Rest, Dir, [KV] ++ Acc);
parse_test(Rest, [{Key, Path}] ++ Test) parse_tests([], _Dir, Acc) ->
end. Acc.
decoder_tests([Test|Rest], Encoding, Acc) ->
Name = lists:flatten(proplists:get_value(name, Test) ++ "::" ++ io_lib:format("~p", [Encoding])),
JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding),
JSX = proplists:get_value(jsx, Test),
Flags = proplists:get_value(jsx_flags, Test, []),
decoder_tests(Rest,
Encoding,
[{"incremental " ++ Name, ?_assert(incremental_decode(JSON, Flags) =:= JSX)}]
++ [{Name, ?_assert(decode(JSON, Flags) =:= JSX)}]
++ Acc
);
decoder_tests([], _Encoding, Acc) ->
io:format("~p~n", [Acc]),
Acc.
decode(JSON, Flags) ->
P = jsx:parser(Flags),
decode_loop(P(JSON), []).
decode_loop({event, end_json, _Next}, Acc) ->
lists:reverse([end_json] ++ Acc);
decode_loop({incomplete, More}, Acc) ->
decode_loop(More(end_stream), Acc);
decode_loop({event, E, Next}, Acc) ->
decode_loop(Next(), [E] ++ Acc).
incremental_decode(<<C:1/binary, Rest/binary>>, Flags) ->
P = jsx:parser(Flags),
incremental_decode_loop(P(C), Rest, []).
incremental_decode_loop({incomplete, Next}, <<>>, Acc) ->
incremental_decode_loop(Next(end_stream), <<>>, Acc);
incremental_decode_loop({incomplete, Next}, <<C:1/binary, Rest/binary>>, Acc) ->
incremental_decode_loop(Next(C), Rest, Acc);
incremental_decode_loop({event, end_json, _Next}, _Rest, Acc) ->
lists:reverse([end_json] ++ Acc);
incremental_decode_loop({event, Event, Next}, Rest, Acc) ->
incremental_decode_loop(Next(), Rest, [Event] ++ Acc).
-endif. -endif.

View file

@ -404,13 +404,13 @@ key_repeats(_Key, []) -> false.
%% eunit tests %% eunit tests
-ifdef(test). -ifdef(test).
jsx_escape_test_() -> escape_test_() ->
[ [
{"json string escaping", ?_assert(json_escape(<<"\"\\\b\f\n\r\t">>) =:= <<"\\\"\\\\\\b\\f\\n\\r\\t">>)}, {"json string escaping", ?_assert(json_escape(<<"\"\\\b\f\n\r\t">>) =:= <<"\\\"\\\\\\b\\f\\n\\r\\t">>)},
{"json string hex escape", ?_assert(json_escape(<<1, 2, 3, 11, 26, 30, 31>>) =:= <<"\\u0001\\u0002\\u0003\\u000b\\u001a\\u001e\\u001f">>)} {"json string hex escape", ?_assert(json_escape(<<1, 2, 3, 11, 26, 30, 31>>) =:= <<"\\u0001\\u0002\\u0003\\u000b\\u001a\\u001e\\u001f">>)}
]. ].
jsx_nice_decimal_test_() -> nice_decimal_test_() ->
[ [
{"0.0", ?_assert(float_to_decimal(0.0) =:= "0.0")}, {"0.0", ?_assert(float_to_decimal(0.0) =:= "0.0")},
{"1.0", ?_assert(float_to_decimal(1.0) =:= "1.0")}, {"1.0", ?_assert(float_to_decimal(1.0) =:= "1.0")},
@ -428,7 +428,7 @@ jsx_nice_decimal_test_() ->
{"max denormalized float", ?_assert(float_to_decimal((1 - math:pow(2, -52)) * math:pow(2, -1022)) =:= "2.225073858507201e-308")} {"max denormalized float", ?_assert(float_to_decimal((1 - math:pow(2, -52)) * math:pow(2, -1022)) =:= "2.225073858507201e-308")}
]. ].
jsx_key_repeats_test_() -> key_repeats_test_() ->
[ [
{"encoded key repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"key">>}, {key, <<"trailing key">>}]) =:= true)}, {"encoded key repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"key">>}, {key, <<"trailing key">>}]) =:= true)},
{"encoded key no repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"trailing key">>}]) =:= false)}, {"encoded key no repeat", ?_assert(key_repeats([{key, <<"key">>}], [{key, <<>>}, {key, <<"notkey">>}, {key, <<"trailing key">>}]) =:= false)},

140
src/jsx_test.erl Normal file
View file

@ -0,0 +1,140 @@
%% The MIT License
%% Copyright (c) 2010 Alisdair Sullivan <alisdairsullivan@yahoo.ca>
%% Permission is hereby granted, free of charge, to any person obtaining a copy
%% of this software and associated documentation files (the "Software"), to deal
%% in the Software without restriction, including without limitation the rights
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%% copies of the Software, and to permit persons to whom the Software is
%% furnished to do so, subject to the following conditions:
%% The above copyright notice and this permission notice shall be included in
%% all copies or substantial portions of the Software.
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
%% THE SOFTWARE.
-module(jsx_test).
-author("alisdairsullivan@yahoo.ca").
-export([test/0]).
-ifdef(test).
-include_lib("eunit/include/eunit.hrl").
-endif.
%% if not compiled with test support
-ifndef(test).
test() -> erlang:error(notest).
-else.
jsx_decoder_test_() ->
jsx_decoder_gen(load_tests("./test/cases"), [utf8, utf16, {utf16, little}, utf32, {utf32, little}]).
jsx_decoder_gen([Test|Rest], []) ->
jsx_decoder_gen(Rest, [utf8, utf16, {utf16, little}, utf32, {utf32, little}]);
jsx_decoder_gen([], _) ->
[];
jsx_decoder_gen([Test|Rest] = Tests, [Encoding|Encodings]) ->
Name = lists:flatten(proplists:get_value(name, Test) ++ " :: " ++ io_lib:format("~p", [Encoding])),
JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding),
JSX = proplists:get_value(jsx, Test),
Flags = proplists:get_value(jsx_flags, Test, []),
{generator,
fun() ->
[{Name, ?_assert(decode(JSON, Flags) =:= JSX)} | jsx_decoder_gen(Tests, Encodings)]
end
}.
load_tests(Path) ->
%% search the specified directory for any files with the .test ending
TestSpecs = filelib:wildcard("*.test", Path),
load_tests(TestSpecs, Path, []).
load_tests([], _Dir, Acc) ->
lists:reverse(Acc);
load_tests([Test|Rest], Dir, Acc) ->
%% should alert about badly formed tests eventually, but for now just skip over them
case file:consult(Dir ++ "/" ++ Test) of
{ok, TestSpec} ->
try
ParsedTest = parse_tests(TestSpec, Dir),
load_tests(Rest, Dir, [ParsedTest] ++ Acc)
catch _:_ ->
load_tests(Rest, Dir, Acc)
end
; {error, _Reason} ->
load_tests(Rest, Dir, Acc)
end.
parse_tests(TestSpec, Dir) ->
parse_tests(TestSpec, Dir, []).
parse_tests([{json, Path}|Rest], Dir, Acc) when is_list(Path) ->
case file:read_file(Dir ++ "/" ++ Path) of
{ok, Bin} -> parse_tests(Rest, Dir, [{json, Bin}] ++ Acc)
; _ -> erlang:error(badarg)
end;
parse_tests([KV|Rest], Dir, Acc) ->
parse_tests(Rest, Dir, [KV] ++ Acc);
parse_tests([], _Dir, Acc) ->
Acc.
decoder_tests([Test|Rest], Encoding, Acc) ->
Name = lists:flatten(proplists:get_value(name, Test) ++ "::" ++ io_lib:format("~p", [Encoding])),
JSON = unicode:characters_to_binary(proplists:get_value(json, Test), unicode, Encoding),
JSX = proplists:get_value(jsx, Test),
Flags = proplists:get_value(jsx_flags, Test, []),
decoder_tests(Rest,
Encoding,
[{"incremental " ++ Name, ?_assert(incremental_decode(JSON, Flags) =:= JSX)}]
++ [{Name, ?_assert(decode(JSON, Flags) =:= JSX)}]
++ Acc
);
decoder_tests([], _Encoding, Acc) ->
io:format("~p~n", [Acc]),
Acc.
decode(JSON, Flags) ->
P = jsx:parser(Flags),
decode_loop(P(JSON), []).
decode_loop({event, end_json, _Next}, Acc) ->
lists:reverse([end_json] ++ Acc);
decode_loop({incomplete, More}, Acc) ->
decode_loop(More(end_stream), Acc);
decode_loop({event, E, Next}, Acc) ->
decode_loop(Next(), [E] ++ Acc).
incremental_decode(<<C:1/binary, Rest/binary>>, Flags) ->
P = jsx:parser(Flags),
incremental_decode_loop(P(C), Rest, []).
incremental_decode_loop({incomplete, Next}, <<>>, Acc) ->
incremental_decode_loop(Next(end_stream), <<>>, Acc);
incremental_decode_loop({incomplete, Next}, <<C:1/binary, Rest/binary>>, Acc) ->
incremental_decode_loop(Next(C), Rest, Acc);
incremental_decode_loop({event, end_json, _Next}, _Rest, Acc) ->
lists:reverse([end_json] ++ Acc);
incremental_decode_loop({event, Event, Next}, Rest, Acc) ->
incremental_decode_loop(Next(), Rest, [Event] ++ Acc).
-endif.

View file

@ -1,4 +1,4 @@
-file("priv/jsx_decoder.erl", 1). -file("priv/jsx_decoder_template.erl", 1).
-module(jsx_utf16). -module(jsx_utf16).
@ -8,7 +8,7 @@
-file("./include/jsx_decoder.hrl", 1). -file("./include/jsx_decoder.hrl", 1).
-file("priv/jsx_decoder.erl", 38). -file("priv/jsx_decoder_template.erl", 35).
-file("./include/jsx_types.hrl", 1). -file("./include/jsx_types.hrl", 1).
@ -111,7 +111,7 @@
| indent | indent
| {output_encoding, supported_utf()}. | {output_encoding, supported_utf()}.
-file("priv/jsx_decoder.erl", 39). -file("priv/jsx_decoder_template.erl", 36).
-spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result().

View file

@ -1,4 +1,4 @@
-file("priv/jsx_decoder.erl", 1). -file("priv/jsx_decoder_template.erl", 1).
-module(jsx_utf16le). -module(jsx_utf16le).
@ -8,7 +8,7 @@
-file("./include/jsx_decoder.hrl", 1). -file("./include/jsx_decoder.hrl", 1).
-file("priv/jsx_decoder.erl", 38). -file("priv/jsx_decoder_template.erl", 35).
-file("./include/jsx_types.hrl", 1). -file("./include/jsx_types.hrl", 1).
@ -111,7 +111,7 @@
| indent | indent
| {output_encoding, supported_utf()}. | {output_encoding, supported_utf()}.
-file("priv/jsx_decoder.erl", 39). -file("priv/jsx_decoder_template.erl", 36).
-spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result().

View file

@ -1,4 +1,4 @@
-file("priv/jsx_decoder.erl", 1). -file("priv/jsx_decoder_template.erl", 1).
-module(jsx_utf32). -module(jsx_utf32).
@ -8,7 +8,7 @@
-file("./include/jsx_decoder.hrl", 1). -file("./include/jsx_decoder.hrl", 1).
-file("priv/jsx_decoder.erl", 38). -file("priv/jsx_decoder_template.erl", 35).
-file("./include/jsx_types.hrl", 1). -file("./include/jsx_types.hrl", 1).
@ -111,7 +111,7 @@
| indent | indent
| {output_encoding, supported_utf()}. | {output_encoding, supported_utf()}.
-file("priv/jsx_decoder.erl", 39). -file("priv/jsx_decoder_template.erl", 36).
-spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result().

View file

@ -1,4 +1,4 @@
-file("priv/jsx_decoder.erl", 1). -file("priv/jsx_decoder_template.erl", 1).
-module(jsx_utf32le). -module(jsx_utf32le).
@ -8,7 +8,7 @@
-file("./include/jsx_decoder.hrl", 1). -file("./include/jsx_decoder.hrl", 1).
-file("priv/jsx_decoder.erl", 38). -file("priv/jsx_decoder_template.erl", 35).
-file("./include/jsx_types.hrl", 1). -file("./include/jsx_types.hrl", 1).
@ -111,7 +111,7 @@
| indent | indent
| {output_encoding, supported_utf()}. | {output_encoding, supported_utf()}.
-file("priv/jsx_decoder.erl", 39). -file("priv/jsx_decoder_template.erl", 36).
-spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result().

View file

@ -1,4 +1,4 @@
-file("priv/jsx_decoder.erl", 1). -file("priv/jsx_decoder_template.erl", 1).
-module(jsx_utf8). -module(jsx_utf8).
@ -8,7 +8,7 @@
-file("./include/jsx_decoder.hrl", 1). -file("./include/jsx_decoder.hrl", 1).
-file("priv/jsx_decoder.erl", 38). -file("priv/jsx_decoder_template.erl", 35).
-file("./include/jsx_types.hrl", 1). -file("./include/jsx_types.hrl", 1).
@ -111,7 +111,7 @@
| indent | indent
| {output_encoding, supported_utf()}. | {output_encoding, supported_utf()}.
-file("priv/jsx_decoder.erl", 39). -file("priv/jsx_decoder_template.erl", 36).
-spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result(). -spec parse(JSON :: json(), Opts :: jsx_opts()) -> jsx_parser_result().

File diff suppressed because one or more lines are too long

View file

@ -1 +1,29 @@
[start_array, {string, "foo"}, {string, "bar"}, {string, "baz"}, start_array, {literal, true}, end_array, start_array, {literal, false}, end_array, start_array, {literal, null}, end_array, {literal, true}, {literal, false}, {literal, null}, {float, "0.7"}, start_object, {key, "key"}, {string, "value"}, end_object, start_array, start_object, end_object, {literal, null}, {literal, null}, {literal, null}, start_array, end_array, end_array, {string, "\n\r\\"}, start_array, {integer, "-1"}, end_array, end_array, end_json]. {name, "array"}.
{jsx, [start_array,
{string,"foo"},
{string,"bar"},
{string,"baz"},
start_array,
{literal,true},
end_array,start_array,
{literal,false},
end_array,start_array,
{literal,null},
end_array,
{literal,true},
{literal,false},
{literal,null},
{float,"0.7"},
start_object,
{key,"key"},
{string,"value"},
end_object,start_array,start_object,end_object,
{literal,null},
{literal,null},
{literal,null},
start_array,end_array,end_array,
{string,"\n\r\\"},
start_array,
{integer,"-1"},
end_array,end_array,end_json]}.
{json, "array.json"}.

View file

@ -1,3 +1,14 @@
[start_array, {string, "a string"}, {integer, "1"}, start_object, {key, "key"}, start_array, end_array, {key, "another key"}, {integer, "0"}, end_object, {literal, true}, end_array, end_json]. {name, "comments"}.
{jsx, [start_array,
[{comments, true}]. {string,"a string"},
{integer,"1"},
start_object,
{key,"key"},
start_array,end_array,
{key,"another key"},
{integer,"0"},
end_object,
{literal,true},
end_array,end_json]}.
{json, "comments.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +1,3 @@
[start_array, start_array, start_array, end_array, end_array, end_array, end_json]. {name, "deep_array"}.
{jsx, [start_array,start_array,start_array,end_array,end_array,end_array,end_json]}.
{json, "deep_array.json"}.

View file

@ -1 +1,3 @@
[start_array, end_array, end_json]. {name, "empty_array"}.
{jsx, [start_array,end_array,end_json]}.
{json, "empty_array.json"}.

View file

@ -1,3 +1,4 @@
[start_array, end_array, end_json]. {name, "empty_array_with_comment"}.
{jsx, [start_array,end_array,end_json]}.
[{comments, true}]. {json, "empty_array_with_comment.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +1,3 @@
[start_object, end_object, end_json]. {name, "empty_object"}.
{jsx, [start_object,end_object,end_json]}.
{json, "empty_object.json"}.

View file

@ -1,3 +1,4 @@
[start_object, end_object, end_json]. {name, "empty_object_with_comment"}.
{jsx, [start_object,end_object,end_json]}.
[{comments, true}]. {json, "empty_object_with_comment.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1,3 +1,4 @@
[start_array, {string, [66560]}, end_array, end_json]. {name, "encoded_surrogates"}.
{jsx, [start_array,{string,[66560]},end_array,end_json]}.
[{escaped_unicode, codepoint}]. {json, "encoded_surrogates.json"}.
{jsx_flags, [{escaped_unicode,codepoint}]}.

View file

@ -1,3 +1,15 @@
[start_array, start_array, {float, "2.0e7"}, end_array, {float, "2.0e7"}, start_object, {key, "key"}, {float, "2.0e7"}, {key, "another key"}, {float, "2.0e7"}, end_object, {float, "4.2e70"}, end_array, end_json]. {name, "exp"}.
{jsx, [start_array,start_array,
[{comments, true}]. {float,"2.0e7"},
end_array,
{float,"2.0e7"},
start_object,
{key,"key"},
{float,"2.0e7"},
{key,"another key"},
{float,"2.0e7"},
end_object,
{float,"4.2e70"},
end_array,end_json]}.
{json, "exp.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1,3 +1,20 @@
[start_array, start_array, {float, "2.0"}, end_array, {float, "2.0"}, start_object, {key, "key"}, {float, "2.0e7"}, {key, "another key"}, {float, "2.0e7"}, end_object, start_object, {key, "key"}, {float, "2.0"}, {key, "another key"}, {float, "2.0"}, end_object, {float, "4.2"}, end_array, end_json]. {name, "fraction"}.
{jsx, [start_array,start_array,
[{comments, true}]. {float,"2.0"},
end_array,
{float,"2.0"},
start_object,
{key,"key"},
{float,"2.0e7"},
{key,"another key"},
{float,"2.0e7"},
end_object,start_object,
{key,"key"},
{float,"2.0"},
{key,"another key"},
{float,"2.0"},
end_object,
{float,"4.2"},
end_array,end_json]}.
{json, "fraction.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +1 @@
[[20], 20, {"key":20, "another key":20}, 42 ] [[20], 20, {"key":20, "another key":20}, 42/*a comment*/ ]

View file

@ -1 +1,15 @@
[start_array, start_array, {integer, "20"}, end_array, {integer, "20"}, start_object, {key, "key"}, {integer, "20"}, {key, "another key"}, {integer, "20"}, end_object, {integer, "42"}, end_array, end_json]. {name, "integer"}.
{jsx, [start_array,start_array,
{integer,"20"},
end_array,
{integer,"20"},
start_object,
{key,"key"},
{integer,"20"},
{key,"another key"},
{integer,"20"},
end_object,
{integer,"42"},
end_array,end_json]}.
{json, "integer.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +1,3 @@
[start_array,{string,[32, 119070, 32]},end_array,end_json]. {name, "multibyte_utf"}.
{jsx, [start_array,{string,[32,119070,32]},end_array,end_json]}.
{json, "multibyte_utf.json"}.

View file

@ -1 +1,3 @@
[{literal, false}, end_json]. {name, "naked_false"}.
{jsx, [{literal,false},end_json]}.
{json, "naked_false.json"}.

View file

@ -1 +1,3 @@
[{literal, null}, end_json]. {name, "naked_null"}.
{jsx, [{literal,null},end_json]}.
{json, "naked_null.json"}.

View file

@ -1 +1,3 @@
[{integer, "42"}, end_json]. {name, "naked_number_a"}.
{jsx, [{integer,"42"},end_json]}.
{json, "naked_number_a.json"}.

View file

@ -1 +1,3 @@
[{integer, "-42"}, end_json]. {name, "naked_number_b"}.
{jsx, [{integer,"-42"},end_json]}.
{json, "naked_number_b.json"}.

View file

@ -1 +1,3 @@
[{float, "-0.7"}, end_json]. {name, "naked_number_c"}.
{jsx, [{float,"-0.7"},end_json]}.
{json, "naked_number_c.json"}.

View file

@ -1 +1,3 @@
[{float, "0.7"}, end_json]. {name, "naked_number_d"}.
{jsx, [{float,"0.7"},end_json]}.
{json, "naked_number_d.json"}.

View file

@ -1 +1,3 @@
[{integer, "0"}, end_json]. {name, "naked_number_e"}.
{jsx, [{integer,"0"},end_json]}.
{json, "naked_number_e.json"}.

View file

@ -1 +1,3 @@
[{float, "1.0e100"}, end_json]. {name, "naked_number_f"}.
{jsx, [{float,"1.0e100"},end_json]}.
{json, "naked_number_f.json"}.

View file

@ -1 +1,3 @@
[{integer, "7"}, end_json]. {name, "naked_number_g"}.
{jsx, [{integer,"7"},end_json]}.
{json, "naked_number_g.json"}.

View file

@ -1 +1,3 @@
[{string, "this is a naked string"}, end_json]. {name, "naked_string"}.
{jsx, [{string,"this is a naked string"},end_json]}.
{json, "naked_string.json"}.

View file

@ -1 +1,3 @@
[{literal, true}, end_json]. {name, "naked_true"}.
{jsx, [{literal,true},end_json]}.
{json, "naked_true.json"}.

View file

@ -1 +1,14 @@
[start_array, start_array, {integer, "-0"}, end_array, {integer, "-0"}, start_object, {key, "key"}, {integer, "-0"}, {key, "another key"}, {integer, "-0"}, end_object, {integer, "-0"}, end_array, end_json]. {name, "negative_zero"}.
{jsx, [start_array,start_array,
{integer,"-0"},
end_array,
{integer,"-0"},
start_object,
{key,"key"},
{integer,"-0"},
{key,"another key"},
{integer,"-0"},
end_object,
{integer,"-0"},
end_array,end_json]}.
{json, "negative_zero.json"}.

View file

@ -1 +1,23 @@
[ start_array, {integer, "1"}, {integer, "2"}, {integer, "3"}, {integer, "4"}, {integer, "5"}, {integer, "6"}, {integer, "7"}, {integer, "8"}, {integer, "9"}, {integer, "42"}, {integer, "127"}, {integer, "99999999999999999999999999999"}, {float, "1.0e1"}, {float, "1.0e1"}, {float, "1.0e1"}, {float, "1.325e478534"}, {integer, "-1"}, {float, "-1.0e-1"}, {float, "3.7e-57834235"}, end_array, end_json]. {name, "numbers"}.
{jsx, [start_array,
{integer,"1"},
{integer,"2"},
{integer,"3"},
{integer,"4"},
{integer,"5"},
{integer,"6"},
{integer,"7"},
{integer,"8"},
{integer,"9"},
{integer,"42"},
{integer,"127"},
{integer,"99999999999999999999999999999"},
{float,"1.0e1"},
{float,"1.0e1"},
{float,"1.0e1"},
{float,"1.325e478534"},
{integer,"-1"},
{float,"-1.0e-1"},
{float,"3.7e-57834235"},
end_array,end_json]}.
{json, "numbers.json"}.

View file

@ -1 +1,22 @@
[start_object, {key, "foo"}, {string, "bar"}, {key, "baz"}, {literal, true}, {key, "false"}, {literal, null}, {key, "object"}, start_object, {key, "key"}, {string, "value"}, end_object, {key, "list"}, start_array, {literal, null}, {literal, null}, {literal, null}, start_array, end_array, {string, "\n\r\\"}, end_array, end_object, end_json]. {name, "object"}.
{jsx, [start_object,
{key,"foo"},
{string,"bar"},
{key,"baz"},
{literal,true},
{key,"false"},
{literal,null},
{key,"object"},
start_object,
{key,"key"},
{string,"value"},
end_object,
{key,"list"},
start_array,
{literal,null},
{literal,null},
{literal,null},
start_array,end_array,
{string,"\n\r\\"},
end_array,end_object,end_json]}.
{json, "object.json"}.

View file

@ -1 +1,5 @@
[start_array, {string, "this is a random string with \n embedded escapes in it"}, end_array, end_json]. {name, "string"}.
{jsx, [start_array,
{string,"this is a random string with \n embedded escapes in it"},
end_array,end_json]}.
{json, "string.json"}.

View file

@ -1,3 +1,12 @@
[start_array, {string, "\""}, {string, "\\"}, {string, "/"}, {string, "\b"}, {string, "\f"}, {string, "\n"}, {string, "\r"}, {string, "\t"}, end_array, end_json]. {name, "string_escapes"}.
{jsx, [start_array,
{string,"\""},
{string,"\\"},
{string,"/"},
{string,"\b"},
{string,"\f"},
{string,"\n"},
{string,"\r"},
{string,"\t"},
end_array,end_json]}.
{json, "string_escapes.json"}.

View file

@ -1,3 +1,7 @@
[start_array, {string, "arabic letter alef: "}, {string, [16#0627]}, end_array, end_json]. {name, "unicode_to_codepoint"}.
{jsx, [start_array,
[{escaped_unicode, codepoint}]. {string,"arabic letter alef: "},
{string,[1575]},
end_array,end_json]}.
{json, "unicode_to_codepoint.json"}.
{jsx_flags, [{escaped_unicode,codepoint}]}.

View file

@ -1,3 +1,7 @@
[start_array, {string, "arabic letter alef: "}, {string, "\\u0627"}, end_array, end_json]. {name, "unicode_unconverted"}.
{jsx, [start_array,
[{escaped_unicode, ascii}]. {string,"arabic letter alef: "},
{string,"\\u0627"},
end_array,end_json]}.
{json, "unicode_unconverted.json"}.
{jsx_flags, [{escaped_unicode,ascii}]}.

View file

@ -1 +1,3 @@
[start_array, {float, "0.3"}, end_array, end_json]. {name, "whitespace"}.
{jsx, [start_array,{float,"0.3"},end_array,end_json]}.
{json, "whitespace.json"}.

View file

@ -1 +1,14 @@
[start_array, start_array, {integer, "0"}, end_array, {integer, "0"}, start_object, {key, "key"}, {integer, "0"}, {key, "another key"}, {integer, "0"}, end_object, {integer, "0"}, end_array, end_json]. {name, "zero"}.
{jsx, [start_array,start_array,
{integer,"0"},
end_array,
{integer,"0"},
start_object,
{key,"key"},
{integer,"0"},
{key,"another key"},
{integer,"0"},
end_object,
{integer,"0"},
end_array,end_json]}.
{json, "zero.json"}.