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 |