1 package commontest
2
3 import (
4 "fmt"
5 "strconv"
6 )
7
8
9
10 type encodingBehavior struct {
11 encodeAsHex func(rune) bool
12 forParsing bool
13 }
14
15 type testValue struct {
16 name string
17 encoding string
18 value AnyValue
19 }
20
21 type numberTestValueBase struct {
22 name string
23 val float64
24 encoding string
25 simplestEncoding string
26 }
27
28 type stringTestValueBase struct {
29 name string
30 val string
31 encoding string
32 }
33
34 func makeBoolTestValues() []testValue {
35 return []testValue{
36 {"bool true", "true", AnyValue{Kind: BoolValue, Bool: true}},
37 {"bool false", "false", AnyValue{Kind: BoolValue, Bool: false}},
38 }
39 }
40
41 func makeNumberTestValues(encodingBehavior encodingBehavior) []testValue {
42 var ret []testValue
43 for _, v := range []numberTestValueBase{
44 {"zero", 0, "0", ""},
45 {"int", 3, "3", ""},
46 {"int negative", -3, "-3", ""},
47 {"int large", 1603312301195, "1603312301195", ""},
48 {"float", 3.5, "3.5", ""},
49 {"float negative", -3.5, "-3.5", ""},
50 {"float with exp and decimal", 3500, "3.5e3", "3500"},
51 {"float with Exp and decimal", 3500, "3.5E3", "3500"},
52 {"float with exp+ and decimal", 3500, "3.5e+3", "3500"},
53 {"float with exp- and decimal", 0.0035, "3.5e-3", "0.0035"},
54 {"float with exp but no decimal", 5000, "5e3", "5000"},
55 {"float with Exp but no decimal", 5000, "5E3", "5000"},
56 {"float with exp+ but no decimal", 5000, "5e+3", "5000"},
57 {"float with exp- but no decimal", 0.005, "5e-3", "0.005"},
58 } {
59 enc := v.encoding
60 if !encodingBehavior.forParsing && v.simplestEncoding != "" {
61 enc = v.simplestEncoding
62 }
63 ret = append(ret, testValue{"number " + v.name, enc, AnyValue{Kind: NumberValue, Number: v.val}})
64 }
65 return ret
66 }
67
68 func makeStringTestValues(encodingBehavior encodingBehavior, allPermutations bool) []testValue {
69 base := []stringTestValueBase{
70 {name: "empty", val: "", encoding: `""`},
71 {name: "simple", val: "abc", encoding: `"abc"`},
72 }
73 allEscapeTests := []stringTestValueBase{}
74 if allPermutations {
75 baseEscapeTests := []stringTestValueBase{
76 {val: `"`, encoding: `\"`},
77 {val: `\`, encoding: `\\`},
78 {val: "\x05", encoding: `\u0005`},
79 {val: "\x1c", encoding: `\u001c`},
80 {val: "π¦π¦ππ§Άπ» yes", encoding: "π¦π¦ππ§Άπ» yes"},
81 }
82 addControlChar := func(str, shortEncoding string) {
83 hex := strconv.FormatInt(int64(str[0]), 16)
84 if len(hex) == 1 {
85 hex = "0" + hex
86 }
87 encodeAsHex := false
88 if encodingBehavior.encodeAsHex != nil {
89 encodeAsHex = encodingBehavior.encodeAsHex(rune(str[0]))
90 }
91 if !encodingBehavior.forParsing && !encodeAsHex {
92 baseEscapeTests = append(baseEscapeTests, stringTestValueBase{val: str, encoding: shortEncoding})
93 }
94 if encodingBehavior.forParsing || encodeAsHex {
95 baseEscapeTests = append(baseEscapeTests, stringTestValueBase{val: str, encoding: `\u00` + hex})
96 }
97 }
98 addControlChar("\b", `\b`)
99 addControlChar("\t", `\t`)
100 addControlChar("\n", `\n`)
101 addControlChar("\f", `\f`)
102 addControlChar("\r", `\r`)
103 if encodingBehavior.forParsing {
104
105 baseEscapeTests = append(baseEscapeTests, stringTestValueBase{val: "/", encoding: `\/`})
106 baseEscapeTests = append(baseEscapeTests, stringTestValueBase{val: "γ", encoding: `\u3082`})
107 }
108 for _, et := range baseEscapeTests {
109 allEscapeTests = append(allEscapeTests, et)
110 addTransformed := func(valFn func(string) string, encFn func(string) string) {
111 tt := stringTestValueBase{
112 val: valFn(et.val),
113 encoding: encFn(et.encoding),
114 }
115 allEscapeTests = append(allEscapeTests, tt)
116 }
117 for _, f := range []string{"%sabcd", "abcd%s", "ab%scd"} {
118 addTransformed(func(s string) string { return fmt.Sprintf(f, s) },
119 func(s string) string { return fmt.Sprintf(f, s) })
120 }
121 for _, et2 := range baseEscapeTests {
122 for _, f := range []string{"%s%sabcd", "ab%s%scd", "a%sbc%sd", "abcd%s%s"} {
123 addTransformed(func(s string) string { return fmt.Sprintf(f, s, et2.val) },
124 func(s string) string { return fmt.Sprintf(f, s, et2.encoding) })
125 }
126 }
127 }
128 } else {
129
130
131
132 allEscapeTests = []stringTestValueBase{{val: "simple\tescape", encoding: `simple\tescape`}}
133 }
134 for i, et := range allEscapeTests {
135 st := stringTestValueBase{
136 name: fmt.Sprintf("with escapes %d", i+1),
137 val: et.val,
138 encoding: `"` + et.encoding + `"`,
139 }
140 base = append(base, st)
141 }
142 ret := make([]testValue, 0, len(base))
143 for _, b := range base {
144 ret = append(ret, testValue{name: "string " + b.name, encoding: b.encoding,
145 value: AnyValue{Kind: StringValue, String: b.val}})
146 }
147 return ret
148 }
149
150 func MakeWhitespaceOptions() map[string]string {
151 return map[string]string{"spaces": " ", "tab": "\t", "newline": "\n"}
152 }
153
View as plain text