diff --git a/core/os/os2/path.odin b/core/os/os2/path.odin index c3effe69e..1d3dca5c9 100644 --- a/core/os/os2/path.odin +++ b/core/os/os2/path.odin @@ -771,6 +771,14 @@ scan_chunk :: proc(pattern: string) -> (star: bool, chunk, rest: string) { @(private="file") match_chunk :: proc(chunk, s: string) -> (rest: string, ok: bool, err: Error) { + slash_equal :: proc(a, b: u8) -> bool { + switch a { + case '/': return b == '/' || b == '\\' + case '\\': return b == '/' || b == '\\' + case: return a == b + } + } + chunk, s := chunk, s for len(chunk) > 0 { if len(s) == 0 { @@ -831,7 +839,7 @@ match_chunk :: proc(chunk, s: string) -> (rest: string, ok: bool, err: Error) { } fallthrough case: - if chunk[0] != s[0] { + if !slash_equal(chunk[0], s[0]) { return } s = s[1:] diff --git a/tests/core/os/os2/path.odin b/tests/core/os/os2/path.odin index 26cf1c290..a256b3e22 100644 --- a/tests/core/os/os2/path.odin +++ b/tests/core/os/os2/path.odin @@ -1,5 +1,6 @@ package tests_core_os_os2 +import "core:fmt" import os "core:os/os2" import "core:log" import "core:testing" @@ -386,24 +387,62 @@ Glob_Test :: struct { glob_tests := []Glob_Test{ { pattern = ODIN_ROOT + "tests/core/os/*/*.txt", - matches = {}, - err = nil, + matches = { + ODIN_ROOT + "tests/core/os/dir/b.txt", + }, + err = {}, + }, + { + pattern = ODIN_ROOT + "tests/core/os/os2/*.odin", + matches = { + ODIN_ROOT + "tests/core/os/os2/dir.odin", + ODIN_ROOT + "tests/core/os/os2/file.odin", + ODIN_ROOT + "tests/core/os/os2/path.odin", + ODIN_ROOT + "tests/core/os/os2/process.odin", + }, + err = {}, }, } @(test) test_glob :: proc(t: ^testing.T) { + compare_matches :: proc(t: ^testing.T, pattern: string, globbed, expected: []string) { + glob_fold := make([]string, len(globbed), context.temp_allocator) + expect_fold := make([]string, len(globbed), context.temp_allocator) + + for glob, i in globbed { + // If `glob` returned a path in response to a pattern, + // then `match` should consider that path a match, too, + // irrespective of `/` versus `\` presence. + no_match_msg := fmt.tprintf("Expected os.match(%q, %q) to be `true`, got `false`", pattern, glob) + match, _ := os.match(pattern, glob) + + f, _ := strings.replace_all(glob, `\`, `/`, context.temp_allocator) + glob_fold[i] = f + testing.expect(t, match, no_match_msg) + } + + for exp, i in expected { + f, _ := strings.replace_all(exp, `\`, `/`, context.temp_allocator) + expect_fold[i] = f + } + + slice.sort(glob_fold) + slice.sort(expect_fold) + + not_equal_msg := fmt.tprintf("Expected os.glob(%q) to return %v, got %v", pattern, glob_fold, expect_fold) + testing.expect(t, slice.equal(glob_fold, expect_fold), not_equal_msg) + } + for glob in glob_tests { - files, err := os.glob(glob.pattern, context.allocator) + globbed, err := os.glob(glob.pattern, context.allocator) defer { - for file in files { + for file in globbed { delete(file) } - delete(files) + delete(globbed) } testing.expect_value(t, err, glob.err) - - slice.sort(files) - log.infof("files: %v", files) + compare_matches(t, glob.pattern, globbed, glob.matches) } } \ No newline at end of file