1 #!/usr/bin/python 2 # -*- coding: utf-8; -*- 3 # 4 # Copyright (C) 2009 Google Inc. All rights reserved. 5 # Copyright (C) 2009 Torch Mobile Inc. 6 # Copyright (C) 2009 Apple Inc. All rights reserved. 7 # Copyright (C) 2010 Chris Jerdonek (chris.jerdonek (at] gmail.com) 8 # 9 # Redistribution and use in source and binary forms, with or without 10 # modification, are permitted provided that the following conditions are 11 # met: 12 # 13 # * Redistributions of source code must retain the above copyright 14 # notice, this list of conditions and the following disclaimer. 15 # * Redistributions in binary form must reproduce the above 16 # copyright notice, this list of conditions and the following disclaimer 17 # in the documentation and/or other materials provided with the 18 # distribution. 19 # * Neither the name of Google Inc. nor the names of its 20 # contributors may be used to endorse or promote products derived from 21 # this software without specific prior written permission. 22 # 23 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 35 """Unit tests for style.py.""" 36 37 import unittest 38 39 import checker as style 40 from checker import _PATH_RULES_SPECIFIER as PATH_RULES_SPECIFIER 41 from checker import style_categories 42 from checker import ProcessorDispatcher 43 from checker import ProcessorOptions 44 from checker import StyleChecker 45 from filter import validate_filter_rules 46 from filter import FilterConfiguration 47 from processors.cpp import CppProcessor 48 from processors.text import TextProcessor 49 50 51 class ProcessorOptionsTest(unittest.TestCase): 52 53 """Tests ProcessorOptions class.""" 54 55 def test_init(self): 56 """Test __init__ constructor.""" 57 # Check default parameters. 58 options = ProcessorOptions() 59 self.assertEquals(options.extra_flag_values, {}) 60 self.assertEquals(options.filter_configuration, FilterConfiguration()) 61 self.assertEquals(options.git_commit, None) 62 self.assertEquals(options.max_reports_per_category, {}) 63 self.assertEquals(options.output_format, "emacs") 64 self.assertEquals(options.verbosity, 1) 65 66 # Check argument validation. 67 self.assertRaises(ValueError, ProcessorOptions, output_format="bad") 68 ProcessorOptions(output_format="emacs") # No ValueError: works 69 ProcessorOptions(output_format="vs7") # works 70 self.assertRaises(ValueError, ProcessorOptions, verbosity=0) 71 self.assertRaises(ValueError, ProcessorOptions, verbosity=6) 72 ProcessorOptions(verbosity=1) # works 73 ProcessorOptions(verbosity=5) # works 74 75 # Check attributes. 76 filter_configuration = FilterConfiguration(base_rules=["+"]) 77 options = ProcessorOptions(extra_flag_values={"extra_value" : 2}, 78 filter_configuration=filter_configuration, 79 git_commit="commit", 80 max_reports_per_category={"category": 3}, 81 output_format="vs7", 82 verbosity=3) 83 self.assertEquals(options.extra_flag_values, {"extra_value" : 2}) 84 self.assertEquals(options.filter_configuration, filter_configuration) 85 self.assertEquals(options.git_commit, "commit") 86 self.assertEquals(options.max_reports_per_category, {"category": 3}) 87 self.assertEquals(options.output_format, "vs7") 88 self.assertEquals(options.verbosity, 3) 89 90 def test_eq(self): 91 """Test __eq__ equality function.""" 92 # == calls __eq__. 93 self.assertTrue(ProcessorOptions() == ProcessorOptions()) 94 95 # Verify that a difference in any argument causes equality to fail. 96 filter_configuration = FilterConfiguration(base_rules=["+"]) 97 options = ProcessorOptions(extra_flag_values={"extra_value" : 1}, 98 filter_configuration=filter_configuration, 99 git_commit="commit", 100 max_reports_per_category={"category": 3}, 101 output_format="vs7", 102 verbosity=1) 103 self.assertFalse(options == ProcessorOptions(extra_flag_values={"extra_value" : 2})) 104 new_config = FilterConfiguration(base_rules=["-"]) 105 self.assertFalse(options == 106 ProcessorOptions(filter_configuration=new_config)) 107 self.assertFalse(options == ProcessorOptions(git_commit="commit2")) 108 self.assertFalse(options == ProcessorOptions(max_reports_per_category= 109 {"category": 2})) 110 self.assertFalse(options == ProcessorOptions(output_format="emacs")) 111 self.assertFalse(options == ProcessorOptions(verbosity=2)) 112 113 def test_ne(self): 114 """Test __ne__ inequality function.""" 115 # != calls __ne__. 116 # By default, __ne__ always returns true on different objects. 117 # Thus, just check the distinguishing case to verify that the 118 # code defines __ne__. 119 self.assertFalse(ProcessorOptions() != ProcessorOptions()) 120 121 def test_is_reportable(self): 122 """Test is_reportable().""" 123 filter_configuration = FilterConfiguration(base_rules=["-xyz"]) 124 options = ProcessorOptions(filter_configuration=filter_configuration, 125 verbosity=3) 126 127 # Test verbosity 128 self.assertTrue(options.is_reportable("abc", 3, "foo.h")) 129 self.assertFalse(options.is_reportable("abc", 2, "foo.h")) 130 131 # Test filter 132 self.assertTrue(options.is_reportable("xy", 3, "foo.h")) 133 self.assertFalse(options.is_reportable("xyz", 3, "foo.h")) 134 135 136 class GlobalVariablesTest(unittest.TestCase): 137 138 """Tests validity of the global variables.""" 139 140 def _all_categories(self): 141 return style.style_categories() 142 143 def defaults(self): 144 return style.webkit_argument_defaults() 145 146 def test_filter_rules(self): 147 defaults = self.defaults() 148 already_seen = [] 149 validate_filter_rules(defaults.base_filter_rules, 150 self._all_categories()) 151 # Also do some additional checks. 152 for rule in defaults.base_filter_rules: 153 # Check no leading or trailing white space. 154 self.assertEquals(rule, rule.strip()) 155 # All categories are on by default, so defaults should 156 # begin with -. 157 self.assertTrue(rule.startswith('-')) 158 # Check no rule occurs twice. 159 self.assertFalse(rule in already_seen) 160 already_seen.append(rule) 161 162 def test_defaults(self): 163 """Check that default arguments are valid.""" 164 defaults = self.defaults() 165 166 # FIXME: We should not need to call parse() to determine 167 # whether the default arguments are valid. 168 parser = style.ArgumentParser(defaults) 169 # No need to test the return value here since we test parse() 170 # on valid arguments elsewhere. 171 parser.parse([]) # arguments valid: no error or SystemExit 172 173 def test_path_rules_specifier(self): 174 all_categories = style_categories() 175 for (sub_paths, path_rules) in PATH_RULES_SPECIFIER: 176 self.assertTrue(isinstance(path_rules, tuple), 177 "Checking: " + str(path_rules)) 178 validate_filter_rules(path_rules, self._all_categories()) 179 180 # Try using the path specifier (as an "end-to-end" check). 181 config = FilterConfiguration(path_specific=PATH_RULES_SPECIFIER) 182 self.assertTrue(config.should_check("xxx_any_category", 183 "xxx_non_matching_path")) 184 self.assertTrue(config.should_check("xxx_any_category", 185 "WebKitTools/WebKitAPITest/")) 186 self.assertFalse(config.should_check("build/include", 187 "WebKitTools/WebKitAPITest/")) 188 self.assertFalse(config.should_check("readability/naming", 189 "WebKit/qt/tests/qwebelement/tst_qwebelement.cpp")) 190 191 def test_max_reports_per_category(self): 192 """Check that MAX_REPORTS_PER_CATEGORY is valid.""" 193 all_categories = self._all_categories() 194 for category in style.MAX_REPORTS_PER_CATEGORY.iterkeys(): 195 self.assertTrue(category in all_categories, 196 'Key "%s" is not a category' % category) 197 198 199 class ArgumentPrinterTest(unittest.TestCase): 200 201 """Tests the ArgumentPrinter class.""" 202 203 _printer = style.ArgumentPrinter() 204 205 def _create_options(self, 206 output_format='emacs', 207 verbosity=3, 208 user_rules=[], 209 git_commit=None, 210 extra_flag_values={}): 211 filter_configuration = FilterConfiguration(user_rules=user_rules) 212 return style.ProcessorOptions(extra_flag_values=extra_flag_values, 213 filter_configuration=filter_configuration, 214 git_commit=git_commit, 215 output_format=output_format, 216 verbosity=verbosity) 217 218 def test_to_flag_string(self): 219 options = self._create_options('vs7', 5, ['+foo', '-bar'], 'git', 220 {'a': 0, 'z': 1}) 221 self.assertEquals('--a=0 --filter=+foo,-bar --git-commit=git ' 222 '--output=vs7 --verbose=5 --z=1', 223 self._printer.to_flag_string(options)) 224 225 # This is to check that --filter and --git-commit do not 226 # show up when not user-specified. 227 options = self._create_options() 228 self.assertEquals('--output=emacs --verbose=3', 229 self._printer.to_flag_string(options)) 230 231 232 class ArgumentParserTest(unittest.TestCase): 233 234 """Test the ArgumentParser class.""" 235 236 def _parse(self): 237 """Return a default parse() function for testing.""" 238 return self._create_parser().parse 239 240 def _create_defaults(self, default_output_format='vs7', 241 default_verbosity=3, 242 default_filter_rules=['-', '+whitespace']): 243 """Return a default ArgumentDefaults instance for testing.""" 244 return style.ArgumentDefaults(default_output_format, 245 default_verbosity, 246 default_filter_rules) 247 248 def _create_parser(self, defaults=None): 249 """Return an ArgumentParser instance for testing.""" 250 def create_usage(_defaults): 251 """Return a usage string for testing.""" 252 return "usage" 253 254 def doc_print(message): 255 # We do not want the usage string or style categories 256 # to print during unit tests, so print nothing. 257 return 258 259 if defaults is None: 260 defaults = self._create_defaults() 261 262 return style.ArgumentParser(defaults, create_usage, doc_print) 263 264 def test_parse_documentation(self): 265 parse = self._parse() 266 267 # FIXME: Test both the printing of the usage string and the 268 # filter categories help. 269 270 # Request the usage string. 271 self.assertRaises(SystemExit, parse, ['--help']) 272 # Request default filter rules and available style categories. 273 self.assertRaises(SystemExit, parse, ['--filter=']) 274 275 def test_parse_bad_values(self): 276 parse = self._parse() 277 278 # Pass an unsupported argument. 279 self.assertRaises(SystemExit, parse, ['--bad']) 280 281 self.assertRaises(ValueError, parse, ['--verbose=bad']) 282 self.assertRaises(ValueError, parse, ['--verbose=0']) 283 self.assertRaises(ValueError, parse, ['--verbose=6']) 284 parse(['--verbose=1']) # works 285 parse(['--verbose=5']) # works 286 287 self.assertRaises(ValueError, parse, ['--output=bad']) 288 parse(['--output=vs7']) # works 289 290 # Pass a filter rule not beginning with + or -. 291 self.assertRaises(ValueError, parse, ['--filter=build']) 292 parse(['--filter=+build']) # works 293 # Pass files and git-commit at the same time. 294 self.assertRaises(SystemExit, parse, ['--git-commit=', 'file.txt']) 295 # Pass an extra flag already supported. 296 self.assertRaises(ValueError, parse, [], ['filter=']) 297 parse([], ['extra=']) # works 298 # Pass an extra flag with typo. 299 self.assertRaises(SystemExit, parse, ['--extratypo='], ['extra=']) 300 parse(['--extra='], ['extra=']) # works 301 self.assertRaises(ValueError, parse, [], ['extra=', 'extra=']) 302 303 304 def test_parse_default_arguments(self): 305 parse = self._parse() 306 307 (files, options) = parse([]) 308 309 self.assertEquals(files, []) 310 311 self.assertEquals(options.output_format, 'vs7') 312 self.assertEquals(options.verbosity, 3) 313 self.assertEquals(options.filter_configuration, 314 FilterConfiguration(base_rules=["-", "+whitespace"], 315 path_specific=PATH_RULES_SPECIFIER)) 316 self.assertEquals(options.git_commit, None) 317 318 def test_parse_explicit_arguments(self): 319 parse = self._parse() 320 321 # Pass non-default explicit values. 322 (files, options) = parse(['--output=emacs']) 323 self.assertEquals(options.output_format, 'emacs') 324 (files, options) = parse(['--verbose=4']) 325 self.assertEquals(options.verbosity, 4) 326 (files, options) = parse(['--git-commit=commit']) 327 self.assertEquals(options.git_commit, 'commit') 328 329 # Pass user_rules. 330 (files, options) = parse(['--filter=+build,-whitespace']) 331 config = options.filter_configuration 332 self.assertEquals(options.filter_configuration, 333 FilterConfiguration(base_rules=["-", "+whitespace"], 334 path_specific=PATH_RULES_SPECIFIER, 335 user_rules=["+build", "-whitespace"])) 336 337 # Pass spurious white space in user rules. 338 (files, options) = parse(['--filter=+build, -whitespace']) 339 self.assertEquals(options.filter_configuration, 340 FilterConfiguration(base_rules=["-", "+whitespace"], 341 path_specific=PATH_RULES_SPECIFIER, 342 user_rules=["+build", "-whitespace"])) 343 344 # Pass extra flag values. 345 (files, options) = parse(['--extra'], ['extra']) 346 self.assertEquals(options.extra_flag_values, {'--extra': ''}) 347 (files, options) = parse(['--extra='], ['extra=']) 348 self.assertEquals(options.extra_flag_values, {'--extra': ''}) 349 (files, options) = parse(['--extra=x'], ['extra=']) 350 self.assertEquals(options.extra_flag_values, {'--extra': 'x'}) 351 352 def test_parse_files(self): 353 parse = self._parse() 354 355 (files, options) = parse(['foo.cpp']) 356 self.assertEquals(files, ['foo.cpp']) 357 358 # Pass multiple files. 359 (files, options) = parse(['--output=emacs', 'foo.cpp', 'bar.cpp']) 360 self.assertEquals(files, ['foo.cpp', 'bar.cpp']) 361 362 363 class ProcessorDispatcherSkipTest(unittest.TestCase): 364 365 """Tests the "should skip" methods of the ProcessorDispatcher class.""" 366 367 def test_should_skip_with_warning(self): 368 """Test should_skip_with_warning().""" 369 dispatcher = ProcessorDispatcher() 370 371 # Check a non-skipped file. 372 self.assertFalse(dispatcher.should_skip_with_warning("foo.txt")) 373 374 # Check skipped files. 375 paths_to_skip = [ 376 "gtk2drawing.c", 377 "gtk2drawing.h", 378 "JavaScriptCore/qt/api/qscriptengine_p.h", 379 "WebCore/platform/gtk/gtk2drawing.c", 380 "WebCore/platform/gtk/gtk2drawing.h", 381 "WebKit/gtk/tests/testatk.c", 382 "WebKit/qt/Api/qwebpage.h", 383 "WebKit/qt/tests/qwebsecurityorigin/tst_qwebsecurityorigin.cpp", 384 ] 385 386 for path in paths_to_skip: 387 self.assertTrue(dispatcher.should_skip_with_warning(path), 388 "Checking: " + path) 389 390 def test_should_skip_without_warning(self): 391 """Test should_skip_without_warning().""" 392 dispatcher = ProcessorDispatcher() 393 394 # Check a non-skipped file. 395 self.assertFalse(dispatcher.should_skip_without_warning("foo.txt")) 396 397 # Check skipped files. 398 paths_to_skip = [ 399 # LayoutTests folder 400 "LayoutTests/foo.txt", 401 ] 402 403 for path in paths_to_skip: 404 self.assertTrue(dispatcher.should_skip_without_warning(path), 405 "Checking: " + path) 406 407 408 class ProcessorDispatcherDispatchTest(unittest.TestCase): 409 410 """Tests dispatch_processor() method of ProcessorDispatcher class.""" 411 412 def mock_handle_style_error(self): 413 pass 414 415 def dispatch_processor(self, file_path): 416 """Call dispatch_processor() with the given file path.""" 417 dispatcher = ProcessorDispatcher() 418 processor = dispatcher.dispatch_processor(file_path, 419 self.mock_handle_style_error, 420 verbosity=3) 421 return processor 422 423 def assert_processor_none(self, file_path): 424 """Assert that the dispatched processor is None.""" 425 processor = self.dispatch_processor(file_path) 426 self.assertTrue(processor is None, 'Checking: "%s"' % file_path) 427 428 def assert_processor(self, file_path, expected_class): 429 """Assert the type of the dispatched processor.""" 430 processor = self.dispatch_processor(file_path) 431 got_class = processor.__class__ 432 self.assertEquals(got_class, expected_class, 433 'For path "%(file_path)s" got %(got_class)s when ' 434 "expecting %(expected_class)s." 435 % {"file_path": file_path, 436 "got_class": got_class, 437 "expected_class": expected_class}) 438 439 def assert_processor_cpp(self, file_path): 440 """Assert that the dispatched processor is a CppProcessor.""" 441 self.assert_processor(file_path, CppProcessor) 442 443 def assert_processor_text(self, file_path): 444 """Assert that the dispatched processor is a TextProcessor.""" 445 self.assert_processor(file_path, TextProcessor) 446 447 def test_cpp_paths(self): 448 """Test paths that should be checked as C++.""" 449 paths = [ 450 "-", 451 "foo.c", 452 "foo.cpp", 453 "foo.h", 454 ] 455 456 for path in paths: 457 self.assert_processor_cpp(path) 458 459 # Check processor attributes on a typical input. 460 file_base = "foo" 461 file_extension = "c" 462 file_path = file_base + "." + file_extension 463 self.assert_processor_cpp(file_path) 464 processor = self.dispatch_processor(file_path) 465 self.assertEquals(processor.file_extension, file_extension) 466 self.assertEquals(processor.file_path, file_path) 467 self.assertEquals(processor.handle_style_error, self.mock_handle_style_error) 468 self.assertEquals(processor.verbosity, 3) 469 # Check "-" for good measure. 470 file_base = "-" 471 file_extension = "" 472 file_path = file_base 473 self.assert_processor_cpp(file_path) 474 processor = self.dispatch_processor(file_path) 475 self.assertEquals(processor.file_extension, file_extension) 476 self.assertEquals(processor.file_path, file_path) 477 478 def test_text_paths(self): 479 """Test paths that should be checked as text.""" 480 paths = [ 481 "ChangeLog", 482 "foo.css", 483 "foo.html", 484 "foo.idl", 485 "foo.js", 486 "foo.mm", 487 "foo.php", 488 "foo.pm", 489 "foo.py", 490 "foo.txt", 491 "FooChangeLog.bak", 492 "WebCore/ChangeLog", 493 "WebCore/inspector/front-end/inspector.js", 494 "WebKitTools/Scripts/check-webkit=style", 495 "WebKitTools/Scripts/modules/text_style.py", 496 ] 497 498 for path in paths: 499 self.assert_processor_text(path) 500 501 # Check processor attributes on a typical input. 502 file_base = "foo" 503 file_extension = "css" 504 file_path = file_base + "." + file_extension 505 self.assert_processor_text(file_path) 506 processor = self.dispatch_processor(file_path) 507 self.assertEquals(processor.file_path, file_path) 508 self.assertEquals(processor.handle_style_error, self.mock_handle_style_error) 509 510 def test_none_paths(self): 511 """Test paths that have no file type..""" 512 paths = [ 513 "Makefile", 514 "foo.png", 515 "foo.exe", 516 ] 517 518 for path in paths: 519 self.assert_processor_none(path) 520 521 522 class StyleCheckerTest(unittest.TestCase): 523 524 """Test the StyleChecker class. 525 526 Attributes: 527 error_messages: A string containing all of the warning messages 528 written to the mock_stderr_write method of 529 this class. 530 531 """ 532 533 def _mock_stderr_write(self, message): 534 pass 535 536 def _style_checker(self, options): 537 return StyleChecker(options, self._mock_stderr_write) 538 539 def test_init(self): 540 """Test __init__ constructor.""" 541 options = ProcessorOptions() 542 style_checker = self._style_checker(options) 543 544 self.assertEquals(style_checker.error_count, 0) 545 self.assertEquals(style_checker.options, options) 546 547 548 class StyleCheckerCheckFileTest(unittest.TestCase): 549 550 """Test the check_file() method of the StyleChecker class. 551 552 The check_file() method calls its process_file parameter when 553 given a file that should not be skipped. 554 555 The "got_*" attributes of this class are the parameters passed 556 to process_file by calls to check_file() made by this test 557 class. These attributes allow us to check the parameter values 558 passed internally to the process_file function. 559 560 Attributes: 561 got_file_path: The file_path parameter passed by check_file() 562 to its process_file parameter. 563 got_handle_style_error: The handle_style_error parameter passed 564 by check_file() to its process_file 565 parameter. 566 got_processor: The processor parameter passed by check_file() to 567 its process_file parameter. 568 warning_messages: A string containing all of the warning messages 569 written to the mock_stderr_write method of 570 this class. 571 572 """ 573 def setUp(self): 574 self.got_file_path = None 575 self.got_handle_style_error = None 576 self.got_processor = None 577 self.warning_messages = "" 578 579 def mock_stderr_write(self, warning_message): 580 self.warning_messages += warning_message 581 582 def mock_handle_style_error(self): 583 pass 584 585 def mock_process_file(self, processor, file_path, handle_style_error): 586 """A mock _process_file(). 587 588 See the documentation for this class for more information 589 on this function. 590 591 """ 592 self.got_file_path = file_path 593 self.got_handle_style_error = handle_style_error 594 self.got_processor = processor 595 596 def assert_attributes(self, 597 expected_file_path, 598 expected_handle_style_error, 599 expected_processor, 600 expected_warning_messages): 601 """Assert that the attributes of this class equal the given values.""" 602 self.assertEquals(self.got_file_path, expected_file_path) 603 self.assertEquals(self.got_handle_style_error, expected_handle_style_error) 604 self.assertEquals(self.got_processor, expected_processor) 605 self.assertEquals(self.warning_messages, expected_warning_messages) 606 607 def call_check_file(self, file_path): 608 """Call the check_file() method of a test StyleChecker instance.""" 609 # Confirm that the attributes are reset. 610 self.assert_attributes(None, None, None, "") 611 612 # Create a test StyleChecker instance. 613 # 614 # The verbosity attribute is the only ProcessorOptions 615 # attribute that needs to be checked in this test. 616 # This is because it is the only option is directly 617 # passed to the constructor of a style processor. 618 options = ProcessorOptions(verbosity=3) 619 620 style_checker = StyleChecker(options, self.mock_stderr_write) 621 622 style_checker.check_file(file_path, 623 self.mock_handle_style_error, 624 self.mock_process_file) 625 626 def test_check_file_on_skip_without_warning(self): 627 """Test check_file() for a skipped-without-warning file.""" 628 629 file_path = "LayoutTests/foo.txt" 630 631 dispatcher = ProcessorDispatcher() 632 # Confirm that the input file is truly a skipped-without-warning file. 633 self.assertTrue(dispatcher.should_skip_without_warning(file_path)) 634 635 # Check the outcome. 636 self.call_check_file(file_path) 637 self.assert_attributes(None, None, None, "") 638 639 def test_check_file_on_skip_with_warning(self): 640 """Test check_file() for a skipped-with-warning file.""" 641 642 file_path = "gtk2drawing.c" 643 644 dispatcher = ProcessorDispatcher() 645 # Check that the input file is truly a skipped-with-warning file. 646 self.assertTrue(dispatcher.should_skip_with_warning(file_path)) 647 648 # Check the outcome. 649 self.call_check_file(file_path) 650 self.assert_attributes(None, None, None, 651 'Ignoring "gtk2drawing.c": this file is exempt from the style guide.\n') 652 653 def test_check_file_on_non_skipped(self): 654 655 # We use a C++ file since by using a CppProcessor, we can check 656 # that all of the possible information is getting passed to 657 # process_file (in particular, the verbosity). 658 file_base = "foo" 659 file_extension = "cpp" 660 file_path = file_base + "." + file_extension 661 662 dispatcher = ProcessorDispatcher() 663 # Check that the input file is truly a C++ file. 664 self.assertEquals(dispatcher._file_type(file_path), style.FileType.CPP) 665 666 # Check the outcome. 667 self.call_check_file(file_path) 668 669 expected_processor = CppProcessor(file_path, file_extension, self.mock_handle_style_error, 3) 670 671 self.assert_attributes(file_path, 672 self.mock_handle_style_error, 673 expected_processor, 674 "") 675 676 677 if __name__ == '__main__': 678 import sys 679 680 unittest.main() 681 682