-
-
Notifications
You must be signed in to change notification settings - Fork 655
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #674 from leenipper/variable-length-quantity-add-g…
…enerator variable-length-quantity: create test case generator
- Loading branch information
Showing
4 changed files
with
347 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"text/template" | ||
|
||
"../../../gen" | ||
) | ||
|
||
func main() { | ||
t := template.New("").Funcs(template.FuncMap{ | ||
"GroupComment": GroupComment, | ||
"byteSlice": byteSlice, | ||
"lengthSlice": lengthSlice, | ||
}) | ||
t, err := t.Parse(tmpl) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
var j js | ||
if err := gen.Gen("variable-length-quantity", &j, t); err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
// byteSlice converts a slice of uint32 to a byte slice. | ||
func byteSlice(ns []uint32) []byte { | ||
b := make([]byte, len(ns)) | ||
for i, n := range ns { | ||
b[i] = byte(n) | ||
} | ||
return b | ||
} | ||
|
||
// lengthSlice returns the length of given slice. | ||
func lengthSlice(ns []uint32) int { | ||
return len(ns) | ||
} | ||
|
||
// The JSON structure we expect to be able to unmarshal into | ||
type js struct { | ||
Groups []TestGroup `json:"Cases"` | ||
} | ||
|
||
type TestGroup struct { | ||
Description string | ||
Cases []OneCase | ||
} | ||
|
||
type OneCase struct { | ||
Description string | ||
Property string // "encode" or "decode" | ||
Input []uint32 // supports both []byte and []uint32 in JSON. | ||
Expected []uint32 // supports []byte, []uint32, or null in JSON. | ||
} | ||
|
||
// PropertyMatch returns true when given test case c has .Property field matching property; | ||
// this serves as a filter to put test cases with "like" property into the same group. | ||
func (c OneCase) PropertyMatch(property string) bool { return c.Property == property } | ||
|
||
// GroupComment looks in each of the test case groups to find the | ||
// group for which every test case has the .Property matching given property; | ||
// it returns the .Description field for the matching property group, | ||
// or a 'Note: ...' if no test group consistently matches given property. | ||
func GroupComment(groups []TestGroup, property string) string { | ||
for _, group := range groups { | ||
propertyGroupMatch := true | ||
for _, testcase := range group.Cases { | ||
if !testcase.PropertyMatch(property) { | ||
propertyGroupMatch = false | ||
break | ||
} | ||
} | ||
if propertyGroupMatch { | ||
return group.Description | ||
} | ||
} | ||
return "Note: Apparent inconsistent use of \"property\": \"" + property + "\" within test case group!" | ||
} | ||
|
||
// template applied to above data structure generates the Go test cases | ||
var tmpl = `package variablelengthquantity | ||
{{.Header}} | ||
// {{GroupComment .J.Groups "encode"}} | ||
var encodeTestCases = []struct { | ||
description string | ||
input []uint32 | ||
output []byte | ||
}{ {{range .J.Groups}} {{range .Cases}} | ||
{{if .PropertyMatch "encode"}} { | ||
{{printf "%q" .Description}}, | ||
{{printf "%#v" .Input }}, | ||
{{byteSlice .Expected | printf "%#v" }}, | ||
},{{- end}}{{end}}{{end}} | ||
} | ||
// {{GroupComment .J.Groups "decode"}} | ||
var decodeTestCases = []struct { | ||
description string | ||
input []byte | ||
output []uint32 // nil slice indicates error expected. | ||
size int | ||
}{ {{range .J.Groups}} {{range .Cases}} | ||
{{if .PropertyMatch "decode"}} { | ||
{{printf "%q" .Description}}, | ||
{{byteSlice .Input | printf "%#v" }}, | ||
{{printf "%#v" .Expected }}, | ||
{{lengthSlice .Input}}, | ||
},{{- end}}{{end}}{{end}} | ||
} | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package variablelengthquantity | ||
|
||
// Source: exercism/x-common | ||
// Commit: d6a62f7 variable-length-quantity: Fix canonical-data.json formatting | ||
// x-common version: 1.0.0 | ||
|
||
// Encode a series of integers, producing a series of bytes. | ||
var encodeTestCases = []struct { | ||
description string | ||
input []uint32 | ||
output []byte | ||
}{ | ||
{ | ||
"zero", | ||
[]uint32{0x0}, | ||
[]byte{0x0}, | ||
}, | ||
{ | ||
"arbitrary single byte", | ||
[]uint32{0x40}, | ||
[]byte{0x40}, | ||
}, | ||
{ | ||
"largest single byte", | ||
[]uint32{0x7f}, | ||
[]byte{0x7f}, | ||
}, | ||
{ | ||
"smallest double byte", | ||
[]uint32{0x80}, | ||
[]byte{0x81, 0x0}, | ||
}, | ||
{ | ||
"arbitrary double byte", | ||
[]uint32{0x2000}, | ||
[]byte{0xc0, 0x0}, | ||
}, | ||
{ | ||
"largest double byte", | ||
[]uint32{0x3fff}, | ||
[]byte{0xff, 0x7f}, | ||
}, | ||
{ | ||
"smallest triple byte", | ||
[]uint32{0x4000}, | ||
[]byte{0x81, 0x80, 0x0}, | ||
}, | ||
{ | ||
"arbitrary triple byte", | ||
[]uint32{0x100000}, | ||
[]byte{0xc0, 0x80, 0x0}, | ||
}, | ||
{ | ||
"largest triple byte", | ||
[]uint32{0x1fffff}, | ||
[]byte{0xff, 0xff, 0x7f}, | ||
}, | ||
{ | ||
"smallest quadruple byte", | ||
[]uint32{0x200000}, | ||
[]byte{0x81, 0x80, 0x80, 0x0}, | ||
}, | ||
{ | ||
"arbitrary quadruple byte", | ||
[]uint32{0x8000000}, | ||
[]byte{0xc0, 0x80, 0x80, 0x0}, | ||
}, | ||
{ | ||
"largest quadruple byte", | ||
[]uint32{0xfffffff}, | ||
[]byte{0xff, 0xff, 0xff, 0x7f}, | ||
}, | ||
{ | ||
"smallest quintuple byte", | ||
[]uint32{0x10000000}, | ||
[]byte{0x81, 0x80, 0x80, 0x80, 0x0}, | ||
}, | ||
{ | ||
"arbitrary quintuple byte", | ||
[]uint32{0xff000000}, | ||
[]byte{0x8f, 0xf8, 0x80, 0x80, 0x0}, | ||
}, | ||
{ | ||
"maximum 32-bit integer input", | ||
[]uint32{0xffffffff}, | ||
[]byte{0x8f, 0xff, 0xff, 0xff, 0x7f}, | ||
}, | ||
{ | ||
"two single-byte values", | ||
[]uint32{0x40, 0x7f}, | ||
[]byte{0x40, 0x7f}, | ||
}, | ||
{ | ||
"two multi-byte values", | ||
[]uint32{0x4000, 0x123456}, | ||
[]byte{0x81, 0x80, 0x0, 0xc8, 0xe8, 0x56}, | ||
}, | ||
{ | ||
"many multi-byte values", | ||
[]uint32{0x2000, 0x123456, 0xfffffff, 0x0, 0x3fff, 0x4000}, | ||
[]byte{0xc0, 0x0, 0xc8, 0xe8, 0x56, 0xff, 0xff, 0xff, 0x7f, 0x0, 0xff, 0x7f, 0x81, 0x80, 0x0}, | ||
}, | ||
} | ||
|
||
// Decode a series of bytes, producing a series of integers. | ||
var decodeTestCases = []struct { | ||
description string | ||
input []byte | ||
output []uint32 // nil slice indicates error expected. | ||
size int | ||
}{ | ||
|
||
{ | ||
"one byte", | ||
[]byte{0x7f}, | ||
[]uint32{0x7f}, | ||
1, | ||
}, | ||
{ | ||
"two bytes", | ||
[]byte{0xc0, 0x0}, | ||
[]uint32{0x2000}, | ||
2, | ||
}, | ||
{ | ||
"three bytes", | ||
[]byte{0xff, 0xff, 0x7f}, | ||
[]uint32{0x1fffff}, | ||
3, | ||
}, | ||
{ | ||
"four bytes", | ||
[]byte{0x81, 0x80, 0x80, 0x0}, | ||
[]uint32{0x200000}, | ||
4, | ||
}, | ||
{ | ||
"maximum 32-bit integer", | ||
[]byte{0x8f, 0xff, 0xff, 0xff, 0x7f}, | ||
[]uint32{0xffffffff}, | ||
5, | ||
}, | ||
{ | ||
"incomplete sequence causes error", | ||
[]byte{0xff}, | ||
[]uint32(nil), | ||
1, | ||
}, | ||
{ | ||
"incomplete sequence causes error, even if value is zero", | ||
[]byte{0x80}, | ||
[]uint32(nil), | ||
1, | ||
}, | ||
{ | ||
"multiple values", | ||
[]byte{0xc0, 0x0, 0xc8, 0xe8, 0x56, 0xff, 0xff, 0xff, 0x7f, 0x0, 0xff, 0x7f, 0x81, 0x80, 0x0}, | ||
[]uint32{0x2000, 0x123456, 0xfffffff, 0x0, 0x3fff, 0x4000}, | ||
15, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.