Skip to content

Commit 7c09fbd

Browse files
committed
feat: add dirname functions to return a directory name
This is useful when you don't want to create a directory with vitest-testdirs, but just want to generate a path that you can be created by something else.
1 parent adfafb3 commit 7c09fbd

File tree

2 files changed

+62
-13
lines changed

2 files changed

+62
-13
lines changed

src/index.ts

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
} from "node:fs/promises";
2828
import {
2929
dirname,
30-
join,
3130
normalize,
3231
sep as pathSeparator,
3332
resolve,
@@ -42,7 +41,7 @@ import {
4241
} from "vitest/suite";
4342
import { BASE_DIR, FIXTURE_METADATA_SYMBOL, FIXTURE_ORIGINAL_PATH_SYMBOL } from "./constants";
4443
import { hasMetadata, isLink, isPrimitive, isSymlink } from "./helpers";
45-
import { createDirnameFromTask, isDirectory, isDirectorySync, isInVitest, processDirectory, processDirectorySync } from "./utils";
44+
import { internalGenerateDirname, isDirectory, isDirectorySync, isInVitest, processDirectory, processDirectorySync } from "./utils";
4645

4746
export * from "./constants";
4847
export * from "./helpers";
@@ -96,11 +95,7 @@ export async function testdir(
9695
const test = getCurrentTest();
9796
const suite = getCurrentSuite();
9897

99-
const dirname = options?.dirname
100-
? normalize(join(BASE_DIR, options.dirname))
101-
: normalize(join(BASE_DIR, createDirnameFromTask(
102-
(test?.type === "test" ? test : suite) || suite,
103-
)));
98+
const dirname = internalGenerateDirname(options?.dirname);
10499

105100
const allowOutside = options?.allowOutside ?? false;
106101

@@ -134,6 +129,24 @@ export async function testdir(
134129
return dirname;
135130
}
136131

132+
/**
133+
* Generates the path for a test directory.
134+
*
135+
* @param {string?} dirname - The directory name to use.
136+
*
137+
* If not provided, a directory name will be generated based on the test name.
138+
*
139+
* @returns {string} The path of the current test directory.
140+
* @throws An error if `testdir` is called outside of a test.
141+
*/
142+
testdir.dirname = (dirname?: string): string => {
143+
if (!isInVitest()) {
144+
throw new Error("testdir must be called inside vitest context");
145+
}
146+
147+
return internalGenerateDirname(dirname);
148+
};
149+
137150
/**
138151
* Creates a test directory with the specified files and options.
139152
*
@@ -153,11 +166,7 @@ export function testdirSync(
153166
const test = getCurrentTest();
154167
const suite = getCurrentSuite();
155168

156-
const dirname = options?.dirname
157-
? normalize(join(BASE_DIR, options.dirname))
158-
: normalize(join(BASE_DIR, createDirnameFromTask(
159-
(test?.type === "test" ? test : suite) || suite,
160-
)));
169+
const dirname = internalGenerateDirname(options?.dirname);
161170

162171
const allowOutside = options?.allowOutside ?? false;
163172

@@ -191,6 +200,24 @@ export function testdirSync(
191200
return dirname;
192201
}
193202

203+
/**
204+
* Generates the path for a test directory.
205+
*
206+
* @param {string?} dirname - The directory name to use.
207+
*
208+
* If not provided, a directory name will be generated based on the test name.
209+
*
210+
* @returns {string} The path of the current test directory.
211+
* @throws An error if `testdir` is called outside of a test.
212+
*/
213+
testdirSync.dirname = (dirname?: string): string => {
214+
if (!isInVitest()) {
215+
throw new Error("testdirSync must be called inside vitest context");
216+
}
217+
218+
return internalGenerateDirname(dirname);
219+
};
220+
194221
/**
195222
* Creates a file tree at the specified path using the provided files object.
196223
* The files object represents the directory structure and file contents of the tree.

src/utils.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import type { DirectoryJSON, FromFileSystemOptions } from "./types";
22
import { readdirSync, readFileSync, readlinkSync, statSync } from "node:fs";
33
import { readdir, readFile, readlink, stat } from "node:fs/promises";
4-
import { normalize } from "node:path";
4+
import { join, normalize } from "node:path";
55
import process from "node:process";
66
import { expect, type RunnerTask, type SuiteCollector } from "vitest";
77
import { getCurrentSuite, getCurrentTest } from "vitest/suite";
88
import {
9+
BASE_DIR,
910
FIXTURE_ORIGINAL_PATH_SYMBOL,
1011
} from "./constants";
1112
import { symlink } from "./helpers";
@@ -210,3 +211,24 @@ export function processDirectorySync(
210211

211212
return files;
212213
}
214+
215+
/**
216+
* Generates a normalized directory path based on the provided dirname or the current test/suite context.
217+
* This function must be called within a Vitest context.
218+
*
219+
* @param {string?} dirname - Optional directory name to use as the base path
220+
* @returns {string} A normalized absolute path combining the base directory with either the provided dirname or a generated name from the current test/suite
221+
* @internal
222+
*/
223+
export function internalGenerateDirname(dirname?: string): string {
224+
const test = getCurrentTest();
225+
const suite = getCurrentSuite();
226+
227+
if (dirname != null) {
228+
return normalize(join(BASE_DIR, dirname));
229+
}
230+
231+
return normalize(join(BASE_DIR, createDirnameFromTask(
232+
(test?.type === "test" ? test : suite) || suite,
233+
)));
234+
}

0 commit comments

Comments
 (0)