Skip to content

Commit a725ccb

Browse files
cmccandlessyawpitch
authored andcommitted
high-scores: add test template (exercism#1866)
* high-scores: add test template * add missing exception assignment * skip `scores` tests
1 parent 0734968 commit a725ccb

3 files changed

Lines changed: 61 additions & 12 deletions

File tree

bin/generate_tests.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ def camel_case(string):
6363
return ''.join(w.title() for w in to_snake(string).split('_'))
6464

6565

66+
def get_tested_properties(spec):
67+
"""
68+
Get set of tested properties from spec. Include nested cases.
69+
"""
70+
props = set()
71+
for case in spec["cases"]:
72+
if "property" in case:
73+
props.add(case["property"])
74+
if "cases" in case:
75+
props.update(get_tested_properties(case))
76+
return sorted(props)
77+
78+
6679
def load_canonical(exercise, spec_path):
6780
"""
6881
Loads the canonical data for an exercise as a nested dictionary
@@ -71,7 +84,9 @@ def load_canonical(exercise, spec_path):
7184
spec_path, 'exercises', exercise, 'canonical-data.json'
7285
)
7386
with open(full_path) as f:
74-
return json.load(f)
87+
spec = json.load(f)
88+
spec["properties"] = get_tested_properties(spec)
89+
return spec
7590

7691

7792
def format_file(path):
@@ -121,9 +136,11 @@ def generate_exercise(env, spec_path, exercise, check=False):
121136
else:
122137
shutil.move(tmp.name, tests_path)
123138
print(f'{slug} generated at {tests_path}')
124-
except TemplateNotFound:
139+
except TemplateNotFound as e:
140+
logger.debug(str(e))
125141
logger.info(f'{slug}: no template found; skipping')
126-
except FileNotFoundError:
142+
except FileNotFoundError as e:
143+
logger.debug(str(e))
127144
logger.info(f'{slug}: no canonical data found; skipping')
128145

129146

@@ -155,5 +172,5 @@ def generate(exercise_glob, spec_path=DEFAULT_SPEC_LOCATION, check=False, **kwar
155172
parser.add_argument('--check', action='store_true')
156173
opts = parser.parse_args()
157174
if opts.verbose:
158-
logger.setLevel(logging.INFO)
175+
logger.setLevel(logging.DEBUG)
159176
generate(**opts.__dict__)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{%- macro testcase(case) %}
2+
def test_{{ case["description"] | to_snake }}(self):
3+
scores = {{ case["input"]["scores"] }}
4+
expected = {{ case["expected"] }}
5+
self.assertEqual({{ case["property"] | to_snake }}(scores), expected)
6+
{% endmacro -%}
7+
import unittest
8+
9+
from {{ exercise | to_snake }} import (
10+
{%- for prop in properties %}
11+
{%- if prop != "scores" %}
12+
{{ prop | to_snake }},
13+
{% endif -%}
14+
{%- endfor %}
15+
)
16+
17+
# Tests adapted from `problem-specifications//canonical-data.json` @ v{{ version }}
18+
19+
class {{ exercise | camel_case }}Test(unittest.TestCase):
20+
{%- for case in cases -%}
21+
{%- if "cases" in case -%}
22+
{%- for subcase in case["cases"] -%}
23+
{{- testcase(subcase) -}}
24+
{% endfor %}
25+
{%- else %}
26+
{%- if case["property"] != "scores" %}
27+
{{- testcase(case) -}}
28+
{% endif -%}
29+
{% endif -%}
30+
{% endfor %}
31+
32+
33+
if __name__ == '__main__':
34+
unittest.main()

exercises/high-scores/high_scores_test.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
from high_scores import latest, personal_best, personal_top_three
44

5-
65
# Tests adapted from `problem-specifications//canonical-data.json` @ v4.0.0
76

87

9-
class HighScoreTest(unittest.TestCase):
10-
8+
class HighScoresTest(unittest.TestCase):
119
def test_latest_score(self):
1210
scores = [100, 0, 90, 30]
1311
expected = 30
@@ -18,27 +16,27 @@ def test_personal_best(self):
1816
expected = 100
1917
self.assertEqual(personal_best(scores), expected)
2018

21-
def test_personal_top_three_from_a_long_list(self):
19+
def test_personal_top_three_from_a_list_of_scores(self):
2220
scores = [10, 30, 90, 30, 100, 20, 10, 0, 30, 40, 40, 70, 70]
2321
expected = [100, 90, 70]
2422
self.assertEqual(personal_top_three(scores), expected)
2523

26-
def test_personal_top_three_highest_to_lowest(self):
24+
def test_personal_top_highest_to_lowest(self):
2725
scores = [20, 10, 30]
2826
expected = [30, 20, 10]
2927
self.assertEqual(personal_top_three(scores), expected)
3028

31-
def test_personal_top_three_when_there_is_a_tie(self):
29+
def test_personal_top_when_there_is_a_tie(self):
3230
scores = [40, 20, 40, 30]
3331
expected = [40, 40, 30]
3432
self.assertEqual(personal_top_three(scores), expected)
3533

36-
def test_personal_top_three_when_there_are_less_than_3(self):
34+
def test_personal_top_when_there_are_less_than_3(self):
3735
scores = [30, 70]
3836
expected = [70, 30]
3937
self.assertEqual(personal_top_three(scores), expected)
4038

41-
def test_personal_top_three_when_there_is_only_one(self):
39+
def test_personal_top_when_there_is_only_one(self):
4240
scores = [40]
4341
expected = [40]
4442
self.assertEqual(personal_top_three(scores), expected)

0 commit comments

Comments
 (0)