Skip to content

Commit 123397b

Browse files
Merge pull request #16 from networktocode-llc/dga-issue-12
Add order_children methods in Diff Object
2 parents b88d114 + 197f671 commit 123397b

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

dsync/diff.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,30 @@ def has_diffs(self) -> bool:
6868
return False
6969

7070
def get_children(self) -> Iterator["DiffElement"]:
71-
"""Iterate over all child elements in all groups in self.children."""
71+
"""Iterate over all child elements in all groups in self.children.
72+
73+
For each group of children, check if an order method is defined,
74+
Otherwise use the default method.
75+
"""
76+
order_default = "order_children_default"
77+
7278
for group in self.groups():
73-
for child in self.children[group].values():
74-
yield child
79+
order_method_name = f"order_children_{group}"
80+
if hasattr(self, order_method_name):
81+
order_method = getattr(self, order_method_name)
82+
else:
83+
order_method = getattr(self, order_default)
84+
85+
yield from order_method(self.children[group])
86+
87+
@classmethod
88+
def order_children_default(cls, children: dict) -> Iterator["DiffElement"]:
89+
"""Default method to an Iterator for children.
90+
91+
Since children is already an OrderedDefaultDict, this method is not doing anything special.
92+
"""
93+
for child in children.values():
94+
yield child
7595

7696
def print_detailed(self, indent: int = 0):
7797
"""Print all diffs to screen for all child elements.

examples/example1/main.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@
55
from backend_c import BackendC
66

77

8+
from dsync import Diff
9+
10+
11+
class MyDiff(Diff):
12+
"""Custom Diff class to control the order of the site objects."""
13+
14+
@classmethod
15+
def order_children_site(cls, children):
16+
"""Return the site children ordered in alphabetical order."""
17+
keys = sorted(children.keys(), reverse=False)
18+
for key in keys:
19+
yield children[key]
20+
21+
822
def main():
923
"""Demonstrate DSync behavior using the example backends provided."""
1024
# pylint: disable=invalid-name
@@ -18,7 +32,7 @@ def main():
1832
c = BackendC()
1933
c.load()
2034

21-
diff_a_b = a.diff_to(b)
35+
diff_a_b = a.diff_to(b, diff_class=MyDiff)
2236
diff_a_b.print_detailed()
2337

2438
a.sync_to(b)

tests/unit/test_diff.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,42 @@ def test_diff_children():
4949
assert diff.has_diffs()
5050

5151
# TODO: test print_detailed
52+
53+
54+
def test_order_children_default(backend_a, backend_b):
55+
"""Test that order_children_default is properly called when calling get_children."""
56+
57+
class MyDiff(Diff):
58+
"""custom diff class to test order_children_default."""
59+
60+
@classmethod
61+
def order_children_default(cls, children):
62+
"""Return the children ordered in alphabetical order."""
63+
keys = sorted(children.keys(), reverse=False)
64+
for key in keys:
65+
yield children[key]
66+
67+
# Validating default order method
68+
diff_a_b = backend_a.diff_from(backend_b, diff_class=MyDiff)
69+
children = diff_a_b.get_children()
70+
children_names = [child.name for child in children]
71+
assert children_names == ["atl", "nyc", "rdu", "sfo"]
72+
73+
74+
def test_order_children_custom(backend_a, backend_b):
75+
"""Test that a custom order_children method is properly called when calling get_children."""
76+
77+
class MyDiff(Diff):
78+
"""custom diff class to test order_children_site."""
79+
80+
@classmethod
81+
def order_children_site(cls, children):
82+
"""Return the site children ordered in reverse-alphabetical order."""
83+
keys = sorted(children.keys(), reverse=True)
84+
for key in keys:
85+
yield children[key]
86+
87+
diff_a_b = backend_a.diff_from(backend_b, diff_class=MyDiff)
88+
children = diff_a_b.get_children()
89+
children_names = [child.name for child in children]
90+
assert children_names == ["sfo", "rdu", "nyc", "atl"]

0 commit comments

Comments
 (0)