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()