1package ini
2
3import (
4	"reflect"
5	"testing"
6)
7
8func TestIsNumberValue(t *testing.T) {
9	cases := []struct {
10		name     string
11		b        []rune
12		expected bool
13	}{
14		{
15			"integer",
16			[]rune("123"),
17			true,
18		},
19		{
20			"negative integer",
21			[]rune("-123"),
22			true,
23		},
24		{
25			"decimal",
26			[]rune("123.456"),
27			true,
28		},
29		{
30			"small e exponent",
31			[]rune("1e234"),
32			true,
33		},
34		{
35			"big E exponent",
36			[]rune("1E234"),
37			true,
38		},
39		{
40			"error case exponent base 16",
41			[]rune("1ea4"),
42			false,
43		},
44		{
45			"error case negative",
46			[]rune("1-23"),
47			false,
48		},
49		{
50			"error case multiple negative",
51			[]rune("-1-23"),
52			false,
53		},
54		{
55			"error case end negative",
56			[]rune("123-"),
57			false,
58		},
59		{
60			"error case non-number",
61			[]rune("a"),
62			false,
63		},
64		{
65			"utf8 whitespace",
66			[]rune("00"),
67			true,
68		},
69	}
70
71	for i, c := range cases {
72		t.Run(c.name, func(t *testing.T) {
73			if e, a := c.expected, isNumberValue(c.b); e != a {
74				t.Errorf("%d: expected %t, but received %t", i+1, e, a)
75			}
76		})
77	}
78}
79
80// TODO: test errors
81func TestNewLiteralToken(t *testing.T) {
82	cases := []struct {
83		name          string
84		b             []rune
85		expectedRead  int
86		expectedToken Token
87		expectedError bool
88	}{
89		{
90			name:         "numbers",
91			b:            []rune("123"),
92			expectedRead: 3,
93			expectedToken: newToken(TokenLit,
94				[]rune("123"),
95				IntegerType,
96			),
97		},
98		{
99			name:         "decimal",
100			b:            []rune("123.456"),
101			expectedRead: 7,
102			expectedToken: newToken(TokenLit,
103				[]rune("123.456"),
104				DecimalType,
105			),
106		},
107		{
108			name:         "two numbers",
109			b:            []rune("123 456"),
110			expectedRead: 3,
111			expectedToken: newToken(TokenLit,
112				[]rune("123"),
113				IntegerType,
114			),
115		},
116		{
117			name:         "number followed by alpha",
118			b:            []rune("123 abc"),
119			expectedRead: 3,
120			expectedToken: newToken(TokenLit,
121				[]rune("123"),
122				IntegerType,
123			),
124		},
125		{
126			name:         "quoted string followed by number",
127			b:            []rune(`"Hello" 123`),
128			expectedRead: 7,
129			expectedToken: newToken(TokenLit,
130				[]rune("Hello"),
131				QuotedStringType,
132			),
133		},
134		{
135			name:         "quoted string",
136			b:            []rune(`"Hello World"`),
137			expectedRead: 13,
138			expectedToken: newToken(TokenLit,
139				[]rune("Hello World"),
140				QuotedStringType,
141			),
142		},
143		{
144			name:         "boolean true",
145			b:            []rune("true"),
146			expectedRead: 4,
147			expectedToken: newToken(TokenLit,
148				[]rune("true"),
149				BoolType,
150			),
151		},
152		{
153			name:         "boolean false",
154			b:            []rune("false"),
155			expectedRead: 5,
156			expectedToken: newToken(TokenLit,
157				[]rune("false"),
158				BoolType,
159			),
160		},
161		{
162			name: "utf8 whitespace",
163			b: []rune("00"),
164			expectedRead: 1,
165			expectedToken: newToken(TokenLit,
166				[]rune("0"),
167				IntegerType,
168			),
169		},
170		{
171			name: "utf8 whitespace expr",
172			b: []rune("0=00"),
173			expectedRead: 1,
174			expectedToken: newToken(TokenLit,
175				[]rune("0"),
176				StringType,
177			),
178		},
179	}
180
181	for i, c := range cases {
182		t.Run(c.name, func(t *testing.T) {
183			tok, n, err := newLitToken(c.b)
184
185			if e, a := c.expectedToken.ValueType, tok.ValueType; !reflect.DeepEqual(e, a) {
186				t.Errorf("%d: expected %v, but received %v", i+1, e, a)
187			}
188
189			if e, a := c.expectedRead, n; e != a {
190				t.Errorf("%d: expected %v, but received %v", i+1, e, a)
191			}
192
193			if e, a := c.expectedError, err != nil; e != a {
194				t.Errorf("%d: expected %v, but received %v", i+1, e, a)
195			}
196		})
197	}
198}
199