package test

import "github.com/google/cel-go/test"

Package test provides a YAML-serializable test suite for CEL tests.

Index

Variables

var (
	// Empty generates a program with no instructions.
	Empty = &TestExpr{
		Expr: &exprpb.Expr{},

		SourceInfo: &exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// Exists generates "[1, 1u, 1.0].exists(x, type(x) == uint)".
	Exists = &TestExpr{
		Expr: ExprComprehension(1,
			"x",
			ExprList(8,
				ExprLiteral(2, int64(0)),
				ExprLiteral(3, int64(1)),
				ExprLiteral(4, int64(2)),
				ExprLiteral(5, int64(3)),
				ExprLiteral(6, int64(4)),
				ExprLiteral(7, uint64(5))),
			"__result__",
			ExprLiteral(9, false),
			ExprCall(12,
				operators.NotStrictlyFalse,
				ExprCall(10,
					operators.LogicalNot,
					ExprIdent(11, "__result__"))),
			ExprCall(13,
				operators.LogicalOr,
				ExprIdent(14, "__result__"),
				ExprCall(15,
					operators.Equals,
					ExprCall(16,
						"type",
						ExprIdent(17, "x")),
					ExprIdent(18, "uint"))),
			ExprIdent(19, "__result__")),

		SourceInfo: &exprpb.SourceInfo{
			LineOffsets: []int32{0},
			Positions: map[int64]int32{
				0:  12,
				1:  0,
				2:  1,
				3:  4,
				4:  8,
				5:  0,
				6:  18,
				7:  18,
				8:  18,
				9:  18,
				10: 18,
				11: 20,
				12: 20,
				13: 28,
				14: 28,
				15: 28,
				16: 28,
				17: 28,
				18: 28,
				19: 28}}}

	// ExistsWithInput generates "elems.exists(x, type(x) == uint)".
	ExistsWithInput = &TestExpr{
		Expr: ExprComprehension(1,
			"x",
			ExprIdent(2, "elems"),
			"__result__",
			ExprLiteral(3, false),
			ExprCall(4,
				operators.LogicalNot,
				ExprIdent(5, "__result__")),
			ExprCall(6,
				operators.Equals,
				ExprCall(7,
					"type",
					ExprIdent(8, "x")),
				ExprIdent(9, "uint")),
			ExprIdent(10, "__result__")),

		SourceInfo: &exprpb.SourceInfo{
			LineOffsets: []int32{0},
			Positions: map[int64]int32{
				0:  12,
				1:  0,
				2:  1,
				3:  4,
				4:  8,
				5:  0,
				6:  18,
				7:  18,
				8:  18,
				9:  18,
				10: 18}}}

	// DynMap generates a map literal:
	// {"hello": "world".size(),
	//  "dur": duration.Duration{10},
	//  "ts": timestamp.Timestamp{1000},
	//  "null": null,
	//  "bytes": b"bytes-string"}
	DynMap = &TestExpr{
		Expr: ExprMap(17,
			ExprEntry(2,
				ExprLiteral(1, "hello"),
				ExprMemberCall(3,
					"size",
					ExprLiteral(4, "world"))),
			ExprEntry(12,
				ExprLiteral(11, "null"),
				ExprLiteral(13, structpb.NullValue_NULL_VALUE)),
			ExprEntry(15,
				ExprLiteral(14, "bytes"),
				ExprLiteral(16, []byte("bytes-string")))),

		SourceInfo: &exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// LogicalAnd generates "a && {c: true}.c".
	LogicalAnd = &TestExpr{
		ExprCall(2, operators.LogicalAnd,
			ExprIdent(1, "a"),
			ExprSelect(8,
				ExprMap(5,
					ExprEntry(4, ExprLiteral(6, "c"), ExprLiteral(7, true))),
				"c")),
		&exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// LogicalOr generates "{c: false}.c || a".
	LogicalOr = &TestExpr{
		ExprCall(2, operators.LogicalOr,
			ExprSelect(8,
				ExprMap(5,
					ExprEntry(4, ExprLiteral(6, "c"), ExprLiteral(7, false))),
				"c"),
			ExprIdent(1, "a")),
		&exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// LogicalOrEquals generates "a || b == 'b'".
	LogicalOrEquals = &TestExpr{
		ExprCall(5, operators.LogicalOr,
			ExprIdent(1, "a"),
			ExprCall(4, operators.Equals,
				ExprIdent(2, "b"),
				ExprLiteral(3, "b"))),
		&exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// LogicalAndMissingType generates "a && TestProto{c: true}.c" where the
	// type 'TestProto' is undefined.
	LogicalAndMissingType = &TestExpr{
		ExprCall(2, operators.LogicalAnd,
			ExprIdent(1, "a"),
			ExprSelect(7,
				ExprType(5, "TestProto",
					ExprField(4, "c", ExprLiteral(6, true))),
				"c")),
		&exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// Conditional generates "a ? b < 1.0 : c == ["hello"]".
	Conditional = &TestExpr{
		Expr: ExprCall(9, operators.Conditional,
			ExprIdent(1, "a"),
			ExprCall(3,
				operators.Less,
				ExprIdent(2, "b"),
				ExprLiteral(4, 1.0)),
			ExprCall(6,
				operators.Equals,
				ExprIdent(5, "c"),
				ExprList(8, ExprLiteral(7, "hello")))),
		SourceInfo: &exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// Select generates "a.b.c".
	Select = &TestExpr{
		Expr: ExprSelect(3,
			ExprSelect(2,
				ExprIdent(1, "a"),
				"b"),
			"c"),
		SourceInfo: &exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// Equality generates "a == 42".
	Equality = &TestExpr{
		Expr: ExprCall(2,
			operators.Equals,
			ExprIdent(1, "a"),
			ExprLiteral(3, int64(42))),
		SourceInfo: &exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}

	// TypeEquality generates "type(a) == uint".
	TypeEquality = &TestExpr{
		Expr: ExprCall(4,
			operators.Equals,
			ExprCall(1, "type",
				ExprIdent(2, "a")),
			ExprIdent(3, "uint")),
		SourceInfo: &exprpb.SourceInfo{
			LineOffsets: []int32{},
			Positions:   map[int64]int32{}}}
)

Functions

func Compare

func Compare(a string, e string) bool

Compare compares two strings, a for actual, e for expected, and returns true or false. The comparison is done, by filtering out whitespace (i.e. space, tabs and newline).

func DiffMessage

func DiffMessage(context string, actual interface{}, expected interface{}) string

DiffMessage creates a diff dump message for test failures.

func ExprCall

func ExprCall(id int64, function string, args ...*exprpb.Expr) *exprpb.Expr

ExprCall creates a call Expr.

func ExprComprehension

func ExprComprehension(id int64,
	iterVar string, iterRange *exprpb.Expr,
	accuVar string, accuInit *exprpb.Expr,
	loopCondition *exprpb.Expr, loopStep *exprpb.Expr,
	resultExpr *exprpb.Expr) *exprpb.Expr

ExprComprehension returns a comprehension Expr.

func ExprEntry

func ExprEntry(id int64, key *exprpb.Expr,
	value *exprpb.Expr) *exprpb.Expr_CreateStruct_Entry

ExprEntry creates a map entry for a create struct Expr.

func ExprField

func ExprField(id int64, field string,
	value *exprpb.Expr) *exprpb.Expr_CreateStruct_Entry

ExprField creates a field entry for a create struct Expr.

func ExprIdent

func ExprIdent(id int64, name string) *exprpb.Expr

ExprIdent creates an ident (variable) Expr.

func ExprList

func ExprList(id int64, elements ...*exprpb.Expr) *exprpb.Expr

ExprList creates a create list Expr.

func ExprLiteral

func ExprLiteral(id int64, value interface{}) *exprpb.Expr

ExprLiteral creates a literal (constant) Expr.

func ExprMap

func ExprMap(id int64, entries ...*exprpb.Expr_CreateStruct_Entry) *exprpb.Expr

ExprMap creates a create struct Expr for a map.

func ExprMemberCall

func ExprMemberCall(id int64, function string, target *exprpb.Expr, args ...*exprpb.Expr) *exprpb.Expr

ExprMemberCall creates a receiver-style call Expr.

func ExprSelect

func ExprSelect(id int64, operand *exprpb.Expr, field string) *exprpb.Expr

ExprSelect creates a select Expr.

func ExprType

func ExprType(id int64, messageName string,
	entries ...*exprpb.Expr_CreateStruct_Entry) *exprpb.Expr

ExprType creates creates a create struct Expr for a message.

Types

type Case

type Case struct {
	Name          string                 `yaml:"name"`
	Description   string                 `yaml:"description"`
	Input         map[string]*InputValue `yaml:"input,omitempty"`
	*InputContext `yaml:",inline,omitempty"`
	Output        *Output `yaml:"output"`
}

Case is a test case to validate a CEL policy or expression. The test case encompasses evaluation of the compiled expression using the provided input bindings and asserting the result against the expected result.

type InputContext

type InputContext struct {
	ContextExpr string `yaml:"context_expr"`
}

InputContext represents an optional context expression.

type InputValue

type InputValue struct {
	Value any    `yaml:"value"`
	Expr  string `yaml:"expr"`
}

InputValue represents an input value for a binding which can be either a simple literal value or an expression.

type Output

type Output struct {
	Value      any      `yaml:"value"`
	Expr       string   `yaml:"expr"`
	ErrorSet   []string `yaml:"error_set"`
	UnknownSet []int64  `yaml:"unknown_set"`
}

Output represents the expected result of a test case.

type Section

type Section struct {
	Name  string  `yaml:"name"`
	Tests []*Case `yaml:"tests"`
}

Section is a collection of related test cases.

type Suite

type Suite struct {
	Name        string     `yaml:"name"`
	Description string     `yaml:"description"`
	Sections    []*Section `yaml:"section"`
}

Suite is a collection of tests designed to evaluate the correctness of a CEL policy or a CEL expression

type TestExpr

type TestExpr struct {
	Expr       *exprpb.Expr
	SourceInfo *exprpb.SourceInfo
}

TestExpr packages an Expr with SourceInfo, for testing.

func (*TestExpr) Info

func (t *TestExpr) Info(location string) *exprpb.SourceInfo

Info returns a copy of the SourceInfo with the given location.

Source Files

compare.go expr.go suite.go

Directories

PathSynopsis
test/benchPackage bench defines a structure for benchmarked tests against custom CEL environments.
test/proto2pb
test/proto3pb
Version
v0.25.0 (latest)
Published
Apr 22, 2025
Platform
linux/amd64
Imports
6 packages
Last checked
1 week ago

Tools for package owners.