Skip to content

Commit

Permalink
improve tests (#49)
Browse files Browse the repository at this point in the history
* improve tests

Signed-off-by: Flipez <code@brauser.io>

* test missing emoji

Signed-off-by: Flipez <code@brauser.io>

* remove expressionNode and statementNode

Signed-off-by: Flipez <code@brauser.io>

* improve object/array tests

Signed-off-by: Flipez <code@brauser.io>

* fix linter warnings

Signed-off-by: Flipez <code@brauser.io>

* fix tests

Signed-off-by: Flipez <code@brauser.io>

* add missing error checks

* simplify make statements

* increase test coverage even more

Co-authored-by: Markus Freitag <fmarkus@mailbox.org>
  • Loading branch information
Flipez and MarkusFreitag authored Jan 18, 2022
1 parent bc92247 commit da0b71e
Show file tree
Hide file tree
Showing 36 changed files with 231 additions and 57 deletions.
1 change: 0 additions & 1 deletion ast/array.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type Array struct {
Elements []Expression
}

func (al *Array) expressionNode() {}
func (al *Array) TokenLiteral() string { return al.Token.Literal }
func (al *Array) String() string {
var out bytes.Buffer
Expand Down
2 changes: 0 additions & 2 deletions ast/assign.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ type Assign struct {
Value Expression
}

func (as *Assign) expressionNode() {}
func (as *Assign) statementNode() {}
func (as *Assign) TokenLiteral() string { return as.Token.Literal }
func (as *Assign) String() string {
var out bytes.Buffer
Expand Down
2 changes: 0 additions & 2 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ type Node interface {

type Statement interface {
Node
statementNode()
}

type Expression interface {
Node
expressionNode()
}

type Program struct {
Expand Down
1 change: 0 additions & 1 deletion ast/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ type Block struct {
Statements []Statement
}

func (bs *Block) statementNode() {}
func (bs *Block) TokenLiteral() string { return bs.Token.Literal }
func (bs *Block) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/boolean.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ type Boolean struct {
Value bool
}

func (b *Boolean) expressionNode() {}
func (b *Boolean) TokenLiteral() string { return b.Token.Literal }
func (b *Boolean) String() string { return b.Token.Literal }
1 change: 0 additions & 1 deletion ast/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ type Call struct {
Arguments []Expression
}

func (ce *Call) expressionNode() {}
func (ce *Call) TokenLiteral() string { return ce.Token.Literal }
func (ce *Call) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/expression_statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ type ExpressionStatement struct {
Expression Expression
}

func (es *ExpressionStatement) statementNode() {}
func (es *ExpressionStatement) TokenLiteral() string { return es.Token.Literal }
func (es *ExpressionStatement) String() string {
if es.Expression != nil {
Expand Down
1 change: 0 additions & 1 deletion ast/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ type Float struct {
Value float64
}

func (fl *Float) expressionNode() {}
func (fl *Float) TokenLiteral() string { return fl.Token.Literal }
func (fl *Float) String() string { return fl.Token.Literal }
1 change: 0 additions & 1 deletion ast/foreach.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ type Foreach struct {
Body *Block
}

func (fes *Foreach) expressionNode() {}
func (fes *Foreach) TokenLiteral() string { return fes.Token.Literal }
func (fes *Foreach) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ type Function struct {
Body *Block
}

func (fl *Function) expressionNode() {}
func (fl *Function) TokenLiteral() string { return fl.Token.Literal }
func (fl *Function) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type Hash struct {
Pairs map[Expression]Expression
}

func (hl *Hash) expressionNode() {}
func (hl *Hash) TokenLiteral() string { return hl.Token.Literal }
func (hl *Hash) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/identifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ type Identifier struct {
Value string
}

func (i *Identifier) expressionNode() {}
func (i *Identifier) TokenLiteral() string { return i.Token.Literal }
func (i *Identifier) String() string { return i.Value }
1 change: 0 additions & 1 deletion ast/if.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ type If struct {
Alternative *Block
}

func (ie *If) expressionNode() {}
func (ie *If) TokenLiteral() string { return ie.Token.Literal }
func (ie *If) String() string {
var out bytes.Buffer
Expand Down
3 changes: 0 additions & 3 deletions ast/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ type Import struct {
Name Expression
}

func (ie *Import) expressionNode() {}

func (ie *Import) TokenLiteral() string { return ie.Token.Literal }

func (ie *Import) String() string {
var out bytes.Buffer

Expand Down
1 change: 0 additions & 1 deletion ast/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type Index struct {
Index Expression
}

func (ie *Index) expressionNode() {}
func (ie *Index) TokenLiteral() string { return ie.Token.Literal }
func (ie *Index) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/infix.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ type Infix struct {
Right Expression
}

func (ie *Infix) expressionNode() {}
func (ie *Infix) TokenLiteral() string { return ie.Token.Literal }
func (ie *Infix) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/integer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ type Integer struct {
Value int64
}

func (il *Integer) expressionNode() {}
func (il *Integer) TokenLiteral() string { return il.Token.Literal }
func (il *Integer) String() string { return il.Token.Literal }
1 change: 0 additions & 1 deletion ast/object_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type ObjectCall struct {
Call Expression
}

func (oce *ObjectCall) expressionNode() {}
func (oce *ObjectCall) TokenLiteral() string { return oce.Token.Literal }
func (oce *ObjectCall) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/prefix.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type Prefix struct {
Right Expression
}

func (pe *Prefix) expressionNode() {}
func (pe *Prefix) TokenLiteral() string { return pe.Token.Literal }
func (pe *Prefix) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/return.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ type Return struct {
ReturnValue Expression
}

func (rs *Return) statementNode() {}
func (rs *Return) TokenLiteral() string { return rs.Token.Literal }
func (rs *Return) String() string {
var out bytes.Buffer
Expand Down
1 change: 0 additions & 1 deletion ast/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ type String struct {
Value string
}

func (sl *String) expressionNode() {}
func (sl *String) TokenLiteral() string { return sl.Token.Literal }
func (sl *String) String() string { return sl.Token.Literal }
13 changes: 12 additions & 1 deletion evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestEvalIntegerExpression(t *testing.T) {
{"3 * 3 * 3 + 10", 37},
{"3 * (3 * 3) + 10", 37},
{"(5 + 10 * 2 + 15 / 3) * 2 + -10", 50},
{"5 ➕ 5 ➕ 5 ➕ 5 - 10", 10},
}

for _, tt := range tests {
Expand Down Expand Up @@ -67,6 +68,12 @@ func TestEvalBooleanExpression(t *testing.T) {
{"(1 < 2) == false", false},
{"(1 > 2) == true", false},
{"(1 > 2) == false", true},
{"👍", true},
{"👎", false},
{"👍 == 👍", true},
{"👍 == 👎", false},
{"👍 != 👎", true},
{"👍 != 👍", false},
}

for _, tt := range tests {
Expand Down Expand Up @@ -173,6 +180,7 @@ func TestErrorHandling(t *testing.T) {
},
{`"Hello" - "World"`, "unknown operator: STRING - STRING"},
{`{"name": "Monkey"}[def(x) { x }];`, "unusable as hash key: FUNCTION"},
{"🔥 != 👍", "identifier not found: IDENT"},
}

for _, tt := range tests {
Expand Down Expand Up @@ -535,7 +543,10 @@ func TestImportExpression(t *testing.T) {
}

func TestImportSearchPaths(t *testing.T) {
utilities.AddPath("../stubs")
if err := utilities.AddPath("../stubs"); err != nil {
t.Errorf("error adding the stubs path: %s", err)
return
}

tests := []struct {
input string
Expand Down
18 changes: 8 additions & 10 deletions object/array.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ func NewArray(slice []Object) *Array {
}

func NewArrayWithObjects(objs ...Object) *Array {
slice := make([]Object, len(objs), len(objs))
for idx, obj := range objs {
slice[idx] = obj
}
slice := make([]Object, len(objs))
copy(slice, objs)
return NewArray(slice)
}

Expand All @@ -28,7 +26,7 @@ func (ao *Array) Inspect() string {
var out bytes.Buffer

length := len(ao.Elements)
elements := make([]string, length, length)
elements := make([]string, length)
for index, element := range ao.Elements {
elements[index] = element.Inspect()
}
Expand Down Expand Up @@ -81,7 +79,7 @@ func init() {
}

length := len(items)
newElements := make([]Object, length, length)
newElements := make([]Object, length)
var idx int
for _, item := range items {
newElements[idx] = item
Expand Down Expand Up @@ -125,7 +123,7 @@ func init() {
method: func(o Object, _ []Object) Object {
ao := o.(*Array)
if len(ao.Elements) == 0 {
return new(Null)
return NULL
}
return ao.Elements[0]
},
Expand All @@ -140,7 +138,7 @@ func init() {
method: func(o Object, _ []Object) Object {
ao := o.(*Array)
if len(ao.Elements) == 0 {
return new(Null)
return NULL
}
return ao.Elements[len(ao.Elements)-1]
},
Expand All @@ -160,7 +158,7 @@ func init() {
ao := o.(*Array)
length := len(ao.Elements)

newElements := make([]Object, length-1, length-1)
newElements := make([]Object, length-1)
copy(newElements, ao.Elements[:(length-1)])

returnElement := ao.Elements[length-1]
Expand Down Expand Up @@ -188,7 +186,7 @@ func init() {
ao := o.(*Array)
length := len(ao.Elements)

newElements := make([]Object, length+1, length+1)
newElements := make([]Object, length+1)
copy(newElements, ao.Elements)
newElements[length] = args[0]

Expand Down
46 changes: 45 additions & 1 deletion object/array_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ import (
"github.com/flipez/rocket-lang/object"
)

func TestNewArrayWithObjects(t *testing.T) {
arr := object.NewArrayWithObjects(object.NewString("a"))
if v := arr.Type(); v != object.ARRAY_OBJ {
t.Errorf("array.Type() return wrong type: %s", v)
}

if v := arr.Elements[0].Type(); v != object.STRING_OBJ {
t.Errorf("first array element should be a string object")
}
}

func TestArrayObject(t *testing.T) {
tests := []inputTestCase{
{"[1] == [1]", true},
{"[1] == [true]", false},
{"[1] == [true, 1]", false},
}

testInput(t, tests)
}

func TestArrayObjectMethods(t *testing.T) {
tests := []inputTestCase{
{`[1,2,3][0]`, 1},
Expand All @@ -19,8 +40,16 @@ func TestArrayObjectMethods(t *testing.T) {
{`[1,2,3].index(4)`, -1},
{`[1,2,3].index(3)`, 2},
{`[1,2,3].index(true)`, -1},
{`[1,2,3].index()`, "To few arguments: want=1, got=0"},
{`[1,2,3].index()`, "to few arguments: want=1, got=0"},
{`a = []; b = []; foreach i in a { b.yoink(a[i]) }; a.size()==b.size()`, true},
{`[1,1,2].uniq().size()`, 2},
{`[true,true,2].uniq().size()`, 2},
{`["test","test",2].uniq().size()`, 2},
{`["12".reverse!()].uniq()`, "failed because element NULL is not hashable"},
{"[].first()", "NULL"},
{"[1,2,3].first()", 1},
{"[].last()", "NULL"},
{"[1,2,3].last()", 3},
}

testInput(t, tests)
Expand All @@ -33,3 +62,18 @@ func TestArrayInspect(t *testing.T) {
t.Errorf("array.Type() returns wrong type")
}
}

func TestArrayHashKey(t *testing.T) {
arr1 := &object.Array{Elements: []object.Object{}}
arr2 := &object.Array{Elements: []object.Object{}}
diff1 := &object.Array{Elements: []object.Object{&object.String{Value: "Hello World"}}}
diff2 := &object.Array{Elements: []object.Object{&object.String{Value: "Hello Another World"}}}

if arr1.HashKey() != arr2.HashKey() {
t.Errorf("arrays with same content have different hash keys")
}

if diff1.HashKey() == diff2.HashKey() {
t.Errorf("arrays with different content have same hash keys")
}
}
2 changes: 2 additions & 0 deletions object/boolean_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ func TestBooleanObjectMethods(t *testing.T) {

// other
{"(true.wat().lines().size() == true.methods().size() + 1).plz_s()", "true"},
{"true == true", true},
{"true == false", false},
}

testInput(t, tests)
Expand Down
30 changes: 30 additions & 0 deletions object/builtin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package object_test

import (
"testing"

"github.com/flipez/rocket-lang/object"
)

func TestBuiltinObjectMethods(t *testing.T) {
tests := []inputTestCase{
{`puts.nope()`, "Failed to invoke method: nope"},
}

testInput(t, tests)
}

func TestBuiltinType(t *testing.T) {
tests := []inputTestCase{
{"puts", "builtin function"},
}

for _, tt := range tests {
def := testEval(tt.input).(*object.Builtin)
defInspect := def.Inspect()

if defInspect != tt.expected {
t.Errorf("wrong string. expected=%#v, got=%#v", tt.expected, defInspect)
}
}
}
Loading

1 comment on commit da0b71e

@vercel
Copy link

@vercel vercel bot commented on da0b71e Jan 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.