jsone_decode_tests.erl 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. %% Copyright (c) 2013, Takeru Ohta <phjgt308@gmail.com>
  2. -module(jsone_decode_tests).
  3. -include_lib("eunit/include/eunit.hrl").
  4. decode_test_() ->
  5. [
  6. %% シンボル系
  7. {"'false'がデコード可能",
  8. fun () ->
  9. ?assertEqual({ok, false, <<"">>}, jsone_decode:decode(<<"false">>))
  10. end},
  11. {"'true'がデコード可能",
  12. fun () ->
  13. ?assertEqual({ok, true, <<"">>}, jsone_decode:decode(<<"true">>))
  14. end},
  15. {"'null'がデコード可能",
  16. fun () ->
  17. ?assertEqual({ok, null, <<"">>}, jsone_decode:decode(<<"null">>))
  18. end},
  19. {"正の整数がデコード可能",
  20. fun () ->
  21. ?assertEqual({ok, 1, <<"">>}, jsone_decode:decode(<<"1">>))
  22. end},
  23. %% 数値系: 整数
  24. {"0がデコード可能",
  25. fun () ->
  26. ?assertEqual({ok, 0, <<"">>}, jsone_decode:decode(<<"0">>))
  27. end},
  28. {"負の整数がデコード可能",
  29. fun () ->
  30. ?assertEqual({ok, -1, <<"">>}, jsone_decode:decode(<<"-1">>))
  31. end},
  32. {"整数の値の大きさに制限はなし",
  33. fun () ->
  34. ?assertEqual({ok, 111111111111111111111111111111111111111111111111111111111111111111111111111111, <<"">>},
  35. jsone_decode:decode(<<"111111111111111111111111111111111111111111111111111111111111111111111111111111">>))
  36. end},
  37. {"先頭に余計な0がつく場合は、先頭文字とそれ以降が別々のトークンと判断される",
  38. fun () ->
  39. ?assertEqual({ok, 0, <<"0">>}, jsone_decode:decode(<<"00">>)),
  40. ?assertEqual({ok, 0, <<"1">>}, jsone_decode:decode(<<"01">>)),
  41. ?assertEqual({ok, 0, <<"1">>}, jsone_decode:decode(<<"-01">>))
  42. end},
  43. {"正の整数の前の'+'記号は許可されない",
  44. fun () ->
  45. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"+1">>))
  46. end},
  47. %% 数値系: 小数
  48. {"小数がデコード可能",
  49. fun () ->
  50. ?assertEqual({ok, 1.23, <<"">>}, jsone_decode:decode(<<"1.23">>))
  51. end},
  52. {"指数形式の小数がデコード可能",
  53. fun () ->
  54. ?assertEqual({ok, 12.345, <<"">>}, jsone_decode:decode(<<"12345e-3">>)),
  55. ?assertEqual({ok, 12.345, <<"">>}, jsone_decode:decode(<<"12345E-3">>)), % 'e'は大文字でも可
  56. ?assertEqual({ok, 12.345, <<"">>}, jsone_decode:decode(<<"12345.0e-3">>)),
  57. ?assertEqual({ok, 12.345, <<"">>}, jsone_decode:decode(<<"0.12345E2">>)),
  58. ?assertEqual({ok, 12.345, <<"">>}, jsone_decode:decode(<<"0.12345e+2">>)), % 指数部では'+'をつけても良い
  59. ?assertEqual({ok, 12.345, <<"">>}, jsone_decode:decode(<<"0.12345E+2">>)), % 指数部では'+'をつけても良い
  60. ?assertEqual({ok, -12.345, <<"">>}, jsone_decode:decode(<<"-0.012345e3">>))
  61. end},
  62. {"不正な形式の小数",
  63. fun () ->
  64. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<".123">>)), % 整数部が省略されている
  65. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"0.">>)), % '.'の後ろに小数部が続かない
  66. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"0.e+3">>)), % '.'の後ろに指数部が来る
  67. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"0.1e">>)), % 指数部が欠けている
  68. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"0.1e-">>)), % 指数部が欠けている
  69. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"0.1ee-1">>)), % 'e'が複数ある
  70. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"0.1e--1">>)), % 符号が複数ある
  71. ?assertEqual({ok, 0.1, <<".2">>}, jsone_decode:decode(<<"0.1.2">>)) % '.'が複数ある => 別々のトークンと判断される
  72. end},
  73. %% 文字列系
  74. {"文字列がデコード可能",
  75. fun () ->
  76. ?assertEqual({ok, <<"abc">>, <<"">>}, jsone_decode:decode(<<"\"abc\"">>))
  77. end},
  78. {"各種エスケープ文字がデコード可能",
  79. fun () ->
  80. Input = list_to_binary([$", [[$\\, C] || C <- [$", $/, $\\, $b, $f, $n, $r, $t]], $"]),
  81. Expected = <<"\"\/\\\b\f\n\r\t">>,
  82. ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
  83. end},
  84. {"エスケープされたUTF-16文字列がデコード可能",
  85. fun () ->
  86. %% 日本語
  87. Input1 = <<"\"\\u3042\\u3044\\u3046\\u3048\\u304A\"">>,
  88. Expected1 = <<"あいうえお">>, % このファイルの文字エンコーディングがUTF-8であることが前提
  89. ?assertEqual({ok, Expected1, <<"">>}, jsone_decode:decode(Input1)),
  90. %% ascii
  91. Input2 = <<"\"\\u0061\\u0062\\u0063\"">>,
  92. Expected2 = <<"abc">>,
  93. ?assertEqual({ok, Expected2, <<"">>}, jsone_decode:decode(Input2)),
  94. %% 日本語以外のマルチバイト文字
  95. Input3 = <<"\"\\u06DD\\u06DE\\u10AE\\u10AF\"">>,
  96. Expected3 = <<"۝۞ႮႯ">>,
  97. ?assertEqual({ok, Expected3, <<"">>}, jsone_decode:decode(Input3)),
  98. %% 日本語と英数字が混在
  99. Input4 = <<"\"a\\u30421\\u3044bb\\u304622\\u3048ccc\\u304A333\"">>,
  100. Expected4 = <<"aあ1いbbう22えcccお333">>, % このファイルの文字エンコーディングがUTF-8であることが前提
  101. ?assertEqual({ok, Expected4, <<"">>}, jsone_decode:decode(Input4))
  102. end},
  103. {"サロゲートペアを含む文字列がデコード可能",
  104. fun () ->
  105. Input = <<"\"\\ud848\\udc49\\ud848\\udc9a\\ud848\\udcfc\"">>,
  106. Expected = <<"𢁉𢂚𢃼">>,
  107. ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
  108. end},
  109. {"不正なエスケープ文字",
  110. fun () ->
  111. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"\"\\z\"">>)), % '\z'は未定義のエスケープ文字
  112. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"\"\\uab\"">>)), % '\u'の後ろに続く数値が足りない
  113. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"\"\\ud848\"">>)), % 上位サロゲートが単独で出現
  114. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"\"\\udc49\"">>)), % 下位サロゲーが単独で出現
  115. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(<<"\"\\ud848\\u0061\"">>)) % 上位サロゲートの後ろに下位サロゲートが続かない
  116. end},
  117. %% 配列系
  118. {"配列がデコード可能",
  119. fun () ->
  120. Input = <<"[1,2,\"abc\",null]">>,
  121. Expected = [1, 2, <<"abc">>, null],
  122. ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
  123. end},
  124. {"空白文字を含む配列がデコード可能",
  125. fun () ->
  126. Input = <<"[ 1,\t2, \n \"abc\",\r null]">>,
  127. Expected = [1, 2, <<"abc">>, null],
  128. ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
  129. end},
  130. {"空配列がデコード可能",
  131. fun () ->
  132. ?assertEqual({ok, [], <<"">>}, jsone_decode:decode(<<"[]">>)),
  133. ?assertEqual({ok, [], <<"">>}, jsone_decode:decode(<<"[ \t\r\n]">>))
  134. end},
  135. {"配列の末尾のカンマは許容されない",
  136. fun () ->
  137. Input = <<"[1, 2, \"abc\", null, ]">>,
  138. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  139. end},
  140. {"区切り文字のカンマが抜けているとエラーとなる",
  141. fun () ->
  142. Input = <<"[1 2, \"abc\", null]">>, % 1と2の間にカンマがない
  143. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  144. end},
  145. {"配列が閉じていないとエラー",
  146. fun () ->
  147. Input = <<"[1, 2, \"abc\", null">>,
  148. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  149. end},
  150. %% オブジェクト系
  151. {"オブジェクトがデコード可能",
  152. fun () ->
  153. Input = <<"{\"1\":2,\"key\":\"value\"}">>,
  154. Expected = {[{<<"key">>, <<"value">>}, {<<"1">>, 2}]},
  155. ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
  156. end},
  157. {"空白文字を含むオブジェクトがデコード可能",
  158. fun () ->
  159. Input = <<"{ \"1\" :\t 2,\n\r\"key\" : \n \"value\"}">>,
  160. Expected = {[{<<"key">>, <<"value">>}, {<<"1">>, 2}]},
  161. ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
  162. end},
  163. {"空オブジェクトがデコード可能",
  164. fun () ->
  165. ?assertEqual({ok, {[]}, <<"">>}, jsone_decode:decode(<<"{}">>)),
  166. ?assertEqual({ok, {[]}, <<"">>}, jsone_decode:decode(<<"{ \t\r\n}">>))
  167. end},
  168. {"オブジェクトの末尾のカンマは許容されない",
  169. fun () ->
  170. Input = <<"{\"1\":2, \"key\":\"value\", }">>,
  171. io:format("~p\n", [catch jsone_decode:decode(Input)]),
  172. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  173. end},
  174. {"区切り文字のカンマが抜けているとエラーとなる",
  175. fun () ->
  176. Input = <<"{\"1\":2 \"key\":\"value\"}">>,
  177. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  178. end},
  179. {"メンバのキーがない場合はエラー",
  180. fun () ->
  181. Input = <<"{:2, \"key\":\"value\"}">>,
  182. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  183. end},
  184. {"メンバのキーが文字列以外の場合はエラー",
  185. fun () ->
  186. Input = <<"{1:2, \"key\":\"value\"}">>,
  187. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  188. end},
  189. {"メンバの値がない場合はエラー",
  190. fun () ->
  191. Input = <<"{\"1\", \"key\":\"value\"}">>,
  192. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  193. end},
  194. {"オブジェクトが閉じていないとエラー",
  195. fun () ->
  196. Input = <<"{\"1\":2 \"key\":\"value\"">>,
  197. ?assertMatch({error, {badarg, _}}, jsone_decode:decode(Input))
  198. end},
  199. %% その他
  200. {"複雑なデータがデコード可能",
  201. fun () ->
  202. Input = <<" [true, {\"1\" : 2, \"array\":[[[[1]]], {\"ab\":\"cd\"}, false]}, null] ">>,
  203. Expected = [true, {[{<<"array">>, [[[[1]]], {[{<<"ab">>, <<"cd">>}]}, false]}, {<<"1">>, 2}]}, null],
  204. ?assertEqual({ok, Expected, <<" ">>}, jsone_decode:decode(Input))
  205. end}
  206. ].