From 66166505d6ecda3eb8b085676273544926b39246 Mon Sep 17 00:00:00 2001 From: Sergey Vasilyev Date: Tue, 23 Apr 2019 01:28:27 +0200 Subject: [PATCH] Test diffs calculation and manipulation --- tests/diffs/test_diff.py | 78 +++++++++++++++++++++++++++++++++++ tests/diffs/test_reduction.py | 54 ++++++++++++++++++++++++ tests/diffs/test_resolving.py | 28 +++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 tests/diffs/test_diff.py create mode 100644 tests/diffs/test_reduction.py create mode 100644 tests/diffs/test_resolving.py diff --git a/tests/diffs/test_diff.py b/tests/diffs/test_diff.py new file mode 100644 index 00000000..feec1232 --- /dev/null +++ b/tests/diffs/test_diff.py @@ -0,0 +1,78 @@ +from kopf.structs.diffs import diff + + +def test_scalars_equal(): + a = 100 + b = 100 + d = diff(a, b) + assert d == () + + +def test_scalars_unequal(): + a = 100 + b = 200 + d = diff(a, b) + assert d == (('change', (), 100, 200),) + + +def test_strings_equal(): + a = 'hello' + b = 'hello' + d = diff(a, b) + assert d == () + + +def test_strings_unequal(): + a = 'hello' + b = 'world' + d = diff(a, b) + assert d == (('change', (), 'hello', 'world'),) + + +def test_lists_equal(): + a = [100, 200, 300] + b = [100, 200, 300] + d = diff(a, b) + assert d == () + + +def test_lists_unequal(): + a = [100, 200, 300] + b = [100, 666, 300] + d = diff(a, b) + assert d == (('change', (), [100, 200, 300], [100, 666, 300]),) + + +def test_dicts_equal(): + a = {'hello': 'world', 'key': 'val'} + b = {'key': 'val', 'hello': 'world'} + d = diff(a, b) + assert d == () + + +def test_dicts_with_keys_added(): + a = {'hello': 'world'} + b = {'hello': 'world', 'key': 'val'} + d = diff(a, b) + assert d == (('add', ('key',), None, 'val'),) + + +def test_dicts_with_keys_removed(): + a = {'hello': 'world', 'key': 'val'} + b = {'hello': 'world'} + d = diff(a, b) + assert d == (('remove', ('key',), 'val', None),) + + +def test_dicts_with_keys_changed(): + a = {'hello': 'world', 'key': 'old'} + b = {'hello': 'world', 'key': 'new'} + d = diff(a, b) + assert d == (('change', ('key',), 'old', 'new'),) + + +def test_dicts_with_subkeys_changed(): + a = {'main': {'hello': 'world', 'key': 'old'}} + b = {'main': {'hello': 'world', 'key': 'new'}} + d = diff(a, b) + assert d == (('change', ('main', 'key'), 'old', 'new'),) diff --git a/tests/diffs/test_reduction.py b/tests/diffs/test_reduction.py new file mode 100644 index 00000000..d38f2ec0 --- /dev/null +++ b/tests/diffs/test_reduction.py @@ -0,0 +1,54 @@ +import pytest + +from kopf.structs.diffs import reduce + + +DIFF = ( + ('op' , (), 'old', 'new'), # unknown operations should be passed through + ('add' , ('key1',), None, 'new1'), + ('change', ('key2',), 'old2', 'new2'), + ('add' , ('key2', 'suba'), 'olda', 'newa'), + ('remove', ('key2', 'subb'), 'oldb', 'newb'), + ('remove', ('key3',), 'old3', None), +) + + +@pytest.mark.parametrize('diff', [ + [['op', ['key', 'sub'], 'old', 'new']], + [['op', ('key', 'sub'), 'old', 'new']], + [('op', ['key', 'sub'], 'old', 'new')], + [('op', ('key', 'sub'), 'old', 'new')], + (['op', ['key', 'sub'], 'old', 'new'],), + (['op', ('key', 'sub'), 'old', 'new'],), + (('op', ['key', 'sub'], 'old', 'new'),), + (('op', ('key', 'sub'), 'old', 'new'),), +], ids=[ + 'lll-diff', 'llt-diff', 'ltl-diff', 'ltt-diff', + 'tll-diff', 'tlt-diff', 'ttl-diff', 'ttt-diff', +]) +@pytest.mark.parametrize('path', [ + ['key', 'sub'], + ('key', 'sub'), +], ids=['list-path', 'tuple-path']) +def test_type_ignored_for_inputs_but_is_tuple_for_output(diff, path): + result = reduce(diff, path) + assert result == (('op', (), 'old', 'new'),) + + +def test_empty_path_selects_all_ops(): + result = reduce(DIFF, []) + assert result == DIFF + + +def test_existent_path_selects_relevant_ops(): + result = reduce(DIFF, ['key2']) + assert result == ( + ('change', (), 'old2', 'new2'), + ('add' , ('suba',), 'olda', 'newa'), + ('remove', ('subb',), 'oldb', 'newb'), + ) + + +def test_nonexistent_path_selects_nothing(): + result = reduce(DIFF, ['nonexistent-key']) + assert result == () diff --git a/tests/diffs/test_resolving.py b/tests/diffs/test_resolving.py new file mode 100644 index 00000000..bc7426d3 --- /dev/null +++ b/tests/diffs/test_resolving.py @@ -0,0 +1,28 @@ +import pytest + +from kopf.structs.diffs import resolve + + +def test_existing_key(): + d = {'abc': {'def': {'hij': 'val'}}} + r = resolve(d, ['abc', 'def', 'hij']) + assert r == 'val' + + +def test_unexisting_key(): + d = {'abc': {'def': {'hij': 'val'}}} + with pytest.raises(KeyError): + resolve(d, ['abc', 'def', 'xyz']) + + +def test_nonmapping_key(): + d = {'key': 'val'} + with pytest.raises(TypeError): + resolve(d, ['key', 'sub']) + + +def test_empty_path(): + d = {'key': 'val'} + r = resolve(d, []) + assert r == d + assert r is d