def test_sanity(): log.title(f"test_sanity()") work = default_work(TEST_START_ARROW) work.stop() with temp_sheet("/tmp/timefred-sheet-test_log__test_sanity.toml"): store.dump(work) log_action()
def test_ongoing(self): log.title(f"test_models.test_ongoing()") work = default_work(TEST_START_ARROW) day: Day = work.__getitem__(TEST_START_ARROW.DDMMYY) got_to_office_activity: Activity = day.__getitem__("Got to office") ongoing_activity: Activity = work.ongoing_activity() assert ongoing_activity is got_to_office_activity assert ongoing_activity.ongoing() is True assert got_to_office_activity.ongoing() is True
def test_load_store(self, work=None): log.title(f"test_load_store({work = })") if not work: work = default_work() with temp_sheet( "/tmp/timefred-sheet-test_on_device_validation_08_30.toml" ): store.dump(work) work = store.load() self.test_sanity(work=work)
def test_dump(self): work = default_work() log.title(f"test_dump({work = })") # os.environ['TIMEFRED_SHEET'] = "/tmp/timefred-sheet-test_on_device_validation_08_30.toml" # config.sheet.path = "/tmp/timefred-sheet-test_on_device_validation_08_30.toml" # store.path = "/tmp/timefred-sheet-test_on_device_validation_08_30.toml" with temp_sheet( "/tmp/timefred-sheet-test_on_device_validation_08_30.toml"): store.dump(work) work = store.load()
def test_stop_when_not_ongoing(self): log.title(f"test_models.test_stop_when_not_ongoing()") work = default_work(TEST_START_ARROW) day: Day = work.__getitem__(TEST_START_ARROW.DDMMYY) got_to_office_activity: Activity = day.__getitem__("Got to office") assert got_to_office_activity.ongoing() is True now = XArrow.now() entry: Entry = got_to_office_activity.stop(now) assert entry is got_to_office_activity.safe_last_entry() assert entry.end == now assert got_to_office_activity.ongoing() is False with assert_raises(ValueError, f'{got_to_office_activity} is not ongoing'): got_to_office_activity.stop()
def test_stop_before_last_entry_started(self): log.title(f"test_models.test_stop_before_last_entry_started()") work = default_work(TEST_START_ARROW) day: Day = work.__getitem__(TEST_START_ARROW.DDMMYY) assert work[TEST_START_ARROW.DDMMYY] is day got_to_office_activity: Activity = day.__getitem__("Got to office") assert got_to_office_activity.ongoing() is True assert day['Got to office'] is got_to_office_activity last_entry: Entry = got_to_office_activity[-1] assert got_to_office_activity.safe_last_entry() is last_entry yesterday = XArrow.dehumanize('yesterday') with assert_raises( ValueError, f'Cannot stop {got_to_office_activity.shortrepr()} before start time (tried to stop at {yesterday!r})' ): got_to_office_activity.stop(yesterday)
def test_dehumanize_vanilla(self): """Make sure we don't break vanilla Arrow.dehumanize() functionality""" log.title('TestXArrow.Test_dehumanize.test_dehumanize_vanilla') now = XArrow.now() now_dehumanized = XArrow.dehumanize("now") assert_arrows_soft_eq(now_dehumanized, now) assert_arrows_soft_eq(XArrow.dehumanize("just now"), now) # * 1 unit # "hour": "an hour", "days": "{0} days" for unit, expression in EnglishLocale.timeframes.items(): for relative_fmt in ("{0} ago", "in {0}"): if 'now' in expression: continue if '{0}' in expression: shift = randint(2, 4) hardcoded_number = expression.format( shift) # 3 seconds human_expression = relative_fmt.format( hardcoded_number) # 3 seconds ago / in 3 seconds else: shift = 1 human_expression = relative_fmt.format( expression) # a second ago / in a second dehumanized_static = XArrow.dehumanize(human_expression) if 'ago' in relative_fmt: shift *= -1 shift_kwargs = {unit.removesuffix('s') + 's': shift} now = XArrow.now() now_shifted = now.shift(**shift_kwargs) try: assert_arrows_soft_eq(dehumanized_static, now_shifted) except AssertionError: dehumanized_static = XArrow.dehumanize( human_expression) now = XArrow.now() now_shifted = now.shift(**shift_kwargs) assert_arrows_soft_eq(dehumanized_static, now_shifted) dehumanized_instance = now.dehumanize(human_expression) assert_arrows_soft_eq(dehumanized_instance, now_shifted) # * 2 units for time_unit_1 in TIME_UNITS: for time_unit_2 in TIME_UNITS: if time_unit_1 == time_unit_2: continue if random() < 0.5: continue shift_1 = randint(2, 4) shift_2 = randint(2, 4) singular_time_unit_1 = (f"a" if time_unit_1 != "hour" else "an") + f" {time_unit_1}" singular_time_unit_2 = (f"a" if time_unit_2 != "hour" else "an") + f" {time_unit_2}" plural_time_unit_1 = f"{shift_1} {time_unit_1}s" plural_time_unit_2 = f"{shift_2} {time_unit_2}s" expressions = {} for fmt in ["{0} and {1}", "{0}, {1}", "{0} {1}"]: expressions[ fmt.format(plural_time_unit_1, plural_time_unit_2) + " ago"] = (True, True) expressions["in " + fmt.format( plural_time_unit_1, plural_time_unit_2)] = (True, True) expressions[fmt.format(plural_time_unit_1, singular_time_unit_2) + " ago"] = (True, False) expressions["in " + fmt.format(plural_time_unit_1, singular_time_unit_2)] = (True, False) expressions[fmt.format(singular_time_unit_1, plural_time_unit_2) + " ago"] = (False, True) expressions["in " + fmt.format(singular_time_unit_1, plural_time_unit_2)] = (False, True) expressions[fmt.format(singular_time_unit_1, singular_time_unit_2) + " ago"] = (False, False) expressions["in " + fmt.format(singular_time_unit_1, singular_time_unit_2)] = (False, False) for human_expression, quantity_tuple in expressions.items( ): shift_kwargs = {} sign = 1 if human_expression.startswith("in ") else -1 if quantity_tuple[0]: shift_kwargs[time_unit_1 + 's'] = shift_1 * sign else: shift_kwargs[time_unit_1 + 's'] = 1 * sign if quantity_tuple[1]: shift_kwargs[time_unit_2 + 's'] = shift_2 * sign else: shift_kwargs[time_unit_2 + 's'] = 1 * sign now = XArrow.now() dehumanized_instance_vanilla = Arrow.now().dehumanize( human_expression) dehumanized_instance_vanilla.microsecond = 0 dehumanized_static = XArrow.dehumanize( human_expression) now_shifted = now.shift(**shift_kwargs) dehumanized_instance = now.dehumanize(human_expression) try: assert_arrows_soft_eq(dehumanized_instance, now_shifted) assert_arrows_soft_eq(dehumanized_static, now_shifted) assert_arrows_soft_eq( dehumanized_instance, dehumanized_instance_vanilla) assert_arrows_soft_eq( dehumanized_static, dehumanized_instance_vanilla) except AssertionError: now = XArrow.now() dehumanized_instance = now.dehumanize( human_expression) now_shifted = now.shift(**shift_kwargs) assert_arrows_soft_eq(dehumanized_instance, now_shifted) dehumanized_static = XArrow.dehumanize( human_expression) assert_arrows_soft_eq(dehumanized_static, now_shifted) dehumanized_instance_vanilla = Arrow.now( ).dehumanize(human_expression) assert_arrows_soft_eq( dehumanized_instance, dehumanized_instance_vanilla) assert_arrows_soft_eq( dehumanized_static, dehumanized_instance_vanilla) # * 3 units for time_unit_3 in TIME_UNITS: if time_unit_3 == time_unit_1 or time_unit_3 == time_unit_2: continue if random() < 0.75: continue shift_3 = randint(2, 4) singular_time_unit_3 = (f"a" if time_unit_3 != "hour" else "an") + f" {time_unit_3}" plural_time_unit_3 = f"{shift_3} {time_unit_3}s" expressions = {} for fmt in [ "{0} and {1} and {2}", "{0} and {1}, {2}", "{0} and {1} {2}", "{0}, {1}, {2}", "{0}, {1} and {2}", "{0}, {1} {2}", "{0} {1} {2}", "{0} {1}, {2}", "{0} {1} and {2}", ]: for q1, q2, q3 in product(["plural", "singular"], ["plural", "singular"], ["plural", "singular"]): past_human_expression = eval( f"fmt.format({q1}_time_unit_1, {q2}_time_unit_2, {q3}_time_unit_3) + ' ago'" ) future_human_expression = eval( f"'in ' + fmt.format({q1}_time_unit_1, {q2}_time_unit_2, {q3}_time_unit_3)" ) quantity_tuple = (q1 == "plural", q2 == "plural", q3 == "plural") expressions[ past_human_expression] = quantity_tuple expressions[ future_human_expression] = quantity_tuple for human_expression, quantity_tuple in expressions.items( ): shift_kwargs = {} sign = 1 if human_expression.startswith( "in ") else -1 if quantity_tuple[0]: shift_kwargs[time_unit_1 + 's'] = shift_1 * sign else: shift_kwargs[time_unit_1 + 's'] = 1 * sign if quantity_tuple[1]: shift_kwargs[time_unit_2 + 's'] = shift_2 * sign else: shift_kwargs[time_unit_2 + 's'] = 1 * sign if quantity_tuple[2]: shift_kwargs[time_unit_3 + 's'] = shift_3 * sign else: shift_kwargs[time_unit_3 + 's'] = 1 * sign now = XArrow.now() dehumanized_instance_vanilla = Arrow.now( ).dehumanize(human_expression) dehumanized_static = XArrow.dehumanize( human_expression) now_shifted = now.shift(**shift_kwargs) dehumanized_instance = now.dehumanize( human_expression) try: assert_arrows_soft_eq(dehumanized_instance, now_shifted) assert_arrows_soft_eq(dehumanized_static, now_shifted) assert_arrows_soft_eq( dehumanized_instance, dehumanized_instance_vanilla) assert_arrows_soft_eq( dehumanized_static, dehumanized_instance_vanilla) except AssertionError: now = XArrow.now() dehumanized_instance = now.dehumanize( human_expression) now_shifted = now.shift(**shift_kwargs) assert_arrows_soft_eq(dehumanized_instance, now_shifted) dehumanized_static = XArrow.dehumanize( human_expression) assert_arrows_soft_eq(dehumanized_static, now_shifted) dehumanized_instance_vanilla = Arrow.now( ).dehumanize(human_expression) assert_arrows_soft_eq( dehumanized_instance, dehumanized_instance_vanilla) assert_arrows_soft_eq( dehumanized_static, dehumanized_instance_vanilla)
def test_sanity(self, work=None): log.title(f"test_sanity({work = })") if not work: work = default_work(TEST_START_ARROW) log.debug('work (Work)') assert isinstance(work, Work) assert work assert len(work) == 1 assert TEST_START_ARROW.DDMMYY in work log.debug('Work["30/12/99"] -> Day') day: Day = work[TEST_START_ARROW.DDMMYY] assert isinstance(day, Day) assert day assert len(day) == 1 assert "Got to office" in day log.debug('Day["Got to office"] -> Activity (ongoing)') got_to_office_activity: Activity = day["Got to office"] assert isinstance(got_to_office_activity, Activity) assert got_to_office_activity assert len(got_to_office_activity) == 1 assert isinstance(got_to_office_activity.name, Colored) got_to_office_activity_is_ongoing = got_to_office_activity.ongoing( ) assert got_to_office_activity_is_ongoing is True assert got_to_office_activity.name == "Got to office" log.debug( 'Day["On Device Validation"] -> Activity (not ongoing)') device_validation_activity: Activity = day[ "On Device Validation"] assert got_to_office_activity.name == "Got to office" assert isinstance(device_validation_activity, Activity) assert device_validation_activity.name == "On Device Validation" assert not device_validation_activity assert len(device_validation_activity) == 0 assert isinstance(device_validation_activity.name, Colored) device_validation_activity_is_ongoing = device_validation_activity.ongoing( ) assert device_validation_activity_is_ongoing is False log.debug('Work.ongoing_activity() -> Activity') ongoing_activity: Activity = work.ongoing_activity() assert ongoing_activity assert isinstance(ongoing_activity, Activity) assert ongoing_activity.name == "Got to office" assert isinstance(ongoing_activity.name, Colored) assert len(ongoing_activity) == 1 assert ongoing_activity.ongoing() is True assert ongoing_activity != device_validation_activity assert ongoing_activity == got_to_office_activity assert ongoing_activity is ongoing_activity assert got_to_office_activity is got_to_office_activity assert ongoing_activity is got_to_office_activity assert device_validation_activity.name == "On Device Validation" assert ongoing_activity.name == "Got to office" ongoing_activity_copy = work.ongoing_activity() assert ongoing_activity_copy is ongoing_activity log.debug('Activity.stop() -> Entry') got_to_office_last_entry: Entry = ongoing_activity.stop() assert isinstance(got_to_office_last_entry, Entry) assert got_to_office_last_entry assert got_to_office_last_entry.end assert ongoing_activity.ongoing() is False log.debug('Activity.stop() -> ValueError (not ongoing)') with assert_raises( ValueError, match=f"{ongoing_activity!r} is not ongoing"): ongoing_activity.stop() log.debug( 'Work.ongoing_activity() -> ValueError (no ongoing activity)' ) with assert_raises(ValueError, match="No ongoing activity"): work.ongoing_activity() log.debug('Work.on("Something New") -> Activity') something_new_activity: Activity = work.on("Something New") assert isinstance(something_new_activity, Activity) assert something_new_activity assert len(something_new_activity) == 1 assert something_new_activity.name == "Something New" something_new_activity_is_ongoing = something_new_activity.ongoing( ) assert something_new_activity_is_ongoing is True assert device_validation_activity.name == "On Device Validation" assert ongoing_activity.name == "Got to office" assert device_validation_activity.ongoing() is False assert ongoing_activity.ongoing() is False log.debug('Activity.start() -> ValueError (already ongoing)') with assert_raises( ValueError, match=f"{something_new_activity!r} is already ongoing" ): something_new_activity.start() log.debug( 'Work.on("Something New") -> ValueError (already ongoing)') with assert_raises( ValueError, match=f"{something_new_activity!r} is already ongoing" ): work.on(something_new_activity.name) log.debug('Work.on("Something New2") -> Activity') something_new2_activity: Activity = work.on("Something New2") assert isinstance(something_new2_activity, Activity) assert something_new2_activity assert len(something_new2_activity) == 1 assert something_new2_activity.name == "Something New2" assert something_new2_activity.ongoing() is True assert device_validation_activity.name == "On Device Validation" assert ongoing_activity.name == "Got to office" assert device_validation_activity.ongoing() is False assert ongoing_activity.ongoing() is False assert something_new_activity.ongoing() is False log.debug( 'Work.on("something-new 2") -> ValueError (has similar name)' ) assert something_new2_activity.has_similar_name( "something-new 2") is True with assert_raises( ValueError, match= f"{something_new2_activity!r} is ongoing, and has a similar name to 'something-new 2" ): work.on("something-new 2") log.debug('Work.stop() -> Optional[Activity]') stop_time = XArrow.now() stopped_activity: Activity = work.stop(stop_time) assert stopped_activity.name == "Something New2" assert stopped_activity[-1].end == stop_time assert stopped_activity.ongoing() is False with assert_raises(ValueError, match=f"No ongoing activity"): work.ongoing_activity() with assert_raises(ValueError, match=f"No ongoing activity"): work.stop()