Skip to content

Commit 65239d9

Browse files
committed
refs #278 Unit Test example for ProgressAnimate
Not perfect yet, but shows the basic concepts of testing for both no failures and expected failures. I tried to fix things in ProgressAnimate as I went along so that hopefully you can see the correlation between what was being tested, and the fixes that went in to pass the tests. If you haven't used pytest before, there's a few things to do: - pip install pytest - make sure pysimplesql is reachable as a module. The easiest way is to do a local installation by running `pip -e .` in the pysimplesql root directory - from the commandline, run `pytest` to run all tests. Or you can run tests for a specific file, I.e. `pytest progressanimate_test.py`
1 parent 1666feb commit 65239d9

File tree

2 files changed

+73
-14
lines changed

2 files changed

+73
-14
lines changed

pysimplesql/pysimplesql.py

+24-14
Original file line numberDiff line numberDiff line change
@@ -3917,6 +3917,29 @@ def __init__(self, title: str, config: dict = None):
39173917
:param config: Dictionary of configuration options as listed above
39183918
:returns: None
39193919
"""
3920+
default_config = {
3921+
# oscillators for the bar divider and colors
3922+
"bar": {"value_start": 0, "value_range": 100, "period": 3, "offset": 0},
3923+
"red": {"value_start": 0, "value_range": 255, "period": 2, "offset": 0},
3924+
"green": {"value_start": 0, "value_range": 255, "period": 3, "offset": 120},
3925+
"blue": {"value_start": 0, "value_range": 255, "period": 4, "offset": 240},
3926+
# phrases to display and the number of seconds to elapse between phrases
3927+
"phrases": lang.animate_phrases,
3928+
"phrase_delay": 5,
3929+
}
3930+
if config is None:
3931+
config = {}
3932+
3933+
if type(config) is not dict:
3934+
raise ValueError("config must be a dictionary")
3935+
3936+
if set(config.keys()) - set(default_config.keys()):
3937+
raise NotImplementedError(
3938+
f"config may only contain keys: {default_config.keys()}"
3939+
)
3940+
3941+
self.config = {**default_config, **config}
3942+
39203943
self.title = title
39213944
self.win: sg.Window = None
39223945
self.layout = [
@@ -3935,20 +3958,6 @@ def __init__(self, title: str, config: dict = None):
39353958
self.phrase_index = 0
39363959
self.completed = asyncio.Event()
39373960

3938-
default_config = {
3939-
# oscillators for the bar divider and colors
3940-
"bar": {"value_start": 0, "value_range": 100, "period": 3, "offset": 0},
3941-
"red": {"value_start": 0, "value_range": 255, "period": 2, "offset": 0},
3942-
"green": {"value_start": 0, "value_range": 255, "period": 3, "offset": 120},
3943-
"blue": {"value_start": 0, "value_range": 255, "period": 4, "offset": 240},
3944-
# phrases to display and the number of seconds to elapse between phrases
3945-
"phrases": lang.animate_phrases,
3946-
"phrase_delay": 5,
3947-
}
3948-
if config is None:
3949-
config = {}
3950-
self.config = {**default_config, **config}
3951-
39523961
def run(self, fn: callable, *args, **kwargs):
39533962
"""
39543963
Runs the function in a separate co-routine, while animating the progress bar in
@@ -3985,6 +3994,7 @@ async def run_process(self, fn: callable, *args, **kwargs):
39853994
return result
39863995
except Exception as e: # noqa: BLE001
39873996
print(f"\nAn error occurred in the process: {e}")
3997+
raise e # Pass the exception along to the caller
39883998
finally:
39893999
self.completed.set()
39904000

tests/progressanimate_test.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from time import sleep
2+
3+
import pytest
4+
5+
import pysimplesql as ss
6+
7+
8+
# Simulated process
9+
def process(raise_error=False):
10+
if raise_error:
11+
raise ValueError("Oops! This process had an error!")
12+
sleep(5)
13+
14+
15+
def test_successful_process():
16+
try:
17+
sa = ss.ProgressAnimate("Test ProgressAnimate")
18+
sa.run(process, False)
19+
except Exception as e:
20+
assert False, f"An exception was raised: {e}"
21+
22+
23+
def test_exception_during_process():
24+
with pytest.raises(Exception):
25+
sa = ss.ProgressAnimate("Test ProgressAnimate")
26+
v = sa.run(process, True)
27+
print(v, type(v))
28+
29+
30+
def test_config():
31+
# What if config was set with an int?
32+
with pytest.raises(ValueError):
33+
ss.ProgressAnimate("Test", config=1)
34+
# What if config was set with a string
35+
with pytest.raises(ValueError):
36+
ss.ProgressAnimate("Test", config="My Config")
37+
# What if config was set with a list?
38+
with pytest.raises(ValueError):
39+
ss.ProgressAnimate("Test", config=["red"])
40+
# What if config was set with a bool?
41+
with pytest.raises(ValueError):
42+
ss.ProgressAnimate("Test", config=True)
43+
# What if the user does supply a dict, but it doesn't have the right keys?
44+
with pytest.raises(NotImplementedError):
45+
# Purposely fail by
46+
config = {
47+
"sound_effect": "beep",
48+
}
49+
ss.ProgressAnimate("Test", config=config)

0 commit comments

Comments
 (0)