From 57934b0aef13c47bf6f4b22fb9f3cb472e711ee7 Mon Sep 17 00:00:00 2001 From: Saverio Miroddi Date: Tue, 3 Oct 2017 22:42:38 +0200 Subject: [PATCH] First batch of UTs for the Float class --- vm/float_test.go | 154 +++++++++++++++++++++++++++++++++++++++++++++++ vm/vm_test.go | 20 ++++++ 2 files changed, 174 insertions(+) create mode 100644 vm/float_test.go diff --git a/vm/float_test.go b/vm/float_test.go new file mode 100644 index 000000000..2a27780e4 --- /dev/null +++ b/vm/float_test.go @@ -0,0 +1,154 @@ +package vm + +import ( + "testing" +) + +func TestFloatClassSuperclass(t *testing.T) { + tests := []struct { + input string + expected string + }{ + {`Float.class.name`, "Class"}, + {`Float.superclass.name`, "Object"}, + } + + for i, tt := range tests { + v := initTestVM() + evaluated := v.testEval(t, tt.input, getFilename()) + checkExpected(t, i, evaluated, tt.expected) + v.checkCFP(t, i, 0) + v.checkSP(t, i, 1) + } +} + +func TestFloatArithmeticOperation(t *testing.T) { + tests := []struct { + input string + expected interface{} + }{ + {`'1'.to_f + '2'.to_f`, 3.0}, + {`'10'.to_f + '0'.to_f`, 10.0}, + {`'22'.to_f - '10'.to_f`, 12.0}, + {`'2'.to_f - '10'.to_f`, -8.0}, + {`'5'.to_f * '20'.to_f`, 100.0}, + {`'4'.to_f % '2'.to_f`, 0.0}, + {`'10'.to_f % '3'.to_f`, 1.0}, + {`'6'.to_f % '4'.to_f`, 2.0}, + {`'25'.to_f / '5'.to_f`, 5.0}, + {`'5'.to_f ** '4'.to_f`, 625.0}, + {`'25'.to_f / '5'.to_f`, 5.0}, + {`'1'.to_f / '1'.to_f + '1'.to_f`, 2.0}, + {`'0'.to_f / ('1'.to_f + '1000'.to_f)`, 0.0}, + {`'5'.to_f ** ('3'.to_f * '2'.to_f) + '21'.to_f`, 15646.0}, + {`('3'.to_f - '1'.to_f) ** '4'.to_f / '2'.to_f`, 8.0}, + {`('25'.to_f / '5'.to_f + '5'.to_f) * '3'.to_f`, 30.0}, + {`('25'.to_f / '5'.to_f + '5'.to_f) * '2'.to_f`, 20.0}, + } + + for i, tt := range tests { + v := initTestVM() + evaluated := v.testEval(t, tt.input, getFilename()) + checkExpected(t, i, evaluated, tt.expected) + v.checkCFP(t, i, 0) + v.checkSP(t, i, 1) + } +} + +func TestFloatArithmeticOperationFail(t *testing.T) { + testsFail := []errorTestCase{ + {`'1'.to_f + "p"`, "TypeError: Expect argument to be Float. got: String", 1}, + {`'1'.to_f - "m"`, "TypeError: Expect argument to be Float. got: String", 1}, + {`'1'.to_f ** "p"`, "TypeError: Expect argument to be Float. got: String", 1}, + {`'1'.to_f / "t"`, "TypeError: Expect argument to be Float. got: String", 1}, + } + + for i, tt := range testsFail { + v := initTestVM() + evaluated := v.testEval(t, tt.input, getFilename()) + checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine) + v.checkCFP(t, i, 1) + v.checkSP(t, i, 1) + } +} + +func TestFloatComparison(t *testing.T) { + tests := []struct { + input string + expected interface{} + }{ + {`'25'.to_f > '5'.to_f`, true}, + {`'4'.to_f > '6'.to_f`, false}, + {`'-5'.to_f < '-4'.to_f`, true}, + {`'100'.to_f < '81'.to_f`, false}, + {`'25'.to_f > '5'.to_f`, true}, + {`'4'.to_f > '6'.to_f`, false}, + {`'4'.to_f >= '4'.to_f`, true}, + {`'2'.to_f >= '5'.to_f`, false}, + {`'-5'.to_f < '-4'.to_f`, true}, + {`'100'.to_f < '81'.to_f`, false}, + {`'10'.to_f <= '10'.to_f`, true}, + {`'10'.to_f <= '0'.to_f`, false}, + {`'10'.to_f <=> '0'.to_f`, 1}, + {`'1'.to_f <=> '2'.to_f`, -1}, + {`'4'.to_f <=> '4'.to_f`, 0}, + {`'123'.to_f == '123'.to_f`, true}, + {`'123'.to_f == '124'.to_f`, false}, + {`'123'.to_f == "'123'.to_f"`, false}, + {`'123'.to_f == (1..3)`, false}, + {`'123'.to_f == { a: '1'.to_f, b: '2'.to_f }`, false}, + {`'123'.to_f == ['1'.to_f, "String", true, 2..5]`, false}, + {`'123'.to_f == Float`, false}, + {`'123'.to_f != '123'.to_f`, false}, + {`'123'.to_f != '124'.to_f`, true}, + {`'123'.to_f != "'123'.to_f"`, true}, + {`'123'.to_f != (1..3)`, true}, + {`'123'.to_f != { a: '1'.to_f, b: '2'.to_f }`, true}, + {`'123'.to_f != ['1'.to_f, "String", true, 2..5]`, true}, + {`'123'.to_f != Float`, true}, + } + + for i, tt := range tests { + v := initTestVM() + evaluated := v.testEval(t, tt.input, getFilename()) + checkExpected(t, i, evaluated, tt.expected) + v.checkCFP(t, i, 0) + v.checkSP(t, i, 1) + } +} + +func TestFloatComparisonFail(t *testing.T) { + testsFail := []errorTestCase{ + {`'1'.to_f > "m"`, "TypeError: Expect argument to be Float. got: String", 1}, + {`'1'.to_f >= "m"`, "TypeError: Expect argument to be Float. got: String", 1}, + {`'1'.to_f < "m"`, "TypeError: Expect argument to be Float. got: String", 1}, + {`'1'.to_f <= "m"`, "TypeError: Expect argument to be Float. got: String", 1}, + {`'1'.to_f <=> "m"`, "TypeError: Expect argument to be Float. got: String", 1}, + } + + for i, tt := range testsFail { + v := initTestVM() + evaluated := v.testEval(t, tt.input, getFilename()) + checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine) + v.checkCFP(t, i, 1) + v.checkSP(t, i, 1) + } +} + +func TestFloatConversion(t *testing.T) { + tests := []struct { + input string + expected interface{} + }{ + {`'100'.to_f.to_i`, 100}, + {`'100'.to_f.to_s`, "100"}, + } + + for i, tt := range tests { + v := initTestVM() + evaluated := v.testEval(t, tt.input, getFilename()) + checkExpected(t, i, evaluated, tt.expected) + v.checkCFP(t, i, 0) + v.checkSP(t, i, 1) + } +} diff --git a/vm/vm_test.go b/vm/vm_test.go index 5b8dc0276..310dad34a 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -209,6 +209,24 @@ func testIntegerObject(t *testing.T, i int, obj Object, expected int) bool { } } +func testFloatObject(t *testing.T, i int, obj Object, expected float64) bool { + switch result := obj.(type) { + case *FloatObject: + if result.value != expected { + t.Errorf("At test case %d: object has wrong value. expect=%d, got=%d", i, expected, result.value) + return false + } + + return true + case *Error: + t.Errorf("At test case %d: %s", i, result.Message) + return false + default: + t.Errorf("At test case %d: object is not Float. got=%T (%+v).", i, obj, obj) + return false + } +} + func testNullObject(t *testing.T, i int, obj Object) bool { switch result := obj.(type) { case *NullObject: @@ -343,6 +361,8 @@ func checkExpected(t *testing.T, i int, evaluated Object, expected interface{}) switch expected := expected.(type) { case int: testIntegerObject(t, i, evaluated, expected) + case float64: + testFloatObject(t, i, evaluated, expected) case string: testStringObject(t, i, evaluated, expected) case bool: