mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
* feat: add Azure Policy builtins with YAML test suite Implement ARM template functions for Azure Policy evaluation: Builtins: - String: indexOf, lastIndexOf, trim, format, split, startsWith, endsWith, padLeft, concat, replace, toLower, toUpper, substring, guid, uniqueString - DateTime: dateTimeAdd, dateTimeFromEpoch, dateTimeToEpoch, addDays - Collection: intersection, union, take, skip, first, last, min, max, range, items, tryGet, tryIndexFromEnd, empty, array, createObject - Encoding: base64, base64ToString, base64ToJson, uri, uriComponent, uriComponentToString, dataUri, dataUriToString - Numeric: int, float, intDiv, intMod - Misc: json, join, bool, string, coalesce, if, getParameter, resolveField - Logic: logicAll, logicAny Key implementation details: - Unicode case-insensitive search via ICU4X case folding with single-pass fold_with_char_map() for indexOf/lastIndexOf - .NET composite formatting (System.String.Format) with alignment, standard and custom datetime format specifiers, numeric format specifiers - DateTime round-trip preserves input shape (Z vs +00:00, T vs space, fractional seconds) when no explicit output format is supplied - Zero-cost as_str() helper borrows directly from Value::String(Rc<str>) - BTreeSet<&Value> in array union avoids redundant cloning Test suite: - 53 YAML test files exercising all builtins via direct BUILTINS registry - Coverage for edge cases: empty inputs, Unicode, fractional seconds, invalid alignment, unknown format specifiers, RFC3339 offset shapes Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * fix: address PR review comments - Fix percent_encode to only uppercase hex digits, not entire string - Remove guid/uniqueString (unsupported); delete custom SHA-1 impl - Replace unwrap_or(0) with proper error in format placeholder parsing - Hoist CaseMapper into static CaseMapperBorrowed for zero per-call overhead - Pre-allocate Vec in range() with_capacity - Update bindings/ffi and bindings/ruby Cargo.lock - Fix uri_component test expectations for correct case preservation Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * fix: address second round of PR review comments - float(): return Undefined when as_f64() fails instead of leaking the original non-f64 representation - createObject(): reject odd number of arguments with an error (ARM-template parity) - format(): error on unknown numeric format specifiers instead of silently passing through (matches .NET FormatException behavior) - format(): cap alignment width at 10,000 to prevent DoS from user-controlled format strings like {0,1000000000} - Add YAML test cases for all new error behaviors Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * fix: address third round of PR review comments - percent_decode: reject incomplete % escapes (e.g. "%", "%2") instead of treating them as literal characters - parse_iso8601_duration: reject leftover digits without a unit designator at T boundary and end-of-input (e.g. "P1", "P1T2H") - yaml_to_value: panic on unsupported YAML numeric representations instead of silently mapping to Null - Revert unused src/languages/mod.rs changes (module is defined inline in lib.rs) Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * fix: add missing edge-case tests and fix empty-delimiter panic - fn_split: return input as single-element array for empty string delimiter instead of panicking (Rust's str::split("") panics) - format: add test for F3 higher precision ({0:F3} + 1.23456 → 1.235) - format: add test for N2 float with thousands separator - format: add test for negative index error ({-1}) - split: add test for empty-string delimiter - uri: add tests for query string and fragment in relative URI - createObject: add test for non-string (numeric) keys Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * fix: address fourth round of PR review comments - Add MAX_VARIADIC_ARGS (64) constant for variadic builtin arity instead of registering with 0 (logic_all, logic_any, min, max, format, intersection, union, coalesce, createObject); set dateTimeAdd to exact arity 3 - Switch indexOf/lastIndexOf to UTF-16 code-unit indices to match .NET String.IndexOf semantics (track ch.len_utf16() in fold_with_char_map, use encode_utf16().count() for empty-needle lastIndexOf) - Use DateTime::<Utc>::from_timestamp for explicit timezone type - Remove stale docs/azure-policy/casing.md link from module doc - Fix misleading comment in want_error test branch (code bails on Undefined, not accepts it) Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> --------- Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
90 lines
2.0 KiB
YAML
90 lines
2.0 KiB
YAML
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
|
|
# Tests for azure.policy.fn.union
|
|
builtin: azure.policy.fn.union
|
|
|
|
cases:
|
|
# ── Array union ─────────────────────────────────────────────────────
|
|
- note: union_arrays_basic
|
|
args: [[1, 2], [2, 3]]
|
|
want: [1, 2, 3]
|
|
|
|
- note: union_arrays_no_overlap
|
|
args: [[1, 2], [3, 4]]
|
|
want: [1, 2, 3, 4]
|
|
|
|
- note: union_arrays_identical
|
|
args: [[1, 2], [1, 2]]
|
|
want: [1, 2]
|
|
|
|
- note: union_arrays_empty
|
|
args: [[], [1, 2]]
|
|
want: [1, 2]
|
|
|
|
- note: union_arrays_both_empty
|
|
args: [[], []]
|
|
want: []
|
|
|
|
- note: union_arrays_three
|
|
args: [[1], [2], [3]]
|
|
want: [1, 2, 3]
|
|
|
|
- note: union_arrays_strings
|
|
args: [["a", "b"], ["b", "c"]]
|
|
want: ["a", "b", "c"]
|
|
|
|
# ── Object union ────────────────────────────────────────────────────
|
|
- note: union_objects_merge
|
|
args: [{"a": 1}, {"b": 2}]
|
|
want: {"a": 1, "b": 2}
|
|
|
|
- note: union_objects_overwrite
|
|
args: [{"a": 1, "b": 2}, {"b": 20, "c": 30}]
|
|
want: {"a": 1, "b": 20, "c": 30}
|
|
|
|
- note: union_objects_empty
|
|
args: [{}, {"a": 1}]
|
|
want: {"a": 1}
|
|
|
|
- note: union_objects_recursive_merge
|
|
args:
|
|
- outer:
|
|
inner_a: 1
|
|
inner_b: 2
|
|
- outer:
|
|
inner_b: 20
|
|
inner_c: 30
|
|
want:
|
|
outer:
|
|
inner_a: 1
|
|
inner_b: 20
|
|
inner_c: 30
|
|
|
|
- note: union_objects_deeply_nested_merge
|
|
args:
|
|
- level1:
|
|
level2:
|
|
a: 1
|
|
b: 2
|
|
- level1:
|
|
level2:
|
|
b: 20
|
|
c: 30
|
|
want:
|
|
level1:
|
|
level2:
|
|
a: 1
|
|
b: 20
|
|
c: 30
|
|
|
|
- note: union_objects_array_replaces_not_merges
|
|
args:
|
|
- data:
|
|
items: [1, 2, 3]
|
|
- data:
|
|
items: [4, 5]
|
|
want:
|
|
data:
|
|
items: [4, 5]
|