You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by kx...@apache.org on 2015/07/13 20:45:14 UTC

[15/43] jiffy commit: updated refs/heads/upstream to 446e284

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/010-short-doubles.t
----------------------------------------------------------------------
diff --git a/test/010-short-doubles.t b/test/010-short-doubles.t
deleted file mode 100755
index 4aac375..0000000
--- a/test/010-short-doubles.t
+++ /dev/null
@@ -1,29 +0,0 @@
-#! /usr/bin/env escript
-% This file is part of Jiffy released under the MIT license.
-% See the LICENSE file for more information.
-
-filename() -> "test/cases/short-doubles.txt".
-
-main([]) ->
-    code:add_pathz("ebin"),
-    code:add_pathz("test"),
-
-    etap:plan(100000),
-
-    etap:diag("Loading test cases..."),
-    {ok, Cases} = file:consult(filename()),
-
-    etap:diag("Running tests..."),
-    ok = run_tests(Cases),
-
-    etap:end_tests().
-
-
-run_tests([]) ->
-    ok;
-run_tests([Double | Rest]) ->
-    RoundTrip = jiffy:decode(jiffy:encode(Double)),
-    Desc = lists:flatten(io_lib:format("~e", [Double])),
-    etap:is(RoundTrip, Double, "Roundtrip: " ++ Desc),
-    run_tests(Rest).
-

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/etap.erl
----------------------------------------------------------------------
diff --git a/test/etap.erl b/test/etap.erl
deleted file mode 100644
index 6924d09..0000000
--- a/test/etap.erl
+++ /dev/null
@@ -1,612 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <ni...@gerakines.net>
-%%
-%% 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.
-%%
-%% @author Nick Gerakines <ni...@gerakines.net> [http://socklabs.com/]
-%% @author Jeremy Wall <je...@marzhillstudios.com>
-%% @version 0.3.4
-%% @copyright 2007-2008 Jeremy Wall, 2008-2009 Nick Gerakines
-%% @reference http://testanything.org/wiki/index.php/Main_Page
-%% @reference http://en.wikipedia.org/wiki/Test_Anything_Protocol
-%% @todo Finish implementing the skip directive.
-%% @todo Document the messages handled by this receive loop.
-%% @todo Explain in documentation why we use a process to handle test input.
-%% @doc etap is a TAP testing module for Erlang components and applications.
-%% This module allows developers to test their software using the TAP method.
-%%
-%% <blockquote cite="http://en.wikipedia.org/wiki/Test_Anything_Protocol"><p>
-%% TAP, the Test Anything Protocol, is a simple text-based interface between
-%% testing modules in a test harness. TAP started life as part of the test
-%% harness for Perl but now has implementations in C/C++, Python, PHP, Perl
-%% and probably others by the time you read this.
-%% </p></blockquote>
-%%
-%% The testing process begins by defining a plan using etap:plan/1, running
-%% a number of etap tests and then calling eta:end_tests/0. Please refer to
-%% the Erlang modules in the t directory of this project for example tests.
--module(etap).
--vsn("0.3.4").
-
--export([
-    ensure_test_server/0,
-    start_etap_server/0,
-    test_server/1,
-    msg/1, msg/2,
-    diag/1, diag/2,
-    expectation_mismatch_message/3,
-    plan/1,
-    end_tests/0,
-    not_ok/2, ok/2, is_ok/2, is/3, isnt/3, any/3, none/3,
-    fun_is/3, expect_fun/3, expect_fun/4,
-    is_greater/3,
-    skip/1, skip/2,
-    datetime/1,
-    skip/3,
-    bail/0, bail/1,
-    test_state/0, failure_count/0
-]).
-
--export([
-    contains_ok/3,
-    is_before/4
-]).
-
--export([
-    is_pid/2,
-    is_alive/2,
-    is_mfa/3
-]).
-
--export([
-    loaded_ok/2,
-    can_ok/2, can_ok/3,
-    has_attrib/2, is_attrib/3,
-    is_behaviour/2
-]).
-
--export([
-    dies_ok/2,
-    lives_ok/2,
-    throws_ok/3
-]).
-
-
--record(test_state, {
-    planned = 0,
-    count = 0,
-    pass = 0,
-    fail = 0,
-    skip = 0,
-    skip_reason = ""
-}).
-
-%% @spec plan(N) -> Result
-%%       N = unknown | skip | {skip, string()} | integer()
-%%       Result = ok
-%% @doc Create a test plan and boot strap the test server.
-plan(unknown) ->
-    ensure_test_server(),
-    etap_server ! {self(), plan, unknown},
-    ok;
-plan(skip) ->
-    io:format("1..0 # skip~n");
-plan({skip, Reason}) ->
-    io:format("1..0 # skip ~s~n", [Reason]);
-plan(N) when is_integer(N), N > 0 ->
-    ensure_test_server(),
-    etap_server ! {self(), plan, N},
-    ok.
-
-%% @spec end_tests() -> ok
-%% @doc End the current test plan and output test results.
-%% @todo This should probably be done in the test_server process.
-end_tests() ->
-    case whereis(etap_server) of
-        undefined -> self() ! true;
-        _ -> etap_server ! {self(), state}
-    end,
-    State = receive X -> X end,
-    if
-        State#test_state.planned == -1 ->
-            io:format("1..~p~n", [State#test_state.count]);
-        true ->
-            ok
-    end,
-    case whereis(etap_server) of
-        undefined -> ok;
-        _ -> etap_server ! done, ok
-    end.
-
-bail() ->
-    bail("").
-
-bail(Reason) ->
-    etap_server ! {self(), diag, "Bail out! " ++ Reason},
-    etap_server ! done, ok,
-    ok.
-
-%% @spec test_state() -> Return
-%%       Return = test_state_record() | {error, string()}
-%% @doc Return the current test state
-test_state() ->
-    etap_server ! {self(), state},
-    receive
-	X when is_record(X, test_state) -> X
-    after
-	1000 -> {error, "Timed out waiting for etap server reply.~n"}
-    end.
-
-%% @spec failure_count() -> Return
-%%       Return = integer() | {error, string()}
-%% @doc Return the current failure count
-failure_count() ->
-    case test_state() of
-        #test_state{fail=FailureCount} -> FailureCount;
-        X -> X
-    end.
-
-%% @spec msg(S) -> ok
-%%       S = string()
-%% @doc Print a message in the test output.
-msg(S) -> etap_server ! {self(), diag, S}, ok.
-
-%% @spec msg(Format, Data) -> ok
-%%      Format = atom() | string() | binary()
-%%      Data = [term()]
-%%      UnicodeList = [Unicode]
-%%      Unicode = int()
-%% @doc Print a message in the test output.
-%% Function arguments are passed through io_lib:format/2.
-msg(Format, Data) -> msg(io_lib:format(Format, Data)).
-
-%% @spec diag(S) -> ok
-%%       S = string()
-%% @doc Print a debug/status message related to the test suite.
-diag(S) -> msg("# " ++ S).
-
-%% @spec diag(Format, Data) -> ok
-%%      Format = atom() | string() | binary()
-%%      Data = [term()]
-%%      UnicodeList = [Unicode]
-%%      Unicode = int()
-%% @doc Print a debug/status message related to the test suite.
-%% Function arguments are passed through io_lib:format/2.
-diag(Format, Data) -> diag(io_lib:format(Format, Data)).
-
-%% @spec expectation_mismatch_message(Got, Expected, Desc) -> ok
-%%       Got = any()
-%%       Expected = any()
-%%       Desc = string()
-%% @doc Print an expectation mismatch message in the test output.
-expectation_mismatch_message(Got, Expected, Desc) ->
-    msg("    ---"),
-    msg("    description: ~p", [Desc]),
-    msg("    found:       ~p", [Got]),
-    msg("    wanted:      ~p", [Expected]),
-    msg("    ..."),
-    ok.
-
-% @spec evaluate(Pass, Got, Expected, Desc) -> Result
-%%       Pass = true | false
-%%       Got = any()
-%%       Expected = any()
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Evaluate a test statement, printing an expectation mismatch message
-%%       if the test failed.
-evaluate(Pass, Got, Expected, Desc) ->
-    case mk_tap(Pass, Desc) of
-        false ->
-            expectation_mismatch_message(Got, Expected, Desc),
-            false;
-        true ->
-            true
-    end.
-
-%% @spec ok(Expr, Desc) -> Result
-%%       Expr = true | false
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Assert that a statement is true.
-ok(Expr, Desc) -> evaluate(Expr == true, Expr, true, Desc).
-
-%% @spec not_ok(Expr, Desc) -> Result
-%%       Expr = true | false
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Assert that a statement is false.
-not_ok(Expr, Desc) -> evaluate(Expr == false, Expr, false, Desc).
-
-%% @spec is_ok(Expr, Desc) -> Result
-%%       Expr = any()
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Assert that two values are the same.
-is_ok(Expr, Desc) -> evaluate(Expr == ok, Expr, ok, Desc).
-
-%% @spec is(Got, Expected, Desc) -> Result
-%%       Got = any()
-%%       Expected = any()
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Assert that two values are the same.
-is(Got, Expected, Desc) -> evaluate(Got == Expected, Got, Expected, Desc).
-
-%% @spec isnt(Got, Expected, Desc) -> Result
-%%       Got = any()
-%%       Expected = any()
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Assert that two values are not the same.
-isnt(Got, Expected, Desc) -> evaluate(Got /= Expected, Got, Expected, Desc).
-
-%% @spec is_greater(ValueA, ValueB, Desc) -> Result
-%%       ValueA = number()
-%%       ValueB = number()
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Assert that an integer is greater than another.
-is_greater(ValueA, ValueB, Desc) when is_integer(ValueA), is_integer(ValueB) ->
-    mk_tap(ValueA > ValueB, Desc).
-
-%% @spec any(Got, Items, Desc) -> Result
-%%       Got = any()
-%%       Items = [any()]
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Assert that an item is in a list.
-any(Got, Items, Desc) when is_function(Got) ->
-    is(lists:any(Got, Items), true, Desc);
-any(Got, Items, Desc) ->
-    is(lists:member(Got, Items), true, Desc).
-
-%% @spec none(Got, Items, Desc) -> Result
-%%       Got = any()
-%%       Items = [any()]
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Assert that an item is not in a list.
-none(Got, Items, Desc) when is_function(Got) ->
-    is(lists:any(Got, Items), false, Desc);
-none(Got, Items, Desc) ->
-    is(lists:member(Got, Items), false, Desc).
-
-%% @spec fun_is(Fun, Expected, Desc) -> Result
-%%       Fun = function()
-%%       Expected = any()
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Use an anonymous function to assert a pattern match.
-fun_is(Fun, Expected, Desc) when is_function(Fun) ->
-    is(Fun(Expected), true, Desc).
-
-%% @spec expect_fun(ExpectFun, Got, Desc) -> Result
-%%       ExpectFun = function()
-%%       Got = any()
-%%       Desc = string()
-%%       Result = true | false
-%% @doc Use an anonymous function to assert a pattern match, using actual
-%%       value as the argument to the function.
-expect_fun(ExpectFun, Got, Desc) ->
-    evaluate(ExpectFun(Got), Got, ExpectFun, Desc).
-
-%% @spec expect_fun(ExpectFun, Got, Desc, ExpectStr) -> Result
-%%       ExpectFun = function()
-%%       Got = any()
-%%       Desc = string()
-%%       ExpectStr = string()
-%%       Result = true | false
-%% @doc Use an anonymous function to assert a pattern match, using actual
-%%       value as the argument to the function.
-expect_fun(ExpectFun, Got, Desc, ExpectStr) ->
-    evaluate(ExpectFun(Got), Got, ExpectStr, Desc).
-
-%% @equiv skip(TestFun, "")
-skip(TestFun) when is_function(TestFun) ->
-    skip(TestFun, "").
-
-%% @spec skip(TestFun, Reason) -> ok
-%%       TestFun = function()
-%%       Reason = string()
-%% @doc Skip a test.
-skip(TestFun, Reason) when is_function(TestFun), is_list(Reason) ->
-    begin_skip(Reason),
-    catch TestFun(),
-    end_skip(),
-    ok.
-
-%% @spec skip(Q, TestFun, Reason) -> ok
-%%       Q = true | false | function()
-%%       TestFun = function()
-%%       Reason = string()
-%% @doc Skips a test conditionally. The first argument to this function can
-%% either be the 'true' or 'false' atoms or a function that returns 'true' or
-%% 'false'.
-skip(QFun, TestFun, Reason) when is_function(QFun), is_function(TestFun), is_list(Reason) ->
-    case QFun() of
-        true -> begin_skip(Reason), TestFun(), end_skip();
-        _ -> TestFun()
-    end,
-    ok;
-
-skip(Q, TestFun, Reason) when is_function(TestFun), is_list(Reason), Q == true ->
-    begin_skip(Reason),
-    TestFun(),
-    end_skip(),
-    ok;
-
-skip(_, TestFun, Reason) when is_function(TestFun), is_list(Reason) ->
-    TestFun(),
-    ok.
-
-%% @private
-begin_skip(Reason) ->
-    etap_server ! {self(), begin_skip, Reason}.
-
-%% @private
-end_skip() ->
-    etap_server ! {self(), end_skip}.
-
-%% @spec contains_ok(string(), string(), string()) -> true | false
-%% @doc Assert that a string is contained in another string.
-contains_ok(Source, String, Desc) ->
-    etap:isnt(
-        string:str(Source, String),
-        0,
-        Desc
-    ).
-
-%% @spec is_before(string(), string(), string(), string()) -> true | false
-%% @doc Assert that a string comes before another string within a larger body.
-is_before(Source, StringA, StringB, Desc) ->
-    etap:is_greater(
-        string:str(Source, StringB),
-        string:str(Source, StringA),
-        Desc
-    ).
-
-%% @doc Assert that a given variable is a pid.
-is_pid(Pid, Desc) when is_pid(Pid) -> etap:ok(true, Desc);
-is_pid(_, Desc) -> etap:ok(false, Desc).
-
-%% @doc Assert that a given process/pid is alive.
-is_alive(Pid, Desc) ->
-    etap:ok(erlang:is_process_alive(Pid), Desc).
-
-%% @doc Assert that the current function of a pid is a given {M, F, A} tuple.
-is_mfa(Pid, MFA, Desc) ->
-    etap:is({current_function, MFA}, erlang:process_info(Pid, current_function), Desc).
-
-%% @spec loaded_ok(atom(), string()) -> true | false
-%% @doc Assert that a module has been loaded successfully.
-loaded_ok(M, Desc) when is_atom(M) ->
-    etap:fun_is(fun({module, _}) -> true; (_) -> false end, code:load_file(M), Desc).
-
-%% @spec can_ok(atom(), atom()) -> true | false
-%% @doc Assert that a module exports a given function.
-can_ok(M, F) when is_atom(M), is_atom(F) ->
-    Matches = [X || {X, _} <- M:module_info(exports), X == F],
-    etap:ok(Matches > 0, lists:concat([M, " can ", F])).
-
-%% @spec can_ok(atom(), atom(), integer()) -> true | false
-%% @doc Assert that a module exports a given function with a given arity.
-can_ok(M, F, A) when is_atom(M); is_atom(F), is_number(A) ->
-    Matches = [X || X <- M:module_info(exports), X == {F, A}],
-    etap:ok(Matches > 0, lists:concat([M, " can ", F, "/", A])).
-
-%% @spec has_attrib(M, A) -> true | false
-%%       M = atom()
-%%       A = atom()
-%% @doc Asserts that a module has a given attribute.
-has_attrib(M, A) when is_atom(M), is_atom(A) ->
-    etap:isnt(
-        proplists:get_value(A, M:module_info(attributes), 'asdlkjasdlkads'),
-        'asdlkjasdlkads',
-        lists:concat([M, " has attribute ", A])
-    ).
-
-%% @spec has_attrib(M, A. V) -> true | false
-%%       M = atom()
-%%       A = atom()
-%%       V = any()
-%% @doc Asserts that a module has a given attribute with a given value.
-is_attrib(M, A, V) when is_atom(M) andalso is_atom(A) ->
-    etap:is(
-        proplists:get_value(A, M:module_info(attributes)),
-        [V],
-        lists:concat([M, "'s ", A, " is ", V])
-    ).
-
-%% @spec is_behavior(M, B) -> true | false
-%%       M = atom()
-%%       B = atom()
-%% @doc Asserts that a given module has a specific behavior.
-is_behaviour(M, B) when is_atom(M) andalso is_atom(B) ->
-    is_attrib(M, behaviour, B).
-
-%% @doc Assert that an exception is raised when running a given function.
-dies_ok(F, Desc) ->
-    case (catch F()) of
-        {'EXIT', _} -> etap:ok(true, Desc);
-        _ -> etap:ok(false, Desc)
-    end.
-
-%% @doc Assert that an exception is not raised when running a given function.
-lives_ok(F, Desc) ->
-    etap:is(try_this(F), success, Desc).
-
-%% @doc Assert that the exception thrown by a function matches the given exception.
-throws_ok(F, Exception, Desc) ->
-    try F() of
-        _ -> etap:ok(nok, Desc)
-    catch
-        _:E ->
-            etap:is(E, Exception, Desc)
-    end.
-
-%% @private
-%% @doc Run a function and catch any exceptions.
-try_this(F) when is_function(F, 0) ->
-    try F() of
-        _ -> success
-    catch
-        throw:E -> {throw, E};
-        error:E -> {error, E};
-        exit:E -> {exit, E}
-    end.
-
-%% @private
-%% @doc Start the etap_server process if it is not running already.
-ensure_test_server() ->
-    case whereis(etap_server) of
-        undefined ->
-            proc_lib:start(?MODULE, start_etap_server,[]);
-        _ ->
-            diag("The test server is already running.")
-    end.
-
-%% @private
-%% @doc Start the etap_server loop and register itself as the etap_server
-%% process.
-start_etap_server() ->
-    catch register(etap_server, self()),
-    proc_lib:init_ack(ok),
-    etap:test_server(#test_state{
-        planned = 0,
-        count = 0,
-        pass = 0,
-        fail = 0,
-        skip = 0,
-        skip_reason = ""
-    }).
-
-
-%% @private
-%% @doc The main etap_server receive/run loop. The etap_server receive loop
-%% responds to seven messages apperatining to failure or passing of tests.
-%% It is also used to initiate the testing process with the {_, plan, _}
-%% message that clears the current test state.
-test_server(State) ->
-    NewState = receive
-        {_From, plan, unknown} ->
-            io:format("# Current time local ~s~n", [datetime(erlang:localtime())]),
-            io:format("# Using etap version ~p~n", [ proplists:get_value(vsn, proplists:get_value(attributes, etap:module_info())) ]),
-            State#test_state{
-                planned = -1,
-                count = 0,
-                pass = 0,
-                fail = 0,
-                skip = 0,
-                skip_reason = ""
-            };
-        {_From, plan, N} ->
-            io:format("# Current time local ~s~n", [datetime(erlang:localtime())]),
-            io:format("# Using etap version ~p~n", [ proplists:get_value(vsn, proplists:get_value(attributes, etap:module_info())) ]),
-            io:format("1..~p~n", [N]),
-            State#test_state{
-                planned = N,
-                count = 0,
-                pass = 0,
-                fail = 0,
-                skip = 0,
-                skip_reason = ""
-            };
-        {_From, begin_skip, Reason} ->
-            State#test_state{
-                skip = 1,
-                skip_reason = Reason
-            };
-        {_From, end_skip} ->
-            State#test_state{
-                skip = 0,
-                skip_reason = ""
-            };
-        {_From, pass, Desc} ->
-            FullMessage = skip_diag(
-                " - " ++ Desc,
-                State#test_state.skip,
-                State#test_state.skip_reason
-            ),
-            io:format("ok ~p ~s~n", [State#test_state.count + 1, FullMessage]),
-            State#test_state{
-                count = State#test_state.count + 1,
-                pass = State#test_state.pass + 1
-            };
-
-        {_From, fail, Desc} ->
-            FullMessage = skip_diag(
-                " - " ++ Desc,
-                State#test_state.skip,
-                State#test_state.skip_reason
-            ),
-            io:format("not ok ~p ~s~n", [State#test_state.count + 1, FullMessage]),
-            State#test_state{
-                count = State#test_state.count + 1,
-                fail = State#test_state.fail + 1
-            };
-        {From, state} ->
-            From ! State,
-            State;
-        {_From, diag, Message} ->
-            io:format("~s~n", [Message]),
-            State;
-        {From, count} ->
-            From ! State#test_state.count,
-            State;
-        {From, is_skip} ->
-            From ! State#test_state.skip,
-            State;
-        done ->
-            exit(normal)
-    end,
-    test_server(NewState).
-
-%% @private
-%% @doc Process the result of a test and send it to the etap_server process.
-mk_tap(Result, Desc) ->
-    IsSkip = lib:sendw(etap_server, is_skip),
-    case [IsSkip, Result] of
-        [_, true] ->
-            etap_server ! {self(), pass, Desc},
-            true;
-        [1, _] ->
-            etap_server ! {self(), pass, Desc},
-            true;
-        _ ->
-            etap_server ! {self(), fail, Desc},
-            false
-    end.
-
-%% @private
-%% @doc Format a date/time string.
-datetime(DateTime) ->
-    {{Year, Month, Day}, {Hour, Min, Sec}} = DateTime,
-    io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B", [Year, Month, Day, Hour, Min, Sec]).
-
-%% @private
-%% @doc Craft an output message taking skip/todo into consideration.
-skip_diag(Message, 0, _) ->
-    Message;
-skip_diag(_Message, 1, "") ->
-    " # SKIP";
-skip_diag(_Message, 1, Reason) ->
-    " # SKIP : " ++ Reason.

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_01_yajl_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_01_yajl_tests.erl b/test/jiffy_01_yajl_tests.erl
new file mode 100644
index 0000000..b3ac13a
--- /dev/null
+++ b/test/jiffy_01_yajl_tests.erl
@@ -0,0 +1,33 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_01_yajl_tests).
+
+
+-include_lib("proper/include/proper.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+
+yajl_test_() ->
+    Cases = read_cases(),
+    [gen(Case) || Case <- Cases].
+
+
+gen({Name, Json, {error, _}=Erl}) ->
+    {Name, ?_assertThrow(Erl, jiffy:decode(Json))};
+gen({Name, Json, Erl}) ->
+    {Name, ?_assertEqual(Erl, jiffy:decode(Json))}.
+
+
+read_cases() ->
+    CasesPath = filename:join(["..", "test", "cases", "*.json"]),
+    FileNames = lists:sort(filelib:wildcard(CasesPath)),
+    lists:map(fun(F) -> make_pair(F) end, FileNames).
+
+
+make_pair(FileName) ->
+    {ok, Json} = file:read_file(FileName),
+    BaseName = filename:rootname(FileName),
+    ErlFname = BaseName ++ ".eterm",
+    {ok, [Term]} = file:consult(ErlFname),
+    {filename:basename(BaseName), Json, Term}.

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_02_literal_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_02_literal_tests.erl b/test/jiffy_02_literal_tests.erl
new file mode 100644
index 0000000..4c50a34
--- /dev/null
+++ b/test/jiffy_02_literal_tests.erl
@@ -0,0 +1,28 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_02_literal_tests).
+
+-include_lib("proper/include/proper.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+
+true_test_() ->
+    {"true", [
+        {"Decode", ?_assertEqual(true, jiffy:decode(<<"true">>))},
+        {"Encode", ?_assertEqual(<<"true">>, jiffy:encode(true))}
+    ]}.
+
+
+false_test_() ->
+    {"false", [
+        {"Decode", ?_assertEqual(false, jiffy:decode(<<"false">>))},
+        {"Encode", ?_assertEqual(<<"false">>, jiffy:encode(false))}
+    ]}.
+
+
+null_test_() ->
+    {"null", [
+        {"Decode", ?_assertEqual(null, jiffy:decode(<<"null">>))},
+        {"Encode", ?_assertEqual(<<"null">>, jiffy:encode(null))}
+    ]}.

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_03_number_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_03_number_tests.erl b/test/jiffy_03_number_tests.erl
new file mode 100644
index 0000000..da69049
--- /dev/null
+++ b/test/jiffy_03_number_tests.erl
@@ -0,0 +1,134 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_03_number_tests).
+
+
+-include_lib("proper/include/proper.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include("jiffy_util.hrl").
+
+
+number_success_test_() ->
+    [gen(ok, Case) || Case <- cases(ok)].
+
+
+number_failure_test_() ->
+    [gen(error, Case) || Case <- cases(error)].
+
+
+number_double_test_() ->
+    [gen(floats, Case) || Case <- cases(floats)].
+
+
+gen(ok, {J, E}) ->
+    gen(ok, {J, E, J});
+gen(ok, {J1, E, J2}) ->
+    {msg("~s", [J1]), [
+        {"Decode", ?_assertEqual(E, dec(J1))},
+        {"Encode", ?_assertEqual(J2, enc(E))}
+    ]};
+
+gen(error, J) ->
+    {msg("Error: ~s", [J]), [
+        ?_assertThrow({error, _}, dec(J))
+    ]};
+
+gen(floats, F) ->
+    NegF = -1.0 * F,
+    {msg("float round trip - ~p", [F]), [
+        {"Pos", ?_assertEqual(F, dec(enc(F)))},
+        {"Neg", ?_assertEqual(NegF, dec(enc(NegF)))}
+    ]}.
+
+
+cases(ok) ->
+    [
+        {<<"0">>, 0},
+        {<<"-0">>, 0, <<"0">>},
+        {<<"1">>, 1},
+        {<<"12">>, 12},
+        {<<"-3">>, -3},
+        {<<"1234567890123456789012345">>, 1234567890123456789012345},
+        {<<"1310050760199">>, 1310050760199},
+        {
+            <<"1234567890123456789012345.0">>,
+            1.23456789012345678e24,
+            <<"1.2345678901234568e+24">>
+        },
+        {
+            <<"1234567890123456789012345.0E3">>,
+            1.2345678901234569e27,
+            <<"1.2345678901234569e+27">>
+        },
+        {
+            <<"1234567890123456789012345012">>,
+            1234567890123456789012345012,
+            <<"1234567890123456789012345012">>
+        },
+        {<<"1.0">>, 1.0},
+        {
+            <<"0.000000000000000000000000000000000001">>,
+            1.0E-36,
+            <<"1e-36">>
+        },
+        {<<"0.75">>, 0.75},
+        {<<"2.0123456789">>, 2.0123456789, <<"2.0123456789">>},
+        {<<"2.4234324E24">>, 2.4234324E24, <<"2.4234324e+24">>},
+        {<<"-3.1416">>, -3.1416, <<"-3.1416">>},
+        {<<"1E4">>, 10000.0, <<"10000.0">>},
+        {<<"1.0E+01">>, 10.0, <<"10.0">>},
+        {<<"1e1">>, 10.0, <<"10.0">>},
+        {<<"3.0E2">>, 300.0, <<"300.0">>},
+        {<<"0E3">>, 0.0, <<"0.0">>},
+        {<<"1.5E3">>, 1500.0, <<"1500.0">>},
+        {<<"2.5E-1">>, 0.25, <<"0.25">>},
+        {<<"-0.325E+2">>, -32.5, <<"-32.5">>}
+    ];
+
+cases(error) ->
+    [
+        <<"02">>,
+        <<"-01">>,
+        <<"+12">>,
+        <<"-">>,
+        <<"1.">>,
+        <<".1">>,
+        <<"1.-1">>,
+        <<"1E">>,
+        <<"1-E2">>,
+        <<"2E +3">>,
+        <<"1EA">>
+    ];
+
+cases(floats) ->
+    [
+        0.0,
+        0.00000001,
+        0.000000012,
+        0.0000000123,
+        0.0000001,
+        0.00000012,
+        0.000000123,
+        0.000001,
+        0.00001,
+        0.01,
+        0.0123,
+        0.1,
+        0.3,
+        1.0,
+        1.0e20,
+        1.0e21,
+        9.0,
+        10.0,
+        90.0,
+        90.12,
+        10000.0,
+        12345.0,
+        12345.0e23,
+        100000.0,
+        100000000000000000000.0,
+        111111111111111111111.0,
+        1111111111111111111111.0,
+        11111111111111111111111.0
+    ].

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_04_string_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_04_string_tests.erl b/test/jiffy_04_string_tests.erl
new file mode 100644
index 0000000..46f15ff
--- /dev/null
+++ b/test/jiffy_04_string_tests.erl
@@ -0,0 +1,147 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_04_string_tests).
+
+
+-include_lib("proper/include/proper.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include("jiffy_util.hrl").
+
+
+string_success_test_() ->
+    [gen(ok, Case) || Case <- cases(ok)].
+
+
+string_uescaped_test_() ->
+    [gen(uescaped, Case) || Case <- cases(uescaped)].
+
+
+string_error_test_() ->
+    [gen(error, Case) || Case <- cases(error)].
+
+
+string_utf8_test_() ->
+    [gen(utf8, Case) || Case <- cases(utf8)].
+
+
+gen(ok, {J, E}) ->
+    gen(ok, {J, E, J});
+gen(ok, {J1, E, J2}) ->
+    {msg("ok - ~s", [J1]), [
+        {"Decode", ?_assertEqual(E, dec(J1))},
+        {"Encode", ?_assertEqual(J2, enc(E))}
+    ]};
+
+gen(uescaped, {J, E}) ->
+    {msg("uescape - ~s", [J]), [
+        {"Decode", ?_assertEqual(E, dec(J))},
+        {"Encode", ?_assertEqual(J, enc(E, [uescape]))}
+    ]};
+
+gen(error, J) ->
+    {msg("error - ~s", [J]), [
+        ?_assertThrow({error, _}, dec(J))
+    ]};
+
+gen(utf8, {Case, Fixed}) ->
+    Case2 = <<34, Case/binary, 34>>,
+    Fixed2 = <<34, Fixed/binary, 34>>,
+    {msg("UTF-8: ~s", [hex(Case)]), [
+        ?_assertThrow({error, invalid_string}, jiffy:encode(Case)),
+        ?_assertEqual(Fixed2, jiffy:encode(Case, [force_utf8])),
+        ?_assertThrow({error, {_, invalid_string}}, jiffy:decode(Case2))
+    ]}.
+
+
+cases(ok) ->
+    [
+        {<<"\"\"">>, <<"">>},
+        {<<"\"/\"">>, <<"/">>},
+        {<<"\"0\"">>, <<"0">>},
+        {<<"\"foo\"">>, <<"foo">>},
+        {<<"\"\\\"foobar\\\"\"">>, <<"\"foobar\"">>},
+        {<<"\"\\n\\n\\n\"">>, <<"\n\n\n">>},
+        {<<"\"\\\" \\b\\f\\r\\n\\t\\\"\"">>, <<"\" \b\f\r\n\t\"">>},
+        {<<"\"foo\\u0005bar\"">>, <<"foo", 5, "bar">>},
+        {
+            <<"\"\\uD834\\uDD1E\"">>,
+            <<240, 157, 132, 158>>,
+            <<34, 240, 157, 132, 158, 34>>
+        },
+        {<<"\"\\uFFFF\"">>, <<239,191,191>>, <<34,239,191,191,34>>},
+        {<<"\"\\uFFFE\"">>, <<239,191,190>>, <<34,239,191,190,34>>}
+    ];
+
+cases(uescaped) ->
+    [
+        {
+            <<"\"\\u8CA8\\u5481\\u3002\\u0091\\u0091\"">>,
+            <<232,178,168,229,146,129,227,128,130,194,145,194,145>>
+        },
+        {
+            <<"\"\\uD834\\uDD1E\"">>,
+            <<240, 157, 132, 158>>
+        },
+        {
+            <<"\"\\uD83D\\uDE0A\"">>,
+            <<240, 159, 152, 138>>
+        }
+    ];
+
+cases(error) ->
+    [
+        "\"",
+        <<"\"foo">>,
+        <<"\"", 0, "\"">>,
+        <<"\"\\g\"">>,
+        <<"\"\\uD834foo\\uDD1E\"">>,
+        % CouchDB-345
+        <<34,78,69,73,77,69,78,32,70,216,82,82,32,70,65,69,78,33,34>>
+    ];
+
+cases(utf8) ->
+    [
+        % Stray continuation byte
+        {<<16#C2, 16#81, 16#80>>, <<16#C2, 16#81, 16#EF, 16#BF, 16#BD>>},
+        {<<"foo", 16#80, "bar">>, <<"foo", 16#EF, 16#BF, 16#BD, "bar">>},
+
+        % Not enough extension bytes
+        {<<16#C0>>, <<16#EF, 16#BF, 16#BD>>},
+
+        {<<16#E0>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#E0, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+
+        {<<16#F0>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#F0, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#F0, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+
+        {<<16#F8>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#F8, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#F8, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#F8, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+
+        {<<16#FC>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#FC, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#FC, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#FC, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#FC, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+
+        % No data in high bits.
+        {<<16#C0, 16#80>>, <<"\\u0000">>},
+        {<<16#C1, 16#80>>, <<"@">>},
+
+        {<<16#E0, 16#80, 16#80>>, <<"\\u0000">>},
+        {<<16#E0, 16#90, 16#80>>, <<16#D0, 16#80>>},
+
+        {<<16#F0, 16#80, 16#80, 16#80>>, <<"\\u0000">>},
+        {<<16#F0, 16#88, 16#80, 16#80>>, <<16#E8, 16#80, 16#80>>},
+
+        % UTF-8-like sequenecs of greater than 4 bytes
+        % aren't valid and are replaced with a single
+        % replacement 0xFFFD character.
+        {<<16#F8, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#F8, 16#84, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#FC, 16#80, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
+        {<<16#FC, 16#82, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>}
+    ].

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_05_array_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_05_array_tests.erl b/test/jiffy_05_array_tests.erl
new file mode 100644
index 0000000..6e9b717
--- /dev/null
+++ b/test/jiffy_05_array_tests.erl
@@ -0,0 +1,56 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_05_array_tests).
+
+
+-include_lib("proper/include/proper.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include("jiffy_util.hrl").
+
+
+array_success_test_() ->
+    [gen(ok, Case) || Case <- cases(ok)].
+
+
+array_failure_test_() ->
+    [gen(error, Case) || Case <- cases(error)].
+
+
+gen(ok, {J, E}) ->
+    gen(ok, {J, E, J});
+gen(ok, {J1, E, J2}) ->
+    {msg("~s", [J1]), [
+        {"Decode", ?_assertEqual(E, dec(J1))},
+        {"Encode", ?_assertEqual(J2, enc(E))}
+    ]};
+
+gen(error, J) ->
+    {msg("Error: ~s", [J]), [
+        ?_assertThrow({error, _}, dec(J))
+    ]}.
+
+
+cases(ok) ->
+    [
+        {<<"[]">>, []},
+        {<<"[\t[\n]\r]">>, [[]], <<"[[]]">>},
+        {<<"[\t123, \r true\n]">>, [123, true], <<"[123,true]">>},
+        {<<"[1,\"foo\"]">>, [1, <<"foo">>]},
+        {<<"[11993444355.0,1]">>, [11993444355.0,1]},
+        {
+            <<"[\"\\u00A1\",\"\\u00FC\"]">>,
+            [<<194, 161>>, <<195, 188>>],
+            <<"[\"", 194, 161, "\",\"", 195, 188, "\"]">>
+        }
+    ];
+
+cases(error) ->
+    [
+        <<"[">>,
+        <<"]">>,
+        <<"[,]">>,
+        <<"[123">>,
+        <<"[123,]">>,
+        <<"[32 true]">>
+    ].

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_06_object_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_06_object_tests.erl b/test/jiffy_06_object_tests.erl
new file mode 100644
index 0000000..7aec347
--- /dev/null
+++ b/test/jiffy_06_object_tests.erl
@@ -0,0 +1,56 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_06_object_tests).
+
+
+-include_lib("proper/include/proper.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include("jiffy_util.hrl").
+
+
+object_success_test_() ->
+    [gen(ok, Case) || Case <- cases(ok)].
+
+
+object_failure_test_() ->
+    [gen(error, Case) || Case <- cases(error)].
+
+
+gen(ok, {J, E}) ->
+    gen(ok, {J, E, J});
+gen(ok, {J1, E, J2}) ->
+    {msg("~s", [J1]), [
+        {"Decode", ?_assertEqual(E, dec(J1))},
+        {"Encode", ?_assertEqual(J2, enc(E))}
+    ]};
+
+gen(error, J) ->
+    {msg("Error: ~s", [J]), [
+        ?_assertThrow({error, _}, dec(J))
+    ]}.
+
+
+cases(ok) ->
+    [
+        {<<"{}">>, {[]}},
+        {<<"{\"foo\": \"bar\"}">>,
+            {[{<<"foo">>, <<"bar">>}]},
+            <<"{\"foo\":\"bar\"}">>},
+        {<<"\n\n{\"foo\":\r \"bar\",\n \"baz\"\t: 123 }">>,
+            {[{<<"foo">>, <<"bar">>}, {<<"baz">>, 123}]},
+            <<"{\"foo\":\"bar\",\"baz\":123}">>}
+    ];
+
+cases(error) ->
+    [
+        <<"{">>,
+        <<"{,}">>,
+        <<"{123:true}">>,
+        <<"{false:123}">>,
+        <<"{:\"stuff\"}">>,
+        <<"{\"key\":}">>,
+        <<"{\"key\": 123">>,
+        <<"{\"key\": 123 true">>,
+        <<"{\"key\": 123,}">>
+    ].

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_07_compound_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_07_compound_tests.erl b/test/jiffy_07_compound_tests.erl
new file mode 100644
index 0000000..7a968ab
--- /dev/null
+++ b/test/jiffy_07_compound_tests.erl
@@ -0,0 +1,61 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_07_compound_tests).
+
+
+-include_lib("proper/include/proper.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include("jiffy_util.hrl").
+
+
+compound_success_test_() ->
+    [gen(ok, Case) || Case <- cases(ok)].
+
+
+compound_failure_test_() ->
+    [gen(error, Case) || Case <- cases(error)].
+
+
+gen(ok, {J, E}) ->
+    gen(ok, {J, E, J});
+gen(ok, {J1, E, J2}) ->
+    {msg("~s", [J1]), [
+        {"Decode", ?_assertEqual(E, dec(J1))},
+        {"Encode", ?_assertEqual(J2, enc(E))}
+    ]};
+
+gen(error, J) ->
+    {msg("Error: ~s", [J]), [
+        ?_assertThrow({error, _}, dec(J))
+    ]}.
+
+
+cases(ok) ->
+    [
+        {<<"[{}]">>, [{[]}]},
+        {<<"{\"foo\":[123]}">>, {[{<<"foo">>, [123]}]}},
+        {<<"{\"foo\":{\"bar\":true}}">>,
+            {[{<<"foo">>, {[{<<"bar">>, true}]} }]} },
+        {<<"{\"foo\":[],\"bar\":{\"baz\":true},\"alice\":\"bob\"}">>,
+            {[
+                {<<"foo">>, []},
+                {<<"bar">>, {[{<<"baz">>, true}]}},
+                {<<"alice">>, <<"bob">>}
+            ]}
+        },
+        {<<"[-123,\"foo\",{\"bar\":[]},null]">>,
+            [
+                -123,
+                <<"foo">>,
+                {[{<<"bar">>, []}]},
+                null
+            ]
+        }
+    ];
+
+cases(error) ->
+    [
+        <<"[{}">>,
+        <<"}]">>
+    ].

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/11ab9738/test/jiffy_08_halfword_tests.erl
----------------------------------------------------------------------
diff --git a/test/jiffy_08_halfword_tests.erl b/test/jiffy_08_halfword_tests.erl
new file mode 100644
index 0000000..e18cd93
--- /dev/null
+++ b/test/jiffy_08_halfword_tests.erl
@@ -0,0 +1,16 @@
+% This file is part of Jiffy released under the MIT license.
+% See the LICENSE file for more information.
+
+-module(jiffy_08_halfword_tests).
+
+
+-include_lib("proper/include/proper.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include("jiffy_util.hrl").
+
+
+numerical_identity_test_() ->
+    [
+        {"1 == 1", ?_assert(jiffy:decode(<<"1">>) == 1)},
+        {"1 =:= 1", ?_assert(jiffy:decode(<<"1">>) =:= 1)}
+    ].