style: expand one-line summaries and run dotnet format solution-wide

This commit is contained in:
yyc12345 committed 2026-10-04 10:22:02 +08:00
1 parent 9ea551b600
commit 8b7e50a955
95 files changed
+970 -1424

No files matched your search

+39 -78
View File
@@ -8,15 +8,13 @@ namespace YKanBan.Tests.Search;
/// <see cref="SearchSyntaxException"/>).
/// </summary>
[TestClass]
public class SearchQueryParserTests
{
public class SearchQueryParserTests {
/// <summary>
/// Parses and asserts structural equality against the expected AST.
/// </summary>
/// <param name="expected">The expected AST.</param>
/// <param name="text">The search text.</param>
private static void AssertParsesTo(SearchNode expected, string text)
{
private static void AssertParsesTo(SearchNode expected, string text) {
SearchNode? parsed = SearchQueryParser.Parse(text);
Assert.IsNotNull(parsed, $"Blank-looking input: '{text}'.");
Assert.AreEqual(expected, parsed, SearchNodeComparer.Instance);
@@ -26,53 +24,46 @@ public class SearchQueryParserTests
/// Asserts that the input violates the grammar.
/// </summary>
/// <param name="text">The search text.</param>
private static void AssertSyntaxError(string text)
{
private static void AssertSyntaxError(string text) {
Assert.ThrowsExactly<SearchSyntaxException>(() => SearchQueryParser.Parse(text));
}
#region Successful parses
[TestMethod]
public void BlankInputReturnsNull()
{
public void BlankInputReturnsNull() {
Assert.IsNull(SearchQueryParser.Parse(string.Empty));
Assert.IsNull(SearchQueryParser.Parse(" "));
}
[TestMethod]
public void SingleWordIsFreeText()
{
public void SingleWordIsFreeText() {
AssertParsesTo(new SearchNode.FreeText("login"), "login");
}
[TestMethod]
public void AdjacentWordsAreImplicitAnd()
{
public void AdjacentWordsAreImplicitAnd() {
AssertParsesTo(
new SearchNode.And([new SearchNode.FreeText("fix"), new SearchNode.FreeText("login")]),
"fix login");
}
[TestMethod]
public void ExplicitAndKeyword()
{
public void ExplicitAndKeyword() {
AssertParsesTo(
new SearchNode.And([new SearchNode.FreeText("a"), new SearchNode.FreeText("b")]),
"a AND b");
}
[TestMethod]
public void OrKeyword()
{
public void OrKeyword() {
AssertParsesTo(
new SearchNode.Or([new SearchNode.FreeText("a"), new SearchNode.FreeText("b")]),
"a OR b");
}
[TestMethod]
public void ImplicitAndBindsTighterThanOr()
{
public void ImplicitAndBindsTighterThanOr() {
AssertParsesTo(
new SearchNode.Or([
new SearchNode.And([new SearchNode.FreeText("a"), new SearchNode.FreeText("b")]),
@@ -81,8 +72,7 @@ public class SearchQueryParserTests
}
[TestMethod]
public void ParenthesesForceGrouping()
{
public void ParenthesesForceGrouping() {
AssertParsesTo(
new SearchNode.And([
new SearchNode.FreeText("a"),
@@ -91,16 +81,14 @@ public class SearchQueryParserTests
}
[TestMethod]
public void NestedParenthesesCollapse()
{
public void NestedParenthesesCollapse() {
AssertParsesTo(
new SearchNode.Or([new SearchNode.FreeText("a"), new SearchNode.FreeText("b")]),
"((a OR b))");
}
[TestMethod]
public void LowercaseKeywordsArePlainWords()
{
public void LowercaseKeywordsArePlainWords() {
AssertParsesTo(
new SearchNode.And([
new SearchNode.FreeText("a"),
@@ -111,14 +99,12 @@ public class SearchQueryParserTests
}
[TestMethod]
public void PhraseIsFreeText()
{
public void PhraseIsFreeText() {
AssertParsesTo(new SearchNode.FreeText("hello world"), "\"hello world\"");
}
[TestMethod]
public void QuotedOperatorKeywordIsFreeText()
{
public void QuotedOperatorKeywordIsFreeText() {
// A quoted AND/OR is literal text, not an operator.
AssertParsesTo(new SearchNode.FreeText("AND"), "\"AND\"");
AssertParsesTo(
@@ -127,54 +113,46 @@ public class SearchQueryParserTests
}
[TestMethod]
public void PhraseSupportsEscapes()
{
public void PhraseSupportsEscapes() {
// Escaped quote and escaped backslash.
AssertParsesTo(new SearchNode.FreeText("a\"b"), "\"a\\\"b\"");
AssertParsesTo(new SearchNode.FreeText("a\\b"), "\"a\\\\b\"");
}
[TestMethod]
public void TagQualifier()
{
public void TagQualifier() {
AssertParsesTo(new SearchNode.TagName("bug"), "tag:bug");
}
[TestMethod]
public void TagQualifierAcceptsPhraseValue()
{
public void TagQualifierAcceptsPhraseValue() {
AssertParsesTo(new SearchNode.TagName("a b"), "tag:\"a b\"");
}
[TestMethod]
public void QualifierValueMayContainColons()
{
public void QualifierValueMayContainColons() {
AssertParsesTo(new SearchNode.TagName("a:b"), "tag:a:b");
}
[TestMethod]
public void TitleAndContentQualifiers()
{
public void TitleAndContentQualifiers() {
AssertParsesTo(new SearchNode.FieldText(SearchField.Title, "foo"), "title:foo");
AssertParsesTo(new SearchNode.FieldText(SearchField.Content, "foo"), "content:foo");
}
[TestMethod]
public void ColumnQualifierAcceptsPhraseValue()
{
public void ColumnQualifierAcceptsPhraseValue() {
AssertParsesTo(new SearchNode.ColumnTitle("To Do"), "column:\"To Do\"");
}
[TestMethod]
public void IdQualifierParsesNumber()
{
public void IdQualifierParsesNumber() {
AssertParsesTo(new SearchNode.CardId(42), "id:42");
AssertParsesTo(new SearchNode.CardId(12), "id:\"12\"");
}
[TestMethod]
public void ColonWithoutKeyPrefixIsFreeText()
{
public void ColonWithoutKeyPrefixIsFreeText() {
AssertParsesTo(new SearchNode.FreeText(":foo"), ":foo");
}
@@ -183,106 +161,89 @@ public class SearchQueryParserTests
#region Strict failures
[TestMethod]
public void UnterminatedPhraseIsAnError()
{
public void UnterminatedPhraseIsAnError() {
AssertSyntaxError("\"abc def");
}
[TestMethod]
public void TrailingUnterminatedPhraseIsAnError()
{
public void TrailingUnterminatedPhraseIsAnError() {
AssertSyntaxError("a \"abc");
}
[TestMethod]
public void InvalidEscapeInPhraseIsAnError()
{
public void InvalidEscapeInPhraseIsAnError() {
// A bare backslash (not followed by a quote or another backslash) is invalid.
AssertSyntaxError("\"a\\b\"");
}
[TestMethod]
public void InvalidEscapeInQualifierPhraseIsAnError()
{
public void InvalidEscapeInQualifierPhraseIsAnError() {
AssertSyntaxError("tag:\"a\\x\"");
}
[TestMethod]
public void UnbalancedOpenParenIsAnError()
{
public void UnbalancedOpenParenIsAnError() {
AssertSyntaxError("(a");
}
[TestMethod]
public void StrayCloseParenIsAnError()
{
public void StrayCloseParenIsAnError() {
AssertSyntaxError("a)");
}
[TestMethod]
public void EmptyParensAreAnError()
{
public void EmptyParensAreAnError() {
AssertSyntaxError("()");
}
[TestMethod]
public void DanglingOrIsAnError()
{
public void DanglingOrIsAnError() {
AssertSyntaxError("a OR");
}
[TestMethod]
public void DanglingAndIsAnError()
{
public void DanglingAndIsAnError() {
AssertSyntaxError("a AND");
}
[TestMethod]
public void LeadingAndIsAnError()
{
public void LeadingAndIsAnError() {
AssertSyntaxError("AND a");
}
[TestMethod]
public void OperatorAtOperandPositionIsAnError()
{
public void OperatorAtOperandPositionIsAnError() {
AssertSyntaxError("a AND OR b");
}
[TestMethod]
public void QualifierWithoutValueIsAnError()
{
public void QualifierWithoutValueIsAnError() {
AssertSyntaxError("tag:");
}
[TestMethod]
public void SpacedQualifierValueIsAnError()
{
public void SpacedQualifierValueIsAnError() {
AssertSyntaxError("tag: bug");
}
[TestMethod]
public void NonNumericIdIsAnError()
{
public void NonNumericIdIsAnError() {
AssertSyntaxError("id:12x");
}
[TestMethod]
public void UnknownQualifierKeyIsAnError()
{
public void UnknownQualifierKeyIsAnError() {
AssertSyntaxError("foo:bar");
}
[TestMethod]
public void QualifierKeysAreCaseSensitive()
{
public void QualifierKeysAreCaseSensitive() {
// "Tag" is a key-like prefix but not the known lowercase "tag", so it is unknown.
AssertSyntaxError("Tag:x");
}
[TestMethod]
public void SyntaxErrorCarriesDescriptiveMessage()
{
public void SyntaxErrorCarriesDescriptiveMessage() {
SearchSyntaxException exception = Assert.ThrowsExactly<SearchSyntaxException>(
() => SearchQueryParser.Parse("a AND"));
Assert.IsFalse(string.IsNullOrEmpty(exception.Message));