Skip to content

Commit 4eed8ab

Browse files
Add specs for File.match? from fast-glob (#15604)
Imports test cases for `File.match?` from https://github.com/oxc-project/fast-glob/blob/main/tests/test.rs to enhance the spec suite. I'm planning to fix issue #15319 by porting the matching algorithm from `fast-glob` to Crystal. This is a preparatory step to import the test cases from the base implementation. Our current `match_spec.cr` lacks unit tests for many edge cases, which are covered here. Importing them beforehand makes it clear to identify the differences in behaviour, and it's easier to review in smaller bites. I figure it should be easier to maintain this as a separate test file with a generator to easily include new test from upstream. Most of the examples originate from other projects, bash and minimatch. In violation of the DO NOT EDIT directive, I'm encoding the currently broken test cases directly in the generated file. This will be fixed shortly anyway. The original tests also include a list of more complex patterns, which are tested against a huge list of paths. I'm skipping them here because they need specific code to run them, and add them separately. They're all broken anyway due to #15319. Similarly, some fuzz specs are also a bit more complex for a simple transform, so they'll be added separately as well. Related: #15601
1 parent 701a27d commit 4eed8ab

File tree

3 files changed

+1737
-0
lines changed

3 files changed

+1737
-0
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ src/openssl/ssl/defaults.cr linguist-generated
2020
src/string/grapheme/properties.cr linguist-generated
2121
# produced by scripts/generate_unicode_data.cr
2222
src/unicode/data.cr linguist-generated
23+
# produced by scripts/generate_glob_specs.cr
24+
spec/std/file/match-fast-glob_spec.cr
2325
# produced by scripts/generate_grapheme_break_specs.cr
2426
spec/std/string/grapheme_break_spec.cr linguist-generated
2527
# produced by spec/generate_wasm32_spec.sh

scripts/generate_glob_specs.sh

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/bin/env bash
2+
3+
# This tool generates the tests in spec/std/file/match-fast-glob_spec.cr
4+
# from https://github.com/oxc-project/fast-glob/blob/main/tests/test.rs
5+
# converted to Crystal
6+
7+
set -euo pipefail
8+
9+
target=spec/std/file/match-fast-glob_spec.cr
10+
URL="https://raw.githubusercontent.com/oxc-project/fast-glob/refs/heads/main/tests/test.rs"
11+
12+
curl -L "$URL" |
13+
(
14+
echo '
15+
# This file was automatically generated by running:
16+
#
17+
# scripts/generate_glob_specs.cr
18+
#
19+
# DO NOT EDIT
20+
'
21+
22+
echo "
23+
# These tests are autogenerated from $URL
24+
# They are are collection of tests from bash and micromatch
25+
# https://github.com/micromatch/picomatch/blob/master/test/bash.js.
26+
"
27+
28+
echo '
29+
require "spec"
30+
31+
private def assert_file_matches(pattern, path : String, *, file = __FILE__, line = __LINE__)
32+
File.match?(pattern, path).should be_true, file: file, line: line
33+
File.match?(pattern, Path.posix(path)).should be_true, file: file, line: line
34+
File.match?(pattern, Path.posix(path).to_windows(mappings: false)).should be_true, file: file, line: line
35+
end
36+
37+
private def refute_file_matches(pattern, path : String, *, file = __FILE__, line = __LINE__)
38+
File.match?(pattern, path).should be_false, file: file, line: line
39+
File.match?(pattern, Path.posix(path)).should be_false, file: file, line: line
40+
File.match?(pattern, Path.posix(path).to_windows(mappings: false)).should be_false, file: file, line: line
41+
end
42+
'
43+
44+
echo 'describe "File .match? bash tests" do'
45+
46+
sed -E '1,5d' |
47+
sed '/let patterns/,/#\[test\]/d; s/fn not_paired_braces/end\n\nfn not_paired_braces/' | # drop complex patterns implementation
48+
sed '/fn fuzz_tests/,$d' | # drop complex fuzz tests implementation
49+
sed '/^\s*#\[/d' |
50+
sed -E 's/fn (.*)\(\) \{/it "\1" do/' |
51+
sed -E 's/\}$/end/' |
52+
sed -E 's|^\s*//|#|' |
53+
sed -E 's/assert!\(!glob_match\("(.*)", "(.*)"\)\);/refute_file_matches "\1", "\2"/' |
54+
sed -E 's/assert!\(glob_match\("(.*)", "(.*)"\)\);/assert_file_matches "\1", "\2"/' |
55+
# multiline assertions:
56+
sed -E 's/assert!\(glob_match\(/assert_file_matches(/' |
57+
sed -E 's/assert!\(!glob_match\(/refute_file_matches(/' |
58+
sed -E 's/\)\);/)/' |
59+
sed -E 's/let //' |
60+
sed -E 's/it "negation"/pending "negation"/' | # File.match? currently does not support negated patterns
61+
sed -E '/it "generic_input"/,/end$/d' # Generic input tests are specific to Rust types
62+
63+
echo 'end'
64+
) > "$target"
65+
66+
crystal tool format "$target"

0 commit comments

Comments
 (0)