Skip to content

Commit 114acf6

Browse files
committed
add tests and fix cov
1 parent 39565b9 commit 114acf6

File tree

4 files changed

+67
-7
lines changed

4 files changed

+67
-7
lines changed

src/idom/_option.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,27 @@ def __init__(
1414
self,
1515
name: str,
1616
default: _O,
17-
allow_changes: bool = True,
17+
immutable: bool = False,
1818
validator: Callable[[Any], _O] = lambda x: cast(_O, x),
1919
) -> None:
2020
self.name = name
2121
self._default = default
22-
self._allow_changes = allow_changes
22+
self._immutable = immutable
2323
self._validator = validator
2424
self._value = validator(os.environ.get(name, default))
2525

2626
def get(self) -> _O:
2727
return self._value
2828

2929
def set(self, new: _O) -> _O:
30-
if not self._allow_changes:
31-
raise ValueError(f"{self.name} cannot be modified.")
30+
if self._immutable:
31+
raise TypeError(f"{self} cannot be modified after initial load.")
3232
old = self._value
3333
self._value = self._validator(new)
3434
return old
3535

3636
def reset(self) -> _O:
3737
return self.set(self._default)
38+
39+
def __repr__(self) -> str:
40+
return f"Option(name={self.name!r}, value={self._value!r})"

src/idom/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
IDOM_DEBUG_MODE = _option.Option(
77
"IDOM_DEBUG_MODE",
88
default=False,
9-
allow_changes=False,
9+
immutable=True,
1010
validator=lambda x: bool(int(x)),
1111
)
1212
"""Turn on/off debug mode"""

src/idom/server/flask.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ def run_send() -> None:
241241
if value is None:
242242
stop.set()
243243
break
244-
dispatch_thread_info.dispatch_loop.call_soon_threadsafe(
244+
# BUG: https://github.com/nedbat/coveragepy/issues/1012
245+
# Coverage isn't able to support concurrency coverage for both threading and gevent
246+
dispatch_thread_info.dispatch_loop.call_soon_threadsafe( # pragma: no cover
245247
dispatch_thread_info.async_recv_queue.put_nowait, value
246248
)
247249
finally:
@@ -273,7 +275,8 @@ def update_environ(self) -> None:
273275
This includes getting the correct server name and port.
274276
"""
275277
super().update_environ()
276-
# BUG: for some reason coverage doesn't seem to think this line is covered
278+
# BUG: https://github.com/nedbat/coveragepy/issues/1012
279+
# Coverage isn't able to support concurrency coverage for both threading and gevent
277280
self._before_first_request_callback() # pragma: no cover
278281

279282

tests/test__option.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import os
2+
from unittest import mock
3+
4+
import pytest
5+
6+
from idom._option import Option
7+
8+
9+
def test_option_repr():
10+
opt = Option("A_FAKE_OPTION", "some-value")
11+
assert repr(opt) == "Option(name='A_FAKE_OPTION', value='some-value')"
12+
13+
14+
@mock.patch.dict(os.environ, {"A_FAKE_OPTION": "value-from-environ"})
15+
def test_option_from_os_environ():
16+
opt = Option("A_FAKE_OPTION", "default-value")
17+
assert opt.get() == "value-from-environ"
18+
19+
20+
def test_option_from_default():
21+
opt = Option("A_FAKE_OPTION", "default-value")
22+
assert opt.get() == "default-value"
23+
24+
25+
@mock.patch.dict(os.environ, {"A_FAKE_OPTION": "1"})
26+
def test_option_validator():
27+
opt = Option("A_FAKE_OPTION", False, validator=lambda x: bool(int(x)))
28+
29+
assert opt.get() is True
30+
31+
opt.set("0")
32+
assert opt.get() is False
33+
34+
with pytest.raises(ValueError, match="invalid literal for int"):
35+
opt.set("not-an-int")
36+
37+
38+
def test_immutable_option():
39+
opt = Option("A_FAKE_OPTION", "default-value", immutable=True)
40+
with pytest.raises(TypeError, match="cannot be modified after initial load"):
41+
opt.set("a-new-value")
42+
43+
44+
def test_option_reset():
45+
opt = Option("A_FAKE_OPTION", "default-value")
46+
opt.set("a-new-value")
47+
assert opt.get() == "a-new-value"
48+
opt.reset()
49+
assert opt.get() == "default-value"
50+
51+
52+
def test_option_set_returns_last_value():
53+
opt = Option("A_FAKE_OPTION", "default-value")
54+
assert opt.set("a-new-value") == "default-value"

0 commit comments

Comments
 (0)