def test_000_register_new_time_repr(self, class_Time_resource): assert not hasattr(Time, 'test_1') with pytest.raises(AttributeError): Time.test_1 Time.register_new_time('test_1', ExampleTestTimeRepresentation) assert hasattr(Time, 'test_1') Time.test_1
def test_030_register_new_time_repr_invalid_time_repr_class(self): class NoFromTimeRepr: # without from_rata_die def __init__(self, hour100, minute100): self.hour100 = hour100 self.minute100 = minute100 def to_day_frac(self): return Fraction(self.hour100 * 100 + self.minute100, 10000) with pytest.raises(TypeError): Time.register_new_time('test_1', NoFromTimeRepr) class NoToTimeRepr: # without to_rata_die def __init__(self, hour100, minute100): self.hour100 = hour100 self.minute100 = minute100 @classmethod def from_day_frac(cls, day_frac): minutes_tot = day_frac * 10000 hour100 = int(minutes_tot / 100) return cls(hour100, minutes_tot - hour100 * 100) with pytest.raises(TypeError): Time.register_new_time('test_1', NoToTimeRepr)
def test_017_invalid_argument_values_to_utc(self): """The resulting value must be equal or greater than -1 and less or equal to 1.""" for par in (-100, -1.00001, 1.00000001, 100): with pytest.raises(ValueError): Time("0.5555", to_utc=par) with pytest.raises(ValueError): Time(2, 3, to_utc=par)
def test_000_register_new_time_repr(self, class_Time_resource): assert not hasattr(Time, "test_1") with pytest.raises(AttributeError): Time.test_1 Time.register_new_time("test_1", ExampleTestTimeRepresentation) assert hasattr(Time, "test_1") Time.test_1
def test_040_registered_attribute_simple_class(self, class_Time_resource): Time.register_new_time('test_1', ExampleTestTimeRepresentation) # Time attribute type and metaclass are correct assert Time.test_1.__name__ == 'ExampleTestTimeRepresentationInTime' assert type(Time.test_1).__name__ == 'ModifiedClass' assert issubclass(Time.test_1, ExampleTestTimeRepresentation) # constructed Time type and value are is correct t1a = Time.test_1(10, 8) assert type(t1a) == Time assert t1a.day_frac == Fraction(63, 625) # new attribute on Time instance, type and value are correct t1b = Time("963/1250") assert isinstance(t1b.test_1, ExampleTestTimeRepresentation) assert type(t1b.test_1).__name__ == 'ExampleTestTimeRepresentationInTime' assert type(t1b.test_1.__class__).__name__ == 'ModifiedClass' assert t1b.test_1.hour100 == 77 assert t1b.test_1.minute100 == 4 # new attribute on Time instance build by another calendar, type and value are correct t1c = Time.western(10, 35, 15) assert isinstance(t1c.test_1, ExampleTestTimeRepresentation) assert type(t1c.test_1).__name__ == 'ExampleTestTimeRepresentationInTime' assert type(t1c.test_1.__class__).__name__ == 'ModifiedClass' assert t1c.test_1.hour100 == 44 assert t1c.test_1.minute100 == Fraction("275/24")
def test_040_registered_attribute_simple_class(self, class_Time_resource): Time.register_new_time("test_1", ExampleTestTimeRepresentation) # Time attribute type and metaclass are correct assert Time.test_1.__name__ == "ExampleTestTimeRepresentationInTime" assert type(Time.test_1).__name__ == "ModifiedClass" assert issubclass(Time.test_1, ExampleTestTimeRepresentation) # constructed Time type and value are is correct t1a = Time.test_1(10, 8) assert type(t1a) == Time assert t1a.day_frac == Fraction(63, 625) # new attribute on Time instance, type and value are correct t1b = Time("963/1250") assert isinstance(t1b.test_1, ExampleTestTimeRepresentation) assert type( t1b.test_1).__name__ == "ExampleTestTimeRepresentationInTime" assert type(t1b.test_1.__class__).__name__ == "ModifiedClass" assert t1b.test_1.hour100 == 77 assert t1b.test_1.minute100 == 4 # new attribute on Time instance build by another calendar, type and value are correct t1c = Time.western(10, 35, 15) assert isinstance(t1c.test_1, ExampleTestTimeRepresentation) assert type( t1c.test_1).__name__ == "ExampleTestTimeRepresentationInTime" assert type(t1c.test_1.__class__).__name__ == "ModifiedClass" assert t1c.test_1.hour100 == 44 assert t1c.test_1.minute100 == Fraction("275/24")
def test_030_register_new_time_repr_invalid_time_repr_class(self): class NoFromTimeRepr: # without from_rata_die TODO: shouldn't this comment be from_time_pair? def __init__(self, hour100, minute100): self.hour100 = hour100 self.minute100 = minute100 def to_time_pair(self): return Fraction(self.hour100 * 100 + self.minute100, 10000), None with pytest.raises(TypeError): Time.register_new_time("test_1", NoFromTimeRepr) class NoToTimeRepr: # without to_rata_die def __init__(self, hour100, minute100): self.hour100 = hour100 self.minute100 = minute100 @classmethod def from_time_pair(cls, day_frac): minutes_tot = day_frac * 10000 hour100 = int(minutes_tot / 100) return cls(hour100, minutes_tot - hour100 * 100) with pytest.raises(TypeError): Time.register_new_time("test_1", NoToTimeRepr)
def test_342_hash_equality_to_utc(self): """Time instances are immutable.""" t1 = Time("3/5", to_utc=0.25) t2 = Time(4, 5, to_utc="1/20") assert hash(t1) == hash(t2) dic = {t1: 1} dic[t2] = 2 assert len(dic) == 1 assert dic[t1] == 2 assert dic[t2] == 2 t3 = Time(Decimal("0.2"), to_utc="-7/20") assert hash(t1) == hash(t3) dic[t3] = 2 assert len(dic) == 1 assert dic[t3] == 2 t4 = Time("3/5", to_utc=0.75) assert hash(t1) == hash(t4) dic[t4] = 2 assert len(dic) == 1 assert dic[t4] == 2
def test_030_now_with_argument(self): "Return an object that represents the current moment in the day." # for the time being, let's use the good old datetime module :-) import datetime # we must ensure that at least once in three times we get the same values in seconds count = 0 while count < 3: datetime_now = datetime.datetime.utcnow() datetime_frac_seconds = datetime_now.hour * 3600 + datetime_now.minute * 60 + datetime_now.second time_now = Time.now(to_utc=0) if int(time_now.day_frac * 86400) == datetime_frac_seconds: break count += 1 assert count < 3, "Unable to get at least one a correct Time.now(to_utc=0)" assert time_now.to_utc == 0 # again but with class count = 0 while count < 3: datetime_now = datetime.datetime.utcnow() datetime_frac_seconds = datetime_now.hour * 3600 + datetime_now.minute * 60 + datetime_now.second time_now = Time.now(to_utc=DummyTZ(0, 1)) if int(time_now.day_frac * 86400) == datetime_frac_seconds: break count += 1 assert count < 3, "Unable to get at least one a correct Time.now(to_utc=DummyTZ(0, 1))" assert time_now.to_utc == 0
def test_350_bool(self): """In boolean contexts, all Time instances are considered to be true.""" for day_frac, input_values in time_test_data: for input_value in input_values: assert Time(input_value) for day_frac, input_values in time_test_data_num_den: for input_value in input_values: assert Time(input_value[0], input_value[1])
def test_010_invalid_argument_types(self): """A TypeError exception is raised if the argument type is not one of the accepted types.""" # exception with no or three parameters with pytest.raises(TypeError): Time() # exception with non-numeric types for par in (1j, (1,), [1], {1: 1}, [], {}, None, (1, 2), (1, 2, 3)): with pytest.raises(TypeError): Time(par)
def test_011_invalid_num_den(self): """A TypeError exception is raised if the argument type is not one of the accepted types.""" # exception with non-numeric types for par in (1j, (1,), [1], {1: 1}, [], {}, None, (1, 2), (1, 2, 3)): with pytest.raises(TypeError): Time(par, 2) # None is valid as second argument, so we are not testing it for par in (1j, (1,), [1], {1: 1}, [], {}, (1, 2), (1, 2, 3)): with pytest.raises(TypeError): Time(1, par)
def test_400_relocate(self): "Return another Time instance that identifies the same time" # Im using a mix of values, then check that relocated instance is equal for day_frac, time_input_values in time_test_data: for to_utc_frac, utc_input_values in to_utc_test_data: first = Time(time_input_values[0], to_utc=utc_input_values[0]) for new_utc_value in to_utc_strange_test_data: second = first.relocate(new_utc_value) diff = (first.day_frac + first.to_utc) - (second.day_frac + second.to_utc) # Note that for some of the test value we have an overflow/underflow, # so we must impement a precise test assert diff == int(diff)
def test_400_relocate(self): """Return another Time instance that identifies the same time""" # Im using a mix of values, then check that relocated instance is equal for day_frac, time_input_values in time_test_data: for to_utc_frac, utc_input_values in to_utc_test_data: first = Time(time_input_values[0], to_utc=utc_input_values[0]) for new_utc_value in to_utc_strange_test_data: second = first.relocate(new_utc_value) diff = (first.day_frac + first.to_utc) - ( second.day_frac + second.to_utc ) # Note that for some of the test value we have an overflow/underflow, # so we must implement a precise test assert diff == int(diff) # ????
def test_330_comparison_with_invalid_types(self): class SomeClass: pass t = Time(0) # exception with non-numeric types for par in ("1", (1,), [1], {1: 1}, (), [], {}, None, SomeClass()): assert not (t == par) assert t != par with pytest.raises(TypeError): t < par with pytest.raises(TypeError): t > par with pytest.raises(TypeError): t <= par with pytest.raises(TypeError): t >= par # exception with numeric types (all invalid) and other objects for par in (1, 1.0, Fraction(1, 1), Decimal(1), 1j, 1 + 1j, INF, NAN): assert not (t == par) assert t != par with pytest.raises(TypeError): t < par with pytest.raises(TypeError): t > par with pytest.raises(TypeError): t <= par with pytest.raises(TypeError): t >= par
def test_046_registered_attribute_class_with_static_methods( self, class_Time_resource): class ExampleTestTimeRepresentation3(ExampleTestTimeRepresentation): @staticmethod def is_odd(number): return (number % 2) == 1 Time.register_new_time("test_3", ExampleTestTimeRepresentation3) # Time attribute type and metaclass are correct assert Time.test_3.__name__ == "ExampleTestTimeRepresentation3InTime" assert type(Time.test_3).__name__ == "ModifiedClass" assert issubclass(Time.test_3, ExampleTestTimeRepresentation) # constructed Time type and value are is correct t3a = Time.test_3(10, 8) assert type(t3a) == Time assert t3a.day_frac == Fraction(63, 625) # new attribute on Time instance, type and value are correct t3b = Time("963/1250") assert isinstance(t3b.test_3, ExampleTestTimeRepresentation3) assert type( t3b.test_3).__name__ == "ExampleTestTimeRepresentation3InTime" assert type(t3b.test_3.__class__).__name__ == "ModifiedClass" assert t3b.test_3.hour100 == 77 assert t3b.test_3.minute100 == 4 # new attribute on Time instance build by another calendar, type and value are correct t3c = Time.western(10, 35, 15) assert isinstance(t3c.test_3, ExampleTestTimeRepresentation3) assert type( t3c.test_3).__name__ == "ExampleTestTimeRepresentation3InTime" assert type(t3c.test_3.__class__).__name__ == "ModifiedClass" assert t3c.test_3.hour100 == 44 assert t3c.test_3.minute100 == Fraction("275/24") # static method can be reached on the class and on all types of instance assert Time.test_3.is_odd(3) assert not Time.test_3.is_odd(4) assert t3a.test_3.is_odd(3) assert not t3a.test_3.is_odd(4) assert t3b.test_3.is_odd(3) assert not t3b.test_3.is_odd(4) assert t3c.test_3.is_odd(3) assert not t3c.test_3.is_odd(4)
def test_900_pickling(self): for day_frac, input_values in time_test_data: for input_value in input_values: t = Time(input_value) for protocol in range(pickle.HIGHEST_PROTOCOL + 1): pickled = pickle.dumps(t, protocol) derived = pickle.loads(pickled) assert t == derived
def test_100_write_attributes(self): "This attribute is read-only." t1 = Time('0.12345') with pytest.raises(AttributeError): t1.day_frac = Fraction(3, 7) t1.to_utc = Fraction(1, 11) t2 = Time('0.6789', to_utc='-1/2') with pytest.raises(AttributeError): t2.day_frac = Fraction(3, 7) t2.to_utc = Fraction(1, 11) t3 = Time('0.0123', to_utc=DummyTZ(-2, 3)) with pytest.raises(AttributeError): t3.day_frac = Fraction(3, 7) t3.to_utc = Fraction(1, 11)
def test_340_hash_equality(self): """Time instances are immutable.""" t1 = Time("3/5") t2 = Time(3, 5) assert hash(t1) == hash(t2) dic = {t1: 1} dic[t2] = 2 assert len(dic) == 1 assert dic[t1] == 2 assert dic[t2] == 2 t3 = Time("7/20") + TimeDelta(0.25) assert hash(t1) == hash(t3) dic[t3] = 2 assert len(dic) == 1 assert dic[t3] == 2
def test_110_get_unknown_attribute(self): """Time instances have one attribute.""" # I want to do this, because Time will have attributes added at runtime # let's tests this both on class and instance with pytest.raises(AttributeError): Time.unknown t = Time("0.12345") with pytest.raises(AttributeError): t.unknown
def test_016_invalid_num_den(self): """The resulting value must be equal or greater than 0 and less than 1.""" for num, den in ( (1000, 1), (4, 2), (Fraction(1.000001), 1), (2, 2), (-1, -1), (Fraction(-0.000001), 1), (-1, 1000000), (-3, 3), (1000000, -2), ): with pytest.raises(ValueError): Time(num, den) # denominator should not be 0 with pytest.raises(ZeroDivisionError): Time(2, 0)
def test_046_registered_attribute_class_with_static_methods(self, class_Time_resource): class ExampleTestTimeRepresentation3(ExampleTestTimeRepresentation): @staticmethod def is_odd(number): return (number % 2) == 1 Time.register_new_time('test_3', ExampleTestTimeRepresentation3) # Time attribute type and metaclass are correct assert Time.test_3.__name__ == 'ExampleTestTimeRepresentation3InTime' assert type(Time.test_3).__name__ == 'ModifiedClass' assert issubclass(Time.test_3, ExampleTestTimeRepresentation) # constructed Time type and value are is correct t3a = Time.test_3(10, 8) assert type(t3a) == Time assert t3a.day_frac == Fraction(63, 625) # new attribute on Time instance, type and value are correct t3b = Time("963/1250") assert isinstance(t3b.test_3, ExampleTestTimeRepresentation3) assert type(t3b.test_3).__name__ == 'ExampleTestTimeRepresentation3InTime' assert type(t3b.test_3.__class__).__name__ == 'ModifiedClass' assert t3b.test_3.hour100 == 77 assert t3b.test_3.minute100 == 4 # new attribute on Time instance build by another calendar, type and value are correct t3c = Time.western(10, 35, 15) assert isinstance(t3c.test_3, ExampleTestTimeRepresentation3) assert type(t3c.test_3).__name__ == 'ExampleTestTimeRepresentation3InTime' assert type(t3c.test_3.__class__).__name__ == 'ModifiedClass' assert t3c.test_3.hour100 == 44 assert t3c.test_3.minute100 == Fraction("275/24") # static method can be reached on the class and on all types of instance assert Time.test_3.is_odd(3) assert not Time.test_3.is_odd(4) assert t3a.test_3.is_odd(3) assert not t3a.test_3.is_odd(4) assert t3b.test_3.is_odd(3) assert not t3b.test_3.is_odd(4) assert t3c.test_3.is_odd(3) assert not t3c.test_3.is_odd(4)
def test_308_operations_preserve_naivety(self): a = Time("3/8") b = Time(3, 4, to_utc="1/6") test_obj = DummyToUtc(-1, 8) c = Time(0.25, to_utc=test_obj) for td in (TimeDelta(0.5), TimeDelta(-0.25), TimeDelta(3), TimeDelta(-2.75)): res_a_plus = a + td assert res_a_plus.to_utc is None res_a_minus = a - td assert res_a_minus.to_utc is None res_b_plus = b + td assert res_b_plus.to_utc == Fraction(1, 6) res_b_minus = b - td assert res_b_minus.to_utc == Fraction(1, 6) res_c_plus = c + td assert res_c_plus.to_utc == Fraction(-1, 8) res_c_plus = c - td assert res_c_plus.to_utc == Fraction(-1, 8)
def test_100_Time_has_attributes_but_instance_not(self): # the Time class aways has a registered attribute assert hasattr(Time, 'western') assert Time.western # an instance created with another calendar or by Time does not have # the attribute; it is instead is reachable via the Time class t1 = Time('4/10') with pytest.raises(KeyError): t1.__dict__['western'] assert hasattr(t1, 'western') t1.western t2 = Time.internet(345) with pytest.raises(KeyError): t2.__dict__['western'] assert hasattr(t2, 'western') t2.western # a Time instance created via the calendar does have the same attribute t3 = Time.western(3, 4, 5) assert hasattr(t3, 'western') t3.western
def test_100_Time_has_attributes_but_instance_not(self): # the Time class aways has a registered attribute assert hasattr(Time, "western") assert Time.western # an instance created with another calendar or by Time does not have # the attribute; it is instead is reachable via the Time class t1 = Time("4/10") with pytest.raises(KeyError): t1.__dict__["western"] assert hasattr(t1, "western") t1.western t2 = Time.internet(345) with pytest.raises(KeyError): t2.__dict__["western"] assert hasattr(t2, "western") t2.western # a Time instance created via the calendar does have the same attribute t3 = Time.western(3, 4, 5) assert hasattr(t3, "western") t3.western
def test_012_invalid_argument_types_to_utc(self): """A TypeError exception is raised if the argument type is not one of the accepted types.""" # this object has a time_to_utc attribute, but is isn't callable class WrongObj: def __init__(self): self.time_to_utc = "foo" # exception with invalid parameter name with pytest.raises(TypeError): Time(1, foobar="barfoo") with pytest.raises(TypeError): Time(1, 2, foobar="barfoo") # to_utc must be explicit with pytest.raises(TypeError): Time(1, 2, 1) # exception with non-numeric types for par in (1j, (1,), [1], {1: 1}, [], {}, (1, 2), (1, 2, 3), WrongObj()): with pytest.raises(TypeError): Time("0.4444", to_utc=par)
def test_500_repr(self): import datetime2 for day_frac, input_values in time_test_data: for input_value in input_values: t = Time(input_value) time_repr = repr(t) names, args = time_repr.split("(") assert names.split(".") == ["datetime2", "Time"] args = args[:-1] # drop ')' assert eval(args) == str(day_frac) assert t == eval(time_repr)
def test_110_naivety_is_preserved(self): class NaivetyCheck: def __init__(self, hour100, minute100, to_utc=None): self.hour100 = hour100 self.minute100 = minute100 self.to_utc = to_utc def to_time_pair(self): return Fraction(self.hour100 * 100 + self.minute100, 10000), None @classmethod def from_time_pair(cls, day_frac, to_utc=None): minutes_tot = day_frac * 10000 hour100 = int(minutes_tot / 100) return cls(hour100, minutes_tot - hour100 * 100) Time.register_new_time("test_1", NaivetyCheck) t1 = Time("17/24") assert t1.test_1.to_utc is None t2 = Time("17/24", to_utc=0) assert t2.test_1.to_utc is not None t3 = Time.test_1(11, 12) assert t3.to_utc is None t4 = Time.test_1(11, 12, to_utc=0) assert t4.to_utc is not None
def test_020_register_new_time_repr_invalid_attribute_name(self): with pytest.raises(ValueError): Time.register_new_time("", ExampleTestTimeRepresentation) with pytest.raises(ValueError): Time.register_new_time("123new", ExampleTestTimeRepresentation) with pytest.raises(ValueError): Time.register_new_time(123, ExampleTestTimeRepresentation)
def test_020_register_new_time_repr_invalid_attribute_name(self): with pytest.raises(ValueError): Time.register_new_time('', ExampleTestTimeRepresentation) with pytest.raises(ValueError): Time.register_new_time('123new', ExampleTestTimeRepresentation) with pytest.raises(ValueError): Time.register_new_time(123, ExampleTestTimeRepresentation)
def test_043_registered_attribute_class_with_other_constructors( self, class_Time_resource): class ExampleTestTimeRepresentation2(ExampleTestTimeRepresentation): @classmethod def with_seconds(cls, hour100, minute100, second100): return cls(hour100, minute100 + Fraction(second100, 100)) Time.register_new_time("test_2", ExampleTestTimeRepresentation2) # Time attribute type and metaclass are correct assert Time.test_2.__name__ == "ExampleTestTimeRepresentation2InTime" assert type(Time.test_2).__name__ == "ModifiedClass" assert issubclass(Time.test_2, ExampleTestTimeRepresentation) # constructed Time type and value are is correct t2a = Time.test_2(10, 8) assert type(t2a) == Time assert t2a.day_frac == Fraction(63, 625) d2d = Time.test_2.with_seconds(40, 40, 40) assert type(d2d) == Time assert d2d.day_frac == Fraction("10101/25000") # new attribute on Time instance, type and value are correct t2b = Time("963/1250") assert isinstance(t2b.test_2, ExampleTestTimeRepresentation2) assert type( t2b.test_2).__name__ == "ExampleTestTimeRepresentation2InTime" assert type(t2b.test_2.__class__).__name__ == "ModifiedClass" assert t2b.test_2.hour100 == 77 assert t2b.test_2.minute100 == 4 # new attribute on Time instance build by another calendar, type and value are correct t2c = Time.western(10, 35, 15) assert isinstance(t2c.test_2, ExampleTestTimeRepresentation2) assert type( t2c.test_2).__name__ == "ExampleTestTimeRepresentation2InTime" assert type(t2c.test_2.__class__).__name__ == "ModifiedClass" assert t2c.test_2.hour100 == 44 assert t2c.test_2.minute100 == Fraction("275/24")
def test_410_relocate_invalid_type(self): "Return another Time instance that identifies the same time" class WrongObj: def __init__(self): self.time_to_utc = 'foo' t = Time('123/456', to_utc='-78/90') # exception with invalid parameter name with pytest.raises(TypeError): t.relocate() with pytest.raises(TypeError): t.relocate(1, 2) with pytest.raises(TypeError): t.relocate(foobar='barfoo') # exception with non-numeric types for par in (1j, (1,), [1], {1:1}, [], {}, None, (1,2,3), WrongObj()): with pytest.raises(TypeError): t.relocate(par)
def test_043_registered_attribute_class_with_other_constructors(self, class_Time_resource): class ExampleTestTimeRepresentation2(ExampleTestTimeRepresentation): @classmethod def with_seconds(cls, hour100, minute100, second100): return cls(hour100, minute100 + Fraction(second100, 100)) Time.register_new_time('test_2', ExampleTestTimeRepresentation2) # Time attribute type and metaclass are correct assert Time.test_2.__name__ == 'ExampleTestTimeRepresentation2InTime' assert type(Time.test_2).__name__ == 'ModifiedClass' assert issubclass(Time.test_2, ExampleTestTimeRepresentation) # constructed Time type and value are is correct t2a = Time.test_2(10, 8) assert type(t2a) == Time assert t2a.day_frac == Fraction(63, 625) d2d = Time.test_2.with_seconds(40, 40, 40) assert type(d2d) == Time assert d2d.day_frac == Fraction("10101/25000") # new attribute on Time instance, type and value are correct t2b = Time("963/1250") assert isinstance(t2b.test_2, ExampleTestTimeRepresentation2) assert type(t2b.test_2).__name__ == 'ExampleTestTimeRepresentation2InTime' assert type(t2b.test_2.__class__).__name__ == 'ModifiedClass' assert t2b.test_2.hour100 == 77 assert t2b.test_2.minute100 == 4 # new attribute on Time instance build by another calendar, type and value are correct t2c = Time.western(10, 35, 15) assert isinstance(t2c.test_2, ExampleTestTimeRepresentation2) assert type(t2c.test_2).__name__ == 'ExampleTestTimeRepresentation2InTime' assert type(t2c.test_2.__class__).__name__ == 'ModifiedClass' assert t2c.test_2.hour100 == 44 assert t2c.test_2.minute100 == Fraction("275/24")
def test_030_now_with_argument(self): """Return an object that represents the current moment in the day.""" # for the time being, let's use the good old datetime module :-) import datetime # we must ensure that at least once in three times we get the same values in seconds count = 0 while count < 3: datetime_now = datetime.datetime.utcnow() time_now = Time.now(to_utc=0) datetime_frac_seconds = ( datetime_now.hour * 3600 + datetime_now.minute * 60 + datetime_now.second ) if int(time_now.day_frac * 86400) == datetime_frac_seconds: break count += 1 assert count < 3, "Unable to get at least one a correct Time.now(to_utc=0)" assert time_now.to_utc == 0 # again but with class count = 0 while count < 3: datetime_now = datetime.datetime.utcnow() time_now = Time.now(to_utc=DummyToUtc(0, 1)) datetime_frac_seconds = ( datetime_now.hour * 3600 + datetime_now.minute * 60 + datetime_now.second ) if int(time_now.day_frac * 86400) == datetime_frac_seconds: break count += 1 assert count < 3, "Unable to get at least one a correct Time.now(to_utc=DummyToUtc(0, 1))" assert time_now.to_utc == 0
def test_040_localnow(self): "Return an object that represents the current moment in the day." # for the time being, let's use the good old datetime module :-) import datetime # we must ensure that at least once in three times we get the same values in seconds count = 0 while count < 3: datetime_now = datetime.datetime.now() datetime_frac_seconds = datetime_now.hour * 3600 + datetime_now.minute * 60 + datetime_now.second time_now = Time.localnow() if int(time_now.day_frac * 86400) == datetime_frac_seconds: break count += 1 assert count < 3, "Unable to get at least one a correct Time.localnow()" assert time_now.to_utc is None
def test_920_subclass1(self): # check that there is no interference from the interface mechanism and from possible additional arguments class T(Time): the_answer = 42 def __init__(self, *args, **kws): temp = kws.copy() self.extra = temp.pop("extra") Time.__init__(self, *args, **temp) def newmeth(self, start): return start + (self.day_frac * 3) // 2 t1 = Time("3/8") t2 = T(0.375, extra=7) assert t2.the_answer == 42 assert t2.extra == 7 assert t1.day_frac == t2.day_frac assert t2.newmeth(-7) == (t1.day_frac * 3) // 2 - 7
def test_040_localnow(self): """Return an object that represents the current moment in the day.""" # for the time being, let's use the good old datetime module :-) import datetime # we must ensure that at least once in three times we get the same values in seconds count = 0 while count < 3: datetime_now = datetime.datetime.now() time_now = Time.localnow() datetime_frac_seconds = ( datetime_now.hour * 3600 + datetime_now.minute * 60 + datetime_now.second ) if int(time_now.day_frac * 86400) == datetime_frac_seconds: break count += 1 assert count < 3, "Unable to get at least one a correct Time.localnow()" assert time_now.to_utc is None
def test_310_disallowed_operations(self): a = Time("3/4") b = Time("2/5", to_utc="1/8") # Add/sub int, float, string, complex, specials and containers should be illegal for obj in (10, 34.5, "abc", 1 + 2j, INF, NAN, {}, [], ()): with pytest.raises(TypeError): a + obj with pytest.raises(TypeError): a - obj with pytest.raises(TypeError): obj + a with pytest.raises(TypeError): obj - a with pytest.raises(TypeError): b + obj with pytest.raises(TypeError): b - obj with pytest.raises(TypeError): obj + b with pytest.raises(TypeError): obj - b # Reverse operations with pytest.raises(TypeError): TimeDelta(-0.25) - a with pytest.raises(TypeError): TimeDelta(-0.25) - b for obj in (1, 1.1, Time("2/5")): with pytest.raises(TypeError): a * obj with pytest.raises(TypeError): obj * a with pytest.raises(TypeError): a / obj with pytest.raises(TypeError): obj / a with pytest.raises(TypeError): a // obj with pytest.raises(TypeError): obj // a with pytest.raises(TypeError): pow(a, obj) with pytest.raises(TypeError): pow(obj, a) with pytest.raises(TypeError): a ^ obj with pytest.raises(TypeError): obj ^ a with pytest.raises(TypeError): a >> obj with pytest.raises(TypeError): obj >> a with pytest.raises(TypeError): a << obj with pytest.raises(TypeError): obj << a with pytest.raises(TypeError): b * obj with pytest.raises(TypeError): obj * b with pytest.raises(TypeError): b / obj with pytest.raises(TypeError): obj / b with pytest.raises(TypeError): b // obj with pytest.raises(TypeError): obj // b with pytest.raises(TypeError): pow(b, obj) with pytest.raises(TypeError): pow(obj, b) with pytest.raises(TypeError): b ^ obj with pytest.raises(TypeError): obj ^ b with pytest.raises(TypeError): b >> obj with pytest.raises(TypeError): obj >> b with pytest.raises(TypeError): b << obj with pytest.raises(TypeError): obj << b # operations mixing naive and aware instances with pytest.raises(ValueError): a - b with pytest.raises(ValueError): b - a
def test_320_comparisons(self): t1 = Time("3/8") t2 = Time(0.375) assert t1 == t2 assert t1 <= t2 assert t1 >= t2 assert not (t1 != t2) assert not (t1 < t2) assert not (t1 > t2) t3 = Time("5/7") # this is larger than t1 assert t1 < t3 assert t3 > t1 assert t1 <= t3 assert t3 >= t1 assert t1 != t3 assert t3 != t1 assert not (t1 == t3) assert not (t3 == t1) assert not (t1 > t3) assert not (t3 < t1) assert not (t1 >= t3) assert not (t3 <= t1) # Reverse comparison mechanism class TimeLike: def __init__(self): self.day_frac = Fraction(3, 4) def __eq__(self, other): return self.day_frac == other.day_frac def __ne__(self, other): return self.day_frac != other.day_frac def __lt__(self, other): return self.day_frac < other.day_frac def __le__(self, other): return self.day_frac <= other.day_frac def __gt__(self, other): return self.day_frac > other.day_frac def __ge__(self, other): return self.day_frac >= other.day_frac tl = TimeLike() t12 = Time(1, 2) t34 = Time("3/4") t45 = Time(4, 5) assert not (t12 == tl) assert t34 == tl assert not (t45 == tl) assert t12 != tl assert not (t34 != tl) assert t45 != tl assert t12 < tl assert not (t34 < tl) assert not (t45 < tl) assert t12 <= tl assert t34 <= tl assert not (t45 <= tl) assert not (t12 > tl) assert not (t34 > tl) assert t45 > tl assert not (t12 >= tl) assert t34 >= tl assert t45 >= tl
def test_302_valid_operations_to_utc(self): a = Time(0, to_utc="1/3") b = Time(0.25, to_utc="-1/4") c = Time(0.75, to_utc="1/6") zero = TimeDelta(0) # note that TimeDelta is in days plus_half = TimeDelta(0.5) minus_half = TimeDelta(-1.5) integer = TimeDelta(3) # Addition between Time and TimeDelta # test with zero, negative and positive dates assert a + zero == Time(0, to_utc="1/3") assert a + plus_half == Time(0.5, to_utc="1/3") assert a + minus_half == Time(0.5, to_utc="1/3") assert a + integer == Time(0, to_utc="1/3") assert b + zero == Time(0.25, to_utc="-1/4") assert b + plus_half == Time(0.75, to_utc="-1/4") assert b + minus_half == Time(0.75, to_utc="-1/4") assert b + integer == Time(0.25, to_utc="-1/4") assert c + zero == Time(0.75, to_utc="1/6") assert c + plus_half == Time(0.25, to_utc="1/6") assert c + minus_half == Time(0.25, to_utc="1/6") assert c + integer == Time(0.75, to_utc="1/6") # Reversed addition between Time and TimeDelta # test with zero, negative and positive dates assert zero + a == Time(0, to_utc="1/3") assert plus_half + a == Time(0.5, to_utc="1/3") assert minus_half + a == Time(0.5, to_utc="1/3") assert integer + a == Time(0, to_utc="1/3") assert zero + b == Time(0.25, to_utc="-1/4") assert plus_half + b == Time(0.75, to_utc="-1/4") assert minus_half + b == Time(0.75, to_utc="-1/4") assert integer + b == Time(0.25, to_utc="-1/4") assert zero + c == Time(0.75, to_utc="1/6") assert plus_half + c == Time(0.25, to_utc="1/6") assert minus_half + c == Time(0.25, to_utc="1/6") assert integer + c == Time(0.75, to_utc="1/6") # subtraction between Time and TimeDelta, reverse is not defined # test with zero, negative and positive Times assert a - zero == Time(0, to_utc="1/3") assert a - plus_half == Time(0.5, to_utc="1/3") assert a - minus_half == Time(0.5, to_utc="1/3") assert a - integer == Time(0, to_utc="1/3") assert b - zero == Time(0.25, to_utc="-1/4") assert b - plus_half == Time(0.75, to_utc="-1/4") assert b - minus_half == Time(0.75, to_utc="-1/4") assert b - integer == Time(0.25, to_utc="-1/4") assert c - zero == Time(0.75, to_utc="1/6") assert c - plus_half == Time(0.25, to_utc="1/6") assert c - minus_half == Time(0.25, to_utc="1/6") assert c - integer == Time(0.75, to_utc="1/6")
def test_322_comparisons_to_utc(self): t1 = Time("7/8", to_utc="5/6") # These value have a lot of overflows and underflows t2 = Time(0.375, to_utc=Fraction(-2, 3)) assert t1 == t2 assert t1 <= t2 assert t1 >= t2 assert not (t1 != t2) assert not (t1 < t2) assert not (t1 > t2) t3 = Time("1/2", to_utc=0.25) # this is larger than t1 assert t1 < t3 assert t3 > t1 assert t1 <= t3 assert t3 >= t1 assert t1 != t3 assert t3 != t1 assert not (t1 == t3) assert not (t3 == t1) assert not (t1 > t3) assert not (t3 < t1) assert not (t1 >= t3) assert not (t3 <= t1) assert t2 < t3 # repeating the tests with an instance with negative to_utc assert t3 > t2 assert t2 <= t3 assert t3 >= t2 assert t2 != t3 assert t3 != t2 assert not (t2 == t3) assert not (t3 == t2) assert not (t2 > t3) assert not (t3 < t2) assert not (t2 >= t3) assert not (t3 <= t2) # Reverse comparison mechanism class TimeLike: def __init__(self): self.day_frac = Fraction(3, 4) def __eq__(self, other): return self.day_frac == other.day_frac def __ne__(self, other): return self.day_frac != other.day_frac def __lt__(self, other): return self.day_frac < other.day_frac def __le__(self, other): return self.day_frac <= other.day_frac def __gt__(self, other): return self.day_frac > other.day_frac def __ge__(self, other): return self.day_frac >= other.day_frac tl = TimeLike() # We need not implement naivety checks, which are delegated to the Time-like class, not under test t12 = Time(1, 2, to_utc="-1/3") t34 = Time("3/4", to_utc=0.25) t45 = Time(4, 5, to_utc=Fraction(-1, 8)) assert not (t12 == tl) assert t34 == tl assert not (t45 == tl) assert t12 != tl assert not (t34 != tl) assert t45 != tl assert t12 < tl assert not (t34 < tl) assert not (t45 < tl) assert t12 <= tl assert t34 <= tl assert not (t45 <= tl) assert not (t12 > tl) assert not (t34 > tl) assert t45 > tl assert not (t12 >= tl) assert t34 >= tl assert t45 >= tl
def test_100_write_attribute(self): "This attribute is read-only." t = Time('0.12345') with pytest.raises(AttributeError): t.day_frac = Fraction(3, 7)
def test_010_register_new_time_repr_existing_time_repr_or_attribute(self): with pytest.raises(AttributeError): Time.register_new_time("western", ExampleTestTimeRepresentation) with pytest.raises(AttributeError): Time.register_new_time("day_frac", ExampleTestTimeRepresentation)
def test_010_register_new_time_repr_existing_time_repr_or_attribute(self): with pytest.raises(AttributeError): Time.register_new_time('western', ExampleTestTimeRepresentation) with pytest.raises(AttributeError): Time.register_new_time('day_frac', ExampleTestTimeRepresentation)
def __init__(self, *args, **kws): temp = kws.copy() self.extra = temp.pop('extra') Time.__init__(self, *args, **temp)