Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug/#142 clauses and statements #148

Merged
merged 14 commits into from
Oct 28, 2018
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ install:
dep ensure

test:
go test -v -race ${DIR_PKG}/...
go test -race ${DIR_PKG}/...

cover:
go test -race -coverprofile=coverage.txt -covermode=atomic ${DIR_PKG}/...
Expand Down
45 changes: 45 additions & 0 deletions pkg/compiler/compiler_collect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,51 @@ func TestCollect(t *testing.T) {
So(err, ShouldNotBeNil)
})

Convey("Should not have access to variables defined before COLLECT", t, func() {
c := compiler.New()

_, err := c.Compile(`
LET users = [
{
active: true,
married: true,
age: 31,
gender: "m"
},
{
active: true,
married: false,
age: 25,
gender: "f"
},
{
active: true,
married: false,
age: 36,
gender: "m"
},
{
active: false,
married: true,
age: 69,
gender: "m"
},
{
active: true,
married: true,
age: 45,
gender: "f"
}
]
FOR i IN users
LET x = "foo"
COLLECT gender = i.gender
RETURN {x, gender}
`)

So(err, ShouldNotBeNil)
})

Convey("Should group result by a single key", t, func() {
c := compiler.New()

Expand Down
56 changes: 56 additions & 0 deletions pkg/compiler/compiler_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package compiler_test
import (
"context"
"github.com/MontFerret/ferret/pkg/compiler"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
. "github.com/smartystreets/goconvey/convey"
"testing"
)
Expand Down Expand Up @@ -311,6 +313,60 @@ func TestForFilter(t *testing.T) {

So(string(out), ShouldEqual, `[]`)
})

Convey("Should define variables", t, func() {
c := compiler.New()

p, err := c.Compile(`
FOR i IN [ 1, 2, 3, 4, 1, 3 ]
LET x = 2
FILTER i > x
RETURN i + x
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, `[5,6,5]`)
})

Convey("Should call funcions", t, func() {
c := compiler.New()
counterA := 0
counterB := 0
c.RegisterFunction("COUNT_A", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counterA++

return values.None, nil
})

c.RegisterFunction("COUNT_B", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counterB++

return values.None, nil
})

p, err := c.Compile(`
FOR i IN [ 1, 2, 3, 4, 1, 3 ]
LET x = 2
COUNT_A()
FILTER i > x
COUNT_B()
RETURN i + x
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)
So(counterA, ShouldEqual, 6)
So(counterB, ShouldEqual, 3)
So(string(out), ShouldEqual, `[5,6,5]`)
})
}

func BenchmarkFilter(b *testing.B) {
Expand Down
148 changes: 0 additions & 148 deletions pkg/compiler/compiler_for_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,154 +248,6 @@ func TestFor(t *testing.T) {

So(string(out), ShouldEqual, `[1,2,3,4]`)
})

Convey("Should compile query with LIMIT 2", t, func() {
c := compiler.New()

p, err := c.Compile(`
FOR i IN [ 1, 2, 3, 4, 1, 3 ]
LIMIT 2
RETURN i
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, `[1,2]`)
})

Convey("Should compile query with LIMIT 2, 2", t, func() {
c := compiler.New()

// 4 is offset
// 2 is count
p, err := c.Compile(`
FOR i IN [ 1,2,3,4,5,6,7,8 ]
LIMIT 4, 2
RETURN i
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, `[5,6]`)
})

Convey("Should compile query with SORT statement", t, func() {
c := compiler.New()

p, err := c.Compile(`
LET users = [
{
active: true,
age: 31,
gender: "m"
},
{
active: true,
age: 29,
gender: "f"
},
{
active: true,
age: 36,
gender: "m"
}
]
FOR u IN users
SORT u.age
RETURN u
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, `[{"active":true,"age":29,"gender":"f"},{"active":true,"age":31,"gender":"m"},{"active":true,"age":36,"gender":"m"}]`)
})

Convey("Should compile query with SORT DESC statement", t, func() {
c := compiler.New()

p, err := c.Compile(`
LET users = [
{
active: true,
age: 31,
gender: "m"
},
{
active: true,
age: 29,
gender: "f"
},
{
active: true,
age: 36,
gender: "m"
}
]
FOR u IN users
SORT u.age DESC
RETURN u
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, `[{"active":true,"age":36,"gender":"m"},{"active":true,"age":31,"gender":"m"},{"active":true,"age":29,"gender":"f"}]`)
})

Convey("Should compile query with SORT statement with multiple expressions", t, func() {
c := compiler.New()

p, err := c.Compile(`
LET users = [
{
active: true,
age: 31,
gender: "m"
},
{
active: true,
age: 29,
gender: "f"
},
{
active: true,
age: 31,
gender: "f"
},
{
active: true,
age: 36,
gender: "m"
}
]
FOR u IN users
SORT u.age, u.gender
RETURN u
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, `[{"active":true,"age":29,"gender":"f"},{"active":true,"age":31,"gender":"f"},{"active":true,"age":31,"gender":"m"},{"active":true,"age":36,"gender":"m"}]`)
})
}

func BenchmarkForEmpty(b *testing.B) {
Expand Down
96 changes: 96 additions & 0 deletions pkg/compiler/compiler_limit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package compiler_test

import (
"context"
"github.com/MontFerret/ferret/pkg/compiler"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
. "github.com/smartystreets/goconvey/convey"
"testing"
)

func TestForLimit(t *testing.T) {
Convey("Should compile query with LIMIT 2", t, func() {
c := compiler.New()

p, err := c.Compile(`
FOR i IN [ 1, 2, 3, 4, 1, 3 ]
LIMIT 2
RETURN i
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, `[1,2]`)
})

Convey("Should compile query with LIMIT 2, 2", t, func() {
c := compiler.New()

// 4 is offset
// 2 is count
p, err := c.Compile(`
FOR i IN [ 1,2,3,4,5,6,7,8 ]
LIMIT 4, 2
RETURN i
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, `[5,6]`)
})

Convey("Should define variables and call functions", t, func() {
c := compiler.New()
counter := 0
c.RegisterFunction("TEST", func(ctx context.Context, args ...core.Value) (core.Value, error) {
counter++

So(args[0], ShouldEqual, "foo")

return values.None, nil
})

p, err := c.Compile(`
FOR i IN [ 1,2,3,4,5,6,7,8 ]
LET x = "foo"
TEST(x)
LIMIT 2
RETURN i
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)
So(counter, ShouldEqual, 2)
So(string(out), ShouldEqual, `[1,2]`)
})

Convey("Should be able to reuse values from a source", t, func() {
c := compiler.New()

p, err := c.Compile(`
FOR i IN [ 1,2,3,4,5,6,7,8 ]
LET x = i
LIMIT 2
RETURN i*x
`)

So(err, ShouldBeNil)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)
So(string(out), ShouldEqual, `[1,4]`)
})
}
Loading