| OLD | NEW |
| 1 # Copyright (C) 2010 Google Inc. All rights reserved. | 1 # Copyright (C) 2010 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 | 50 |
| 51 WEBKIT_BUG_PREFIX = 'webkit.org/b/' | 51 WEBKIT_BUG_PREFIX = 'webkit.org/b/' |
| 52 CHROMIUM_BUG_PREFIX = 'crbug.com/' | 52 CHROMIUM_BUG_PREFIX = 'crbug.com/' |
| 53 V8_BUG_PREFIX = 'code.google.com/p/v8/issues/detail?id=' | 53 V8_BUG_PREFIX = 'code.google.com/p/v8/issues/detail?id=' |
| 54 NAMED_BUG_PREFIX = 'Bug(' | 54 NAMED_BUG_PREFIX = 'Bug(' |
| 55 | 55 |
| 56 MISSING_KEYWORD = 'Missing' | 56 MISSING_KEYWORD = 'Missing' |
| 57 NEEDS_REBASELINE_KEYWORD = 'NeedsRebaseline' | 57 NEEDS_REBASELINE_KEYWORD = 'NeedsRebaseline' |
| 58 NEEDS_MANUAL_REBASELINE_KEYWORD = 'NeedsManualRebaseline' | 58 NEEDS_MANUAL_REBASELINE_KEYWORD = 'NeedsManualRebaseline' |
| 59 | 59 |
| 60 |
| 60 class ParseError(Exception): | 61 class ParseError(Exception): |
| 62 |
| 61 def __init__(self, warnings): | 63 def __init__(self, warnings): |
| 62 super(ParseError, self).__init__() | 64 super(ParseError, self).__init__() |
| 63 self.warnings = warnings | 65 self.warnings = warnings |
| 64 | 66 |
| 65 def __str__(self): | 67 def __str__(self): |
| 66 return '\n'.join(map(str, self.warnings)) | 68 return '\n'.join(map(str, self.warnings)) |
| 67 | 69 |
| 68 def __repr__(self): | 70 def __repr__(self): |
| 69 return 'ParseError(warnings=%s)' % self.warnings | 71 return 'ParseError(warnings=%s)' % self.warnings |
| 70 | 72 |
| 71 | 73 |
| 72 class TestExpectationParser(object): | 74 class TestExpectationParser(object): |
| 75 |
| 73 """Provides parsing facilities for lines in the test_expectation.txt file.""
" | 76 """Provides parsing facilities for lines in the test_expectation.txt file.""
" |
| 74 | 77 |
| 75 # FIXME: Rename these to *_KEYWORD as in MISSING_KEYWORD above, but make the
case studdly-caps to match the actual file contents. | 78 # FIXME: Rename these to *_KEYWORD as in MISSING_KEYWORD above, but make |
| 79 # the case studdly-caps to match the actual file contents. |
| 76 REBASELINE_MODIFIER = 'rebaseline' | 80 REBASELINE_MODIFIER = 'rebaseline' |
| 77 NEEDS_REBASELINE_MODIFIER = 'needsrebaseline' | 81 NEEDS_REBASELINE_MODIFIER = 'needsrebaseline' |
| 78 NEEDS_MANUAL_REBASELINE_MODIFIER = 'needsmanualrebaseline' | 82 NEEDS_MANUAL_REBASELINE_MODIFIER = 'needsmanualrebaseline' |
| 79 PASS_EXPECTATION = 'pass' | 83 PASS_EXPECTATION = 'pass' |
| 80 SKIP_MODIFIER = 'skip' | 84 SKIP_MODIFIER = 'skip' |
| 81 SLOW_MODIFIER = 'slow' | 85 SLOW_MODIFIER = 'slow' |
| 82 WONTFIX_MODIFIER = 'wontfix' | 86 WONTFIX_MODIFIER = 'wontfix' |
| 83 | 87 |
| 84 TIMEOUT_EXPECTATION = 'timeout' | 88 TIMEOUT_EXPECTATION = 'timeout' |
| 85 | 89 |
| 86 MISSING_BUG_WARNING = 'Test lacks BUG specifier.' | 90 MISSING_BUG_WARNING = 'Test lacks BUG specifier.' |
| 87 | 91 |
| 88 def __init__(self, port, full_test_list, is_lint_mode): | 92 def __init__(self, port, full_test_list, is_lint_mode): |
| 89 self._port = port | 93 self._port = port |
| 90 self._test_configuration_converter = TestConfigurationConverter(set(port
.all_test_configurations()), port.configuration_specifier_macros()) | 94 self._test_configuration_converter = TestConfigurationConverter( |
| 95 set(port.all_test_configurations()), port.configuration_specifier_ma
cros()) |
| 91 self._full_test_list = full_test_list | 96 self._full_test_list = full_test_list |
| 92 self._is_lint_mode = is_lint_mode | 97 self._is_lint_mode = is_lint_mode |
| 93 | 98 |
| 94 def parse(self, filename, expectations_string): | 99 def parse(self, filename, expectations_string): |
| 95 expectation_lines = [] | 100 expectation_lines = [] |
| 96 line_number = 0 | 101 line_number = 0 |
| 97 for line in expectations_string.split("\n"): | 102 for line in expectations_string.split('\n'): |
| 98 line_number += 1 | 103 line_number += 1 |
| 99 test_expectation = self._tokenize_line(filename, line, line_number) | 104 test_expectation = self._tokenize_line(filename, line, line_number) |
| 100 self._parse_line(test_expectation) | 105 self._parse_line(test_expectation) |
| 101 expectation_lines.append(test_expectation) | 106 expectation_lines.append(test_expectation) |
| 102 return expectation_lines | 107 return expectation_lines |
| 103 | 108 |
| 104 def _create_expectation_line(self, test_name, expectations, file_name): | 109 def _create_expectation_line(self, test_name, expectations, file_name): |
| 105 expectation_line = TestExpectationLine() | 110 expectation_line = TestExpectationLine() |
| 106 expectation_line.original_string = test_name | 111 expectation_line.original_string = test_name |
| 107 expectation_line.name = test_name | 112 expectation_line.name = test_name |
| 108 expectation_line.filename = file_name | 113 expectation_line.filename = file_name |
| 109 expectation_line.expectations = expectations | 114 expectation_line.expectations = expectations |
| 110 return expectation_line | 115 return expectation_line |
| 111 | 116 |
| 112 def expectation_line_for_test(self, test_name, expectations): | 117 def expectation_line_for_test(self, test_name, expectations): |
| 113 expectation_line = self._create_expectation_line(test_name, expectations
, '<Bot TestExpectations>') | 118 expectation_line = self._create_expectation_line(test_name, expectations
, '<Bot TestExpectations>') |
| 114 self._parse_line(expectation_line) | 119 self._parse_line(expectation_line) |
| 115 return expectation_line | 120 return expectation_line |
| 116 | 121 |
| 117 | |
| 118 def expectation_for_skipped_test(self, test_name): | 122 def expectation_for_skipped_test(self, test_name): |
| 119 if not self._port.test_exists(test_name): | 123 if not self._port.test_exists(test_name): |
| 120 _log.warning('The following test %s from the Skipped list doesn\'t e
xist' % test_name) | 124 _log.warning('The following test %s from the Skipped list doesn\'t e
xist' % test_name) |
| 121 expectation_line = self._create_expectation_line(test_name, [TestExpecta
tionParser.PASS_EXPECTATION], '<Skipped file>') | 125 expectation_line = self._create_expectation_line(test_name, [TestExpecta
tionParser.PASS_EXPECTATION], '<Skipped file>') |
| 122 expectation_line.expectations = [TestExpectationParser.SKIP_MODIFIER, Te
stExpectationParser.WONTFIX_MODIFIER] | 126 expectation_line.expectations = [TestExpectationParser.SKIP_MODIFIER, Te
stExpectationParser.WONTFIX_MODIFIER] |
| 123 expectation_line.is_skipped_outside_expectations_file = True | 127 expectation_line.is_skipped_outside_expectations_file = True |
| 124 self._parse_line(expectation_line) | 128 self._parse_line(expectation_line) |
| 125 return expectation_line | 129 return expectation_line |
| 126 | 130 |
| 127 def _parse_line(self, expectation_line): | 131 def _parse_line(self, expectation_line): |
| (...skipping 12 matching lines...) Expand all Loading... |
| 140 self._collect_matching_tests(expectation_line) | 144 self._collect_matching_tests(expectation_line) |
| 141 | 145 |
| 142 self._parse_specifiers(expectation_line) | 146 self._parse_specifiers(expectation_line) |
| 143 self._parse_expectations(expectation_line) | 147 self._parse_expectations(expectation_line) |
| 144 | 148 |
| 145 def _parse_specifiers(self, expectation_line): | 149 def _parse_specifiers(self, expectation_line): |
| 146 if self._is_lint_mode: | 150 if self._is_lint_mode: |
| 147 self._lint_line(expectation_line) | 151 self._lint_line(expectation_line) |
| 148 | 152 |
| 149 parsed_specifiers = set([specifier.lower() for specifier in expectation_
line.specifiers]) | 153 parsed_specifiers = set([specifier.lower() for specifier in expectation_
line.specifiers]) |
| 150 expectation_line.matching_configurations = self._test_configuration_conv
erter.to_config_set(parsed_specifiers, expectation_line.warnings) | 154 expectation_line.matching_configurations = self._test_configuration_conv
erter.to_config_set( |
| 155 parsed_specifiers, |
| 156 expectation_line.warnings) |
| 151 | 157 |
| 152 def _lint_line(self, expectation_line): | 158 def _lint_line(self, expectation_line): |
| 153 expectations = [expectation.lower() for expectation in expectation_line.
expectations] | 159 expectations = [expectation.lower() for expectation in expectation_line.
expectations] |
| 154 if not expectation_line.bugs and self.WONTFIX_MODIFIER not in expectatio
ns: | 160 if not expectation_line.bugs and self.WONTFIX_MODIFIER not in expectatio
ns: |
| 155 expectation_line.warnings.append(self.MISSING_BUG_WARNING) | 161 expectation_line.warnings.append(self.MISSING_BUG_WARNING) |
| 156 if self.REBASELINE_MODIFIER in expectations: | 162 if self.REBASELINE_MODIFIER in expectations: |
| 157 expectation_line.warnings.append('REBASELINE should only be used for
running rebaseline.py. Cannot be checked in.') | 163 expectation_line.warnings.append('REBASELINE should only be used for
running rebaseline.py. Cannot be checked in.') |
| 158 | 164 |
| 159 if self.NEEDS_REBASELINE_MODIFIER in expectations or self.NEEDS_MANUAL_R
EBASELINE_MODIFIER in expectations: | 165 if self.NEEDS_REBASELINE_MODIFIER in expectations or self.NEEDS_MANUAL_R
EBASELINE_MODIFIER in expectations: |
| 160 for test in expectation_line.matching_tests: | 166 for test in expectation_line.matching_tests: |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 [[bugs] [ "[" <configuration specifiers> "]" <name> [ "[" <expectations>
"]" ["#" <comment>] | 255 [[bugs] [ "[" <configuration specifiers> "]" <name> [ "[" <expectations>
"]" ["#" <comment>] |
| 250 | 256 |
| 251 Any errant whitespace is not preserved. | 257 Any errant whitespace is not preserved. |
| 252 | 258 |
| 253 """ | 259 """ |
| 254 expectation_line = TestExpectationLine() | 260 expectation_line = TestExpectationLine() |
| 255 expectation_line.original_string = expectation_string | 261 expectation_line.original_string = expectation_string |
| 256 expectation_line.filename = filename | 262 expectation_line.filename = filename |
| 257 expectation_line.line_numbers = str(line_number) | 263 expectation_line.line_numbers = str(line_number) |
| 258 | 264 |
| 259 comment_index = expectation_string.find("#") | 265 comment_index = expectation_string.find('#') |
| 260 if comment_index == -1: | 266 if comment_index == -1: |
| 261 comment_index = len(expectation_string) | 267 comment_index = len(expectation_string) |
| 262 else: | 268 else: |
| 263 expectation_line.comment = expectation_string[comment_index + 1:] | 269 expectation_line.comment = expectation_string[comment_index + 1:] |
| 264 | 270 |
| 265 remaining_string = re.sub(r"\s+", " ", expectation_string[:comment_index
].strip()) | 271 remaining_string = re.sub(r"\s+", ' ', expectation_string[:comment_index
].strip()) |
| 266 if len(remaining_string) == 0: | 272 if len(remaining_string) == 0: |
| 267 return expectation_line | 273 return expectation_line |
| 268 | 274 |
| 269 # special-case parsing this so that we fail immediately instead of treat
ing this as a test name | 275 # special-case parsing this so that we fail immediately instead of treat
ing this as a test name |
| 270 if remaining_string.startswith('//'): | 276 if remaining_string.startswith('//'): |
| 271 expectation_line.warnings = ['use "#" instead of "//" for comments'] | 277 expectation_line.warnings = ['use "#" instead of "//" for comments'] |
| 272 return expectation_line | 278 return expectation_line |
| 273 | 279 |
| 274 bugs = [] | 280 bugs = [] |
| 275 specifiers = [] | 281 specifiers = [] |
| 276 name = None | 282 name = None |
| 277 expectations = [] | 283 expectations = [] |
| 278 warnings = [] | 284 warnings = [] |
| 279 has_unrecognized_expectation = False | 285 has_unrecognized_expectation = False |
| 280 | 286 |
| 281 tokens = remaining_string.split() | 287 tokens = remaining_string.split() |
| 282 state = 'start' | 288 state = 'start' |
| 283 for token in tokens: | 289 for token in tokens: |
| 284 if (token.startswith(WEBKIT_BUG_PREFIX) or | 290 if (token.startswith(WEBKIT_BUG_PREFIX) or |
| 285 token.startswith(CHROMIUM_BUG_PREFIX) or | 291 token.startswith(CHROMIUM_BUG_PREFIX) or |
| 286 token.startswith(V8_BUG_PREFIX) or | 292 token.startswith(V8_BUG_PREFIX) or |
| 287 token.startswith(NAMED_BUG_PREFIX)): | 293 token.startswith(NAMED_BUG_PREFIX)): |
| 288 if state != 'start': | 294 if state != 'start': |
| 289 warnings.append('"%s" is not at the start of the line.' % to
ken) | 295 warnings.append('"%s" is not at the start of the line.' % to
ken) |
| 290 break | 296 break |
| 291 if token.startswith(WEBKIT_BUG_PREFIX): | 297 if token.startswith(WEBKIT_BUG_PREFIX): |
| 292 bugs.append(token) | 298 bugs.append(token) |
| 293 elif token.startswith(CHROMIUM_BUG_PREFIX): | 299 elif token.startswith(CHROMIUM_BUG_PREFIX): |
| 294 bugs.append(token) | 300 bugs.append(token) |
| 295 elif token.startswith(V8_BUG_PREFIX): | 301 elif token.startswith(V8_BUG_PREFIX): |
| 296 bugs.append(token) | 302 bugs.append(token) |
| 297 else: | 303 else: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 expectation_line.warnings = warnings | 363 expectation_line.warnings = warnings |
| 358 return expectation_line | 364 return expectation_line |
| 359 | 365 |
| 360 @classmethod | 366 @classmethod |
| 361 def _split_space_separated(cls, space_separated_string): | 367 def _split_space_separated(cls, space_separated_string): |
| 362 """Splits a space-separated string into an array.""" | 368 """Splits a space-separated string into an array.""" |
| 363 return [part.strip() for part in space_separated_string.strip().split('
')] | 369 return [part.strip() for part in space_separated_string.strip().split('
')] |
| 364 | 370 |
| 365 | 371 |
| 366 class TestExpectationLine(object): | 372 class TestExpectationLine(object): |
| 373 |
| 367 """Represents a line in test expectations file.""" | 374 """Represents a line in test expectations file.""" |
| 368 | 375 |
| 369 def __init__(self): | 376 def __init__(self): |
| 370 """Initializes a blank-line equivalent of an expectation.""" | 377 """Initializes a blank-line equivalent of an expectation.""" |
| 371 self.original_string = None | 378 self.original_string = None |
| 372 self.filename = None # this is the path to the expectations file for th
is line | 379 self.filename = None # this is the path to the expectations file for th
is line |
| 373 self.line_numbers = "0" | 380 self.line_numbers = '0' |
| 374 self.name = None # this is the path in the line itself | 381 self.name = None # this is the path in the line itself |
| 375 self.path = None # this is the normpath of self.name | 382 self.path = None # this is the normpath of self.name |
| 376 self.bugs = [] | 383 self.bugs = [] |
| 377 self.specifiers = [] | 384 self.specifiers = [] |
| 378 self.parsed_specifiers = [] | 385 self.parsed_specifiers = [] |
| 379 self.matching_configurations = set() | 386 self.matching_configurations = set() |
| 380 self.expectations = [] | 387 self.expectations = [] |
| 381 self.parsed_expectations = set() | 388 self.parsed_expectations = set() |
| 382 self.comment = None | 389 self.comment = None |
| 383 self.matching_tests = [] | 390 self.matching_tests = [] |
| 384 self.warnings = [] | 391 self.warnings = [] |
| 385 self.is_skipped_outside_expectations_file = False | 392 self.is_skipped_outside_expectations_file = False |
| 386 | 393 |
| 387 def __eq__(self, other): | 394 def __eq__(self, other): |
| 388 return (self.original_string == other.original_string | 395 return (self.original_string == other.original_string |
| 389 and self.filename == other.filename | 396 and self.filename == other.filename |
| 390 and self.line_numbers == other.line_numbers | 397 and self.line_numbers == other.line_numbers |
| 391 and self.name == other.name | 398 and self.name == other.name |
| 392 and self.path == other.path | 399 and self.path == other.path |
| 393 and self.bugs == other.bugs | 400 and self.bugs == other.bugs |
| 394 and self.specifiers == other.specifiers | 401 and self.specifiers == other.specifiers |
| 395 and self.parsed_specifiers == other.parsed_specifiers | 402 and self.parsed_specifiers == other.parsed_specifiers |
| 396 and self.matching_configurations == other.matching_configurations | 403 and self.matching_configurations == other.matching_configuration
s |
| 397 and self.expectations == other.expectations | 404 and self.expectations == other.expectations |
| 398 and self.parsed_expectations == other.parsed_expectations | 405 and self.parsed_expectations == other.parsed_expectations |
| 399 and self.comment == other.comment | 406 and self.comment == other.comment |
| 400 and self.matching_tests == other.matching_tests | 407 and self.matching_tests == other.matching_tests |
| 401 and self.warnings == other.warnings | 408 and self.warnings == other.warnings |
| 402 and self.is_skipped_outside_expectations_file == other.is_skipped_ou
tside_expectations_file) | 409 and self.is_skipped_outside_expectations_file == other.is_skippe
d_outside_expectations_file) |
| 403 | 410 |
| 404 def is_invalid(self): | 411 def is_invalid(self): |
| 405 return bool(self.warnings and self.warnings != [TestExpectationParser.MI
SSING_BUG_WARNING]) | 412 return bool(self.warnings and self.warnings != [TestExpectationParser.MI
SSING_BUG_WARNING]) |
| 406 | 413 |
| 407 def is_flaky(self): | 414 def is_flaky(self): |
| 408 return len(self.parsed_expectations) > 1 | 415 return len(self.parsed_expectations) > 1 |
| 409 | 416 |
| 410 def is_whitespace_or_comment(self): | 417 def is_whitespace_or_comment(self): |
| 411 return bool(re.match("^\s*$", self.original_string.split('#')[0])) | 418 return bool(re.match('^\s*$', self.original_string.split('#')[0])) |
| 412 | 419 |
| 413 @staticmethod | 420 @staticmethod |
| 414 def create_passing_expectation(test): | 421 def create_passing_expectation(test): |
| 415 expectation_line = TestExpectationLine() | 422 expectation_line = TestExpectationLine() |
| 416 expectation_line.name = test | 423 expectation_line.name = test |
| 417 expectation_line.path = test | 424 expectation_line.path = test |
| 418 expectation_line.parsed_expectations = set([PASS]) | 425 expectation_line.parsed_expectations = set([PASS]) |
| 419 expectation_line.expectations = set(['PASS']) | 426 expectation_line.expectations = set(['PASS']) |
| 420 expectation_line.matching_tests = [test] | 427 expectation_line.matching_tests = [test] |
| 421 return expectation_line | 428 return expectation_line |
| 422 | 429 |
| 423 @staticmethod | 430 @staticmethod |
| 424 def merge_expectation_lines(line1, line2, model_all_expectations): | 431 def merge_expectation_lines(line1, line2, model_all_expectations): |
| 425 """Merges the expectations of line2 into line1 and returns a fresh objec
t.""" | 432 """Merges the expectations of line2 into line1 and returns a fresh objec
t.""" |
| 426 if line1 is None: | 433 if line1 is None: |
| 427 return line2 | 434 return line2 |
| 428 if line2 is None: | 435 if line2 is None: |
| 429 return line1 | 436 return line1 |
| 430 if model_all_expectations and line1.filename != line2.filename: | 437 if model_all_expectations and line1.filename != line2.filename: |
| 431 return line2 | 438 return line2 |
| 432 | 439 |
| 433 # Don't merge original_string or comment. | 440 # Don't merge original_string or comment. |
| 434 result = TestExpectationLine() | 441 result = TestExpectationLine() |
| 435 # We only care about filenames when we're linting, in which case the fil
enames are the same. | 442 # We only care about filenames when we're linting, in which case the fil
enames are the same. |
| 436 # Not clear that there's anything better to do when not linting and the
filenames are different. | 443 # Not clear that there's anything better to do when not linting and the
filenames are different. |
| 437 if model_all_expectations: | 444 if model_all_expectations: |
| 438 result.filename = line2.filename | 445 result.filename = line2.filename |
| 439 result.line_numbers = line1.line_numbers + "," + line2.line_numbers | 446 result.line_numbers = line1.line_numbers + ',' + line2.line_numbers |
| 440 result.name = line1.name | 447 result.name = line1.name |
| 441 result.path = line1.path | 448 result.path = line1.path |
| 442 result.parsed_expectations = set(line1.parsed_expectations) | set(line2.
parsed_expectations) | 449 result.parsed_expectations = set(line1.parsed_expectations) | set(line2.
parsed_expectations) |
| 443 result.expectations = list(set(line1.expectations) | set(line2.expectati
ons)) | 450 result.expectations = list(set(line1.expectations) | set(line2.expectati
ons)) |
| 444 result.bugs = list(set(line1.bugs) | set(line2.bugs)) | 451 result.bugs = list(set(line1.bugs) | set(line2.bugs)) |
| 445 result.specifiers = list(set(line1.specifiers) | set(line2.specifiers)) | 452 result.specifiers = list(set(line1.specifiers) | set(line2.specifiers)) |
| 446 result.parsed_specifiers = list(set(line1.parsed_specifiers) | set(line2
.parsed_specifiers)) | 453 result.parsed_specifiers = list(set(line1.parsed_specifiers) | set(line2
.parsed_specifiers)) |
| 447 result.matching_configurations = set(line1.matching_configurations) | se
t(line2.matching_configurations) | 454 result.matching_configurations = set(line1.matching_configurations) | se
t(line2.matching_configurations) |
| 448 result.matching_tests = list(list(set(line1.matching_tests) | set(line2.
matching_tests))) | 455 result.matching_tests = list(list(set(line1.matching_tests) | set(line2.
matching_tests))) |
| 449 result.warnings = list(set(line1.warnings) | set(line2.warnings)) | 456 result.warnings = list(set(line1.warnings) | set(line2.warnings)) |
| 450 result.is_skipped_outside_expectations_file = line1.is_skipped_outside_e
xpectations_file or line2.is_skipped_outside_expectations_file | 457 result.is_skipped_outside_expectations_file = line1.is_skipped_outside_e
xpectations_file or line2.is_skipped_outside_expectations_file |
| 451 return result | 458 return result |
| 452 | 459 |
| 453 def to_string(self, test_configuration_converter, include_specifiers=True, i
nclude_expectations=True, include_comment=True): | 460 def to_string(self, test_configuration_converter, include_specifiers=True, i
nclude_expectations=True, include_comment=True): |
| 454 parsed_expectation_to_string = dict([[parsed_expectation, expectation_st
ring] for expectation_string, parsed_expectation in TestExpectations.EXPECTATION
S.items()]) | 461 parsed_expectation_to_string = dict([[parsed_expectation, expectation_st
ring] |
| 462 for expectation_string, parsed_expe
ctation in TestExpectations.EXPECTATIONS.items()]) |
| 455 | 463 |
| 456 if self.is_invalid(): | 464 if self.is_invalid(): |
| 457 return self.original_string or '' | 465 return self.original_string or '' |
| 458 | 466 |
| 459 if self.name is None: | 467 if self.name is None: |
| 460 return '' if self.comment is None else "#%s" % self.comment | 468 return '' if self.comment is None else '#%s' % self.comment |
| 461 | 469 |
| 462 if test_configuration_converter and self.bugs: | 470 if test_configuration_converter and self.bugs: |
| 463 specifiers_list = test_configuration_converter.to_specifiers_list(se
lf.matching_configurations) | 471 specifiers_list = test_configuration_converter.to_specifiers_list(se
lf.matching_configurations) |
| 464 result = [] | 472 result = [] |
| 465 for specifiers in specifiers_list: | 473 for specifiers in specifiers_list: |
| 466 # FIXME: this is silly that we join the specifiers and then imme
diately split them. | 474 # FIXME: this is silly that we join the specifiers and then imme
diately split them. |
| 467 specifiers = self._serialize_parsed_specifiers(test_configuratio
n_converter, specifiers).split() | 475 specifiers = self._serialize_parsed_specifiers(test_configuratio
n_converter, specifiers).split() |
| 468 expectations = self._serialize_parsed_expectations(parsed_expect
ation_to_string).split() | 476 expectations = self._serialize_parsed_expectations(parsed_expect
ation_to_string).split() |
| 469 result.append(self._format_line(self.bugs, specifiers, self.name
, expectations, self.comment)) | 477 result.append(self._format_line(self.bugs, specifiers, self.name
, expectations, self.comment)) |
| 470 return "\n".join(result) if result else None | 478 return '\n'.join(result) if result else None |
| 471 | 479 |
| 472 return self._format_line(self.bugs, self.specifiers, self.name, self.exp
ectations, self.comment, | 480 return self._format_line(self.bugs, self.specifiers, self.name, self.exp
ectations, self.comment, |
| 473 include_specifiers, include_expectations, include_comment) | 481 include_specifiers, include_expectations, inclu
de_comment) |
| 474 | 482 |
| 475 def to_csv(self): | 483 def to_csv(self): |
| 476 # Note that this doesn't include the comments. | 484 # Note that this doesn't include the comments. |
| 477 return '%s,%s,%s,%s' % (self.name, ' '.join(self.bugs), ' '.join(self.sp
ecifiers), ' '.join(self.expectations)) | 485 return '%s,%s,%s,%s' % (self.name, ' '.join(self.bugs), ' '.join(self.sp
ecifiers), ' '.join(self.expectations)) |
| 478 | 486 |
| 479 def _serialize_parsed_expectations(self, parsed_expectation_to_string): | 487 def _serialize_parsed_expectations(self, parsed_expectation_to_string): |
| 480 result = [] | 488 result = [] |
| 481 for index in TestExpectations.EXPECTATIONS.values(): | 489 for index in TestExpectations.EXPECTATIONS.values(): |
| 482 if index in self.parsed_expectations: | 490 if index in self.parsed_expectations: |
| 483 result.append(parsed_expectation_to_string[index]) | 491 result.append(parsed_expectation_to_string[index]) |
| 484 return ' '.join(result) | 492 return ' '.join(result) |
| 485 | 493 |
| 486 def _serialize_parsed_specifiers(self, test_configuration_converter, specifi
ers): | 494 def _serialize_parsed_specifiers(self, test_configuration_converter, specifi
ers): |
| 487 result = [] | 495 result = [] |
| 488 result.extend(sorted(self.parsed_specifiers)) | 496 result.extend(sorted(self.parsed_specifiers)) |
| 489 result.extend(test_configuration_converter.specifier_sorter().sort_speci
fiers(specifiers)) | 497 result.extend(test_configuration_converter.specifier_sorter().sort_speci
fiers(specifiers)) |
| 490 return ' '.join(result) | 498 return ' '.join(result) |
| 491 | 499 |
| 492 @staticmethod | 500 @staticmethod |
| 493 def _filter_redundant_expectations(expectations): | 501 def _filter_redundant_expectations(expectations): |
| 494 if set(expectations) == set(['Pass', 'Skip']): | 502 if set(expectations) == set(['Pass', 'Skip']): |
| 495 return ['Skip'] | 503 return ['Skip'] |
| 496 if set(expectations) == set(['Pass', 'Slow']): | 504 if set(expectations) == set(['Pass', 'Slow']): |
| 497 return ['Slow'] | 505 return ['Slow'] |
| 498 return expectations | 506 return expectations |
| 499 | 507 |
| 500 @staticmethod | 508 @staticmethod |
| 501 def _format_line(bugs, specifiers, name, expectations, comment, include_spec
ifiers=True, include_expectations=True, include_comment=True): | 509 def _format_line(bugs, specifiers, name, expectations, comment, include_spec
ifiers=True, |
| 510 include_expectations=True, include_comment=True): |
| 502 new_specifiers = [] | 511 new_specifiers = [] |
| 503 new_expectations = [] | 512 new_expectations = [] |
| 504 for specifier in specifiers: | 513 for specifier in specifiers: |
| 505 # FIXME: Make this all work with the mixed-cased specifiers (e.g. Wo
ntFix, Slow, etc). | 514 # FIXME: Make this all work with the mixed-cased specifiers (e.g. Wo
ntFix, Slow, etc). |
| 506 specifier = specifier.upper() | 515 specifier = specifier.upper() |
| 507 new_specifiers.append(TestExpectationParser._inverted_configuration_
tokens.get(specifier, specifier)) | 516 new_specifiers.append(TestExpectationParser._inverted_configuration_
tokens.get(specifier, specifier)) |
| 508 | 517 |
| 509 for expectation in expectations: | 518 for expectation in expectations: |
| 510 expectation = expectation.upper() | 519 expectation = expectation.upper() |
| 511 new_expectations.append(TestExpectationParser._inverted_expectation_
tokens.get(expectation, expectation)) | 520 new_expectations.append(TestExpectationParser._inverted_expectation_
tokens.get(expectation, expectation)) |
| 512 | 521 |
| 513 result = '' | 522 result = '' |
| 514 if include_specifiers and (bugs or new_specifiers): | 523 if include_specifiers and (bugs or new_specifiers): |
| 515 if bugs: | 524 if bugs: |
| 516 result += ' '.join(bugs) + ' ' | 525 result += ' '.join(bugs) + ' ' |
| 517 if new_specifiers: | 526 if new_specifiers: |
| 518 result += '[ %s ] ' % ' '.join(new_specifiers) | 527 result += '[ %s ] ' % ' '.join(new_specifiers) |
| 519 result += name | 528 result += name |
| 520 if include_expectations and new_expectations: | 529 if include_expectations and new_expectations: |
| 521 new_expectations = TestExpectationLine._filter_redundant_expectation
s(new_expectations) | 530 new_expectations = TestExpectationLine._filter_redundant_expectation
s(new_expectations) |
| 522 result += ' [ %s ]' % ' '.join(sorted(set(new_expectations))) | 531 result += ' [ %s ]' % ' '.join(sorted(set(new_expectations))) |
| 523 if include_comment and comment is not None: | 532 if include_comment and comment is not None: |
| 524 result += " #%s" % comment | 533 result += ' #%s' % comment |
| 525 return result | 534 return result |
| 526 | 535 |
| 527 | 536 |
| 528 # FIXME: Refactor API to be a proper CRUD. | 537 # FIXME: Refactor API to be a proper CRUD. |
| 529 class TestExpectationsModel(object): | 538 class TestExpectationsModel(object): |
| 539 |
| 530 """Represents relational store of all expectations and provides CRUD semanti
cs to manage it.""" | 540 """Represents relational store of all expectations and provides CRUD semanti
cs to manage it.""" |
| 531 | 541 |
| 532 def __init__(self, shorten_filename=None): | 542 def __init__(self, shorten_filename=None): |
| 533 # Maps a test to its list of expectations. | 543 # Maps a test to its list of expectations. |
| 534 self._test_to_expectations = {} | 544 self._test_to_expectations = {} |
| 535 | 545 |
| 536 # Maps a test to list of its specifiers (string values) | 546 # Maps a test to list of its specifiers (string values) |
| 537 self._test_to_specifiers = {} | 547 self._test_to_specifiers = {} |
| 538 | 548 |
| 539 # Maps a test to a TestExpectationLine instance. | 549 # Maps a test to a TestExpectationLine instance. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 554 | 564 |
| 555 def _merge_dict_of_sets(self, self_dict, other_dict): | 565 def _merge_dict_of_sets(self, self_dict, other_dict): |
| 556 for key in other_dict: | 566 for key in other_dict: |
| 557 self_dict[key] |= other_dict[key] | 567 self_dict[key] |= other_dict[key] |
| 558 | 568 |
| 559 def merge_model(self, other): | 569 def merge_model(self, other): |
| 560 self._merge_test_map(self._test_to_expectations, other._test_to_expectat
ions) | 570 self._merge_test_map(self._test_to_expectations, other._test_to_expectat
ions) |
| 561 | 571 |
| 562 for test, line in other._test_to_expectation_line.items(): | 572 for test, line in other._test_to_expectation_line.items(): |
| 563 if test in self._test_to_expectation_line: | 573 if test in self._test_to_expectation_line: |
| 564 line = TestExpectationLine.merge_expectation_lines(self._test_to
_expectation_line[test], line, model_all_expectations=False) | 574 line = TestExpectationLine.merge_expectation_lines( |
| 575 self._test_to_expectation_line[test], |
| 576 line, |
| 577 model_all_expectations=False) |
| 565 self._test_to_expectation_line[test] = line | 578 self._test_to_expectation_line[test] = line |
| 566 | 579 |
| 567 self._merge_dict_of_sets(self._expectation_to_tests, other._expectation_
to_tests) | 580 self._merge_dict_of_sets(self._expectation_to_tests, other._expectation_
to_tests) |
| 568 self._merge_dict_of_sets(self._timeline_to_tests, other._timeline_to_tes
ts) | 581 self._merge_dict_of_sets(self._timeline_to_tests, other._timeline_to_tes
ts) |
| 569 self._merge_dict_of_sets(self._result_type_to_tests, other._result_type_
to_tests) | 582 self._merge_dict_of_sets(self._result_type_to_tests, other._result_type_
to_tests) |
| 570 | 583 |
| 571 def _dict_of_sets(self, strings_to_constants): | 584 def _dict_of_sets(self, strings_to_constants): |
| 572 """Takes a dict of strings->constants and returns a dict mapping | 585 """Takes a dict of strings->constants and returns a dict mapping |
| 573 each constant to an empty set.""" | 586 each constant to an empty set.""" |
| 574 d = {} | 587 d = {} |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 expectations = self.get_expectations(test) | 630 expectations = self.get_expectations(test) |
| 618 retval = [] | 631 retval = [] |
| 619 | 632 |
| 620 # FIXME: WontFix should cause the test to get skipped without artificial
ly adding SKIP to the expectations list. | 633 # FIXME: WontFix should cause the test to get skipped without artificial
ly adding SKIP to the expectations list. |
| 621 if WONTFIX in expectations and SKIP in expectations: | 634 if WONTFIX in expectations and SKIP in expectations: |
| 622 expectations.remove(SKIP) | 635 expectations.remove(SKIP) |
| 623 | 636 |
| 624 for expectation in expectations: | 637 for expectation in expectations: |
| 625 retval.append(self.expectation_to_string(expectation)) | 638 retval.append(self.expectation_to_string(expectation)) |
| 626 | 639 |
| 627 return " ".join(retval) | 640 return ' '.join(retval) |
| 628 | 641 |
| 629 def expectation_to_string(self, expectation): | 642 def expectation_to_string(self, expectation): |
| 630 """Return the uppercased string equivalent of a given expectation.""" | 643 """Return the uppercased string equivalent of a given expectation.""" |
| 631 for item in TestExpectations.EXPECTATIONS.items(): | 644 for item in TestExpectations.EXPECTATIONS.items(): |
| 632 if item[1] == expectation: | 645 if item[1] == expectation: |
| 633 return item[0].upper() | 646 return item[0].upper() |
| 634 raise ValueError(expectation) | 647 raise ValueError(expectation) |
| 635 | 648 |
| 636 def remove_expectation_line(self, test): | 649 def remove_expectation_line(self, test): |
| 637 if not self.has_test(test): | 650 if not self.has_test(test): |
| 638 return | 651 return |
| 639 self._clear_expectations_for_test(test) | 652 self._clear_expectations_for_test(test) |
| 640 del self._test_to_expectation_line[test] | 653 del self._test_to_expectation_line[test] |
| 641 | 654 |
| 642 def add_expectation_line(self, expectation_line, | 655 def add_expectation_line(self, expectation_line, |
| 643 model_all_expectations=False): | 656 model_all_expectations=False): |
| 644 """Returns a list of warnings encountered while matching specifiers.""" | 657 """Returns a list of warnings encountered while matching specifiers.""" |
| 645 | 658 |
| 646 if expectation_line.is_invalid(): | 659 if expectation_line.is_invalid(): |
| 647 return | 660 return |
| 648 | 661 |
| 649 for test in expectation_line.matching_tests: | 662 for test in expectation_line.matching_tests: |
| 650 if self._already_seen_better_match(test, expectation_line): | 663 if self._already_seen_better_match(test, expectation_line): |
| 651 continue | 664 continue |
| 652 | 665 |
| 653 if model_all_expectations: | 666 if model_all_expectations: |
| 654 expectation_line = TestExpectationLine.merge_expectation_lines(s
elf.get_expectation_line(test), expectation_line, model_all_expectations) | 667 expectation_line = TestExpectationLine.merge_expectation_lines( |
| 668 self.get_expectation_line(test), |
| 669 expectation_line, |
| 670 model_all_expectations) |
| 655 | 671 |
| 656 self._clear_expectations_for_test(test) | 672 self._clear_expectations_for_test(test) |
| 657 self._test_to_expectation_line[test] = expectation_line | 673 self._test_to_expectation_line[test] = expectation_line |
| 658 self._add_test(test, expectation_line) | 674 self._add_test(test, expectation_line) |
| 659 | 675 |
| 660 def _add_test(self, test, expectation_line): | 676 def _add_test(self, test, expectation_line): |
| 661 """Sets the expected state for a given test. | 677 """Sets the expected state for a given test. |
| 662 | 678 |
| 663 This routine assumes the test has not been added before. If it has, | 679 This routine assumes the test has not been added before. If it has, |
| 664 use _clear_expectations_for_test() to reset the state prior to | 680 use _clear_expectations_for_test() to reset the state prior to |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 # to be warnings and return False". | 757 # to be warnings and return False". |
| 742 | 758 |
| 743 if prev_expectation_line.matching_configurations == expectation_line.mat
ching_configurations: | 759 if prev_expectation_line.matching_configurations == expectation_line.mat
ching_configurations: |
| 744 expectation_line.warnings.append('Duplicate or ambiguous entry lines
%s:%s and %s:%s.' % ( | 760 expectation_line.warnings.append('Duplicate or ambiguous entry lines
%s:%s and %s:%s.' % ( |
| 745 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, | 761 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, |
| 746 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) | 762 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) |
| 747 return True | 763 return True |
| 748 | 764 |
| 749 if prev_expectation_line.matching_configurations >= expectation_line.mat
ching_configurations: | 765 if prev_expectation_line.matching_configurations >= expectation_line.mat
ching_configurations: |
| 750 expectation_line.warnings.append('More specific entry for %s on line
%s:%s overrides line %s:%s.' % (expectation_line.name, | 766 expectation_line.warnings.append('More specific entry for %s on line
%s:%s overrides line %s:%s.' % (expectation_line.name, |
| 751 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, | 767
self._shorten_filename( |
| 752 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) | 768
prev_expectation_line.filename), prev_expec
tation_line.line_numbers, |
| 769
self._shorten_filename(expectation_line.filenam
e), expectation_line.line_numbers)) |
| 753 # FIXME: return False if we want more specific to win. | 770 # FIXME: return False if we want more specific to win. |
| 754 return True | 771 return True |
| 755 | 772 |
| 756 if prev_expectation_line.matching_configurations <= expectation_line.mat
ching_configurations: | 773 if prev_expectation_line.matching_configurations <= expectation_line.mat
ching_configurations: |
| 757 expectation_line.warnings.append('More specific entry for %s on line
%s:%s overrides line %s:%s.' % (expectation_line.name, | 774 expectation_line.warnings.append('More specific entry for %s on line
%s:%s overrides line %s:%s.' % (expectation_line.name, |
| 758 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers, | 775
self._shorten_filename( |
| 759 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers)) | 776
expectation_line.filename), expectation_lin
e.line_numbers, |
| 777
self._shorten_filename(prev_expectation_line.fi
lename), prev_expectation_line.line_numbers)) |
| 760 return True | 778 return True |
| 761 | 779 |
| 762 if prev_expectation_line.matching_configurations & expectation_line.matc
hing_configurations: | 780 if prev_expectation_line.matching_configurations & expectation_line.matc
hing_configurations: |
| 763 expectation_line.warnings.append('Entries for %s on lines %s:%s and
%s:%s match overlapping sets of configurations.' % (expectation_line.name, | 781 expectation_line.warnings.append('Entries for %s on lines %s:%s and
%s:%s match overlapping sets of configurations.' % (expectation_line.name, |
| 764 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, | 782
self._shorten_filename( |
| 765 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) | 783
prev_expectation_line.fi
lename), prev_expectation_line.line_numbers, |
| 784
self._shorten_filename(expec
tation_line.filename), expectation_line.line_numbers)) |
| 766 return True | 785 return True |
| 767 | 786 |
| 768 # Configuration sets are disjoint, then. | 787 # Configuration sets are disjoint, then. |
| 769 return False | 788 return False |
| 770 | 789 |
| 771 | 790 |
| 772 class TestExpectations(object): | 791 class TestExpectations(object): |
| 792 |
| 773 """Test expectations consist of lines with specifications of what | 793 """Test expectations consist of lines with specifications of what |
| 774 to expect from layout test cases. The test cases can be directories | 794 to expect from layout test cases. The test cases can be directories |
| 775 in which case the expectations apply to all test cases in that | 795 in which case the expectations apply to all test cases in that |
| 776 directory and any subdirectory. The format is along the lines of: | 796 directory and any subdirectory. The format is along the lines of: |
| 777 | 797 |
| 778 LayoutTests/fast/js/fixme.js [ Failure ] | 798 LayoutTests/fast/js/fixme.js [ Failure ] |
| 779 LayoutTests/fast/js/flaky.js [ Failure Pass ] | 799 LayoutTests/fast/js/flaky.js [ Failure Pass ] |
| 780 LayoutTests/fast/js/crash.js [ Crash Failure Pass Timeout ] | 800 LayoutTests/fast/js/crash.js [ Crash Failure Pass Timeout ] |
| 781 ... | 801 ... |
| 782 | 802 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 808 'timeout': TIMEOUT, | 828 'timeout': TIMEOUT, |
| 809 'crash': CRASH, | 829 'crash': CRASH, |
| 810 'leak': LEAK, | 830 'leak': LEAK, |
| 811 'missing': MISSING, | 831 'missing': MISSING, |
| 812 TestExpectationParser.SKIP_MODIFIER: SKIP, | 832 TestExpectationParser.SKIP_MODIFIER: SKIP, |
| 813 TestExpectationParser.NEEDS_REBASELINE_MODIFIER: NEEDS_REBAS
ELINE, | 833 TestExpectationParser.NEEDS_REBASELINE_MODIFIER: NEEDS_REBAS
ELINE, |
| 814 TestExpectationParser.NEEDS_MANUAL_REBASELINE_MODIFIER: NEED
S_MANUAL_REBASELINE, | 834 TestExpectationParser.NEEDS_MANUAL_REBASELINE_MODIFIER: NEED
S_MANUAL_REBASELINE, |
| 815 TestExpectationParser.WONTFIX_MODIFIER: WONTFIX, | 835 TestExpectationParser.WONTFIX_MODIFIER: WONTFIX, |
| 816 TestExpectationParser.SLOW_MODIFIER: SLOW, | 836 TestExpectationParser.SLOW_MODIFIER: SLOW, |
| 817 TestExpectationParser.REBASELINE_MODIFIER: REBASELINE, | 837 TestExpectationParser.REBASELINE_MODIFIER: REBASELINE, |
| 818 } | 838 } |
| 819 | 839 |
| 820 EXPECTATIONS_TO_STRING = dict((k, v) for (v, k) in EXPECTATIONS.iteritems()) | 840 EXPECTATIONS_TO_STRING = dict((k, v) for (v, k) in EXPECTATIONS.iteritems()) |
| 821 | 841 |
| 822 # (aggregated by category, pass/fail/skip, type) | 842 # (aggregated by category, pass/fail/skip, type) |
| 823 EXPECTATION_DESCRIPTIONS = {SKIP: 'skipped', | 843 EXPECTATION_DESCRIPTIONS = {SKIP: 'skipped', |
| 824 PASS: 'passes', | 844 PASS: 'passes', |
| 825 FAIL: 'failures', | 845 FAIL: 'failures', |
| 826 IMAGE: 'image-only failures', | 846 IMAGE: 'image-only failures', |
| 827 TEXT: 'text-only failures', | 847 TEXT: 'text-only failures', |
| 828 IMAGE_PLUS_TEXT: 'image and text failures', | 848 IMAGE_PLUS_TEXT: 'image and text failures', |
| (...skipping 25 matching lines...) Expand all Loading... |
| 854 """Returns whether we got a result we were expecting. | 874 """Returns whether we got a result we were expecting. |
| 855 Args: | 875 Args: |
| 856 result: actual result of a test execution | 876 result: actual result of a test execution |
| 857 expected_results: set of results listed in test_expectations | 877 expected_results: set of results listed in test_expectations |
| 858 test_needs_rebaselining: whether test was marked as REBASELINE""" | 878 test_needs_rebaselining: whether test was marked as REBASELINE""" |
| 859 if not (set(expected_results) - (set(TestExpectations.NON_TEST_OUTCOME_E
XPECTATIONS))): | 879 if not (set(expected_results) - (set(TestExpectations.NON_TEST_OUTCOME_E
XPECTATIONS))): |
| 860 expected_results = set([PASS]) | 880 expected_results = set([PASS]) |
| 861 | 881 |
| 862 if result in expected_results: | 882 if result in expected_results: |
| 863 return True | 883 return True |
| 864 if result in (PASS, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, MISSING) and (N
EEDS_REBASELINE in expected_results or NEEDS_MANUAL_REBASELINE in expected_resul
ts): | 884 if result in (PASS, TEXT, IMAGE, IMAGE_PLUS_TEXT, AUDIO, MISSING) and ( |
| 885 NEEDS_REBASELINE in expected_results or NEEDS_MANUAL_REBASELINE
in expected_results): |
| 865 return True | 886 return True |
| 866 if result in (TEXT, IMAGE_PLUS_TEXT, AUDIO) and (FAIL in expected_result
s): | 887 if result in (TEXT, IMAGE_PLUS_TEXT, AUDIO) and (FAIL in expected_result
s): |
| 867 return True | 888 return True |
| 868 if result == MISSING and test_needs_rebaselining: | 889 if result == MISSING and test_needs_rebaselining: |
| 869 return True | 890 return True |
| 870 if result == SKIP: | 891 if result == SKIP: |
| 871 return True | 892 return True |
| 872 return False | 893 return False |
| 873 | 894 |
| 874 @staticmethod | 895 @staticmethod |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 suffixes.add('wav') | 941 suffixes.add('wav') |
| 921 if 'MISSING' in expectations: | 942 if 'MISSING' in expectations: |
| 922 suffixes.add('txt') | 943 suffixes.add('txt') |
| 923 suffixes.add('png') | 944 suffixes.add('png') |
| 924 suffixes.add('wav') | 945 suffixes.add('wav') |
| 925 return suffixes | 946 return suffixes |
| 926 | 947 |
| 927 # FIXME: This constructor does too much work. We should move the actual pars
ing of | 948 # FIXME: This constructor does too much work. We should move the actual pars
ing of |
| 928 # the expectations into separate routines so that linting and handling overr
ides | 949 # the expectations into separate routines so that linting and handling overr
ides |
| 929 # can be controlled separately, and the constructor can be more of a no-op. | 950 # can be controlled separately, and the constructor can be more of a no-op. |
| 930 def __init__(self, port, tests=None, include_overrides=True, expectations_di
ct=None, model_all_expectations=False, is_lint_mode=False): | 951 def __init__(self, port, tests=None, include_overrides=True, expectations_di
ct=None, |
| 952 model_all_expectations=False, is_lint_mode=False): |
| 931 self._full_test_list = tests | 953 self._full_test_list = tests |
| 932 self._test_config = port.test_configuration() | 954 self._test_config = port.test_configuration() |
| 933 self._is_lint_mode = is_lint_mode | 955 self._is_lint_mode = is_lint_mode |
| 934 self._model_all_expectations = self._is_lint_mode or model_all_expectati
ons | 956 self._model_all_expectations = self._is_lint_mode or model_all_expectati
ons |
| 935 self._model = TestExpectationsModel(self._shorten_filename) | 957 self._model = TestExpectationsModel(self._shorten_filename) |
| 936 self._parser = TestExpectationParser(port, tests, self._is_lint_mode) | 958 self._parser = TestExpectationParser(port, tests, self._is_lint_mode) |
| 937 self._port = port | 959 self._port = port |
| 938 self._skipped_tests_warnings = [] | 960 self._skipped_tests_warnings = [] |
| 939 self._expectations = [] | 961 self._expectations = [] |
| 940 | 962 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 def _shorten_filename(self, filename): | 1034 def _shorten_filename(self, filename): |
| 1013 if filename.startswith(self._port.path_from_webkit_base()): | 1035 if filename.startswith(self._port.path_from_webkit_base()): |
| 1014 return self._port.host.filesystem.relpath(filename, self._port.path_
from_webkit_base()) | 1036 return self._port.host.filesystem.relpath(filename, self._port.path_
from_webkit_base()) |
| 1015 return filename | 1037 return filename |
| 1016 | 1038 |
| 1017 def _report_warnings(self): | 1039 def _report_warnings(self): |
| 1018 warnings = [] | 1040 warnings = [] |
| 1019 for expectation in self._expectations: | 1041 for expectation in self._expectations: |
| 1020 for warning in expectation.warnings: | 1042 for warning in expectation.warnings: |
| 1021 warnings.append('%s:%s %s %s' % (self._shorten_filename(expectat
ion.filename), expectation.line_numbers, | 1043 warnings.append('%s:%s %s %s' % (self._shorten_filename(expectat
ion.filename), expectation.line_numbers, |
| 1022 warning, expectation.name if expectation.expecta
tions else expectation.original_string)) | 1044 warning, expectation.name if ex
pectation.expectations else expectation.original_string)) |
| 1023 | 1045 |
| 1024 if warnings: | 1046 if warnings: |
| 1025 self._has_warnings = True | 1047 self._has_warnings = True |
| 1026 if self._is_lint_mode: | 1048 if self._is_lint_mode: |
| 1027 raise ParseError(warnings) | 1049 raise ParseError(warnings) |
| 1028 _log.warning('--lint-test-files warnings:') | 1050 _log.warning('--lint-test-files warnings:') |
| 1029 for warning in warnings: | 1051 for warning in warnings: |
| 1030 _log.warning(warning) | 1052 _log.warning(warning) |
| 1031 _log.warning('') | 1053 _log.warning('') |
| 1032 | 1054 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 def serialize(expectation_line): | 1138 def serialize(expectation_line): |
| 1117 # If reconstitute_only_these is an empty list, we want to return ori
ginal_string. | 1139 # If reconstitute_only_these is an empty list, we want to return ori
ginal_string. |
| 1118 # So we need to compare reconstitute_only_these to None, not just ch
eck if it's falsey. | 1140 # So we need to compare reconstitute_only_these to None, not just ch
eck if it's falsey. |
| 1119 if reconstitute_only_these is None or expectation_line in reconstitu
te_only_these: | 1141 if reconstitute_only_these is None or expectation_line in reconstitu
te_only_these: |
| 1120 return expectation_line.to_string(test_configuration_converter) | 1142 return expectation_line.to_string(test_configuration_converter) |
| 1121 return expectation_line.original_string | 1143 return expectation_line.original_string |
| 1122 | 1144 |
| 1123 def nones_out(expectation_line): | 1145 def nones_out(expectation_line): |
| 1124 return expectation_line is not None | 1146 return expectation_line is not None |
| 1125 | 1147 |
| 1126 return "\n".join(filter(nones_out, map(serialize, expectation_lines))) | 1148 return '\n'.join(filter(nones_out, map(serialize, expectation_lines))) |
| OLD | NEW |