From 5300e6816b9a67333c916b13308c0a8d41e9e871 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Thu, 25 Feb 2016 02:18:43 +0100 Subject: [PATCH 1/4] 100% coverage for metasync --- tests/test_metasync.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test_metasync.py b/tests/test_metasync.py index 508347b..522bfdd 100644 --- a/tests/test_metasync.py +++ b/tests/test_metasync.py @@ -5,6 +5,8 @@ import pytest from vdirsyncer.metasync import MetaSyncConflict, metasync from vdirsyncer.storage.memory import MemoryStorage +from . import blow_up + def test_irrelevant_status(): a = MemoryStorage() @@ -15,7 +17,7 @@ def test_irrelevant_status(): assert not status -def test_basic(): +def test_basic(monkeypatch): a = MemoryStorage() b = MemoryStorage() status = {} @@ -28,6 +30,13 @@ def test_basic(): metasync(a, b, status, keys=['foo']) assert a.get_meta('foo') == b.get_meta('foo') == 'baz' + monkeypatch.setattr(a, 'set_meta', blow_up) + monkeypatch.setattr(b, 'set_meta', blow_up) + metasync(a, b, status, keys=['foo']) + assert a.get_meta('foo') == b.get_meta('foo') == 'baz' + monkeypatch.undo() + monkeypatch.undo() + b.set_meta('foo', None) metasync(a, b, status, keys=['foo']) assert a.get_meta('foo') is b.get_meta('foo') is None From f3c459eb7d46eae853eac55f74e2c437d9ecd1a8 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Thu, 25 Feb 2016 02:22:38 +0100 Subject: [PATCH 2/4] 100% coverage for vdirsyncer.__init__ --- vdirsyncer/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vdirsyncer/__init__.py b/vdirsyncer/__init__.py index 29ef0d6..9de885f 100644 --- a/vdirsyncer/__init__.py +++ b/vdirsyncer/__init__.py @@ -7,7 +7,7 @@ from __future__ import print_function try: from .version import version as __version__ # noqa -except ImportError: +except ImportError: # pragma: no cover raise ImportError( 'Failed to find (autogenerated) version.py. ' 'This might be because you are installing from GitHub\'s tarballs, ' @@ -15,7 +15,7 @@ except ImportError: ) -def _detect_faulty_requests(): +def _detect_faulty_requests(): # pragma: no cover import requests if 'dist-packages' not in requests.__file__: return From 8a6ad410da49f76b312b5218cf003c9ee26844bb Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Thu, 25 Feb 2016 02:57:26 +0100 Subject: [PATCH 3/4] Tests for fetchparams --- tests/cli/test_fetchparams.py | 129 ++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/tests/cli/test_fetchparams.py b/tests/cli/test_fetchparams.py index 129aafb..c853e8d 100644 --- a/tests/cli/test_fetchparams.py +++ b/tests/cli/test_fetchparams.py @@ -2,6 +2,42 @@ from textwrap import dedent +from hypothesis import given +import hypothesis.strategies as st + +import pytest + +from vdirsyncer import exceptions +from vdirsyncer.cli.fetchparams import STRATEGIES, expand_fetch_params +from vdirsyncer.utils.compat import PY2 + + +@pytest.fixture +def mystrategy(monkeypatch): + def strategy(x): + calls.append(x) + return x + calls = [] + monkeypatch.setitem(STRATEGIES, 'mystrategy', strategy) + return calls + + +@pytest.fixture +def value_cache(monkeypatch): + _cache = {} + + class FakeContext(object): + fetched_params = _cache + + def find_object(self, _): + return self + + def get_context(*a, **kw): + return FakeContext() + + monkeypatch.setattr('click.get_current_context', get_context) + return _cache + def test_get_password_from_command(tmpdir, runner): runner.write_with_general(dedent(''' @@ -42,3 +78,96 @@ def test_get_password_from_command(tmpdir, runner): result = runner.invoke(['sync'], input='.asdf\n') assert not result.exception assert [x.basename for x in bar.join('a').listdir()] == ['foo.asdf'] + + +def test_key_conflict(monkeypatch, mystrategy): + with pytest.raises(ValueError) as excinfo: + expand_fetch_params({ + 'foo': 'bar', + 'foo.fetch': ['mystrategy', 'baz'] + }) + + assert 'Can\'t set foo.fetch and foo.' in str(excinfo.value) + + +@pytest.mark.skipif(PY2, reason='Don\'t care about Python 2') +@given(s=st.text(), t=st.text(min_size=1)) +def test_fuzzing(s, t, mystrategy): + config = expand_fetch_params({ + '{}.fetch'.format(s): ['mystrategy', t] + }) + + assert config[s] == t + + +@pytest.mark.parametrize('value', [ + [], + 'lol', + 42 +]) +def test_invalid_fetch_value(mystrategy, value): + with pytest.raises(ValueError) as excinfo: + expand_fetch_params({ + 'foo.fetch': value + }) + + assert 'Expected a list' in str(excinfo.value) or \ + 'Expected list of length > 0' in str(excinfo.value) + + +def test_unknown_strategy(): + with pytest.raises(exceptions.UserError) as excinfo: + expand_fetch_params({ + 'foo.fetch': ['unreal', 'asdf'] + }) + + assert 'Unknown strategy' in str(excinfo.value) + + +def test_caching(monkeypatch, mystrategy, value_cache): + orig_cfg = {'foo.fetch': ['mystrategy', 'asdf']} + + rv = expand_fetch_params(orig_cfg) + assert rv['foo'] == 'asdf' + assert mystrategy == ['asdf'] + assert len(value_cache) == 1 + + rv = expand_fetch_params(orig_cfg) + assert rv['foo'] == 'asdf' + assert mystrategy == ['asdf'] + assert len(value_cache) == 1 + + value_cache.clear() + rv = expand_fetch_params(orig_cfg) + assert rv['foo'] == 'asdf' + assert mystrategy == ['asdf'] * 2 + assert len(value_cache) == 1 + + +def test_failed_strategy(monkeypatch, value_cache): + calls = [] + + def strategy(x): + calls.append(x) + raise KeyboardInterrupt() + + monkeypatch.setitem(STRATEGIES, 'mystrategy', strategy) + + orig_cfg = {'foo.fetch': ['mystrategy', 'asdf']} + + for _ in range(2): + with pytest.raises(KeyboardInterrupt): + expand_fetch_params(orig_cfg) + + assert len(value_cache) == 1 + assert len(calls) == 1 + + +def test_empty_value(monkeypatch, mystrategy): + with pytest.raises(exceptions.UserError) as excinfo: + expand_fetch_params({ + 'foo.fetch': ['mystrategy', ''] + }) + + assert 'Empty value for foo.fetch, this most likely indicates an error' \ + in str(excinfo.value) From 7d60c05b2bf65c728e0b48bcd3deeb1dd5574978 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Thu, 25 Feb 2016 03:03:37 +0100 Subject: [PATCH 4/4] filesystem: missing metadata is handled correctly --- tests/storage/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/storage/__init__.py b/tests/storage/__init__.py index 7226722..e0e03a7 100644 --- a/tests/storage/__init__.py +++ b/tests/storage/__init__.py @@ -268,6 +268,10 @@ class StorageTests(object): if getattr(self, 'dav_server', '') == 'owncloud': pytest.skip('ownCloud is fundamentally broken.') + if not getattr(self, 'dav_server', ''): + assert s.get_meta('color') is None + assert s.get_meta('displayname') is None + try: s.set_meta('color', None) assert s.get_meta('color') is None