github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/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  	"io/ioutil"
    10  	"net"
    11  	"reflect"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  // Test values for the stream test.
    17  // One of each JSON kind.
    18  var streamTest = []interface{}{
    19  	0.1,
    20  	"hello",
    21  	nil,
    22  	true,
    23  	false,
    24  	[]interface{}{"a", "b", "c"},
    25  	map[string]interface{}{"K": "Kelvin", "ß": "long s"},
    26  	3.14, // another value to make sure something can follow map
    27  }
    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  
    39  func TestEncoder(t *testing.T) {
    40  	for i := 0; i <= len(streamTest); i++ {
    41  		var buf bytes.Buffer
    42  		enc := NewEncoder(&buf)
    43  		for j, v := range streamTest[0:i] {
    44  			if err := enc.Encode(v); err != nil {
    45  				t.Fatalf("encode #%d: %v", j, err)
    46  			}
    47  		}
    48  		if have, want := buf.String(), nlines(streamEncoded, i); have != want {
    49  			t.Errorf("encoding %d items: mismatch", i)
    50  			diff(t, []byte(have), []byte(want))
    51  			break
    52  		}
    53  	}
    54  }
    55  
    56  func TestDecoder(t *testing.T) {
    57  	for i := 0; i <= len(streamTest); i++ {
    58  		// Use stream without newlines as input,
    59  		// just to stress the decoder even more.
    60  		// Our test input does not include back-to-back numbers.
    61  		// Otherwise stripping the newlines would
    62  		// merge two adjacent JSON values.
    63  		var buf bytes.Buffer
    64  		for _, c := range nlines(streamEncoded, i) {
    65  			if c != '\n' {
    66  				buf.WriteRune(c)
    67  			}
    68  		}
    69  		out := make([]interface{}, i)
    70  		dec := NewDecoder(&buf)
    71  		for j := range out {
    72  			if err := dec.Decode(&out[j]); err != nil {
    73  				t.Fatalf("decode #%d/%d: %v", j, i, err)
    74  			}
    75  		}
    76  		if !reflect.DeepEqual(out, streamTest[0:i]) {
    77  			t.Errorf("decoding %d items: mismatch", i)
    78  			for j := range out {
    79  				if !reflect.DeepEqual(out[j], streamTest[j]) {
    80  					t.Errorf("#%d: have %v want %v", j, out[j], streamTest[j])
    81  				}
    82  			}
    83  			break
    84  		}
    85  	}
    86  }
    87  
    88  func TestDecoderBuffered(t *testing.T) {
    89  	r := strings.NewReader(`{"Name": "Gopher"} extra `)
    90  	var m struct {
    91  		Name string
    92  	}
    93  	d := NewDecoder(r)
    94  	err := d.Decode(&m)
    95  	if err != nil {
    96  		t.Fatal(err)
    97  	}
    98  	if m.Name != "Gopher" {
    99  		t.Errorf("Name = %q; want Gopher", m.Name)
   100  	}
   101  	rest, err := ioutil.ReadAll(d.Buffered())
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  	if g, w := string(rest), " extra "; g != w {
   106  		t.Errorf("Remaining = %q; want %q", g, w)
   107  	}
   108  }
   109  
   110  func nlines(s string, n int) string {
   111  	if n <= 0 {
   112  		return ""
   113  	}
   114  	for i, c := range s {
   115  		if c == '\n' {
   116  			if n--; n == 0 {
   117  				return s[0 : i+1]
   118  			}
   119  		}
   120  	}
   121  	return s
   122  }
   123  
   124  func TestRawMessage(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  	const raw = `["\u0056",null]`
   132  	const msg = `{"X":0.1,"Id":["\u0056",null],"Y":0.2}`
   133  	err := Unmarshal([]byte(msg), &data)
   134  	if err != nil {
   135  		t.Fatalf("Unmarshal: %v", err)
   136  	}
   137  	if string([]byte(*data.Id)) != raw {
   138  		t.Fatalf("Raw mismatch: have %#q want %#q", []byte(*data.Id), raw)
   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  }
   148  
   149  func TestNullRawMessage(t *testing.T) {
   150  	// TODO(rsc): Should not need the * in *RawMessage
   151  	var data struct {
   152  		X  float64
   153  		Id *RawMessage
   154  		Y  float32
   155  	}
   156  	data.Id = new(RawMessage)
   157  	const msg = `{"X":0.1,"Id":null,"Y":0.2}`
   158  	err := Unmarshal([]byte(msg), &data)
   159  	if err != nil {
   160  		t.Fatalf("Unmarshal: %v", err)
   161  	}
   162  	if data.Id != nil {
   163  		t.Fatalf("Raw mismatch: have non-nil, want nil")
   164  	}
   165  	b, err := Marshal(&data)
   166  	if err != nil {
   167  		t.Fatalf("Marshal: %v", err)
   168  	}
   169  	if string(b) != msg {
   170  		t.Fatalf("Marshal: have %#q want %#q", b, msg)
   171  	}
   172  }
   173  
   174  var blockingTests = []string{
   175  	`{"x": 1}`,
   176  	`[1, 2, 3]`,
   177  }
   178  
   179  func TestBlocking(t *testing.T) {
   180  	for _, enc := range blockingTests {
   181  		r, w := net.Pipe()
   182  		go w.Write([]byte(enc))
   183  		var val interface{}
   184  
   185  		// If Decode reads beyond what w.Write writes above,
   186  		// it will block, and the test will deadlock.
   187  		if err := NewDecoder(r).Decode(&val); err != nil {
   188  			t.Errorf("decoding %s: %v", enc, err)
   189  		}
   190  		r.Close()
   191  		w.Close()
   192  	}
   193  }
   194  
   195  func BenchmarkEncoderEncode(b *testing.B) {
   196  	b.ReportAllocs()
   197  	type T struct {
   198  		X, Y string
   199  	}
   200  	v := &T{"foo", "bar"}
   201  	for i := 0; i < b.N; i++ {
   202  		if err := NewEncoder(ioutil.Discard).Encode(v); err != nil {
   203  			b.Fatal(err)
   204  		}
   205  	}
   206  }