mirror of
https://github.com/kuhyx/screen-locker.git
synced 2026-11-10 19:07:16 +01:00
tests: earned_time 0.7.0 tutor policy (confirmed, 15 min per block); hook envs on 0.7.0
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (flutter, flutter-analyze, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint,flutter-analyze) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / lock-popup-safety (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (0) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (1) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (2) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (3) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (4) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (5) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (6) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (7) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (8) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (9) (push) Waiting to run
Tests / flutter-coverage (push) Blocked by required conditions
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (flutter, flutter-analyze, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint,flutter-analyze) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / lock-popup-safety (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (0) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (1) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (2) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (3) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (4) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (5) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (6) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (7) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (8) (push) Waiting to run
Tests / flutter test (shard ${{ matrix.shard }}) (9) (push) Waiting to run
Tests / flutter-coverage (push) Blocked by required conditions
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
41ce020e10
commit
384ffcda7d
@ -134,7 +134,7 @@ repos:
|
||||
# than merely an old one.
|
||||
- gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.9.0#subdirectory=gatelock
|
||||
- crdt-sync @ git+https://github.com/kuhyx/utils@crdt-sync-v0.9.2#subdirectory=crdt-sync
|
||||
- earned-time @ git+https://github.com/kuhyx/utils@earned-time-v0.6.1#subdirectory=earned_time
|
||||
- earned-time @ git+https://github.com/kuhyx/utils@earned-time-v0.7.0#subdirectory=earned_time
|
||||
- freedays @ git+https://github.com/kuhyx/utils@freedays-v0.3.1#subdirectory=freedays
|
||||
- mcp>=2,<3
|
||||
- pydantic
|
||||
@ -155,7 +155,7 @@ repos:
|
||||
# than merely an old one.
|
||||
- gatelock @ git+https://github.com/kuhyx/utils@gatelock-v0.9.0#subdirectory=gatelock
|
||||
- crdt-sync @ git+https://github.com/kuhyx/utils@crdt-sync-v0.9.2#subdirectory=crdt-sync
|
||||
- earned-time @ git+https://github.com/kuhyx/utils@earned-time-v0.6.1#subdirectory=earned_time
|
||||
- earned-time @ git+https://github.com/kuhyx/utils@earned-time-v0.7.0#subdirectory=earned_time
|
||||
- freedays @ git+https://github.com/kuhyx/utils@freedays-v0.3.1#subdirectory=freedays
|
||||
- mcp>=2,<3
|
||||
- pydantic
|
||||
|
||||
@ -5,7 +5,7 @@ A flat earner (LeetCode, reading) pays once a day, stamped
|
||||
signed ledger row per verified 15-minute block -- pays per unit, so its stamp
|
||||
is ``<name>_bonus_units``: the day, and how many units the config already
|
||||
holds. The live pass pays only the difference, priced by
|
||||
``Earner.shutdown_for`` so the uneven rung split (13/13/12/12) and the
|
||||
``Earner.shutdown_for`` so the rung's per-unit split (15 per tutor block) and the
|
||||
``max_units`` cap come from the registry, never from here.
|
||||
|
||||
The workout is counted too, but screen-locker owns its log and
|
||||
|
||||
@ -210,8 +210,8 @@ class TestThroughTheShutdownBase:
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("key")
|
||||
def test_the_real_tutor_rung_pays_13_13_12_12_then_nothing() -> None:
|
||||
"""The registry's uneven split, through this pass, on the cutover day."""
|
||||
def test_the_real_tutor_rung_pays_15_per_block_then_nothing() -> None:
|
||||
"""The registry's per-block rung (earned_time 0.7.0), through this pass."""
|
||||
tutor = getattr(earned_time, "AUTOMATION_TUTOR", None)
|
||||
if tutor is None:
|
||||
pytest.skip("installed earned_time predates the tutor (< 0.5)")
|
||||
@ -233,5 +233,5 @@ def test_the_real_tutor_rung_pays_13_13_12_12_then_nothing() -> None:
|
||||
)
|
||||
write_ledger(tutor, rows)
|
||||
apply_counted_bonus(state, adjust, tutor, cutover)
|
||||
assert [c.args[0] for c in adjust.call_args_list] == [13, 13, 12, 12]
|
||||
assert [c.args[0] for c in adjust.call_args_list] == [15, 15, 15, 15]
|
||||
assert state["automation_bonus_units"] == {"date": cutover, "units": 5}
|
||||
|
||||
@ -120,9 +120,10 @@ class TestResetIncludesReading:
|
||||
apply_flat_bonuses_if_new(state, mixin)
|
||||
mixin._adjust_shutdown_time_by.assert_not_called()
|
||||
|
||||
def test_reset_is_still_capped_at_the_ceiling(
|
||||
def test_reset_without_the_tutor_stops_an_hour_below_the_ceiling(
|
||||
self, tmp_path: Path, answers: tuple[dict[str, bool | None], MagicMock]
|
||||
) -> None:
|
||||
"""Nine workouts still pay one rung; the confirmed tutor's 60 is unpaid."""
|
||||
answers[0]["leetcode"] = True
|
||||
answers[0]["reading"] = True
|
||||
mixin = _mixin()
|
||||
@ -131,7 +132,7 @@ class TestResetIncludesReading:
|
||||
tmp_path / "state.json", mixin, log_file=tmp_path / "log.json"
|
||||
)
|
||||
mixin._write_shutdown_config.assert_called_once_with(
|
||||
1380, 1380, 300, restore=True
|
||||
1320, 1320, 300, restore=True
|
||||
)
|
||||
|
||||
def test_unknown_reading_earns_nothing_warns_and_is_not_stamped(
|
||||
|
||||
@ -76,42 +76,39 @@ def test_the_simulated_cutover_registers_the_tutor(tutor: Any) -> None:
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("tutor")
|
||||
class TestNeverCredited:
|
||||
"""A tutor that never paid out is not penalised once first_credits is wired."""
|
||||
class TestConfirmedButNeverCredited:
|
||||
"""earned_time 0.7.0: a confirmed tutor is penalised from its first day."""
|
||||
|
||||
def test_the_map_says_never(self) -> None:
|
||||
starts = first_credits(registry(_CUTOVER), _CUTOVER)
|
||||
assert starts is not None
|
||||
assert starts["automation"] is None
|
||||
|
||||
def test_no_tutor_penalty_on_the_gaming_base(self) -> None:
|
||||
def test_the_tutor_penalty_is_on_the_gaming_base_unpaid(self) -> None:
|
||||
answers = {e.name: 0 for e in registry(_CUTOVER)}
|
||||
starts = first_credits(registry(_CUTOVER), _CUTOVER)
|
||||
wired = derive(DayInputs(_CUTOVER, answers, first_credits=starts))
|
||||
unwired = derive(DayInputs(_CUTOVER, answers))
|
||||
cut = earned_time.AUTOMATION_TUTOR.max_gaming_minutes
|
||||
assert wired.resolution.base.gaming_minutes == (
|
||||
unwired.resolution.base.gaming_minutes + cut
|
||||
unwired.resolution.base.gaming_minutes
|
||||
)
|
||||
|
||||
def test_no_tutor_rung_off_the_shutdown_floor(self) -> None:
|
||||
"""earned_time 0.6.1: a gate whose penalty has not started spares the floor.
|
||||
def test_the_whole_tutor_rung_comes_off_the_shutdown_floor(self) -> None:
|
||||
"""Confirmed on 2026-10-09, so a never-paid tutor still costs its rung.
|
||||
|
||||
Unwired, the tutor's penalty starts at ``penalty_from`` and its full
|
||||
rung (13+13+12+12) comes off the ladder floor; wired, the never-paid
|
||||
tutor costs no shutdown either, so the floor stays at 19:50.
|
||||
Its full rung (4 blocks of 15) comes off the ladder floor whether or
|
||||
not ``first_credits`` is wired, leaving 18:50.
|
||||
"""
|
||||
answers = {e.name: 0 for e in registry(_CUTOVER)}
|
||||
starts = first_credits(registry(_CUTOVER), _CUTOVER)
|
||||
wired = derive(DayInputs(_CUTOVER, answers, first_credits=starts))
|
||||
unwired = derive(DayInputs(_CUTOVER, answers))
|
||||
tutor = earned_time.AUTOMATION_TUTOR
|
||||
rung = tutor.shutdown_for(tutor.max_units or 1, _CUTOVER)
|
||||
assert rung == 50
|
||||
assert tutor.shutdown_for(tutor.max_units or 1, _CUTOVER) == 60
|
||||
assert wired.resolution.base.shutdown_minutes == (
|
||||
unwired.resolution.base.shutdown_minutes + rung
|
||||
unwired.resolution.base.shutdown_minutes
|
||||
)
|
||||
assert wired.resolution.base.shutdown_minutes == 19 * 60 + 50
|
||||
assert wired.resolution.base.shutdown_minutes == 18 * 60 + 50
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("tutor")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user