Skip to content

Commit

Permalink
Continued Expr migration (#47)
Browse files Browse the repository at this point in the history
* fix: don’t embed resources

We don’t need to ship a binary, we can ship the built files.

* fix: cel references

* Remove CEL dependencies

* fix: make tests runnable, albeit mostly skipped.

* chore: add links to issues for CEL translation

* fix: adjust makefile
  • Loading branch information
polds authored Jan 9, 2024
1 parent 27d30c9 commit 7d7a7fe
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 96 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ test: fmt ## Run tests.

.PHONY: serve
serve: build ## Serve static files.
go run cmd/server/main.go
go run cmd/server/main.go --dir web/

.PHONY: update-data
update-data: ## Update the web/assets/data.json file.
Expand All @@ -36,12 +36,12 @@ update-data: ## Update the web/assets/data.json file.
.PHONY: addlicense
addlicense: ## Add copyright license headers in source code files.
@test -s $(LOCALBIN)/addlicense || GOBIN=$(LOCALBIN) go install github.com/google/addlicense@latest
$(LOCALBIN)/addlicense -c "Undistro Authors; Fork and conversion to Expr by Peter Olds <[email protected]>" -l "apache" -ignore ".github/**" -ignore ".idea/**" -ignore "web/dist/**" .
$(LOCALBIN)/addlicense -c "Undistro Authors; Peter Olds" -l "apache" -ignore ".github/**" -ignore ".idea/**" -ignore "web/dist/**" .

.PHONY: checklicense
checklicense: ## Check copyright license headers in source code files.
@test -s $(LOCALBIN)/addlicense || GOBIN=$(LOCALBIN) go install github.com/google/addlicense@latest
$(LOCALBIN)/addlicense -c "Undistro Authors; Fork and conversion to Expr by Peter Olds <[email protected]>" -l "apache" -ignore ".github/**" -ignore ".idea/**" -ignore "web/dist/**" -check .
$(LOCALBIN)/addlicense -c "Undistro Authors; Peter Olds" -l "apache" -ignore ".github/**" -ignore ".idea/**" -ignore "web/dist/**" -check .

##@ Build

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Please be sure to check out their project and give them a star as well!

## Expr libraries

CEL Playground is built by compiling Go code to WebAssembly. At present only the Expr engine is available in this
Expr Playground is built by compiling Go code to WebAssembly. At present only the Expr engine is available in this
environment. We will look at injecting some other utilities to make this environment more useful, on-par with the the
CEL standard library and CEL Playground.

Expand All @@ -39,4 +39,4 @@ This project adheres to the Contributor Covenant [code of conduct](https://githu

## License

CEL Playground is available under the Apache 2.0 license. See the [LICENSE](LICENSE) file for more info.
Expr Playground and the original CEL Playground is available under the Apache 2.0 license. See the [LICENSE](LICENSE) file for more info.
5 changes: 2 additions & 3 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,16 @@ import (
"flag"
"log"
"net/http"

"github.com/polds/expr-playground/web"
)

var (
listen = flag.String("listen", ":8080", "listen address")
dir = flag.String("dir", ".", "directory to serve")
)

func main() {
flag.Parse()
log.Printf("listening on %s...", *listen)
err := http.ListenAndServe(*listen, http.FileServer(http.FS(web.Assets)))
err := http.ListenAndServe(*listen, http.FileServer(http.Dir(*dir)))
log.Fatalln(err)
}
96 changes: 67 additions & 29 deletions eval/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ package eval

import (
"encoding/json"
"reflect"
"testing"

"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/expr-lang/expr"
"github.com/google/go-cmp/cmp"
)

var input = map[string]any{
Expand All @@ -40,6 +39,7 @@ func TestEval(t *testing.T) {
exp string
want any
wantErr bool
skip bool
}{
{
name: "lte",
Expand All @@ -55,33 +55,39 @@ func TestEval(t *testing.T) {
name: "url",
exp: "isURL(object.href) && url(object.href).getScheme() == 'https' && url(object.href).getEscapedPath() == '/path'",
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/2
},
{
name: "query",
exp: "url(object.href).getQuery()",
want: map[string]any{
"query": []any{"val"},
},
skip: true, // https://github.com/polds/expr-playground/issues/3
},
{
name: "regex",
exp: "object.image.find('v[0-9]+.[0-9]+.[0-9]*$')",
want: "v0.0.0",
skip: true, // https://github.com/polds/expr-playground/issues/4
},
{
name: "list",
exp: "object.items.isSorted() && object.items.sum() == 6 && object.items.max() == 3 && object.items.indexOf(1) == 0",
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/5
},
{
name: "optional",
exp: `object.?foo.orValue("fallback")`,
want: "fallback",
skip: true, // https://github.com/polds/expr-playground/issues/6
},
{
name: "strings",
exp: "object.abc.join(', ')",
want: "a, b, c",
skip: true, // https://github.com/polds/expr-playground/issues/7
},
{
name: "cross type numeric comparisons",
Expand All @@ -92,90 +98,104 @@ func TestEval(t *testing.T) {
name: "split",
exp: "object.image.split(':').size() == 2",
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/8
},
{
name: "quantity",
exp: `isQuantity(object.memory) && quantity(object.memory).add(quantity("700M")).sub(1).isLessThan(quantity("2G"))`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/9
},
{
name: "sets.contains test 1",
exp: `sets.contains([], [])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/10
},
{
name: "sets.contains test 2",
exp: `sets.contains([], [1])`,
want: false,
skip: true, // https://github.com/polds/expr-playground/issues/11
},
{
name: "sets.contains test 3",
exp: `sets.contains([1, 2, 3, 4], [2, 3])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/12
},
{
name: "sets.contains test 4",
exp: `sets.contains([1, 2, 3], [3, 2, 1])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/13
},
{
name: "sets.equivalent test 1",
exp: `sets.equivalent([], [])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/14
},
{
name: "sets.equivalent test 2",
exp: `sets.equivalent([1], [1, 1])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/15
},
{
name: "sets.equivalent test 3",
exp: `sets.equivalent([1], [1, 1])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/16
},
{
name: "sets.equivalent test 4",
exp: `sets.equivalent([1, 2, 3], [3, 2, 1])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/17
},

{
name: "sets.intersects test 1",
exp: `sets.intersects([1], [])`,
want: false,
skip: true, // https://github.com/polds/expr-playground/issues/18
},
{
name: "sets.intersects test 2",
exp: `sets.intersects([1], [1, 2])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/19
},
{
name: "sets.intersects test 3",
exp: `sets.intersects([[1], [2, 3]], [[1, 2], [2, 3]])`,
want: true,
skip: true, // https://github.com/polds/expr-playground/issues/20
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.skip {
t.Skip("Skipping broken test due to CEL -> Expr migration.")
}

got, err := Eval(tt.exp, input)

if (err != nil) != tt.wantErr {
t.Errorf("Eval() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("Eval() got error = %v, wantErr %t", err, tt.wantErr)
return
}
if tt.wantErr {
return
}

if !tt.wantErr {
evalResponse := EvalResponse{}
if err := json.Unmarshal([]byte(got), &evalResponse); err != nil {
t.Errorf("Eval() error = %v", err)
}

if !reflect.DeepEqual(tt.want, evalResponse.Result) {
t.Errorf("Expected %v\n, received %v", tt.want, evalResponse.Result)
}
if evalResponse.Cost == nil || *evalResponse.Cost <= 0 {
t.Errorf("Expected Cost, returned %v", evalResponse.Cost)
}
var res RunResponse
if err := json.Unmarshal([]byte(got), &res); err != nil {
t.Fatalf("json.Unmarshal got error = %v, want %v", err, nil)
}
if diff := cmp.Diff(tt.want, res.Result); diff != "" {
t.Errorf("Eval() mismatch (-want +got):\n%s", diff)
}
})
}
Expand All @@ -186,22 +206,26 @@ func TestValidation(t *testing.T) {
name string
exp string
wantErr bool
skip bool
}{
// Duration Literals
{
name: "Duration Validation test 1",
exp: `duration('1')`,
wantErr: true,
skip: true, // https://github.com/polds/expr-playground/issues/21
},
{
name: "Duration Validation test 2",
exp: `duration('1d')`,
wantErr: true,
skip: true, // https://github.com/polds/expr-playground/issues/22
},
{
name: "Duration Validation test 3",
exp: `duration('1us') < duration('1nns')`,
wantErr: true,
skip: true, // https://github.com/polds/expr-playground/issues/23
},
{
name: "Duration Validation test 4",
Expand All @@ -226,10 +250,12 @@ func TestValidation(t *testing.T) {
{
name: "Timestamp Validation test 3",
exp: `timestamp('1000-01-01T00:00:00Z')`,
skip: true, // https://github.com/polds/expr-playground/issues/24
},
{
name: "Timestamp Validation test 4",
exp: `timestamp(-6213559680)`, // min unix epoch time.
skip: true, // https://github.com/polds/expr-playground/issues/25
},
{
name: "Timestamp Validation test 5",
Expand All @@ -239,12 +265,14 @@ func TestValidation(t *testing.T) {
{
name: "Timestamp Validation test 6",
exp: `timestamp(x)`,
skip: true, // https://github.com/polds/expr-playground/issues/26
},

// Regex Literals
{
name: "Regex Validation test 1",
exp: `'hello'.matches('el*')`,
skip: true, // https://github.com/polds/expr-playground/issues/27
},
{
name: "Regex Validation test 2",
Expand All @@ -264,35 +292,42 @@ func TestValidation(t *testing.T) {
{
name: "Regex Validation test 5",
exp: `'hello'.matches(x)`,
skip: true, // https://github.com/polds/expr-playground/issues/28
},

// Homogeneous Aggregate Literals
{
name: "Homogeneous Aggregate Validation test 1",
exp: `name in ['hello', 0]`,
wantErr: true,
skip: true, // https://github.com/polds/expr-playground/issues/29
},
{
name: "Homogeneous Aggregate Validation test 2",
exp: `{'hello':'world', 1:'!'}`,
wantErr: true,
skip: true, // https://github.com/polds/expr-playground/issues/30
},
{
name: "Homogeneous Aggregate Validation test 3",
exp: `name in {'hello':'world', 'goodbye':true}`,
wantErr: true,
skip: true, // https://github.com/polds/expr-playground/issues/31
},
{
name: "Homogeneous Aggregate Validation test 4",
exp: `name in ['hello', 'world']`,
skip: true, // https://github.com/polds/expr-playground/issues/31
},
{
name: "Homogeneous Aggregate Validation test 5",
exp: `name in ['hello', ?optional.ofNonZeroValue('')]`,
skip: true, // https://github.com/polds/expr-playground/issues/32
},
{
name: "Homogeneous Aggregate Validation test 6",
exp: `name in [?optional.ofNonZeroValue(''), 'hello', ?optional.of('')]`,
skip: true, // https://github.com/polds/expr-playground/issues/33
},
{
name: "Homogeneous Aggregate Validation test 7",
Expand All @@ -301,28 +336,31 @@ func TestValidation(t *testing.T) {
{
name: "Homogeneous Aggregate Validation test 8",
exp: `{'hello': false, ?'world': optional.ofNonZeroValue(true)}`,
skip: true, // https://github.com/polds/expr-playground/issues/34
},
{
name: "Homogeneous Aggregate Validation test 9",
exp: `{?'hello': optional.ofNonZeroValue(false), 'world': true}`,
skip: true, // https://github.com/polds/expr-playground/issues/35
},
}
env, err := cel.NewEnv(append(celEnvOptions,
cel.Variable("x", types.StringType),
cel.Variable("name", types.StringType),
)...)
if err != nil {
t.Errorf("failed to create CEL env: %v", err)

env := map[string]any{
"x": "",
"name": "",
}
opts := append(exprEnvOptions, expr.Env(env))

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, issues := env.Compile(tt.exp)
if tt.wantErr {
if issues.Err() == nil {
t.Fatalf("Compilation should have failed, expr: %v", tt.exp)
}
} else if issues.Err() != nil {
t.Fatalf("Compilation failed, expr: %v, error: %v", tt.exp, issues.Err())
if tt.skip {
t.Skip("Skipping broken test due to CEL -> Expr migration.")
}

_, err := expr.Compile(tt.exp, opts...)
if (err != nil) != tt.wantErr {
t.Errorf("Compile() got error = %v, wantErr %t", err, tt.wantErr)
return
}
})
}
Expand Down
Loading

0 comments on commit 7d7a7fe

Please sign in to comment.