1
0
mirror of https://github.com/MontFerret/ferret.git synced 2025-03-17 21:18:37 +02:00
ferret/pkg/compiler/compiler_use_test.go
2020-05-18 10:51:01 -04:00

247 lines
4.6 KiB
Go

package compiler_test
import (
"context"
"testing"
"github.com/MontFerret/ferret/pkg/compiler"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/stdlib/strings"
"github.com/MontFerret/ferret/pkg/stdlib/types"
. "github.com/smartystreets/goconvey/convey"
)
func TestUseExpression(t *testing.T) {
newCompiler := func() *compiler.Compiler {
c := compiler.New()
err := c.Namespace("X").
RegisterFunctions(core.NewFunctionsFromMap(
map[string]core.Function{
"XXX_CONTAINS": strings.Contains,
"XXX_UPPER": strings.Upper,
},
))
So(err, ShouldBeNil)
return c
}
Convey("Use Expression", t, func() {
Convey("Should compile", func() {
Convey("Single statement", func() {
p, err := newCompiler().Compile(`
USE X
RETURN XXX_CONTAINS("s", "s")
`)
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, "true")
})
Convey("Single statement (lower case)", func() {
p, err := newCompiler().Compile(`
use x
return xxx_contains("s", "s")
`)
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, "true")
})
Convey("Many functions from one lib", func() {
p, err := newCompiler().Compile(`
USE X
RETURN XXX_CONTAINS(XXX_UPPER("s"), "S")
`)
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, "true")
})
Convey("Many statements", func() {
c := newCompiler()
// Z must contain functions different from X
c.Namespace("Z").
RegisterFunction("XXX_TO_STRING", types.ToString)
p, err := c.Compile(`
USE X
USE Z
RETURN XXX_TO_STRING(XXX_CONTAINS("s", "s"))
`)
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, `"true"`)
})
Convey("Namespace doesn't exists", func() {
p, err := newCompiler().Compile(`
USE NOT::EXISTS
RETURN 1
`)
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, "1")
})
Convey("Full and short path works together", func() {
p, err := newCompiler().Compile(`
USE X
LET short = XXX_CONTAINS("s", "s")
LET full = X::XXX_CONTAINS("s", "s")
RETURN short == full
`)
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, "true")
})
Convey("Nested namespace", func() {
c := newCompiler()
c.Namespace("X").
Namespace("Y").
RegisterFunction("YYY_CONTAINS", strings.Contains)
Convey("Short path", func() {
p, err := c.Compile(`
USE X
RETURN Y::YYY_CONTAINS("s", "s")
`)
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, "true")
})
Convey("Full path", func() {
p, err := c.Compile(`
USE X
RETURN X::Y::YYY_CONTAINS("s", "s")
`)
So(err, ShouldBeNil)
out := p.MustRun(context.Background())
So(string(out), ShouldEqual, "true")
})
})
})
Convey("Should not compile", func() {
testCases := []struct {
Name string
Query string
Compiler func() *compiler.Compiler
}{
{
Name: "Wrong namespace format",
Query: `
USE NOT::EXISTS::
RETURN 1`,
},
{
Name: "Empty namespace",
Query: `
USE
RETURN 1`,
},
{
Name: "USE namespace twice",
Query: `
USE X
USE X
RETURN XXX_CONTAINS("s", "s")
`,
},
{
Name: "Functions collision",
Query: `
// Z and Y both contain function "XXX_CONTAINS"
USE Z
USE Y
RETURN 1`,
Compiler: func() *compiler.Compiler {
c := newCompiler()
c.Namespace("Z").
RegisterFunction("XXX_TO_STRING", types.ToString)
// Y contain the same function as Z to test for future collistions
c.Namespace("Y").
RegisterFunction("XXX_TO_STRING", types.ToString)
return c
},
},
{
Name: "Nested namespace collision",
Query: `
USE X
USE Z
RETURN 1
`,
Compiler: func() *compiler.Compiler {
c := newCompiler()
c.Namespace("X").
Namespace("Y").
RegisterFunction("YYY_CONTAINS", strings.Contains)
c.Namespace("Z").
Namespace("Y").
RegisterFunction("YYY_CONTAINS", strings.Contains)
return c
},
},
}
for _, tC := range testCases {
Convey(tC.Name, func() {
c := newCompiler()
if tC.Compiler != nil {
c = tC.Compiler()
}
_, err := c.Compile(tC.Query)
So(err, ShouldNotBeNil)
})
}
})
})
}