2017-10-06 14:54:31 -05:00
|
|
|
import unittest
|
|
|
|
|
|
2017-10-23 15:06:44 -05:00
|
|
|
from forth import evaluate, StackUnderflowError
|
2017-10-06 14:54:31 -05:00
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-10-25 08:17:29 +01:00
|
|
|
# Tests adapted from `problem-specifications//canonical-data.json` @ v1.2.0
|
2017-10-27 16:46:37 +01:00
|
|
|
# Tests for case-insensitivity are track-specific
|
|
|
|
|
|
|
|
|
|
class ForthParsingTest(unittest.TestCase):
|
|
|
|
|
def test_empty_input_empty_stack(self):
|
|
|
|
|
input_data = []
|
|
|
|
|
expected = []
|
|
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
|
|
|
|
|
|
|
|
|
def test_empty_line_empty_stack(self):
|
|
|
|
|
input_data = [""]
|
|
|
|
|
expected = []
|
|
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
|
|
|
|
|
|
|
|
|
def test_numbers_just_get_pushed_to_stack(self):
|
|
|
|
|
input_data = ["1 2 3 4 5"]
|
|
|
|
|
expected = [1, 2, 3, 4, 5]
|
|
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-09 09:14:56 -05:00
|
|
|
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
class ForthAdditionTest(unittest.TestCase):
|
|
|
|
|
def test_can_add_two_numbers(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 2 +"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [3]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_nothing_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["+"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_only_one_value_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 +"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
class ForthSubtractionTest(unittest.TestCase):
|
|
|
|
|
def test_can_subtract_two_numbers(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["3 4 -"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [-1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_nothing_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["-"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_only_one_value_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 -"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
class ForthMultiplicationTest(unittest.TestCase):
|
|
|
|
|
def test_can_multiply_two_numbers(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["2 4 *"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [8]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_nothing_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["*"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_only_one_value_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 *"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
class ForthDivisionTest(unittest.TestCase):
|
|
|
|
|
def test_can_divide_two_numbers(self):
|
2017-10-27 16:46:37 +01:00
|
|
|
input_data = ["12 3 /"]
|
|
|
|
|
expected = [4]
|
|
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_performs_integer_division(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["8 3 /"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [2]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_dividing_by_zero(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["4 0 /"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(ZeroDivisionError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_nothing_on_the_stack(self):
|
2017-10-09 11:27:43 -05:00
|
|
|
input_data = ["/"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_only_one_value_on_the_stack(self):
|
2017-10-09 11:27:43 -05:00
|
|
|
input_data = ["1 /"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
class ForthCombinedArithmeticTest(unittest.TestCase):
|
|
|
|
|
def test_addition_and_subtraction(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 2 + 4 -"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [-1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_multiplication_and_division(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["2 4 * 3 /"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [2]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class ForthDupTest(unittest.TestCase):
|
|
|
|
|
def test_copies_the_top_value_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 DUP"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [1, 1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_is_case_insensitive(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 2 Dup"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [1, 2, 2]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_nothing_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["dup"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
class ForthDropTest(unittest.TestCase):
|
|
|
|
|
def test_removes_the_top_value_on_the_stack_if_it_is_the_only_one(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 DROP"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = []
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_removes_the_top_value_on_the_stack_if_it_not_the_only_one(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["3 4 DROP"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [3]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_is_case_insensitive(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 2 Drop"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_nothing_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["drop"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
class ForthSwapTest(unittest.TestCase):
|
|
|
|
|
def test_swaps_only_two_values_on_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 2 SWAP"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [2, 1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_swaps_two_two_values_on_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 2 3 SWAP"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [1, 3, 2]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_is_case_insensitive(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["3 4 Swap"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [4, 3]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_nothing_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["swap"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_only_one_value_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 swap"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
class ForthOverTest(unittest.TestCase):
|
|
|
|
|
def test_copies_the_second_element_if_there_are_only_two(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 2 OVER"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [1, 2, 1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_copies_the_second_element_if_there_are_more_than_two(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 2 3 OVER"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [1, 2, 3, 2]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_is_case_insensitive(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["3 4 Over"]
|
2017-10-06 15:34:38 -05:00
|
|
|
expected = [3, 4, 3]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_nothing_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["over"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_there_is_only_one_value_on_the_stack(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["1 over"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(StackUnderflowError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
class ForthUserDefinedWordsTest(unittest.TestCase):
|
|
|
|
|
def test_can_consist_of_built_in_words(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = [
|
2017-10-06 15:34:38 -05:00
|
|
|
": dup-twice dup dup ;",
|
|
|
|
|
"1 dup-twice"
|
|
|
|
|
]
|
|
|
|
|
expected = [1, 1, 1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_execute_in_the_right_order(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = [
|
2017-10-06 15:34:38 -05:00
|
|
|
": countup 1 2 3 ;",
|
|
|
|
|
"countup"
|
|
|
|
|
]
|
|
|
|
|
expected = [1, 2, 3]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_can_override_other_user_defined_words(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = [
|
2017-10-06 15:34:38 -05:00
|
|
|
": foo dup ;",
|
|
|
|
|
": foo dup dup ;",
|
|
|
|
|
"1 foo"
|
|
|
|
|
]
|
|
|
|
|
expected = [1, 1, 1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_can_override_built_in_words(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = [
|
2017-10-06 15:34:38 -05:00
|
|
|
": swap dup ;",
|
|
|
|
|
"1 swap"
|
|
|
|
|
]
|
|
|
|
|
expected = [1, 1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_can_override_built_in_operators(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = [
|
2017-10-06 15:34:38 -05:00
|
|
|
": + * ;",
|
|
|
|
|
"3 4 +"
|
|
|
|
|
]
|
|
|
|
|
expected = [12]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_is_case_insensitive(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = [
|
2017-10-06 16:43:57 -05:00
|
|
|
": foo dup ;",
|
2017-10-06 15:34:38 -05:00
|
|
|
"1 FOO"
|
|
|
|
|
]
|
|
|
|
|
expected = [1, 1]
|
2017-10-27 16:46:37 +01:00
|
|
|
self.assertEqual(evaluate(input_data), expected)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_cannot_redefine_numbers(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = [": 1 2 ;"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(ValueError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
def test_errors_if_executing_a_non_existent_word(self):
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = ["foo"]
|
2017-12-12 18:11:43 +00:00
|
|
|
with self.assertRaisesWithMessage(ValueError):
|
2017-10-09 11:27:43 -05:00
|
|
|
evaluate(input_data)
|
2017-10-06 15:34:38 -05:00
|
|
|
|
2017-12-12 18:11:43 +00:00
|
|
|
# Utility functions
|
|
|
|
|
def setUp(self):
|
|
|
|
|
try:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex
|
2017-12-12 18:11:43 +00:00
|
|
|
except AttributeError:
|
2018-01-18 10:47:11 -06:00
|
|
|
self.assertRaisesRegex = self.assertRaisesRegexp
|
2017-12-12 18:11:43 +00:00
|
|
|
|
|
|
|
|
def assertRaisesWithMessage(self, exception):
|
|
|
|
|
return self.assertRaisesRegex(exception, r".+")
|
|
|
|
|
|
2017-10-06 15:34:38 -05:00
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
unittest.main()
|