From 0cf3b1f264fa9ed453d0f82d62f6998ba266204b Mon Sep 17 00:00:00 2001 From: Anton Medvedev Date: Wed, 4 Mar 2020 09:41:20 +0300 Subject: [PATCH] Add AllowUndefinedVariables option examples --- expr_test.go | 103 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 25 deletions(-) diff --git a/expr_test.go b/expr_test.go index d4c1d3f90..a4edbf549 100644 --- a/expr_test.go +++ b/expr_test.go @@ -339,49 +339,102 @@ func ExampleOperator() { // Output: true } -func ExampleOperator_time() { - type Segment struct { - Date time.Time +func ExampleAllowUndefinedVariables() { + code := `name == nil ? "Hello, world!" : sprintf("Hello, %v!", name)` + + env := map[string]interface{}{ + "sprintf": fmt.Sprintf, } - type Request struct { - Segments []Segment - Before func(a, b time.Time) bool - Date func(s string) time.Time + + options := []expr.Option{ + expr.Env(env), + expr.AllowUndefinedVariables(), // Allow to use undefined variables. } - code := `Date("2001-01-01") < Segments[0].Date` + program, err := expr.Compile(code, options...) + if err != nil { + fmt.Printf("%v", err) + return + } - program, err := expr.Compile(code, expr.Env(&Request{}), expr.Operator("<", "Before")) + output, err := expr.Run(program, env) if err != nil { fmt.Printf("%v", err) return } + fmt.Printf("%v\n", output) - request := &Request{ - Segments: []Segment{ - {Date: time.Date(2019, 7, 1, 0, 0, 0, 0, time.UTC)}, - }, - Before: func(a, b time.Time) bool { - return a.Before(b) - }, - Date: func(s string) time.Time { - date, err := time.Parse("2006-01-02", s) - if err != nil { - panic(err) - } - return date - }, + env["name"] = "you" // Define variables later on. + + output, err = expr.Run(program, env) + if err != nil { + fmt.Printf("%v", err) + return } + fmt.Printf("%v\n", output) - output, err := expr.Run(program, request) + // Output: Hello, world! + // Hello, you! +} + +func ExampleAllowUndefinedVariables_zero_value() { + code := `name == "" ? foo + bar : foo + name` + + // If environment has different zero values, then undefined variables + // will have it as default value. + env := map[string]string{} + + options := []expr.Option{ + expr.Env(env), + expr.AllowUndefinedVariables(), // Allow to use undefined variables. + } + + program, err := expr.Compile(code, options...) if err != nil { fmt.Printf("%v", err) return } + env = map[string]string{ + "foo": "Hello, ", + "bar": "world!", + } + + output, err := expr.Run(program, env) + if err != nil { + fmt.Printf("%v", err) + return + } fmt.Printf("%v", output) - // Output: true + // Output: Hello, world! +} + +func ExampleAllowUndefinedVariables_zero_value_functions() { + code := `words == "" ? Split("foo,bar", ",") : Split(words, ",")` + + // Env is map[string]string type on which methods are defined. + env := mockMapStringStringEnv{} + + options := []expr.Option{ + expr.Env(env), + expr.AllowUndefinedVariables(), // Allow to use undefined variables. + } + + program, err := expr.Compile(code, options...) + if err != nil { + fmt.Printf("%v", err) + return + } + + output, err := expr.Run(program, env) + if err != nil { + fmt.Printf("%v", err) + return + } + fmt.Printf("%v", output) + + // Output: [foo bar] } func TestOperator_struct(t *testing.T) {