mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
* fix(interpreter,rvm): resolve function calls through import aliases * fix(rvm): assert every-quantifier results so failing cases don't pass
623 lines
12 KiB
YAML
623 lines
12 KiB
YAML
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
|
|
cases:
|
|
- note: import input
|
|
input:
|
|
a: 10
|
|
modules:
|
|
- |
|
|
package a
|
|
import input as foo
|
|
b = foo
|
|
- |
|
|
package b
|
|
import input.a
|
|
import input.a as A
|
|
|
|
c = a
|
|
d = A
|
|
query: data
|
|
want_result:
|
|
a:
|
|
b:
|
|
a: 10
|
|
b:
|
|
c: 10
|
|
d: 10
|
|
- note: import data, cross ref
|
|
modules:
|
|
- |
|
|
package a
|
|
import data.b.a
|
|
b = a + 1
|
|
|
|
- |
|
|
package b
|
|
import rego.v1
|
|
# Both the following imports are overridden by rules
|
|
#import data.a.b as a
|
|
#import data.a.b
|
|
|
|
import data.a.b as C
|
|
import data.a.b
|
|
|
|
a = 10
|
|
c = C + b
|
|
|
|
r if {
|
|
some v in [C]
|
|
}
|
|
query: data
|
|
want_result:
|
|
a:
|
|
b: 11
|
|
b:
|
|
a: 10
|
|
c: 22
|
|
r: true
|
|
- note: import data inside rule body
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
a_value := "a_value"
|
|
|
|
- |
|
|
package rules
|
|
import data.lib
|
|
import rego.v1
|
|
|
|
sample if {
|
|
lib.a_value == "a_value"
|
|
}
|
|
query: data.rules.sample
|
|
want_result: true
|
|
|
|
- note: import data alias
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
value := "a_value"
|
|
|
|
- |
|
|
package rules
|
|
import data.lib as mylib
|
|
import rego.v1
|
|
|
|
sample if {
|
|
mylib.value == "a_value"
|
|
}
|
|
query: data.rules.sample
|
|
want_result: true
|
|
|
|
- note: import nested package chain
|
|
modules:
|
|
- |
|
|
package lib.inner
|
|
import rego.v1
|
|
|
|
nested := {"key": "value"}
|
|
|
|
- |
|
|
package rules
|
|
import data.lib.inner
|
|
import rego.v1
|
|
|
|
lookup := value if {
|
|
value := inner.nested.key
|
|
}
|
|
query: data.rules.lookup
|
|
want_result: "value"
|
|
|
|
- note: import alias shadowed by rule
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
value := "from data"
|
|
|
|
- |
|
|
package rules
|
|
import data.lib as lib_alias
|
|
import rego.v1
|
|
|
|
lib_alias := {"value": "from rule"}
|
|
|
|
# TODO:
|
|
# OPA currently reports this rule as undefined. This implies that
|
|
# lib_alias retains the imported value eventhough there is a rule
|
|
# with same name. In regorus, the rule takes precedence.
|
|
# Needs investigation to figure out which behavior is correct.
|
|
shadow if {
|
|
lib_alias.value == "from rule"
|
|
}
|
|
query: data.rules.shadow
|
|
want_result: true
|
|
|
|
|
|
- note: import used in comprehension
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
dataset := {"a", "b"}
|
|
|
|
- |
|
|
package rules
|
|
import data.lib
|
|
import rego.v1
|
|
|
|
present if {
|
|
some item in lib.dataset
|
|
item == "b"
|
|
}
|
|
query: data.rules.present
|
|
want_result: true
|
|
|
|
- note: import overridden by rule
|
|
modules:
|
|
- |
|
|
package a
|
|
a = 10
|
|
- |
|
|
package b
|
|
import data.a.a
|
|
|
|
a = 20
|
|
query: data.b.a
|
|
want_result: 20
|
|
|
|
- note: invalid import ref
|
|
modules:
|
|
- |
|
|
package a
|
|
import foo
|
|
query: data
|
|
error: "import path must begin with one of"
|
|
|
|
- note: redundant import input
|
|
modules:
|
|
- |
|
|
package test
|
|
import input
|
|
query: data.test
|
|
want_result: {}
|
|
- note: function call through import
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := lib.double(21)
|
|
query: data.rules.result
|
|
want_result: 42
|
|
- note: function call through import alias
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib as l
|
|
|
|
result := l.double(21)
|
|
query: data.rules.result
|
|
want_result: 42
|
|
- note: function imported directly
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib.double
|
|
|
|
result := double(21)
|
|
query: data.rules.result
|
|
want_result: 42
|
|
- note: function call through import, nested package
|
|
modules:
|
|
- |
|
|
package a.b.c
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.a
|
|
|
|
result := a.b.c.double(21)
|
|
query: data.rules.result
|
|
want_result: 42
|
|
- note: default function value via import
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
default pick(_) := "fallback"
|
|
|
|
pick(x) := x if x == "a"
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
a := lib.pick("a")
|
|
b := lib.pick("z")
|
|
query: data.rules
|
|
want_result:
|
|
a: a
|
|
b: fallback
|
|
- note: with override applies to function call through import
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package lib2
|
|
import rego.v1
|
|
|
|
fake(x) := 1000 + x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := lib.double(5)
|
|
|
|
main := x if {
|
|
x := result with data.lib.double as data.lib2.fake
|
|
}
|
|
query: data.rules.main
|
|
want_result: 1005
|
|
- note: with override target written through import alias
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package lib2
|
|
import rego.v1
|
|
|
|
fake(x) := 1000 + x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := data.lib.double(5)
|
|
|
|
main := x if {
|
|
x := result with lib.double as data.lib2.fake
|
|
}
|
|
query: data.rules.main
|
|
want_result: 1005
|
|
- note: with override replacement written through import alias
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package lib2
|
|
import rego.v1
|
|
|
|
fake(x) := 1000 + x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
import data.lib2
|
|
|
|
result := data.lib.double(5)
|
|
|
|
main := x if {
|
|
x := result with data.lib.double as lib2.fake
|
|
}
|
|
query: data.rules.main
|
|
want_result: 1005
|
|
- note: import alias shadows builtin namespace
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
unmarshal(_) := {"from": "lib"}
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib as json
|
|
|
|
result := json.unmarshal(`[1,2]`)
|
|
query: data.rules.result
|
|
want_result:
|
|
from: lib
|
|
- note: with override target written through builtin-shadowing alias
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
unmarshal(_) := {"from": "lib"}
|
|
- |
|
|
package lib2
|
|
import rego.v1
|
|
|
|
unmarshal(_) := {"from": "lib2"}
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib as json
|
|
|
|
result := json.unmarshal(`[1]`)
|
|
|
|
main := x if {
|
|
x := result with json.unmarshal as data.lib2.unmarshal
|
|
}
|
|
query: data.rules.main
|
|
want_result:
|
|
from: lib2
|
|
- note: with override replacement written through builtin-shadowing alias
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package lib2
|
|
import rego.v1
|
|
|
|
unmarshal(_) := {"from": "lib2"}
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
import data.lib2 as json
|
|
|
|
result := lib.double(5)
|
|
|
|
main := x if {
|
|
x := result with data.lib.double as json.unmarshal
|
|
}
|
|
query: data.rules.main
|
|
want_result:
|
|
from: lib2
|
|
- note: with override target aliasing a non-function rule overrides the value
|
|
modules:
|
|
- |
|
|
package flib
|
|
import rego.v1
|
|
|
|
default flag := false
|
|
|
|
flag := true if input.x == 1
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.flib as fl
|
|
|
|
result := data.flib.flag
|
|
|
|
main := x if {
|
|
x := result with fl.flag as 5
|
|
}
|
|
query: data.rules.main
|
|
want_result: 5
|
|
- note: import shadows module-local rule for function calls
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
lib.double(x) := 100 * x
|
|
|
|
main := lib.double(3)
|
|
query: data.rules.main
|
|
want_result: 6
|
|
- note: import shadows module-local value rule for function calls
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
lib.double := 7
|
|
|
|
main := lib.double(3)
|
|
query: data.rules.main
|
|
want_result: 6
|
|
- note: fully qualified function call with import present
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := data.lib.double(21)
|
|
query: data.rules.result
|
|
want_result: 42
|
|
- note: unknown function through import is an error
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
double(x) := 2 * x
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := lib.missing(1)
|
|
query: data.rules.result
|
|
error: could not find function
|
|
- note: function call in module without imports
|
|
modules:
|
|
- |
|
|
package rules
|
|
|
|
double(x) := 2 * x
|
|
|
|
result := double(21)
|
|
query: data.rules.result
|
|
want_result: 42
|
|
- note: call to non-function value rule through import is an error
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
x := 5
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := lib.x(1)
|
|
query: data.rules.result
|
|
error: could not find function
|
|
- note: call to rule path prefix through import is an error
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
a.c := 9
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := lib.a(7)
|
|
query: data.rules.result
|
|
error: could not find function
|
|
- note: call to prefix of default function through import is an error
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
default a.b(_) := 1
|
|
|
|
a.b(x) := x * 2 if x > 10
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := lib.a(7)
|
|
query: data.rules.result
|
|
error: could not find function
|
|
- note: default-only function call through import
|
|
modules:
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
|
|
default dfl(_) := 42
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
|
|
result := lib.dfl(5)
|
|
query: data.rules.result
|
|
want_result: 42
|
|
- note: overload error does not leak callee module imports
|
|
strict: false
|
|
modules:
|
|
- |
|
|
package libx
|
|
import rego.v1
|
|
|
|
h(_) := "WRONG"
|
|
- |
|
|
package liby
|
|
import rego.v1
|
|
|
|
h(_) := "RIGHT"
|
|
- |
|
|
package lib
|
|
import rego.v1
|
|
import data.libx as ali
|
|
|
|
m(_) := 1
|
|
|
|
m(_) := 2
|
|
|
|
f(x) := 100 if x == 1
|
|
|
|
f(x) := y if {
|
|
x == 1
|
|
y := m(1)
|
|
}
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data.lib
|
|
import data.liby as ali
|
|
|
|
main := [v, w] if {
|
|
v := lib.f(1)
|
|
w := ali.h(1)
|
|
}
|
|
query: data.rules.main
|
|
want_result: [100, "RIGHT"]
|
|
- note: with target through dotted bracket key import
|
|
data:
|
|
"a.b":
|
|
x: 1
|
|
modules:
|
|
- |
|
|
package rules
|
|
import rego.v1
|
|
import data["a.b"] as ab
|
|
|
|
main := x if {
|
|
x := data["a.b"].x with ab.x as 2
|
|
}
|
|
query: data.rules.main
|
|
want_result: 2
|