1 # Copyright (C) 2010 Google Inc. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 """Checks WebKit style for test_expectations files."""
36 from common import TabChecker
37 from webkitpy.common.host import Host
38 from webkitpy.layout_tests.models import test_expectations
39 from webkitpy.layout_tests.port.base import DummyOptions
42 _log = logging.getLogger(__name__)
45 class TestExpectationsChecker(object):
46 """Processes test_expectations.txt lines for validating the syntax."""
48 categories = set(['test/expectations'])
50 def _determine_port_from_exepectations_path(self, host, expectations_path):
52 # I believe what this is trying to do is "when the port name is chromium,
53 # get the chromium-port for this platform". Unclear why that's needed??
54 port_name = expectations_path.split(host.filesystem.sep)[-2]
58 # Pass a configuration to avoid calling default_configuration() when initializing the port (takes 0.5 seconds on a Mac Pro!).
59 if port_name == "chromium":
60 return host.port_factory.get(options=DummyOptions(chromium=True, configuration="Release"))
61 return host.port_factory.get(port_name, options=DummyOptions(configuration="Release"))
63 _log.warn("Exception while getting port for path %s" % expectations_path)
66 def __init__(self, file_path, handle_style_error, host=None):
67 self._file_path = file_path
68 self._handle_style_error = handle_style_error
69 self._handle_style_error.turn_off_line_filtering()
70 self._tab_checker = TabChecker(file_path, handle_style_error)
71 self._output_regex = re.compile('Line:(?P<line>\d+)\s*(?P<message>.+)')
73 # FIXME: host should be a required parameter, not an optional one.
75 host._initialize_scm()
77 # Determining the port of this expectations.
78 self._port_obj = self._determine_port_from_exepectations_path(host, file_path)
79 # Using 'test' port when we couldn't determine the port for this
81 if not self._port_obj:
82 _log.warn("Could not determine the port for %s. "
83 "Using 'test' port, but platform-specific expectations "
84 "will fail the check." % self._file_path)
85 self._port_obj = host.port_factory.get('test')
86 # Suppress error messages of test_expectations module since they will be reported later.
87 log = logging.getLogger("webkitpy.layout_tests.layout_package.test_expectations")
88 log.setLevel(logging.CRITICAL)
90 def _handle_error_message(self, lineno, message, confidence):
93 def check_test_expectations(self, expectations_str, test_configuration, tests=None, overrides=None):
97 expectations = test_expectations.TestExpectations(
98 port=self._port_obj, expectations=expectations_str, tests=tests,
99 test_config=test_configuration,
100 is_lint_mode=True, overrides=overrides)
101 except test_expectations.ParseError, error:
108 for error in err.errors:
109 matched = self._output_regex.match(error)
111 lineno, message = matched.group('line', 'message')
112 self._handle_style_error(int(lineno), 'test/expectations', level, message)
115 def check_tabs(self, lines):
116 self._tab_checker.check(lines)
118 def check(self, lines):
119 overrides = self._port_obj.test_expectations_overrides()
120 expectations = '\n'.join(lines)
121 for test_configuration in self._port_obj.all_test_configurations():
122 self.check_test_expectations(expectations_str=expectations,
123 test_configuration=test_configuration,
126 # Warn tabs in lines as well
127 self.check_tabs(lines)