Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / astroid / tests / unittest_builder.py @ 745

History | View | Annotate | Download (28.2 KB)

1
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
3
#
4
# This file is part of astroid.
5
#
6
# astroid is free software: you can redistribute it and/or modify it
7
# under the terms of the GNU Lesser General Public License as published by the
8
# Free Software Foundation, either version 2.1 of the License, or (at your
9
# option) any later version.
10
#
11
# astroid is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
14
# for more details.
15
#
16
# You should have received a copy of the GNU Lesser General Public License along
17
# with astroid. If not, see <http://www.gnu.org/licenses/>.
18
"""tests for the astroid builder and rebuilder module"""
19

    
20
import os
21
import sys
22
import unittest
23

    
24
import six
25

    
26
from astroid import builder
27
from astroid import exceptions
28
from astroid import manager
29
from astroid import nodes
30
from astroid import test_utils
31
from astroid import util
32
from astroid.tests import resources
33

    
34
MANAGER = manager.AstroidManager()
35
BUILTINS = six.moves.builtins.__name__
36

    
37

    
38
class FromToLineNoTest(unittest.TestCase):
39

    
40
    def setUp(self):
41
        self.astroid = resources.build_file('data/format.py')
42

    
43
    def test_callfunc_lineno(self):
44
        stmts = self.astroid.body
45
        # on line 4:
46
        #    function('aeozrijz\
47
        #    earzer', hop)
48
        discard = stmts[0]
49
        self.assertIsInstance(discard, nodes.Expr)
50
        self.assertEqual(discard.fromlineno, 4)
51
        self.assertEqual(discard.tolineno, 5)
52
        callfunc = discard.value
53
        self.assertIsInstance(callfunc, nodes.Call)
54
        self.assertEqual(callfunc.fromlineno, 4)
55
        self.assertEqual(callfunc.tolineno, 5)
56
        name = callfunc.func
57
        self.assertIsInstance(name, nodes.Name)
58
        self.assertEqual(name.fromlineno, 4)
59
        self.assertEqual(name.tolineno, 4)
60
        strarg = callfunc.args[0]
61
        self.assertIsInstance(strarg, nodes.Const)
62
        if hasattr(sys, 'pypy_version_info'):
63
            lineno = 4
64
        else:
65
            lineno = 5 # no way for this one in CPython (is 4 actually)
66
        self.assertEqual(strarg.fromlineno, lineno)
67
        self.assertEqual(strarg.tolineno, lineno)
68
        namearg = callfunc.args[1]
69
        self.assertIsInstance(namearg, nodes.Name)
70
        self.assertEqual(namearg.fromlineno, 5)
71
        self.assertEqual(namearg.tolineno, 5)
72
        # on line 10:
73
        #    fonction(1,
74
        #             2,
75
        #             3,
76
        #             4)
77
        discard = stmts[2]
78
        self.assertIsInstance(discard, nodes.Expr)
79
        self.assertEqual(discard.fromlineno, 10)
80
        self.assertEqual(discard.tolineno, 13)
81
        callfunc = discard.value
82
        self.assertIsInstance(callfunc, nodes.Call)
83
        self.assertEqual(callfunc.fromlineno, 10)
84
        self.assertEqual(callfunc.tolineno, 13)
85
        name = callfunc.func
86
        self.assertIsInstance(name, nodes.Name)
87
        self.assertEqual(name.fromlineno, 10)
88
        self.assertEqual(name.tolineno, 10)
89
        for i, arg in enumerate(callfunc.args):
90
            self.assertIsInstance(arg, nodes.Const)
91
            self.assertEqual(arg.fromlineno, 10+i)
92
            self.assertEqual(arg.tolineno, 10+i)
93

    
94
    def test_function_lineno(self):
95
        stmts = self.astroid.body
96
        # on line 15:
97
        #    def definition(a,
98
        #                   b,
99
        #                   c):
100
        #        return a + b + c
101
        function = stmts[3]
102
        self.assertIsInstance(function, nodes.FunctionDef)
