Skip to content

Commit 5dd9c39

Browse files
committed
Fixed tests
1 parent 430ccc9 commit 5dd9c39

2 files changed

Lines changed: 31 additions & 23 deletions

File tree

lib/jsonpatch.ex

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ defmodule Jsonpatch do
111111
iex> destination = %{"name" => "Bob", "married" => true, "hobbies" => ["Elixir!"], "age" => 33}
112112
iex> Jsonpatch.diff(source, destination)
113113
[
114-
%Add{path: "/age", value: 33},
115-
%Replace{path: "/hobbies/0", value: "Elixir!"},
116-
%Replace{path: "/married", value: true},
117-
%Remove{path: "/hobbies/1"},
118-
%Remove{path: "/hobbies/2"}
114+
%Jsonpatch.Operation.Replace{path: "/married", value: true},
115+
%Jsonpatch.Operation.Remove{path: "/hobbies/2"},
116+
%Jsonpatch.Operation.Remove{path: "/hobbies/1"},
117+
%Jsonpatch.Operation.Replace{path: "/hobbies/0", value: "Elixir!"},
118+
%Jsonpatch.Operation.Add{path: "/age", value: 33}
119119
]
120120
"""
121121
@spec diff(maybe_improper_list | map, maybe_improper_list | map) :: list(Jsonpatch.t())
@@ -144,15 +144,26 @@ defmodule Jsonpatch do
144144
defguardp are_unequal_lists(val1, val2)
145145
when val1 != val2 and is_list(val2) and is_list(val1)
146146

147-
defp do_diff(destination, source, current_path, acc \\ [])
147+
defp do_diff(destination, source, ancestor_path, acc \\ [], checked_keys \\ [])
148+
149+
defp do_diff([], source, ancestor_path, acc, checked_keys) do
150+
# The complete desination was check. Every key that is not in the list of
151+
# checked keys, must be removed.
152+
acc =
153+
source
154+
|> flat()
155+
|> Stream.map(fn {k, _} -> k end)
156+
|> Stream.filter(fn k -> k not in checked_keys end)
157+
|> Stream.map(fn k -> %Remove{path: "#{ancestor_path}/#{k}"} end)
158+
|> Enum.reduce(acc, fn r, acc -> [r | acc] end)
148159

149-
defp do_diff([], _, _, acc) do
150160
acc
151161
end
152162

153-
defp do_diff([{key, val} | tail], source, ancestor_path, acc)
163+
defp do_diff([{key, val} | tail], source, ancestor_path, acc, checked_keys)
154164
when is_list(source) or is_map(source) do
155165
current_path = "#{ancestor_path}/#{escape(key)}"
166+
checked_keys = [escape(key) | checked_keys]
156167

157168
from_source =
158169
cond do
@@ -169,8 +180,8 @@ defmodule Jsonpatch do
169180
# Source has a different value but both (destination and source) value are lists or a maps
170181
source_val
171182
when are_unequal_lists(source_val, val) or are_unequal_maps(source_val, val) ->
172-
# Enter next level
173-
do_diff(next_level(val), source_val, current_path, acc)
183+
# Enter next level - set check_keys to empty list because it is a different level
184+
do_diff(flat(val), source_val, current_path, acc, [])
174185

175186
# Scalar source val that is not equal
176187
source_val when source_val != val ->
@@ -181,13 +192,13 @@ defmodule Jsonpatch do
181192
end
182193

183194
# Diff next value of same level
184-
do_diff(tail, source, ancestor_path, acc)
195+
do_diff(tail, source, ancestor_path, acc, checked_keys)
185196
end
186197

187198
# Transforms a map into a tuple list and a list also into a tuple list with indizes
188-
defp next_level(val) do
199+
defp flat(val) do
189200
cond do
190-
is_list(val) -> Enum.with_index(val) |> Enum.map(fn {v, k} -> {k, v} end)
201+
is_list(val) -> Stream.with_index(val) |> Enum.map(fn {v, k} -> {k, v} end)
191202
is_map(val) -> Map.to_list(val)
192203
true -> []
193204
end

test/jsonpatch_test.exs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,23 +75,20 @@ defmodule JsonpatchTest do
7575
patch = Jsonpatch.diff(source, destination)
7676

7777
assert [
78+
%Jsonpatch.Operation.Remove{
79+
path: "/items/0/spec/template/spec/containers/0/ports/0"
80+
},
81+
%Jsonpatch.Operation.Replace{
82+
path: "/items/0/spec/template/spec/containers/0/image",
83+
value: "whoami:1.1.2"
84+
},
7885
%Jsonpatch.Operation.Add{
7986
path: "/items/0/spec/template/spec/containers/0/env/1",
8087
value: %{"name" => "ANOTHER_MESSAGE", "value" => "Hey there!"}
8188
},
8289
%Jsonpatch.Operation.Replace{
8390
path: "/items/0/spec/template/spec/containers/0/env/0/name",
8491
value: "ENVIRONMENT_MESSAGE"
85-
},
86-
%Jsonpatch.Operation.Replace{
87-
path: "/items/0/spec/template/spec/containers/0/image",
88-
value: "whoami:1.1.2"
89-
},
90-
%Jsonpatch.Operation.Remove{
91-
path: "/items/0/spec/template/spec/containers/0/ports/0/protocol"
92-
},
93-
%Jsonpatch.Operation.Remove{
94-
path: "/items/0/spec/template/spec/containers/0/ports/0/containerPort"
9592
}
9693
] = patch
9794
end

0 commit comments

Comments
 (0)