mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
5b60daabd9
* 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>
162 lines
4.8 KiB
YAML
162 lines
4.8 KiB
YAML
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
|
|
# Tests for azure.policy.fn.date_time_add
|
|
builtin: azure.policy.fn.date_time_add
|
|
|
|
cases:
|
|
- note: add_one_day
|
|
args: ["2024-01-15T12:00:00Z", "P1D"]
|
|
want: "2024-01-16T12:00:00Z"
|
|
|
|
- note: add_one_hour
|
|
args: ["2024-01-15T12:00:00Z", "PT1H"]
|
|
want: "2024-01-15T13:00:00Z"
|
|
|
|
- note: add_thirty_minutes
|
|
args: ["2024-01-15T12:00:00Z", "PT30M"]
|
|
want: "2024-01-15T12:30:00Z"
|
|
|
|
- note: add_negative_one_day
|
|
args: ["2024-01-15T12:00:00Z", "-P1D"]
|
|
want: "2024-01-14T12:00:00Z"
|
|
|
|
- note: add_complex_duration
|
|
args: ["2024-01-15T12:00:00Z", "P1DT2H30M"]
|
|
want: "2024-01-16T14:30:00Z"
|
|
|
|
- note: add_one_year_approx
|
|
args: ["2024-01-01T00:00:00Z", "P1Y"]
|
|
want: "2024-12-31T00:00:00Z"
|
|
|
|
- note: add_zero_duration
|
|
args: ["2024-06-15T10:30:00Z", "PT0S"]
|
|
want: "2024-06-15T10:30:00Z"
|
|
|
|
- note: invalid_base_datetime
|
|
args: ["not-a-date", "P1D"]
|
|
want_undefined: true
|
|
|
|
- note: invalid_duration
|
|
args: ["2024-01-15T12:00:00Z", "invalid"]
|
|
want_undefined: true
|
|
|
|
- note: datetime_without_timezone
|
|
args: ["2024-01-15T12:00:00", "P1D"]
|
|
want: "2024-01-16T12:00:00"
|
|
|
|
- note: add_one_week
|
|
args: ["2024-01-15T00:00:00Z", "P1W"]
|
|
want: "2024-01-22T00:00:00Z"
|
|
|
|
- note: space_separated_datetime
|
|
args: ["2020-04-07 14:55:59", "P3D"]
|
|
want: "2020-04-10 14:55:59"
|
|
|
|
- note: space_separated_datetime_with_z
|
|
args: ["2020-04-07 14:55:59Z", "P3D"]
|
|
want: "2020-04-10 14:55:59Z"
|
|
|
|
- note: space_separated_datetime_with_offset
|
|
args: ["2020-04-07 14:55:59+05:30", "P1D"]
|
|
want: "2020-04-08 14:55:59+05:30"
|
|
|
|
- note: output_format_date_only
|
|
args: ["2020-04-07T14:55:59Z", "P3Y2M", "yyyy-MM-dd"]
|
|
want: "2023-06-06"
|
|
|
|
- note: output_format_custom
|
|
args: ["2024-01-15T12:00:00Z", "PT1H", "yyyy-MM-dd HH:mm:ss"]
|
|
want: "2024-01-15 13:00:00"
|
|
|
|
- note: output_format_with_k_utc
|
|
args: ["2024-01-15T12:00:00Z", "P0D", "yyyy-MM-ddTHH:mm:ssK"]
|
|
want: "2024-01-15T12:00:00Z"
|
|
|
|
# Standard .NET format specifiers
|
|
- note: output_standard_format_d
|
|
args: ["2024-01-15T12:30:00Z", "P1D", "d"]
|
|
want: "01/16/2024"
|
|
|
|
- note: output_standard_format_G
|
|
args: ["2024-01-15T12:30:00Z", "PT1H", "G"]
|
|
want: "01/15/2024 13:30:00"
|
|
|
|
- note: output_standard_format_o
|
|
args: ["2024-01-15T12:00:00Z", "P0D", "o"]
|
|
want: "2024-01-15T12:00:00.0000000Z"
|
|
|
|
- note: output_standard_format_o_with_nanos
|
|
args: ["2024-01-15T12:00:00.123456700Z", "P0D", "o"]
|
|
want: "2024-01-15T12:00:00.1234567Z"
|
|
|
|
- note: output_standard_format_u
|
|
args: ["2024-01-15T12:00:00Z", "P0D", "u"]
|
|
want: "2024-01-15 12:00:00Z"
|
|
|
|
- note: output_standard_format_u_with_offset
|
|
args: ["2024-01-15T12:00:00+05:30", "P0D", "u"]
|
|
want: "2024-01-15 06:30:00Z"
|
|
|
|
# Fractional seconds preservation (default round-trip, no explicit format)
|
|
- note: roundtrip_iso_no_tz_with_frac
|
|
args: ["2024-01-15T12:00:00.123", "P0D"]
|
|
want: "2024-01-15T12:00:00.123"
|
|
|
|
- note: roundtrip_iso_no_tz_with_frac_add
|
|
args: ["2024-01-15T12:00:00.500", "P1D"]
|
|
want: "2024-01-16T12:00:00.500"
|
|
|
|
- note: roundtrip_space_no_tz_with_frac
|
|
args: ["2024-01-15 12:00:00.456", "P0D"]
|
|
want: "2024-01-15 12:00:00.456"
|
|
|
|
- note: roundtrip_space_z_with_frac
|
|
args: ["2024-01-15 12:00:00.789Z", "P0D"]
|
|
want: "2024-01-15 12:00:00.789Z"
|
|
|
|
- note: roundtrip_space_offset_with_frac
|
|
args: ["2024-01-15 12:00:00.123+05:30", "P0D"]
|
|
want: "2024-01-15 12:00:00.123+05:30"
|
|
|
|
- note: roundtrip_no_frac_stays_clean
|
|
args: ["2024-01-15T12:00:00", "P0D"]
|
|
want: "2024-01-15T12:00:00"
|
|
|
|
- note: roundtrip_rfc3339_utc_with_frac
|
|
args: ["2024-01-15T12:00:00.123Z", "P0D"]
|
|
want: "2024-01-15T12:00:00.123Z"
|
|
|
|
- note: roundtrip_rfc3339_offset_with_frac
|
|
args: ["2024-01-15T12:00:00.456+05:30", "P0D"]
|
|
want: "2024-01-15T12:00:00.456+05:30"
|
|
|
|
- note: roundtrip_rfc3339_utc_no_frac_stays_clean
|
|
args: ["2024-01-15T12:00:00Z", "P0D"]
|
|
want: "2024-01-15T12:00:00Z"
|
|
|
|
- note: roundtrip_rfc3339_explicit_zero_offset
|
|
args: ["2024-01-15T12:00:00+00:00", "P0D"]
|
|
want: "2024-01-15T12:00:00+00:00"
|
|
|
|
- note: roundtrip_rfc3339_explicit_zero_offset_with_frac
|
|
args: ["2024-01-15T12:00:00.500+00:00", "P0D"]
|
|
want: "2024-01-15T12:00:00.500+00:00"
|
|
|
|
# Unknown single-char format specifier is a real error
|
|
- note: unknown_format_specifier_q
|
|
args: ["2024-01-15T12:00:00Z", "P0D", "q"]
|
|
want_error: "unrecognised standard format specifier 'q'"
|
|
|
|
- note: output_standard_format_U
|
|
args: ["2024-01-15T12:00:00+05:30", "P0D", "U"]
|
|
want: "Monday, 15 January 2024 06:30:00"
|
|
|
|
- note: output_standard_format_s
|
|
args: ["2024-01-15T12:00:00Z", "P0D", "s"]
|
|
want: "2024-01-15T12:00:00"
|
|
|
|
- note: output_standard_format_R
|
|
args: ["2024-01-15T12:00:00+05:30", "P0D", "R"]
|
|
want: "Mon, 15 Jan 2024 06:30:00 GMT"
|