From 77e355a9854182894de7609da708994787146a81 Mon Sep 17 00:00:00 2001 From: jneem Date: Tue, 24 Dec 2024 09:15:59 +0700 Subject: [PATCH] Freeze records on insert/remove/update. (#2131) * Freeze the record before insert/remove/update * Add tests * Make the test evaluate --- core/stdlib/std.ncl | 9 +++++---- .../records/freeze_insert_fails_on_missing.ncl | 8 ++++++++ .../integration/inputs/records/freezing_ops.ncl | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 core/tests/integration/inputs/records/freeze_insert_fails_on_missing.ncl create mode 100644 core/tests/integration/inputs/records/freezing_ops.ncl diff --git a/core/stdlib/std.ncl b/core/stdlib/std.ncl index 91086278d..ed5c5af97 100644 --- a/core/stdlib/std.ncl +++ b/core/stdlib/std.ncl @@ -3187,7 +3187,7 @@ # => error ``` "%% - = fun field content r => %record/insert% field r content, + = fun field content r => %record/insert% field (%record/freeze% r) content, insert_with_opts : forall a. String -> a -> { _ : a } -> { _ : a } @@ -3221,7 +3221,7 @@ # => error ``` "%% - = fun field content r => %record/insert_with_opts% field r content, + = fun field content r => %record/insert_with_opts% field (%record/freeze% r) content, remove : forall a. String -> { _ : a } -> { _ : a } @@ -3256,7 +3256,7 @@ # => error ``` "% - = fun field r => %record/remove% field r, + = fun field r => %record/remove% field (%record/freeze% r), remove_with_opts : forall a. String -> { _ : a } -> { _ : a } @@ -3284,7 +3284,7 @@ # => error ``` "% - = fun field r => %record/remove_with_opts% field r, + = fun field r => %record/remove_with_opts% field (%record/freeze% r), update : forall a. String -> a -> { _ : a } -> { _ : a } @@ -3327,6 +3327,7 @@ ``` "% = fun field content r => + let r = %record/freeze% r in let r = if %record/has_field% field r then %record/remove% field r diff --git a/core/tests/integration/inputs/records/freeze_insert_fails_on_missing.ncl b/core/tests/integration/inputs/records/freeze_insert_fails_on_missing.ncl new file mode 100644 index 000000000..22dfaa4a7 --- /dev/null +++ b/core/tests/integration/inputs/records/freeze_insert_fails_on_missing.ncl @@ -0,0 +1,8 @@ +# test.type = 'error' +# +# [test.metadata] +# error = 'EvalError::MissingFieldDef' +# +# [test.metadata.expectation] +# field = 'bar' +((std.record.insert "bar" 1 { foo = bar + 1, bar | optional }) & { bar | force = 2 }).foo diff --git a/core/tests/integration/inputs/records/freezing_ops.ncl b/core/tests/integration/inputs/records/freezing_ops.ncl new file mode 100644 index 000000000..b289ad6e3 --- /dev/null +++ b/core/tests/integration/inputs/records/freezing_ops.ncl @@ -0,0 +1,15 @@ +# test.type = 'pass' +[ + ((std.record.insert "baz" 1 { foo = bar + 1, bar = 0 }) & { bar | force = 2 }) == { foo = 1, bar = 2, baz = 1 }, + ((std.record.insert_with_opts "baz" 1 { foo = bar + 1, bar = 0 }) & { bar | force = 2 }) == { foo = 1, bar = 2, baz = 1 }, + ( + (std.record.remove "to_remove" { foo = bar + 1, bar = 0, to_remove = false, rev_dep = to_remove }) + & { bar | force = 1, to_remove = true } + ) == { foo = 1, bar = 1, to_remove = true, rev_dep = false }, + ( + (std.record.remove_with_opts "to_remove" { foo = bar + 1, bar = 0, to_remove = false, rev_dep = to_remove }) + & { bar | force = 1, to_remove = true } + ) == { foo = 1, bar = 1, to_remove = true, rev_dep = false }, + ((std.record.update "bar" 1 { foo = bar + 1, bar = 0 }) & { bar | force = 2 }) == { foo = 1, bar = 2, }, +] +|> std.test.assert_all