mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
The RVM was silently succeeding on `every` quantifiers (and loops nested inside an `every` body) that should have failed. In each case the loop computed a pass/fail into a register that the surrounding query then ignored, so the RVM disagreed with the interpreter. Four related fixes: - compile_every_quantifier: guard the loop result so a failing `every` body makes the rule undefined instead of always succeeding. - resolve_iteration_state: `every` over a non-iterable scalar (number, string, bool, null, undefined) is now undefined, not vacuously true. Only genuinely empty collections stay true; any/forEach are untouched. - a `some ... in` inside an `every` body now guards its loop result, so a `some` that matches nothing fails the current iteration. Top-level rule bodies still rely on context yields and are unaffected. - a hoisted index iteration (`some i` / `arr[i]`) inside an `every` body gets the same guard. Also drop `every` from OPA_TODO_FOLDERS so the interpreter-vs-RVM differential suite covers it, add an OPA_UNSKIP_FOLDERS env override for auditing other still-skipped folders, and add regression cases for every variant above.
379 lines
7.4 KiB
YAML
379 lines
7.4 KiB
YAML
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
|
|
# Loops and Quantifiers Test Suite
|
|
# Tests basic loop constructs, quantifiers (some/every), and comprehensions
|
|
|
|
cases:
|
|
- note: basic_variable_test
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := result if {
|
|
x := 5
|
|
result := x > 2
|
|
}
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: basic_some_test
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := result if {
|
|
some x in [1, 2, 3]
|
|
x > 2
|
|
result := x
|
|
}
|
|
query: data.test.main
|
|
want_result: 3
|
|
|
|
- note: basic_every_test
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := result if {
|
|
every x in [1, 2, 3] {
|
|
x > 0
|
|
}
|
|
result := true
|
|
}
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_body_fails_for_one_element
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := result if {
|
|
every x in [1, 2, 3] {
|
|
x > 1
|
|
}
|
|
result := true
|
|
}
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_body_fails_for_all_elements
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := result if {
|
|
every x in [1, 2, 3] {
|
|
x > 100
|
|
}
|
|
result := true
|
|
}
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_used_directly_as_condition_false
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every x in [1, 2, 3] {
|
|
x > 1
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_used_directly_as_condition_true
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every x in [1, 2, 3] {
|
|
x > 0
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_over_non_iterable_number_is_undefined
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every x in 42 {
|
|
x > 1
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_over_non_iterable_string_is_undefined
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every x in "hello" {
|
|
x == x
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_over_empty_array_is_vacuously_true
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every x in [] {
|
|
x > 1
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_with_inner_some_matching_nothing_fails
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every c in [1, 2] {
|
|
some x in []
|
|
c == x
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_with_inner_some_matching_succeeds
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every c in [1, 2] {
|
|
some x in [1, 2, 3]
|
|
c == x
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_with_hoisted_index_matching_nothing_fails
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every c in [1] {
|
|
some i
|
|
[2, 3][i] == c
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_with_hoisted_index_matching_succeeds
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every c in [2, 3] {
|
|
some i
|
|
[1, 2, 3][i] == c
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_keyval_over_object_succeeds
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every k, v in {"a": 1, "b": 2} {
|
|
v > 0
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_keyval_over_object_fails
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every k, v in {"a": 1, "b": 2} {
|
|
v > 1
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_over_set_domain_succeeds
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every x in {1, 2, 3} {
|
|
x > 0
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_over_empty_object_is_vacuously_true
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every k, v in {} {
|
|
v > 1
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_over_empty_set_is_vacuously_true
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every x in set() {
|
|
x > 1
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_over_undefined_domain_is_undefined
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every x in input.missing {
|
|
x > 0
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_nested_inside_every_succeeds
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every row in [[1, 2], [3, 4]] {
|
|
every c in row {
|
|
c > 0
|
|
}
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: every_nested_inside_every_fails
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
every row in [[1, 2], [3, 0]] {
|
|
every c in row {
|
|
c > 0
|
|
}
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: "#undefined"
|
|
|
|
- note: every_with_outer_binding
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
allowed if {
|
|
threshold := 5
|
|
every x in [6, 7, 8] {
|
|
x > threshold
|
|
}
|
|
}
|
|
main := allowed
|
|
query: data.test.main
|
|
want_result: true
|
|
|
|
- note: simple_loop_test
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := result if {
|
|
x := 1
|
|
y := 2
|
|
result := x * y
|
|
}
|
|
query: data.test.main
|
|
want_result: 2
|
|
|
|
- note: loop_array_comprehension
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := [(x * 2) | x := [1, 2, 3][_]]
|
|
query: data.test.main
|
|
want_result: [2, 4, 6]
|
|
|
|
- note: loop_set_comprehension
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := {(x * 2) | x := [1, 2, 3][_]}
|
|
query: data.test.main
|
|
want_result:
|
|
set!: [2, 4, 6]
|
|
|
|
- note: loop_object_comprehension
|
|
data: {}
|
|
modules:
|
|
- |
|
|
package test
|
|
main := {k: (v * 2) | v := {"a": 1, "b": 2, "c": 3}[k]}
|
|
query: data.test.main
|
|
want_result:
|
|
a: 2
|
|
b: 4
|
|
c: 6
|