-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
for: * compiler * parser * bundle compiler * rego SDK * OPA SDK Signed-off-by: Johan Fylling <[email protected]>
- Loading branch information
1 parent
c22d553
commit 31b5f17
Showing
14 changed files
with
1,627 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright 2024 The OPA Authors. All rights reserved. | ||
// Use of this source code is governed by an Apache2 | ||
// license that can be found in the LICENSE file. | ||
|
||
package ast | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestCompile_DefaultRegoVersion(t *testing.T) { | ||
tests := []struct { | ||
note string | ||
modules map[string]*Module | ||
expErrs []string | ||
}{ | ||
{ | ||
note: "no module rego-version, no v1 violations", | ||
modules: map[string]*Module{ | ||
"test": { | ||
Package: MustParsePackage(`package test`), | ||
Imports: MustParseImports(`import data.foo | ||
import data.bar`), | ||
}, | ||
}, | ||
}, | ||
{ | ||
note: "no module rego-version, v1 violations", // default is v0, no errors expected | ||
modules: map[string]*Module{ | ||
"test": { | ||
Package: MustParsePackage(`package test`), | ||
Imports: MustParseImports(`import data.foo | ||
import data.bar as foo`), | ||
}, | ||
}, | ||
}, | ||
{ | ||
note: "v0 module, v1 violations", | ||
modules: map[string]*Module{ | ||
"test": MustParseModuleWithOpts(`package test | ||
import data.foo | ||
import data.bar as foo`, | ||
ParserOptions{RegoVersion: RegoV0}), | ||
}, | ||
}, | ||
{ | ||
note: "v1 module, v1 violations", | ||
modules: map[string]*Module{ | ||
"test": MustParseModuleWithOpts(`package test | ||
import data.foo | ||
import data.bar as foo`, | ||
ParserOptions{RegoVersion: RegoV1}), | ||
}, | ||
expErrs: []string{ | ||
"3:7: rego_compile_error: import must not shadow import data.foo", | ||
}, | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
t.Run(tc.note, func(t *testing.T) { | ||
compiler := NewCompiler() | ||
|
||
compiler.Compile(tc.modules) | ||
|
||
if len(tc.expErrs) > 0 { | ||
assertErrors(t, compiler.Errors, tc.expErrs) | ||
} else { | ||
if len(compiler.Errors) > 0 { | ||
t.Fatalf("Unexpected errors: %v", compiler.Errors) | ||
} | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func assertErrors(t *testing.T, actual Errors, expected []string) { | ||
t.Helper() | ||
if len(expected) != len(actual) { | ||
t.Fatalf("Expected %d errors, got %d:\n\n%s\n", len(expected), len(actual), actual.Error()) | ||
} | ||
incorrectErrs := false | ||
for _, e := range expected { | ||
found := false | ||
for _, actual := range actual { | ||
if strings.Contains(actual.Error(), e) { | ||
found = true | ||
break | ||
} | ||
} | ||
if !found { | ||
incorrectErrs = true | ||
} | ||
} | ||
if incorrectErrs { | ||
t.Fatalf("Expected errors:\n\n%s\n\nGot:\n\n%s\n", expected, actual.Error()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// Copyright 2024 The OPA Authors. All rights reserved. | ||
// Use of this source code is governed by an Apache2 | ||
// license that can be found in the LICENSE file. | ||
|
||
package ast_test | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/open-policy-agent/opa/ast" | ||
"github.com/open-policy-agent/opa/format" | ||
) | ||
|
||
func TestParseModule_DefaultRegoVersion(t *testing.T) { | ||
tests := []struct { | ||
note string | ||
mod string | ||
expRules []string | ||
expErrs []string | ||
}{ | ||
{ | ||
note: "v0", // default rego-version | ||
mod: `package test | ||
p[x] { | ||
x = "a" | ||
}`, | ||
expRules: []string{"p"}, | ||
}, | ||
{ | ||
note: "import rego.v1", | ||
mod: `package test | ||
import rego.v1 | ||
p contains x if { | ||
x = "a" | ||
}`, | ||
expRules: []string{"p"}, | ||
}, | ||
{ | ||
note: "v1", // NOT default rego-version | ||
mod: `package test | ||
p contains x if { | ||
x = "a" | ||
}`, | ||
expErrs: []string{ | ||
"test.rego:2: rego_parse_error: var cannot be used for rule name", | ||
}, | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
t.Run(tc.note, func(t *testing.T) { | ||
m, err := ast.ParseModule("test.rego", tc.mod) | ||
|
||
if len(tc.expErrs) > 0 { | ||
for i, expErr := range tc.expErrs { | ||
if !strings.Contains(err.Error(), expErr) { | ||
t.Fatalf("Expected error %d to contain %q, got %q", i, expErr, err.Error()) | ||
} | ||
} | ||
} else { | ||
if err != nil { | ||
t.Fatalf("Unexpected error: %s", err) | ||
} | ||
|
||
if len(m.Rules) != len(tc.expRules) { | ||
t.Fatalf("Expected %d rules, got %d", len(tc.expRules), len(m.Rules)) | ||
} | ||
for i, r := range m.Rules { | ||
if r.Head.Name.String() != tc.expRules[i] { | ||
t.Fatalf("Expected rule %q, got %q", tc.expRules[i], r.Head.Name.String()) | ||
} | ||
} | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestParseBody_DefaultRegoVersion(t *testing.T) { | ||
tests := []struct { | ||
note string | ||
body string | ||
expStmts int | ||
assertSame bool | ||
}{ | ||
{ | ||
note: "v0", // default rego-version | ||
body: `x := ["a", "b", "c"][i] | ||
`, | ||
expStmts: 1, | ||
assertSame: true, | ||
}, | ||
{ | ||
note: "v1", // NOT default rego-version | ||
body: `some x, i in ["a", "b", "c"] | ||
`, | ||
expStmts: 3, | ||
assertSame: false, | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
t.Run(tc.note, func(t *testing.T) { | ||
body, err := ast.ParseBody(tc.body) | ||
|
||
if err != nil { | ||
t.Fatalf("Unexpected error: %s", err) | ||
} | ||
|
||
if len(body) != tc.expStmts { | ||
t.Fatalf("Expected %d statements, got %d:%q\n\n", tc.expStmts, len(body), body) | ||
} | ||
|
||
if tc.assertSame { | ||
formatted, err := format.AstWithOpts(body, format.Opts{RegoVersion: ast.RegoV1}) // every body is v1-compatible | ||
if err != nil { | ||
t.Fatalf("Unexpected error: %s", err) | ||
} | ||
|
||
if strings.Compare(string(formatted), tc.body) != 0 { | ||
t.Fatalf("Expected body to be %q, got %q", tc.body, string(formatted)) | ||
} | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.