oship-dev team mailing list archive
-
oship-dev team
-
Mailing list archive
-
Message #01494
[Branch ~oship-dev/oship/devel] Rev 488: Fixed bug #610972 .
Merge authors:
Diego Manhães Pinheiro (dmpinheiro)
------------------------------------------------------------
revno: 488 [merge]
fixes bug(s): https://launchpad.net/bugs/610972
committer: Diego Manhães Pinheiro <dmpinheiro@xxxxxxxxx>
branch nick: trunk
timestamp: Thu 2010-09-16 17:25:44 -0300
message:
Fixed bug #610972 .
added:
src/oship/openehr/rm/datatypes/quantity/tests/dvamount.txt
modified:
src/oship/openehr/rm/datatypes/quantity/__init__.py
src/oship/openehr/rm/datatypes/quantity/interfaces.py
src/oship/openehr/rm/datatypes/quantity/tests/dvquantified.py
--
lp:oship
https://code.launchpad.net/~oship-dev/oship/devel
Your team OSHIP Development Team is subscribed to branch lp:oship.
To unsubscribe from this branch go to https://code.launchpad.net/~oship-dev/oship/devel/+edit-subscription
=== modified file 'src/oship/openehr/rm/datatypes/quantity/__init__.py'
--- src/oship/openehr/rm/datatypes/quantity/__init__.py 2010-09-07 21:28:23 +0000
+++ src/oship/openehr/rm/datatypes/quantity/__init__.py 2010-09-16 20:21:31 +0000
@@ -1,5 +1,7 @@
# -*- coding: UTF-8 -*-
+
+import copy
from zope.schema.fieldproperty import FieldProperty
import grok
@@ -7,7 +9,6 @@
from oship.openehr.rm.datatypes.text import DvCodedText, DvText
from oship.openehr.rm.support import Interval
-
from interfaces import *
@@ -17,8 +18,6 @@
class DvOrdered(DataValue):
-
-
grok.implements(IDvOrdered)
normal_range = FieldProperty(IDvOrdered['normal_range'])
@@ -120,88 +119,97 @@
class DvQuantified(DvOrdered):
- """
- Abstract class defining the concept of true quantified values, i.e. values which are
- not only ordered, but which have a precise magnitude.
- """
-
grok.implements(IDvQuantified)
- def __init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus, magnitudeStatus=None):
+
+
+
+ def __init__(self, magnitude, accuracy=None, normal_range=None, other_reference_ranges=None, normal_status=None, magnitude_status=None):
self.magnitude=magnitude
self.accuracy=accuracy
- if magnitudeStatus is not None:
- if self.validMagnitudeStatus(magnitudeStatus):
- self.magnitudeStatus = magnitudeStatus
+ if magnitude_status is not None:
+ if self.valid_magnitude_status(magnitude_status):
+ self.magnitude_status = magnitude_status
else:
- raise ValueError(u"magnitudeStatus must be '=', '>', '<', '<=', '>=', '~' or None")
+ raise ValueError(u"magnitude status must be '=', '>', '<', '<=', '>=', '~' or None")
else:
- self.magnitudeStatus = None
- DvOrdered.__init__(self,normalRange,otherReferenceRanges,normalStatus)
+ self.magnitude_status = None
+ super(DvQuantified,self).__init__(normal_range, other_reference_ranges, normal_status)
- def validMagnitudeStatus(self,val):
- """
- Test whether a string 'val' is one of the valid values for the magnitude_status attribute.
- """
+ def valid_magnitude_status(self,val):
return val in ['=','>','<','<=','>=','~']
+ def accuracy_unknown(self):
+ raise NotImplementedError("This method must be implemented on the class.")
+
class DvAbsoluteQuantity(DvQuantified):
- """
- Abstract class defining the concept of quantified entities whose values are abso-
- lute with respect to an origin. Dates and Times are the main example.
- """
-
grok.implements(IDvAbsoluteQuantity)
- def __init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus,magnitudeStatus=None):
+ def __init__(self,magnitude,accuracy=None,normal_range=None,other_reference_ranges=None,normal_status=None,magnitude_status=None):
self.accuracy = accuracy
- DvQuantified.__init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus,magnitudeStatus)
-
-
- def accuracyUnknown(self):
- """ True if accuracy is None """
+ super(DvAbsoluteQuantity,self).__init__(magnitude,accuracy,normal_range,other_reference_ranges,normal_status,magnitude_status)
+
+ def accuracy_unknown(self):
return self.accuracy is None
class DvAmount(DvQuantified):
- u"""
- Abstract class defining the concept of relative quantified 'amounts'. For relative
- quantities, the '+' and '-' operators are defined (unlike descendants of
- DV_ABSOLUTE_QUANTITY, such as the date/time types).
- """
+ UNKNOWN_ACCURACY_VALUE = -1.0
grok.implements(IDvAmount)
- def __init__(self,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus):
- if accuracy is None:
- self.accuracy = -1
- else:
- self.accuracy = accuracy
- self.accuracyIsPercent = accuracyIsPercent
- DvQuantified.__init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus)
-
- # constant
- self.unknownAccuracyValue = -1.0
-
- def validPercentage(val):
- u"""
- Test whether a number is a valid percentage,i.e. between 0 and 100.
- ensure
- Result implies val >= 0.0 and val <= 100.0
- """
-
+ accuracy = FieldProperty(IDvAmount['accuracy'])
+
+ def __init__(self,magnitude,accuracy=UNKNOWN_ACCURACY_VALUE,accuracy_is_percent=False,magnitude_status=u"=",normal_range=None,other_reference_ranges=None,normal_status=None):
+ self.accuracy_is_percent = accuracy_is_percent
+ super(DvAmount,self).__init__(magnitude,accuracy,normal_range,other_reference_ranges,normal_status,magnitude_status)
+
+ def valid_percentage(self,val):
return val >= 0.0 and val <= 100.0
- def accuracyUnknown(self):
- """
- Accuracy wasn't known or wasn't recorded.
- """
- if self.accuracy == -1:
- return True
+ def accuracy_unknown(self):
+ return self.accuracy == self.UNKNOWN_ACCURACY_VALUE
+
+ def __add__(self,other):
+ assert self.is_strictly_comparable_to(other)
+ klass = type(self)
+ return self._do_arithmetic_expression(other,klass,"+")
+
+ def __sub__(self,other):
+ assert self.is_strictly_comparable_to(other)
+ klass = type(self)
+ return self._do_arithmetic_expression(other,klass,"-")
+
+ def __neg__(self):
+ negated_copy = copy.copy(self)
+ negated_copy.magnitude = -self.magnitude
+ return negated_copy
+
+ def _do_arithmetic_expression(self,other,klass,operator):
+ has_ac_unknown = self.accuracy_unknown()
+ other_has_ac_unknown = other.accuracy_unknown()
+ other_has_percent = other.accuracy_is_percent
+ has_percent = self.accuracy_is_percent
+ new_obj_data = {}
+ if has_ac_unknown or other_has_ac_unknown:
+ new_obj_data['accuracy'] = self.UNKNOWN_ACCURACY_VALUE
+ elif has_percent^other_has_percent:
+ chosen_accuracy = max(self.accuracy,other.accuracy)
+ new_obj_data['accuracy_is_percent'] = False
+ if chosen_accuracy == other.accuracy and other.accuracy_is_percent:
+ new_obj_data['accuracy_is_percent'] = True
+ elif chosen_accuracy == self.accuracy and self.accuracy_is_percent:
+ new_obj_data['accuracy_is_percent'] = True
+ new_obj_data['accuracy'] = chosen_accuracy
else:
- return False
+ new_accuracy = eval("float(self.accuracy"+operator+"other.accuracy)")
+ new_obj_data['accuracy'] = new_accuracy
+
+ new_obj_data['magnitude'] = eval("self.magnitude"+ operator + "other.magnitude")
+ obj = klass(**new_obj_data)
+ return obj
class DvCount(DvAmount):
@@ -240,9 +248,6 @@
return DvCount(-self.magnitude, self.accuracy, self.accuracyIsPercent, self.magnitudeStatus, self.normalStatus, self.normalRange, self.otherReferenceRanges)
-
-
-
class DvInterval(DataValue,Interval):
"""
Used to define intervals of dates, times, quantities (whose units match) and so on.
@@ -344,7 +349,6 @@
return self.numerator / self.denominator
-
class DvProportion(DvAmount,ProportionKind):
"""
Models a ratio of values, i.e. where the numerator and denominator are both pure
@@ -401,7 +405,6 @@
return self.numerator / self.denominator
-
class DvQuantity(DvAmount):
"""
Quantitified type representing "scientific" quantities, i.e. quantities expressed as a
@@ -470,3 +473,4 @@
"""
return self.range_.has(val)
+
=== modified file 'src/oship/openehr/rm/datatypes/quantity/interfaces.py'
--- src/oship/openehr/rm/datatypes/quantity/interfaces.py 2010-09-07 19:39:42 +0000
+++ src/oship/openehr/rm/datatypes/quantity/interfaces.py 2010-09-16 20:21:31 +0000
@@ -1,13 +1,14 @@
# -*- coding: UTF-8 -*-
+
from zope.interface import Interface, Attribute, invariant, Invalid
from zope.schema import (Text, Bool, TextLine, Int, Field,
- BytesLine, Float, List, URI, Choice, Object)
+ BytesLine, Float, List, URI, Choice, Object)
from zope.i18nmessageid.message import MessageFactory
from oship.openehr.rm.datatypes.basic.interfaces import IDataValue
from oship.openehr.rm.datatypes.text.interfaces import (IDvText, IDvCodedText,
- ICodePhrase)
+ ICodePhrase)
_ = MessageFactory('oship')
@@ -33,6 +34,7 @@
"""
pass
+
class IReferenceRange(Interface):
"""
Defines a named range to be associated with any ORDERED datum. Each such
@@ -118,7 +120,9 @@
"""
def is_strictly_comparable_to(other):
- pass
+ """
+ Test if two instances are strictly comparable.
+ """
@invariant
def other_reference_ranges_validity(obj):
@@ -148,14 +152,14 @@
pass
-class IDvQuantified(Interface):
+class IDvQuantified(IDvOrdered):
"""
Abstract class defining the concept of true quantified values, i.e. values which are
not only ordered, but which have a precise magnitude.
"""
- magnitude = Float(
- title=_(u"magnitude"),
+ magnitude = Field(
+ title=_(u"Magnitude"),
description=_(u"""Numeric value of the quantity in canonical (i.e. single value)
form. Implemented as constant, function or attribute in subtypes as
appropriate. The type OrdereNumeric is mapped to the available
@@ -163,12 +167,10 @@
required=True
)
- accuracy = Field(
- title = _(u"accuracy"),
- )
+ accuracy = Attribute(_(u"Accuracy"))
- magnitudeStatus = TextLine(
- title=_(u"magnitudeStatus"),
+ magnitude_status = TextLine(
+ title=_(u"Magnitude status"),
description=_(u"""Optional status of magnitude with values:
= : magnitude is a point value
< : value is < magnitude
@@ -181,16 +183,25 @@
)
- def validMagnitudeStatus(val):
+ def valid_magnitude_status(val):
"""
Test whether a string 'val' is one of the valid values for the magnitude_status attribute.
"""
- def accuracyUnknown():
+ def accuracy_unknown():
"""
True if accuracy is not known.
"""
+ @invariant
+ def magnitude_exists(obj):
+ if obj.magnitude is None:
+ raise Invalid("The magnitude attribute cannot be None.")
+ @invariant
+ def valid_status_valid(obj):
+ if obj.magnitude_status is not None:
+ if not obj.valid_magnitude_status(obj.magnitude_status):
+ raise Invalid("The magnitude is not valid.")
class IDvOrdinal(Interface):
"""
@@ -230,52 +241,72 @@
Returns DvOrdinal.
"""
- def isStrictlyComparableTo(other):
- """
- True if symbols come from same vocabulary,assuming the vocabulary is a
- subset or value range, e.g. urine:protein.
-
- (other: like Current): Boolean
- ensure
- symbol.is_comparable (other.symbol) implies Result
- """
-
-
-class IDvAmount(Interface):
- """
- Abstract class defining the concept of relative quantified amounts. For relative
- quantities, the + and - operators are defined (unlike descendants of
- DV_ABSOLUTE_QUANTITY, such as the date/time types).
- """
-
- accuracy = Int(
- title=_(u"accuracy"),
- description=_(u"""Accuracy of measurement, expressed either as a half-range
- percent value (accuracyIsPercent = True) or a half-range
- quantity. A value of 0 means that accuracy was not recorded."""),
- required=False
- )
-
-
- accuracyIsPercent = Bool(
- title=_(u"accuracyIsPercent"),
- description=_(u"""If True, indicates that when this object was created, accuracy was recorded
- as a percent value; if False, as an absolute quantity value."""),
- required=False
- )
-
-
- def validPercentage(val):
- """
- Test whether a number is a valid percentage,i.e. between 0 and 100.
- ensure
- Result implies val >= 0.0 and val <= 100.0
- """
-
+
+class IDvAmount(IDvQuantified):
+ """
+ Abstract interface defining the concept of relative quantified amounts.
+ For relative quantities, the + and - operators are defined (unlike
+ descendants of IDvAbsoluteQuantity, such as the date/time types).
+ """
+
+ UNKNOWN_ACCURACY_VALUE = Attribute(("Special value for accuracy "
+ "indicating no accuracy recorded."))
+
+ accuracy = Float(
+ title=_(u"Accuracy"),
+ description=_((u"Accuracy of measurement, expressed either as a "
+ "half-range percent value or a half-range quantity.")),
+ required=False
+ )
+
+ accuracy_is_percent = Bool(
+ title=_(u"Percent"),
+ description=_((u"Indicates that accuracy was recorded "
+ "as a percent value or as an absolute "
+ "quantity value.")),
+ required=False
+ )
+
+ def valid_percentage(val):
+ """
+ Test whether a number is a valid percentage, i.e. between 0 and 100.
+ """
+
+ def __neg__():
+ """
+ Negated version of current object, such as
+ used for representing a difference.
+ """
+
+ def __add__(other):
+ """
+ Sum of this quantity and another quantity of
+ the same concrete type.
+ """
+
+ def __sub__(other):
+ """
+ Difference of this quantity and another quantity
+ of the same concrete type.
+ """
+
+ @invariant
+ def accuracy_is_percent_validity(obj):
+ if obj.accuracy == 0:
+ if obj.accuracy_is_percent:
+ raise Invalid("The percentage accuracy cannot be zero.")
+
+ @invariant
+ def accuracy_validity(obj):
+ if obj.accuracy_is_percent:
+ if not obj.valid_percentage(obj.accuracy):
+ raise Invalid("The percentage accuracy is not valid.")
+
class IDvAbsoluteQuantity(Interface):
"""
- Abstract class defining the concept of quantified entities whose values are absolute with respect to an origin. Dates and Times are the main example.
+ Abstract class defining the concept of quantified entities whose values are
+ absolute with respect to an origin. Dates and Times are the main example.
"""
accuracy = Field(
@@ -342,6 +373,7 @@
True if n is one of the defined types.
"""
+
class IDvProportion(Interface):
"""
Models a ratio of values, i.e. where the numerator and denominator are both pure
=== added file 'src/oship/openehr/rm/datatypes/quantity/tests/dvamount.txt'
--- src/oship/openehr/rm/datatypes/quantity/tests/dvamount.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/tests/dvamount.txt 2010-09-16 20:21:31 +0000
@@ -0,0 +1,183 @@
+Defining quantity amounts with DvAmount
+=======================================
+
+:Test-Layer: unit
+
+
+An `DvAmount` class represents relative quantified 'amounts'. The amount here
+means amounts about something, which allows defines either a physical property,
+such as a mass, or items in general(cigarettes, for example). The arithmetic
+operators(+, - , * and /) and any other in the mathematical field act here as a
+true numbers. In case two relative quantities are evaluated using these
+operators and they have the same measured property, it should create other relative
+quantity of the same type. If was executed a subtraction as an arithmetic operation,
+the scenario happens in the same way : another object is created.
+The only mandatory attributes to create a `DvAmount` is the magnitude attribute,
+which is the number that corresponds how amount will be represented. The
+optional attributes are the magnitude_status and accuracy following the
+`IDvQuantified` interface and normal_range, other_reference_ranges and
+normal_status attributes specified by `IDvOrdered` interface. In order to
+exercise it's operations which are defined on the abstract class, concrete
+classes must be defined. The DvAmount is a abstract class, which means that
+object cannot be a direct instance of it. All antecessors parameters
+and behaviors still valid::
+
+ >>> import grok
+ >>> from oship.openehr.rm.datatypes.quantity import DvAmount
+ >>> from oship.openehr.rm.datatypes.quantity.interfaces import IDvAmount
+ >>> class Amount(DvAmount):
+ ... def is_strictly_comparable_to(self,other):
+ ... if other.__class__ == self.__class__:
+ ... return True
+ ... return False
+ ... def __lt__(self,other):
+ ... assert self.is_strictly_comparable_to(other)
+ ... return self.magnitude < other.magnitude
+ >>> class AnotherAmount(DvAmount):
+ ... pass
+ >>> box_quantity = Amount(7)
+ >>> str(box_quantity.normal_range)
+ 'None'
+ >>> str(box_quantity.other_reference_ranges)
+ 'None'
+ >>> str(box_quantity.normal_status)
+ 'None'
+ >>> box_quantity.accuracy
+ -1.0
+ >>> box_quantity.magnitude_status
+ u'='
+ >>> box_quantity.magnitude
+ 7
+ >>> box_quantity.is_normal()
+ Traceback (most recent call last):
+ ...
+ TypeError: The object doesn't have any normal range.
+ >>> box_quantity.is_simple()
+ True
+ >>> box_quantity.valid_magnitude_status(u"=")
+ True
+ >>> weird_amount = AnotherAmount(2)
+ >>> weird_amount + box_quantity
+ Traceback (most recent call last):
+ ...
+ NotImplementedError: The class AnotherAmount must implement this method.
+
+The only mandatory methods that must be implemented to pass on all abstract
+restrictions are is_strictly_comparable_to, and __lt__ which is the < operator.
+The is_strictly_comparable_to is used by other methods to verify if two object
+can be compared correctly.
+The Amount class defined here for test purposes, have all requirements to a true
+`DvAmout` concrete class::
+
+ >>> other_box_quantity = Amount(5)
+ >>> box_quantity < other_box_quantity
+ False
+ >>> all_boxes = box_quantity + other_box_quantity
+ >>> all_boxes.magnitude
+ 12
+ >>> negated_box_quantity= -all_boxes
+ >>> negated_box_quantity.magnitude
+ -12
+
+
+Setting accuracy in a DvAmount object
+-------------------------------------
+
+The *accuracy* of a value usually isn't included in a model for quantified
+values. In the realistic health domain, it's required for statistical purposes
+allowing make queries which the measurement error can be disambiguated from a
+true correlation. For practical purposes, a (in)accuracy corresponds to a range
+of possible values. A value of 0 in either case indicates 100% accuracy, i.e.
+no error in measurement. The method unknown_accuracy verifies if the accuracy
+was measured::
+
+ >>> main_room_brightlight = Amount(magnitude=200,accuracy=200.0)
+ >>> main_room_brightlight.accuracy_is_percent
+ False
+ >>> wait_room_brightlight = Amount(magnitude=300,accuracy=150.0)
+ >>> sheets_of_paper = Amount(500)
+ >>> sheets_of_paper.accuracy_unknown()
+ True
+ >>> more_sheets_of_papers = Amount(70,0.0)
+ >>> more_sheets_of_papers.accuracy_unknown()
+ False
+ >>> a_set_of_simple_chairs = Amount(magnitude=50,accuracy=80.0,accuracy_is_percent=True)
+ >>> a_set_of_simple_chairs.accuracy_unknown()
+ False
+ >>> a_set_of_elegant_chairs = Amount(70,300.0)
+ >>> a_set_of_elegant_chairs.accuracy_is_percent
+ False
+
+
+Where accuracy is not recorded in a quantity, it is represented by a special
+value. In `DvAmount`, the `UNKNOWN_ACCURACY_VALUE` value is used for this
+purpose. In addition, the class `DvAmount`, provides a attribute called
+accuracy_is_percent: A boolean to indicate if accuracy value is to be understood
+as a percentage, or an absolute value.
+
+
+When two compatible quantities are added or subtracted using the + or -
+operators (`DvAmount` descendants), the accuracy behaves in the following way:
+
+* if accuracies are present in both quantities, they are added in the result,
+for both addition and subtraction operations::
+
+ >>> total_bright = main_room_brightlight + wait_room_brightlight
+ >>> total_bright.magnitude
+ 500
+ >>> total_bright.accuracy
+ 350.0
+
+ >>> turn_wait_room_lights_off = main_room_brightlight - wait_room_brightlight
+ >>> turn_wait_room_lights_off.magnitude
+ -100
+ >>> turn_wait_room_lights_off.accuracy
+ 50.0
+
+* if either or both quantities has an unknown accuracy, the accuracy of the
+result is also unknown::
+
+ >>> total_sheets = sheets_of_paper + more_sheets_of_papers
+ >>> total_sheets.magnitude
+ 570
+ >>> total_sheets.accuracy_unknown()
+ True
+ >>> the_best_sheets = sheets_of_paper - more_sheets_of_papers
+ >>> the_best_sheets.magnitude
+ 430
+ >>> the_best_sheets.accuracy_unknown()
+ True
+
+* if two `DvAmount` descendants are added or subtracted, and only one has
+accuracy_is_percent equals True, accuracy is expressed in the form used
+in the larger of the two quantities::
+
+ >>> all_chairs = a_set_of_simple_chairs + a_set_of_elegant_chairs
+ >>> all_chairs.magnitude
+ 120
+ >>> all_chairs.accuracy
+ 300.0
+
+
+
+Validating Invariants
+---------------------
+
+The `IDvAmount` have two invariants:
+
+* The first one verifies if the accuracy is zero and is a percentage accuracy::
+
+ >>> a_set_of_cars = Amount(magnitude=70,accuracy=0.0,accuracy_is_percent=True)
+ >>> IDvAmount.validateInvariants(a_set_of_cars)
+ Traceback (most recent call last):
+ ...
+ Invalid: The percentage accuracy cannot be zero.
+
+* The second and last invariant check the percentage validity: it must be a
+value between 0 and 100::
+
+ >>> a_set_of_computers = Amount(magnitude=70,accuracy=120.0,accuracy_is_percent=True)
+ >>> IDvAmount.validateInvariants(a_set_of_computers)
+ Traceback (most recent call last):
+ ...
+ Invalid: The percentage accuracy is not valid.
=== modified file 'src/oship/openehr/rm/datatypes/quantity/tests/dvquantified.py'
--- src/oship/openehr/rm/datatypes/quantity/tests/dvquantified.py 2010-08-08 19:19:54 +0000
+++ src/oship/openehr/rm/datatypes/quantity/tests/dvquantified.py 2010-09-16 20:21:31 +0000
@@ -5,39 +5,65 @@
"""
import unittest
import grok
+from zope.interface import Invalid
from oship.openehr.rm.datatypes.quantity import DvQuantified
+from oship.openehr.rm.datatypes.quantity.interfaces import IDvQuantified
+
+
+
+
+class SimpleDvQuantified(DvQuantified):
+ pass
+
+
class DvQuantifiedTest(unittest.TestCase):
def setUp(self):
- self.aDvQuantified = SimpleDvQuantified(None,None,None,None,None,None)
- self.validMagnitudeStatus = ('=','>','<','<=','>=','~')
-
- def tearDown(self):
- self.aDvQuantified = None
-
- def testValidMagnitudeStatusWithValidValues(self):
- for status in self.validMagnitudeStatus:
- self.assertEqual(True, self.aDvQuantified.validMagnitudeStatus(status))
-
- def testValidMagnitudeStatusWithInvalidValues(self):
- self.assertEqual(False, self.aDvQuantified.validMagnitudeStatus('a'))
- self.assertEqual(False, self.aDvQuantified.validMagnitudeStatus(''))
- self.assertEqual(False, self.aDvQuantified.validMagnitudeStatus(None))
-
- def testConstructorWithInvalidMagnitudeStatus(self):
- self.assertRaises(ValueError, SimpleDvQuantified, None,None,None,None,None,'a')
- self.assertRaises(ValueError, SimpleDvQuantified, None,None,None,None,None,'')
-
- def testContructorWithValidMagnitudeStatus(self):
- for status in self.validMagnitudeStatus:
- dvQuantified = SimpleDvQuantified(None,None,None,None,None,status)
- self.assertEqual(status, dvQuantified.magnitudeStatus)
-
- def testConstructurWithANoneMagnitudeStatus(self):
- dvQuantified = SimpleDvQuantified(None,None,None,None,None,None)
- self.assertEquals(None, dvQuantified.magnitudeStatus)
-
-class SimpleDvQuantified(DvQuantified):
- pass
+ self.a_quantity = SimpleDvQuantified(2)
+ self.valid_magnitude_status = ('=','>','<','<=','>=','~',)
+
+ def test_commom_properties(self):
+ self.assertTrue(self.a_quantity.normal_status is None)
+ self.assertTrue(self.a_quantity.normal_range is None)
+ self.assertTrue(self.a_quantity.other_reference_ranges is None)
+ self.assertEquals(self.a_quantity.magnitude, 2)
+ self.assertTrue(self.a_quantity.accuracy is None)
+ self.assertTrue(self.a_quantity.magnitude_status is None)
+ self.assertRaises(NotImplementedError, self.a_quantity.accuracy_unknown)
+
+
+ def test_valid_magnitude_status_with_valid_values(self):
+ for status in self.valid_magnitude_status:
+ self.assertTrue(self.a_quantity.valid_magnitude_status(status))
+
+ def test_valid_magnitude_status_with_invalid_values(self):
+ self.assertFalse(self.a_quantity.valid_magnitude_status('a'))
+ self.assertFalse(self.a_quantity.valid_magnitude_status(''))
+ self.assertFalse(self.a_quantity.valid_magnitude_status(None))
+
+ def test_constructor_with_invalid_magnitude_status(self):
+ self.assertRaises(ValueError, SimpleDvQuantified,2,magnitude_status='a')
+ self.assertRaises(ValueError, SimpleDvQuantified,3,magnitude_status='')
+
+ def test_constructor_with_valid_magnitude_status(self):
+ for status in self.valid_magnitude_status:
+ another_quantity = SimpleDvQuantified(6,magnitude_status=status)
+ self.assertEqual(status, another_quantity.magnitude_status)
+
+ def test_constructor_with_a_None_magnitude_status(self):
+ a_quantity = SimpleDvQuantified(78)
+ self.assertEquals(None, a_quantity.magnitude_status)
+
+ def test_magnitude_invariant(self):
+ a_simple_quantity = SimpleDvQuantified(None)
+ assert a_simple_quantity.magnitude is None
+ self.assertRaises(Invalid, IDvQuantified.validateInvariants, a_simple_quantity)
+
+ def test_magnitude_status_invariant(self):
+ a_simple_quantity = SimpleDvQuantified(42, "=")
+ a_simple_quantity.magnitude_status = "doh!"
+ self.assertRaises(Invalid, IDvQuantified.validateInvariants, a_simple_quantity)
+
+