jsoniter_string_test.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // +build go1.8
  2. package jsoniter
  3. import (
  4. "bytes"
  5. "encoding/json"
  6. "fmt"
  7. "testing"
  8. "unicode/utf8"
  9. "github.com/stretchr/testify/require"
  10. )
  11. func Test_read_string(t *testing.T) {
  12. badInputs := []string{
  13. ``,
  14. `"`,
  15. `"\"`,
  16. `"\\\"`,
  17. "\"\n\"",
  18. `navy`,
  19. }
  20. for _, input := range badInputs {
  21. testReadString(t, input, "", true, "json.Unmarshal", json.Unmarshal)
  22. testReadString(t, input, "", true, "jsoniter.Unmarshal", Unmarshal)
  23. testReadString(t, input, "", true, "jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal", ConfigCompatibleWithStandardLibrary.Unmarshal)
  24. }
  25. goodInputs := []struct {
  26. input string
  27. expectValue string
  28. }{
  29. {`""`, ""},
  30. {`"a"`, "a"},
  31. {`null`, ""},
  32. {`"Iñtërnâtiônàlizætiøn,💝🐹🌇⛔"`, "Iñtërnâtiônàlizætiøn,💝🐹🌇⛔"},
  33. }
  34. for _, tc := range goodInputs {
  35. testReadString(t, tc.input, tc.expectValue, false, "json.Unmarshal", json.Unmarshal)
  36. testReadString(t, tc.input, tc.expectValue, false, "jsoniter.Unmarshal", Unmarshal)
  37. testReadString(t, tc.input, tc.expectValue, false, "jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal", ConfigCompatibleWithStandardLibrary.Unmarshal)
  38. }
  39. }
  40. func testReadString(t *testing.T, input string, expectValue string, expectError bool, marshalerName string, marshaler func([]byte, interface{}) error) {
  41. var value string
  42. err := marshaler([]byte(input), &value)
  43. if expectError != (err != nil) {
  44. t.Errorf("%q: %s: expected error %v, got %v", input, marshalerName, expectError, err)
  45. return
  46. }
  47. if value != expectValue {
  48. t.Errorf("%q: %s: expected %q, got %q", input, marshalerName, expectValue, value)
  49. return
  50. }
  51. }
  52. func Test_read_normal_string(t *testing.T) {
  53. cases := map[string]string{
  54. `"0123456789012345678901234567890123456789"`: `0123456789012345678901234567890123456789`,
  55. `""`: ``,
  56. `"hello"`: `hello`,
  57. }
  58. for input, output := range cases {
  59. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  60. should := require.New(t)
  61. iter := ParseString(ConfigDefault, input)
  62. should.Equal(output, iter.ReadString())
  63. })
  64. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  65. should := require.New(t)
  66. iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
  67. should.Equal(output, iter.ReadString())
  68. })
  69. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  70. should := require.New(t)
  71. iter := ParseString(ConfigDefault, input)
  72. should.Equal(output, string(iter.ReadStringAsSlice()))
  73. })
  74. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  75. should := require.New(t)
  76. iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
  77. should.Equal(output, string(iter.ReadStringAsSlice()))
  78. })
  79. }
  80. }
  81. func Test_read_exotic_string(t *testing.T) {
  82. cases := map[string]string{
  83. `"hel\"lo"`: `hel"lo`,
  84. `"hel\nlo"`: "hel\nlo",
  85. `"\u4e2d\u6587"`: "中文",
  86. `"\ud83d\udc4a"`: "\xf0\x9f\x91\x8a", // surrogate
  87. }
  88. for input, output := range cases {
  89. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  90. should := require.New(t)
  91. iter := ParseString(ConfigDefault, input)
  92. should.Equal(output, iter.ReadString())
  93. })
  94. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  95. should := require.New(t)
  96. iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
  97. should.Equal(output, iter.ReadString())
  98. })
  99. }
  100. }
  101. func Test_read_string_as_interface(t *testing.T) {
  102. should := require.New(t)
  103. iter := ParseString(ConfigDefault, `"hello"`)
  104. should.Equal("hello", iter.Read())
  105. }
  106. func Test_write_string(t *testing.T) {
  107. should := require.New(t)
  108. str, err := MarshalToString("hello")
  109. should.Equal(`"hello"`, str)
  110. should.Nil(err)
  111. str, err = MarshalToString(`hel"lo`)
  112. should.Equal(`"hel\"lo"`, str)
  113. should.Nil(err)
  114. }
  115. func Test_write_val_string(t *testing.T) {
  116. should := require.New(t)
  117. buf := &bytes.Buffer{}
  118. stream := NewStream(ConfigDefault, buf, 4096)
  119. stream.WriteVal("hello")
  120. stream.Flush()
  121. should.Nil(stream.Error)
  122. should.Equal(`"hello"`, buf.String())
  123. }
  124. func Test_decode_slash(t *testing.T) {
  125. should := require.New(t)
  126. var obj interface{}
  127. should.NotNil(json.Unmarshal([]byte("\\"), &obj))
  128. should.NotNil(UnmarshalFromString("\\", &obj))
  129. }
  130. func Test_html_escape(t *testing.T) {
  131. should := require.New(t)
  132. output, err := json.Marshal(`>`)
  133. should.Nil(err)
  134. should.Equal(`"\u003e"`, string(output))
  135. output, err = ConfigCompatibleWithStandardLibrary.Marshal(`>`)
  136. should.Nil(err)
  137. should.Equal(`"\u003e"`, string(output))
  138. type MyString string
  139. output, err = ConfigCompatibleWithStandardLibrary.Marshal(MyString(`>`))
  140. should.Nil(err)
  141. should.Equal(`"\u003e"`, string(output))
  142. }
  143. func Test_string_encode_with_std(t *testing.T) {
  144. should := require.New(t)
  145. for i := 0; i < utf8.RuneSelf; i++ {
  146. input := string([]byte{byte(i)})
  147. stdOutputBytes, err := json.Marshal(input)
  148. should.Nil(err)
  149. stdOutput := string(stdOutputBytes)
  150. jsoniterOutputBytes, err := ConfigCompatibleWithStandardLibrary.Marshal(input)
  151. should.Nil(err)
  152. jsoniterOutput := string(jsoniterOutputBytes)
  153. should.Equal(stdOutput, jsoniterOutput)
  154. }
  155. }
  156. func Test_unicode(t *testing.T) {
  157. should := require.New(t)
  158. output, _ := MarshalToString(map[string]interface{}{"a": "数字山谷"})
  159. should.Equal(`{"a":"数字山谷"}`, output)
  160. output, _ = Config{EscapeHTML: false}.Froze().MarshalToString(map[string]interface{}{"a": "数字山谷"})
  161. should.Equal(`{"a":"数字山谷"}`, output)
  162. }
  163. func Test_unicode_and_escape(t *testing.T) {
  164. should := require.New(t)
  165. output, err := MarshalToString(`"数字山谷"`)
  166. should.Nil(err)
  167. should.Equal(`"\"数字山谷\""`, output)
  168. output, err = ConfigFastest.MarshalToString(`"数字山谷"`)
  169. should.Nil(err)
  170. should.Equal(`"\"数字山谷\""`, output)
  171. }
  172. func Test_unsafe_unicode(t *testing.T) {
  173. ConfigDefault.(*frozenConfig).cleanEncoders()
  174. should := require.New(t)
  175. output, err := ConfigDefault.MarshalToString("he\u2029\u2028he")
  176. should.Nil(err)
  177. should.Equal(`"he\u2029\u2028he"`, output)
  178. output, err = ConfigFastest.MarshalToString("he\u2029\u2028he")
  179. should.Nil(err)
  180. should.Equal("\"he\u2029\u2028he\"", output)
  181. }
  182. func Benchmark_jsoniter_unicode(b *testing.B) {
  183. for n := 0; n < b.N; n++ {
  184. iter := ParseString(ConfigDefault, `"\ud83d\udc4a"`)
  185. iter.ReadString()
  186. }
  187. }
  188. func Benchmark_jsoniter_ascii(b *testing.B) {
  189. iter := NewIterator(ConfigDefault)
  190. input := []byte(`"hello, world! hello, world!"`)
  191. b.ResetTimer()
  192. for n := 0; n < b.N; n++ {
  193. iter.ResetBytes(input)
  194. iter.ReadString()
  195. }
  196. }
  197. func Benchmark_jsoniter_string_as_bytes(b *testing.B) {
  198. iter := ParseString(ConfigDefault, `"hello, world!"`)
  199. b.ResetTimer()
  200. for n := 0; n < b.N; n++ {
  201. iter.ResetBytes(iter.buf)
  202. iter.ReadStringAsSlice()
  203. }
  204. }
  205. func Benchmark_json_unicode(b *testing.B) {
  206. for n := 0; n < b.N; n++ {
  207. result := ""
  208. json.Unmarshal([]byte(`"\ud83d\udc4a"`), &result)
  209. }
  210. }
  211. func Benchmark_json_ascii(b *testing.B) {
  212. for n := 0; n < b.N; n++ {
  213. result := ""
  214. json.Unmarshal([]byte(`"hello"`), &result)
  215. }
  216. }