gettc 1.6.2 → 1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/core/lib/gettc.rb +1 -1
- data/core/lib/gettc/generate.rb +133 -133
- data/dist/config.yml +1 -1
- data/dist/include/cpp/engine.rb +22 -15
- data/dist/include/go/engine.rb +70 -0
- data/dist/include/go/src/topcoder/errors.go +41 -0
- data/dist/include/go/src/topcoder/reader.go +266 -0
- data/dist/include/go/src/topcoder/reader_test.go +335 -0
- data/dist/include/go/src/topcoder/writer.go +54 -0
- data/dist/include/go/src/topcoder/writer_test.go +19 -0
- data/dist/include/haskell/engine.rb +16 -15
- data/dist/include/java/engine.rb +14 -10
- data/dist/include/python/engine.rb +36 -13
- data/dist/include/python/topcoder/__pycache__/__init__.cpython-32.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/errors.cpython-32.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/reader.cpython-32.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/writer.cpython-32.pyc +0 -0
- data/dist/template/solve/cpp/Makefile +1 -5
- data/dist/template/solve/cpp/{name}.cpp +2 -2
- data/dist/template/solve/go/Makefile +29 -0
- data/dist/template/solve/go/{name}/{name}.go +7 -0
- data/dist/template/solve/go/{name}Runner.go +34 -0
- data/dist/template/solve/haskell/Makefile +1 -5
- data/dist/template/solve/java/build.xml +0 -16
- data/dist/template/solve/python/Makefile +1 -1
- data/dist/template/solve/python/{name}.py +2 -2
- data/dist/template/solve/python/{name}Runner.py +4 -5
- data/dist/template/util/check/check.cpp +1 -1
- metadata +11 -2
@@ -0,0 +1,266 @@
|
|
1
|
+
package topcoder
|
2
|
+
|
3
|
+
import (
|
4
|
+
"bytes"
|
5
|
+
"bufio"
|
6
|
+
"fmt"
|
7
|
+
"io"
|
8
|
+
"reflect"
|
9
|
+
"unicode"
|
10
|
+
)
|
11
|
+
|
12
|
+
func spaces(br *bufio.Reader) error {
|
13
|
+
for {
|
14
|
+
switch b, err := br.ReadByte(); {
|
15
|
+
case err == io.EOF:
|
16
|
+
return nil
|
17
|
+
case err != nil:
|
18
|
+
return err
|
19
|
+
case !unicode.IsSpace(rune(b)):
|
20
|
+
br.UnreadByte()
|
21
|
+
return nil
|
22
|
+
}
|
23
|
+
}
|
24
|
+
return nil
|
25
|
+
}
|
26
|
+
|
27
|
+
func genericExpect(br *bufio.Reader, what string, predicate func(byte) bool) error {
|
28
|
+
switch b, err := br.ReadByte(); {
|
29
|
+
case err == io.EOF:
|
30
|
+
return io.ErrUnexpectedEOF
|
31
|
+
case err != nil:
|
32
|
+
return err
|
33
|
+
case !predicate(b):
|
34
|
+
br.UnreadByte()
|
35
|
+
return NewErrExpect(br, what)
|
36
|
+
}
|
37
|
+
return nil
|
38
|
+
}
|
39
|
+
|
40
|
+
func expect(br *bufio.Reader, b byte) error {
|
41
|
+
return genericExpect(br, fmt.Sprintf("<%c>", b), func(got byte) bool {
|
42
|
+
return got == b
|
43
|
+
})
|
44
|
+
}
|
45
|
+
|
46
|
+
func next(br *bufio.Reader) error {
|
47
|
+
if err := spaces(br); err != nil {
|
48
|
+
return err
|
49
|
+
}
|
50
|
+
return expect(br, ',')
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
func readPrimitive(br *bufio.Reader, x interface{}) error {
|
55
|
+
_, err := fmt.Fscan(br, x)
|
56
|
+
return err
|
57
|
+
}
|
58
|
+
|
59
|
+
func readChar(br *bufio.Reader, pChar *byte) error {
|
60
|
+
var (
|
61
|
+
err error
|
62
|
+
b byte
|
63
|
+
)
|
64
|
+
if err = spaces(br); err != nil {
|
65
|
+
return err
|
66
|
+
}
|
67
|
+
if err = expect(br, '\''); err != nil {
|
68
|
+
return err
|
69
|
+
}
|
70
|
+
switch b, err = br.ReadByte(); {
|
71
|
+
case err == io.EOF:
|
72
|
+
return io.ErrUnexpectedEOF
|
73
|
+
case err != nil:
|
74
|
+
return err
|
75
|
+
}
|
76
|
+
if err = expect(br, '\''); err != nil {
|
77
|
+
return err
|
78
|
+
}
|
79
|
+
*pChar = b
|
80
|
+
return nil
|
81
|
+
}
|
82
|
+
|
83
|
+
|
84
|
+
func isEndOfString(br *bufio.Reader) (ended bool, text string, err error) {
|
85
|
+
var b byte
|
86
|
+
w := bytes.NewBufferString("")
|
87
|
+
for {
|
88
|
+
switch b, err = br.ReadByte(); {
|
89
|
+
case err == io.EOF:
|
90
|
+
ended = true
|
91
|
+
err = nil
|
92
|
+
return
|
93
|
+
case err != nil:
|
94
|
+
return
|
95
|
+
case b == ',' || b == ']':
|
96
|
+
br.UnreadByte()
|
97
|
+
ended = true
|
98
|
+
return
|
99
|
+
case !unicode.IsSpace(rune(b)):
|
100
|
+
ended = false
|
101
|
+
text = w.String()
|
102
|
+
err = nil
|
103
|
+
br.UnreadByte()
|
104
|
+
return
|
105
|
+
}
|
106
|
+
w.WriteByte(b)
|
107
|
+
}
|
108
|
+
return
|
109
|
+
}
|
110
|
+
|
111
|
+
func readString(br *bufio.Reader, pString *string) error {
|
112
|
+
var (
|
113
|
+
b byte
|
114
|
+
err error
|
115
|
+
ended bool
|
116
|
+
text string
|
117
|
+
)
|
118
|
+
if err = spaces(br); err != nil {
|
119
|
+
return err
|
120
|
+
}
|
121
|
+
if err = expect(br, '"'); err != nil {
|
122
|
+
return err
|
123
|
+
}
|
124
|
+
w := bytes.NewBufferString("")
|
125
|
+
for {
|
126
|
+
switch b, err = br.ReadByte(); {
|
127
|
+
case err == io.EOF:
|
128
|
+
return io.ErrUnexpectedEOF
|
129
|
+
case err != nil:
|
130
|
+
return err
|
131
|
+
case b != '"':
|
132
|
+
if err = w.WriteByte(b); err != nil {
|
133
|
+
return err
|
134
|
+
}
|
135
|
+
continue
|
136
|
+
}
|
137
|
+
switch ended, text, err = isEndOfString(br); {
|
138
|
+
case err != nil:
|
139
|
+
return err
|
140
|
+
case ended:
|
141
|
+
*pString = w.String()
|
142
|
+
return nil
|
143
|
+
}
|
144
|
+
w.WriteByte('"')
|
145
|
+
w.WriteString(text)
|
146
|
+
}
|
147
|
+
return nil
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
func isEndOfSlice(br *bufio.Reader) (bool, error) {
|
152
|
+
var (
|
153
|
+
b byte
|
154
|
+
err error
|
155
|
+
)
|
156
|
+
if err = spaces(br); err != nil {
|
157
|
+
return false, err
|
158
|
+
}
|
159
|
+
switch b, err = br.ReadByte(); {
|
160
|
+
case err != nil:
|
161
|
+
return false, err
|
162
|
+
case b == ']':
|
163
|
+
return true, nil
|
164
|
+
}
|
165
|
+
br.UnreadByte()
|
166
|
+
return false, nil
|
167
|
+
}
|
168
|
+
|
169
|
+
func betterNew(typ reflect.Type) reflect.Value {
|
170
|
+
ret := reflect.New(typ)
|
171
|
+
if typ.Kind() == reflect.Slice {
|
172
|
+
slice := reflect.MakeSlice(typ, 0, 0)
|
173
|
+
reflect.Indirect(ret).Set(slice)
|
174
|
+
}
|
175
|
+
return ret
|
176
|
+
}
|
177
|
+
|
178
|
+
func appendSlice(br *bufio.Reader, slice reflect.Value) error {
|
179
|
+
another := betterNew(slice.Type().Elem())
|
180
|
+
if err := readOne(br, another.Interface()); err != nil {
|
181
|
+
return err
|
182
|
+
}
|
183
|
+
slice.Set(reflect.Append(slice, another.Elem()))
|
184
|
+
return nil
|
185
|
+
}
|
186
|
+
|
187
|
+
func readSlice(br *bufio.Reader, x interface{}) error {
|
188
|
+
var (
|
189
|
+
err error
|
190
|
+
ended bool
|
191
|
+
)
|
192
|
+
|
193
|
+
value := reflect.ValueOf(x)
|
194
|
+
slice := value.Elem()
|
195
|
+
if slice.Kind() != reflect.Slice {
|
196
|
+
return NewErrType(value.Type())
|
197
|
+
}
|
198
|
+
|
199
|
+
if err = spaces(br); err != nil {
|
200
|
+
return err
|
201
|
+
}
|
202
|
+
if err = expect(br, '['); err != nil {
|
203
|
+
return err
|
204
|
+
}
|
205
|
+
|
206
|
+
switch ended, err = isEndOfSlice(br); {
|
207
|
+
case err != nil:
|
208
|
+
return err
|
209
|
+
case ended:
|
210
|
+
return nil
|
211
|
+
}
|
212
|
+
if err = appendSlice(br, slice); err != nil {
|
213
|
+
return err
|
214
|
+
}
|
215
|
+
|
216
|
+
for {
|
217
|
+
switch ended, err = isEndOfSlice(br); {
|
218
|
+
case err != nil:
|
219
|
+
return err
|
220
|
+
case ended:
|
221
|
+
return nil
|
222
|
+
}
|
223
|
+
if err = next(br); err != nil {
|
224
|
+
return err
|
225
|
+
}
|
226
|
+
if err = appendSlice(br, slice); err != nil {
|
227
|
+
return err
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
return nil
|
232
|
+
}
|
233
|
+
|
234
|
+
|
235
|
+
func readOne(br *bufio.Reader, x interface{}) error {
|
236
|
+
switch p := x.(type) {
|
237
|
+
case *bool, *int, *int64, *float32, *float64:
|
238
|
+
return readPrimitive(br, x)
|
239
|
+
case *byte:
|
240
|
+
return readChar(br, p)
|
241
|
+
case *string:
|
242
|
+
return readString(br, p)
|
243
|
+
default:
|
244
|
+
value := reflect.ValueOf(x)
|
245
|
+
if value.Kind() != reflect.Ptr {
|
246
|
+
return NewErrType(value.Type())
|
247
|
+
}
|
248
|
+
return readSlice(br, x)
|
249
|
+
}
|
250
|
+
return nil
|
251
|
+
}
|
252
|
+
|
253
|
+
func Read(r io.Reader, xs ...interface{}) error {
|
254
|
+
br := bufio.NewReader(r)
|
255
|
+
for i, x := range xs {
|
256
|
+
if i != 0 {
|
257
|
+
if err := next(br); err != nil {
|
258
|
+
return err
|
259
|
+
}
|
260
|
+
}
|
261
|
+
if err := readOne(br, x); err != nil {
|
262
|
+
return err
|
263
|
+
}
|
264
|
+
}
|
265
|
+
return nil
|
266
|
+
}
|
@@ -0,0 +1,335 @@
|
|
1
|
+
package topcoder
|
2
|
+
|
3
|
+
import (
|
4
|
+
"bufio"
|
5
|
+
"fmt"
|
6
|
+
"reflect"
|
7
|
+
"strings"
|
8
|
+
"testing"
|
9
|
+
)
|
10
|
+
|
11
|
+
func newReader(s string) *bufio.Reader {
|
12
|
+
return bufio.NewReader(strings.NewReader(s))
|
13
|
+
}
|
14
|
+
|
15
|
+
func unexpectedError(err error) string {
|
16
|
+
return " raised an unexpected Error: " + err.Error()
|
17
|
+
}
|
18
|
+
|
19
|
+
func expectError() string {
|
20
|
+
return " should have raised an error"
|
21
|
+
}
|
22
|
+
|
23
|
+
func mismatch(got, required interface{}) string {
|
24
|
+
return fmt.Sprintf(" got %v (expected %v instead)", got, required)
|
25
|
+
}
|
26
|
+
|
27
|
+
func TestReadBool(t *testing.T) {
|
28
|
+
type aTest struct {
|
29
|
+
in string
|
30
|
+
out bool
|
31
|
+
ok bool
|
32
|
+
}
|
33
|
+
var (
|
34
|
+
xs = []aTest {
|
35
|
+
aTest {"True", true, true},
|
36
|
+
aTest {"\n\t\n fAlSe", false, true},
|
37
|
+
aTest {"truz", true, false},
|
38
|
+
}
|
39
|
+
got bool
|
40
|
+
)
|
41
|
+
for _, x := range xs {
|
42
|
+
br := newReader(x.in)
|
43
|
+
err := readOne(br, &got)
|
44
|
+
f := fmt.Sprintf("readOne(%q, *bool)", x.in)
|
45
|
+
switch {
|
46
|
+
case x.ok && err != nil:
|
47
|
+
t.Errorf(f + unexpectedError(err))
|
48
|
+
case !x.ok && err == nil:
|
49
|
+
t.Errorf(f + expectError())
|
50
|
+
case !x.ok && err != nil:
|
51
|
+
break
|
52
|
+
case got != x.out:
|
53
|
+
t.Errorf(f + mismatch(got, x.out))
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
func TestReadInt(t *testing.T) {
|
59
|
+
type aTest struct {
|
60
|
+
in string
|
61
|
+
out int
|
62
|
+
ok bool
|
63
|
+
}
|
64
|
+
var (
|
65
|
+
xs = []aTest {
|
66
|
+
aTest{"123", 123, true},
|
67
|
+
aTest{"\n\t\n 123", 123, true},
|
68
|
+
aTest{"x123", 123, false},
|
69
|
+
}
|
70
|
+
got int
|
71
|
+
)
|
72
|
+
for _, x := range xs {
|
73
|
+
br := newReader(x.in)
|
74
|
+
err := readOne(br, &got)
|
75
|
+
f := fmt.Sprintf("readOne(%q, *int)", x.in)
|
76
|
+
switch {
|
77
|
+
case x.ok && err != nil:
|
78
|
+
t.Errorf(f + unexpectedError(err))
|
79
|
+
case !x.ok && err == nil:
|
80
|
+
t.Errorf(f + expectError())
|
81
|
+
case !x.ok && err != nil:
|
82
|
+
break
|
83
|
+
case got != x.out:
|
84
|
+
t.Errorf(f + mismatch(got, x.out))
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
func TestReadInt64(t *testing.T) {
|
90
|
+
type aTest struct {
|
91
|
+
in string
|
92
|
+
out int64
|
93
|
+
ok bool
|
94
|
+
}
|
95
|
+
var (
|
96
|
+
xs = []aTest {
|
97
|
+
aTest{"1234567890123", 1234567890123, true},
|
98
|
+
aTest{"\n\t\n 1234567890123", 1234567890123, true},
|
99
|
+
aTest{"x123", 123, false},
|
100
|
+
}
|
101
|
+
got int64
|
102
|
+
)
|
103
|
+
for _, x := range xs {
|
104
|
+
br := newReader(x.in)
|
105
|
+
err := readOne(br, &got)
|
106
|
+
f := fmt.Sprintf("readOne(%q, *int64)", x.in)
|
107
|
+
switch {
|
108
|
+
case x.ok && err != nil:
|
109
|
+
t.Errorf(f + unexpectedError(err))
|
110
|
+
case !x.ok && err == nil:
|
111
|
+
t.Errorf(f + expectError())
|
112
|
+
case !x.ok && err != nil:
|
113
|
+
break
|
114
|
+
case got != x.out:
|
115
|
+
t.Errorf(f + mismatch(got, x.out))
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
func TestReadFloat64(t *testing.T) {
|
121
|
+
type aTest struct {
|
122
|
+
in string
|
123
|
+
out float64
|
124
|
+
ok bool
|
125
|
+
}
|
126
|
+
var (
|
127
|
+
xs = []aTest {
|
128
|
+
aTest{"12345.6789", 12345.6789, true},
|
129
|
+
aTest{"\n\t\n 12345.6789", 12345.6789, true},
|
130
|
+
aTest{"x123", 123.0, false},
|
131
|
+
}
|
132
|
+
got float64
|
133
|
+
)
|
134
|
+
for _, x := range xs {
|
135
|
+
br := newReader(x.in)
|
136
|
+
err := readOne(br, &got)
|
137
|
+
f := fmt.Sprintf("readOne(%q, *float64)", x.in)
|
138
|
+
switch {
|
139
|
+
case x.ok && err != nil:
|
140
|
+
t.Errorf(f + unexpectedError(err))
|
141
|
+
case !x.ok && err == nil:
|
142
|
+
t.Errorf(f + expectError())
|
143
|
+
case !x.ok && err != nil:
|
144
|
+
break
|
145
|
+
case got != x.out:
|
146
|
+
t.Errorf(f + mismatch(got, x.out))
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
func TestReadByte(t *testing.T) {
|
152
|
+
type aTest struct {
|
153
|
+
in string
|
154
|
+
out byte
|
155
|
+
ok bool
|
156
|
+
}
|
157
|
+
var (
|
158
|
+
xs = []aTest {
|
159
|
+
aTest{"'H'ello", 'H', true},
|
160
|
+
aTest{"\n\t 'H'23", 'H', true},
|
161
|
+
aTest{"Hello", 'H', false},
|
162
|
+
}
|
163
|
+
got byte
|
164
|
+
)
|
165
|
+
for _, x := range xs {
|
166
|
+
br := newReader(x.in)
|
167
|
+
err := readOne(br, &got)
|
168
|
+
f := fmt.Sprintf("readOne(%q, *byte)", x.in)
|
169
|
+
switch {
|
170
|
+
case x.ok && err != nil:
|
171
|
+
t.Errorf(f + unexpectedError(err))
|
172
|
+
case !x.ok && err == nil:
|
173
|
+
t.Errorf(f + expectError())
|
174
|
+
case !x.ok && err != nil:
|
175
|
+
break
|
176
|
+
case got != x.out:
|
177
|
+
t.Errorf(f + mismatch(got, x.out))
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
func TestReadString(t *testing.T) {
|
183
|
+
type aTest struct {
|
184
|
+
in string
|
185
|
+
out string
|
186
|
+
ok bool
|
187
|
+
}
|
188
|
+
var (
|
189
|
+
xs = []aTest {
|
190
|
+
aTest{"\"H e l l o\"", "H e l l o", true},
|
191
|
+
aTest{"\"Hello\"world", "Hello", false},
|
192
|
+
aTest{"\"Hello\" , world", "Hello", true},
|
193
|
+
aTest{"\n\t \"Hello world\"!", "Hello world", false},
|
194
|
+
aTest{"Hello", "Hello", false},
|
195
|
+
aTest{"H\"ello\\\" worl\"d", "ello\" worl", false},
|
196
|
+
aTest{"H\"ello\\\" worl\"d", "ello\" worl", false},
|
197
|
+
}
|
198
|
+
got string
|
199
|
+
)
|
200
|
+
for _, x := range xs {
|
201
|
+
br := newReader(x.in)
|
202
|
+
err := readOne(br, &got)
|
203
|
+
f := fmt.Sprintf("readOne(%q, *string)", x.in)
|
204
|
+
switch {
|
205
|
+
case x.ok && err != nil:
|
206
|
+
t.Errorf(f + unexpectedError(err))
|
207
|
+
case !x.ok && err == nil:
|
208
|
+
t.Errorf(f + expectError())
|
209
|
+
case !x.ok && err != nil:
|
210
|
+
break
|
211
|
+
case got != x.out:
|
212
|
+
t.Errorf(f + mismatch(got, x.out))
|
213
|
+
}
|
214
|
+
}
|
215
|
+
}
|
216
|
+
|
217
|
+
func TestReadIntSlice(t *testing.T) {
|
218
|
+
type aTest struct {
|
219
|
+
in string
|
220
|
+
out []int
|
221
|
+
ok bool
|
222
|
+
}
|
223
|
+
var (
|
224
|
+
xs = []aTest {
|
225
|
+
aTest{"[]", []int {}, true},
|
226
|
+
aTest{"[1]", []int {1}, true},
|
227
|
+
aTest{"[1, 2, 3]", []int {1, 2, 3}, true},
|
228
|
+
aTest{"\n[\n1\t\n,2,3,1001\n\n]", []int {1, 2, 3, 1001}, true},
|
229
|
+
aTest{"\n[\n1\t\n,2,3,1001\n\n", []int {1, 2, 3, 1001}, false},
|
230
|
+
}
|
231
|
+
)
|
232
|
+
for _, x := range xs {
|
233
|
+
got := []int {}
|
234
|
+
br := newReader(x.in)
|
235
|
+
err := readOne(br, &got)
|
236
|
+
f := fmt.Sprintf("readOne(%q, *[]int)", x.in)
|
237
|
+
switch {
|
238
|
+
case x.ok && err != nil:
|
239
|
+
t.Errorf(f + unexpectedError(err))
|
240
|
+
case !x.ok && err == nil:
|
241
|
+
t.Errorf(f + expectError())
|
242
|
+
case !x.ok && err != nil:
|
243
|
+
break
|
244
|
+
case !reflect.DeepEqual(got, x.out):
|
245
|
+
t.Errorf(f + mismatch(got, x.out))
|
246
|
+
}
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
func TestReadStringSlice(t *testing.T) {
|
251
|
+
type aTest struct {
|
252
|
+
in string
|
253
|
+
out []string
|
254
|
+
ok bool
|
255
|
+
}
|
256
|
+
var (
|
257
|
+
xs = []aTest {
|
258
|
+
aTest{"[]", []string {}, true},
|
259
|
+
aTest{"[\"Hello\"]", []string {"Hello"}, true},
|
260
|
+
aTest{"[\"Hello\", \"World\"]", []string {"Hello", "World"}, true},
|
261
|
+
aTest{"[\"Hello \" World\"]", []string {"Hello \" World"}, true},
|
262
|
+
aTest{"\n[\n\"Hello\"\t\n,\n\"Wo\",\"rld\"\n\n]", []string {"Hello", "Wo", "rld"}, true},
|
263
|
+
aTest{"\n[\n\"Hello\"\t\n\n\n", []string {"Hello"}, false},
|
264
|
+
}
|
265
|
+
)
|
266
|
+
for _, x := range xs {
|
267
|
+
got := []string {}
|
268
|
+
br := newReader(x.in)
|
269
|
+
err := readOne(br, &got)
|
270
|
+
f := fmt.Sprintf("readOne(%q, *[]string)", x.in)
|
271
|
+
switch {
|
272
|
+
case x.ok && err != nil:
|
273
|
+
t.Errorf(f + unexpectedError(err))
|
274
|
+
case !x.ok && err == nil:
|
275
|
+
t.Errorf(f + expectError())
|
276
|
+
case !x.ok && err != nil:
|
277
|
+
break
|
278
|
+
case !reflect.DeepEqual(got, x.out):
|
279
|
+
t.Errorf(f + mismatch(got, x.out))
|
280
|
+
}
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
func TestReadSliceOfIntSlice(t *testing.T) {
|
285
|
+
type aTest struct {
|
286
|
+
in string
|
287
|
+
out [][]int
|
288
|
+
ok bool
|
289
|
+
}
|
290
|
+
var (
|
291
|
+
xs = []aTest {
|
292
|
+
aTest{"[[]]", [][]int {{}}, true},
|
293
|
+
aTest{"[[1],[2,3]]", [][]int {{1}, {2, 3}}, true},
|
294
|
+
aTest{"\n\t[\n[1,2],\n[]\n,[3, 4, 5]]", [][]int {{1, 2}, {}, {3, 4, 5}}, true},
|
295
|
+
aTest{"[[1], [2], [3]", [][]int {{}}, false},
|
296
|
+
aTest{"[[7, 8], []]", [][]int {{7, 8}, {}}, true},
|
297
|
+
}
|
298
|
+
)
|
299
|
+
for _, x := range xs {
|
300
|
+
var got [][]int
|
301
|
+
br := newReader(x.in)
|
302
|
+
err := readOne(br, &got)
|
303
|
+
f := fmt.Sprintf("readOne(%q, *[][]int)", x.in)
|
304
|
+
switch {
|
305
|
+
case x.ok && err != nil:
|
306
|
+
t.Errorf(f + unexpectedError(err))
|
307
|
+
case !x.ok && err == nil:
|
308
|
+
t.Errorf(f + expectError())
|
309
|
+
case !x.ok && err != nil:
|
310
|
+
break
|
311
|
+
case !reflect.DeepEqual(got, x.out):
|
312
|
+
t.Errorf(f + mismatch(got, x.out))
|
313
|
+
}
|
314
|
+
}
|
315
|
+
}
|
316
|
+
|
317
|
+
func TestReadAll(t *testing.T) {
|
318
|
+
var (
|
319
|
+
name string
|
320
|
+
age int
|
321
|
+
gender byte
|
322
|
+
average float32
|
323
|
+
courses []string
|
324
|
+
grades [][]float64
|
325
|
+
)
|
326
|
+
in := "\"Joe\", 20, 'M', 7.5, [\"Math\", \"Computer \"Science\"\"], [[7, 8], []]"
|
327
|
+
br := newReader(in)
|
328
|
+
f := fmt.Sprintf("Read(%v)", in)
|
329
|
+
Read(br, &name, &age, &gender, &average, &courses, &grades)
|
330
|
+
if name != "Joe" || age != 20 || average != 7.5 || gender != 'M' ||
|
331
|
+
!reflect.DeepEqual(courses, []string{"Math", "Computer \"Science\""}) ||
|
332
|
+
!reflect.DeepEqual(grades, [][]float64{{7, 8}, {}}) {
|
333
|
+
t.Errorf(f + " produces (%q, %d, &q, %f, %v, %v)", name, age, gender, average, courses, grades)
|
334
|
+
}
|
335
|
+
}
|