Add merge method to Story

This commit is contained in:
Joakim Soderlund 2017-01-29 00:06:15 +01:00
parent b70c56e632
commit 4ebe8fe29a
4 changed files with 65 additions and 23 deletions

View file

@ -94,3 +94,18 @@ class Story:
self._data = self.fetcher.fetch_data(self.key)
return self._data
def merge(self, **params):
"""
Returns a shallow copy, optionally replacing attributes.
Args:
**params: Overrides parameters from the current instance.
Raises:
TypeError: If passed an unexpected parameter.
"""
kwargs = {k.lstrip('_'): v for k, v in vars(self).items()}
kwargs.update(params)
return type(self)(**kwargs)

View file

@ -121,7 +121,7 @@ class TestStoryDateMapper:
"""
Tests `None` is returned when meta is empty.
"""
story = self.merge(story, dict())
story = story.merge(meta=dict())
assert mapper(story) is None
@ -137,7 +137,7 @@ class TestStoryDateMapper:
],
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) is None
@ -149,7 +149,7 @@ class TestStoryDateMapper:
MODIFIED: 5,
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) == 5
@ -162,7 +162,7 @@ class TestStoryDateMapper:
CHAPTERS: None,
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) == 5
@ -175,7 +175,7 @@ class TestStoryDateMapper:
CHAPTERS: [],
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) == 5
@ -191,7 +191,7 @@ class TestStoryDateMapper:
],
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) == 5
@ -208,7 +208,7 @@ class TestStoryDateMapper:
],
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) == 5
@ -225,7 +225,7 @@ class TestStoryDateMapper:
],
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) == 5
@ -242,7 +242,7 @@ class TestStoryDateMapper:
],
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) == 5
@ -259,7 +259,7 @@ class TestStoryDateMapper:
],
}
story = self.merge(story, meta)
story = story.merge(meta=meta)
assert mapper(story) == 5

View file

@ -46,16 +46,6 @@ class TestUpdateSelector:
"""
return UpdateSelector()
def merge(self, story, **params):
"""
Returns a cloned story, optionally overriding parameters.
"""
data = vars(story)
data = {k.lstrip('_'): v for k, v in data.items()}
data.update(params)
return Story(**data)
def populate(self, story, date=0):
"""
Returns a cloned story populated with chapter meta.
@ -70,7 +60,7 @@ class TestUpdateSelector:
],
}
return self.merge(story, meta=meta)
return story.merge(meta=meta)
def test_filter_empty_with_chapters(self, selector, story):
"""
@ -98,7 +88,7 @@ class TestUpdateSelector:
'chapters': []
}
story = self.merge(story, meta=meta)
story = story.merge(meta=meta)
selected = selector.filter_empty(story)
assert selected is None
@ -268,7 +258,7 @@ class TestUpdateSelector:
fetcher = Mock(spec=Fetcher)
fetcher.fetch_data.side_effect = InvalidStoryError
new = self.merge(story, fetcher=fetcher, data=None)
new = story.merge(fetcher=fetcher, data=None)
selected = selector(old, new)

View file

@ -211,3 +211,40 @@ class TestStory:
assert story.flavors is not flavors
assert story.flavors == {flavor.A}
assert type(story.flavors) == set
def test_merge_without_parameters(self, story):
"""
Tests `merge` returns new story containing current attributes.
"""
merge = story.merge()
assert merge is not story
assert merge.data is story.data
assert merge.meta is story.meta
for k, v in vars(story).items():
assert getattr(merge, k) == v
def test_merge_with_parameters(self, story):
"""
Tests `merge` can override attributes.
"""
meta = dict(story.meta)
merge = story.merge(meta=meta)
assert meta is not story.meta
assert meta is merge.meta
def test_merge_with_invalid_state(self, story):
"""
Tests `merge` is affected by validation in `__init__`.
"""
with pytest.raises(ValueError):
story.merge(fetcher=None, meta=None)
def test_merge_with_invalid_arguments(self, story):
"""
Tests `merge` cannot create story using invalid arguments.
"""
with pytest.raises(TypeError):
story.merge(alpaca=True)