| 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 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 raise ValueError(expectation) | 654 raise ValueError(expectation) |
| 655 | 655 |
| 656 def remove_expectation_line(self, test): | 656 def remove_expectation_line(self, test): |
| 657 if not self.has_test(test): | 657 if not self.has_test(test): |
| 658 return | 658 return |
| 659 self._clear_expectations_for_test(test) | 659 self._clear_expectations_for_test(test) |
| 660 del self._test_to_expectation_line[test] | 660 del self._test_to_expectation_line[test] |
| 661 | 661 |
| 662 def add_expectation_line(self, expectation_line, | 662 def add_expectation_line(self, expectation_line, |
| 663 model_all_expectations=False): | 663 model_all_expectations=False): |
| 664 """Returns a list of warnings encountered while matching specifiers.""" |
| 665 |
| 664 if expectation_line.is_invalid(): | 666 if expectation_line.is_invalid(): |
| 665 return | 667 return |
| 666 | 668 |
| 667 for test in expectation_line.matching_tests: | 669 for test in expectation_line.matching_tests: |
| 668 lines_involve_rebaseline = False | 670 if self._already_seen_better_match(test, expectation_line): |
| 669 prev_expectation_line = self.get_expectation_line(test) | 671 continue |
| 670 | 672 |
| 671 if prev_expectation_line: | 673 if model_all_expectations: |
| 672 # The previous path matched more of the test. | 674 expectation_line = TestExpectationLine.merge_expectation_lines(s
elf.get_expectation_line(test), expectation_line, model_all_expectations) |
| 673 if len(prev_expectation_line.path) > len(expectation_line.path): | |
| 674 continue | |
| 675 | |
| 676 if self._lines_conflict(prev_expectation_line, expectation_line)
: | |
| 677 continue | |
| 678 | |
| 679 lines_involve_rebaseline = self._expects_rebaseline(prev_expecta
tion_line) or self._expects_rebaseline(expectation_line) | |
| 680 | |
| 681 # Exact path matches that conflict should be merged, e.g. | |
| 682 # [ Pass Timeout ] + [ NeedsRebaseline ] ==> [ Pass Timeout NeedsReb
aseline ]. | |
| 683 if model_all_expectations or lines_involve_rebaseline: | |
| 684 expectation_line = TestExpectationLine.merge_expectation_lines(p
rev_expectation_line, expectation_line, model_all_expectations) | |
| 685 | 675 |
| 686 self._clear_expectations_for_test(test) | 676 self._clear_expectations_for_test(test) |
| 687 self._test_to_expectation_line[test] = expectation_line | 677 self._test_to_expectation_line[test] = expectation_line |
| 688 self._add_test(test, expectation_line) | 678 self._add_test(test, expectation_line) |
| 689 | 679 |
| 690 def _add_test(self, test, expectation_line): | 680 def _add_test(self, test, expectation_line): |
| 691 """Sets the expected state for a given test. | 681 """Sets the expected state for a given test. |
| 692 | 682 |
| 693 This routine assumes the test has not been added before. If it has, | 683 This routine assumes the test has not been added before. If it has, |
| 694 use _clear_expectations_for_test() to reset the state prior to | 684 use _clear_expectations_for_test() to reset the state prior to |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 def _remove_from_sets(self, test, dict_of_sets_of_tests): | 718 def _remove_from_sets(self, test, dict_of_sets_of_tests): |
| 729 """Removes the given test from the sets in the dictionary. | 719 """Removes the given test from the sets in the dictionary. |
| 730 | 720 |
| 731 Args: | 721 Args: |
| 732 test: test to look for | 722 test: test to look for |
| 733 dict: dict of sets of files""" | 723 dict: dict of sets of files""" |
| 734 for set_of_tests in dict_of_sets_of_tests.itervalues(): | 724 for set_of_tests in dict_of_sets_of_tests.itervalues(): |
| 735 if test in set_of_tests: | 725 if test in set_of_tests: |
| 736 set_of_tests.remove(test) | 726 set_of_tests.remove(test) |
| 737 | 727 |
| 738 def _expects_rebaseline(self, expectation_line): | 728 def _already_seen_better_match(self, test, expectation_line): |
| 739 expectations = expectation_line.parsed_expectations | 729 """Returns whether we've seen a better match already in the file. |
| 740 return REBASELINE in expectations or NEEDS_REBASELINE in expectations or
NEEDS_MANUAL_REBASELINE in expectations | |
| 741 | 730 |
| 742 def _lines_conflict(self, prev_expectation_line, expectation_line): | 731 Returns True if we've already seen a expectation_line.name that matches
more of the test |
| 743 if prev_expectation_line.path != expectation_line.path: | 732 than this path does |
| 733 """ |
| 734 # FIXME: See comment below about matching test configs and specificity. |
| 735 if not self.has_test(test): |
| 736 # We've never seen this test before. |
| 744 return False | 737 return False |
| 745 | 738 |
| 746 if PASS in expectation_line.parsed_expectations and self._expects_rebase
line(prev_expectation_line): | 739 prev_expectation_line = self._test_to_expectation_line[test] |
| 740 |
| 741 if prev_expectation_line.filename != expectation_line.filename: |
| 742 # We've moved on to a new expectation file, which overrides older on
es. |
| 747 return False | 743 return False |
| 748 | 744 |
| 749 if PASS in prev_expectation_line.parsed_expectations and self._expects_r
ebaseline(expectation_line): | 745 if len(prev_expectation_line.path) > len(expectation_line.path): |
| 746 # The previous path matched more of the test. |
| 747 return True |
| 748 |
| 749 if len(prev_expectation_line.path) < len(expectation_line.path): |
| 750 # This path matches more of the test. |
| 750 return False | 751 return False |
| 751 | 752 |
| 753 # At this point we know we have seen a previous exact match on this |
| 754 # base path, so we need to check the two sets of specifiers. |
| 755 |
| 756 # FIXME: This code was originally designed to allow lines that matched |
| 757 # more specifiers to override lines that matched fewer specifiers. |
| 758 # However, we currently view these as errors. |
| 759 # |
| 760 # To use the "more specifiers wins" policy, change the errors for overri
des |
| 761 # to be warnings and return False". |
| 762 |
| 752 if prev_expectation_line.matching_configurations == expectation_line.mat
ching_configurations: | 763 if prev_expectation_line.matching_configurations == expectation_line.mat
ching_configurations: |
| 753 expectation_line.warnings.append('Duplicate or ambiguous entry lines
%s:%s and %s:%s.' % ( | 764 expectation_line.warnings.append('Duplicate or ambiguous entry lines
%s:%s and %s:%s.' % ( |
| 754 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, | 765 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, |
| 755 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) | 766 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) |
| 756 return True | 767 return True |
| 757 | 768 |
| 758 if prev_expectation_line.matching_configurations >= expectation_line.mat
ching_configurations: | 769 if prev_expectation_line.matching_configurations >= expectation_line.mat
ching_configurations: |
| 759 expectation_line.warnings.append('More specific entry for %s on line
%s:%s overrides line %s:%s.' % (expectation_line.name, | 770 expectation_line.warnings.append('More specific entry for %s on line
%s:%s overrides line %s:%s.' % (expectation_line.name, |
| 760 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, | 771 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, |
| 761 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) | 772 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 # If reconstitute_only_these is an empty list, we want to return ori
ginal_string. | 1137 # If reconstitute_only_these is an empty list, we want to return ori
ginal_string. |
| 1127 # So we need to compare reconstitute_only_these to None, not just ch
eck if it's falsey. | 1138 # So we need to compare reconstitute_only_these to None, not just ch
eck if it's falsey. |
| 1128 if reconstitute_only_these is None or expectation_line in reconstitu
te_only_these: | 1139 if reconstitute_only_these is None or expectation_line in reconstitu
te_only_these: |
| 1129 return expectation_line.to_string(test_configuration_converter) | 1140 return expectation_line.to_string(test_configuration_converter) |
| 1130 return expectation_line.original_string | 1141 return expectation_line.original_string |
| 1131 | 1142 |
| 1132 def nones_out(expectation_line): | 1143 def nones_out(expectation_line): |
| 1133 return expectation_line is not None | 1144 return expectation_line is not None |
| 1134 | 1145 |
| 1135 return "\n".join(filter(nones_out, map(serialize, expectation_lines))) | 1146 return "\n".join(filter(nones_out, map(serialize, expectation_lines))) |
| OLD | NEW |