103
        self.assertEqual(function.fromlineno, 15)
104
        self.assertEqual(function.tolineno, 18)
105
        return_ = function.body[0]
106
        self.assertIsInstance(return_, nodes.Return)
107
        self.assertEqual(return_.fromlineno, 18)
108
        self.assertEqual(return_.tolineno, 18)
109
        if sys.version_info < (3, 0):
110
            self.assertEqual(function.blockstart_tolineno, 17)
111
        else:
112
            self.skipTest('FIXME  http://bugs.python.org/issue10445 '
113
                          '(no line number on function args)')
114

    
115
    def test_decorated_function_lineno(self):
116
        astroid = builder.parse('''
117
            @decorator
118
            def function(
119
                arg):
120
                print (arg)
121
            ''', __name__)
122
        function = astroid['function']
123
        self.assertEqual(function.fromlineno, 3) # XXX discussable, but that's what is expected by pylint right now
124
        self.assertEqual(function.tolineno, 5)
125
        self.assertEqual(function.decorators.fromlineno, 2)
126
        self.assertEqual(function.decorators.tolineno, 2)
127
        if sys.version_info < (3, 0):
128
            self.assertEqual(function.blockstart_tolineno, 4)
129
        else:
130
            self.skipTest('FIXME  http://bugs.python.org/issue10445 '
131
                          '(no line number on function args)')
132

    
133

    
134
    def test_class_lineno(self):
135
        stmts = self.astroid.body
136
        # on line 20:
137
        #    class debile(dict,
138
        #                 object):
139
        #       pass
140
        class_ = stmts[4]
141
        self.assertIsInstance(class_, nodes.ClassDef)
142
        self.assertEqual(class_.fromlineno, 20)
143
        self.assertEqual(class_.tolineno, 22)
144
        self.assertEqual(class_.blockstart_tolineno, 21)
145
        pass_ = class_.body[0]
146
        self.assertIsInstance(pass_, nodes.Pass)
147
        self.assertEqual(pass_.fromlineno, 22)
148
        self.assertEqual(pass_.tolineno, 22)
149

    
150
    def test_if_lineno(self):
151
        stmts = self.astroid.body
152
        # on line 20:
153
        #    if aaaa: pass
154
        #    else:
155
        #        aaaa,bbbb = 1,2
156
        #        aaaa,bbbb = bbbb,aaaa
157
        if_ = stmts[5]
158
        self.assertIsInstance(if_, nodes.If)
159
        self.assertEqual(if_.fromlineno, 24)
160
        self.assertEqual(if_.tolineno, 27)
161
        self.assertEqual(if_.blockstart_tolineno, 24)
162
        self.assertEqual(if_.orelse[0].fromlineno, 26)
163
        self.assertEqual(if_.orelse[1].tolineno, 27)
164

    
165
    def test_for_while_lineno(self):
166
        for code in ('''
167
            for a in range(4):
168
              print (a)
169
              break
170
            else:
171
              print ("bouh")
172
            ''', '''
173
            while a:
174
              print (a)
175
              break
176
            else:
177
              print ("bouh")
178
            '''):
179
            astroid = builder.parse(code, __name__)
180
            stmt = astroid.body[0]
181
            self.assertEqual(stmt.fromlineno, 2)
182
            self.assertEqual(stmt.tolineno, 6)
183
            self.assertEqual(stmt.blockstart_tolineno, 2)
184
            self.assertEqual(stmt.orelse[0].fromlineno, 6) # XXX
185
            self.assertEqual(stmt.orelse[0].tolineno, 6)
186

    
187
    def test_try_except_lineno(self):
188
        astroid = builder.parse('''
189
            try:
190
              print (a)
191
            except:
192
              pass
193
            else:
194
              print ("bouh")
195
            ''', __name__)
196
        try_ = astroid.body[0]
197
        self.assertEqual(try_.fromlineno, 2)
198
        self.assertEqual(try_.tolineno, 7)
199
        self.assertEqual(try_.blockstart_tolineno, 2)
