You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ch...@apache.org on 2014/08/15 22:24:51 UTC
[24/50] [abbrv] couch commit: updated refs/heads/1963-eunit-bigcouch
to 95bfc03
Port 190-json-stream-parse.t etap test suite to eunit
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/bdc3e8bb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/bdc3e8bb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/bdc3e8bb
Branch: refs/heads/1963-eunit-bigcouch
Commit: bdc3e8bb29076d57178e065586349d1fe72d26b2
Parents: 102d8e0
Author: Alexander Shorin <kx...@apache.org>
Authored: Wed Jun 4 13:22:13 2014 +0400
Committer: Russell Branca <ch...@apache.org>
Committed: Fri Aug 15 13:23:44 2014 -0700
----------------------------------------------------------------------
test/couchdb/json_stream_parse_tests.erl | 151 ++++++++++++++++++++++++++
1 file changed, 151 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/bdc3e8bb/test/couchdb/json_stream_parse_tests.erl
----------------------------------------------------------------------
diff --git a/test/couchdb/json_stream_parse_tests.erl b/test/couchdb/json_stream_parse_tests.erl
new file mode 100644
index 0000000..92303b6
--- /dev/null
+++ b/test/couchdb/json_stream_parse_tests.erl
@@ -0,0 +1,151 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(json_stream_parse_tests).
+
+-include("couch_eunit.hrl").
+
+-define(CASES,
+ [
+ {1, "1", "integer numeric literial"},
+ {3.1416, "3.14160", "float numeric literal"}, % text representation may truncate, trail zeroes
+ {-1, "-1", "negative integer numeric literal"},
+ {-3.1416, "-3.14160", "negative float numeric literal"},
+ {12.0e10, "1.20000e+11", "float literal in scientific notation"},
+ {1.234E+10, "1.23400e+10", "another float literal in scientific notation"},
+ {-1.234E-10, "-1.23400e-10", "negative float literal in scientific notation"},
+ {10.0, "1.0e+01", "yet another float literal in scientific notation"},
+ {123.456, "1.23456E+2", "yet another float literal in scientific notation"},
+ {10.0, "1e1", "yet another float literal in scientific notation"},
+ {<<"foo">>, "\"foo\"", "string literal"},
+ {<<"foo", 5, "bar">>, "\"foo\\u0005bar\"", "string literal with \\u0005"},
+ {<<"">>, "\"\"", "empty string literal"},
+ {<<"\n\n\n">>, "\"\\n\\n\\n\"", "only new lines literal"},
+ {<<"\" \b\f\r\n\t\"">>, "\"\\\" \\b\\f\\r\\n\\t\\\"\"",
+ "only white spaces string literal"},
+ {null, "null", "null literal"},
+ {true, "true", "true literal"},
+ {false, "false", "false literal"},
+ {<<"null">>, "\"null\"", "null string literal"},
+ {<<"true">>, "\"true\"", "true string literal"},
+ {<<"false">>, "\"false\"", "false string literal"},
+ {{[]}, "{}", "empty object literal"},
+ {{[{<<"foo">>, <<"bar">>}]}, "{\"foo\":\"bar\"}",
+ "simple object literal"},
+ {{[{<<"foo">>, <<"bar">>}, {<<"baz">>, 123}]},
+ "{\"foo\":\"bar\",\"baz\":123}", "another simple object literal"},
+ {[], "[]", "empty array literal"},
+ {[[]], "[[]]", "empty array literal inside a single element array literal"},
+ {[1, <<"foo">>], "[1,\"foo\"]", "simple non-empty array literal"},
+ {[1199344435545.0, 1], "[1199344435545.0,1]",
+ "another simple non-empty array literal"},
+ {[false, true, 321, null], "[false, true, 321, null]", "array of literals"},
+ {{[{<<"foo">>, [123]}]}, "{\"foo\":[123]}",
+ "object literal with an array valued property"},
+ {{[{<<"foo">>, {[{<<"bar">>, true}]}}]},
+ "{\"foo\":{\"bar\":true}}", "nested object literal"},
+ {{[{<<"foo">>, []}, {<<"bar">>, {[{<<"baz">>, true}]}},
+ {<<"alice">>, <<"bob">>}]},
+ "{\"foo\":[],\"bar\":{\"baz\":true},\"alice\":\"bob\"}",
+ "complex object literal"},
+ {[-123, <<"foo">>, {[{<<"bar">>, []}]}, null],
+ "[-123,\"foo\",{\"bar\":[]},null]",
+ "complex array literal"}
+ ]
+).
+
+
+raw_json_input_test_() ->
+ Tests = lists:map(
+ fun({EJson, JsonString, Desc}) ->
+ {Desc,
+ ?_assert(equiv(EJson, json_stream_parse:to_ejson(JsonString)))}
+ end, ?CASES),
+ {"Tests with raw JSON string as the input", Tests}.
+
+one_byte_data_fun_test_() ->
+ Tests = lists:map(
+ fun({EJson, JsonString, Desc}) ->
+ DataFun = fun() -> single_byte_data_fun(JsonString) end,
+ {Desc,
+ ?_assert(equiv(EJson, json_stream_parse:to_ejson(DataFun)))}
+ end, ?CASES),
+ {"Tests with a 1 byte output data function as the input", Tests}.
+
+test_multiple_bytes_data_fun_test_() ->
+ Tests = lists:map(
+ fun({EJson, JsonString, Desc}) ->
+ DataFun = fun() -> multiple_bytes_data_fun(JsonString) end,
+ {Desc,
+ ?_assert(equiv(EJson, json_stream_parse:to_ejson(DataFun)))}
+ end, ?CASES),
+ {"Tests with a multiple bytes output data function as the input", Tests}.
+
+
+%% Test for equivalence of Erlang terms.
+%% Due to arbitrary order of construction, equivalent objects might
+%% compare unequal as erlang terms, so we need to carefully recurse
+%% through aggregates (tuples and objects).
+equiv({Props1}, {Props2}) ->
+ equiv_object(Props1, Props2);
+equiv(L1, L2) when is_list(L1), is_list(L2) ->
+ equiv_list(L1, L2);
+equiv(N1, N2) when is_number(N1), is_number(N2) ->
+ N1 == N2;
+equiv(B1, B2) when is_binary(B1), is_binary(B2) ->
+ B1 == B2;
+equiv(true, true) ->
+ true;
+equiv(false, false) ->
+ true;
+equiv(null, null) ->
+ true.
+
+%% Object representation and traversal order is unknown.
+%% Use the sledgehammer and sort property lists.
+equiv_object(Props1, Props2) ->
+ L1 = lists:keysort(1, Props1),
+ L2 = lists:keysort(1, Props2),
+ Pairs = lists:zip(L1, L2),
+ true = lists:all(
+ fun({{K1, V1}, {K2, V2}}) ->
+ equiv(K1, K2) andalso equiv(V1, V2)
+ end,
+ Pairs).
+
+%% Recursively compare tuple elements for equivalence.
+equiv_list([], []) ->
+ true;
+equiv_list([V1 | L1], [V2 | L2]) ->
+ equiv(V1, V2) andalso equiv_list(L1, L2).
+
+single_byte_data_fun([]) ->
+ done;
+single_byte_data_fun([H | T]) ->
+ {<<H>>, fun() -> single_byte_data_fun(T) end}.
+
+multiple_bytes_data_fun([]) ->
+ done;
+multiple_bytes_data_fun(L) ->
+ N = crypto:rand_uniform(0, 7),
+ {Part, Rest} = split(L, N),
+ {list_to_binary(Part), fun() -> multiple_bytes_data_fun(Rest) end}.
+
+split(L, N) when length(L) =< N ->
+ {L, []};
+split(L, N) ->
+ take(N, L, []).
+
+take(0, L, Acc) ->
+ {lists:reverse(Acc), L};
+take(N, [H|L], Acc) ->
+ take(N - 1, L, [H | Acc]).