add tests because of feedback

This commit is contained in:
DomNomNomVR 2025-03-09 23:27:45 +13:00
parent 488d1e8bff
commit 171c1fae66
3 changed files with 93 additions and 4 deletions

View File

@ -1,4 +1,4 @@
from typing import Any, Hashable, TypeVar, Callable
from typing import Any, Hashable, Optional, TypeVar, Callable
from gears.effect import effect_of
from gears.gear import Gear
@ -8,6 +8,8 @@ def connect[S: Hashable, T: Hashable](
source: Gear[S],
to_target_val: Callable[[S], T],
to_source: Callable[[S, T], S],
# i_know_what_im_doing: Optional[bool] = None,
i_know_what_im_doing: Optional[bool] = True,
) -> Gear[T]:
target = Gear(to_target_val(source()))
@ -20,7 +22,10 @@ def connect[S: Hashable, T: Hashable](
def set_target_val(source_val: S):
nonlocal entry_guard
if entry_guard:
if i_know_what_im_doing:
return
else:
raise ValueError("You have a bad bidirectional mapping")
entry_guard = True
try:
target.set(to_target_val(source_val))
@ -31,7 +36,10 @@ def connect[S: Hashable, T: Hashable](
def set_source_val(target_val: T):
nonlocal entry_guard
if entry_guard:
if i_know_what_im_doing:
return
else:
raise ValueError("You have a bad bidirectional mapping")
entry_guard = True
try:
source.set(to_source(source(), target_val))

View File

@ -5,6 +5,7 @@ class Gear[T: Hashable]:
def __init__(self, value: T):
self._value = value
self.effects = []
self.connection_effects = []
def get(self) -> T:
return self._value
@ -13,8 +14,11 @@ class Gear[T: Hashable]:
return self.get()
def set(self, value: T):
print("setty: ", value)
if value == self._value:
return
self._value = value
for effect in self.connection_effects:
effect.on_change(value)
for effect in self.effects:
effect.on_change(value)

View File

@ -1,9 +1,11 @@
from dataclasses import dataclass
from typing import NamedTuple
from unittest.mock import MagicMock
import pytest
from gears import Gear
from gears.connections import connect
from gears.effect import effect_of, effect_of_2
from gears.effect import Effect, effect_of, effect_of_2
def test_get_set():
@ -28,6 +30,9 @@ def test_basic_effect():
assert last_arg == "E"
g.set("hello")
assert last_arg == "hello"
def test_effect_of_2():
g1 = Gear("E")
@ -54,15 +59,87 @@ def test_connect():
assert my_str() == "321"
# def test_dualis():
# val_both: Gear[tuple[int, int]] = Gear((5, 6))
# val0 = connect(val_both, lambda both: both[0], lambda both, val0: (val0, both[1]))
# val1 = connect(val_both, lambda both: both[1], lambda both, val1: (both[0], val1))
def test_watts():
volts = Gear(3.0)
amps = Gear(5.0)
@effect_of_2(volts, amps)
def on_watts_changed(volts: float, amps: float):
watts = volts * amps
if watts > 100:
raise ValueError("OMG ITS BURNING")
volts.set(5.0)
with pytest.raises(ValueError):
volts.set(50.0)
def test_led():
battery_voltage = Gear(3.0)
switch: Gear[bool] = Gear(True) # true means circuit closed
# ohms_circuit = Gear(1.0)
ohms_circuit = connect(
switch, lambda x: 1.0 if x else 100000000.0, lambda _, y: y < 100
)
log: list[str] = []
@effect_of_2(battery_voltage, ohms_circuit)
def on_led_inputs_changed(volts: float, ohms: float):
amps = volts / ohms
if amps > 1:
print("LED ACTIVE!")
log.append("LED ACTIVE!")
else:
print("LED INACTIVE!")
log.append("LED INACTIVE!")
# Effect(on_led_inputs_changed, battery_voltage, led_ohms)
assert log == ["LED ACTIVE!"]
switch.set(False)
assert log == ["LED ACTIVE!", "LED INACTIVE!"]
def test_connect_multiplication():
mul1 = Gear(10.0)
mul2 = connect(mul1, lambda x: x * 2.0, lambda _, y: y / 2.0)
mul4 = connect(mul2, lambda x: x * 2.0, lambda _, y: y / 2.0)
mul3 = connect(mul1, lambda x: x * 3.0, lambda _, y: y / 3.0)
assert mul2() == 20
assert mul3() == 30
mul2.set(30)
assert mul1() == 15
assert mul3() == 45
assert mul4() == 60
# mul1
# |> mul2
# |> mul4
# |> mul3
#
class Person:
name: str
class HouseHold:
people: list[Person]
class NameEntry:
def __init__(self, name: Gear[str]):
# self.name = name
textBox = TextBox(...)
effect_of(name)(textBox.setValue)
textBox.onChange = name.set
def test_connect_property():