add tests because of feedback
This commit is contained in:
parent
488d1e8bff
commit
171c1fae66
@ -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:
|
||||
return
|
||||
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:
|
||||
return
|
||||
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))
|
||||
|
@ -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)
|
||||
|
@ -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():
|
||||
|
Loading…
x
Reference in New Issue
Block a user