| 1 | # This program is free software; you can redistribute it and/or modify it under |
|---|
| 2 | # the terms of the GNU General Public License as published by the Free Software |
|---|
| 3 | # Foundation; either version 2 of the License, or (at your option) any later |
|---|
| 4 | # version. |
|---|
| 5 | |
|---|
| 6 | # This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 7 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|---|
| 8 | # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
|---|
| 9 | |
|---|
| 10 | # You should have received a copy of the GNU General Public License along with |
|---|
| 11 | # this program; if not, write to the Free Software Foundation, Inc., |
|---|
| 12 | # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 13 | """tests for the astng variable lookup capabilities |
|---|
| 14 | """ |
|---|
| 15 | import sys |
|---|
| 16 | from os.path import join, abspath |
|---|
| 17 | from logilab.common.testlib import TestCase, unittest_main |
|---|
| 18 | |
|---|
| 19 | from logilab.astng import builder, nodes, scoped_nodes, \ |
|---|
| 20 | InferenceError, NotFoundError |
|---|
| 21 | |
|---|
| 22 | from unittest_inference import get_name_node |
|---|
| 23 | |
|---|
| 24 | builder = builder.ASTNGBuilder() |
|---|
| 25 | MODULE = builder.file_build('data/module.py', 'data.module') |
|---|
| 26 | MODULE2 = builder.file_build('data/module2.py', 'data.module2') |
|---|
| 27 | NONREGR = builder.file_build('data/nonregr.py', 'data.nonregr') |
|---|
| 28 | |
|---|
| 29 | class LookupTC(TestCase): |
|---|
| 30 | |
|---|
| 31 | def test_limit(self): |
|---|
| 32 | data = ''' |
|---|
| 33 | l = [a |
|---|
| 34 | for a,b in list] |
|---|
| 35 | |
|---|
| 36 | a = 1 |
|---|
| 37 | b = a |
|---|
| 38 | a = None |
|---|
| 39 | |
|---|
| 40 | def func(): |
|---|
| 41 | c = 1 |
|---|
| 42 | ''' |
|---|
| 43 | astng = builder.string_build(data, __name__, __file__) |
|---|
| 44 | names = astng.nodes_of_class(nodes.Name) |
|---|
| 45 | a = names.next() |
|---|
| 46 | stmts = a.lookup('a')[1] |
|---|
| 47 | self.failUnlessEqual(len(stmts), 1) |
|---|
| 48 | b = astng.locals['b'][1] |
|---|
| 49 | #self.failUnlessEqual(len(b.lookup('b')[1]), 1) |
|---|
| 50 | self.failUnlessEqual(len(astng.lookup('b')[1]), 2) |
|---|
| 51 | b_infer = b.infer() |
|---|
| 52 | b_value = b_infer.next() |
|---|
| 53 | self.failUnlessEqual(b_value.value, 1) |
|---|
| 54 | self.failUnlessRaises(StopIteration, b_infer.next) |
|---|
| 55 | func = astng.locals['func'][0] |
|---|
| 56 | self.failUnlessEqual(len(func.lookup('c')[1]), 1) |
|---|
| 57 | |
|---|
| 58 | def test_module(self): |
|---|
| 59 | astng = builder.string_build('pass', __name__, __file__) |
|---|
| 60 | # built-in objects |
|---|
| 61 | none = astng.ilookup('None').next() |
|---|
| 62 | self.assertEquals(none.value, None) |
|---|
| 63 | obj = astng.ilookup('object').next() |
|---|
| 64 | self.assertIsInstance(obj, nodes.Class) |
|---|
| 65 | self.assertEquals(obj.name, 'object') |
|---|
| 66 | self.assertRaises(InferenceError, astng.ilookup('YOAA').next) |
|---|
| 67 | |
|---|
| 68 | # XXX |
|---|
| 69 | self.assertEquals(len(list(NONREGR.ilookup('enumerate'))), 2) |
|---|
| 70 | |
|---|
| 71 | def test_class_ancestor_name(self): |
|---|
| 72 | data = ''' |
|---|
| 73 | class A: |
|---|
| 74 | pass |
|---|
| 75 | |
|---|
| 76 | class A(A): |
|---|
| 77 | pass |
|---|
| 78 | ''' |
|---|
| 79 | astng = builder.string_build(data, __name__, __file__) |
|---|
| 80 | cls1 = astng.locals['A'][0] |
|---|
| 81 | cls2 = astng.locals['A'][1] |
|---|
| 82 | name = cls2.nodes_of_class(nodes.Name).next() |
|---|
| 83 | self.assertEquals(name.infer().next(), cls1) |
|---|
| 84 | |
|---|
| 85 | ### backport those test to inline code |
|---|
| 86 | def test_method(self): |
|---|
| 87 | method = MODULE['YOUPI']['method'] |
|---|
| 88 | my_dict = method.ilookup('MY_DICT').next() |
|---|
| 89 | self.assert_(isinstance(my_dict, nodes.Dict), my_dict) |
|---|
| 90 | none = method.ilookup('None').next() |
|---|
| 91 | self.assertEquals(none.value, None) |
|---|
| 92 | self.assertRaises(InferenceError, method.ilookup('YOAA').next) |
|---|
| 93 | |
|---|
| 94 | def test_function_argument_with_default(self): |
|---|
| 95 | make_class = MODULE2['make_class'] |
|---|
| 96 | base = make_class.ilookup('base').next() |
|---|
| 97 | self.assert_(isinstance(base, nodes.Class), base.__class__) |
|---|
| 98 | self.assertEquals(base.name, 'YO') |
|---|
| 99 | self.assertEquals(base.root().name, 'data.module') |
|---|
| 100 | |
|---|
| 101 | def test_class(self): |
|---|
| 102 | klass = MODULE['YOUPI'] |
|---|
| 103 | #print klass.getattr('MY_DICT') |
|---|
| 104 | my_dict = klass.ilookup('MY_DICT').next() |
|---|
| 105 | self.assertIsInstance(my_dict, nodes.Dict) |
|---|
| 106 | none = klass.ilookup('None').next() |
|---|
| 107 | self.assertEquals(none.value, None) |
|---|
| 108 | obj = klass.ilookup('object').next() |
|---|
| 109 | self.assertIsInstance(obj, nodes.Class) |
|---|
| 110 | self.assertEquals(obj.name, 'object') |
|---|
| 111 | self.assertRaises(InferenceError, klass.ilookup('YOAA').next) |
|---|
| 112 | |
|---|
| 113 | def test_inner_classes(self): |
|---|
| 114 | ccc = NONREGR['Ccc'] |
|---|
| 115 | self.assertEquals(ccc.ilookup('Ddd').next().name, 'Ddd') |
|---|
| 116 | |
|---|
| 117 | def test_nonregr_method_lookup(self): |
|---|
| 118 | if sys.version_info < (2, 4): |
|---|
| 119 | self.skip('this test require python >= 2.4') |
|---|
| 120 | data = ''' |
|---|
| 121 | class FileA: |
|---|
| 122 | @staticmethod |
|---|
| 123 | def funcA(): |
|---|
| 124 | return 4 |
|---|
| 125 | |
|---|
| 126 | |
|---|
| 127 | class Test: |
|---|
| 128 | FileA = [1,2,3] |
|---|
| 129 | |
|---|
| 130 | def __init__(self): |
|---|
| 131 | print FileA.funcA() |
|---|
| 132 | ''' |
|---|
| 133 | astng = builder.string_build(data, __name__, __file__) |
|---|
| 134 | it = astng['Test']['__init__'].ilookup('FileA') |
|---|
| 135 | obj = it.next() |
|---|
| 136 | self.assertIsInstance(obj, nodes.Class) |
|---|
| 137 | self.assertRaises(StopIteration, it.next) |
|---|
| 138 | |
|---|
| 139 | def test_nonregr_decorator_member_lookup(self): |
|---|
| 140 | if sys.version_info < (2, 4): |
|---|
| 141 | self.skip('this test require python >= 2.4') |
|---|
| 142 | data = ''' |
|---|
| 143 | class FileA: |
|---|
| 144 | def decorator(bla): |
|---|
| 145 | return bla |
|---|
| 146 | |
|---|
| 147 | @decorator |
|---|
| 148 | def funcA(): |
|---|
| 149 | return 4 |
|---|
| 150 | ''' |
|---|
| 151 | astng = builder.string_build(data, __name__, __file__) |
|---|
| 152 | decname = get_name_node(astng['FileA'], 'decorator') |
|---|
| 153 | it = decname.infer() |
|---|
| 154 | obj = it.next() |
|---|
| 155 | self.assertIsInstance(obj, nodes.Function) |
|---|
| 156 | self.assertRaises(StopIteration, it.next) |
|---|
| 157 | |
|---|
| 158 | |
|---|
| 159 | if __name__ == '__main__': |
|---|
| 160 | unittest_main() |
|---|