|
5 | 5 | */
|
6 | 6 |
|
7 | 7 | import { mapValues, pick } from "@std/collections";
|
8 |
| -import { join } from "@std/path"; |
| 8 | +import { dirname, fromFileUrl, join, resolve } from "@std/path"; |
9 | 9 | import type { Spy } from "@std/testing/mock";
|
10 | 10 | import * as std from "@std/testing/mock";
|
11 |
| -import { isUnder, relative, tryCatch, tryFinally } from "./internal.ts"; |
| 11 | +import { relative, tryCatch, tryFinally } from "./internal.ts"; |
12 | 12 |
|
13 | 13 | /**
|
14 | 14 | * The base names of Deno's APIs related to file system operations that takes
|
@@ -117,7 +117,7 @@ export interface FileSystemStub extends FileSystemSpy {
|
117 | 117 | * to a temporary directory.
|
118 | 118 | */
|
119 | 119 | function createFsFake(
|
120 |
| - base: string | URL, |
| 120 | + base: string, |
121 | 121 | temp: string,
|
122 | 122 | readThrough: boolean,
|
123 | 123 | ): Fs {
|
@@ -156,8 +156,16 @@ function createFsFake(
|
156 | 156 | */
|
157 | 157 | const spies = new class extends Map<string | URL, FileSystemSpy> {
|
158 | 158 | /** Returns the spy for the path that is under the given path. */
|
159 |
| - override get(key: string | URL) { |
160 |
| - return Array.from(this.entries()).find(([path]) => isUnder(key, path))?.[1]; |
| 159 | + override get(path: string | URL): FileSystemSpy | undefined { |
| 160 | + const spy = super.get(path); |
| 161 | + if (spy) { |
| 162 | + return spy; |
| 163 | + } |
| 164 | + path = path.toString(); |
| 165 | + if (path === "." || path === ".." || path === "/") { |
| 166 | + return; |
| 167 | + } |
| 168 | + return this.get(dirname(path)); |
161 | 169 | }
|
162 | 170 | }();
|
163 | 171 |
|
@@ -189,6 +197,7 @@ export function stub(
|
189 | 197 | path: string | URL,
|
190 | 198 | fakeOrOptions?: Partial<Fs> | StubOptions,
|
191 | 199 | ): FileSystemStub {
|
| 200 | + path = normalize(path); |
192 | 201 | const temp = Deno.makeTempDirSync();
|
193 | 202 |
|
194 | 203 | const fake = isStubOptions(fakeOrOptions)
|
@@ -231,7 +240,8 @@ export function mock(): Disposable {
|
231 | 240 | function mockFsFn<T extends FsFnName>(name: T) {
|
232 | 241 | Deno[name] = new Proxy(Deno[name], {
|
233 | 242 | apply(target, thisArg, args) {
|
234 |
| - const spy = spies.get(args[0])?.[name]; |
| 243 | + const path = normalize(args[0]); |
| 244 | + const spy = spies.get(path)?.[name]; |
235 | 245 | if (spy) {
|
236 | 246 | return Reflect.apply(spy, thisArg, args);
|
237 | 247 | }
|
@@ -260,3 +270,13 @@ function restoreFsFn<T extends FsFnName>(
|
260 | 270 | ) {
|
261 | 271 | Deno[name] = fn;
|
262 | 272 | }
|
| 273 | + |
| 274 | +/** Normalize a path or file URL to an absolute path */ |
| 275 | +function normalize(path: string | URL): string { |
| 276 | + if (path instanceof URL) { |
| 277 | + path = path.protocol === "file:" ? fromFileUrl(path) : path.href; |
| 278 | + } else { |
| 279 | + path = resolve(path); |
| 280 | + } |
| 281 | + return path.endsWith("/") ? path.slice(0, -1) : path; |
| 282 | +} |
0 commit comments