def test_212_last_edited_should_stay_none_after_updating_other_attributes( self): """last_edited attribute should still be `None` after changing non-content attributes.""" article = qualifier.Article(title="b", author="c", content="d", publication_date=mock.Mock( datetime.datetime)) self.assertTrue(hasattr(article, "last_edited"), msg="`Article` object has no `last_edited` attribute") self.assertIsNone(article.last_edited, "Initial value of last_edited should be None") # We need to make sure to set correct types to account for solutions # that use the ArticleField descriptor. new_values = (("title", "one"), ("author", "two"), ("publication_date", mock.Mock(datetime.datetime))) for attribute, new_value in new_values: try: setattr(article, attribute, new_value) except AttributeError: # We did not explicitly state that the attributes have to be # mutable, so I guess making them immutable is another way to # make sure that `last_edited` only changes when `content` is # changed. continue else: self.assertIsNone(article.last_edited, "Value of last_edited should still be None")
def test_202_last_edited(self, local_datetime): """last_edited attribute should update to the current time when the content changes.""" article = qualifier.Article( title="a", author="b", content="c", publication_date=mock.Mock(datetime.datetime) ) self.assertTrue( hasattr(article, "last_edited"), msg="`Article` object has no `last_edited` attribute" ) self.assertIsNone(article.last_edited, "Initial value of last_edited should be None") # Set twice to account for both "import datetime" and "from datetime import datetime" side_effects = ( datetime.datetime(2020, 7, 2, 15, 3, 10), datetime.datetime(2020, 7, 2, 16, 3, 10), ) local_datetime.now.side_effect = side_effects local_datetime.datetime.now.side_effect = side_effects article.content = "'I know I'm not stupid,' the man thought," self.assertEqual(side_effects[0], article.last_edited) article.content = "'Magnificent,' said the two officials" self.assertEqual(side_effects[1], article.last_edited)
def test_203_sort(self): """Articles should be inherently sortable by their publication date.""" kwargs = {"title": "a", "author": "b", "content": "c"} articles = [ qualifier.Article(**kwargs, publication_date=datetime.datetime(2001, 7, 5)), qualifier.Article(**kwargs, publication_date=datetime.datetime(1837, 4, 7)), qualifier.Article(**kwargs, publication_date=datetime.datetime(2015, 8, 20)), qualifier.Article(**kwargs, publication_date=datetime.datetime(1837, 4, 7)), ] expected = [articles[1], articles[3], articles[0], articles[2]] try: actual = sorted(articles) except TypeError: self.fail("`Article` does not support sorting.") self.assertSequenceEqual(expected, actual)
def setUp(self) -> None: """Create a new Article instance before running each test.""" self.title = "The emperor's new clothes" self.author = "Hans Christian Andersen" self.content = "'But he has nothing at all on!' at last cried out all the people." self.publication_date = datetime.datetime(1837, 4, 7, 12, 15, 0) self.article = qualifier.Article( title=self.title, author=self.author, content=self.content, publication_date=self.publication_date)
def setUp(self) -> None: """Create a new Article instance before running each test.""" self.title = "Rapunzel" self.author = "The Brothers Grimm" self.content = "There were once a man and a woman who had long in vain wished for a child." self.publication_date = datetime.datetime(1812, 12, 20, 11, 11, 9) self.article = qualifier.Article( title=self.title, author=self.author, content=self.content, publication_date=self.publication_date)
def test_201_unique_id(self): """New Articles should be assigned a unique, sequential ID starting at 0.""" importlib.reload(qualifier) articles = [] for _ in range(5): article = qualifier.Article( title="a", author="b", content="c", publication_date=mock.Mock(datetime.datetime) ) articles.append(article) # Assert in a separate loop to ensure that new articles didn't affect previous IDs. for expected_id, article in enumerate(articles): self.assertTrue(hasattr(article, "id"), msg="`Article` object has no `id` attribute") self.assertEqual(expected_id, article.id)
def test_214_last_edited_should_be_unique_for_each_article( self, local_datetime): """Each Article instance should have its own `last_edited` field.""" article_one = qualifier.Article(title="one", author="een", content="en", publication_date=mock.Mock( datetime.datetime)) article_two = qualifier.Article(title="two", author="twee", content="to", publication_date=mock.Mock( datetime.datetime)) self.assertTrue(hasattr(article_one, "last_edited"), msg="`Article` object has no `last_edited` attribute") self.assertIsNone(article_one.last_edited, "Initial value of last_edited should be None") self.assertIsNone(article_two.last_edited, "Initial value of last_edited should be None") # Set twice to account for both "import datetime" and "from datetime import datetime" side_effects = ( datetime.datetime(2019, 2, 1, 12, 1, 12), datetime.datetime(2019, 2, 2, 3, 2, 5), ) local_datetime.now.side_effect = side_effects local_datetime.datetime.now.side_effect = side_effects article_one.content = "one one" self.assertEqual(article_one.last_edited, side_effects[0]) self.assertIsNone(article_two.last_edited, "last_edited for article_two should still be None") article_two.content = "two two" self.assertEqual(article_one.last_edited, side_effects[0]) self.assertEqual(article_two.last_edited, side_effects[1])
def test_211_id_should_set_on_creation_not_access(self): """IDs should be assigned when the Article is instantiated.""" importlib.reload(qualifier) articles = [] for _ in range(5): article = qualifier.Article(title="a", author="b", content="c", publication_date=mock.Mock( datetime.datetime)) articles.append(article) # Check articles in reverse creation order for expected_id, article in reversed(tuple(enumerate(articles))): self.assertTrue(hasattr(article, "id"), msg="`Article` object has no `id` attribute") self.assertEqual(expected_id, article.id)
def test_213_last_edited_should_not_change_when_updating_other_attributes( self, local_datetime): """last_edited attribute should not change after another attribute gets updated.""" article = qualifier.Article(title="x", author="y", content="z", publication_date=mock.Mock( datetime.datetime)) self.assertTrue(hasattr(article, "last_edited"), msg="`Article` object has no `last_edited` attribute") self.assertIsNone(article.last_edited, "Initial value of last_edited should be None") # Set twice to account for both "import datetime" and "from datetime import datetime" side_effects = ( datetime.datetime(2019, 1, 1, 12, 1, 12), datetime.datetime(2019, 1, 2, 3, 2, 5), datetime.datetime(2019, 1, 3, 3, 2, 5), datetime.datetime(2019, 1, 4, 3, 2, 5), ) local_datetime.now.side_effect = side_effects local_datetime.datetime.now.side_effect = side_effects article.content = "You know what's odd? A flying elephant, that's odd!" self.assertEqual(side_effects[0], article.last_edited) # We need to make sure to set correct types to account for solutions # that use the ArticleField descriptor. new_values = (("title", "Dumbo"), ("author", "The White Elephant"), ("publication_date", mock.Mock(datetime.datetime))) for attribute, new_value in new_values: try: setattr(article, attribute, new_value) except AttributeError: # We did not explicitly state that the attributes have to be # mutable, so I guess making them immutable is another way to # make sure that `last_edited` only changes when `content` is # changed. continue else: self.assertEqual(side_effects[0], article.last_edited)