github.com/qiniu/dyn@v1.3.0/text/internal/encoding/json/stream_test.go (about) 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 5 package json 6 7 import ( 8 "bytes" 9 "reflect" 10 "testing" 11 ) 12 13 // Test values for the stream test. 14 // One of each JSON kind. 15 var streamTest = []interface{}{ 16 0.1, 17 "hello", 18 nil, 19 true, 20 false, 21 []interface{}{"a", "b", "c"}, 22 map[string]interface{}{"K": "Kelvin", "ß": "long s"}, 23 3.14, // another value to make sure something can follow map 24 } 25 26 var streamEncoded = `0.1 27 "hello" 28 null 29 true 30 false 31 ["a","b","c"] 32 {"ß":"long s","K":"Kelvin"} 33 3.14 34 ` 35 36 func TestEncoder(t *testing.T) { 37 for i := 0; i <= len(streamTest); i++ { 38 var buf bytes.Buffer 39 enc := NewEncoder(&buf) 40 for j, v := range streamTest[0:i] { 41 if err := enc.Encode(v); err != nil { 42 t.Fatalf("encode #%d: %v", j, err) 43 } 44 } 45 if have, want := buf.String(), nlines(streamEncoded, i); have != want { 46 t.Errorf("encoding %d items: mismatch", i) 47 diff(t, []byte(have), []byte(want)) 48 break 49 } 50 } 51 } 52 53 func TestDecoder(t *testing.T) { 54 for i := 0; i <= len(streamTest); i++ { 55 // Use stream without newlines as input, 56 // just to stress the decoder even more. 57 // Our test input does not include back-to-back numbers. 58 // Otherwise stripping the newlines would 59 // merge two adjacent JSON values. 60 var buf bytes.Buffer 61 for _, c := range nlines(streamEncoded, i) { 62 if c != '\n' { 63 buf.WriteRune(c) 64 } 65 } 66 out := make([]interface{}, i) 67 dec := NewDecoder(&buf) 68 for j := range out { 69 if err := dec.Decode(&out[j]); err != nil { 70 t.Fatalf("decode #%d/%d: %v", j, i, err) 71 } 72 } 73 if !reflect.DeepEqual(out, streamTest[0:i]) { 74 t.Errorf("decoding %d items: mismatch", i) 75 for j := range out { 76 if !reflect.DeepEqual(out[j], streamTest[j]) { 77 t.Errorf("#%d: have %v want %v", j, out[j], streamTest[j]) 78 } 79 } 80 break 81 } 82 } 83 } 84 85 func nlines(s string, n int) string { 86 if n <= 0 { 87 return "" 88 } 89 for i, c := range s { 90 if c == '\n' { 91 if n--; n == 0 { 92 return s[0 : i+1] 93 } 94 } 95 } 96 return s 97 } 98 99 func TestRawMessage(t *testing.T) { 100 // TODO(rsc): Should not need the * in *RawMessage 101 var data struct { 102 X float64 103 Id *RawMessage 104 Y float32 105 } 106 const raw = `["\u0056",null]` 107 const msg = `{"X":0.1,"Id":["\u0056",null],"Y":0.2}` 108 err := Unmarshal([]byte(msg), &data) 109 if err != nil { 110 t.Fatalf("Unmarshal: %v", err) 111 } 112 if string([]byte(*data.Id)) != raw { 113 t.Fatalf("Raw mismatch: have %#q want %#q", []byte(*data.Id), raw) 114 } 115 b, err := Marshal(&data) 116 if err != nil { 117 t.Fatalf("Marshal: %v", err) 118 } 119 if string(b) != msg { 120 t.Fatalf("Marshal: have %#q want %#q", b, msg) 121 } 122 } 123 124 func TestNullRawMessage(t *testing.T) { 125 // TODO(rsc): Should not need the * in *RawMessage 126 var data struct { 127 X float64 128 Id *RawMessage 129 Y float32 130 } 131 data.Id = new(RawMessage) 132 const msg = `{"X":0.1,"Id":null,"Y":0.2}` 133 err := Unmarshal([]byte(msg), &data) 134 if err != nil { 135 t.Fatalf("Unmarshal: %v", err) 136 } 137 if data.Id != nil { 138 t.Fatalf("Raw mismatch: have non-nil, want nil") 139 } 140 b, err := Marshal(&data) 141 if err != nil { 142 t.Fatalf("Marshal: %v", err) 143 } 144 if string(b) != msg { 145 t.Fatalf("Marshal: have %#q want %#q", b, msg) 146 } 147 }