Skip to content

Commit e74e92a

Browse files
committed
[TASK] Improve expectation handling
1 parent 233756f commit e74e92a

File tree

8 files changed

+93
-18
lines changed

8 files changed

+93
-18
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ _build/
88
latest.txt
99
next.txt
1010
.idea
11-
11+
challenges.env

challenges/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from challenges.graph import Graph, Node, Edge
2-
from challenges.conf import Conf
31
from challenges.challenge import Challenge
2+
from challenges.conf import Conf
3+
from challenges.graph import Graph, Node, Edge
44
from challenges.scaffold import Scaffold
55
from challenges.runner import Runner
66
from challenges.main import main
7+

challenges/challenge.py

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,25 @@ class Challenge:
5858
5959
"""
6060

61-
sample = 'sample'
62-
"""Holds a minimal example of the input.
61+
sample = '''
62+
sample
63+
sample
64+
'''
65+
"""Holds a minimal example of the input with additional whitespace.
6366
6467
This class variable should always be preset with a tiny sample of input.
68+
Whitespace surrounding lines is for readability. It typically needs to be
69+
stripped to get the actual sample.
70+
"""
71+
72+
expect = '''
73+
expected result
74+
expected result
75+
'''
76+
"""Holds the expected result with additional leading whitespace.
77+
78+
Whitespace surrounding lines is for readability. It typically needs to be
79+
stripped to get the actual expactation.
6580
"""
6681

6782
br = '\n'
@@ -135,8 +150,7 @@ def read(self):
135150
136151
Typically this method can be used as is.
137152
"""
138-
lines = self.sample.strip().splitlines()
139-
self.lines = [line.strip() for line in lines]
153+
self.lines = self.example().splitlines()
140154

141155
def build(self):
142156
"""Set up the model from the input lines.
@@ -171,13 +185,36 @@ def format(self):
171185
self.output = str(self.result)
172186

173187
# --------------------------------------------------
174-
# Accessing lines
188+
# Accessing example and expectation
189+
# --------------------------------------------------
190+
191+
def example(self):
192+
"""Get the sample, with heading whitespace trimmed"""
193+
lines = self.sample.strip().splitlines()
194+
return '\n'.join(line.strip() for line in lines)
195+
196+
def expectation(self):
197+
"""Get the expecation, with heading whitespace trimmed"""
198+
lines = self.expect.strip().splitlines()
199+
return '\n'.join(line.strip() for line in lines)
200+
201+
# --------------------------------------------------
202+
# Accessing input lines
175203
# --------------------------------------------------
176204

177205
def line(self, number):
178206
""" Return one line by the given number. """
179207
return self.lines[number]
180208

209+
def line_to_words(self, line_nr):
210+
""" Split one line into a list of words.
211+
212+
The number of the line is selected by line_nr.
213+
The split behaviour can be adjusted by changing self.split_pattern.
214+
"""
215+
216+
return list(re.compile(self.split_pattern).split(self.line(line_nr)))
217+
181218
def line_to_integers(self, line_nr):
182219
""" Split one line into a list of integers.
183220
@@ -188,6 +225,14 @@ def line_to_integers(self, line_nr):
188225
return [int(i) for i in
189226
re.compile(self.split_pattern).split(self.line(line_nr))]
190227

228+
def line_to_integer(self, line_nr):
229+
""" Return line as integer.
230+
231+
The number of the line is selected by line_nr.
232+
"""
233+
234+
return int(self.line(line_nr))
235+
191236
def line_to_floats(self, line_nr):
192237
""" Split one line into a list of floats.
193238
@@ -271,6 +316,12 @@ def fasta(self, start=0, stop=None):
271316
# Yield final sequence
272317
yield name, sequence
273318

319+
def fasta_strands(self, start=0, stop=None):
320+
""" Get the strands of a fasta read as list.
321+
322+
Takes the same arguments as self.fasta() and delegates to it.
323+
"""
324+
return list(dict(self.fasta(start, stop)).values())
274325

275326
# noinspection PyMethodMayBeStatic
276327
def _to_edge(self, match):

