Repository: yshavit/mdq
Pull request #284 (2025-03-30 06:13:38)

add some test cases of invalid query strings

yshavit: @coderabbitai Are there any test cases in the new file that I'm missing?
coderabbitai[bot]: <!-- This is an auto-generated reply by CodeRabbit -->
> [!TIP]
> For best results, initiate chat on the files or code changes.

<details>
<summary>🧩 Analysis chain</summary>

🏁 Script executed:
```
#!/bin/bash
# Get the changes in the PR
git diff --name-status HEAD~1 HEAD
```

Length of output: 223

---

🏁 Script executed:
```
#!/bin/bash
# Get information about PR #284
gh pr view 284 --json files,additions,deletions
```

Length of output: 284

---

🏁 Script executed:
```
#!/bin/bash
# Get the content of the new test file
cat tests/md_cases/bad_queries.toml
```

Length of output: 4453

---

🏁 Script executed:
```
#!/bin/bash
# Check the grammar file and look for other test files
cat src/query/grammar.pest
# Find other test files that might contain query tests
find tests -name "*.toml" | grep -v bad_queries.toml
```

Length of output: 4492

---

🏁 Script executed:
```
#!/bin/bash
# Let's check a few more test files that might give us insight into valid query patterns
# Check matchers.toml for examples of valid queries
cat tests/md_cases/matchers.toml

# Also check a couple of selector test files to understand the syntax patterns
head -50 tests/md_cases/select_sections.toml
```

Length of output: 1867

---



</details>

@yshavit The test file `tests/md_cases/bad_queries.toml` is quite comprehensive with 20 different test cases for invalid query strings. After examining the grammar and other test files, I noticed a few potential test cases that aren't currently covered:

1. Empty or malformed pipe chains (e.g., `# * | |` or `# * || *`)
2. Misused wildcards in various contexts
3. Empty selectors after a pipe (e.g., `# * |`)
4. Specific code block errors (e.g., malformed language specifier)
5. HTML selector errors (`</>` with invalid syntax)
6. Paragraph selector issues (`P:` with invalid content)
7. More complex table syntax errors

These additional test cases would cover more edge cases in the query parsing logic. Would you like me to suggest specific examples for any of these categories?
yshavit: Those aren't super interesting. Will merge!

Patch:
diff --git a/src/query/grammar.pest b/src/query/grammar.pest
index 6e6f2b4..60cdc4e 100644
--- a/src/query/grammar.pest
+++ b/src/query/grammar.pest
@@ -16,7 +16,7 @@ selector = {
 }
 
 selector_delim = _{ explicit_space | EOI }
