build/pymake/tests/formattingtests.py

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

michael@0 1 # This file contains test code for the formatting of parsed statements back to
michael@0 2 # make file "source." It essentially verifies to to_source() functions
michael@0 3 # scattered across the tree.
michael@0 4
michael@0 5 import glob
michael@0 6 import logging
michael@0 7 import os.path
michael@0 8 import unittest
michael@0 9
michael@0 10 from pymake.data import Expansion
michael@0 11 from pymake.data import StringExpansion
michael@0 12 from pymake.functions import BasenameFunction
michael@0 13 from pymake.functions import SubstitutionRef
michael@0 14 from pymake.functions import VariableRef
michael@0 15 from pymake.functions import WordlistFunction
michael@0 16 from pymake.parserdata import Include
michael@0 17 from pymake.parserdata import SetVariable
michael@0 18 from pymake.parser import parsestring
michael@0 19 from pymake.parser import SyntaxError
michael@0 20
michael@0 21 class TestBase(unittest.TestCase):
michael@0 22 pass
michael@0 23
michael@0 24 class VariableRefTest(TestBase):
michael@0 25 def test_string_name(self):
michael@0 26 e = StringExpansion('foo', None)
michael@0 27 v = VariableRef(None, e)
michael@0 28
michael@0 29 self.assertEqual(v.to_source(), '$(foo)')
michael@0 30
michael@0 31 def test_special_variable(self):
michael@0 32 e = StringExpansion('<', None)
michael@0 33 v = VariableRef(None, e)
michael@0 34
michael@0 35 self.assertEqual(v.to_source(), '$<')
michael@0 36
michael@0 37 def test_expansion_simple(self):
michael@0 38 e = Expansion()
michael@0 39 e.appendstr('foo')
michael@0 40 e.appendstr('bar')
michael@0 41
michael@0 42 v = VariableRef(None, e)
michael@0 43
michael@0 44 self.assertEqual(v.to_source(), '$(foobar)')
michael@0 45
michael@0 46 class StandardFunctionTest(TestBase):
michael@0 47 def test_basename(self):
michael@0 48 e1 = StringExpansion('foo', None)
michael@0 49 v = VariableRef(None, e1)
michael@0 50 e2 = Expansion(None)
michael@0 51 e2.appendfunc(v)
michael@0 52
michael@0 53 b = BasenameFunction(None)
michael@0 54 b.append(e2)
michael@0 55
michael@0 56 self.assertEqual(b.to_source(), '$(basename $(foo))')
michael@0 57
michael@0 58 def test_wordlist(self):
michael@0 59 e1 = StringExpansion('foo', None)
michael@0 60 e2 = StringExpansion('bar ', None)
michael@0 61 e3 = StringExpansion(' baz', None)
michael@0 62
michael@0 63 w = WordlistFunction(None)
michael@0 64 w.append(e1)
michael@0 65 w.append(e2)
michael@0 66 w.append(e3)
michael@0 67
michael@0 68 self.assertEqual(w.to_source(), '$(wordlist foo,bar , baz)')
michael@0 69
michael@0 70 def test_curly_brackets(self):
michael@0 71 e1 = Expansion(None)
michael@0 72 e1.appendstr('foo')
michael@0 73
michael@0 74 e2 = Expansion(None)
michael@0 75 e2.appendstr('foo ( bar')
michael@0 76
michael@0 77 f = WordlistFunction(None)
michael@0 78 f.append(e1)
michael@0 79 f.append(e2)
michael@0 80
michael@0 81 self.assertEqual(f.to_source(), '${wordlist foo,foo ( bar}')
michael@0 82
michael@0 83 class StringExpansionTest(TestBase):
michael@0 84 def test_simple(self):
michael@0 85 e = StringExpansion('foobar', None)
michael@0 86 self.assertEqual(e.to_source(), 'foobar')
michael@0 87
michael@0 88 e = StringExpansion('$var', None)
michael@0 89 self.assertEqual(e.to_source(), '$var')
michael@0 90
michael@0 91 def test_escaping(self):
michael@0 92 e = StringExpansion('$var', None)
michael@0 93 self.assertEqual(e.to_source(escape_variables=True), '$$var')
michael@0 94
michael@0 95 e = StringExpansion('this is # not a comment', None)
michael@0 96 self.assertEqual(e.to_source(escape_comments=True),
michael@0 97 'this is \# not a comment')
michael@0 98
michael@0 99 def test_empty(self):
michael@0 100 e = StringExpansion('', None)
michael@0 101 self.assertEqual(e.to_source(), '')
michael@0 102
michael@0 103 e = StringExpansion(' ', None)
michael@0 104 self.assertEqual(e.to_source(), ' ')
michael@0 105
michael@0 106 class ExpansionTest(TestBase):
michael@0 107 def test_single_string(self):
michael@0 108 e = Expansion()
michael@0 109 e.appendstr('foo')
michael@0 110
michael@0 111 self.assertEqual(e.to_source(), 'foo')
michael@0 112
michael@0 113 def test_multiple_strings(self):
michael@0 114 e = Expansion()
michael@0 115 e.appendstr('hello')
michael@0 116 e.appendstr('world')
michael@0 117
michael@0 118 self.assertEqual(e.to_source(), 'helloworld')
michael@0 119
michael@0 120 def test_string_escape(self):
michael@0 121 e = Expansion()
michael@0 122 e.appendstr('$var')
michael@0 123 self.assertEqual(e.to_source(), '$var')
michael@0 124 self.assertEqual(e.to_source(escape_variables=True), '$$var')
michael@0 125
michael@0 126 e = Expansion()
michael@0 127 e.appendstr('foo')
michael@0 128 e.appendstr(' $bar')
michael@0 129 self.assertEqual(e.to_source(escape_variables=True), 'foo $$bar')
michael@0 130
michael@0 131 class SubstitutionRefTest(TestBase):
michael@0 132 def test_simple(self):
michael@0 133 name = StringExpansion('foo', None)
michael@0 134 c = StringExpansion('%.c', None)
michael@0 135 o = StringExpansion('%.o', None)
michael@0 136 s = SubstitutionRef(None, name, c, o)
michael@0 137
michael@0 138 self.assertEqual(s.to_source(), '$(foo:%.c=%.o)')
michael@0 139
michael@0 140 class SetVariableTest(TestBase):
michael@0 141 def test_simple(self):
michael@0 142 v = SetVariable(StringExpansion('foo', None), '=', 'bar', None, None)
michael@0 143 self.assertEqual(v.to_source(), 'foo = bar')
michael@0 144
michael@0 145 def test_multiline(self):
michael@0 146 s = 'hello\nworld'
michael@0 147 foo = StringExpansion('FOO', None)
michael@0 148
michael@0 149 v = SetVariable(foo, '=', s, None, None)
michael@0 150
michael@0 151 self.assertEqual(v.to_source(), 'define FOO\nhello\nworld\nendef')
michael@0 152
michael@0 153 def test_multiline_immediate(self):
michael@0 154 source = 'define FOO :=\nhello\nworld\nendef'
michael@0 155
michael@0 156 statements = parsestring(source, 'foo.mk')
michael@0 157 self.assertEqual(statements.to_source(), source)
michael@0 158
michael@0 159 def test_target_specific(self):
michael@0 160 foo = StringExpansion('FOO', None)
michael@0 161 bar = StringExpansion('BAR', None)
michael@0 162
michael@0 163 v = SetVariable(foo, '+=', 'value', None, bar)
michael@0 164
michael@0 165 self.assertEqual(v.to_source(), 'BAR: FOO += value')
michael@0 166
michael@0 167 class IncludeTest(TestBase):
michael@0 168 def test_include(self):
michael@0 169 e = StringExpansion('rules.mk', None)
michael@0 170 i = Include(e, True, False)
michael@0 171 self.assertEqual(i.to_source(), 'include rules.mk')
michael@0 172
michael@0 173 i = Include(e, False, False)
michael@0 174 self.assertEqual(i.to_source(), '-include rules.mk')
michael@0 175
michael@0 176 class IfdefTest(TestBase):
michael@0 177 def test_simple(self):
michael@0 178 source = 'ifdef FOO\nbar := $(value)\nendif'
michael@0 179
michael@0 180 statements = parsestring(source, 'foo.mk')
michael@0 181 self.assertEqual(statements[0].to_source(), source)
michael@0 182
michael@0 183 def test_nested(self):
michael@0 184 source = 'ifdef FOO\nifdef BAR\nhello = world\nendif\nendif'
michael@0 185
michael@0 186 statements = parsestring(source, 'foo.mk')
michael@0 187 self.assertEqual(statements[0].to_source(), source)
michael@0 188
michael@0 189 def test_negation(self):
michael@0 190 source = 'ifndef FOO\nbar += value\nendif'
michael@0 191
michael@0 192 statements = parsestring(source, 'foo.mk')
michael@0 193 self.assertEqual(statements[0].to_source(), source)
michael@0 194
michael@0 195 class IfeqTest(TestBase):
michael@0 196 def test_simple(self):
michael@0 197 source = 'ifeq ($(foo),bar)\nhello = $(world)\nendif'
michael@0 198
michael@0 199 statements = parsestring(source, 'foo.mk')
michael@0 200 self.assertEqual(statements[0].to_source(), source)
michael@0 201
michael@0 202 def test_negation(self):
michael@0 203 source = 'ifneq (foo,bar)\nhello = world\nendif'
michael@0 204
michael@0 205 statements = parsestring(source, 'foo.mk')
michael@0 206 self.assertEqual(statements.to_source(), source)
michael@0 207
michael@0 208 class ConditionBlocksTest(TestBase):
michael@0 209 def test_mixed_conditions(self):
michael@0 210 source = 'ifdef FOO\nifeq ($(FOO),bar)\nvar += $(value)\nendif\nendif'
michael@0 211
michael@0 212 statements = parsestring(source, 'foo.mk')
michael@0 213 self.assertEqual(statements.to_source(), source)
michael@0 214
michael@0 215 def test_extra_statements(self):
michael@0 216 source = 'ifdef FOO\nF := 1\nifdef BAR\nB += 1\nendif\nC = 1\nendif'
michael@0 217
michael@0 218 statements = parsestring(source, 'foo.mk')
michael@0 219 self.assertEqual(statements.to_source(), source)
michael@0 220
michael@0 221 def test_whitespace_preservation(self):
michael@0 222 source = "ifeq ' x' 'x '\n$(error stripping)\nendif"
michael@0 223
michael@0 224 statements = parsestring(source, 'foo.mk')
michael@0 225 self.assertEqual(statements.to_source(), source)
michael@0 226
michael@0 227 source = 'ifneq (x , x)\n$(error stripping)\nendif'
michael@0 228 statements = parsestring(source, 'foo.mk')
michael@0 229 self.assertEqual(statements.to_source(),
michael@0 230 'ifneq (x,x)\n$(error stripping)\nendif')
michael@0 231
michael@0 232 class MakefileCorupusTest(TestBase):
michael@0 233 """Runs the make files from the pymake corpus through the formatter.
michael@0 234
michael@0 235 All the above tests are child's play compared to this.
michael@0 236 """
michael@0 237
michael@0 238 # Our reformatting isn't perfect. We ignore files with known failures until
michael@0 239 # we make them work.
michael@0 240 # TODO Address these formatting corner cases.
michael@0 241 _IGNORE_FILES = [
michael@0 242 # We are thrown off by backslashes at end of lines.
michael@0 243 'comment-parsing.mk',
michael@0 244 'escape-chars.mk',
michael@0 245 'include-notfound.mk',
michael@0 246 ]
michael@0 247
michael@0 248 def _get_test_files(self):
michael@0 249 ourdir = os.path.dirname(os.path.abspath(__file__))
michael@0 250
michael@0 251 for makefile in glob.glob(os.path.join(ourdir, '*.mk')):
michael@0 252 if os.path.basename(makefile) in self._IGNORE_FILES:
michael@0 253 continue
michael@0 254
michael@0 255 source = None
michael@0 256 with open(makefile, 'rU') as fh:
michael@0 257 source = fh.read()
michael@0 258
michael@0 259 try:
michael@0 260 yield (makefile, source, parsestring(source, makefile))
michael@0 261 except SyntaxError:
michael@0 262 continue
michael@0 263
michael@0 264 def test_reparse_consistency(self):
michael@0 265 for filename, source, statements in self._get_test_files():
michael@0 266 reformatted = statements.to_source()
michael@0 267
michael@0 268 # We should be able to parse the reformatted source fine.
michael@0 269 new_statements = parsestring(reformatted, filename)
michael@0 270
michael@0 271 # If we do the formatting again, the representation shouldn't
michael@0 272 # change. i.e. the only lossy change should be the original
michael@0 273 # (whitespace and some semantics aren't preserved).
michael@0 274 reformatted_again = new_statements.to_source()
michael@0 275 self.assertEqual(reformatted, reformatted_again,
michael@0 276 '%s has lossless reformat.' % filename)
michael@0 277
michael@0 278 self.assertEqual(len(statements), len(new_statements))
michael@0 279
michael@0 280 for i in xrange(0, len(statements)):
michael@0 281 original = statements[i]
michael@0 282 formatted = new_statements[i]
michael@0 283
michael@0 284 self.assertEqual(original, formatted, '%s %d: %s != %s' % (filename,
michael@0 285 i, original, formatted))
michael@0 286
michael@0 287 if __name__ == '__main__':
michael@0 288 logging.basicConfig(level=logging.DEBUG)
michael@0 289 unittest.main()

mercurial