200
        self.assertEqual(try_.orelse[0].fromlineno, 7) # XXX
201
        self.assertEqual(try_.orelse[0].tolineno, 7)
202
        hdlr = try_.handlers[0]
203
        self.assertEqual(hdlr.fromlineno, 4)
204
        self.assertEqual(hdlr.tolineno, 5)
205
        self.assertEqual(hdlr.blockstart_tolineno, 4)
206

    
207

    
208
    def test_try_finally_lineno(self):
209
        astroid = builder.parse('''
210
            try:
211
              print (a)
212
            finally:
213
              print ("bouh")
214
            ''', __name__)
215
        try_ = astroid.body[0]
216
        self.assertEqual(try_.fromlineno, 2)
217
        self.assertEqual(try_.tolineno, 5)
218
        self.assertEqual(try_.blockstart_tolineno, 2)
219
        self.assertEqual(try_.finalbody[0].fromlineno, 5) # XXX
220
        self.assertEqual(try_.finalbody[0].tolineno, 5)
221

    
222

    
223
    def test_try_finally_25_lineno(self):
224
        astroid = builder.parse('''
225
            try:
226
              print (a)
227
            except:
228
              pass
229
            finally:
230
              print ("bouh")
231
            ''', __name__)
232
        try_ = astroid.body[0]
233
        self.assertEqual(try_.fromlineno, 2)
234
        self.assertEqual(try_.tolineno, 7)
235
        self.assertEqual(try_.blockstart_tolineno, 2)
236
        self.assertEqual(try_.finalbody[0].fromlineno, 7) # XXX
237
        self.assertEqual(try_.finalbody[0].tolineno, 7)
238

    
239

    
240
    def test_with_lineno(self):
241
        astroid = builder.parse('''
242
            from __future__ import with_statement
243
            with file("/tmp/pouet") as f:
244
                print (f)
245
            ''', __name__)
246
        with_ = astroid.body[1]
247
        self.assertEqual(with_.fromlineno, 3)
248
        self.assertEqual(with_.tolineno, 4)
249
        self.assertEqual(with_.blockstart_tolineno, 3)
250

    
251

    
252
class BuilderTest(unittest.TestCase):
253

    
254
    def setUp(self):
255
        self.builder = builder.AstroidBuilder()
256

    
257
    def test_data_build_null_bytes(self):
258
        with self.assertRaises(exceptions.AstroidBuildingException):
259
            self.builder.string_build('\x00')
260

    
261
    def test_data_build_invalid_x_escape(self):
262
        with self.assertRaises(exceptions.AstroidBuildingException):
263
            self.builder.string_build('"\\x1"')
264

    
265
    def test_missing_newline(self):
266
        """check that a file with no trailing new line is parseable"""
267
        resources.build_file('data/noendingnewline.py')
268

    
269
    def test_missing_file(self):
270
        with self.assertRaises(exceptions.AstroidBuildingException):
271
            resources.build_file('data/inexistant.py')
272

    
273
    def test_inspect_build0(self):
274
        """test astroid tree build from a living object"""
275
        builtin_ast = MANAGER.ast_from_module_name(BUILTINS)
276
        if six.PY2:
277
            fclass = builtin_ast['file']
278
            self.assertIn('name', fclass)
279
            self.assertIn('mode', fclass)
280
            self.assertIn('read', fclass)
281
            self.assertTrue(fclass.newstyle)
282
            self.assertTrue(fclass.pytype(), '%s.type' % BUILTINS)
283
            self.assertIsInstance(fclass['read'], nodes.FunctionDef)
284
            # check builtin function has args.args == None
285
            dclass = builtin_ast['dict']
286
            self.assertIsNone(dclass['has_key'].args.args)
287
        # just check type and object are there
288
        builtin_ast.getattr('type')
289
        objectastroid = builtin_ast.getattr('object')[0]
290
        self.assertIsInstance(objectastroid.getattr('__new__')[0], nodes.FunctionDef)
291
        # check open file alias
292
        builtin_ast.getattr('open')
293
        # check 'help' is there (defined dynamically by site.py)