-explicit_space = !{ " " }
+explicit_space = !{ " " } // making this a rule lets us have nicer error messages if the user doesn't include it
 
 select_section =  { section_start ~ #title = string_to_pipe? }
 section_start  = @{ "#" ~ selector_delim }
diff --git a/src/query/query.rs b/src/query/query.rs
index a0c99ec..bfbde5a 100644
--- a/src/query/query.rs
+++ b/src/query/query.rs
@@ -58,15 +58,15 @@ impl Query {
                 | Rule::unquoted_string_to_space
                 | Rule::unquoted_string_to_colon => "unquoted string",
                 Rule::regex => "_/_",
-                Rule::regex_char => "regular expression character",
+                Rule::regex_char => "regex character",
                 Rule::regex_escaped_slash => "_/_",
-                Rule::regex_normal_char => "regular expression character",
+                Rule::regex_normal_char => "regex character",
                 Rule::quoted_string => "quoted string",
-                Rule::quoted_char => "character",
+                Rule::quoted_char => "character in quoted string",
                 Rule::anchor_start => "_^_",
                 Rule::anchor_end => "_$_",
                 Rule::only_anchors => "_^_ _$_",
-                Rule::quoted_plain_chars => "character",
+                Rule::quoted_plain_chars => "character in quoted string",
                 Rule::escaped_char => "\", ', `, \\, n, r, or t",
                 Rule::unicode_seq => "1 - 6 hex characters",
             }


Test patch:
diff --git a/tests/md_cases/bad_queries.toml b/tests/md_cases/bad_queries.toml
new file mode 100644
index 0000000..20755b4
--- /dev/null
+++ b/tests/md_cases/bad_queries.toml
@@ -0,0 +1,255 @@
+[given]
+md = ''
+
+[chained]
+needed = false
+
+[expect."start with string"]
+cli_args = ['"hello"']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:1
+  |
+1 | "hello"
+  | ^---
+  |
+  = expected valid query
+'''
+
+[expect."double quote isn't closed"]
+cli_args = ['# "hello']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:9
+  |
+1 | # "hello
+  |         ^---
+  |
+  = expected character in quoted string
+'''
+
+[expect."single quote isn't closed"]
+cli_args = ["# 'hello"]
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:9
+  |
+1 | # 'hello
+  |         ^---
+  |
+  = expected character in quoted string
+'''
+
+[expect."regex isn't closed"]
+cli_args = ['# /hello']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:9
+  |
+1 | # /hello
+  |         ^---
+  |
+  = expected regex character
+'''
+
+[expect."invalid regex"]
+cli_args = ['# /\P{/']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:3
+  |
+1 | # /\P{/
+  |   ^---^
+  |
+  = regex parse error:
+    \P{
+       ^
+error: incomplete escape sequence, reached end of pattern prematurely
+'''
+
+[expect."bareword isn't closed"]
+cli_args = ['[](http']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:8
+  |
+1 | [](http
+  |        ^---
+  |
+  = expected "$"
+'''
+
+[expect."quoted string bad escape"]
+cli_args = ['# "\x"']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:5
+  |
+1 | # "\x"
+  |     ^---
+  |
+  = expected ", ', `, \, n, r, or t
+'''
+
+[expect."quoted string bad unicode: not hex"]
+cli_args = ['# "\u{snowman}"']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:7
+  |
+1 | # "\u{snowman}"
+  |       ^---
+  |
+  = expected 1 - 6 hex characters
+'''
+
+[expect."quoted string bad unicode: no chars"]
+cli_args = ['# "\u{}"']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:7
+  |
+1 | # "\u{}"
+  |       ^---
+  |
+  = expected 1 - 6 hex characters
+'''
+
+[expect."quoted string bad unicode: too many chars"]
+cli_args = ['# "\u{1234567}"']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:5
+  |
+1 | # "\u{1234567}"
+  |     ^---
+  |
+  = expected ", ', `, \, n, r, or t
+'''
+
+[expect."invalid unicode: invalid codepoint"]
+cli_args = ['# "\u{FFFFFF}"']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:7
+  |
+1 | # "\u{FFFFFF}"
+  |       ^----^
+  |
+  = invalid unicode sequence: FFFFFF
+'''
+
+[expect."no space after selector"]
+cli_args = ["#foo"]
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:2
+  |
+1 | #foo
+  |  ^---
+  |
+  = expected space
+'''
+
+[expect."anchors in incorrect order"]
+cli_args = ['# $hello^']
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:4
+  |
+1 | # $hello^
+  |    ^---
+  |
+  = expected end of input
+'''
+
+[expect."invalid selector"]
+cli_args = ["~"]
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:1
+  |
+1 | ~
+  | ^---
+  |
+  = expected valid query
+'''
+
+[expect."invalid task"]
+cli_args = ["- [*]"]
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:4
+  |
+1 | - [*]
+  |    ^---
+  |
+  = expected "[x]", "[x]", or "[?]"
+'''
+
+[expect."numbered list not 1"]
+cli_args = ["2. hello"]
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:1
+  |
+1 | 2. hello
+  | ^---
+  |
+  = expected valid query
+'''
+
+[expect."table missing explicit column matcher"]
+cli_args = [":-: :-: row"]
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:5
+  |
+1 | :-: :-: row
+  |     ^---
+  |
+  = expected explicit "*" or string
+'''
+
+[expect."table missing second delimiter"]
+cli_args = [":-: *"]
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:1
+  |
+1 | :-: *
+  | ^---
+  |
+  = expected valid query
+'''
+
+[expect."invalid selector after valid one"]
+cli_args = ["# * | :-: *"]
+expect_success = false
+output = ''
+output_err = '''Syntax error in select specifier:
+ --> 1:7
+  |
+1 | # * | :-: *
+  |       ^---
+  |
+  = expected end of input or selector
+'''