test_parse.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. from unittest import TestCase
  2. from parse import split_selectors, parse_groups
  3. class TestHelpers(TestCase):
  4. def test_split_selectors(self):
  5. self.assertEqual(split_selectors(''), [])
  6. self.assertEqual(split_selectors('a, b'), ['a', 'b'])
  7. self.assertEqual(split_selectors('a ,b'), ['a', 'b'])
  8. self.assertEqual(split_selectors('\na ,b '), ['a', 'b'])
  9. self.assertEqual(split_selectors('a, b\nc'), ['a', 'b c'])
  10. self.assertEqual(split_selectors('a,\nb c ,d\n'), ['a', 'b c', 'd'])
  11. class TestParseGroups(TestCase):
  12. def test_empty_stylesheet(self):
  13. self.assertParse('', [])
  14. self.assertParse(' \n ', [])
  15. def test_empty_block(self):
  16. self.assertParse('div {}', [(None, [(['div'], [])])])
  17. def test_single_property(self):
  18. self.assertParse('div {color:black;}',
  19. [(None, [(['div'], [('color', 'black')])])])
  20. self.assertParse('div {color:black}',
  21. [(None, [(['div'], [('color', 'black')])])])
  22. self.assertParse('''
  23. div {
  24. color: black;
  25. }
  26. ''', [(None, [(['div'], [('color', 'black')])])])
  27. self.assertParse('''
  28. div {
  29. color: black
  30. }
  31. ''', [(None, [(['div'], [('color', 'black')])])])
  32. def test_multiple_properties(self):
  33. self.assertParse('''
  34. div {
  35. color: black;
  36. border: none;
  37. }
  38. ''', [(None, [(['div'], [('color', 'black'), ('border', 'none')])])])
  39. self.assertParse('''
  40. div {
  41. color: black;
  42. border: none
  43. }
  44. ''', [(None, [(['div'], [('color', 'black'), ('border', 'none')])])])
  45. def test_multiple_selectors(self):
  46. self.assertParse('div,p {color: black}',
  47. [(None, [(['div', 'p'], [('color', 'black')])])])
  48. self.assertParse('div, p {color: black}',
  49. [(None, [(['div', 'p'], [('color', 'black')])])])
  50. self.assertParse('p,\n\tdiv {color: black}',
  51. [(None, [(['p', 'div'], [('color', 'black')])])])
  52. def test_single_group(self):
  53. self.assertParse('''
  54. @media (min-width: 970px) {
  55. div {color: black}
  56. }
  57. ''', [(['@media (min-width: 970px)'],
  58. [(['div'], [('color', 'black')])])])
  59. def test_single_group_multiple_blocks(self):
  60. self.assertParse('''
  61. @media (min-width: 970px) {
  62. div {color: black}
  63. p {margin: 0}
  64. }
  65. ''', [(['@media (min-width: 970px)'],
  66. [(['div'], [('color', 'black')]), (['p'], [('margin', '0')])])])
  67. def test_multiple_groups(self):
  68. self.assertParse('''
  69. @media (min-width: 970px) {
  70. div {color: black}
  71. }
  72. @media (max-width: 969px) {
  73. div {color: red}
  74. }
  75. ''', [
  76. (['@media (min-width: 970px)'], [(['div'], [('color', 'black')])]),
  77. (['@media (max-width: 969px)'], [(['div'], [('color', 'red')])])
  78. ])
  79. def test_group_with_root(self):
  80. self.assertParse('''
  81. div {
  82. color: black
  83. }
  84. @media (max-width: 969px) {
  85. div {color: red}
  86. }
  87. ''', [
  88. (None, [(['div'], [('color', 'black')])]),
  89. (['@media (max-width: 969px)'], [(['div'], [('color', 'red')])])
  90. ])
  91. self.assertParse('''
  92. @media (max-width: 969px) {
  93. div {color: red}
  94. }
  95. div {
  96. color: black
  97. }
  98. ''', [
  99. (['@media (max-width: 969px)'], [(['div'], [('color', 'red')])]),
  100. (None, [(['div'], [('color', 'black')])])
  101. ])
  102. def test_group_with_multiple_roots(self):
  103. self.assertParse('''
  104. div {
  105. color: black
  106. }
  107. @media (max-width: 969px) {
  108. div {color: red}
  109. }
  110. p {
  111. margin: 0
  112. }
  113. ''', [
  114. (None, [(['div'], [('color', 'black')])]),
  115. (['@media (max-width: 969px)'], [(['div'], [('color', 'red')])]),
  116. (None, [(['p'], [('margin', '0')])])
  117. ])
  118. def test_multiple_groups_multiple_roots(self):
  119. self.assertParse('''
  120. @media (min-width: 970px) {
  121. div {color: black}
  122. }
  123. div {
  124. color: black
  125. }
  126. @media (max-width: 969px) {
  127. div {color: red}
  128. }
  129. p {
  130. margin: 0
  131. }
  132. ''', [
  133. (['@media (min-width: 970px)'], [(['div'], [('color', 'black')])]),
  134. (None, [(['div'], [('color', 'black')])]),
  135. (['@media (max-width: 969px)'], [(['div'], [('color', 'red')])]),
  136. (None, [(['p'], [('margin', '0')])])
  137. ])
  138. self.assertParse('''
  139. p {
  140. margin: 0
  141. }
  142. @media (min-width: 970px) {
  143. div {color: black}
  144. }
  145. div {
  146. color: black
  147. }
  148. @media (max-width: 969px) {
  149. div {color: red}
  150. }
  151. ''', [
  152. (None, [(['p'], [('margin', '0')])]),
  153. (['@media (min-width: 970px)'], [(['div'], [('color', 'black')])]),
  154. (None, [(['div'], [('color', 'black')])]),
  155. (['@media (max-width: 969px)'], [(['div'], [('color', 'red')])]),
  156. ])
  157. def test_comment(self):
  158. self.assertParse('''
  159. /* this is a comment */
  160. div {color: black}
  161. ''', [(None, [(['div'], [('color', 'black')])])])
  162. self.assertParse('''
  163. /*
  164. * this is a multiline comment
  165. */
  166. div {color: black}
  167. ''', [(None, [(['div'], [('color', 'black')])])])
  168. self.assertParse('''
  169. div {color: /*inline comment*/ black}
  170. ''', [(None, [(['div'], [('color', 'black')])])])
  171. def test_error_brackets(self):
  172. self.assertRaisesRegexp(Exception, 'unexpected \'{\' on line 1',
  173. parse_groups, '{')
  174. self.assertRaisesRegexp(Exception, 'unexpected \'{\' on line 2',
  175. parse_groups, 'div {\n{}')
  176. self.assertRaisesRegexp(Exception, 'unexpected \'}\' on line 1',
  177. parse_groups, '}')
  178. self.assertRaisesRegexp(Exception, 'unexpected \'}\' on line 2',
  179. parse_groups, 'div\n}')
  180. def test_error_EOF(self):
  181. self.assertRaisesRegexp(Exception, 'unexpected <EOF> on line 3',
  182. parse_groups, '\ndiv\n')
  183. self.assertRaisesRegexp(Exception, 'unexpected <EOF> on line 2',
  184. parse_groups, '\ndiv {')
  185. def test_error_property_name(self):
  186. self.assertRaisesRegexp(Exception, 'unexpected \':\' on line 2',
  187. parse_groups, 'div{margin\nleft: 0}')
  188. def test_error_property_value(self):
  189. self.assertRaisesRegexp(Exception, 'unexpected \';\' on line 1',
  190. parse_groups, 'div{margin:;}')
  191. self.assertRaisesRegexp(Exception, 'unexpected \';\' on line 1',
  192. parse_groups, 'div{foo;}')
  193. self.assertParse('div {;}', [(None, [(['div'], [])])])
  194. def assertParse(self, css, result):
  195. self.assertEqual(parse_groups(css), result)