class CountGarbageCharactersTest(unittest.TestCase): def setUp(self): self.processor = StreamProcessor() def eat_garbage_test(self, garbage, num_characters): # Keep in mind: first < is already eaten before passing on to # eat_garbage() with StringIO(garbage[1:]) as s: actual_num_characters = self.processor.eat_garbage(s) rest = s.read() self.assertEqual(rest, '') self.assertEqual(actual_num_characters, num_characters) def test_empty_garbage(self): self.eat_garbage_test('<>', num_characters=0) def test_long_garbage(self): self.eat_garbage_test('<random characters>', num_characters=17) def test_opening_garbage(self): self.eat_garbage_test('<<<<>', num_characters=3) def test_cancelled_garbage(self): self.eat_garbage_test('<{!>}>', num_characters=2) def test_doubly_cancelled_garbage(self): self.eat_garbage_test('<!!>', num_characters=0) def test_triple_cancelled_garbage(self): self.eat_garbage_test('<!!!>>', num_characters=0) def test_complex_garbage(self): self.eat_garbage_test('<{o"i!a,<{i<a>', num_characters=10)
class CountGarbageWithinGroupsTest(unittest.TestCase): def setUp(self): self.processor = StreamProcessor() def process_group_garbage_test(self, group, num_garbage=0): # Keep in mind: first { is already eaten before passing on to # process_group() with StringIO(group[1:]) as s: _, _, actual_garbage = self.processor.process_group(s) rest = s.read() self.assertEqual(rest, '') self.assertEqual(actual_garbage, num_garbage) def test_empty_group(self): self.process_group_garbage_test('{}', num_garbage=0) def test_empty_garbage(self): self.process_group_garbage_test('{<>}', num_garbage=0) def test_simple_garbage(self): self.process_group_garbage_test('{<foo>}', num_garbage=3) def test_nested_simple_garbage(self): self.process_group_garbage_test('{{<foo>}}', num_garbage=3) def test_complex_garbage(self): self.process_group_garbage_test('{{<123>},<4567>,<89>}', num_garbage=9)
class RemoveGarbageTest(unittest.TestCase): def setUp(self): self.processor = StreamProcessor() def eat_garbage_test(self, garbage): # Keep in mind: first < is already eaten before passing on to # eat_garbage() with StringIO(garbage[1:]) as s: self.processor.eat_garbage(s) rest = s.read() self.assertEqual(rest, '') def test_raises_exception_when_stream_runs_out(self): with self.assertRaises(RuntimeError): self.eat_garbage_test('<') def test_empty_garbage(self): self.eat_garbage_test('<>') def test_random_garbage(self): self.eat_garbage_test('<random characters>') def test_ignore_start_codon(self): self.eat_garbage_test('<<<<>') def test_cancel_closing_marker(self): self.eat_garbage_test('<{!>}>') def test_cancel_cancel_marker(self): self.eat_garbage_test('<!!>') def test_handle_many_cancels(self): self.eat_garbage_test('<!!!>>') def test_complex_garbage(self): self.eat_garbage_test('<{o"i!a,<{i<a>')
class ProcessGroupTest(unittest.TestCase): def setUp(self): self.processor = StreamProcessor() def process_group_test(self, group, num_groups=0): # Keep in mind: first { is already eaten before passing on to # process_group() with StringIO(group[1:]) as s: actual_num_groups, _, _ = self.processor.process_group(s) rest = s.read() self.assertEqual(rest, '') self.assertEqual(actual_num_groups, num_groups) def test_raises_exception_when_stream_runs_out(self): with self.assertRaises(RuntimeError): self.process_group_test('{') def test_empty_group(self): self.process_group_test('{}', num_groups=1) def test_three_nested_groups(self): self.process_group_test('{{{}}}', num_groups=3) def test_three_sequential_groups(self): self.process_group_test('{{},{}}', num_groups=3) def test_mixed_groups(self): self.process_group_test('{{{},{},{{}}}}', num_groups=6) def test_mixed_group_garbage(self): self.process_group_test('{<{},{},{{}}>}', num_groups=1) def test_sequential_garbage(self): self.process_group_test('{<a>,<a>,<a>,<a>}', num_groups=1) def test_grouped_garbage(self): self.process_group_test('{{<a>},{<a>},{<a>},{<a>}}', num_groups=5) def test_cancelled_garbage(self): self.process_group_test('{{<!>},{<!>},{<!>},{<a>}}', num_groups=2)
class ProcessGroupScoreTest(unittest.TestCase): def setUp(self): self.processor = StreamProcessor() def process_group_score_test(self, group, score=0): # Keep in mind: first { is already eaten before passing on to # process_group() with StringIO(group[1:]) as s: _, actual_score, _ = self.processor.process_group(s) rest = s.read() self.assertEqual(rest, '') self.assertEqual(actual_score, score) def test_empty_group(self): self.process_group_score_test('{}', score=1) def test_three_nested_groups(self): self.process_group_score_test('{{{}}}', score=6) def test_three_sequential_groups(self): self.process_group_score_test('{{},{}}', score=5) def test_mixed_groups(self): self.process_group_score_test('{{{},{},{{}}}}', score=16) def test_sequential_garbage(self): self.process_group_score_test('{<a>,<a>,<a>,<a>}', score=1) def test_grouped_garbage(self): self.process_group_score_test('{{<ab>},{<ab>},{<ab>},{<ab>}}', score=9) def test_doubly_cancelled_garbage(self): self.process_group_score_test('{{<!!>},{<!!>},{<!!>},{<!!>}}', score=9) def test_mostly_cancelled_garbage(self): self.process_group_score_test('{{<a!>},{<a!>},{<a!>},{<ab>}}', score=3)
def setUp(self): self.processor = StreamProcessor()