jsoniter_string_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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_normal_string(t *testing.T) {
  12. cases := map[string]string{
  13. `"0123456789012345678901234567890123456789"`: `0123456789012345678901234567890123456789`,
  14. `""`: ``,
  15. `"hello"`: `hello`,
  16. }
  17. for input, output := range cases {
  18. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  19. should := require.New(t)
  20. iter := ParseString(ConfigDefault, input)
  21. should.Equal(output, iter.ReadString())
  22. })
  23. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  24. should := require.New(t)
  25. iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
  26. should.Equal(output, iter.ReadString())
  27. })
  28. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  29. should := require.New(t)
  30. iter := ParseString(ConfigDefault, input)
  31. should.Equal(output, string(iter.ReadStringAsSlice()))
  32. })
  33. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  34. should := require.New(t)
  35. iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
  36. should.Equal(output, string(iter.ReadStringAsSlice()))
  37. })
  38. }
  39. }
  40. func Test_read_exotic_string(t *testing.T) {
  41. cases := map[string]string{
  42. `"hel\"lo"`: `hel"lo`,
  43. `"hel\\\/lo"`: `hel\/lo`,
  44. `"hel\\blo"`: `hel\blo`,
  45. `"hel\\\blo"`: "hel\\\blo",
  46. `"hel\\nlo"`: `hel\nlo`,
  47. `"hel\\\nlo"`: "hel\\\nlo",
  48. `"hel\\tlo"`: `hel\tlo`,
  49. `"hel\\flo"`: `hel\flo`,
  50. `"hel\\\flo"`: "hel\\\flo",
  51. `"hel\\\rlo"`: "hel\\\rlo",
  52. `"hel\\\tlo"`: "hel\\\tlo",
  53. `"\u4e2d\u6587"`: "中文",
  54. `"\ud83d\udc4a"`: "\xf0\x9f\x91\x8a", // surrogate
  55. }
  56. for input, output := range cases {
  57. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  58. should := require.New(t)
  59. iter := ParseString(ConfigDefault, input)
  60. should.Equal(output, iter.ReadString())
  61. })
  62. t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
  63. should := require.New(t)
  64. iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
  65. should.Equal(output, iter.ReadString())
  66. })
  67. }
  68. }
  69. func Test_read_string_as_interface(t *testing.T) {
  70. should := require.New(t)
  71. iter := ParseString(ConfigDefault, `"hello"`)
  72. should.Equal("hello", iter.Read())
  73. }
  74. func Test_write_string(t *testing.T) {
  75. should := require.New(t)
  76. str, err := MarshalToString("hello")
  77. should.Equal(`"hello"`, str)
  78. should.Nil(err)
  79. str, err = MarshalToString(`hel"lo`)
  80. should.Equal(`"hel\"lo"`, str)
  81. should.Nil(err)
  82. }
  83. func Test_write_val_string(t *testing.T) {
  84. should := require.New(t)
  85. buf := &bytes.Buffer{}
  86. stream := NewStream(ConfigDefault, buf, 4096)
  87. stream.WriteVal("hello")
  88. stream.Flush()
  89. should.Nil(stream.Error)
  90. should.Equal(`"hello"`, buf.String())
  91. }
  92. func Test_decode_slash(t *testing.T) {
  93. should := require.New(t)
  94. var obj interface{}
  95. should.NotNil(json.Unmarshal([]byte("\\"), &obj))
  96. should.NotNil(UnmarshalFromString("\\", &obj))
  97. }
  98. func Test_html_escape(t *testing.T) {
  99. should := require.New(t)
  100. output, err := json.Marshal(`>`)
  101. should.Nil(err)
  102. should.Equal(`"\u003e"`, string(output))
  103. output, err = ConfigCompatibleWithStandardLibrary.Marshal(`>`)
  104. should.Nil(err)
  105. should.Equal(`"\u003e"`, string(output))
  106. type MyString string
  107. output, err = ConfigCompatibleWithStandardLibrary.Marshal(MyString(`>`))
  108. should.Nil(err)
  109. should.Equal(`"\u003e"`, string(output))
  110. }
  111. func Test_string_encode_with_std(t *testing.T) {
  112. should := require.New(t)
  113. for i := 0; i < utf8.RuneSelf; i++ {
  114. input := string([]byte{byte(i)})
  115. stdOutputBytes, err := json.Marshal(input)
  116. should.Nil(err)
  117. stdOutput := string(stdOutputBytes)
  118. jsoniterOutputBytes, err := ConfigCompatibleWithStandardLibrary.Marshal(input)
  119. should.Nil(err)
  120. jsoniterOutput := string(jsoniterOutputBytes)
  121. should.Equal(stdOutput, jsoniterOutput)
  122. }
  123. }
  124. func Test_unicode(t *testing.T) {
  125. should := require.New(t)
  126. output, _ := MarshalToString(map[string]interface{}{"a": "数字山谷"})
  127. should.Equal(`{"a":"数字山谷"}`, output)
  128. output, _ = Config{EscapeHtml: false}.Froze().MarshalToString(map[string]interface{}{"a": "数字山谷"})
  129. should.Equal(`{"a":"数字山谷"}`, output)
  130. }
  131. func Test_unicode_and_escape(t *testing.T) {
  132. should := require.New(t)
  133. output, err := MarshalToString(`"数字山谷"`)
  134. should.Nil(err)
  135. should.Equal(`"\"数字山谷\""`, output)
  136. output, err = ConfigFastest.MarshalToString(`"数字山谷"`)
  137. should.Nil(err)
  138. should.Equal(`"\"数字山谷\""`, output)
  139. }
  140. func Test_unsafe_unicode(t *testing.T) {
  141. ConfigDefault.cleanEncoders()
  142. should := require.New(t)
  143. output, err := ConfigDefault.MarshalToString("he\u2029\u2028he")
  144. should.Nil(err)
  145. should.Equal(`"he\u2029\u2028he"`, output)
  146. output, err = ConfigFastest.MarshalToString("he\u2029\u2028he")
  147. should.Nil(err)
  148. should.Equal("\"he\u2029\u2028he\"", output)
  149. }
  150. func Benchmark_jsoniter_unicode(b *testing.B) {
  151. for n := 0; n < b.N; n++ {
  152. iter := ParseString(ConfigDefault, `"\ud83d\udc4a"`)
  153. iter.ReadString()
  154. }
  155. }
  156. func Benchmark_jsoniter_ascii(b *testing.B) {
  157. iter := NewIterator(ConfigDefault)
  158. input := []byte(`"hello, world! hello, world!"`)
  159. b.ResetTimer()
  160. for n := 0; n < b.N; n++ {
  161. iter.ResetBytes(input)
  162. iter.ReadString()
  163. }
  164. }
  165. func Benchmark_jsoniter_string_as_bytes(b *testing.B) {
  166. iter := ParseString(ConfigDefault, `"hello, world!"`)
  167. b.ResetTimer()
  168. for n := 0; n < b.N; n++ {
  169. iter.ResetBytes(iter.buf)
  170. iter.ReadStringAsSlice()
  171. }
  172. }
  173. func Benchmark_json_unicode(b *testing.B) {
  174. for n := 0; n < b.N; n++ {
  175. result := ""
  176. json.Unmarshal([]byte(`"\ud83d\udc4a"`), &result)
  177. }
  178. }
  179. func Benchmark_json_ascii(b *testing.B) {
  180. for n := 0; n < b.N; n++ {
  181. result := ""
  182. json.Unmarshal([]byte(`"hello"`), &result)
  183. }
  184. }