Skip to content

Commit 7c13168

Browse files
Fix doc strings and version support on math extensions (#1046)
1 parent 04eb5b9 commit 7c13168

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-2
lines changed

ext/math.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,12 @@ import (
325325
//
326326
// math.isFinite(0.0/0.0) // returns false
327327
// math.isFinite(1.2) // returns true
328-
func Math() cel.EnvOption {
329-
return cel.Lib(&mathLib{version: math.MaxUint32})
328+
func Math(options ...MathOption) cel.EnvOption {
329+
m := &mathLib{version: math.MaxUint32}
330+
for _, o := range options {
331+
m = o(m)
332+
}
333+
return cel.Lib(m)
330334
}
331335

332336
const (
@@ -366,8 +370,10 @@ var (
366370
errIntOverflow = types.NewErr("integer overflow")
367371
)
368372

373+
// MathOption declares a functional operator for configuring math extensions.
369374
type MathOption func(*mathLib) *mathLib
370375

376+
// MathVersion sets the library version for math extensions.
371377
func MathVersion(version uint32) MathOption {
372378
return func(lib *mathLib) *mathLib {
373379
lib.version = version

ext/math_test.go

+73
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"testing"
2121

2222
"github.com/google/cel-go/cel"
23+
"github.com/google/cel-go/common/types"
2324
)
2425

2526
func TestMath(t *testing.T) {
@@ -566,6 +567,78 @@ func TestMathWithExtension(t *testing.T) {
566567
}
567568
}
568569

570+
func TestMathVersions(t *testing.T) {
571+
versionCases := []struct {
572+
version uint32
573+
supportedFunctions map[string]string
574+
}{
575+
{
576+
version: 0,
577+
supportedFunctions: map[string]string{
578+
"greatest": `math.greatest(1, 2) == 2`,
579+
"least": `math.least(2.1, -1.0) == -1.0`,
580+
},
581+
},
582+
{
583+
version: 1,
584+
supportedFunctions: map[string]string{
585+
"ceil": `math.ceil(1.5) == 2.0`,
586+
"floor": `math.floor(1.2) == 1.0`,
587+
"round": `math.round(1.5) == 2.0`,
588+
"trunc": `math.trunc(1.222) == 1.0`,
589+
"isInf": `!math.isInf(0.0)`,
590+
"isNaN": `math.isNaN(0.0/0.0)`,
591+
"isFinite": `math.isFinite(0.0)`,
592+
"abs": `math.abs(1.2) == 1.2`,
593+
"sign": `math.sign(-1) == -1`,
594+
"bitAnd": `math.bitAnd(1, 2) == 0`,
595+
"bitOr": `math.bitOr(1, 2) == 3`,
596+
"bitXor": `math.bitXor(1, 3) == 2`,
597+
"bitNot": `math.bitNot(-1) == 0`,
598+
"bitShiftLeft": `math.bitShiftLeft(4, 2) == 16`,
599+
"bitShiftRight": `math.bitShiftRight(4, 2) == 1`,
600+
},
601+
},
602+
}
603+
for _, lib := range versionCases {
604+
env, err := cel.NewEnv(Math(MathVersion(lib.version)))
605+
if err != nil {
606+
t.Fatalf("cel.NewEnv(Math(MathVersion(%d))) failed: %v", lib.version, err)
607+
}
608+
t.Run(fmt.Sprintf("version=%d", lib.version), func(t *testing.T) {
609+
for _, tc := range versionCases {
610+
for name, expr := range tc.supportedFunctions {
611+
supported := lib.version >= tc.version
612+
t.Run(fmt.Sprintf("%s-supported=%t", name, supported), func(t *testing.T) {
613+
ast, iss := env.Compile(expr)
614+
if supported {
615+
if iss.Err() != nil {
616+
t.Errorf("unexpected error: %v", iss.Err())
617+
}
618+
} else {
619+
if iss.Err() == nil || !strings.Contains(iss.Err().Error(), "undeclared reference") {
620+
t.Errorf("got error %v, wanted error %s for expr: %s, version: %d", iss.Err(), "undeclared reference", expr, tc.version)
621+
}
622+
return
623+
}
624+
prg, err := env.Program(ast)
625+
if err != nil {
626+
t.Fatalf("env.Program() failed: %v", err)
627+
}
628+
out, _, err := prg.Eval(cel.NoVars())
629+
if err != nil {
630+
t.Fatalf("prg.Eval() failed: %v", err)
631+
}
632+
if out != types.True {
633+
t.Errorf("prg.Eval() got %v, wanted true", out)
634+
}
635+
})
636+
}
637+
}
638+
})
639+
}
640+
}
641+
569642
func testMathEnv(t *testing.T, opts ...cel.EnvOption) *cel.Env {
570643
t.Helper()
571644
baseOpts := []cel.EnvOption{Math(), cel.EnableMacroCallTracking()}

0 commit comments

Comments
 (0)