294
        builtin_ast.getattr('help')
295
        # check property has __init__
296
        pclass = builtin_ast['property']
297
        self.assertIn('__init__', pclass)
298
        self.assertIsInstance(builtin_ast['None'], nodes.Const)
299
        self.assertIsInstance(builtin_ast['True'], nodes.Const)
300
        self.assertIsInstance(builtin_ast['False'], nodes.Const)
301
        if six.PY3:
302
            self.assertIsInstance(builtin_ast['Exception'], nodes.ClassDef)
303
            self.assertIsInstance(builtin_ast['NotImplementedError'], nodes.ClassDef)
304
        else:
305
            self.assertIsInstance(builtin_ast['Exception'], nodes.ImportFrom)
306
            self.assertIsInstance(builtin_ast['NotImplementedError'], nodes.ImportFrom)
307

    
308
    def test_inspect_build1(self):
309
        time_ast = MANAGER.ast_from_module_name('time')
310
        self.assertTrue(time_ast)
311
        self.assertEqual(time_ast['time'].args.defaults, [])
312

    
313
    if os.name == 'java':
314
        test_inspect_build1 = unittest.expectedFailure(test_inspect_build1)
315

    
316
    def test_inspect_build2(self):
317
        """test astroid tree build from a living object"""
318
        try:
319
            from mx import DateTime
320
        except ImportError:
321
            self.skipTest('test skipped: mxDateTime is not available')
322
        else:
323
            dt_ast = self.builder.inspect_build(DateTime)
324
            dt_ast.getattr('DateTime')
325
            # this one is failing since DateTimeType.__module__ = 'builtins' !
326
            #dt_ast.getattr('DateTimeType')
327

    
328
    def test_inspect_build3(self):
329
        self.builder.inspect_build(unittest)
330

    
331
    @test_utils.require_version(maxver='3.0')
332
    def test_inspect_build_instance(self):
333
        """test astroid tree build from a living object"""
334
        import exceptions
335
        builtin_ast = self.builder.inspect_build(exceptions)
336
        fclass = builtin_ast['OSError']
337
        # things like OSError.strerror are now (2.5) data descriptors on the
338
        # class instead of entries in the __dict__ of an instance
339
        container = fclass
340
        self.assertIn('errno', container)
341
        self.assertIn('strerror', container)
342
        self.assertIn('filename', container)
343

    
344
    def test_inspect_build_type_object(self):
345
        builtin_ast = MANAGER.ast_from_module_name(BUILTINS)
346

    
347
        inferred = list(builtin_ast.igetattr('object'))
348
        self.assertEqual(len(inferred), 1)
349
        inferred = inferred[0]
350
        self.assertEqual(inferred.name, 'object')
351
        inferred.as_string() # no crash test
352

    
353
        inferred = list(builtin_ast.igetattr('type'))
354
        self.assertEqual(len(inferred), 1)
355
        inferred = inferred[0]
356
        self.assertEqual(inferred.name, 'type')
357
        inferred.as_string() # no crash test
358

    
359
    def test_inspect_transform_module(self):
360
        # ensure no cached version of the time module
361
        MANAGER._mod_file_cache.pop(('time', None), None)
362
        MANAGER.astroid_cache.pop('time', None)
363
        def transform_time(node):
364
            if node.name == 'time':
365
                node.transformed = True
366
        MANAGER.register_transform(nodes.Module, transform_time)
367
        try:
368
            time_ast = MANAGER.ast_from_module_name('time')
369
            self.assertTrue(getattr(time_ast, 'transformed', False))
370
        finally:
371
            MANAGER.unregister_transform(nodes.Module, transform_time)
372

    
373
    def test_package_name(self):
374
        """test base properties and method of a astroid module"""
375
        datap = resources.build_file('data/__init__.py', 'data')
376
        self.assertEqual(datap.name, 'data')
377
        self.assertEqual(datap.package, 1)
378
        datap = resources.build_file('data/__init__.py', 'data.__init__')
379
        self.assertEqual(datap.name, 'data')
