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.

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

mercurial