Skip to content

Conversation

east1k
Copy link

@east1k east1k commented May 21, 2025

Fixes #1680

Changes:

  • If the filter is "tests" and the operator is regex, take the value without normalization.
  • If the filter is "tests" and the operator is comparison, take the value using "GetTestName".
  • GetTestName takes the value to the end, rather than truncating at the first closing parenthesis.
  • GetTestName removes extra spaces everywhere except in quoted arguments.
  • GetTestName ignores escaped quotes.

Changes:
 - If the filter is "tests" and the operator is regex, take the value without normalization.
 - If the filter is "tests" and the operator is comparison, take the value using "GetTestName".
 - GetTestName takes the value to the end, rather than truncating at the first closing parenthesis.
 - GetTestName removes extra spaces everywhere except in quoted arguments.
 - GetTestName ignores escaped quotes.
@east1k
Copy link
Author

east1k commented May 21, 2025

@dotnet-policy-service agree

Copy link
Member

@CharliePoole CharliePoole left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See inline comment. It's not clear to me why you want to avoid use of GetTestName() for regex expressions. With your other changes, it seems to work fine.

rhs = GetTestName();
rhs = op == MATCH_OP || op == NOMATCH_OP
? Expect(TokenKind.String, TokenKind.Word)
: GetTestName();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All tests pass without this change. Could you either remove it or add a test that shows it's required?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regular expressions lack predictability in string formatting, which can lead to mismatched quotes, potentially resulting in the removal of spaces in undesirable places.

Examples:

  1. A regular expression can be an arbitrary substring of test names.
tests:
  a.b.c("1111", "a b")
  a.b.c("2222", "b c")
  a.b.c("3333", "a b")
  a.b.c("3333", "a b с")
  a.b.c(Enum.X, "a b с")

command: 
  nunit "test.dll" -where 'test =~ /a b c/' --explore

expected:
  a.b.c("3333", "a b с")
  a.b.c(Enum.X, "a b с")

actual:
  <nothing>, because /a b c/ => /abc/
  1. A regular expression can shorten the string using special constructs.
before: a\.b\.c\(\"[^"]+", "a b"\)
after:  a\.b\.c\(\"[^"]+", "ab"\)
                             ^
before: .1111., .a b.
after:  .1111.,.ab.
               ^  ^

before: .*", "a b c"
after:  .*", "abc"
               ^ ^

before: (X|"), "a b c"
after:  (X|"), "abc"
                 ^ ^

before: 3"|"b c"
after:  3"|"bc"
             ^

I can remove the 'if' statement or add tests for that cases. Which option is better?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, of course! A regex may be an actual test name, but is only required to match a test name. So calling TestTestName really doesn't make sense. This means that the user has to be especially precise in formulating regular expressions and also has to be aware of how best to enter them at the command-line for each OS. But it has always been so with regex. :-)

No change needed. I'm going to merge this.

continue;
sb.Append(ch);
inQuotes = (!inQuotes && ch == '"') || (inQuotes && ch != '"') || (inQuotes && ch == '"' && inEscape);
inEscape = inQuotes && !inEscape && ch == '\\';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much cleaner!

@CharliePoole CharliePoole merged commit 812d1a7 into nunit:main May 24, 2025
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The filter "tests" truncates the provided value at the first closing parenthesis.
2 participants