Skip to content

Commit

Permalink
wordy: create test case generator (#949)
Browse files Browse the repository at this point in the history
Add .meta/gen.go to generate cases_test.go.

Update test program to use generated test case array.
Put FAIL and PASS in test result output.

For #605.
  • Loading branch information
leenipper authored Nov 13, 2017
1 parent edde64a commit 87d9c28
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 29 deletions.
76 changes: 76 additions & 0 deletions exercises/wordy/.meta/gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"log"
"text/template"

"../../../gen"
)

func main() {
t, err := template.New("").Parse(tmpl)
if err != nil {
log.Fatal(err)
}
var j js
if err := gen.Gen("wordy", &j, t); err != nil {
log.Fatal(err)
}
}

type OneCase struct {
Description string
Input string
Expected interface{}
}

// The JSON structure we expect to be able to unmarshal into
type js struct {
Cases []OneCase
}

func (c OneCase) Valid() bool {
valid, _ := determineExpected(c.Expected)
return valid
}

func (c OneCase) Answer() int {
_, answer := determineExpected(c.Expected)
return answer
}

// determineExpected examines an .Expected interface{} object and determines
// whether a test case is valid(bool) and has an answer or expects an error.
// returning valid and answer.
func determineExpected(expected interface{}) (bool, int) {
ans, ok := expected.(float64)
if ok {
return ok, int(ans)
}
return false, 0
}

// template applied to above data structure generates the Go test cases
var tmpl = `package wordy
{{.Header}}
type wordyTest struct {
description string
question string
ok bool
answer int
}
var tests = []wordyTest {
{{range .J.Cases}}{
"{{.Description}}",
"{{.Input}}",
{{if .Valid}} true,
{{.Answer}},
{{- else}} false,
0,
{{- end}}
},
{{end}}}
`
111 changes: 111 additions & 0 deletions exercises/wordy/cases_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package wordy

// Source: exercism/problem-specifications
// Commit: 5b8ad58 wordy: Fix canonical-data.json formatting
// Problem Specifications Version: 1.0.0

type wordyTest struct {
description string
question string
ok bool
answer int
}

var tests = []wordyTest{
{
"addition",
"What is 1 plus 1?",
true,
2,
},
{
"more addition",
"What is 53 plus 2?",
true,
55,
},
{
"addition with negative numbers",
"What is -1 plus -10?",
true,
-11,
},
{
"large addition",
"What is 123 plus 45678?",
true,
45801,
},
{
"subtraction",
"What is 4 minus -12?",
true,
16,
},
{
"multiplication",
"What is -3 multiplied by 25?",
true,
-75,
},
{
"division",
"What is 33 divided by -3?",
true,
-11,
},
{
"multiple additions",
"What is 1 plus 1 plus 1?",
true,
3,
},
{
"addition and subtraction",
"What is 1 plus 5 minus -2?",
true,
8,
},
{
"multiple subtraction",
"What is 20 minus 4 minus 13?",
true,
3,
},
{
"subtraction then addition",
"What is 17 minus 6 plus 3?",
true,
14,
},
{
"multiple multiplication",
"What is 2 multiplied by -2 multiplied by 3?",
true,
-12,
},
{
"addition and multiplication",
"What is -3 plus 7 multiplied by -2?",
true,
-8,
},
{
"multiple division",
"What is -12 divided by 2 divided by -3?",
true,
2,
},
{
"unknown operation",
"What is 52 cubed?",
false,
0,
},
{
"Non math question",
"Who is the President of the United States?",
false,
0,
},
}
36 changes: 7 additions & 29 deletions exercises/wordy/wordy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,27 @@ package wordy

import "testing"

var tests = []struct {
q string
a int
ok bool
}{
{"What is 1 plus 1?", 2, true},
{"What is 53 plus 2?", 55, true},
{"What is -1 plus -10?", -11, true},
{"What is 123 plus 45678?", 45801, true},
{"What is 4 minus -12?", 16, true},
{"What is -3 multiplied by 25?", -75, true},
{"What is 33 divided by -3?", -11, true},
{"What is 1 plus 1 plus 1?", 3, true},
{"What is 1 plus 5 minus -2?", 8, true},
{"What is 20 minus 4 minus 13?", 3, true},
{"What is 17 minus 6 plus 3?", 14, true},
{"What is 2 multiplied by -2 multiplied by 3?", -12, true},
{"What is -3 plus 7 multiplied by -2?", -8, true},
{"What is -12 divided by 2 divided by -3?", 2, true},
{"What is 53 cubed?", 0, false},
{"Who is the president of the United States?", 0, false},
}

func TestAnswer(t *testing.T) {
for _, test := range tests {
switch a, ok := Answer(test.q); {
switch answer, ok := Answer(test.question); {
case !ok:
if test.ok {
t.Errorf("Answer(%q) returned ok = false, expecting true.", test.q)
t.Fatalf("FAIL: %s\nAnswer(%q)\nreturned ok = false, expecting true.", test.description, test.question)
}
case !test.ok:
t.Errorf("Answer(%q) = %d, %t, expecting ok = false.", test.q, a, ok)
case a != test.a:
t.Errorf("Answer(%q) = %d, want %d.", test.q, a, test.a)
t.Errorf("FAIL: %s\nAnswer(%q)\nreturned %d, %t, expecting ok = false.", test.description, test.question, answer, ok)
case answer != test.answer:
t.Errorf("FAIL: %s\nAnswer(%q)\nreturned %d, expected %d.", test.description, test.question, answer, test.answer)
}
t.Logf("PASS: %s", test.description)
}
}

// Benchmark combined time to answer all questions.
func BenchmarkAnswer(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, test := range tests {
Answer(test.q)
Answer(test.question)
}
}
}

0 comments on commit 87d9c28

Please sign in to comment.