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@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 37import unittest 38 39import checker as style 40from checker import _PATH_RULES_SPECIFIER as PATH_RULES_SPECIFIER 41from checker import style_categories 42from checker import ProcessorDispatcher 43from checker import ProcessorOptions 44from checker import StyleChecker 45from filter import validate_filter_rules 46from filter import FilterConfiguration 47from processors.cpp import CppProcessor 48from processors.text import TextProcessor 49 50 51class 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 136class 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 199class 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 232class 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 363class 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 408class 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 522class 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 548class 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 677if __name__ == '__main__': 678 import sys 679 680 unittest.main() 681 682