diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs
index 3bc210353c..1b8f468f16 100644
--- a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs
+++ b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs
@@ -50,6 +50,12 @@ internal TreeNodeFilter(string filter)
/// OP = '&' | '|'
/// NODE_VALUE = TOKEN | TOKEN '[' FILTER_EXPR ']'
/// TOKEN = string
+ ///
+ /// OR expressions are supported for a single path segment, for example:
+ /// /A/B/C/(Test1|Test2).
+ ///
+ /// OR expressions over full paths are not supported, for example:
+ /// (/A/B/C/Test1)|(/A/B/C/Test2).
///
///
///
@@ -97,14 +103,14 @@ private static List ParseFilter(string filter)
_ => throw ApplicationStateGuard.Unreachable(),
};
- ProcessHigherPrecedenceOperators(expressionStack, operatorStack, currentOp);
+ ProcessHigherPrecedenceOperators(expressionStack, operatorStack, currentOp, filter);
isOperatorAllowed = false;
isPropAllowed = false;
break;
case "/":
- ProcessHigherPrecedenceOperators(expressionStack, operatorStack, OperatorKind.Separator);
+ ProcessHigherPrecedenceOperators(expressionStack, operatorStack, OperatorKind.Separator, filter);
isOperatorAllowed = false;
isPropAllowed = false;
@@ -147,7 +153,7 @@ private static List ParseFilter(string filter)
break;
}
- ProcessStackOperator(topStackOperator, expressionStack, operatorStack);
+ ProcessStackOperator(topStackOperator, expressionStack, operatorStack, filter);
}
isOperatorAllowed = true;
@@ -179,7 +185,7 @@ private static List ParseFilter(string filter)
break;
}
- ProcessStackOperator(topStackOperator, expressionStack, operatorStack);
+ ProcessStackOperator(topStackOperator, expressionStack, operatorStack, filter);
}
// We should end up with an expression and a property.
@@ -244,7 +250,7 @@ private static List ParseFilter(string filter)
while (operatorStack.Count > 0 && operatorStack.Peek() != OperatorKind.Separator)
{
topStackOperator = operatorStack.Pop();
- ProcessStackOperator(topStackOperator, expressionStack, operatorStack);
+ ProcessStackOperator(topStackOperator, expressionStack, operatorStack, filter);
}
var parsedFilter = expressionStack.Reverse().ToList();
@@ -265,12 +271,13 @@ private static List ParseFilter(string filter)
static void ProcessHigherPrecedenceOperators(
Stack expressionStack,
Stack operatorStack,
- OperatorKind currentOp)
+ OperatorKind currentOp,
+ string currentFilter)
{
while (operatorStack.Count != 0 && operatorStack.Peek() > currentOp)
{
OperatorKind topStackOperator = operatorStack.Pop();
- ProcessStackOperator(topStackOperator, expressionStack, operatorStack);
+ ProcessStackOperator(topStackOperator, expressionStack, operatorStack, currentFilter);
break;
}
@@ -303,7 +310,7 @@ private static void ValidateExpression(FilterExpression expr, bool isMatchAllAll
}
}
- private static void ProcessStackOperator(OperatorKind op, Stack expr, Stack ops)
+ private static void ProcessStackOperator(OperatorKind op, Stack expr, Stack ops, string filter)
{
switch (op)
{
@@ -325,14 +332,14 @@ private static void ProcessStackOperator(OperatorKind op, Stack FilterOperator.And,
OperatorKind.Or => FilterOperator.Or,
_ => throw ApplicationStateGuard.Unreachable(),
};
- expr.Push(new OperatorExpression(filter, subexprs));
+ expr.Push(new OperatorExpression(filterOperator, subexprs));
break;
case OperatorKind.FilterEquals:
@@ -364,7 +371,9 @@ private static void ProcessStackOperator(OperatorKind op, Stack(
+ () => _ = new TreeNodeFilter("(/*/*/*/MyTest1)|(/*/*/*/MyTest2)"));
+
+ Assert.IsTrue(exception.Message.Contains("/A/B/C/(X|Y)", StringComparison.Ordinal));
+ }
+
[TestMethod]
public void AndExpression()
{