github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-tools-src/grumpy_tools/compiler/expr_visitor_test.py (about)

     1  # coding=utf-8
     2  
     3  # Copyright 2016 Google Inc. All Rights Reserved.
     4  #
     5  # Licensed under the Apache License, Version 2.0 (the "License");
     6  # you may not use this file except in compliance with the License.
     7  # You may obtain a copy of the License at
     8  #
     9  #     http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  
    17  """Tests for ExprVisitor."""
    18  
    19  from __future__ import unicode_literals
    20  
    21  import subprocess
    22  import textwrap
    23  import unittest
    24  
    25  from grumpy_tools.compiler import block
    26  from grumpy_tools.compiler import imputil
    27  from grumpy_tools.compiler import shard_test
    28  from grumpy_tools.compiler import stmt
    29  import pythonparser
    30  
    31  # Handles "Set self.maxDiff to None to see it" annoyance
    32  unittest.TestCase.maxDiff = None
    33  
    34  
    35  def _MakeExprTest(expr):
    36    def Test(self):
    37      code = 'assert ({}) == ({!r}), {!r}'.format(expr, eval(expr), expr)  # pylint: disable=eval-used
    38      self.assertEqual((0, ''), _GrumpRun(code))
    39    return Test
    40  
    41  
    42  def _MakeLiteralTest(lit, expected=None):
    43    if expected is None:
    44      expected = lit
    45    def Test(self):
    46      status, output = _GrumpRun('print repr({}),'.format(lit))
    47      self.assertEqual(0, status, output)
    48      self.assertEqual(expected, output.strip())  # pylint: disable=eval-used
    49    return Test
    50  
    51  
    52  def _MakeSliceTest(subscript, want):
    53    """Define a test function that evaluates a slice expression."""
    54    def Test(self):
    55      code = textwrap.dedent("""\
    56          class Slicer(object):
    57            def __getitem__(self, slice):
    58              print slice
    59          Slicer()[{}]""")
    60      status, output = _GrumpRun(code.format(subscript))
    61      self.assertEqual(0, status, output)
    62      self.assertEqual(want, output.strip())
    63    return Test
    64  
    65  
    66  class ExprVisitorTest(unittest.TestCase):
    67  
    68    # pylint: disable=invalid-name
    69  
    70    def testAttribute(self):
    71      code = textwrap.dedent("""\
    72          class Foo(object):
    73            bar = 42
    74          assert Foo.bar == 42""")
    75      self.assertEqual((0, ''), _GrumpRun(code))
    76  
    77    testBinOpArithmeticAdd = _MakeExprTest('1 + 2')
    78    testBinOpArithmeticAnd = _MakeExprTest('7 & 12')
    79    testBinOpArithmeticDiv = _MakeExprTest('8 / 4')
    80    testBinOpArithmeticFloorDiv = _MakeExprTest('8 // 4')
    81    testBinOpArithmeticFloorDivRemainder = _MakeExprTest('5 // 2')
    82    testBinOpArithmeticMod = _MakeExprTest('9 % 5')
    83    testBinOpArithmeticMul = _MakeExprTest('3 * 2')
    84    testBinOpArithmeticOr = _MakeExprTest('2 | 6')
    85    testBinOpArithmeticPow = _MakeExprTest('2 ** 16')
    86    testBinOpArithmeticSub = _MakeExprTest('10 - 3')
    87    testBinOpArithmeticXor = _MakeExprTest('3 ^ 5')
    88  
    89    testBoolOpTrueAndFalse = _MakeExprTest('True and False')
    90    testBoolOpTrueAndTrue = _MakeExprTest('True and True')
    91    testBoolOpTrueAndExpr = _MakeExprTest('True and 2 == 2')
    92    testBoolOpTrueOrFalse = _MakeExprTest('True or False')
    93    testBoolOpFalseOrFalse = _MakeExprTest('False or False')
    94    testBoolOpFalseOrExpr = _MakeExprTest('False or 2 == 2')
    95  
    96    def testCall(self):
    97      code = textwrap.dedent("""\
    98          def foo():
    99           print 'bar'
   100          foo()""")
   101      self.assertEqual((0, 'bar\n'), _GrumpRun(code))
   102  
   103    def testCallKeywords(self):
   104      code = textwrap.dedent("""\
   105          def foo(a=1, b=2):
   106           print a, b
   107          foo(b=3)""")
   108      self.assertEqual((0, '1 3\n'), _GrumpRun(code))
   109  
   110    def testCallVarArgs(self):
   111      code = textwrap.dedent("""\
   112          def foo(a, b):
   113            print a, b
   114          foo(*(123, 'abc'))""")
   115      self.assertEqual((0, '123 abc\n'), _GrumpRun(code))
   116  
   117    def testCallKwargs(self):
   118      code = textwrap.dedent("""\
   119          def foo(a, b=2):
   120            print a, b
   121          foo(**{'a': 4})""")
   122      self.assertEqual((0, '4 2\n'), _GrumpRun(code))
   123  
   124    testCompareLT = _MakeExprTest('1 < 2')
   125    testCompareLE = _MakeExprTest('7 <= 12')
   126    testCompareEq = _MakeExprTest('8 == 4')
   127    testCompareNE = _MakeExprTest('9 != 5')
   128    testCompareGE = _MakeExprTest('3 >= 2')
   129    testCompareGT = _MakeExprTest('2 > 6')
   130    testCompareLTLT = _MakeExprTest('3 < 6 < 9')
   131    testCompareLTEq = _MakeExprTest('3 < 6 == 9')
   132    testCompareLTGE = _MakeExprTest('3 < 6 >= -2')
   133    testCompareGTEq = _MakeExprTest('88 > 12 == 12')
   134    testCompareInStr = _MakeExprTest('"1" in "abc"')
   135    testCompareInTuple = _MakeExprTest('1 in (1, 2, 3)')
   136    testCompareNotInTuple = _MakeExprTest('10 < 12 not in (1, 2, 3)')
   137  
   138    testDictEmpty = _MakeLiteralTest('{}')
   139    testDictNonEmpty = _MakeLiteralTest("{'foo': 42, 'bar': 43}")
   140  
   141    testSetNonEmpty = _MakeLiteralTest("{'foo', 'bar'}", "set(['foo', 'bar'])")
   142  
   143    testDictCompFor = _MakeExprTest('{x: str(x) for x in range(3)}')
   144    testDictCompForIf = _MakeExprTest(
   145        '{x: 3 * x for x in range(10) if x % 3 == 0}')
   146    testDictCompForFor = _MakeExprTest(
   147        '{x: y for x in range(3) for y in range(x)}')
   148  
   149    testGeneratorExpFor = _MakeExprTest('tuple(int(x) for x in "123")')
   150    testGeneratorExpForIf = _MakeExprTest(
   151        'tuple(x / 3 for x in range(10) if x % 3)')
   152    testGeneratorExprForFor = _MakeExprTest(
   153        'tuple(x + y for x in range(3) for y in range(x + 2))')
   154  
   155    testIfExpr = _MakeExprTest('1 if True else 0')
   156    testIfExprCompound = _MakeExprTest('42 if "ab" == "a" + "b" else 24')
   157    testIfExprNested = _MakeExprTest(
   158        '"foo" if "" else "bar" if 0 else "baz"')
   159  
   160    testLambda = _MakeExprTest('(lambda: 123)()')
   161    testLambda = _MakeExprTest('(lambda a, b: (a, b))("foo", "bar")')
   162    testLambda = _MakeExprTest('(lambda a, b=3: (a, b))("foo")')
   163    testLambda = _MakeExprTest('(lambda *args: args)(1, 2, 3)')
   164    testLambda = _MakeExprTest('(lambda **kwargs: kwargs)(x="foo", y="bar")')
   165  
   166    testListEmpty = _MakeLiteralTest('[]')
   167    testListNonEmpty = _MakeLiteralTest('[1, 2]')
   168  
   169    testListCompFor = _MakeExprTest('[int(x) for x in "123"]')
   170    testListCompForIf = _MakeExprTest('[x / 3 for x in range(10) if x % 3]')
   171    testListCompForFor = _MakeExprTest(
   172        '[x + y for x in range(3) for y in range(x + 2)]')
   173  
   174    def testNameGlobal(self):
   175      code = textwrap.dedent("""\
   176          foo = 123
   177          assert foo == 123""")
   178      self.assertEqual((0, ''), _GrumpRun(code))
   179  
   180    def testNameLocal(self):
   181      code = textwrap.dedent("""\
   182          def foo():
   183            bar = 'abc'
   184            assert bar == 'abc'
   185          foo()""")
   186      self.assertEqual((0, ''), _GrumpRun(code))
   187  
   188    testNumInt = _MakeLiteralTest('42')
   189    testNumLong = _MakeLiteralTest('42L')
   190    testNumIntLarge = _MakeLiteralTest('12345678901234567890',
   191                                       '12345678901234567890L')
   192    testNumFloat = _MakeLiteralTest('102.1')
   193    testNumFloatOnlyDecimal = _MakeLiteralTest('.5', '0.5')
   194    testNumFloatNoDecimal = _MakeLiteralTest('5.', '5.0')
   195    testNumFloatSci = _MakeLiteralTest('1e6', '1000000.0')
   196    testNumFloatSciCap = _MakeLiteralTest('1E6', '1000000.0')
   197    testNumFloatSciCapPlus = _MakeLiteralTest('1E+6', '1000000.0')
   198    testNumFloatSciMinus = _MakeLiteralTest('1e-06')
   199    testNumComplex = _MakeLiteralTest('3j')
   200  
   201    testSubscriptDictStr = _MakeExprTest('{"foo": 42}["foo"]')
   202    testSubscriptListInt = _MakeExprTest('[1, 2, 3][2]')
   203    testSubscriptTupleSliceStart = _MakeExprTest('(1, 2, 3)[2:]')
   204    testSubscriptTupleSliceStartStop = _MakeExprTest('(1, 2, 3)[10:11]')
   205    testSubscriptTupleSliceStartStep = _MakeExprTest('(1, 2, 3, 4, 5, 6)[-2::-2]')
   206    testSubscriptStartStop = _MakeSliceTest('2:3', 'slice(2, 3, None)')
   207    testSubscriptMultiDim = _MakeSliceTest('1,2,3', '(1, 2, 3)')
   208    testSubscriptStartStopObjects = _MakeSliceTest(
   209        'True:False', 'slice(True, False, None)')
   210    testSubscriptMultiDimSlice = _MakeSliceTest(
   211        "'foo','bar':'baz':'qux'", "('foo', slice('bar', 'baz', 'qux'))")
   212  
   213    testStrEmpty = _MakeLiteralTest("''")
   214    testStrAscii = _MakeLiteralTest("'abc'")
   215    testStrUtf8 = _MakeLiteralTest(r"'\tfoo\n\xcf\x80'")
   216    testStrQuoted = _MakeLiteralTest('\'"foo"\'', '\'"foo"\'')
   217    testStrUtf16 = _MakeLiteralTest("u'\\u0432\\u043e\\u043b\\u043d'")
   218  
   219    testTupleEmpty = _MakeLiteralTest('()')
   220    testTupleNonEmpty = _MakeLiteralTest('(1, 2, 3)')
   221  
   222    testUnaryOpNot = _MakeExprTest('not True')
   223    testUnaryOpInvert = _MakeExprTest('~4')
   224    testUnaryOpPos = _MakeExprTest('+4')
   225  
   226  
   227  def _MakeModuleBlock():
   228    return block.ModuleBlock(None, '__main__', '<test>', '',
   229                             imputil.FutureFeatures())
   230  
   231  
   232  def _ParseExpr(expr):
   233    return pythonparser.parse(expr).body[0].value
   234  
   235  
   236  def _ParseAndVisitExpr(expr):
   237    visitor = stmt.StatementVisitor(_MakeModuleBlock())
   238    visitor.visit_expr(_ParseExpr(expr))
   239    return visitor.writer.getvalue()
   240  
   241  
   242  def _GrumpRun(cmd):
   243    p = subprocess.Popen(['grumpy', 'run'], stdin=subprocess.PIPE,
   244                         stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
   245    out, _ = p.communicate(cmd)
   246    return p.returncode, out
   247  
   248  
   249  if __name__ == '__main__':
   250    shard_test.main()