380
        self.assertEqual(datap.package, 1)
381

    
382
    def test_yield_parent(self):
383
        """check if we added discard nodes as yield parent (w/ compiler)"""
384
        code = """
385
            def yiell(): #@
386
                yield 0
387
                if noe:
388
                    yield more
389
        """
390
        func = test_utils.extract_node(code)
391
        self.assertIsInstance(func, nodes.FunctionDef)
392
        stmt = func.body[0]
393
        self.assertIsInstance(stmt, nodes.Expr)
394
        self.assertIsInstance(stmt.value, nodes.Yield)
395
        self.assertIsInstance(func.body[1].body[0], nodes.Expr)
396
        self.assertIsInstance(func.body[1].body[0].value, nodes.Yield)
397

    
398
    def test_object(self):
399
        obj_ast = self.builder.inspect_build(object)
400
        self.assertIn('__setattr__', obj_ast)
401

    
402
    def test_newstyle_detection(self):
403
        data = '''
404
            class A:
405
                "old style"
406

407
            class B(A):
408
                "old style"
409

410
            class C(object):
411
                "new style"
412

413
            class D(C):
414
                "new style"
415

416
            __metaclass__ = type
417

418
            class E(A):
419
                "old style"
420

421
            class F:
422
                "new style"
423
        '''
424
        mod_ast = builder.parse(data, __name__)
425
        if six.PY3:
426
            self.assertTrue(mod_ast['A'].newstyle)
427
            self.assertTrue(mod_ast['B'].newstyle)
428
            self.assertTrue(mod_ast['E'].newstyle)
429
        else:
430
            self.assertFalse(mod_ast['A'].newstyle)
431
            self.assertFalse(mod_ast['B'].newstyle)
432
            self.assertFalse(mod_ast['E'].newstyle)
433
        self.assertTrue(mod_ast['C'].newstyle)
434
        self.assertTrue(mod_ast['D'].newstyle)
435
        self.assertTrue(mod_ast['F'].newstyle)
436

    
437
    def test_globals(self):
438
        data = '''
439
            CSTE = 1
440

441
            def update_global():
442
                global CSTE
443
                CSTE += 1
444

445
            def global_no_effect():
446
                global CSTE2
447
                print (CSTE)
448
        '''
449
        astroid = builder.parse(data, __name__)
450
        self.assertEqual(len(astroid.getattr('CSTE')), 2)
451
        self.assertIsInstance(astroid.getattr('CSTE')[0], nodes.AssignName)
452
        self.assertEqual(astroid.getattr('CSTE')[0].fromlineno, 2)
453
        self.assertEqual(astroid.getattr('CSTE')[1].fromlineno, 6)
454
        with self.assertRaises(exceptions.NotFoundError):
455
            astroid.getattr('CSTE2')
456
        with self.assertRaises(exceptions.InferenceError):
457
            next(astroid['global_no_effect'].ilookup('CSTE2'))
458

    
459
    @unittest.skipIf(os.name == 'java',
460
                     'This test is skipped on Jython, because the '
461
                     'socket object is patched later on with the '
462
                     'methods we are looking for. Since we do not '
463
                     'understand setattr in for loops yet, we skip this')
464
    def test_socket_build(self):
465
        import socket
466
        astroid = self.builder.module_build(socket)
467
        # XXX just check the first one. Actually 3 objects are inferred (look at
468
        # the socket module) but the last one as those attributes dynamically
469
        # set and astroid is missing this.
470
        for fclass in astroid.igetattr('socket'):
471
            self.assertIn('connect', fclass)
472
            self.assertIn('send', fclass)
473
            self.assertIn('close', fclass)
474
            break
475

    
476
    def test_gen_expr_var_scope(self):
477
        data = 'l = list(n for n in range(10))\n'
478
        astroid = builder.parse(data, __name__)
479
        # n unavailable outside gen expr scope
480
        self.assertNotIn('n', astroid)
481
        # test n is inferable anyway
482
        n = test_utils.get_name_node(astroid, 'n')
