- % 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("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)].
-
-
- string_bad_utf8_key_test_() ->
- Cases = cases(bad_utf8_key),
- {{J}, {E}} = hd(Cases),
- ExtraProps = [{<<"abcdeefeadasffasdfa">>, I} || I <- lists:seq(1, 10000)],
- Big = {{ExtraProps ++ J}, {ExtraProps ++ E}},
- AllCases = [Big | Cases],
- [gen(bad_utf8_key, Case) || Case <- AllCases].
-
-
- string_escaped_slashes_test_() ->
- [gen(escaped_slashes, Case) || Case <- cases(escaped_slashes)].
-
- 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))
- ]};
-
- gen(bad_utf8_key, {J, E}) ->
- {msg("Bad UTF-8 key: - ~p", [size(term_to_binary(J))]), [
- ?_assertThrow({error, {invalid_object_member_key, _}}, jiffy:encode(J)),
- ?_assertEqual(E, jiffy:decode(jiffy:encode(J, [force_utf8])))
- ]};
-
- gen(escaped_slashes, {J, E}) ->
- {msg("escaped_slashes - ~s", [J]), [
- {"Decode", ?_assertEqual(E, dec(J))},
- {"Encode", ?_assertEqual(J, enc(E, [escape_forward_slashes]))}
- ]}.
-
- 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>>}
- ];
-
- cases(bad_utf8_key) ->
- [
- {
- {[{<<"foo", 16#80, "bar">>, true}]},
- {[{<<"foo", 16#EF, 16#BF, 16#BD, "bar">>, true}]}
- }
- ];
-
- cases(escaped_slashes) ->
- [
- {<<"\"\\/\"">>, <<"/">>}
- ].
|