1package ogórek
2
3import (
4	"bytes"
5	"io"
6	"reflect"
7	"testing"
8)
9
10func TestEncode(t *testing.T) {
11
12	type foo struct {
13		Foo string
14		Bar int32
15	}
16
17	tests := []struct {
18		name   string
19		input  interface{}
20		output interface{}
21	}{
22		{
23			"graphite message",
24			[]interface{}{map[interface{}]interface{}{"values": []interface{}{float64(473), float64(497), float64(540), float64(1497), float64(1808), float64(1890), float64(2013), float64(1821), float64(1847), float64(2176), float64(2156), float64(1250), float64(2055), float64(1570), None{}, None{}}, "start": int64(1383782400), "step": int64(86400), "end": int64(1385164800), "name": "ZZZZ.UUUUUUUU.CCCCCCCC.MMMMMMMM.XXXXXXXXX.TTT"}},
25			nil,
26		},
27		{
28			"small types",
29			[]interface{}{int64(0), int64(1), int64(258), int64(65537), false, true},
30			nil,
31		},
32		{
33			"array of struct types",
34			[]foo{{"Qux", 4}},
35			[]interface{}{map[interface{}]interface{}{"Foo": "Qux", "Bar": int64(4)}},
36		},
37	}
38
39	for _, tt := range tests {
40		p := &bytes.Buffer{}
41		e := NewEncoder(p)
42		err := e.Encode(tt.input)
43		if err != nil {
44			t.Errorf("%s: encode error: %v", tt.name, err)
45		}
46
47		d := NewDecoder(bytes.NewReader(p.Bytes()))
48		output, _ := d.Decode()
49
50		want := tt.output
51		if want == nil {
52			want = tt.input
53		}
54
55		if !reflect.DeepEqual(want, output) {
56			t.Errorf("%s: got\n%q\n expected\n%q", tt.name, output, want)
57		}
58
59		for l := int64(p.Len()) - 1; l >= 0; l-- {
60			p.Reset()
61			e := NewEncoder(LimitWriter(p, l))
62			err = e.Encode(tt.input)
63			if err != io.EOF {
64				t.Errorf("%s: encoder did not handle write error @%v: got %#v", tt.name, l, err)
65			}
66		}
67
68	}
69}
70
71// like io.LimitedReader but for writes
72// XXX it would be good to have it in stdlib
73type LimitedWriter struct {
74	W io.Writer
75	N int64
76}
77
78func (l *LimitedWriter) Write(p []byte) (n int, err error) {
79	if l.N <= 0 {
80		return 0, io.EOF
81	}
82	if int64(len(p)) > l.N {
83		p = p[0:l.N]
84	}
85	n, err = l.W.Write(p)
86	l.N -= int64(n)
87	return
88}
89
90type testMarshalPickle struct {
91}
92
93func (p *testMarshalPickle) MarshalPickle() (text []byte, err error) {
94	return []byte("(lp0\nI1\naI2\na"), nil
95}
96func TestMarshalPickle(t *testing.T) {
97	testData := map[string]interface{}{
98		"key": &testMarshalPickle{},
99	}
100
101	p := &bytes.Buffer{}
102	e := NewEncoder(p)
103	e.Encode(testData)
104
105	if p.String() != "}(U\x03key(lp0\nI1\naI2\nau." {
106		t.FailNow()
107	}
108}
109func LimitWriter(w io.Writer, n int64) io.Writer { return &LimitedWriter{w, n} }
110