483
        self.assertIsNot(n.scope(), astroid)
484
        self.assertEqual([i.__class__ for i in n.infer()],
485
                         [util.YES.__class__])
486

    
487
    def test_no_future_imports(self):
488
        mod = builder.parse("import sys")
489
        self.assertEqual(set(), mod._future_imports)
490

    
491
    def test_future_imports(self):
492
        mod = builder.parse("from __future__ import print_function")
493
        self.assertEqual(set(['print_function']), mod._future_imports)
494

    
495
    def test_two_future_imports(self):
496
        mod = builder.parse("""
497
            from __future__ import print_function
498
            from __future__ import absolute_import
499
            """)
500
        self.assertEqual(set(['print_function', 'absolute_import']), mod._future_imports)
501

    
502
    def test_inferred_build(self):
503
        code = '''
504
            class A: pass
505
            A.type = "class"
506

507
            def A_assign_type(self):
508
                print (self)
509
            A.assign_type = A_assign_type
510
            '''
511
        astroid = builder.parse(code)
512
        lclass = list(astroid.igetattr('A'))
513
        self.assertEqual(len(lclass), 1)
514
        lclass = lclass[0]
515
        self.assertIn('assign_type', lclass._locals)
516
        self.assertIn('type', lclass._locals)
517

    
518
    def test_augassign_attr(self):
519
        builder.parse("""
520
            class Counter:
521
                v = 0
522
                def inc(self):
523
                    self.v += 1
524
            """, __name__)
525
        # TODO: Check self.v += 1 generate AugAssign(AssAttr(...)),
526
        # not AugAssign(GetAttr(AssName...))
527

    
528
    def test_inferred_dont_pollute(self):
529
        code = '''
530
            def func(a=None):
531
                a.custom_attr = 0
532
            def func2(a={}):
533
                a.custom_attr = 0
534
            '''
535
        builder.parse(code)
536
        nonetype = nodes.const_factory(None)
537
        self.assertNotIn('custom_attr', nonetype._locals)
538
        self.assertNotIn('custom_attr', nonetype._instance_attrs)
539
        nonetype = nodes.const_factory({})
540
        self.assertNotIn('custom_attr', nonetype._locals)
541
        self.assertNotIn('custom_attr', nonetype._instance_attrs)
542

    
543
    def test_asstuple(self):
544
        code = 'a, b = range(2)'
545
        astroid = builder.parse(code)
546
        self.assertIn('b', astroid._locals)
547
        code = '''
548
            def visit_if(self, node):
549
                node.test, body = node.tests[0]
550
            '''
551
        astroid = builder.parse(code)
552
        self.assertIn('body', astroid['visit_if']._locals)
553

    
554
    def test_build_constants(self):
555
        '''test expected values of constants after rebuilding'''
556
        code = '''
557
            def func():
558
                return None
559
                return
560
                return 'None'
561
            '''
562
        astroid = builder.parse(code)
563
        none, nothing, chain = [ret.value for ret in astroid.body[0].body]
564
        self.assertIsInstance(none, nodes.Const)
565
        self.assertIsNone(none.value)
566
        self.assertIsNone(nothing)
567
        self.assertIsInstance(chain, nodes.Const)
568
        self.assertEqual(chain.value, 'None')
569

    
570
    def test_not_implemented(self):
571
        node = test_utils.extract_node('''
572
        NotImplemented #@
573
        ''')
574
        inferred = next(node.infer())
575
        self.assertIsInstance(inferred, nodes.Const)
576
        self.assertEqual(inferred.value, NotImplemented)
577

    
578

    
579
class FileBuildTest(unittest.TestCase):
580
    def setUp(self):
581
        self.module = resources.build_file('data/module.py', 'data.module')
582

    
583
    def test_module_base_props(self):
584
        """test base properties and method of a astroid module"""
585
        module = self.module
586
        self.assertEqual(module.name, 'data.module')
587
        self.assertEqual(module.doc, "test module for astroid\n")
588
        self.assertEqual(module.fromlineno, 0)
