% 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>>}
|
|
].
|