diff options
Diffstat (limited to 'nix/mergePatch/default.nix')
-rw-r--r-- | nix/mergePatch/default.nix | 140 |
1 files changed, 73 insertions, 67 deletions
diff --git a/nix/mergePatch/default.nix b/nix/mergePatch/default.nix index 0f80b93d4c65..d56106925a65 100644 --- a/nix/mergePatch/default.nix +++ b/nix/mergePatch/default.nix @@ -8,31 +8,31 @@ For example, given the following original document: { - a = "b"; - c = { + a = "b"; + c = { d = "e"; f = "g"; - } + } } Changing the value of `a` and removing `f` can be achieved by merging the patch { - a = "z"; - c.f = null; + a = "z"; + c.f = null; } which results in { - a = "z"; - c = { + a = "z"; + c = { d = "e"; - }; + }; } Pseudo-code: - define MergePatch(Target, Patch): + define MergePatch(Target, Patch): if Patch is an Object: if Target is not an Object: Target = {} # Ignore the contents and set it to an empty Object @@ -55,19 +55,19 @@ let mergePatch = target: patch: if lib.isAttrs patch then - let target' = if lib.isAttrs target then target else {}; + let target' = if lib.isAttrs target then target else { }; in foldlAttrs - (acc: patchEl: - if patchEl.value == null - then removeAttrs acc [ patchEl.name ] - else acc // { - ${patchEl.name} = - mergePatch - (acc.${patchEl.name} or "unnused") - patchEl.value; - }) - target' - patch + (acc: patchEl: + if patchEl.value == null + then removeAttrs acc [ patchEl.name ] + else acc // { + ${patchEl.name} = + mergePatch + (acc.${patchEl.name} or "unnused") + patchEl.value; + }) + target' + patch else patch; inherit (depot.nix.runTestsuite) @@ -93,46 +93,49 @@ let }; emptyPatch = it "the empty patch returns the original target" [ (assertEq "id" - (mergePatch testTarget {}) + (mergePatch testTarget { }) testTarget) ]; nonAttrs = it "one side is a non-attrset value" [ (assertEq "target is a value means the value is replaced by the patch" (mergePatch 42 testPatch) - (mergePatch {} testPatch)) + (mergePatch { } testPatch)) (assertEq "patch is a value means it replaces target alltogether" (mergePatch testTarget 42) 42) ]; rfcExamples = it "the examples from the RFC" [ (assertEq "a subset is deleted and overwritten" - (mergePatch testTarget testPatch) { + (mergePatch testTarget testPatch) + { a = "z"; c = { d = "e"; }; }) (assertEq "a more complicated example from the example section" - (mergePatch { - title = "Goodbye!"; + (mergePatch + { + title = "Goodbye!"; author = { givenName = "John"; familyName = "Doe"; }; - tags = [ "example" "sample" ]; - content = "This will be unchanged"; - } { - title = "Hello!"; - phoneNumber = "+01-123-456-7890"; - author.familyName = null; - tags = [ "example" ]; - }) + tags = [ "example" "sample" ]; + content = "This will be unchanged"; + } + { + title = "Hello!"; + phoneNumber = "+01-123-456-7890"; + author.familyName = null; + tags = [ "example" ]; + }) { title = "Hello!"; phoneNumber = "+01-123-456-7890"; - author = { - givenName = "John"; - }; + author = { + givenName = "John"; + }; tags = [ "example" ]; content = "This will be unchanged"; }) @@ -144,42 +147,45 @@ let (assertEq "test number ${toString index}" (mergePatch target patch) res); - in it "the test suite from the RFC" [ - (r 1 {"a" = "b";} {"a" = "c";} {"a" = "c";}) - (r 2 {"a" = "b";} {"b" = "c";} {"a" = "b"; "b" = "c";}) - (r 3 {"a" = "b";} {"a" = null;} {}) - (r 4 {"a" = "b"; "b" = "c";} - {"a" = null;} - {"b" = "c";}) - (r 5 {"a" = ["b"];} {"a" = "c";} {"a" = "c";}) - (r 6 {"a" = "c";} {"a" = ["b"];} {"a" = ["b"];}) - (r 7 {"a" = {"b" = "c";}; } - {"a" = {"b" = "d"; "c" = null;};} - {"a" = {"b" = "d";};}) - (r 8 {"a" = [{"b" = "c";}];} - {"a" = [1];} - {"a" = [1];}) - (r 9 ["a" "b"] ["c" "d"] ["c" "d"]) - (r 10 {"a" = "b";} ["c"] ["c"]) - (r 11 {"a" = "foo";} null null) - (r 12 {"a" = "foo";} "bar" "bar") - (r 13 {"e" = null;} {"a" = 1;} {"e" = null; "a" = 1;}) - (r 14 [1 2] - {"a" = "b"; "c" = null;} - {"a" = "b";}) - (r 15 {} - {"a" = {"bb" = {"ccc" = null;};};} - {"a" = {"bb" = {};};}) - ]; - - in runTestsuite "mergePatch" [ + in + it "the test suite from the RFC" [ + (r 1 { "a" = "b"; } { "a" = "c"; } { "a" = "c"; }) + (r 2 { "a" = "b"; } { "b" = "c"; } { "a" = "b"; "b" = "c"; }) + (r 3 { "a" = "b"; } { "a" = null; } { }) + (r 4 { "a" = "b"; "b" = "c"; } + { "a" = null; } + { "b" = "c"; }) + (r 5 { "a" = [ "b" ]; } { "a" = "c"; } { "a" = "c"; }) + (r 6 { "a" = "c"; } { "a" = [ "b" ]; } { "a" = [ "b" ]; }) + (r 7 { "a" = { "b" = "c"; }; } + { "a" = { "b" = "d"; "c" = null; }; } + { "a" = { "b" = "d"; }; }) + (r 8 { "a" = [{ "b" = "c"; }]; } + { "a" = [ 1 ]; } + { "a" = [ 1 ]; }) + (r 9 [ "a" "b" ] [ "c" "d" ] [ "c" "d" ]) + (r 10 { "a" = "b"; } [ "c" ] [ "c" ]) + (r 11 { "a" = "foo"; } null null) + (r 12 { "a" = "foo"; } "bar" "bar") + (r 13 { "e" = null; } { "a" = 1; } { "e" = null; "a" = 1; }) + (r 14 [ 1 2 ] + { "a" = "b"; "c" = null; } + { "a" = "b"; }) + (r 15 { } + { "a" = { "bb" = { "ccc" = null; }; }; } + { "a" = { "bb" = { }; }; }) + ]; + + in + runTestsuite "mergePatch" [ emptyPatch nonAttrs rfcExamples rfcTests ]; -in { +in +{ __functor = _: mergePatch; inherit tests; |