589
        self.assertIsNone(module.parent)
590
        self.assertEqual(module.frame(), module)
591
        self.assertEqual(module.root(), module)
592
        self.assertEqual(module.source_file, os.path.abspath(resources.find('data/module.py')))
593
        self.assertEqual(module.pure_python, 1)
594
        self.assertEqual(module.package, 0)
595
        self.assertFalse(module.is_statement)
596
        self.assertEqual(module.statement(), module)
597
        self.assertEqual(module.statement(), module)
598

    
599
    def test_module_locals(self):
600
        """test the 'locals' dictionary of a astroid module"""
601
        module = self.module
602
        _locals = module._locals
603
        self.assertIs(_locals, module._globals)
604
        keys = sorted(_locals.keys())
605
        should = ['MY_DICT', 'NameNode', 'YO', 'YOUPI',
606
                  '__revision__', 'global_access', 'modutils', 'four_args',
607
                  'os', 'redirect']
608
        should.sort()
609
        self.assertEqual(keys, sorted(should))
610

    
611
    def test_function_base_props(self):
612
        """test base properties and method of a astroid function"""
613
        module = self.module
614
        function = module['global_access']
615
        self.assertEqual(function.name, 'global_access')
616
        self.assertEqual(function.doc, 'function test')
617
        self.assertEqual(function.fromlineno, 11)
618
        self.assertTrue(function.parent)
619
        self.assertEqual(function.frame(), function)
620
        self.assertEqual(function.parent.frame(), module)
621
        self.assertEqual(function.root(), module)
622
        self.assertEqual([n.name for n in function.args.args], ['key', 'val'])
623
        self.assertEqual(function.type, 'function')
624

    
625
    def test_function_locals(self):
626
        """test the 'locals' dictionary of a astroid function"""
627
        _locals = self.module['global_access']._locals
628
        self.assertEqual(len(_locals), 4)
629
        keys = sorted(_locals.keys())
630
        self.assertEqual(keys, ['i', 'key', 'local', 'val'])
631

    
632
    def test_class_base_props(self):
633
        """test base properties and method of a astroid class"""
634
        module = self.module
635
        klass = module['YO']
636
        self.assertEqual(klass.name, 'YO')
637
        self.assertEqual(klass.doc, 'hehe')
638
        self.assertEqual(klass.fromlineno, 25)
639
        self.assertTrue(klass.parent)
640
        self.assertEqual(klass.frame(), klass)
641
        self.assertEqual(klass.parent.frame(), module)
642
        self.assertEqual(klass.root(), module)
643
        self.assertEqual(klass.basenames, [])
644
        if six.PY3:
645
            self.assertTrue(klass.newstyle)
646
        else:
647
            self.assertFalse(klass.newstyle)
648

    
649
    def test_class_locals(self):
650
        """test the 'locals' dictionary of a astroid class"""
651
        module = self.module
652
        klass1 = module['YO']
653
        locals1 = klass1._locals
654
        keys = sorted(locals1.keys())
655
        self.assertEqual(keys, ['__init__', 'a'])
656
        klass2 = module['YOUPI']
657
        locals2 = klass2._locals
658
        keys = locals2.keys()
659
        self.assertEqual(sorted(keys),
660
                         ['__init__', 'class_attr', 'class_method',
661
                          'method', 'static_method'])
662

    
663
    def test_class_instance_attrs(self):
664
        module = self.module
665
        klass1 = module['YO']
666
        klass2 = module['YOUPI']
667
        self.assertEqual(list(klass1._instance_attrs.keys()), ['yo'])
668
        self.assertEqual(list(klass2._instance_attrs.keys()), ['member'])
669

    
670
    def test_class_basenames(self):
671
        module = self.module
672
        klass1 = module['YO']
673
        klass2 = module['YOUPI']
674
        self.assertEqual(klass1.basenames, [])
675
        self.assertEqual(klass2.basenames, ['YO'])
676

    
677
    def test_method_base_props(self):
678
        """test base properties and method of a astroid method"""
679
        klass2 = self.module['YOUPI']