challenges/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class Conf:
99
def __init__(self):
1010
sys.path.insert(0, '.')
11-
sys.setrecursionlimit(5000)
11+
sys.setrecursionlimit(15000)
1212
self.root = os.path.realpath('.')
1313
self.parser = None
1414
self.args = None

challenges/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from challenges import Conf
2-
from challenges import Runner
1+
from challenges.conf import Conf
2+
from challenges.runner import Runner
33

44

55
def main():

challenges/runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import time
33
import unittest
44

5-
from challenges import Scaffold
5+
from challenges.scaffold import Scaffold
66

77

88
class Runner:

challenges/scaffold.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def scaffold(self):
4747

4848
def get_class_content(self):
4949
text = '''
50+
# https://github.com/elmar-hinz/Python.Challenges
5051
from challenges import Challenge
5152
5253
class {}Challenge(Challenge):
@@ -88,7 +89,7 @@ def test_format(self):
8889
8990
def test_full_integration(self):
9091
self.challenge.main()
91-
self.assertEqual(self.challenge.expect, self.challenge.output)
92+
self.assertEqual(self.challenge.expectation(), self.challenge.output)
9293
'''
9394
n = self.conf.get_challenge_name()
9495
return text.strip().format(n, n, n, n, n)

tests/test_challenge.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66

77

88
class ChallengeTestCase(unittest.TestCase):
9+
910
"""Test cases of the challenge base class."""
1011

1112
def setUp(self):
1213
self.challenge = Challenge()
1314

1415
def test_class_attributes(self):
1516
"""Check setting of class attributes."""
16-
self.assertEqual(Challenge.sample, 'sample')
17+
self.assertIn('sample', self.challenge.sample)
18+
self.assertIn('expected result', self.challenge.expect)
1719
self.assertEqual(Challenge.br, '\n', Challenge.br)
1820
self.assertEqual(Challenge.split_pattern, '\s+|\s?,\s?')
1921
self.assertEqual(Challenge.edge_pattern, '^(\d+)->(\d+)(:(\d+))?$')
@@ -27,11 +29,19 @@ def test_instance_attributes(self):
2729

2830
def test_instance_shadows_class_attribute_of_sample(self):
2931
""" Show that instance attribute shadows class attribute."""
30-
self.assertEqual(Challenge.sample, 'sample')
31-
self.assertEqual(self.challenge.sample, 'sample')
32+
self.assertIn('sample', Challenge.sample)
33+
self.assertIn('sample', self.challenge.sample)
3234
self.challenge.sample = 'mine'
33-
self.assertEqual(Challenge.sample, 'sample')
34-
self.assertEqual(self.challenge.sample, 'mine')
35+
self.assertIn('sample', Challenge.sample)
36+
self.assertIn('mine', self.challenge.sample)
37+
38+
def test_instance_shadows_class_attribute_of_expect(self):
39+
""" Show that instance attribute shadows class attribute."""
40+
self.assertIn('expected result', Challenge.expect)
41+
self.assertIn('expected result', self.challenge.expect)
42+
self.challenge.expect = 'my result'
43+
self.assertIn('expected result', Challenge.expect)
44+
self.assertIn('my result', self.challenge.expect)
3545

3646
def test_read(self):
3747
"""Show that read creates list of lines."""
@@ -227,6 +237,18 @@ def test_read_fasta_format(self):
227237
self.assertIn('FAS_2', fasta.keys())
228238
self.assertEqual('AAATTT', fasta['FAS_2'])
229239

240+
def test_fasta_strands(self):
241+
""" Check the method works as expected. """
242+
self.challenge.sample = '''
243+
>FAS_1
244+
AAA
245+
>FAS_2
246+
CCC
247+
'''
248+
self.challenge.read()
249+
result = self.challenge.fasta_strands()
250+
self.assertEqual(['AAA', 'CCC'], result)
251+
230252
def test_format_list_of_integers(self):
231253
"""Show concatenation of list of integers."""
232254
self.assertEqual(self.challenge.format_list_of_integers([1, 2]),

0 commit comments

Comments
 (0)