On 01/23/2013 09:49 PM, Ben Reser wrote:
# The EXPECTED lines must match a subset of the ACTUAL lines,
# one-to-one, in the same order, with zero or more other ACTUAL
# lines interspersed among the matching ACTUAL lines.
i_expected = 0
for actual_line in actual:
- if expected[i_expected] == actual_line:
+ # As soon an actual_line matches something, then we're good.
+ # Also check if the regex in the EXPECTED line matches the
+ # corresponding ACTUAL line.
+ if ((expected[i_expected] == actual_line) or
+ (expected[i_expected].startswith(".*") and
+ re.match(expected[i_expected], actual_line))):
i_expected += 1
if i_expected == len(expected):
return True
Looking for .* is not a valid way of determining if something is a
regex. If you want to match the first character then you'll end up
having to put a bogus .* in your pattern to deal with this.
If you look just below the code you changed you'll see:
expected_re = expected[0]
I'd look at that and adjust it.
Now the question is how. I can see two ways:
2) An ordered list of regular expressions where one is consumed for each line.
The first way is easier to maintain consistency with the current
implementation. If you really want the second way then I'd suggest
subclassing RegexOutput with another class like say RegexListOutput,
add another flag to the implementation e.g. is_regex_list = True, and
create a 3rd code path in is_equivalent_list.
Yeah nice...
But how do we find if the list contains just strings or regexes. I am
not sure of any concrete idea for this.
We can set *is_regex_list = True* only if we are sure that the list
contains regexes.
So far, we supported three things
1. a list of strings
2. a string (regex)
3. integer (regex)
Since, we so far had only list of 'strings' it was easy to compare the
EXPECTED list and the ACTUAL list. If we support both list of 'regex' as
well as 'strings' it would be difficult to find if the list contains
regexes or strings. We need to identify the type of the list because of
the below reason:
eg:
CASE 1:
----------
ACTUAL = ["* Verified revision 1\n", "* Verified revision 2\n"]
EXPECTED = ["* Verified revision 1\n", "* Verified revision 2\n"]
If treated as a list of regexes
re.match(expected, actual) would fail because of the '*'.
If treated as a list of strings this would pass.
CASE 2:
----------
ACTUAL = ["* Verified revision 1\n", "* Verified revision 2\n"]
EXPECTED = [".* Verified revision 1", ".* Verified revision 2"]
If treated as a list of regexes
re.match(expected, actual) would pass.
If treated as a list of strings this would fail.
Are we going to support both list of strings as well as list of regexes ?
Not sure if I am missing something.
I am attaching a patch with this mail which would support both list of
regexes as well as list of strings. I have checked that all tests pass.
In the new implementation, we always check for "exact match 'or'
re.match" which would solve our problem easily. Please let me know if
this approach is good to go with, since we do not need a new flag nor
any new logic.
Regards
Prabhu
Support regex in the expected error list. In addition to directly matching the
entries of the expected error list with the actual error, support regex
in the entries of the expected error list.
* tests/cmdline/svntest/verify.py
(ExpectedOutput): Match the corresponding entries of the EXPECTED list to
that of the ACTUAL list. Check each entry of the EXPECTED list for
exact match in the ACTUAL list in the same order, if not found, check for
regex match.
Example:
--------
Expected err = ["* Verified revision 1.",
"* Error verifying revision 2.",
".*svnadmin: E160004*",
"* Verified revision 3.",
".*svnadmin: E165005*"]
Actual err = ["* Verified revision 1.",
"* Error verifying revision 2.",
"svnadmin: E160004: Invalid change kind in rev file",
"* Verified revision 3.",
"svnadmin: E165005: Repository 'svn-test-work/repositories/svnadmin_tests-32' failed to verify"]
The above Expected err and Actual err would match successfully.
Earlier, only *exact* entries in the list were checked for match and hence
the above example wouldnt match successfully.
Index: tests/cmdline/svntest/verify.py
===================================================================
--- tests/cmdline/svntest/verify.py (revision 1437863)
+++ tests/cmdline/svntest/verify.py (working copy)
@@ -165,17 +165,18 @@ class ExpectedOutput:
def is_equivalent_list(self, expected, actual):
"Return whether EXPECTED and ACTUAL are equivalent."
if not self.is_regex:
- if self.match_all:
- # The EXPECTED lines must match the ACTUAL lines, one-to-one, in
- # the same order.
- return expected == actual
+ if self.match_all and not actual:
+ # If MATCH_ALL is True and there are no ACTUAL lines, then we are good
+ # to go.
+ return True
# The EXPECTED lines must match a subset of the ACTUAL lines,
# one-to-one, in the same order, with zero or more other ACTUAL
# lines interspersed among the matching ACTUAL lines.
i_expected = 0
for actual_line in actual:
- if expected[i_expected] == actual_line:
+ if (expected[i_expected] == actual_line or
+ re.match(expected[i_expected], actual_line)):
i_expected += 1
if i_expected == len(expected):
return True