680
        # "normal" method
681
        method = klass2['method']
682
        self.assertEqual(method.name, 'method')
683
        self.assertEqual([n.name for n in method.args.args], ['self'])
684
        self.assertEqual(method.doc, 'method test')
685
        self.assertEqual(method.fromlineno, 47)
686
        self.assertEqual(method.type, 'method')
687
        # class method
688
        method = klass2['class_method']
689
        self.assertEqual([n.name for n in method.args.args], ['cls'])
690
        self.assertEqual(method.type, 'classmethod')
691
        # static method
692
        method = klass2['static_method']
693
        self.assertEqual(method.args.args, [])
694
        self.assertEqual(method.type, 'staticmethod')
695

    
696
    def test_method_locals(self):
697
        """test the 'locals' dictionary of a astroid method"""
698
        method = self.module['YOUPI']['method']
699
        _locals = method._locals
700
        keys = sorted(_locals)
701
        if sys.version_info < (3, 0):
702
            self.assertEqual(len(_locals), 5)
703
            self.assertEqual(keys, ['a', 'autre', 'b', 'local', 'self'])
704
        else:# ListComp variables are no more accessible outside
705
            self.assertEqual(len(_locals), 3)
706
            self.assertEqual(keys, ['autre', 'local', 'self'])
707

    
708

    
709
class ModuleBuildTest(resources.SysPathSetup, FileBuildTest):
710

    
711
    def setUp(self):
712
        super(ModuleBuildTest, self).setUp()
713
        abuilder = builder.AstroidBuilder()
714
        try:
715
            import data.module
716
        except ImportError:
717
            # Make pylint happy.
718
            self.skipTest('Unable to load data.module')
719
        else:
720
            self.module = abuilder.module_build(data.module, 'data.module')
721

    
722
@unittest.skipIf(six.PY3, "guess_encoding not used on Python 3")
723
class TestGuessEncoding(unittest.TestCase):
724
    def setUp(self):
725
        self.guess_encoding = builder._guess_encoding
726

    
727
    def testEmacs(self):
728
        e = self.guess_encoding('# -*- coding: UTF-8  -*-')
729
        self.assertEqual(e, 'UTF-8')
730
        e = self.guess_encoding('# -*- coding:UTF-8 -*-')
731
        self.assertEqual(e, 'UTF-8')
732
        e = self.guess_encoding('''
733
        ### -*- coding: ISO-8859-1  -*-
734
        ''')
735
        self.assertEqual(e, 'ISO-8859-1')
736
        e = self.guess_encoding('''
737

738
        ### -*- coding: ISO-8859-1  -*-
739
        ''')
740
        self.assertIsNone(e)
741

    
742
    def testVim(self):
743
        e = self.guess_encoding('# vim:fileencoding=UTF-8')
744
        self.assertEqual(e, 'UTF-8')
745
        e = self.guess_encoding('''
746
        ### vim:fileencoding=ISO-8859-1
747
        ''')
748
        self.assertEqual(e, 'ISO-8859-1')
749
        e = self.guess_encoding('''
750

751
        ### vim:fileencoding= ISO-8859-1
752
        ''')
753
        self.assertIsNone(e)
754

    
755
    def test_wrong_coding(self):
756
        # setting "coding" varaible
757
        e = self.guess_encoding("coding = UTF-8")
758
        self.assertIsNone(e)
759
        # setting a dictionnary entry
760
        e = self.guess_encoding("coding:UTF-8")
761
        self.assertIsNone(e)
762
        # setting an arguement
763
        e = self.guess_encoding("def do_something(a_word_with_coding=None):")
764
        self.assertIsNone(e)
765

    
766
    def testUTF8(self):
767
        e = self.guess_encoding('\xef\xbb\xbf any UTF-8 data')
768
        self.assertEqual(e, 'UTF-8')
769
        e = self.guess_encoding(' any UTF-8 data \xef\xbb\xbf')
770
        self.assertIsNone(e)
771

    
772

    
773
if __name__ == '__main__':
774
    unittest.main()