From fc6a94d840903d738f1d4ef815c6a94e7c07d44b Mon Sep 17 00:00:00 2001 From: Erkan Ozgur Yilmaz Date: Sun, 15 Feb 2015 02:24:08 +0200 Subject: [PATCH] 0.2.13.2 ======== * **New:** Removed ``msrp``, ``cost`` and ``unit`` arguments from ``BudgetEntry.__init__()`` and added a new ``good`` argument to get all of the data from the related ``Good`` instance. But the ``msrp``, ``cost`` and ``unit`` attributes of ``BudgetEntry`` class are still there to store the values that may not correlate with the related ``Good`` in future. --- CHANGELOG | 9 + stalker/__init__.py | 2 +- stalker/models/budget.py | 62 ++++-- tests/db/test_db.py | 12 +- tests/models/test_budget.py | 421 +++++++++++++++++++++++------------- 5 files changed, 326 insertions(+), 180 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ed09f92..0232fd6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,15 @@ Stalker Changes =============== +0.2.13.2 +======== + +* **New:** Removed ``msrp``, ``cost`` and ``unit`` arguments from + ``BudgetEntry.__init__()`` and added a new ``good`` argument to get all of + the data from the related ``Good`` instance. But the ``msrp``, ``cost`` and + ``unit`` attributes of ``BudgetEntry`` class are still there to store the + values that may not correlate with the related ``Good`` in future. + 0.2.13.1 ======== diff --git a/stalker/__init__.py b/stalker/__init__.py index 583d1f2..b48cffd 100644 --- a/stalker/__init__.py +++ b/stalker/__init__.py @@ -23,7 +23,7 @@ See docs for more information. """ -__version__ = '0.2.13.1' +__version__ = '0.2.13.2' import sys diff --git a/stalker/models/budget.py b/stalker/models/budget.py index 2974e63..96f836f 100644 --- a/stalker/models/budget.py +++ b/stalker/models/budget.py @@ -252,15 +252,17 @@ def _validate_entry(self, key, entry): class BudgetEntry(Entity): - """Manages budget entries in a budget + """Manages entries in a Budget. - With budget entries one can manage project budget costs. Each entry shows - one component of a bigger budget. + With BudgetEntries one can manage project budget entries one by one. Each + entry shows one component of a bigger budget. Entries are generally a + reflection of a :class:`.Good` instance and shows how many of that Good has + been included in this Budget, and what was the discounted price of that + Good. - :param float cost: This should be the direct copy of the Good.cost that - this item is related to. - :param float msrp: Again this should be the direct copy of the Good.msrp - that this item is related to. + :param budget: The :class:`.Budget` that this entry is a part of. + :param good: Stores a :class:`.Good` instance to carry all the + cost/msrp/unit data from. :param float price: The decided price of this entry. This is generally bigger than the cost and should be also bigger than msrp but the person that is editing the the budget which this entry is related to can decide @@ -270,9 +272,6 @@ class BudgetEntry(Entity): price of this entry. It can be the same number of the :attr:`.price` multiplied by the :attr:`.amount` or can be something else that reflects the reality. Generally it is for calculating the "service" cost/profit. - :param str unit: The unit of this budget entry. Nothing so important for - now. Just a text like "$/hour". Stalker doesn't do any unit conversions - for now. :param float amount: Defines the amount of :class:`Good` that is in consideration for this entry. """ @@ -289,7 +288,6 @@ class BudgetEntry(Entity): ) budget_id = Column( - 'budget_id', Integer, ForeignKey('Budgets.id') ) @@ -301,6 +299,17 @@ class BudgetEntry(Entity): uselist=False ) + good_id = Column( + Integer, + ForeignKey('Goods.id') + ) + + good = relationship( + 'Good', + primaryjoin='BudgetEntries.c.good_id==Goods.c.id', + uselist=False + ) + cost = Column(Float, default=0.0) msrp = Column(Float, default=0.0) @@ -312,30 +321,23 @@ class BudgetEntry(Entity): def __init__(self, budget=None, - cost=0, - msrp=0, + good=None, price=0, realized_total=0, - unit='', amount=0.0, **kwargs): super(BudgetEntry, self).__init__(**kwargs) self.budget = budget - self.cost = cost - self.msrp = msrp + self.good = good + self.cost = good.cost + self.msrp = good.msrp + self.unit = good.unit self.price = price self.realized_total = realized_total self.amount = amount - self.unit = unit - - @property - def total(self): - """returns the total cost of this entry - """ - return self.amount * self.cost @validates('budget') def _validate_budget(self, key, budget): @@ -446,3 +448,17 @@ def _validate_amount(self, key, amount): ) return float(amount) + + @validates('good') + def _validate_good(self, key, good): + """validates the given good value + """ + if not isinstance(good, Good): + raise TypeError( + '%s.good should be a stalker.models.budget.Good instance, ' + 'not %s' % ( + self.__class__.__name__, good.__class__.__name__ + ) + ) + + return good diff --git a/tests/db/test_db.py b/tests/db/test_db.py index 3984b44..bf5eedf 100644 --- a/tests/db/test_db.py +++ b/tests/db/test_db.py @@ -1247,9 +1247,13 @@ def test_persistence_of_Budget_and_BudgetEntry(self): DBSession.add(test_budget) DBSession.commit() + good = Good(name='Some Good', cost=9, msrp=10, unit='$/hour') + DBSession.add(good) + DBSession.commit() + # create some entries - entry1 = BudgetEntry(budget=test_budget, amount=5.0) - entry2 = BudgetEntry(budget=test_budget, amount=1.0) + entry1 = BudgetEntry(budget=test_budget, good=good, amount=5.0) + entry2 = BudgetEntry(budget=test_budget, good=good, amount=1.0) DBSession.add_all([entry1, entry2]) DBSession.commit() @@ -1313,6 +1317,10 @@ def test_persistence_of_Budget_and_BudgetEntry(self): BudgetEntry.query.all() == [] ) + # we still should have the good + good_db = Good.query.filter(Good.name == 'Some Good').first() + self.assertTrue(good_db is not None) + def test_persistence_of_Page(self): """testing the persistence of Page """ diff --git a/tests/models/test_budget.py b/tests/models/test_budget.py index 73dd348..2ca0b24 100644 --- a/tests/models/test_budget.py +++ b/tests/models/test_budget.py @@ -21,7 +21,7 @@ import unittest import datetime from stalker import (db, defaults, Project, Status, StatusList, Type, - Repository, User, Budget, BudgetEntry) + Repository, User, Budget, BudgetEntry, Good) class BudgetTestBase(unittest.TestCase): @@ -131,8 +131,15 @@ def setUp(self): self.test_budget = Budget(**self.kwargs) + self.test_good = Good( + name='Some Good', + cost=100, + msrp=120, + unit='$' + ) + -class BudgetTest(BudgetTestBase): +class BudgetTestCase(BudgetTestBase): """tests the stalker.models.budget.Budget class """ @@ -156,8 +163,14 @@ def test_entries_attribute_is_working_properly(self): name='Test Budget', project=self.test_project ) - entry1 = BudgetEntry(budget=some_other_budget) - entry2 = BudgetEntry(budget=some_other_budget) + entry1 = BudgetEntry( + budget=some_other_budget, + good=self.test_good, + ) + entry2 = BudgetEntry( + budget=some_other_budget, + good=self.test_good, + ) self.test_budget.entries = [entry1, entry2] @@ -200,7 +213,8 @@ def test_budget_attribute_is_set_to_none(self): set to None """ entry = BudgetEntry( - budget=self.test_budget + budget=self.test_budget, + good=self.test_good, ) with self.assertRaises(TypeError) as cm: entry.budget = None @@ -229,7 +243,11 @@ def test_budget_attribute_is_not_a_budget_instance(self): """testing if a TypeError will be raised if the budget attribute is not set to a something that is a Budget instance """ - entry = BudgetEntry(budget=self.test_budget, amount=10.0) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + amount=10.0 + ) with self.assertRaises(TypeError) as cm: entry.budget = 'not a budget instance' @@ -244,6 +262,7 @@ def test_budget_argument_is_working_properly(self): """ entry = BudgetEntry( budget=self.test_budget, + good=self.test_good, amount=10.0 ) self.assertEqual(entry.budget, self.test_budget) @@ -253,6 +272,7 @@ def test_budget_attribute_is_working_properly(self): """ entry = BudgetEntry( budget=self.test_budget, + good=self.test_good, amount=10.0 ) new_budget = Budget(name='Test Budget', project=self.test_project) @@ -260,45 +280,33 @@ def test_budget_attribute_is_working_properly(self): entry.budget = new_budget self.assertEqual(entry.budget, new_budget) - def test_cost_argument_is_skipped(self): - """testing if the cost attribute will be 0 if the cost argument is - skipped - """ - entry = BudgetEntry(budget=self.test_budget) - self.assertEqual(entry.cost, 0.0) - - def test_cost_argument_is_set_to_None(self): - """testing if the cost attribute will be set to 0 if the cost argument - is set to None + def test_cost_attribute_value_will_be_copied_from_the_supplied_good_argument(self): + """testing if the cost attribute value will be copied from the supplied + good argument value """ - entry = BudgetEntry(budget=self.test_budget, cost=None) - self.assertEqual(entry.cost, 0.0) + good = Good(name='Some Good', cost=10, msrp=20, unit='$/hour') + entry = BudgetEntry(budget=self.test_budget, good=good) + self.assertEqual(entry.cost, good.cost) def test_cost_attribute_is_set_to_None(self): """testing if the cost attribute will be set to 0 if it is set to None """ - entry = BudgetEntry(budget=self.test_budget, cost=10.0) - self.assertEqual(entry.cost, 10.0) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + ) + self.assertEqual(entry.cost, self.test_good.cost) entry.cost = None self.assertEqual(entry.cost, 0.0) - def test_cost_argument_is_not_a_number(self): - """testing if a TypeError will be raised if the cost argument is set to - something other than a number - """ - with self.assertRaises(TypeError) as cm: - BudgetEntry(budget=self.test_budget, cost='some string') - - self.assertEqual( - str(cm.exception), - 'BudgetEntry.cost should be a number, not str' - ) - def test_cost_attribute_is_not_a_number(self): """testing if a TypeError will be raised if cost attribute is set to something other than a number """ - entry = BudgetEntry(budget=self.test_budget, cost=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + ) with self.assertRaises(TypeError) as cm: entry.cost = 'some string' @@ -307,62 +315,38 @@ def test_cost_attribute_is_not_a_number(self): 'BudgetEntry.cost should be a number, not str' ) - def test_cost_argument_is_working_properly(self): - """testing if the cost argument value is correctly passed to the cost - attribute - """ - entry = BudgetEntry(budget=self.test_budget, cost=10) - self.assertEqual(entry.cost, 10.0) - def test_cost_attribute_is_working_properly(self): """testing if the cost attribute is working properly """ - entry = BudgetEntry(budget=self.test_budget, cost=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + ) test_value = 5.0 self.assertNotEqual(entry.cost, test_value) entry.cost = test_value self.assertEqual(entry.cost, test_value) - def test_msrp_argument_is_skipped(self): - """testing if the msrp attribute will be 0 if the msrp argument is - skipped - """ - entry = BudgetEntry(budget=self.test_budget) - self.assertEqual(entry.msrp, 0.0) - - def test_msrp_argument_is_set_to_None(self): - """testing if the msrp attribute will be set to 0 if the msrp argument - is set to None - """ - entry = BudgetEntry(budget=self.test_budget, msrp=None) - self.assertEqual(entry.msrp, 0.0) - def test_msrp_attribute_is_set_to_None(self): """testing if the msrp attribute will be set to 0 if msrp attribute is set to None """ - entry = BudgetEntry(budget=self.test_budget, msrp=10.0) - self.assertEqual(entry.msrp, 10.0) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + ) + self.assertEqual(entry.msrp, self.test_good.msrp) entry.msrp = None self.assertEqual(entry.msrp, 0.0) - def test_msrp_argument_is_not_a_number(self): - """testing if a TypeError will be raised if the msrp argument is set to - something other than a number - """ - with self.assertRaises(TypeError) as cm: - BudgetEntry(budget=self.test_budget, msrp='some string') - - self.assertEqual( - str(cm.exception), - 'BudgetEntry.msrp should be a number, not str' - ) - def test_msrp_attribute_is_not_a_number(self): """testing if a TypeError will be raised if msrp attribute is set to something other than a number """ - entry = BudgetEntry(budget=self.test_budget, msrp=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + ) with self.assertRaises(TypeError) as cm: entry.msrp = 'some string' @@ -371,44 +355,55 @@ def test_msrp_attribute_is_not_a_number(self): 'BudgetEntry.msrp should be a number, not str' ) - def test_msrp_argument_is_working_properly(self): - """testing if the msrp argument value is correctly passed to the msrp - attribute - """ - entry = BudgetEntry(budget=self.test_budget, msrp=10) - self.assertEqual(entry.msrp, 10.0) - def test_msrp_attribute_is_working_properly(self): """testing if the msrp attribute is working properly """ - entry = BudgetEntry(budget=self.test_budget, msrp=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + ) test_value = 5.0 self.assertNotEqual(entry.msrp, test_value) entry.msrp = test_value self.assertEqual(entry.msrp, test_value) - - + def test_msrp_attribute_value_will_be_copied_from_the_supplied_good_argument(self): + """testing if the msrp attribute value will be copied from the supplied + good argument value + """ + entry = BudgetEntry(budget=self.test_budget, good=self.test_good) + self.assertEqual(entry.msrp, self.test_good.msrp) def test_price_argument_is_skipped(self): """testing if the price attribute will be 0 if the price argument is skipped """ - entry = BudgetEntry(budget=self.test_budget) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + ) self.assertEqual(entry.price, 0.0) def test_price_argument_is_set_to_None(self): """testing if the price attribute will be set to 0 if the price argument is set to None """ - entry = BudgetEntry(budget=self.test_budget, price=None) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + price=None + ) self.assertEqual(entry.price, 0.0) def test_price_attribute_is_set_to_None(self): """testing if the price attribute will be set to 0 if price attribute is set to None """ - entry = BudgetEntry(budget=self.test_budget, price=10.0) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + price=10.0 + ) self.assertEqual(entry.price, 10.0) entry.price = None self.assertEqual(entry.price, 0.0) @@ -418,7 +413,11 @@ def test_price_argument_is_not_a_number(self): to something other than a number """ with self.assertRaises(TypeError) as cm: - BudgetEntry(budget=self.test_budget, price='some string') + BudgetEntry( + budget=self.test_budget, + good=self.test_good, + price='some string' + ) self.assertEqual( str(cm.exception), @@ -429,7 +428,11 @@ def test_price_attribute_is_not_a_number(self): """testing if a TypeError will be raised if price attribute is set to something other than a number """ - entry = BudgetEntry(budget=self.test_budget, price=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + price=10 + ) with self.assertRaises(TypeError) as cm: entry.price = 'some string' @@ -442,13 +445,21 @@ def test_price_argument_is_working_properly(self): """testing if the price argument value is correctly passed to the price attribute """ - entry = BudgetEntry(budget=self.test_budget, price=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + price=10 + ) self.assertEqual(entry.price, 10.0) def test_price_attribute_is_working_properly(self): """testing if the price attribute is working properly """ - entry = BudgetEntry(budget=self.test_budget, price=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + price=10 + ) test_value = 5.0 self.assertNotEqual(entry.price, test_value) entry.price = test_value @@ -458,21 +469,32 @@ def test_realized_total_argument_is_skipped(self): """testing if the realized_total attribute will be 0 if the realized_total argument is skipped """ - entry = BudgetEntry(budget=self.test_budget) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good + ) self.assertEqual(entry.realized_total, 0.0) def test_realized_total_argument_is_set_to_None(self): """testing if the realized_total attribute will be set to 0 if the realized_total argument is set to None """ - entry = BudgetEntry(budget=self.test_budget, realized_total=None) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + realized_total=None + ) self.assertEqual(entry.realized_total, 0.0) def test_realized_total_attribute_is_set_to_None(self): """testing if the realized_total attribute will be set to 0 if it is set to None """ - entry = BudgetEntry(budget=self.test_budget, realized_total=10.0) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + realized_total=10.0 + ) self.assertEqual(entry.realized_total, 10.0) entry.realized_total = None self.assertEqual(entry.realized_total, 0.0) @@ -482,7 +504,11 @@ def test_realized_total_argument_is_not_a_number(self): is set to something other than a number """ with self.assertRaises(TypeError) as cm: - BudgetEntry(budget=self.test_budget, realized_total='some string') + BudgetEntry( + budget=self.test_budget, + good=self.test_good, + realized_total='some string' + ) self.assertEqual( str(cm.exception), @@ -493,7 +519,11 @@ def test_realized_total_attribute_is_not_a_number(self): """testing if a TypeError will be raised if realized_total attribute is set to something other than a number """ - entry = BudgetEntry(budget=self.test_budget, realized_total=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + realized_total=10 + ) with self.assertRaises(TypeError) as cm: entry.realized_total = 'some string' @@ -506,58 +536,40 @@ def test_realized_total_argument_is_working_properly(self): """testing if the realized_total argument value is correctly passed to the realized_total attribute """ - entry = BudgetEntry(budget=self.test_budget, realized_total=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + realized_total=10 + ) self.assertEqual(entry.realized_total, 10.0) def test_realized_total_attribute_is_working_properly(self): """testing if the realized_total attribute is working properly """ - entry = BudgetEntry(budget=self.test_budget, realized_total=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + realized_total=10 + ) test_value = 5.0 self.assertNotEqual(entry.realized_total, test_value) entry.realized_total = test_value self.assertEqual(entry.realized_total, test_value) - def test_unit_argument_is_skipped(self): - """testing if the unit attribute will be an empty string if the unit - argument is skipped - """ - entry = BudgetEntry(budget=self.test_budget) - self.assertEqual(entry.unit, '') - - def test_unit_argument_is_set_to_None(self): - """testing if the unit attribute will be set to an empty string if the - unit argument is set to None - """ - entry = BudgetEntry(budget=self.test_budget, unit=None) - self.assertEqual(entry.unit, '') - def test_unit_attribute_is_set_to_None(self): """testing if the unit attribute will be set to an empty if it is set to None """ - entry = BudgetEntry(budget=self.test_budget, unit='$/hour') - self.assertEqual(entry.unit, '$/hour') + entry = BudgetEntry(budget=self.test_budget, good=self.test_good) + self.assertEqual(entry.unit, self.test_good.unit) entry.unit = None self.assertEqual(entry.unit, '') - def test_unit_argument_is_not_a_string(self): - """testing if a TypeError will be raised if the unit argument is set to - something other than a string - """ - with self.assertRaises(TypeError) as cm: - BudgetEntry(budget=self.test_budget, unit=10.0) - - self.assertEqual( - str(cm.exception), - 'BudgetEntry.unit should be a string, not float' - ) - def test_unit_attribute_is_not_a_string(self): """testing if a TypeError will be raised if the unit attribute is set to something other than a string """ - entry = BudgetEntry(budget=self.test_budget, unit='$/hour') + entry = BudgetEntry(budget=self.test_budget, good=self.test_good) with self.assertRaises(TypeError) as cm: entry.unit = 100.212 @@ -566,41 +578,52 @@ def test_unit_attribute_is_not_a_string(self): 'BudgetEntry.unit should be a string, not float' ) - def test_unit_argument_is_working_properly(self): - """testing if the unit argument value is correctly passed to the unit - attribute - """ - entry = BudgetEntry(budget=self.test_budget, unit='$/hour') - self.assertEqual(entry.unit, '$/hour') - def test_unit_attribute_is_working_properly(self): """testing if the unit attribute is working properly """ - entry = BudgetEntry(budget=self.test_budget, unit='$/hour') + entry = BudgetEntry(budget=self.test_budget, good=self.test_good) test_value = 'TL/hour' self.assertNotEqual(entry.unit, test_value) entry.unit = test_value self.assertEqual(entry.unit, test_value) + def test_unit_attribute_value_will_be_copied_from_the_supplied_good(self): + """testing if the unit attribute value will be copied from the good + argument value + """ + entry = BudgetEntry(budget=self.test_budget, good=self.test_good,) + self.assertEqual(entry.unit, self.test_good.unit) + def test_amount_argument_is_skipped(self): """testing if the amount attribute will be 0 if the amount argument is skipped """ - entry = BudgetEntry(budget=self.test_budget) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good + ) self.assertEqual(entry.amount, 0.0) def test_amount_argument_is_set_to_None(self): """testing if the amount attribute will be set to 0 if the amount argument is set to None """ - entry = BudgetEntry(budget=self.test_budget, amount=None) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + amount=None + ) self.assertEqual(entry.amount, 0.0) def test_amount_attribute_is_set_to_None(self): """testing if the amount attribute will be set to 0 if it is set to None """ - entry = BudgetEntry(budget=self.test_budget, amount=10.0) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + amount=10.0 + ) self.assertEqual(entry.amount, 10.0) entry.amount = None self.assertEqual(entry.amount, 0.0) @@ -610,7 +633,11 @@ def test_amount_argument_is_not_a_number(self): to something other than a number """ with self.assertRaises(TypeError) as cm: - BudgetEntry(budget=self.test_budget, amount='some string') + BudgetEntry( + budget=self.test_budget, + good=self.test_good, + amount='some string' + ) self.assertEqual( str(cm.exception), @@ -621,7 +648,11 @@ def test_amount_attribute_is_not_a_number(self): """testing if a TypeError will be raised if amount attribute is set to something other than a number """ - entry = BudgetEntry(budget=self.test_budget, amount=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + amount=10 + ) with self.assertRaises(TypeError) as cm: entry.amount = 'some string' @@ -634,51 +665,133 @@ def test_amount_argument_is_working_properly(self): """testing if the amount argument value is correctly passed to the amount attribute """ - entry = BudgetEntry(budget=self.test_budget, amount=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + amount=10 + ) self.assertEqual(entry.amount, 10.0) def test_amount_attribute_is_working_properly(self): """testing if the amount attribute is working properly """ - entry = BudgetEntry(budget=self.test_budget, amount=10) + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + amount=10 + ) test_value = 5.0 self.assertNotEqual(entry.amount, test_value) entry.amount = test_value self.assertEqual(entry.amount, test_value) - def test_total_property_is_read_only(self): - """testing if the total property is a read-only property + def test_good_argument_is_skipped(self): + """testing if a TypeError will be raised when the good argument is + skipped + """ + with self.assertRaises(TypeError) as cm: + entry = BudgetEntry( + budget=self.test_budget, + ) + self.assertEqual( + str(cm.exception), + 'BudgetEntry.good should be a stalker.models.budget.Good instance,' + ' not NoneType' + ) + + def test_good_argument_is_None(self): + """testing if a TypeError will be raised when the good argument is None + """ + with self.assertRaises(TypeError) as cm: + entry = BudgetEntry( + budget=self.test_budget, + good=None, + amount=53, + ) + + self.assertEqual( + str(cm.exception), + 'BudgetEntry.good should be a stalker.models.budget.Good instance,' + ' not NoneType' + ) + + def test_good_attribute_is_set_to_None(self): + """testing if a TypeError will be raised if the good attribute is set + to None """ entry = BudgetEntry( budget=self.test_budget, - cost=100.0, - unit='$/hour', + good=Good(name='Some Good'), amount=53 ) + with self.assertRaises(TypeError) as cm: + entry.good = None - with self.assertRaises(AttributeError) as cm: - # use setattr to prevent the IDE to highlight - # this line as a weak warning - setattr(entry, 'total', 10002) + self.assertEqual( + str(cm.exception), + 'BudgetEntry.good should be a stalker.models.budget.Good instance,' + ' not NoneType' + ) + + def test_good_argument_is_not_a_good_instance(self): + """testing if a TypeError will be raised when the good argument is not + a Good instance + """ + with self.assertRaises(TypeError) as cm: + entry = BudgetEntry( + budget=self.test_budget, + good='this is not a Good instance', + amount=53, + ) self.assertEqual( str(cm.exception), - "can't set attribute" + 'BudgetEntry.good should be a stalker.models.budget.Good instance, ' + 'not str' ) - def test_total_property_is_working_properly(self): - """testing if the total property is working properly + def test_good_attribute_is_not_a_good_instance(self): + """testing if a TypeError will be raised when the good attribute is set + to a value other than a Good instance """ entry = BudgetEntry( budget=self.test_budget, - cost=100.0, - unit='$/hour', - amount=53 + good=self.test_good, + amount=53, ) + with self.assertRaises(TypeError) as cm: + entry.good = 'this is not a Good instance' + self.assertEqual( - entry.total, - 5300.0 + str(cm.exception), + 'BudgetEntry.good should be a stalker.models.budget.Good instance, ' + 'not str' + ) + + def test_good_argument_is_working_properly(self): + """testing if the good argument value is correctly passed to the good + attribute + """ + test_value = Good(name='Some Good') + entry = BudgetEntry( + budget=self.test_budget, + good=test_value, + amount=53, + ) + self.assertEqual(entry.good, test_value) + + def test_good_attribute_is_working_properly(self): + """testing if the good attribute can be correctly set + """ + test_value = Good(name='Some Other Good') + entry = BudgetEntry( + budget=self.test_budget, + good=self.test_good, + amount=53 ) + self.assertNotEqual(entry.good, test_value) + entry.good = test_value + self.assertEqual(entry.good, test_value) class BudgetDAGMixinTestCase(BudgetTestBase):