tree - write_test.go
1 package tree
2
3 import (
4 "bytes"
5 "io"
6 "iter"
7 "reflect"
8 "testing"
9 )
10
11 type node struct {
12 name string
13 children []node
14 data []byte
15 }
16
17 func (nd *node) WriteTo(w io.Writer) (int64, error) {
18 n, err := w.Write(nd.data)
19
20 return int64(n), err
21 }
22
23 func (nd *node) Children() iter.Seq2[string, Node] {
24 return func(yield func(string, Node) bool) {
25 for _, child := range nd.children {
26 if !yield(child.name, &child) {
27 break
28 }
29 }
30 }
31 }
32
33 func TestSerialise(t *testing.T) {
34 for n, test := range [...]struct {
35 Input Node
36 Output []byte
37 Error error
38 }{
39 {
40 Input: &node{},
41 }, // 1
42 { // 2
43 Input: &node{
44 data: []byte("ABC"),
45 },
46 Output: []byte{'A', 'B', 'C', 3, 0x20 | 1},
47 },
48 { // 3
49 Input: &node{
50 children: []node{
51 {
52 name: "Child1",
53 data: []byte("123"),
54 },
55 },
56 },
57 Output: []byte{'1', '2', '3', 3, 0x20 | 1, 'C', 'h', 'i', 'l', 'd', '1', 5, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0x40 | 1},
58 },
59 { // 4
60 Input: &node{
61 children: []node{
62 {
63 name: "Child1",
64 data: []byte("123"),
65 },
66 {
67 name: "child-2",
68 data: []byte("qwerty"),
69 },
70 },
71 },
72 Output: []byte{'1', '2', '3', 3, 0x20 | 1, 'q', 'w', 'e', 'r', 't', 'y', 6, 0x20 | 1, 'C', 'h', 'i', 'l', 'd', '1', 'c', 'h', 'i', 'l', 'd', '-', '2', 5, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 6, 7, 2, 0x40 | 1},
73 },
74 { // 5
75 Input: &node{
76 children: []node{
77 {
78 name: "child-2",
79 data: []byte("qwerty"),
80 },
81 {
82 name: "Child1",
83 data: []byte("123"),
84 },
85 },
86 data: []byte("abc"),
87 },
88 Output: []byte{'q', 'w', 'e', 'r', 't', 'y', 6, 0x20 | 1, '1', '2', '3', 3, 0x20 | 1, 'C', 'h', 'i', 'l', 'd', '1', 'c', 'h', 'i', 'l', 'd', '-', '2', 13, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 6, 7, 'a', 'b', 'c', 2, 3, 0x60 | 2},
89 },
90 { // 6
91 Input: &node{
92 children: []node{
93 {
94 name: "Child1",
95 },
96 {
97 name: "Child1",
98 },
99 },
100 },
101 Error: DuplicateChildError{"Child1"},
102 },
103 { // 7
104 Input: &node{
105 children: []node{
106 {
107 name: "Child1",
108 children: []node{
109 {
110 name: "SubChild1",
111 },
112 {
113 name: "SubChild1",
114 },
115 },
116 },
117 {
118 name: "Child2",
119 },
120 },
121 },
122 Error: DuplicateChildError{"Child1", "SubChild1"},
123 },
124 { // 8
125 Input: errorWriter{},
126 Error: io.ErrShortWrite,
127 },
128 } {
129 var buf bytes.Buffer
130
131 if err := Serialise(&buf, test.Input); !reflect.DeepEqual(err, test.Error) {
132 t.Errorf("test %d: expected error %v, got %v", n+1, test.Error, err)
133 } else if written := buf.Bytes(); !bytes.Equal(written, test.Output) {
134 t.Errorf("test %d: expecting to have written %v, wrote %v", n+1, test.Output, written)
135 }
136 }
137 }
138
139 type errorWriter struct{}
140
141 func (errorWriter) Children() iter.Seq2[string, Node] {
142 return noChildren
143 }
144
145 func (errorWriter) WriteTo(_ io.Writer) (int64, error) {
146 return 0, io.ErrShortWrite
147 }
148