1 package xml
2
3 import (
4 "bytes"
5 "fmt"
6 "math"
7 "math/big"
8 "strconv"
9 "testing"
10 )
11
12 var (
13 oneInt = new(big.Int).SetInt64(1)
14 oneFloat = new(big.Float).SetFloat64(1.0)
15 )
16
17 func TestValue(t *testing.T) {
18 nested := StartElement{Name: Name{Local: "nested"}}
19
20 cases := map[string]struct {
21 setter func(Value)
22 expected string
23 }{
24 "string value": {
25 setter: func(value Value) {
26 value.String("foo")
27 },
28 expected: `foo`,
29 },
30 "string escaped": {
31 setter: func(value Value) {
32 value.String("{\"foo\":\"bar\"}")
33 },
34 expected: fmt.Sprintf("{%sfoo%s:%sbar%s}", escQuot, escQuot, escQuot, escQuot),
35 },
36 "integer": {
37 setter: func(value Value) {
38 value.Long(1024)
39 },
40 expected: `1024`,
41 },
42 "float": {
43 setter: func(value Value) {
44 value.Double(1e20)
45 },
46 expected: `100000000000000000000`,
47 },
48 "float exponent component": {
49 setter: func(value Value) {
50 value.Double(3e22)
51 },
52 expected: `3e+22`,
53 },
54 "boolean true": {
55 setter: func(value Value) {
56 value.Boolean(true)
57 },
58 expected: `true`,
59 },
60 "boolean false": {
61 setter: func(value Value) {
62 value.Boolean(false)
63 },
64 expected: `false`,
65 },
66 "encode bytes": {
67 setter: func(value Value) {
68 value.Base64EncodeBytes([]byte("foo bar"))
69 },
70 expected: `Zm9vIGJhcg==`,
71 },
72 "encode bytes nil": {
73 setter: func(value Value) {
74 value.Base64EncodeBytes(nil)
75 },
76 expected: ``,
77 },
78 "object": {
79 setter: func(value Value) {
80 defer value.Close()
81 value.MemberElement(nested).String("value")
82 },
83 expected: `<nested>value</nested>`,
84 },
85 "null": {
86 setter: func(value Value) {
87 value.Close()
88 },
89 expected: ``,
90 },
91 "nullWithRoot": {
92 setter: func(value Value) {
93 defer value.Close()
94 o := value.MemberElement(nested)
95 defer o.Close()
96 },
97 expected: `<nested></nested>`,
98 },
99 "write text": {
100 setter: func(value Value) {
101 defer value.Close()
102 o := value.MemberElement(nested)
103 o.Write([]byte(`{"nested":"value"}`), false)
104 },
105 expected: `<nested>{"nested":"value"}</nested>`,
106 },
107 "write escaped text": {
108 setter: func(value Value) {
109 defer value.Close()
110 o := value.MemberElement(nested)
111 o.Write([]byte(`{"nested":"value"}`), true)
112 },
113 expected: fmt.Sprintf("<nested>{%snested%s:%svalue%s}</nested>", escQuot, escQuot, escQuot, escQuot),
114 },
115 "bigInteger": {
116 setter: func(value Value) {
117 v := new(big.Int).SetInt64(math.MaxInt64)
118 value.BigInteger(v.Sub(v, oneInt))
119 },
120 expected: strconv.FormatInt(math.MaxInt64-1, 10),
121 },
122 "bigInteger > int64": {
123 setter: func(value Value) {
124 v := new(big.Int).SetInt64(math.MaxInt64)
125 value.BigInteger(v.Add(v, oneInt))
126 },
127 expected: "9223372036854775808",
128 },
129 "bigInteger < int64": {
130 setter: func(value Value) {
131 v := new(big.Int).SetInt64(math.MinInt64)
132 value.BigInteger(v.Sub(v, oneInt))
133 },
134 expected: "-9223372036854775809",
135 },
136 "bigFloat": {
137 setter: func(value Value) {
138 v := new(big.Float).SetFloat64(math.MaxFloat64)
139 value.BigDecimal(v.Sub(v, oneFloat))
140 },
141 expected: strconv.FormatFloat(math.MaxFloat64-1, 'e', -1, 64),
142 },
143 "bigFloat fits in int64": {
144 setter: func(value Value) {
145 v := new(big.Float).SetInt64(math.MaxInt64)
146 value.BigDecimal(v)
147 },
148 expected: "9223372036854775807",
149 },
150 }
151 scratch := make([]byte, 64)
152
153 for name, tt := range cases {
154 t.Run(name, func(t *testing.T) {
155 b := bytes.NewBuffer(nil)
156 root := StartElement{Name: Name{Local: "root"}}
157 value := newValue(b, &scratch, root)
158 tt.setter(value)
159
160 if e, a := []byte("<root>"+tt.expected+"</root>"), b.Bytes(); bytes.Compare(e, a) != 0 {
161 t.Errorf("expected %+q, but got %+q", e, a)
162 }
163 })
164 }
165 }
166
167 func TestWrappedValue(t *testing.T) {
168 buffer := bytes.NewBuffer(nil)
169 scratch := make([]byte, 64)
170
171 func() {
172 root := StartElement{Name: Name{Local: "root"}}
173 object := newValue(buffer, &scratch, root)
174 defer object.Close()
175
176 foo := StartElement{Name: Name{Local: "foo"}}
177 faz := StartElement{Name: Name{Local: "faz"}}
178
179 object.MemberElement(foo).String("bar")
180 object.MemberElement(faz).String("baz")
181 }()
182
183 e := []byte(`<root><foo>bar</foo><faz>baz</faz></root>`)
184 if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
185 t.Errorf("expected %+q, but got %+q", e, a)
186 }
187 }
188
189 func TestWrappedValueWithNameSpaceAndAttributes(t *testing.T) {
190 buffer := bytes.NewBuffer(nil)
191 scratch := make([]byte, 64)
192
193 func() {
194 root := StartElement{Name: Name{Local: "root"}}
195 object := newValue(buffer, &scratch, root)
196 defer object.Close()
197
198 foo := StartElement{Name: Name{Local: "foo"}, Attr: []Attr{
199 NewNamespaceAttribute("newspace", "https://endpoint.com"),
200 NewAttribute("attrName", "attrValue"),
201 }}
202 faz := StartElement{Name: Name{Local: "faz"}}
203
204 object.MemberElement(foo).String("bar")
205 object.MemberElement(faz).String("baz")
206 }()
207
208 e := []byte(`<root><foo xmlns:newspace="https://endpoint.com" attrName="attrValue">bar</foo><faz>baz</faz></root>`)
209 if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
210 t.Errorf("expected %+q, but got %+q", e, a)
211 }
212 }
213
View as plain text