Repository: microsoft/regorus (language: python)

Issue:
Objects can be created with `undefined` keys and values
In object expressions, "undefined" values are added to the object instead of making the expression itself undefined.

ORIGINAL TITLE: Different behavior of Regorus vs OPA for when invoking count

---- Original Description ---
Regorus it is behaving differently for `count(expr)` in case that the expression to be evaluated is `null` or `scalar`. The OPA is doing evaluation like the expression is undefined but regorus evaluation fails with error.

**Repro scenario:**

**Step 1:** Create **bug.rego** file with following content

```rego
package test
import rego.v1

foo := input.a

some_id := {
    "count_value": count(foo) > 2,
}
```
**Step 2:** Create **bug.json** file with following content
```json
{
    "a":null
}
```
**Step 3:** run command below (assuming you already run `cargo install --example regorus --path .`

```bash
./target/release/examples/regorus eval -d ./bug.rego -i ./bug.json data.test
```
The output is
```text
Error:
--> ./bug.rego:7:26
  |
7 |     "count_value": count(foo) > 2,
  |                          ^
error: `count` requires array/object/set/string argument. Got `null`.
```

However, if you go to the https://play.openpolicyagent.org/ and fill in the content of the `bug.rego` into the input the content of `bug.json` and click `Evaluate`, you'll get following output

```json
{
    "foo": null
}
```

Is it possible to change the regorus so the  evaluation output to be similar to OPA evaluation? 


Discussion / hints:
Seems like this is related to Regorus enabling strict built-in errors by default. If you pass `--non-strict` it works:

```
$ ./target/release/examples/regorus eval -d examples/bug.rego -i ./examples/bug.json data.test --non-strict
{
  "result": [
    {
      "expressions": [
        {
          "value": {
            "foo": null,
            "some_id": {
              "count_value": "<undefined>"
            }
          },
          "text": "data.test",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}
```

And you also get same error on OPA Playground if you enable strict built-in errors by via "Options > Built-in Error Behaviour > Strict".

Fix patch:
diff --git a/src/interpreter.rs b/src/interpreter.rs
index e00e3f35..b3e68d93 100644
--- a/src/interpreter.rs
+++ b/src/interpreter.rs
@@ -1905,7 +1905,13 @@ impl Interpreter {
             // ( scalar | ref | var ) ":" term, the OPA
             // implementation is more like expr ":" expr
             let key = self.eval_expr(key)?;
+            if key == Value::Undefined {
+                return Ok(Value::Undefined);
+            }
             let value = self.eval_expr(value)?;
+            if value == Value::Undefined {
+                return Ok(Value::Undefined);
+            }
             object.insert(key, value);
         }
 


Test patch:
diff --git a/tests/interpreter/cases/nonstrict/tests.yaml b/tests/interpreter/cases/nonstrict/tests.yaml
index 665ff134..b20be4c8 100644
--- a/tests/interpreter/cases/nonstrict/tests.yaml
+++ b/tests/interpreter/cases/nonstrict/tests.yaml
@@ -17,3 +17,38 @@
           a = to_number("abc")
       query: data.test
       error: "could not parse string as number"
+
+    - note: count of null error gobbled up in non strict mode
+      modules:
+        - |
+          package test
+          import rego.v1
+
+          foo := input.a
+
+          some_id := {
+            "count_value": count(foo) > 2,
+          }
+      input:
+        a: null
+      query: data.test
+      strict: false
+      want_result:
+        foo: null
+
+    - note: count of null error in strict mode
+      modules:
+        - |
+          package test
+          import rego.v1
+
+          foo := input.a
+
+          some_id := {
+            "count_value": count(foo) > 2,
+            (count(foo) > 2): "count_value",
+          }
+      input:
+        a: null
+      query: data.test
+      error: "`count` requires array/object/set/string argument"