You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

354 lines
8.3 KiB

  1. // Copyright 2010 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package fastjson
  5. import (
  6. "bytes"
  7. "io"
  8. "io/ioutil"
  9. "log"
  10. "net"
  11. "net/http"
  12. "net/http/httptest"
  13. "reflect"
  14. "strings"
  15. "testing"
  16. )
  17. // Test values for the stream test.
  18. // One of each JSON kind.
  19. var streamTest = []interface{}{
  20. 0.1,
  21. "hello",
  22. nil,
  23. true,
  24. false,
  25. []interface{}{"a", "b", "c"},
  26. map[string]interface{}{"K": "Kelvin", "ß": "long s"},
  27. 3.14, // another value to make sure something can follow map
  28. }
  29. var streamEncoded = `0.1
  30. "hello"
  31. null
  32. true
  33. false
  34. ["a","b","c"]
  35. {"ß":"long s","K":"Kelvin"}
  36. 3.14
  37. `
  38. func TestEncoder(t *testing.T) {
  39. for i := 0; i <= len(streamTest); i++ {
  40. var buf bytes.Buffer
  41. enc := NewEncoder(&buf)
  42. for j, v := range streamTest[0:i] {
  43. if err := enc.Encode(v); err != nil {
  44. t.Fatalf("encode #%d: %v", j, err)
  45. }
  46. }
  47. if have, want := buf.String(), nlines(streamEncoded, i); have != want {
  48. t.Errorf("encoding %d items: mismatch", i)
  49. diff(t, []byte(have), []byte(want))
  50. break
  51. }
  52. }
  53. }
  54. func TestDecoder(t *testing.T) {
  55. for i := 0; i <= len(streamTest); i++ {
  56. // Use stream without newlines as input,
  57. // just to stress the decoder even more.
  58. // Our test input does not include back-to-back numbers.
  59. // Otherwise stripping the newlines would
  60. // merge two adjacent JSON values.
  61. var buf bytes.Buffer
  62. for _, c := range nlines(streamEncoded, i) {
  63. if c != '\n' {
  64. buf.WriteRune(c)
  65. }
  66. }
  67. out := make([]interface{}, i)
  68. dec := NewDecoder(&buf)
  69. for j := range out {
  70. if err := dec.Decode(&out[j]); err != nil {
  71. t.Fatalf("decode #%d/%d: %v", j, i, err)
  72. }
  73. }
  74. if !reflect.DeepEqual(out, streamTest[0:i]) {
  75. t.Errorf("decoding %d items: mismatch", i)
  76. for j := range out {
  77. if !reflect.DeepEqual(out[j], streamTest[j]) {
  78. t.Errorf("#%d: have %v want %v", j, out[j], streamTest[j])
  79. }
  80. }
  81. break
  82. }
  83. }
  84. }
  85. func TestDecoderBuffered(t *testing.T) {
  86. r := strings.NewReader(`{"Name": "Gopher"} extra `)
  87. var m struct {
  88. Name string
  89. }
  90. d := NewDecoder(r)
  91. err := d.Decode(&m)
  92. if err != nil {
  93. t.Fatal(err)
  94. }
  95. if m.Name != "Gopher" {
  96. t.Errorf("Name = %q; want Gopher", m.Name)
  97. }
  98. rest, err := ioutil.ReadAll(d.Buffered())
  99. if err != nil {
  100. t.Fatal(err)
  101. }
  102. if g, w := string(rest), " extra "; g != w {
  103. t.Errorf("Remaining = %q; want %q", g, w)
  104. }
  105. }
  106. func nlines(s string, n int) string {
  107. if n <= 0 {
  108. return ""
  109. }
  110. for i, c := range s {
  111. if c == '\n' {
  112. if n--; n == 0 {
  113. return s[0 : i+1]
  114. }
  115. }
  116. }
  117. return s
  118. }
  119. func TestRawMessage(t *testing.T) {
  120. // TODO(rsc): Should not need the * in *RawMessage
  121. var data struct {
  122. X float64
  123. Id *RawMessage
  124. Y float32
  125. }
  126. const raw = `["\u0056",null]`
  127. const msg = `{"X":0.1,"Id":["\u0056",null],"Y":0.2}`
  128. err := Unmarshal([]byte(msg), &data)
  129. if err != nil {
  130. t.Fatalf("Unmarshal: %v", err)
  131. }
  132. if string([]byte(*data.Id)) != raw {
  133. t.Fatalf("Raw mismatch: have %#q want %#q", []byte(*data.Id), raw)
  134. }
  135. b, err := Marshal(&data)
  136. if err != nil {
  137. t.Fatalf("Marshal: %v", err)
  138. }
  139. if string(b) != msg {
  140. t.Fatalf("Marshal: have %#q want %#q", b, msg)
  141. }
  142. }
  143. func TestNullRawMessage(t *testing.T) {
  144. // TODO(rsc): Should not need the * in *RawMessage
  145. var data struct {
  146. X float64
  147. Id *RawMessage
  148. Y float32
  149. }
  150. data.Id = new(RawMessage)
  151. const msg = `{"X":0.1,"Id":null,"Y":0.2}`
  152. err := Unmarshal([]byte(msg), &data)
  153. if err != nil {
  154. t.Fatalf("Unmarshal: %v", err)
  155. }
  156. if data.Id != nil {
  157. t.Fatalf("Raw mismatch: have non-nil, want nil")
  158. }
  159. b, err := Marshal(&data)
  160. if err != nil {
  161. t.Fatalf("Marshal: %v", err)
  162. }
  163. if string(b) != msg {
  164. t.Fatalf("Marshal: have %#q want %#q", b, msg)
  165. }
  166. }
  167. var blockingTests = []string{
  168. `{"x": 1}`,
  169. `[1, 2, 3]`,
  170. }
  171. func TestBlocking(t *testing.T) {
  172. for _, enc := range blockingTests {
  173. r, w := net.Pipe()
  174. go w.Write([]byte(enc))
  175. var val interface{}
  176. // If Decode reads beyond what w.Write writes above,
  177. // it will block, and the test will deadlock.
  178. if err := NewDecoder(r).Decode(&val); err != nil {
  179. t.Errorf("decoding %s: %v", enc, err)
  180. }
  181. r.Close()
  182. w.Close()
  183. }
  184. }
  185. func BenchmarkEncoderEncode(b *testing.B) {
  186. b.ReportAllocs()
  187. type T struct {
  188. X, Y string
  189. }
  190. v := &T{"foo", "bar"}
  191. for i := 0; i < b.N; i++ {
  192. if err := NewEncoder(ioutil.Discard).Encode(v); err != nil {
  193. b.Fatal(err)
  194. }
  195. }
  196. }
  197. type tokenStreamCase struct {
  198. json string
  199. expTokens []interface{}
  200. }
  201. type decodeThis struct {
  202. v interface{}
  203. }
  204. var tokenStreamCases []tokenStreamCase = []tokenStreamCase{
  205. // streaming token cases
  206. {json: `10`, expTokens: []interface{}{float64(10)}},
  207. {json: ` [10] `, expTokens: []interface{}{
  208. Delim('['), float64(10), Delim(']')}},
  209. {json: ` [false,10,"b"] `, expTokens: []interface{}{
  210. Delim('['), false, float64(10), "b", Delim(']')}},
  211. {json: `{ "a": 1 }`, expTokens: []interface{}{
  212. Delim('{'), "a", float64(1), Delim('}')}},
  213. {json: `{"a": 1, "b":"3"}`, expTokens: []interface{}{
  214. Delim('{'), "a", float64(1), "b", "3", Delim('}')}},
  215. {json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
  216. Delim('['),
  217. Delim('{'), "a", float64(1), Delim('}'),
  218. Delim('{'), "a", float64(2), Delim('}'),
  219. Delim(']')}},
  220. {json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
  221. Delim('{'), "obj", Delim('{'), "a", float64(1), Delim('}'),
  222. Delim('}')}},
  223. {json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
  224. Delim('{'), "obj", Delim('['),
  225. Delim('{'), "a", float64(1), Delim('}'),
  226. Delim(']'), Delim('}')}},
  227. // streaming tokens with intermittent Decode()
  228. {json: `{ "a": 1 }`, expTokens: []interface{}{
  229. Delim('{'), "a",
  230. decodeThis{float64(1)},
  231. Delim('}')}},
  232. {json: ` [ { "a" : 1 } ] `, expTokens: []interface{}{
  233. Delim('['),
  234. decodeThis{map[string]interface{}{"a": float64(1)}},
  235. Delim(']')}},
  236. {json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
  237. Delim('['),
  238. decodeThis{map[string]interface{}{"a": float64(1)}},
  239. decodeThis{map[string]interface{}{"a": float64(2)}},
  240. Delim(']')}},
  241. {json: `{ "obj" : [ { "a" : 1 } ] }`, expTokens: []interface{}{
  242. Delim('{'), "obj", Delim('['),
  243. decodeThis{map[string]interface{}{"a": float64(1)}},
  244. Delim(']'), Delim('}')}},
  245. {json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
  246. Delim('{'), "obj",
  247. decodeThis{map[string]interface{}{"a": float64(1)}},
  248. Delim('}')}},
  249. {json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
  250. Delim('{'), "obj",
  251. decodeThis{[]interface{}{
  252. map[string]interface{}{"a": float64(1)},
  253. }},
  254. Delim('}')}},
  255. {json: ` [{"a": 1} {"a": 2}] `, expTokens: []interface{}{
  256. Delim('['),
  257. decodeThis{map[string]interface{}{"a": float64(1)}},
  258. decodeThis{&SyntaxError{"expected comma after array element", 0}},
  259. }},
  260. {json: `{ "a" 1 }`, expTokens: []interface{}{
  261. Delim('{'), "a",
  262. decodeThis{&SyntaxError{"expected colon after object key", 0}},
  263. }},
  264. }
  265. func TestDecodeInStream(t *testing.T) {
  266. for ci, tcase := range tokenStreamCases {
  267. dec := NewDecoder(strings.NewReader(tcase.json))
  268. for i, etk := range tcase.expTokens {
  269. var tk interface{}
  270. var err error
  271. if dt, ok := etk.(decodeThis); ok {
  272. etk = dt.v
  273. err = dec.Decode(&tk)
  274. } else {
  275. tk, err = dec.Token()
  276. }
  277. if experr, ok := etk.(error); ok {
  278. if err == nil || err.Error() != experr.Error() {
  279. t.Errorf("case %v: Expected error %v in %q, but was %v", ci, experr, tcase.json, err)
  280. }
  281. break
  282. } else if err == io.EOF {
  283. t.Errorf("case %v: Unexpected EOF in %q", ci, tcase.json)
  284. break
  285. } else if err != nil {
  286. t.Errorf("case %v: Unexpected error '%v' in %q", ci, err, tcase.json)
  287. break
  288. }
  289. if !reflect.DeepEqual(tk, etk) {
  290. t.Errorf(`case %v: %q @ %v expected %T(%v) was %T(%v)`, ci, tcase.json, i, etk, etk, tk, tk)
  291. break
  292. }
  293. }
  294. }
  295. }
  296. // Test from golang.org/issue/11893
  297. func TestHTTPDecoding(t *testing.T) {
  298. const raw = `{ "foo": "bar" }`
  299. ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  300. w.Write([]byte(raw))
  301. }))
  302. defer ts.Close()
  303. res, err := http.Get(ts.URL)
  304. if err != nil {
  305. log.Fatalf("GET failed: %v", err)
  306. }
  307. defer res.Body.Close()
  308. foo := struct {
  309. Foo string
  310. }{}
  311. d := NewDecoder(res.Body)
  312. err = d.Decode(&foo)
  313. if err != nil {
  314. t.Fatalf("Decode: %v", err)
  315. }
  316. if foo.Foo != "bar" {
  317. t.Errorf("decoded %q; want \"bar\"", foo.Foo)
  318. }
  319. // make sure we get the EOF the second time
  320. err = d.Decode(&foo)
  321. if err != io.EOF {
  322. t.Errorf("err = %v; want io.EOF", err)
  323. }
  324. }