diff --git a/src/jsx_utf8.erl b/src/jsx_utf8.erl index c22ac3c..7a797d1 100644 --- a/src/jsx_utf8.erl +++ b/src/jsx_utf8.erl @@ -242,6 +242,8 @@ zero(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); zero(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> zero(Resume, Stack, Callbacks, Opts, Acc) end); +zero(<<>>, [], Callbacks, _Opts, Acc) -> + callback(eof, callback({number, lists:reverse(Acc)}, Callbacks)); zero(<<>>, Stack, Callbacks, Opts, Acc) -> fun(Stream) -> zero(Stream, Stack, Callbacks, Opts, Acc) end. @@ -268,6 +270,8 @@ integer(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespac maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); integer(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> integer(Resume, Stack, Callbacks, Opts, Acc) end); +integer(<<>>, [], Callbacks, _Opts, Acc) -> + callback(eof, callback({number, lists:reverse(Acc)}, Callbacks)); integer(<<>>, Stack, Callbacks, Opts, Acc) -> fun(Stream) -> integer(Stream, Stack, Callbacks, Opts, Acc) end. @@ -292,6 +296,8 @@ fraction(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespa maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); fraction(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> fraction(Resume, Stack, Callbacks, Opts, Acc) end); +fraction(<<>>, [], Callbacks, _Opts, Acc) -> + callback(eof, callback({number, lists:reverse(Acc)}, Callbacks)); fraction(<<>>, Stack, Callbacks, Opts, Acc) -> fun(Stream) -> fraction(Stream, Stack, Callbacks, Opts, Acc) end. @@ -326,6 +332,8 @@ exp(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); exp(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> exp(Resume, Stack, Callbacks, Opts, Acc) end); +exp(<<>>, [], Callbacks, _Opts, Acc) -> + callback(eof, callback({number, lists:reverse(Acc)}, Callbacks)); exp(<<>>, Stack, Callbacks, Opts, Acc) -> fun(Stream) -> exp(Stream, Stack, Callbacks, Opts, Acc) end. diff --git a/test/jsx_test.erl b/test/jsx_test.erl new file mode 100644 index 0000000..c9d1cfd --- /dev/null +++ b/test/jsx_test.erl @@ -0,0 +1,48 @@ +-module(jsx_test). + +-export([test/0]). + +-define(assert(A, B), + case A == B of true -> ok ; false -> erlang:error(failed_assert, ?LINE) end +). + +test() -> + Strict = jsx:decoder(), + Comments = jsx:decoder([{comments, true}]), + Naked = jsx:decoder([{naked_values, true}]), + NakedComments = jsx:decoder([{comments, true}, {naked_values, true}]), + + %% empty objects and arrays + ?assert([start_array, end_array], Strict(<<"[]">>)), + ?assert([start_object, end_object], Strict(<<"{}">>)), + + %% really deep array + ?assert([start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, start_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array, end_array], Strict(<<"[[[[[[[[[[]]]]]]]]]]">>)), + + %% naked values + ?assert([{literal, true}], Naked(<<"true">>)), + ?assert([{literal, false}], Naked(<<"false">>)), + ?assert([{literal, null}], Naked(<<"null">>)), + ?assert([{string, "blah blah blah"}], Naked(<<"\"blah blah blah\"">>)), + ?assert([{number, "1"}], Naked(<<"1">>)), + ?assert([{number, "0.51323412"}], Naked(<<"0.51323412">>)), + ?assert([{number, "-1.1"}], Naked(<<"-1.1">>)), + + %% comments + ?assert([start_array, end_array], Comments(<<"[ /* this is ignored */ ]">>)), + ?assert([start_object, end_object], Comments(<<"{ /* this too */ }">>)), + + %% strings and unicode + ?assert([start_array, {string, "a test string"}, end_array], Strict(<<"[ \"a test string\" ]">>)), + ?assert([start_array, {string, "a high unicode value: " ++ [100000]}, end_array], Strict(<<"[ \"a high unicode value: ", 100000/utf8, "\" ]">>)), + ?assert([start_object, {key, "key"}, {string, "value"}, end_object], Strict(<<"{ \"key\": \"value\" }">>)), + + %% numbers + ?assert([start_array, {number, "1"}, end_array], Strict(<<"[ 1 ]">>)), + ?assert([start_array, {number, "0"}, end_array], Strict(<<"[ 0 ]">>)), + ?assert([start_array, {number, "1e1"}, end_array], Strict(<<"[ 1e1 ]">>)), + ?assert([start_array, {number, "-1.0e5123"}, end_array], Strict(<<"[ -1.0e5123 ]">>)), + ?assert([start_array, {number, "324523452345256234455"}, end_array], Strict(<<"[ 324523452345256234455 ]">>)), + + ok. + \ No newline at end of file