...
1 package jwriter
2
3 import (
4 "encoding/json"
5 "fmt"
6 "strconv"
7 "testing"
8
9 "github.com/launchdarkly/go-jsonstream/v3/internal/commontest"
10 )
11
12
13
14
15 type tokenWriterTestContext struct {
16 tw *tokenWriter
17 getOutput func() []byte
18 }
19
20 type tokenWriterValueTestFactory struct{}
21
22 const (
23 writeNumberAsInt commontest.ValueVariant = "int:"
24 )
25
26 var (
27 variantsForScalarValues = []commontest.ValueVariant{"", commontest.UntypedVariant}
28 variantsForWritingNumbers = []commontest.ValueVariant{"", writeNumberAsInt, commontest.UntypedVariant}
29 )
30
31 type tokenWriterTestSuite struct {
32 Factory func() (*tokenWriter, func() []byte)
33 EncodeAsHex func(rune) bool
34 }
35
36 func TestTokenWriter(t *testing.T) {
37 s := tokenWriterTestSuite{
38 Factory: func() (*tokenWriter, func() []byte) {
39 tw := newTokenWriter()
40 return &tw, tw.Bytes
41 },
42 }
43 s.Run(t)
44 }
45
46 func (s tokenWriterTestSuite) Run(t *testing.T) {
47 ws := commontest.WriterTestSuite{
48 ContextFactory: func() commontest.TestContext {
49 tw, getOutput := s.Factory()
50 return &tokenWriterTestContext{
51 tw: tw,
52 getOutput: getOutput,
53 }
54 },
55 ValueTestFactory: tokenWriterValueTestFactory{},
56 EncodeAsHex: tokenWriterWillEncodeAsHex,
57 }
58 ws.Run(t)
59 }
60
61 func (c tokenWriterTestContext) JSONData() []byte { return c.getOutput() }
62
63 func (f tokenWriterValueTestFactory) EOF() commontest.Action {
64 return func(c commontest.TestContext) error { return nil }
65 }
66
67 func (f tokenWriterValueTestFactory) Variants(value commontest.AnyValue) []commontest.ValueVariant {
68
69 if value.Kind == commontest.NumberValue && float64(int(value.Number)) == value.Number {
70 return variantsForWritingNumbers
71 }
72 if value.Kind != commontest.ArrayValue && value.Kind != commontest.ObjectValue {
73 return variantsForScalarValues
74 }
75 return nil
76 }
77
78 func (f tokenWriterValueTestFactory) Value(value commontest.AnyValue, variant commontest.ValueVariant) commontest.Action {
79 return func(c commontest.TestContext) error {
80 ctx := c.(*tokenWriterTestContext)
81 tw := ctx.tw
82
83 switch value.Kind {
84 case commontest.NullValue:
85 if variant == commontest.UntypedVariant {
86 return tw.Raw(json.RawMessage(`null`))
87 }
88 return tw.Null()
89
90 case commontest.BoolValue:
91 if variant == commontest.UntypedVariant {
92 return tw.Raw(json.RawMessage(fmt.Sprintf("%t", value.Bool)))
93 }
94 return tw.Bool(value.Bool)
95
96 case commontest.NumberValue:
97 if variant == commontest.UntypedVariant {
98 return tw.Raw(json.RawMessage(strconv.FormatFloat(value.Number, 'f', -1, 64)))
99 }
100 if variant == writeNumberAsInt {
101 return tw.Int(int(value.Number))
102 } else {
103 return tw.Float64(value.Number)
104 }
105
106 case commontest.StringValue:
107 if variant == commontest.UntypedVariant {
108
109 tw1 := newTokenWriter()
110 _ = tw1.String(value.String)
111 return tw.Raw(json.RawMessage(tw1.Bytes()))
112 }
113 return tw.String(value.String)
114
115 case commontest.ArrayValue:
116 if err := tw.Delimiter('['); err != nil {
117 return err
118 }
119 first := true
120 for _, e := range value.Array {
121 if !first {
122 if err := tw.Delimiter(','); err != nil {
123 return err
124 }
125 }
126 first = false
127 if err := e(c); err != nil {
128 return err
129 }
130 }
131 return tw.Delimiter(']')
132
133 case commontest.ObjectValue:
134 if err := tw.Delimiter('{'); err != nil {
135 return err
136 }
137 first := true
138 for _, p := range value.Object {
139 if !first {
140 if err := tw.Delimiter(','); err != nil {
141 return err
142 }
143 }
144 first = false
145 if err := tw.String(p.Name); err != nil {
146 return err
147 }
148 if err := tw.Delimiter(':'); err != nil {
149 return err
150 }
151 if err := p.Action(c); err != nil {
152 return err
153 }
154 }
155 return tw.Delimiter('}')
156 }
157 return nil
158 }
159 }
160
View as plain text