test_line.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import unittest
  2. import doctest
  3. import line
  4. from node import Node as N, Leaf as L
  5. from line import generate_line, is_id, is_int
  6. class TestLine(unittest.TestCase):
  7. def test_doctest(self):
  8. self.assertEqual(doctest.testmod(m=line)[0], 0)
  9. def test_empty(self):
  10. self.assertEquals(generate_line(None), '<empty expression>')
  11. def test_simple(self):
  12. l0, l1 = L(1), L(2)
  13. plus = N('+', l0, l1)
  14. self.assertEquals(generate_line(plus), '1 + 2')
  15. def test_parentheses(self):
  16. l0, l1 = L(1), L(2)
  17. plus = N('+', l0, l1)
  18. times = N('*', plus, plus)
  19. self.assertEquals(generate_line(times), '(1 + 2)(1 + 2)')
  20. def test_parentheses_equal_precedence_right(self):
  21. l0, l1, l2 = L(1), L(2), L(3)
  22. plus = N('+', l1, l2)
  23. minus = N('-', l0, plus)
  24. self.assertEquals(generate_line(minus), '1 - (2 + 3)')
  25. def test_parentheses_equal_precedence_left(self):
  26. a, b, c, d = L('a'), L('b'), L('c'), L('d')
  27. exp = N('*', N('/', N('*', a, b), c), d)
  28. self.assertEquals(generate_line(exp), 'ab / c * d')
  29. def test_parentheses_nary(self):
  30. l0, l1, l2 = L(1), L(2), L(3)
  31. plus = N('+', N('+', l0, l1), l2)
  32. self.assertEquals(generate_line(plus), '1 + 2 + 3')
  33. def test_function(self):
  34. exp = L('x')
  35. inf = L('oo')
  36. minus_inf = -L('oo')
  37. integral = N('int', exp, minus_inf, inf)
  38. self.assertEquals(generate_line(integral), 'int(x, -oo, oo)')
  39. def test_mod(self):
  40. l0, l1 = L(1), L(2)
  41. mod = N('mod', l1, l0)
  42. self.assertEquals(generate_line(mod), '2 mod 1')
  43. def test_multiplication_identifiers(self):
  44. a, b = L('a'), L('b')
  45. self.assertEquals(generate_line(N('*', a, b)), 'ab')
  46. self.assertEquals(generate_line(N('*', a, -b)), 'a * -b')
  47. def test_multiplication_constant_identifier(self):
  48. l0, a = L(2), L('a')
  49. mul = N('*', l0, a)
  50. self.assertEquals(generate_line(mul), '2a')
  51. def test_multiplication_identifier_constant(self):
  52. l0, a = L(2), L('a')
  53. mul = N('*', a, l0)
  54. self.assertEquals(generate_line(mul), 'a * 2')
  55. def test_multiplication_constants(self):
  56. l0, l1 = L(1), L(2)
  57. mul = N('*', l0, l1)
  58. self.assertEquals(generate_line(mul), '1 * 2')
  59. def test_nary(self):
  60. l0, l1, l2 = L(1), L(2), L(3)
  61. plus = N('+', l0, l1, l2)
  62. self.assertEquals(generate_line(plus), '1 + 2 + 3')
  63. def test_pow_basic(self):
  64. a, b, c = L('a'), L('b'), L('c')
  65. node_pow = N('^', a, N('+', b, c))
  66. self.assertEquals(generate_line(node_pow), 'a ^ (b + c)')
  67. def test_pow_intermediate1(self):
  68. # expression: (a(b+c))^(d+e)
  69. a, b, c, d, e = L('a'), L('b'), L('c'), L('d'), L('e')
  70. node_bc = N('+', b, c)
  71. node_de = N('+', d, e)
  72. node_mul = N('*', a, node_bc)
  73. node_pow = N('^', node_mul, node_de)
  74. self.assertEquals(generate_line(node_pow), '(a(b + c)) ^ (d + e)')
  75. def test_pow_intermediate2(self):
  76. # expression: a(b+c)^(d+e)
  77. a, b, c, d, e = L('a'), L('b'), L('c'), L('d'), L('e')
  78. node_bc = N('+', b, c)
  79. node_de = N('+', d, e)
  80. node_pow = N('^', node_bc, node_de)
  81. node_mul = N('*', a, node_pow)
  82. self.assertEquals(generate_line(node_mul), 'a(b + c) ^ (d + e)')
  83. def test_multiplication_sign(self):
  84. a, b, c, l2 = L('a'), L('b'), L('c'), L(2)
  85. mul = N('*', a, b)
  86. self.assertEquals(generate_line(mul), 'ab')
  87. mul = N('*', mul, c)
  88. self.assertEquals(generate_line(mul), 'abc')
  89. mul = N('*', N('*', a, l2), b)
  90. self.assertEquals(generate_line(mul), 'a * 2b')
  91. plus = N('*', N('*', -a, b), c)
  92. self.assertEquals(generate_line(plus), '-abc')
  93. mul = N('*', a, N('-', b, c))
  94. self.assertEquals(generate_line(mul), 'a(b - c)')
  95. mul = N('*', l2, N('-', b, c))
  96. self.assertEquals(generate_line(mul), '2(b - c)')
  97. mul = N('*', N('+', a, b), c)
  98. self.assertEquals(generate_line(mul), '(a + b)c')
  99. mul = N('*', N('+', a, b), l2)
  100. self.assertEquals(generate_line(mul), '(a + b) * 2')
  101. mul = N('*', N('+', a, b), N('+', c, l2))
  102. self.assertEquals(generate_line(mul), '(a + b)(c + 2)')
  103. mul = N('*', l2, a)
  104. self.assertEquals(generate_line(mul), '2a')
  105. mul = N('*', a, l2)
  106. self.assertEquals(generate_line(mul), 'a * 2')
  107. def test_plus_to_minus(self):
  108. plus = N('+', L(1), -L(2))
  109. self.assertEquals(generate_line(plus), '1 - 2')
  110. l1, a, b, c = L(1), L('a'), L('b'), L('c')
  111. plus = N('+', l1, N('*', N('*', -a, b), c))
  112. self.assertEquals(generate_line(plus), '1 - abc')
  113. def test_helper_functions(self):
  114. l1, a = L(1), L('a')
  115. neg = -l1
  116. neg_a = -a
  117. plus = N('+', l1, a)
  118. self.assertTrue(is_id(a))
  119. self.assertTrue(is_id(neg_a))
  120. self.assertFalse(is_id(neg))
  121. self.assertFalse(is_id(plus))
  122. self.assertTrue(is_int(l1))
  123. self.assertTrue(is_int(neg))
  124. self.assertFalse(is_int(neg_a))
  125. self.assertFalse(is_int(plus))
  126. def test_negated_operator(self):
  127. neg = -N('+', L(1), L(2))
  128. self.assertEquals(generate_line(neg), '-(1 + 2)')
  129. neg = -N('-', L(1), L(2))
  130. self.assertEquals(generate_line(neg), '-(1 - 2)')
  131. neg = N('+', L(1), N('+', L(1), L(2)))
  132. self.assertEquals(generate_line(neg), '1 + 1 + 2')
  133. neg = N('+', L(1), -N('+', L(1), L(2)))
  134. self.assertEquals(generate_line(neg), '1 - (1 + 2)')
  135. neg = N('+', L(1), N('+', L(1), -L(2)))
  136. self.assertEquals(generate_line(neg), '1 + (1 - 2)')
  137. neg = -N('*', L(4), L('a'))
  138. self.assertEquals(generate_line(neg), '-4a')
  139. neg = N('*', L(4), -L('a'))
  140. self.assertEquals(generate_line(neg), '4 * -a')
  141. neg = -N('*', L(4), L(5))
  142. self.assertEquals(generate_line(neg), '-4 * 5')
  143. plus = N('+', L(1), -N('*', L(4), L(5)))
  144. self.assertEquals(generate_line(plus), '1 - 4 * 5')
  145. plus = N('+', L(1), -L(4))
  146. self.assertEquals(generate_line(plus), '1 - 4')
  147. plus = N('+', N('/', L('a'), L('b')), -N('/', L('c'), L('d')))
  148. self.assertEquals(generate_line(plus), 'a / b - c / d')
  149. mul = N('*', N('+', L('a'), L('b')), -N('+', L('c'), L('d')))
  150. self.assertEquals(generate_line(mul), '(a + b) * -(c + d)')
  151. def test_double_negation(self):
  152. neg = --L(1)
  153. self.assertEquals(generate_line(neg), '--1')