OLD | NEW |
(Empty) | |
| 1 try: |
| 2 import unittest2 as unittest |
| 3 except ImportError: |
| 4 import unittest |
| 5 |
| 6 import rope.base.evaluate |
| 7 from rope.base import libutils |
| 8 from rope.base import exceptions, worder, codeanalyze |
| 9 from rope.base.codeanalyze import (SourceLinesAdapter, |
| 10 LogicalLineFinder, get_block_start) |
| 11 from ropetest import testutils |
| 12 |
| 13 |
| 14 class SourceLinesAdapterTest(unittest.TestCase): |
| 15 |
| 16 def setUp(self): |
| 17 super(SourceLinesAdapterTest, self).setUp() |
| 18 |
| 19 def tearDown(self): |
| 20 super(SourceLinesAdapterTest, self).tearDown() |
| 21 |
| 22 def test_source_lines_simple(self): |
| 23 to_lines = SourceLinesAdapter('line1\nline2\n') |
| 24 self.assertEquals('line1', to_lines.get_line(1)) |
| 25 self.assertEquals('line2', to_lines.get_line(2)) |
| 26 self.assertEquals('', to_lines.get_line(3)) |
| 27 self.assertEquals(3, to_lines.length()) |
| 28 |
| 29 def test_source_lines_get_line_number(self): |
| 30 to_lines = SourceLinesAdapter('line1\nline2\n') |
| 31 self.assertEquals(1, to_lines.get_line_number(0)) |
| 32 self.assertEquals(1, to_lines.get_line_number(5)) |
| 33 self.assertEquals(2, to_lines.get_line_number(7)) |
| 34 self.assertEquals(3, to_lines.get_line_number(12)) |
| 35 |
| 36 def test_source_lines_get_line_start(self): |
| 37 to_lines = SourceLinesAdapter('line1\nline2\n') |
| 38 self.assertEquals(0, to_lines.get_line_start(1)) |
| 39 self.assertEquals(6, to_lines.get_line_start(2)) |
| 40 self.assertEquals(12, to_lines.get_line_start(3)) |
| 41 |
| 42 def test_source_lines_get_line_end(self): |
| 43 to_lines = SourceLinesAdapter('line1\nline2\n') |
| 44 self.assertEquals(5, to_lines.get_line_end(1)) |
| 45 self.assertEquals(11, to_lines.get_line_end(2)) |
| 46 self.assertEquals(12, to_lines.get_line_end(3)) |
| 47 |
| 48 def test_source_lines_last_line_with_no_new_line(self): |
| 49 to_lines = SourceLinesAdapter('line1') |
| 50 self.assertEquals(1, to_lines.get_line_number(5)) |
| 51 |
| 52 |
| 53 class WordRangeFinderTest(unittest.TestCase): |
| 54 |
| 55 def setUp(self): |
| 56 super(WordRangeFinderTest, self).setUp() |
| 57 |
| 58 def tearDown(self): |
| 59 super(WordRangeFinderTest, self).tearDown() |
| 60 |
| 61 def _find_primary(self, code, offset): |
| 62 word_finder = worder.Worder(code) |
| 63 result = word_finder.get_primary_at(offset) |
| 64 return result |
| 65 |
| 66 def test_keyword_before_parens(self): |
| 67 code = 'if (a_var).an_attr:\n pass\n' |
| 68 self.assertEquals('(a_var).an_attr', |
| 69 self._find_primary(code, code.index(':'))) |
| 70 |
| 71 def test_inside_parans(self): |
| 72 code = 'a_func(a_var)' |
| 73 self.assertEquals('a_var', self._find_primary(code, 10)) |
| 74 |
| 75 def test_simple_names(self): |
| 76 code = 'a_var = 10' |
| 77 self.assertEquals('a_var', self._find_primary(code, 3)) |
| 78 |
| 79 def test_function_calls(self): |
| 80 code = 'sample_function()' |
| 81 self.assertEquals('sample_function', self._find_primary(code, 10)) |
| 82 |
| 83 def test_attribute_accesses(self): |
| 84 code = 'a_var.an_attr' |
| 85 self.assertEquals('a_var.an_attr', self._find_primary(code, 10)) |
| 86 |
| 87 def test_word_finder_on_word_beginning(self): |
| 88 code = 'print a_var\n' |
| 89 word_finder = worder.Worder(code) |
| 90 result = word_finder.get_word_at(code.index('a_var')) |
| 91 self.assertEquals('a_var', result) |
| 92 |
| 93 def test_word_finder_on_primary_beginning(self): |
| 94 code = 'print a_var\n' |
| 95 result = self._find_primary(code, code.index('a_var')) |
| 96 self.assertEquals('a_var', result) |
| 97 |
| 98 def test_word_finder_on_word_ending(self): |
| 99 code = 'print a_var\n' |
| 100 word_finder = worder.Worder(code) |
| 101 result = word_finder.get_word_at(code.index('a_var') + 5) |
| 102 self.assertEquals('a_var', result) |
| 103 |
| 104 def test_word_finder_on_primary_ending(self): |
| 105 code = 'print a_var\n' |
| 106 result = self._find_primary(code, code.index('a_var') + 5) |
| 107 self.assertEquals('a_var', result) |
| 108 |
| 109 def test_word_finder_on_primaries_with_dots_inside_parens(self): |
| 110 code = '(a_var.\nattr)' |
| 111 result = self._find_primary(code, code.index('attr') + 1) |
| 112 self.assertEquals('a_var.\nattr', result) |
| 113 |
| 114 def test_strings(self): |
| 115 code = '"a string".split()' |
| 116 self.assertEquals('"a string".split', self._find_primary(code, 14)) |
| 117 |
| 118 def test_function_calls2(self): |
| 119 code = 'file("afile.txt").read()' |
| 120 self.assertEquals('file("afile.txt").read', |
| 121 self._find_primary(code, 18)) |
| 122 |
| 123 def test_parens(self): |
| 124 code = '("afile.txt").split()' |
| 125 self.assertEquals('("afile.txt").split', self._find_primary(code, 18)) |
| 126 |
| 127 def test_function_with_no_param(self): |
| 128 code = 'AClass().a_func()' |
| 129 self.assertEquals('AClass().a_func', self._find_primary(code, 12)) |
| 130 |
| 131 def test_function_with_multiple_param(self): |
| 132 code = 'AClass(a_param, another_param, "a string").a_func()' |
| 133 self.assertEquals('AClass(a_param, another_param, "a string").a_func', |
| 134 self._find_primary(code, 44)) |
| 135 |
| 136 def test_param_expressions(self): |
| 137 code = 'AClass(an_object.an_attr).a_func()' |
| 138 self.assertEquals('an_object.an_attr', self._find_primary(code, 20)) |
| 139 |
| 140 def test_string_parens(self): |
| 141 code = 'a_func("(").an_attr' |
| 142 self.assertEquals('a_func("(").an_attr', self._find_primary(code, 16)) |
| 143 |
| 144 def test_extra_spaces(self): |
| 145 code = 'a_func ( "(" ) . an_attr' |
| 146 self.assertEquals('a_func ( "(" ) . an_attr', |
| 147 self._find_primary(code, 26)) |
| 148 |
| 149 def test_functions_on_ending_parens(self): |
| 150 code = 'A()' |
| 151 self.assertEquals('A()', self._find_primary(code, 2)) |
| 152 |
| 153 def test_splitted_statement(self): |
| 154 word_finder = worder.Worder('an_object.an_attr') |
| 155 self.assertEquals(('an_object', 'an_at', 10), |
| 156 word_finder.get_splitted_primary_before(15)) |
| 157 |
| 158 def test_empty_splitted_statement(self): |
| 159 word_finder = worder.Worder('an_attr') |
| 160 self.assertEquals(('', 'an_at', 0), |
| 161 word_finder.get_splitted_primary_before(5)) |
| 162 |
| 163 def test_empty_splitted_statement2(self): |
| 164 word_finder = worder.Worder('an_object.') |
| 165 self.assertEquals(('an_object', '', 10), |
| 166 word_finder.get_splitted_primary_before(10)) |
| 167 |
| 168 def test_empty_splitted_statement3(self): |
| 169 word_finder = worder.Worder('') |
| 170 self.assertEquals(('', '', 0), |
| 171 word_finder.get_splitted_primary_before(0)) |
| 172 |
| 173 def test_empty_splitted_statement4(self): |
| 174 word_finder = worder.Worder('a_var = ') |
| 175 self.assertEquals(('', '', 8), |
| 176 word_finder.get_splitted_primary_before(8)) |
| 177 |
| 178 def test_empty_splitted_statement5(self): |
| 179 word_finder = worder.Worder('a.') |
| 180 self.assertEquals(('a', '', 2), |
| 181 word_finder.get_splitted_primary_before(2)) |
| 182 |
| 183 def test_operators_inside_parens(self): |
| 184 code = '(a_var + another_var).reverse()' |
| 185 self.assertEquals('(a_var + another_var).reverse', |
| 186 self._find_primary(code, 25)) |
| 187 |
| 188 def test_dictionaries(self): |
| 189 code = 'print {1: "one", 2: "two"}.keys()' |
| 190 self.assertEquals('{1: "one", 2: "two"}.keys', |
| 191 self._find_primary(code, 29)) |
| 192 |
| 193 def test_following_parens(self): |
| 194 code = 'a_var = a_func()()' |
| 195 result = self._find_primary(code, code.index(')(') + 3) |
| 196 self.assertEquals('a_func()()', result) |
| 197 |
| 198 def test_comments_for_finding_statements(self): |
| 199 code = '# var2 . \n var3' |
| 200 self.assertEquals('var3', self._find_primary(code, code.index('3'))) |
| 201 |
| 202 def test_str_in_comments_for_finding_statements(self): |
| 203 code = '# "var2" . \n var3' |
| 204 self.assertEquals('var3', self._find_primary(code, code.index('3'))) |
| 205 |
| 206 def test_comments_for_finding_statements2(self): |
| 207 code = 'var1 + "# var2".\n var3' |
| 208 self.assertEquals('var3', self._find_primary(code, 21)) |
| 209 |
| 210 def test_comments_for_finding_statements3(self): |
| 211 code = '"" + # var2.\n var3' |
| 212 self.assertEquals('var3', self._find_primary(code, 21)) |
| 213 |
| 214 def test_import_statement_finding(self): |
| 215 code = 'import mod\na_var = 10\n' |
| 216 word_finder = worder.Worder(code) |
| 217 self.assertTrue(word_finder.is_import_statement(code.index('mod') + 1)) |
| 218 self.assertFalse(word_finder.is_import_statement( |
| 219 code.index('a_var') + 1)) |
| 220 |
| 221 def test_import_statement_finding2(self): |
| 222 code = 'import a.b.c.d\nresult = a.b.c.d.f()\n' |
| 223 word_finder = worder.Worder(code) |
| 224 self.assertFalse(word_finder.is_import_statement(code.rindex('d') + 1)) |
| 225 |
| 226 def test_word_parens_range(self): |
| 227 code = 's = str()\ns.title()\n' |
| 228 word_finder = worder.Worder(code) |
| 229 result = word_finder.get_word_parens_range(code.rindex('()') - 1) |
| 230 self.assertEquals((len(code) - 3, len(code) - 1), result) |
| 231 |
| 232 def test_getting_primary_before_get_index(self): |
| 233 code = '\na = (b + c).d[0]()\n' |
| 234 result = self._find_primary(code, len(code) - 2) |
| 235 self.assertEquals('(b + c).d[0]()', result) |
| 236 |
| 237 def test_getting_primary_and_strings_at_the_end_of_line(self): |
| 238 code = 'f(\'\\\'\')\n' |
| 239 result = self._find_primary(code, len(code) - 1) # noqa |
| 240 |
| 241 def test_getting_primary_and_not_crossing_newlines(self): |
| 242 code = '\na = (b + c)\n(4 + 1).x\n' |
| 243 result = self._find_primary(code, len(code) - 1) |
| 244 self.assertEquals('(4 + 1).x', result) |
| 245 |
| 246 # XXX: cancatenated string literals |
| 247 def xxx_test_getting_primary_cancatenating_strs(self): |
| 248 code = 's = "a"\n"b" "c"\n' |
| 249 result = self._find_primary(code, len(code) - 2) |
| 250 self.assertEquals('"b" "c"', result) |
| 251 |
| 252 def test_is_a_function_being_called_with_parens_on_next_line(self): |
| 253 code = 'func\n(1, 2)\n' |
| 254 word_finder = worder.Worder(code) |
| 255 self.assertFalse(word_finder.is_a_function_being_called(1)) |
| 256 |
| 257 # XXX: handling triple quotes |
| 258 def xxx_test_triple_quotes(self): |
| 259 code = 's = """string"""\n' |
| 260 result = self._find_primary(code, len(code) - 1) |
| 261 self.assertEquals('"""string"""', result) |
| 262 |
| 263 def test_triple_quotes_spanning_multiple_lines(self): |
| 264 code = 's = """\\\nl1\nl2\n """\n' |
| 265 result = self._find_primary(code, len(code) - 2) |
| 266 self.assertEquals('"""\\\nl1\nl2\n """', result) |
| 267 |
| 268 def test_get_word_parens_range_and_string_literals(self): |
| 269 code = 'f(1, ")", 2)\n' |
| 270 word_finder = worder.Worder(code) |
| 271 result = word_finder.get_word_parens_range(0) |
| 272 self.assertEquals((1, len(code) - 1), result) |
| 273 |
| 274 def test_is_assigned_here_for_equality_test(self): |
| 275 code = 'a == 1\n' |
| 276 word_finder = worder.Worder(code) |
| 277 self.assertFalse(word_finder.is_assigned_here(0)) |
| 278 |
| 279 def test_is_assigned_here_for_not_equal_test(self): |
| 280 code = 'a != 1\n' |
| 281 word_finder = worder.Worder(code) |
| 282 self.assertFalse(word_finder.is_assigned_here(0)) |
| 283 |
| 284 # XXX: is_assigned_here should work for tuple assignments |
| 285 def xxx_test_is_assigned_here_for_tuple_assignment(self): |
| 286 code = 'a, b = (1, 2)\n' |
| 287 word_finder = worder.Worder(code) |
| 288 self.assertTrue(word_finder.is_assigned_here(0)) |
| 289 |
| 290 def test_is_from_with_from_import_and_multiline_parens(self): |
| 291 code = 'from mod import \\\n (f,\n g, h)\n' |
| 292 word_finder = worder.Worder(code) |
| 293 self.assertTrue(word_finder.is_from_statement(code.rindex('g'))) |
| 294 |
| 295 def test_is_from_with_from_import_and_line_breaks_in_the_middle(self): |
| 296 code = 'from mod import f,\\\n g\n' |
| 297 word_finder = worder.Worder(code) |
| 298 self.assertTrue(word_finder.is_from_statement(code.rindex('g'))) |
| 299 |
| 300 def test_one_letter_function_keyword_arguments(self): |
| 301 code = 'f(p=1)\n' |
| 302 word_finder = worder.Worder(code) |
| 303 index = code.rindex('p') |
| 304 self.assertTrue(word_finder.is_function_keyword_parameter(index)) |
| 305 |
| 306 def test_find_parens_start(self): |
| 307 code = 'f(p)\n' |
| 308 finder = worder.Worder(code) |
| 309 self.assertEquals(1, finder.find_parens_start_from_inside(2)) |
| 310 |
| 311 def test_underlined_find_parens_start(self): |
| 312 code = 'f(p="")\n' |
| 313 finder = worder.Worder(code) |
| 314 self.assertEquals(1, finder._find_parens_start(len(code) - 2)) |
| 315 |
| 316 def test_find_parens_start_with_multiple_entries(self): |
| 317 code = 'myfunc(p1, p2, p3\n' |
| 318 finder = worder.Worder(code) |
| 319 self.assertEquals(code.index('('), |
| 320 finder.find_parens_start_from_inside(len(code) - 1)) |
| 321 |
| 322 def test_find_parens_start_with_nested_parens(self): |
| 323 code = 'myfunc(p1, (p2, p3), p4\n' |
| 324 finder = worder.Worder(code) |
| 325 self.assertEquals(code.index('('), |
| 326 finder.find_parens_start_from_inside(len(code) - 1)) |
| 327 |
| 328 def test_find_parens_start_with_parens_in_strs(self): |
| 329 code = 'myfunc(p1, "(", p4\n' |
| 330 finder = worder.Worder(code) |
| 331 self.assertEquals(code.index('('), |
| 332 finder.find_parens_start_from_inside(len(code) - 1)) |
| 333 |
| 334 def test_find_parens_start_with_parens_in_strs_in_multiple_lines(self): |
| 335 code = 'myfunc (\np1\n , \n "(" \n, \np4\n' |
| 336 finder = worder.Worder(code) |
| 337 self.assertEquals(code.index('('), |
| 338 finder.find_parens_start_from_inside(len(code) - 1)) |
| 339 |
| 340 def test_is_on_function_keyword(self): |
| 341 code = 'myfunc(va' |
| 342 finder = worder.Worder(code) |
| 343 self.assertTrue(finder.is_on_function_call_keyword(len(code) - 1)) |
| 344 |
| 345 |
| 346 class ScopeNameFinderTest(unittest.TestCase): |
| 347 |
| 348 def setUp(self): |
| 349 super(ScopeNameFinderTest, self).setUp() |
| 350 self.project = testutils.sample_project() |
| 351 |
| 352 def tearDown(self): |
| 353 testutils.remove_project(self.project) |
| 354 super(ScopeNameFinderTest, self).tearDown() |
| 355 |
| 356 # FIXME: in normal scopes the interpreter raises `UnboundLocalName` |
| 357 # exception, but not in class bodies |
| 358 def xxx_test_global_name_in_class_body(self): |
| 359 code = 'a_var = 10\nclass C(object):\n a_var = a_var\n' |
| 360 scope = libutils.get_string_scope(self.project, code) |
| 361 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 362 result = name_finder.get_pyname_at(len(code) - 3) |
| 363 self.assertEquals(scope['a_var'], result) |
| 364 |
| 365 def test_class_variable_attribute_in_class_body(self): |
| 366 code = 'a_var = 10\nclass C(object):\n a_var = a_var\n' |
| 367 scope = libutils.get_string_scope(self.project, code) |
| 368 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 369 a_var_pyname = scope['C'].get_object()['a_var'] |
| 370 result = name_finder.get_pyname_at(len(code) - 12) |
| 371 self.assertEquals(a_var_pyname, result) |
| 372 |
| 373 def test_class_variable_attribute_in_class_body2(self): |
| 374 code = 'a_var = 10\nclass C(object):\n a_var \\\n= a_var\n' |
| 375 scope = libutils.get_string_scope(self.project, code) |
| 376 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 377 a_var_pyname = scope['C'].get_object()['a_var'] |
| 378 result = name_finder.get_pyname_at(len(code) - 12) |
| 379 self.assertEquals(a_var_pyname, result) |
| 380 |
| 381 def test_class_method_attribute_in_class_body(self): |
| 382 code = 'class C(object):\n def a_method(self):\n pass\n' |
| 383 scope = libutils.get_string_scope(self.project, code) |
| 384 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 385 a_method_pyname = scope['C'].get_object()['a_method'] |
| 386 result = name_finder.get_pyname_at(code.index('a_method') + 2) |
| 387 self.assertEquals(a_method_pyname, result) |
| 388 |
| 389 def test_inner_class_attribute_in_class_body(self): |
| 390 code = 'class C(object):\n class CC(object):\n pass\n' |
| 391 scope = libutils.get_string_scope(self.project, code) |
| 392 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 393 a_class_pyname = scope['C'].get_object()['CC'] |
| 394 result = name_finder.get_pyname_at(code.index('CC') + 2) |
| 395 self.assertEquals(a_class_pyname, result) |
| 396 |
| 397 def test_class_method_in_class_body_but_not_indexed(self): |
| 398 code = 'class C(object):\n def func(self, func):\n pass\n' |
| 399 scope = libutils.get_string_scope(self.project, code) |
| 400 a_func_pyname = scope.get_scopes()[0].get_scopes()[0]['func'] |
| 401 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 402 result = name_finder.get_pyname_at(code.index(', func') + 3) |
| 403 self.assertEquals(a_func_pyname, result) |
| 404 |
| 405 def test_function_but_not_indexed(self): |
| 406 code = 'def a_func(a_func):\n pass\n' |
| 407 scope = libutils.get_string_scope(self.project, code) |
| 408 a_func_pyname = scope['a_func'] |
| 409 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 410 result = name_finder.get_pyname_at(code.index('a_func') + 3) |
| 411 self.assertEquals(a_func_pyname, result) |
| 412 |
| 413 def test_modules_after_from_statements(self): |
| 414 root_folder = self.project.root |
| 415 mod = testutils.create_module(self.project, 'mod', root_folder) |
| 416 mod.write('def a_func():\n pass\n') |
| 417 code = 'from mod import a_func\n' |
| 418 scope = libutils.get_string_scope(self.project, code) |
| 419 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 420 mod_pyobject = self.project.get_pymodule(mod) |
| 421 found_pyname = name_finder.get_pyname_at(code.index('mod') + 1) |
| 422 self.assertEquals(mod_pyobject, found_pyname.get_object()) |
| 423 |
| 424 def test_renaming_functions_with_from_import_and_parens(self): |
| 425 mod1 = testutils.create_module(self.project, 'mod1') |
| 426 mod1.write('def afunc():\n pass\n') |
| 427 code = 'from mod1 import (\n afunc as func)\n' |
| 428 scope = libutils.get_string_scope(self.project, code) |
| 429 name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) |
| 430 mod_pyobject = self.project.get_pymodule(mod1) |
| 431 afunc = mod_pyobject['afunc'] |
| 432 found_pyname = name_finder.get_pyname_at(code.index('afunc') + 1) |
| 433 self.assertEquals(afunc.get_object(), found_pyname.get_object()) |
| 434 |
| 435 @testutils.run_only_for_25 |
| 436 def test_relative_modules_after_from_statements(self): |
| 437 pkg1 = testutils.create_package(self.project, 'pkg1') |
| 438 pkg2 = testutils.create_package(self.project, 'pkg2', pkg1) |
| 439 mod1 = testutils.create_module(self.project, 'mod1', pkg1) |
| 440 mod2 = testutils.create_module(self.project, 'mod2', pkg2) |
| 441 mod1.write('def a_func():\n pass\n') |
| 442 code = 'from ..mod1 import a_func\n' |
| 443 mod2.write(code) |
| 444 mod2_scope = self.project.get_pymodule(mod2).get_scope() |
| 445 name_finder = rope.base.evaluate.ScopeNameFinder(mod2_scope.pyobject) |
| 446 mod1_pyobject = self.project.get_pymodule(mod1) |
| 447 found_pyname = name_finder.get_pyname_at(code.index('mod1') + 1) |
| 448 self.assertEquals(mod1_pyobject, found_pyname.get_object()) |
| 449 |
| 450 def test_relative_modules_after_from_statements2(self): |
| 451 mod1 = testutils.create_module(self.project, 'mod1') |
| 452 pkg1 = testutils.create_package(self.project, 'pkg1') |
| 453 pkg2 = testutils.create_package(self.project, 'pkg2', pkg1) |
| 454 mod2 = testutils.create_module(self.project, 'mod2', pkg2) # noqa |
| 455 mod1.write('import pkg1.pkg2.mod2') |
| 456 |
| 457 mod1_scope = self.project.get_pymodule(mod1).get_scope() |
| 458 name_finder = rope.base.evaluate.ScopeNameFinder(mod1_scope.pyobject) |
| 459 pkg2_pyobject = self.project.get_pymodule(pkg2) |
| 460 found_pyname = name_finder.get_pyname_at(mod1.read().index('pkg2') + 1) |
| 461 self.assertEquals(pkg2_pyobject, found_pyname.get_object()) |
| 462 |
| 463 def test_get_pyname_at_on_language_keywords(self): |
| 464 code = 'def a_func(a_func):\n pass\n' |
| 465 pymod = libutils.get_string_module(self.project, code) |
| 466 name_finder = rope.base.evaluate.ScopeNameFinder(pymod) |
| 467 with self.assertRaises(exceptions.RopeError): |
| 468 name_finder.get_pyname_at(code.index('pass')) |
| 469 |
| 470 def test_one_liners(self): |
| 471 code = 'var = 1\ndef f(): var = 2\nprint var\n' |
| 472 pymod = libutils.get_string_module(self.project, code) |
| 473 name_finder = rope.base.evaluate.ScopeNameFinder(pymod) |
| 474 pyname = name_finder.get_pyname_at(code.rindex('var')) |
| 475 self.assertEquals(pymod['var'], pyname) |
| 476 |
| 477 def test_one_liners_with_line_breaks(self): |
| 478 code = 'var = 1\ndef f(\n): var = 2\nprint var\n' |
| 479 pymod = libutils.get_string_module(self.project, code) |
| 480 name_finder = rope.base.evaluate.ScopeNameFinder(pymod) |
| 481 pyname = name_finder.get_pyname_at(code.rindex('var')) |
| 482 self.assertEquals(pymod['var'], pyname) |
| 483 |
| 484 def test_one_liners_with_line_breaks2(self): |
| 485 code = 'var = 1\ndef f(\np): var = 2\nprint var\n' |
| 486 pymod = libutils.get_string_module(self.project, code) |
| 487 name_finder = rope.base.evaluate.ScopeNameFinder(pymod) |
| 488 pyname = name_finder.get_pyname_at(code.rindex('var')) |
| 489 self.assertEquals(pymod['var'], pyname) |
| 490 |
| 491 |
| 492 class LogicalLineFinderTest(unittest.TestCase): |
| 493 |
| 494 def setUp(self): |
| 495 super(LogicalLineFinderTest, self).setUp() |
| 496 |
| 497 def tearDown(self): |
| 498 super(LogicalLineFinderTest, self).tearDown() |
| 499 |
| 500 def _logical_finder(self, code): |
| 501 return LogicalLineFinder(SourceLinesAdapter(code)) |
| 502 |
| 503 def test_normal_lines(self): |
| 504 code = 'a_var = 10' |
| 505 line_finder = self._logical_finder(code) |
| 506 self.assertEquals((1, 1), line_finder.logical_line_in(1)) |
| 507 |
| 508 def test_normal_lines2(self): |
| 509 code = 'another = 10\na_var = 20\n' |
| 510 line_finder = self._logical_finder(code) |
| 511 self.assertEquals((1, 1), line_finder.logical_line_in(1)) |
| 512 self.assertEquals((2, 2), line_finder.logical_line_in(2)) |
| 513 |
| 514 def test_implicit_continuation(self): |
| 515 code = 'a_var = 3 + \\\n 4 + \\\n 5' |
| 516 line_finder = self._logical_finder(code) |
| 517 self.assertEquals((1, 3), line_finder.logical_line_in(2)) |
| 518 |
| 519 def test_explicit_continuation(self): |
| 520 code = 'print 2\na_var = (3 + \n 4, \n 5)\n' |
| 521 line_finder = self._logical_finder(code) |
| 522 self.assertEquals((2, 4), line_finder.logical_line_in(2)) |
| 523 |
| 524 def test_explicit_continuation_comments(self): |
| 525 code = '#\na_var = 3\n' |
| 526 line_finder = self._logical_finder(code) |
| 527 self.assertEquals((2, 2), line_finder.logical_line_in(2)) |
| 528 |
| 529 def test_multiple_indented_ifs(self): |
| 530 code = 'if True:\n if True:\n ' \ |
| 531 'if True:\n pass\n a = 10\n' |
| 532 line_finder = self._logical_finder(code) |
| 533 self.assertEquals((5, 5), line_finder.logical_line_in(5)) |
| 534 |
| 535 def test_list_comprehensions_and_fors(self): |
| 536 code = 'a_list = [i\n for i in range(10)]\n' |
| 537 line_finder = self._logical_finder(code) |
| 538 self.assertEquals((1, 2), line_finder.logical_line_in(2)) |
| 539 |
| 540 def test_generator_expressions_and_fors(self): |
| 541 code = 'a_list = (i\n for i in range(10))\n' |
| 542 line_finder = self._logical_finder(code) |
| 543 self.assertEquals((1, 2), line_finder.logical_line_in(2)) |
| 544 |
| 545 def test_fors_and_block_start(self): |
| 546 code = 'l = range(10)\nfor i in l:\n print i\n' |
| 547 self.assertEquals(2, get_block_start(SourceLinesAdapter(code), 2)) |
| 548 |
| 549 def test_problems_with_inner_indentations(self): |
| 550 code = 'if True:\n if True:\n if True:\n pass\n' \ |
| 551 ' a = \\\n 1\n' |
| 552 line_finder = self._logical_finder(code) |
| 553 self.assertEquals((5, 6), line_finder.logical_line_in(6)) |
| 554 |
| 555 def test_problems_with_inner_indentations2(self): |
| 556 code = 'if True:\n if True:\n pass\n' \ |
| 557 'a = 1\n' |
| 558 line_finder = self._logical_finder(code) |
| 559 self.assertEquals((4, 4), line_finder.logical_line_in(4)) |
| 560 |
| 561 def test_logical_lines_for_else(self): |
| 562 code = 'if True:\n pass\nelse:\n pass\n' |
| 563 line_finder = self._logical_finder(code) |
| 564 self.assertEquals((3, 3), line_finder.logical_line_in(3)) |
| 565 |
| 566 def test_logical_lines_for_lines_with_wrong_continues(self): |
| 567 code = 'var = 1 + \\' |
| 568 line_finder = self._logical_finder(code) |
| 569 self.assertEquals((1, 1), line_finder.logical_line_in(1)) |
| 570 |
| 571 def test_generating_line_starts(self): |
| 572 code = 'a = 1\na = 2\n\na = 3\n' |
| 573 line_finder = self._logical_finder(code) |
| 574 self.assertEquals([1, 2, 4], list(line_finder.generate_starts())) |
| 575 |
| 576 def test_generating_line_starts2(self): |
| 577 code = 'a = 1\na = 2\n\na = \\ 3\n' |
| 578 line_finder = LogicalLineFinder(SourceLinesAdapter(code)) |
| 579 self.assertEquals([2, 4], list(line_finder.generate_starts(2))) |
| 580 |
| 581 def test_generating_line_starts3(self): |
| 582 code = 'a = 1\na = 2\n\na = \\ 3\n' |
| 583 line_finder = LogicalLineFinder(SourceLinesAdapter(code)) |
| 584 self.assertEquals([2], list(line_finder.generate_starts(2, 3))) |
| 585 |
| 586 def test_generating_line_starts_for_multi_line_statements(self): |
| 587 code = '\na = \\\n 1 + \\\n 1\n' |
| 588 line_finder = self._logical_finder(code) |
| 589 self.assertEquals([2], list(line_finder.generate_starts())) |
| 590 |
| 591 def test_generating_line_starts_and_unmatched_deindents(self): |
| 592 code = 'if True:\n if True:\n if True:\n' \ |
| 593 ' a = 1\n b = 1\n' |
| 594 line_finder = self._logical_finder(code) |
| 595 self.assertEquals([4, 5], list(line_finder.generate_starts(4))) |
| 596 |
| 597 |
| 598 class TokenizerLogicalLineFinderTest(LogicalLineFinderTest): |
| 599 |
| 600 def _logical_finder(self, code): |
| 601 lines = SourceLinesAdapter(code) |
| 602 return codeanalyze.CachingLogicalLineFinder( |
| 603 lines, codeanalyze.tokenizer_generator) |
| 604 |
| 605 |
| 606 class CustomLogicalLineFinderTest(LogicalLineFinderTest): |
| 607 |
| 608 def _logical_finder(self, code): |
| 609 lines = SourceLinesAdapter(code) |
| 610 return codeanalyze.CachingLogicalLineFinder( |
| 611 lines, codeanalyze.custom_generator) |
| 612 |
| 613 |
| 614 def suite(): |
| 615 result = unittest.TestSuite() |
| 616 result.addTests(unittest.makeSuite(SourceLinesAdapterTest)) |
| 617 result.addTests(unittest.makeSuite(WordRangeFinderTest)) |
| 618 result.addTests(unittest.makeSuite(ScopeNameFinderTest)) |
| 619 result.addTests(unittest.makeSuite(LogicalLineFinderTest)) |
| 620 result.addTests(unittest.makeSuite(TokenizerLogicalLineFinderTest)) |
| 621 result.addTests(unittest.makeSuite(CustomLogicalLineFinderTest)) |
| 622 return result |
| 623 |
| 624 if __name__ == '__main__': |
| 625 unittest.main() |
OLD | NEW |