summaryrefslogtreecommitdiff
path: root/go/forth/cases_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/forth/cases_test.go')
-rw-r--r--go/forth/cases_test.go309
1 files changed, 309 insertions, 0 deletions
diff --git a/go/forth/cases_test.go b/go/forth/cases_test.go
new file mode 100644
index 0000000..63f1f19
--- /dev/null
+++ b/go/forth/cases_test.go
@@ -0,0 +1,309 @@
+package forth
+
+// Source: exercism/problem-specifications
+// Commit: c853973 forth: add tests for word redefinition (#1243)
+// Problem Specifications Version: 1.6.0
+
+type testGroup struct {
+ group string
+ tests []testCase
+}
+
+type testCase struct {
+ description string
+ input []string
+ expected []int // nil slice indicates error expected.
+}
+
+var testGroups = []testGroup{
+ {
+ group: "parsing and numbers",
+ tests: []testCase{
+ {
+ "numbers just get pushed onto the stack",
+ []string{"1 2 3 4 5"},
+ []int{1, 2, 3, 4, 5},
+ },
+ },
+ },
+ {
+ group: "addition",
+ tests: []testCase{
+ {
+ "can add two numbers",
+ []string{"1 2 +"},
+ []int{3},
+ },
+ {
+ "errors if there is nothing on the stack",
+ []string{"+"},
+ []int(nil),
+ },
+ {
+ "errors if there is only one value on the stack",
+ []string{"1 +"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "subtraction",
+ tests: []testCase{
+ {
+ "can subtract two numbers",
+ []string{"3 4 -"},
+ []int{-1},
+ },
+ {
+ "errors if there is nothing on the stack",
+ []string{"-"},
+ []int(nil),
+ },
+ {
+ "errors if there is only one value on the stack",
+ []string{"1 -"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "multiplication",
+ tests: []testCase{
+ {
+ "can multiply two numbers",
+ []string{"2 4 *"},
+ []int{8},
+ },
+ {
+ "errors if there is nothing on the stack",
+ []string{"*"},
+ []int(nil),
+ },
+ {
+ "errors if there is only one value on the stack",
+ []string{"1 *"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "division",
+ tests: []testCase{
+ {
+ "can divide two numbers",
+ []string{"12 3 /"},
+ []int{4},
+ },
+ {
+ "performs integer division",
+ []string{"8 3 /"},
+ []int{2},
+ },
+ {
+ "errors if dividing by zero",
+ []string{"4 0 /"},
+ []int(nil),
+ },
+ {
+ "errors if there is nothing on the stack",
+ []string{"/"},
+ []int(nil),
+ },
+ {
+ "errors if there is only one value on the stack",
+ []string{"1 /"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "combined arithmetic",
+ tests: []testCase{
+ {
+ "addition and subtraction",
+ []string{"1 2 + 4 -"},
+ []int{-1},
+ },
+ {
+ "multiplication and division",
+ []string{"2 4 * 3 /"},
+ []int{2},
+ },
+ },
+ },
+ {
+ group: "dup",
+ tests: []testCase{
+ {
+ "copies a value on the stack",
+ []string{"1 dup"},
+ []int{1, 1},
+ },
+ {
+ "copies the top value on the stack",
+ []string{"1 2 dup"},
+ []int{1, 2, 2},
+ },
+ {
+ "errors if there is nothing on the stack",
+ []string{"dup"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "drop",
+ tests: []testCase{
+ {
+ "removes the top value on the stack if it is the only one",
+ []string{"1 drop"},
+ []int{},
+ },
+ {
+ "removes the top value on the stack if it is not the only one",
+ []string{"1 2 drop"},
+ []int{1},
+ },
+ {
+ "errors if there is nothing on the stack",
+ []string{"drop"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "swap",
+ tests: []testCase{
+ {
+ "swaps the top two values on the stack if they are the only ones",
+ []string{"1 2 swap"},
+ []int{2, 1},
+ },
+ {
+ "swaps the top two values on the stack if they are not the only ones",
+ []string{"1 2 3 swap"},
+ []int{1, 3, 2},
+ },
+ {
+ "errors if there is nothing on the stack",
+ []string{"swap"},
+ []int(nil),
+ },
+ {
+ "errors if there is only one value on the stack",
+ []string{"1 swap"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "over",
+ tests: []testCase{
+ {
+ "copies the second element if there are only two",
+ []string{"1 2 over"},
+ []int{1, 2, 1},
+ },
+ {
+ "copies the second element if there are more than two",
+ []string{"1 2 3 over"},
+ []int{1, 2, 3, 2},
+ },
+ {
+ "errors if there is nothing on the stack",
+ []string{"over"},
+ []int(nil),
+ },
+ {
+ "errors if there is only one value on the stack",
+ []string{"1 over"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "user-defined words",
+ tests: []testCase{
+ {
+ "can consist of built-in words",
+ []string{": dup-twice dup dup ;", "1 dup-twice"},
+ []int{1, 1, 1},
+ },
+ {
+ "execute in the right order",
+ []string{": countup 1 2 3 ;", "countup"},
+ []int{1, 2, 3},
+ },
+ {
+ "can override other user-defined words",
+ []string{": foo dup ;", ": foo dup dup ;", "1 foo"},
+ []int{1, 1, 1},
+ },
+ {
+ "can override built-in words",
+ []string{": swap dup ;", "1 swap"},
+ []int{1, 1},
+ },
+ {
+ "can override built-in operators",
+ []string{": + * ;", "3 4 +"},
+ []int{12},
+ },
+ {
+ "can use different words with the same name",
+ []string{": foo 5 ;", ": bar foo ;", ": foo 6 ;", "bar foo"},
+ []int{5, 6},
+ },
+ {
+ "can define word that uses word with the same name",
+ []string{": foo 10 ;", ": foo foo 1 + ;", "foo"},
+ []int{11},
+ },
+ {
+ "cannot redefine numbers",
+ []string{": 1 2 ;"},
+ []int(nil),
+ },
+ {
+ "errors if executing a non-existent word",
+ []string{"foo"},
+ []int(nil),
+ },
+ },
+ },
+ {
+ group: "case-insensitivity",
+ tests: []testCase{
+ {
+ "DUP is case-insensitive",
+ []string{"1 DUP Dup dup"},
+ []int{1, 1, 1, 1},
+ },
+ {
+ "DROP is case-insensitive",
+ []string{"1 2 3 4 DROP Drop drop"},
+ []int{1},
+ },
+ {
+ "SWAP is case-insensitive",
+ []string{"1 2 SWAP 3 Swap 4 swap"},
+ []int{2, 3, 4, 1},
+ },
+ {
+ "OVER is case-insensitive",
+ []string{"1 2 OVER Over over"},
+ []int{1, 2, 1, 2, 1},
+ },
+ {
+ "user-defined words are case-insensitive",
+ []string{": foo dup ;", "1 FOO Foo foo"},
+ []int{1, 1, 1, 1},
+ },
+ {
+ "definitions are case-insensitive",
+ []string{": SWAP DUP Dup dup ;", "1 swap"},
+ []int{1, 1, 1, 1},
+ },
+ },
+ },
+}