root / logilab.pylintinstaller / logilab / astng / test / unittest_builder.py

Revision 202:d67e86292521, 18.4 kB (checked in by tziade@…, 11 months ago)

added logilab.pylintinstaller

Line 
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 builder module
14"""
15
16import unittest
17import sys
18from os.path import join, abspath, dirname
19
20from logilab.common.testlib import TestCase, unittest_main
21from unittest_inference import get_name_node
22from pprint import pprint
23       
24from logilab.astng.astutils import cvrtr
25from logilab.astng import builder, nodes, Module, YES
26
27import data
28from data import module as test_module
29
30class TransformerTC(TestCase):
31       
32    def setUp(self):
33        transformer = builder.ASTNGTransformer()
34        self.astng = transformer.parsesuite(open('data/format.py').read())
35
36    def test_callfunc_lineno(self):
37        stmts = self.astng.getChildNodes()[0].nodes
38        # on line 4:
39        #    function('aeozrijz\
40        #    earzer', hop)
41        discard = stmts[0]
42        self.assertIsInstance(discard, nodes.Discard)
43        self.assertEquals(discard.fromlineno, 4)
44        self.assertEquals(discard.tolineno, 5)
45        callfunc = discard.expr
46        self.assertIsInstance(callfunc, nodes.CallFunc)
47        self.assertEquals(callfunc.fromlineno, 4)
48        self.assertEquals(callfunc.tolineno, 5)
49        name = callfunc.node
50        self.assertIsInstance(name, nodes.Name)
51        self.assertEquals(name.fromlineno, 4)
52        self.assertEquals(name.tolineno, 4)
53        strarg = callfunc.args[0]
54        self.assertIsInstance(strarg, nodes.Const)
55        self.assertEquals(strarg.fromlineno, 5) # no way for this one (is 4 actually)
56        self.assertEquals(strarg.tolineno, 5)
57        namearg = callfunc.args[1]
58        self.assertIsInstance(namearg, nodes.Name)
59        self.assertEquals(namearg.fromlineno, 5)
60        self.assertEquals(namearg.tolineno, 5)
61        # on line 10:
62        #    fonction(1,
63        #             2,
64        #             3,
65        #             4)
66        discard = stmts[2]
67        self.assertIsInstance(discard, nodes.Discard)
68        self.assertEquals(discard.fromlineno, 10)
69        self.assertEquals(discard.tolineno, 13)
70        callfunc = discard.expr
71        self.assertIsInstance(callfunc, nodes.CallFunc)
72        self.assertEquals(callfunc.fromlineno, 10)
73        self.assertEquals(callfunc.tolineno, 13)
74        name = callfunc.node
75        self.assertIsInstance(name, nodes.Name)
76        self.assertEquals(name.fromlineno, 10)
77        self.assertEquals(name.tolineno, 10)
78        for i, arg in enumerate(callfunc.args):
79            self.assertIsInstance(arg, nodes.Const)
80            self.assertEquals(arg.fromlineno, 10+i)
81            self.assertEquals(arg.tolineno, 10+i)
82
83    def test_function_lineno(self):
84        stmts = self.astng.getChildNodes()[0].nodes
85        # on line 15:
86        #    def definition(a,
87        #                   b,
88        #                   c):
89        #        return a + b + c
90        function = stmts[3]
91        self.assertIsInstance(function, nodes.Function)
92        self.assertEquals(function.fromlineno, 15)
93        self.assertEquals(function.tolineno, 17)
94        code = function.code
95        self.assertIsInstance(code, nodes.Stmt)
96##         self.assertEquals(code.fromlineno, 18)
97##         self.assertEquals(code.tolineno, 18)
98        return_ = code.nodes[0]
99        self.assertIsInstance(return_, nodes.Return)
100        self.assertEquals(return_.fromlineno, 18)
101        self.assertEquals(return_.tolineno, 18)
102
103    def test_class_lineno(self):
104        stmts = self.astng.getChildNodes()[0].nodes
105        # on line 20:
106        #    class debile(dict,
107        #                 object):
108        #       pass
109        class_ = stmts[4]
110        self.assertIsInstance(class_, nodes.Class)
111        self.assertEquals(class_.fromlineno, 20)
112        self.assertEquals(class_.tolineno, 21)
113        code = class_.code
114        self.assertIsInstance(code, nodes.Stmt)
115##         self.assertEquals(code.fromlineno, 18)
116##         self.assertEquals(code.tolineno, 18)
117        pass_ = code.nodes[0]
118        self.assertIsInstance(pass_, nodes.Pass)
119        self.assertEquals(pass_.fromlineno, 22)
120        self.assertEquals(pass_.tolineno, 22)
121
122    def test_if_lineno(self):
123        stmts = self.astng.getChildNodes()[0].nodes
124        # on line 20:
125        #    if aaaa: pass
126        #    else:
127        #        aaaa,bbbb = 1,2
128        #        aaaa,bbbb = bbbb,aaaa
129        if_ = stmts[5]
130        self.assertIsInstance(if_, nodes.If)
131        self.assertEquals(if_.fromlineno, 24)
132        self.assertEquals(if_.tolineno, 24)
133        else_ = if_.else_
134        self.assertIsInstance(else_, nodes.Stmt)
135        self.assertEquals(else_.fromlineno, 25)
136        self.assertEquals(else_.tolineno, 27)
137
138       
139class BuilderTC(TestCase):
140       
141    def setUp(self):
142        self.builder = builder.ASTNGBuilder()
143       
144    def test_border_cases(self):
145        """check that a file with no trailing new line is parseable"""
146        self.builder.file_build('data/noendingnewline.py', 'data.noendingnewline')
147        self.assertRaises(builder.ASTNGBuildingException,
148                          self.builder.file_build, 'data/inexistant.py', 'whatever')
149       
150    def test_inspect_build(self):
151        """test astng tree build from a living object"""
152        import __builtin__
153        builtin_astng = self.builder.inspect_build(__builtin__)
154        fclass = builtin_astng['file']
155        self.assert_('name' in fclass)
156        self.assert_('mode' in fclass)
157        self.assert_('read' in fclass)
158        self.assert_(fclass.newstyle)
159        self.assert_(fclass.pytype(), '__builtin__.type')
160        self.assert_(isinstance(fclass['read'], nodes.Function))
161        self.assert_(isinstance(fclass['__doc__'], nodes.Const), fclass['__doc__'])
162        # check builtin function has argnames == None
163        dclass = builtin_astng['dict']
164        self.assertEquals(dclass['has_key'].argnames, None)
165        # just check type and object are there
166        builtin_astng.getattr('type')
167        builtin_astng.getattr('object')
168        # check open file alias
169        builtin_astng.getattr('open')
170        # check 'help' is there (defined dynamically by site.py)
171        builtin_astng.getattr('help')
172        # check property has __init__
173        pclass = builtin_astng['property']
174        self.assert_('__init__' in pclass)
175        #
176        import time
177        time_astng = self.builder.module_build(time)
178        self.assert_(time_astng)
179        #
180        unittest_astng = self.builder.inspect_build(unittest)
181        self.failUnless(isinstance(builtin_astng['None'], nodes.Const), builtin_astng['None'])
182        self.failUnless(isinstance(builtin_astng['Exception'], nodes.From), builtin_astng['Exception'])
183        self.failUnless(isinstance(builtin_astng['NotImplementedError'], nodes.From))
184
185       
186    def test_inspect_build2(self):
187        """test astng tree build from a living object"""
188        try:
189            from mx import DateTime
190        except ImportError:
191            self.skip('test skipped: mxDateTime is not available')
192        else:
193            dt_astng = self.builder.inspect_build(DateTime)
194            dt_astng.getattr('DateTime')
195            # this one is failing since DateTimeType.__module__ = 'builtins' !
196            #dt_astng.getattr('DateTimeType')
197
198    def test_inspect_build_instance(self):
199        """test astng tree build from a living object"""
200        import exceptions
201        builtin_astng = self.builder.inspect_build(exceptions)
202        fclass = builtin_astng['OSError']
203        # things like OSError.strerror are now (2.5) data descriptors on the
204        # class instead of entries in the __dict__ of an instance
205        if sys.version_info < (2, 5):
206            container = fclass.instance_attrs
207        else:
208            container = fclass
209        self.assert_('errno' in container)
210        self.assert_('strerror' in container)
211        self.assert_('filename' in container)
212
213    def test_inspect_build_type_object(self):
214        import __builtin__
215        builtin_astng = self.builder.inspect_build(__builtin__)
216       
217        infered = list(builtin_astng.igetattr('object'))
218        self.assertEquals(len(infered), 1)
219        infered = infered[0]
220        self.assertEquals(infered.name, 'object')
221        try:
222            infered.as_string()
223        except:
224            print repr(infered)
225           
226        infered = list(builtin_astng.igetattr('type'))
227        self.assertEquals(len(infered), 1)
228        infered = infered[0]
229        self.assertEquals(infered.name, 'type')
230        try:
231            infered.as_string()
232        except:
233            print repr(infered)
234       
235    def test_package_name(self):
236        """test base properties and method of a astng module"""
237        datap = self.builder.file_build('data/__init__.py', 'data')
238        self.assertEquals(datap.name, 'data')
239        self.assertEquals(datap.package, 1)
240        datap = self.builder.file_build('data/__init__.py', 'data.__init__')
241        self.assertEquals(datap.name, 'data')
242        self.assertEquals(datap.package, 1)
243
244    def test_object(self):
245        obj_astng = self.builder.inspect_build(object)
246        self.failUnless('__setattr__' in obj_astng)
247
248    def test_newstyle_detection(self):
249        data = '''
250class A:
251    "old style"
252       
253class B(A):
254    "old style"
255       
256class C(object):
257    "new style"
258       
259class D(C):
260    "new style"
261
262__metaclass__ = type
263
264class E(A):
265    "old style"
266   
267class F:
268    "new style"
269'''
270        mod_astng = self.builder.string_build(data, __name__, __file__)
271        self.failIf(mod_astng['A'].newstyle)
272        self.failIf(mod_astng['B'].newstyle)
273        self.failUnless(mod_astng['C'].newstyle)
274        self.failUnless(mod_astng['D'].newstyle)
275        self.failIf(mod_astng['E'].newstyle)
276        self.failUnless(mod_astng['F'].newstyle)
277
278    def test_globals(self):
279        data = '''
280CSTE = 1
281
282def update_global():
283    global CSTE
284    CSTE += 1
285
286def global_no_effect():
287    global CSTE2
288    print CSTE
289'''       
290        astng = self.builder.string_build(data, __name__, __file__)
291        self.failUnlessEqual(len(astng.getattr('CSTE')), 2)
292        self.failUnlessEqual(astng.getattr('CSTE')[0].source_line(), 2)
293        self.failUnlessEqual(astng.getattr('CSTE')[1].source_line(), 6)
294        self.assertRaises(nodes.NotFoundError,
295                          astng.getattr, 'CSTE2')
296        self.assertRaises(nodes.InferenceError,
297                          astng['global_no_effect'].ilookup('CSTE2').next)
298
299    def test_socket_build(self):
300        import socket
301        astng = self.builder.module_build(socket)
302        # XXX just check the first one. Actually 3 objects are infered (look at
303        # the socket module) but the last one as those attributes dynamically
304        # set and astng is missing this.
305        for fclass in astng.igetattr('socket'):
306            #print fclass.root().name, fclass.name, fclass.lineno
307            self.assert_('connect' in fclass)
308            self.assert_('send' in fclass)
309            self.assert_('close' in fclass)
310            break
311
312    if sys.version_info >= (2, 4):
313        def test_gen_expr_var_scope(self):
314            data = 'l = list(n for n in range(10))\n'
315            astng = self.builder.string_build(data, __name__, __file__)
316            # n unvailable touside gen expr scope
317            self.failIf('n' in astng)
318            # test n is inferable anyway
319            n = get_name_node(astng, 'n')
320            self.failIf(n.scope() is astng)
321            self.failUnlessEqual([i.__class__ for i in n.infer()],
322                                 [YES.__class__])
323       
324       
325class FileBuildTC(TestCase):
326
327    def setUp(self):
328        abuilder = builder.ASTNGBuilder()
329        self.module = abuilder.file_build('data/module.py', 'data.module')
330
331    def test_module_base_props(self):
332        """test base properties and method of a astng module"""
333        module = self.module
334        self.assertEquals(module.name, 'data.module')
335        self.assertEquals(module.doc, "test module for astng\n")
336        self.assertEquals(module.source_line(), 0)
337        self.assertEquals(module.parent, None)
338        self.assertEquals(module.frame(), module)
339        self.assertEquals(module.root(), module)
340        self.assertEquals(module.file, join(abspath(data.__path__[0]), 'module.py'))
341        self.assertEquals(module.pure_python, 1)
342        self.assertEquals(module.package, 0)
343        self.assert_(not module.is_statement())
344        self.assertEquals(module.statement(), module)
345        self.assertEquals(module.node.statement(), module)
346       
347    def test_module_locals(self):
348        """test the 'locals' dictionary of a astng module"""
349        module = self.module
350        _locals = module.locals
351        self.assertEquals(len(_locals), 17)
352        self.assert_(_locals is module.globals)
353        keys = _locals.keys()
354        keys.sort()
355        self.assertEquals(keys, ['MY_DICT', 'YO', 'YOUPI', '__dict__', 
356                                 '__doc__', '__file__', '__name__', '__revision__',
357                                 'clean', 'cvrtr', 'debuild', 'global_access',
358                                 'modutils', 'nested_args', 'os', 'redirect',
359                                 'spawn'])
360
361    def test_function_base_props(self):
362        """test base properties and method of a astng function"""
363        module = self.module
364        function = module['global_access']
365        self.assertEquals(function.name, 'global_access')
366        self.assertEquals(function.doc, 'function test')
367        self.assertEquals(function.source_line(), 15)
368        self.assert_(function.parent)
369        self.assertEquals(function.frame(), function)
370        self.assertEquals(function.parent.frame(), module)
371        self.assertEquals(function.root(), module)
372        self.assertEquals(function.argnames, ['key', 'val'])
373        self.assertEquals(function.type, 'function')
374