Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

193 wiersze
5.7 KiB

  1. % This file is part of Jiffy released under the MIT license.
  2. % See the LICENSE file for more information.
  3. -module(jiffy_04_string_tests).
  4. -include_lib("eunit/include/eunit.hrl").
  5. -include("jiffy_util.hrl").
  6. latin1_atom_test_() ->
  7. Key = list_to_atom([228]), %% `ä`
  8. Expected = <<"{\"", 195, 164, "\":\"bar\"}">>,
  9. ?_assertEqual(Expected, jiffy:encode({[{Key, <<"bar">>}]})).
  10. string_success_test_() ->
  11. [gen(ok, Case) || Case <- cases(ok)].
  12. string_uescaped_test_() ->
  13. [gen(uescaped, Case) || Case <- cases(uescaped)].
  14. string_error_test_() ->
  15. [gen(error, Case) || Case <- cases(error)].
  16. string_utf8_test_() ->
  17. [gen(utf8, Case) || Case <- cases(utf8)].
  18. string_bad_utf8_key_test_() ->
  19. Cases = cases(bad_utf8_key),
  20. {{J}, {E}} = hd(Cases),
  21. ExtraProps = [{<<"abcdeefeadasffasdfa">>, I} || I <- lists:seq(1, 10000)],
  22. Big = {{ExtraProps ++ J}, {ExtraProps ++ E}},
  23. AllCases = [Big | Cases],
  24. [gen(bad_utf8_key, Case) || Case <- AllCases].
  25. string_escaped_slashes_test_() ->
  26. [gen(escaped_slashes, Case) || Case <- cases(escaped_slashes)].
  27. gen(ok, {J, E}) ->
  28. gen(ok, {J, E, J});
  29. gen(ok, {J1, E, J2}) ->
  30. {msg("ok - ~s", [J1]), [
  31. {"Decode", ?_assertEqual(E, dec(J1))},
  32. {"Encode", ?_assertEqual(J2, enc(E))}
  33. ]};
  34. gen(uescaped, {J, E}) ->
  35. {msg("uescape - ~s", [J]), [
  36. {"Decode", ?_assertEqual(E, dec(J))},
  37. {"Encode", ?_assertEqual(J, enc(E, [uescape]))}
  38. ]};
  39. gen(error, J) ->
  40. {msg("error - ~s", [J]), [
  41. ?_assertError(_, dec(J))
  42. ]};
  43. gen(utf8, {Case, Fixed}) ->
  44. Case2 = <<34, Case/binary, 34>>,
  45. Fixed2 = <<34, Fixed/binary, 34>>,
  46. {msg("UTF-8: ~s", [hex(Case)]), [
  47. ?_assertError({invalid_string, _}, enc(Case)),
  48. ?_assertEqual(Fixed2, enc(Case, [force_utf8])),
  49. ?_assertError({_, invalid_string}, dec(Case2))
  50. ]};
  51. gen(bad_utf8_key, {J, E}) ->
  52. {msg("Bad UTF-8 key: - ~p", [size(term_to_binary(J))]), [
  53. ?_assertError({invalid_object_member_key, _}, enc(J)),
  54. ?_assertEqual(E, dec(enc(J, [force_utf8])))
  55. ]};
  56. gen(escaped_slashes, {J, E}) ->
  57. {msg("escaped_slashes - ~s", [J]), [
  58. {"Decode", ?_assertEqual(E, dec(J))},
  59. {"Encode", ?_assertEqual(J, enc(E, [escape_forward_slashes]))}
  60. ]}.
  61. cases(ok) ->
  62. [
  63. {<<"\"\"">>, <<"">>},
  64. {<<"\"/\"">>, <<"/">>},
  65. {<<"\"0\"">>, <<"0">>},
  66. {<<"\"foo\"">>, <<"foo">>},
  67. {<<"\"\\\"foobar\\\"\"">>, <<"\"foobar\"">>},
  68. {<<"\"\\n\\n\\n\"">>, <<"\n\n\n">>},
  69. {<<"\"\\\" \\b\\f\\r\\n\\t\\\"\"">>, <<"\" \b\f\r\n\t\"">>},
  70. {<<"\"foo\\u0005bar\"">>, <<"foo", 5, "bar">>},
  71. {
  72. <<"\"\\uD834\\uDD1E\"">>,
  73. <<240, 157, 132, 158>>,
  74. <<34, 240, 157, 132, 158, 34>>
  75. },
  76. {<<"\"\\uFFFF\"">>, <<239,191,191>>, <<34,239,191,191,34>>},
  77. {<<"\"\\uFFFE\"">>, <<239,191,190>>, <<34,239,191,190,34>>}
  78. ];
  79. cases(uescaped) ->
  80. [
  81. {
  82. <<"\"\\u8CA8\\u5481\\u3002\\u0091\\u0091\"">>,
  83. <<232,178,168,229,146,129,227,128,130,194,145,194,145>>
  84. },
  85. {
  86. <<"\"\\uD834\\uDD1E\"">>,
  87. <<240, 157, 132, 158>>
  88. },
  89. {
  90. <<"\"\\uD83D\\uDE0A\"">>,
  91. <<240, 159, 152, 138>>
  92. },
  93. {
  94. <<"\"\\uDBFF\\uDFFF\"">>,
  95. <<244, 143, 191, 191>>
  96. }
  97. ];
  98. cases(error) ->
  99. [
  100. "\"",
  101. <<"\"foo">>,
  102. <<"\"", 0, "\"">>,
  103. <<"\"\\g\"">>,
  104. <<"\"\\uD834foo\\uDD1E\"">>,
  105. <<"\"\\u", 200, 200, 200, 200, "\"">>,
  106. % CouchDB-345
  107. <<34,78,69,73,77,69,78,32,70,216,82,82,32,70,65,69,78,33,34>>
  108. ];
  109. cases(utf8) ->
  110. [
  111. % Stray continuation byte
  112. {<<16#C2, 16#81, 16#80>>, <<16#C2, 16#81, 16#EF, 16#BF, 16#BD>>},
  113. {<<"foo", 16#80, "bar">>, <<"foo", 16#EF, 16#BF, 16#BD, "bar">>},
  114. % Not enough extension bytes
  115. {<<16#C0>>, <<16#EF, 16#BF, 16#BD>>},
  116. {<<16#E0>>, <<16#EF, 16#BF, 16#BD>>},
  117. {<<16#E0, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  118. {<<16#F0>>, <<16#EF, 16#BF, 16#BD>>},
  119. {<<16#F0, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  120. {<<16#F0, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  121. {<<16#F8>>, <<16#EF, 16#BF, 16#BD>>},
  122. {<<16#F8, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  123. {<<16#F8, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  124. {<<16#F8, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  125. {<<16#FC>>, <<16#EF, 16#BF, 16#BD>>},
  126. {<<16#FC, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  127. {<<16#FC, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  128. {<<16#FC, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  129. {<<16#FC, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  130. % No data in high bits.
  131. {<<16#C0, 16#80>>, <<"\\u0000">>},
  132. {<<16#C1, 16#80>>, <<"@">>},
  133. {<<16#E0, 16#80, 16#80>>, <<"\\u0000">>},
  134. {<<16#E0, 16#90, 16#80>>, <<16#D0, 16#80>>},
  135. {<<16#F0, 16#80, 16#80, 16#80>>, <<"\\u0000">>},
  136. {<<16#F0, 16#88, 16#80, 16#80>>, <<16#E8, 16#80, 16#80>>},
  137. % UTF-8-like sequenecs of greater than 4 bytes
  138. % aren't valid and are replaced with a single
  139. % replacement 0xFFFD character.
  140. {<<16#F8, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  141. {<<16#F8, 16#84, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  142. {<<16#FC, 16#80, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
  143. {<<16#FC, 16#82, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>}
  144. ];
  145. cases(bad_utf8_key) ->
  146. [
  147. {
  148. {[{<<"foo", 16#80, "bar">>, true}]},
  149. {[{<<"foo", 16#EF, 16#BF, 16#BD, "bar">>, true}]}
  150. }
  151. ];
  152. cases(escaped_slashes) ->
  153. [
  154. {<<"\"\\/\"">>, <<"/">>}
  155. ].