Skip to content

Commit ad80181

Browse files
yawpitchcmccandless
andcommitted
Gigasecond template (#2135)
* Add gigasecond test template and generate tests. * Add datetime import. * gigasecond: add test template Adds the gigasecond test template. Addresses most of the concerns on the defunct #2066 submitted by @simonbcodes, however the `strptime` fix suggested by @cmccandless was brittle, as some of the incoming data had time data. We'd _maybe_ want to add a `dateutil` dependency if the canonical data strays in any way from bog standard ISO 8601 dates, but hopefully if that happens the `datetime.fromisoformat` calls here will blow up and let us know. Closes #1950 * gigasecond: generate with dateutil parse Adds a dependency to the generator, but shifts the work off the student. As an added benefit should parse a lot more than fromisoformat would. Must be merged _after_ #2134. * Update requirements-generator.txt Woops! Co-Authored-By: Corey McCandless <[email protected]>
1 parent d3d04fb commit ad80181

File tree

4 files changed

+53
-22
lines changed

4 files changed

+53
-22
lines changed

bin/generate_tests.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from textwrap import wrap
3838

3939
from jinja2 import Environment, FileSystemLoader, TemplateNotFound, UndefinedError
40+
from dateutil.parser import parse
4041

4142
VERSION = "0.2.1"
4243

@@ -81,6 +82,26 @@ def wrap_overlong(string, width=70):
8182
return ["{0!r} \\".format(w) for w in wrap(string, width)]
8283

8384

85+
def parse_datetime(string, strip_module=False):
86+
"""
87+
Parse a (hopefully ISO 8601) datestamp to a datetime object and
88+
return its repr for use in a jinja2 template.
89+
90+
If used the template will need to import the datetime module.
91+
92+
import datetime
93+
94+
However if strip_module is True then the template will need to
95+
import the datetime _class_ instead.
96+
97+
from datetime import datetime
98+
"""
99+
result = repr(parse(string))
100+
if strip_module:
101+
return result.replace("datetime.", "", 1)
102+
return result
103+
104+
84105
def get_tested_properties(spec):
85106
"""
86107
Get set of tested properties from spec. Include nested cases.
@@ -258,6 +279,7 @@ def generate(
258279
env.filters["camel_case"] = camel_case
259280
env.filters["wrap_overlong"] = wrap_overlong
260281
env.filters["regex_replace"] = regex_replace
282+
env.filters["parse_datetime"] = parse_datetime
261283
env.tests["error_case"] = error_case
262284
result = True
263285
for exercise in sorted(glob(os.path.join("exercises", exercise_glob))):
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{%- import "generator_macros.j2" as macros with context -%}
2+
from datetime import datetime
3+
{{ macros.header() }}
4+
5+
class {{ exercise | camel_case }}Test(unittest.TestCase):
6+
{% for supercase in cases -%}
7+
{% for case in supercase["cases"] -%}
8+
{% set input = case["input"]["moment"] | parse_datetime(strip_module=true) -%}
9+
{% set expected = case["expected"] | parse_datetime(strip_module=true) -%}
10+
def test_{{ case["description"] | to_snake }}(self):
11+
self.assertEqual({{ case["property"] }}({{ input }}), {{ expected }})
12+
{% endfor %}
13+
{% endfor %}
14+
15+
{{ macros.footer() }}
Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,37 @@
1-
import unittest
21
from datetime import datetime
2+
import unittest
33

44
from gigasecond import add
55

6-
76
# Tests adapted from `problem-specifications//canonical-data.json` @ v2.0.0
87

8+
99
class GigasecondTest(unittest.TestCase):
1010
def test_date_only_specification_of_time(self):
1111
self.assertEqual(
12-
add(datetime(2011, 4, 25)),
13-
datetime(2043, 1, 1, 1, 46, 40))
12+
add(datetime(2011, 4, 25, 0, 0)), datetime(2043, 1, 1, 1, 46, 40)
13+
)
1414

15-
def test_another_date_only_specification_of_time(self):
15+
def test_second_test_for_date_only_specification_of_time(self):
1616
self.assertEqual(
17-
add(datetime(1977, 6, 13)),
18-
datetime(2009, 2, 19, 1, 46, 40))
17+
add(datetime(1977, 6, 13, 0, 0)), datetime(2009, 2, 19, 1, 46, 40)
18+
)
1919

20-
def test_one_more_date_only_specification_of_time(self):
20+
def test_third_test_for_date_only_specification_of_time(self):
2121
self.assertEqual(
22-
add(datetime(1959, 7, 19)),
23-
datetime(1991, 3, 27, 1, 46, 40))
22+
add(datetime(1959, 7, 19, 0, 0)), datetime(1991, 3, 27, 1, 46, 40)
23+
)
2424

2525
def test_full_time_specified(self):
2626
self.assertEqual(
27-
add(datetime(2015, 1, 24, 22, 0, 0)),
28-
datetime(2046, 10, 2, 23, 46, 40))
27+
add(datetime(2015, 1, 24, 22, 0)), datetime(2046, 10, 2, 23, 46, 40)
28+
)
2929

3030
def test_full_time_with_day_roll_over(self):
3131
self.assertEqual(
32-
add(datetime(2015, 1, 24, 23, 59, 59)),
33-
datetime(2046, 10, 3, 1, 46, 39))
34-
35-
def test_yourself(self):
36-
# customize this to test your birthday and find your gigasecond date:
37-
your_birthday = datetime(1970, 1, 1)
38-
your_gigasecond = datetime(2001, 9, 9, 1, 46, 40)
39-
40-
self.assertEqual(add(your_birthday), your_gigasecond)
32+
add(datetime(2015, 1, 24, 23, 59, 59)), datetime(2046, 10, 3, 1, 46, 39)
33+
)
4134

4235

43-
if __name__ == '__main__':
36+
if __name__ == "__main__":
4437
unittest.main()

requirements-generator.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
black==19.3b0
22
flake8==3.7.8
33
Jinja2==2.10.1
4+
python-dateutil==2.8.1

0 commit comments

Comments
 (0)