From 1394c1e7f2dde35b7afb147896f35a96d830edcb Mon Sep 17 00:00:00 2001 From: Louis Thibault Date: Mon, 21 Dec 2020 00:03:21 -0500 Subject: [PATCH 1/4] Add tests for VectorExpr.Eval. --- builtin/expr_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/builtin/expr_test.go b/builtin/expr_test.go index af92337..3fce48b 100644 --- a/builtin/expr_test.go +++ b/builtin/expr_test.go @@ -262,6 +262,45 @@ func TestInvokeExpr_Eval(t *testing.T) { }) } +func TestVectorExpr_Eval(t *testing.T) { + t.Run("ConstMembers", func(t *testing.T) { + vec := NewVector(Keyword("foo")) + + any, err := (VectorExpr{ + Analyzer: &Analyzer{}, + Vector: vec, + }).Eval(nil) + + assert.NoError(t, err) + assert.NotNil(t, any) + assert.IsType(t, PersistentVector{}, any) + assert.Equal(t, NewVector(Keyword("foo")), any) + + any, err = any.(core.Vector).EntryAt(0) + assert.NoError(t, err) + assert.Equal(t, Keyword("foo"), any) + }) + + t.Run("SymbolMember", func(t *testing.T) { + env := core.New(map[string]core.Any{"foo": Keyword("foo")}) + vec := NewVector(Symbol("foo")) + + any, err := (VectorExpr{ + Analyzer: &Analyzer{}, + Vector: vec, + }).Eval(env) + + assert.NoError(t, err) + assert.NotNil(t, any) + assert.IsType(t, PersistentVector{}, any) + assert.Equal(t, NewVector(Keyword("foo")), any) + + any, err = any.(core.Vector).EntryAt(0) + assert.NoError(t, err) + assert.Equal(t, Keyword("foo"), any) + }) +} + func runExprTests(t *testing.T, table []exprTest) { for _, tt := range table { t.Run(tt.title, func(t *testing.T) { From d3137669c3372a3684a69f5cf2e438f9435ffab0 Mon Sep 17 00:00:00 2001 From: Louis Thibault Date: Mon, 21 Dec 2020 00:23:22 -0500 Subject: [PATCH 2/4] Bugfix: ensure call to TransientVector.Persistent() happens *after* rd.Container(). --- reader/macros.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/reader/macros.go b/reader/macros.go index d7e38c3..ff12c62 100644 --- a/reader/macros.go +++ b/reader/macros.go @@ -270,8 +270,10 @@ func readVector(rd *Reader, _ rune) (core.Any, error) { const vecEnd = ']' v := builtin.EmptyVector.Transient() - return v.Persistent(), rd.Container(vecEnd, "Vector", func(val core.Any) error { + err := rd.Container(vecEnd, "Vector", func(val core.Any) error { v.Cons(val) return nil }) + + return v.Persistent(), err } From ca7fe3d196f7d6730b22cbbfcd5e3aab28c9cf30 Mon Sep 17 00:00:00 2001 From: Louis Thibault Date: Mon, 21 Dec 2020 00:23:48 -0500 Subject: [PATCH 3/4] Add reader tests for Vector. --- reader/reader_test.go | 125 +++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/reader/reader_test.go b/reader/reader_test.go index b570f15..0b1b639 100644 --- a/reader/reader_test.go +++ b/reader/reader_test.go @@ -127,7 +127,7 @@ func TestReader_All(t *testing.T) { }{ { name: "ValidLiteralSample", - src: `123 "Hello World" 12.34 -0xF +010 true nil 0b1010 \a :hello`, + src: `123 "Hello World" 12.34 -0xF +010 true nil 0b1010 \a :hello [:foo "bar"]`, want: []core.Any{ builtin.Int64(123), builtin.String("Hello World"), @@ -139,6 +139,7 @@ func TestReader_All(t *testing.T) { builtin.Int64(10), builtin.Char('a'), builtin.Keyword("hello"), + builtin.NewVector(builtin.Keyword("foo"), builtin.String("bar")), }, }, { @@ -586,67 +587,67 @@ func TestReader_One_List(t *testing.T) { }) } -// func TestReader_One_Vector(t *testing.T) { -// executeReaderTests(t, []readerTestCase{ -// { -// name: "EmptyVector", -// src: `[]`, -// want: builtin.Vector{}, -// }, -// { -// name: "VectorWithOneEntry", -// src: `[help]`, -// want: builtin.Vector{builtin.Symbol("help")}, -// }, -// { -// name: "VectorWithMultipleEntry", -// src: `[+ 0xF 3.1413]`, -// want: builtin.Vector{ -// builtin.Symbol("+"), -// builtin.Int64(15), -// builtin.Float64(3.1413), -// }, -// }, -// { -// name: "VectorWithCommaSeparator", -// src: `[+,0xF,3.1413]`, -// want: builtin.Vector{ -// builtin.Symbol("+"), -// builtin.Int64(15), -// builtin.Float64(3.1413), -// }, -// }, -// { -// name: "MultiLine", -// src: `[+ -// 0xF -// 3.1413 -// ]`, -// want: builtin.Vector{ -// builtin.Symbol("+"), -// builtin.Int64(15), -// builtin.Float64(3.1413), -// }, -// }, -// { -// name: "MultiLineWithComments", -// src: `[+ ; plus operator adds numerical values -// 0xF ; hex representation of 15 -// 3.1413 ; value of math constant pi -// ]`, -// want: builtin.Vector{ -// builtin.Symbol("+"), -// builtin.Int64(15), -// builtin.Float64(3.1413), -// }, -// }, -// { -// name: "UnexpectedEOF", -// src: "[+ 1 2 ", -// wantErr: true, -// }, -// }) -// } +func TestReader_One_Vector(t *testing.T) { + executeReaderTests(t, []readerTestCase{ + { + name: "EmptyVector", + src: `[]`, + want: builtin.EmptyVector, + }, + { + name: "VectorWithOneEntry", + src: `[help]`, + want: builtin.NewVector(builtin.Symbol("help")), + }, + { + name: "VectorWithMultipleEntry", + src: `[+ 0xF 3.1413]`, + want: builtin.NewVector( + builtin.Symbol("+"), + builtin.Int64(15), + builtin.Float64(3.1413), + ), + }, + { + name: "VectorWithCommaSeparator", + src: `[+,0xF,3.1413]`, + want: builtin.NewVector( + builtin.Symbol("+"), + builtin.Int64(15), + builtin.Float64(3.1413), + ), + }, + { + name: "MultiLine", + src: `[+ + 0xF + 3.1413 + ]`, + want: builtin.NewVector( + builtin.Symbol("+"), + builtin.Int64(15), + builtin.Float64(3.1413), + ), + }, + { + name: "MultiLineWithComments", + src: `[+ ; plus operator adds numerical values + 0xF ; hex representation of 15 + 3.1413 ; value of math constant pi + ]`, + want: builtin.NewVector( + builtin.Symbol("+"), + builtin.Int64(15), + builtin.Float64(3.1413), + ), + }, + { + name: "UnexpectedEOF", + src: "[+ 1 2 ", + wantErr: true, + }, + }) +} type readerTestCase struct { name string From bc9aa3925ce65591bb700955688905cf4aef7008 Mon Sep 17 00:00:00 2001 From: Louis Thibault Date: Mon, 21 Dec 2020 00:24:04 -0500 Subject: [PATCH 4/4] Add unbound symbol test for VectorExpr. --- builtin/expr_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/builtin/expr_test.go b/builtin/expr_test.go index 3fce48b..2c88c84 100644 --- a/builtin/expr_test.go +++ b/builtin/expr_test.go @@ -299,6 +299,18 @@ func TestVectorExpr_Eval(t *testing.T) { assert.NoError(t, err) assert.Equal(t, Keyword("foo"), any) }) + + t.Run("UnboundSymbolMember", func(t *testing.T) { + vec := NewVector(Symbol("foo"), Symbol("bar"), Symbol("baz")) + + any, err := (VectorExpr{ + Analyzer: &Analyzer{}, + Vector: vec, + }).Eval(core.New(nil)) + + assert.Error(t, err) + assert.Nil(t, any) + }) } func runExprTests(t *testing.T, table []exprTest) {