@forwardimpact/libutil 0.1.70 → 0.1.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,338 +0,0 @@
1
- import { test, describe, beforeEach, afterEach } from "node:test";
2
- import assert from "node:assert";
3
- import fs from "fs";
4
- import fsPromises from "fs/promises";
5
- import path from "path";
6
- import { fileURLToPath } from "url";
7
-
8
- // Module under test
9
- import { TarExtractor, ZipExtractor } from "../extractor.js";
10
-
11
- describe("TarExtractor", () => {
12
- let extractor;
13
- let tempDir;
14
- let fixturesDir;
15
-
16
- beforeEach(() => {
17
- extractor = new TarExtractor(fsPromises, path);
18
-
19
- // Setup directories
20
- const __filename = fileURLToPath(import.meta.url);
21
- const __dirname = path.dirname(__filename);
22
- fixturesDir = path.join(__dirname, "fixtures");
23
- tempDir = path.join(__dirname, ".tmp-extractor-test");
24
-
25
- // Clean up any existing temp directory
26
- if (fs.existsSync(tempDir)) {
27
- fs.rmSync(tempDir, { recursive: true, force: true });
28
- }
29
- fs.mkdirSync(tempDir, { recursive: true });
30
- });
31
-
32
- afterEach(() => {
33
- // Clean up temp directory
34
- if (fs.existsSync(tempDir)) {
35
- fs.rmSync(tempDir, { recursive: true, force: true });
36
- }
37
- });
38
-
39
- describe("constructor", () => {
40
- test("creates TarExtractor with fs and path", () => {
41
- const extractor = new TarExtractor(fsPromises, path);
42
-
43
- assert.ok(extractor instanceof TarExtractor);
44
- });
45
-
46
- test("validates fs parameter", () => {
47
- assert.throws(() => new TarExtractor(), {
48
- message: /fs dependency is required/,
49
- });
50
- assert.throws(() => new TarExtractor(null, path), {
51
- message: /fs dependency is required/,
52
- });
53
- });
54
-
55
- test("validates path parameter", () => {
56
- assert.throws(() => new TarExtractor(fsPromises), {
57
- message: /path dependency is required/,
58
- });
59
- assert.throws(() => new TarExtractor(fsPromises, null), {
60
- message: /path dependency is required/,
61
- });
62
- });
63
- });
64
-
65
- describe("extract", () => {
66
- test("extracts tar.gz archive to specified directory", async () => {
67
- const tarPath = path.join(fixturesDir, "sample.tar.gz");
68
- const outputDir = path.join(tempDir, "tar-output");
69
-
70
- await extractor.extract(tarPath, outputDir);
71
-
72
- // Verify extracted files exist
73
- assert.ok(fs.existsSync(path.join(outputDir, "test.txt")));
74
- assert.ok(fs.existsSync(path.join(outputDir, "nested.txt")));
75
- assert.ok(fs.existsSync(path.join(outputDir, "subdir", "deep.txt")));
76
- });
77
-
78
- test("extracts files with correct content", async () => {
79
- const tarPath = path.join(fixturesDir, "sample.tar.gz");
80
- const outputDir = path.join(tempDir, "tar-content");
81
-
82
- await extractor.extract(tarPath, outputDir);
83
-
84
- // Verify file contents
85
- const testContent = await fsPromises.readFile(
86
- path.join(outputDir, "test.txt"),
87
- "utf8",
88
- );
89
- assert.strictEqual(testContent.trim(), "Hello from root file");
90
-
91
- const nestedContent = await fsPromises.readFile(
92
- path.join(outputDir, "nested.txt"),
93
- "utf8",
94
- );
95
- assert.strictEqual(nestedContent.trim(), "Nested content");
96
-
97
- const deepContent = await fsPromises.readFile(
98
- path.join(outputDir, "subdir", "deep.txt"),
99
- "utf8",
100
- );
101
- assert.strictEqual(deepContent.trim(), "Deep file content");
102
- });
103
-
104
- test("creates nested directory structure", async () => {
105
- const tarPath = path.join(fixturesDir, "sample.tar.gz");
106
- const outputDir = path.join(tempDir, "tar-structure");
107
-
108
- await extractor.extract(tarPath, outputDir);
109
-
110
- // Verify directory structure
111
- const subdirPath = path.join(outputDir, "subdir");
112
- assert.ok(fs.existsSync(subdirPath));
113
-
114
- const stats = await fsPromises.stat(subdirPath);
115
- assert.ok(stats.isDirectory());
116
- });
117
-
118
- test("handles non-existent output directory", async () => {
119
- const tarPath = path.join(fixturesDir, "sample.tar.gz");
120
- const outputDir = path.join(tempDir, "deep", "nested", "tar-output");
121
-
122
- // Should not throw - should create directory structure
123
- await extractor.extract(tarPath, outputDir);
124
-
125
- assert.ok(fs.existsSync(path.join(outputDir, "test.txt")));
126
- });
127
- });
128
- });
129
-
130
- describe("ZipExtractor", () => {
131
- let extractor;
132
- let tempDir;
133
- let fixturesDir;
134
-
135
- beforeEach(() => {
136
- extractor = new ZipExtractor(fsPromises, path);
137
-
138
- // Setup directories
139
- const __filename = fileURLToPath(import.meta.url);
140
- const __dirname = path.dirname(__filename);
141
- fixturesDir = path.join(__dirname, "fixtures");
142
- tempDir = path.join(__dirname, ".tmp-extractor-test");
143
-
144
- // Clean up any existing temp directory
145
- if (fs.existsSync(tempDir)) {
146
- fs.rmSync(tempDir, { recursive: true, force: true });
147
- }
148
- fs.mkdirSync(tempDir, { recursive: true });
149
- });
150
-
151
- afterEach(() => {
152
- // Clean up temp directory
153
- if (fs.existsSync(tempDir)) {
154
- fs.rmSync(tempDir, { recursive: true, force: true });
155
- }
156
- });
157
-
158
- describe("constructor", () => {
159
- test("creates ZipExtractor with fs and path", () => {
160
- const extractor = new ZipExtractor(fsPromises, path);
161
-
162
- assert.ok(extractor instanceof ZipExtractor);
163
- });
164
-
165
- test("validates fs parameter", () => {
166
- assert.throws(() => new ZipExtractor(), {
167
- message: /fs dependency is required/,
168
- });
169
- assert.throws(() => new ZipExtractor(null, path), {
170
- message: /fs dependency is required/,
171
- });
172
- });
173
-
174
- test("validates path parameter", () => {
175
- assert.throws(() => new ZipExtractor(fsPromises), {
176
- message: /path dependency is required/,
177
- });
178
- assert.throws(() => new ZipExtractor(fsPromises, null), {
179
- message: /path dependency is required/,
180
- });
181
- });
182
- });
183
-
184
- describe("extract", () => {
185
- test("extracts zip archive to specified directory", async () => {
186
- const zipPath = path.join(fixturesDir, "sample.zip");
187
- const outputDir = path.join(tempDir, "zip-output");
188
-
189
- await extractor.extract(zipPath, outputDir);
190
-
191
- // Verify extracted files exist
192
- assert.ok(fs.existsSync(path.join(outputDir, "test.txt")));
193
- assert.ok(fs.existsSync(path.join(outputDir, "nested.txt")));
194
- assert.ok(fs.existsSync(path.join(outputDir, "subdir", "deep.txt")));
195
- });
196
-
197
- test("extracts files with correct content", async () => {
198
- const zipPath = path.join(fixturesDir, "sample.zip");
199
- const outputDir = path.join(tempDir, "zip-content");
200
-
201
- await extractor.extract(zipPath, outputDir);
202
-
203
- // Verify file contents
204
- const testContent = await fsPromises.readFile(
205
- path.join(outputDir, "test.txt"),
206
- "utf8",
207
- );
208
- assert.strictEqual(testContent.trim(), "Hello from root file");
209
-
210
- const nestedContent = await fsPromises.readFile(
211
- path.join(outputDir, "nested.txt"),
212
- "utf8",
213
- );
214
- assert.strictEqual(nestedContent.trim(), "Nested content");
215
-
216
- const deepContent = await fsPromises.readFile(
217
- path.join(outputDir, "subdir", "deep.txt"),
218
- "utf8",
219
- );
220
- assert.strictEqual(deepContent.trim(), "Deep file content");
221
- });
222
-
223
- test("creates nested directory structure", async () => {
224
- const zipPath = path.join(fixturesDir, "sample.zip");
225
- const outputDir = path.join(tempDir, "zip-structure");
226
-
227
- await extractor.extract(zipPath, outputDir);
228
-
229
- // Verify directory structure
230
- const subdirPath = path.join(outputDir, "subdir");
231
- assert.ok(fs.existsSync(subdirPath));
232
-
233
- const stats = await fsPromises.stat(subdirPath);
234
- assert.ok(stats.isDirectory());
235
- });
236
-
237
- test("handles non-existent output directory", async () => {
238
- const zipPath = path.join(fixturesDir, "sample.zip");
239
- const outputDir = path.join(tempDir, "deep", "nested", "zip-output");
240
-
241
- // Should not throw - should create directory structure
242
- await extractor.extract(zipPath, outputDir);
243
-
244
- assert.ok(fs.existsSync(path.join(outputDir, "test.txt")));
245
- });
246
-
247
- test("throws error for invalid zip file", async () => {
248
- const invalidZipPath = path.join(tempDir, "invalid.zip");
249
-
250
- // Create an invalid zip file (just some random bytes)
251
- await fsPromises.writeFile(invalidZipPath, Buffer.from([0, 1, 2, 3, 4]));
252
-
253
- const outputDir = path.join(tempDir, "invalid-output");
254
-
255
- await assert.rejects(
256
- async () => {
257
- await extractor.extract(invalidZipPath, outputDir);
258
- },
259
- {
260
- message: /Invalid ZIP file/,
261
- },
262
- );
263
- });
264
- });
265
-
266
- describe("format comparison", () => {
267
- test("both extractors produce identical file content", async () => {
268
- const tarPath = path.join(fixturesDir, "sample.tar.gz");
269
- const zipPath = path.join(fixturesDir, "sample.zip");
270
- const tarOutput = path.join(tempDir, "tar-compare");
271
- const zipOutput = path.join(tempDir, "zip-compare");
272
-
273
- const tarExtractor = new TarExtractor(fsPromises, path);
274
- const zipExtractor = new ZipExtractor(fsPromises, path);
275
-
276
- await tarExtractor.extract(tarPath, tarOutput);
277
- await zipExtractor.extract(zipPath, zipOutput);
278
-
279
- // Compare file contents
280
- const tarTest = await fsPromises.readFile(
281
- path.join(tarOutput, "test.txt"),
282
- "utf8",
283
- );
284
- const zipTest = await fsPromises.readFile(
285
- path.join(zipOutput, "test.txt"),
286
- "utf8",
287
- );
288
- assert.strictEqual(tarTest, zipTest);
289
-
290
- const tarNested = await fsPromises.readFile(
291
- path.join(tarOutput, "nested.txt"),
292
- "utf8",
293
- );
294
- const zipNested = await fsPromises.readFile(
295
- path.join(zipOutput, "nested.txt"),
296
- "utf8",
297
- );
298
- assert.strictEqual(tarNested, zipNested);
299
-
300
- const tarDeep = await fsPromises.readFile(
301
- path.join(tarOutput, "subdir", "deep.txt"),
302
- "utf8",
303
- );
304
- const zipDeep = await fsPromises.readFile(
305
- path.join(zipOutput, "subdir", "deep.txt"),
306
- "utf8",
307
- );
308
- assert.strictEqual(tarDeep, zipDeep);
309
- });
310
-
311
- test("both extractors create identical directory structure", async () => {
312
- const tarPath = path.join(fixturesDir, "sample.tar.gz");
313
- const zipPath = path.join(fixturesDir, "sample.zip");
314
- const tarOutput = path.join(tempDir, "tar-struct");
315
- const zipOutput = path.join(tempDir, "zip-struct");
316
-
317
- const tarExtractor = new TarExtractor(fsPromises, path);
318
- const zipExtractor = new ZipExtractor(fsPromises, path);
319
-
320
- await tarExtractor.extract(tarPath, tarOutput);
321
- await zipExtractor.extract(zipPath, zipOutput);
322
-
323
- // Check that both have the subdir
324
- assert.ok(fs.existsSync(path.join(tarOutput, "subdir")));
325
- assert.ok(fs.existsSync(path.join(zipOutput, "subdir")));
326
-
327
- // Check that both subdirs are directories
328
- const tarSubdirStats = await fsPromises.stat(
329
- path.join(tarOutput, "subdir"),
330
- );
331
- const zipSubdirStats = await fsPromises.stat(
332
- path.join(zipOutput, "subdir"),
333
- );
334
- assert.ok(tarSubdirStats.isDirectory());
335
- assert.ok(zipSubdirStats.isDirectory());
336
- });
337
- });
338
- });
@@ -1,358 +0,0 @@
1
- import { test, describe, beforeEach, afterEach, mock } from "node:test";
2
- import assert from "node:assert";
3
- import fs from "fs";
4
- import fsPromises from "fs/promises";
5
- import path from "path";
6
- import { fileURLToPath } from "url";
7
-
8
- import { createMockLogger } from "@forwardimpact/libharness";
9
-
10
- // Module under test
11
- import { Finder } from "../finder.js";
12
-
13
- describe("Finder", () => {
14
- let mockLogger;
15
- let mockProcess;
16
- let finder;
17
- let tempDir;
18
-
19
- beforeEach(() => {
20
- mockLogger = createMockLogger();
21
-
22
- mockProcess = {
23
- cwd: () => "/test/project",
24
- };
25
-
26
- finder = new Finder(fsPromises, mockLogger, mockProcess);
27
-
28
- // Create a temporary directory for testing
29
- const __filename = fileURLToPath(import.meta.url);
30
- const __dirname = path.dirname(__filename);
31
- tempDir = path.join(__dirname, ".tmp-linker-test");
32
-
33
- // Clean up any existing temp directory
34
- if (fs.existsSync(tempDir)) {
35
- fs.rmSync(tempDir, { recursive: true, force: true });
36
- }
37
- fs.mkdirSync(tempDir, { recursive: true });
38
- });
39
-
40
- afterEach(() => {
41
- // Clean up temp directory
42
- if (fs.existsSync(tempDir)) {
43
- fs.rmSync(tempDir, { recursive: true, force: true });
44
- }
45
- });
46
-
47
- describe("constructor", () => {
48
- test("creates Finder with fs, logger and process", () => {
49
- const finder = new Finder(fsPromises, mockLogger, mockProcess);
50
-
51
- assert.ok(finder instanceof Finder);
52
- });
53
-
54
- test("validates fs parameter", () => {
55
- assert.throws(() => new Finder(), {
56
- message: /fs is required/,
57
- });
58
- assert.throws(() => new Finder(null), {
59
- message: /fs is required/,
60
- });
61
- });
62
-
63
- test("validates logger parameter", () => {
64
- assert.throws(() => new Finder(fsPromises), {
65
- message: /logger is required/,
66
- });
67
- assert.throws(() => new Finder(fsPromises, null), {
68
- message: /logger is required/,
69
- });
70
- });
71
-
72
- test("validates process parameter", () => {
73
- assert.throws(() => new Finder(fsPromises, mockLogger, null), {
74
- message: /process is required/,
75
- });
76
- });
77
-
78
- test("uses global process when not provided", () => {
79
- const finder = new Finder(fsPromises, mockLogger);
80
- assert.ok(finder instanceof Finder);
81
- });
82
- });
83
-
84
- describe("findUpward", () => {
85
- test("finds file in current directory", () => {
86
- // Create test structure
87
- const testFile = path.join(tempDir, "target.txt");
88
- fs.writeFileSync(testFile, "test");
89
-
90
- const result = finder.findUpward(tempDir, "target.txt");
91
-
92
- assert.strictEqual(result, testFile);
93
- });
94
-
95
- test("finds file in parent directory", () => {
96
- // Create test structure
97
- const subDir = path.join(tempDir, "subdir");
98
- fs.mkdirSync(subDir);
99
- const testFile = path.join(tempDir, "target.txt");
100
- fs.writeFileSync(testFile, "test");
101
-
102
- const result = finder.findUpward(subDir, "target.txt");
103
-
104
- assert.strictEqual(result, testFile);
105
- });
106
-
107
- test("returns null when file not found", () => {
108
- const result = finder.findUpward(tempDir, "nonexistent.txt");
109
-
110
- assert.strictEqual(result, null);
111
- });
112
-
113
- test("respects maxDepth parameter", () => {
114
- // Create nested structure
115
- const deepDir = path.join(tempDir, "a", "b", "c");
116
- fs.mkdirSync(deepDir, { recursive: true });
117
- const testFile = path.join(tempDir, "target.txt");
118
- fs.writeFileSync(testFile, "test");
119
-
120
- // Should not find with maxDepth of 2
121
- const result = finder.findUpward(deepDir, "target.txt", 2);
122
-
123
- assert.strictEqual(result, null);
124
- });
125
- });
126
-
127
- describe("findProjectRoot", () => {
128
- test("finds project root with package.json", () => {
129
- // Create test project structure
130
- const projectRoot = path.join(tempDir, "project");
131
- const packagesDir = path.join(projectRoot, "packages", "somepackage");
132
- fs.mkdirSync(packagesDir, { recursive: true });
133
- fs.writeFileSync(path.join(projectRoot, "package.json"), "{}");
134
-
135
- // Test from the package directory (3 levels deep from project root)
136
- const result = finder.findProjectRoot(packagesDir);
137
-
138
- assert.strictEqual(result, projectRoot);
139
- });
140
-
141
- test("throws error when project root not found", () => {
142
- // Create a directory structure without package.json at any level
143
- const deepDir = path.join(tempDir, "no-project", "deep", "dir");
144
- fs.mkdirSync(deepDir, { recursive: true });
145
-
146
- assert.throws(() => finder.findProjectRoot(deepDir), {
147
- message: /Could not find project root/,
148
- });
149
- });
150
- });
151
-
152
- describe("createSymlink", () => {
153
- test("creates symlink between directories", async () => {
154
- const sourceDir = path.join(tempDir, "source");
155
- const targetPath = path.join(tempDir, "target");
156
-
157
- await finder.createSymlink(sourceDir, targetPath);
158
-
159
- assert.ok(fs.existsSync(targetPath));
160
- assert.ok(fs.lstatSync(targetPath).isSymbolicLink());
161
- assert.strictEqual(mockLogger.debug.mock.calls.length, 1);
162
- assert.ok(
163
- mockLogger.debug.mock.calls[0].arguments[1].includes("Created symlink"),
164
- );
165
- });
166
-
167
- test("removes existing target before creating symlink", async () => {
168
- const sourceDir = path.join(tempDir, "source");
169
- const targetPath = path.join(tempDir, "target");
170
-
171
- // Create existing target directory
172
- fs.mkdirSync(targetPath);
173
- fs.writeFileSync(path.join(targetPath, "existing.txt"), "test");
174
-
175
- await finder.createSymlink(sourceDir, targetPath);
176
-
177
- assert.ok(fs.existsSync(targetPath));
178
- assert.ok(fs.lstatSync(targetPath).isSymbolicLink());
179
- // Original file should be gone
180
- assert.ok(!fs.existsSync(path.join(targetPath, "existing.txt")));
181
- });
182
-
183
- test("removes existing symlink before creating new one", async () => {
184
- const sourceDir = path.join(tempDir, "source");
185
- const oldSourceDir = path.join(tempDir, "old-source");
186
- const targetPath = path.join(tempDir, "target");
187
-
188
- // Create old symlink
189
- fs.mkdirSync(oldSourceDir);
190
- fs.symlinkSync(oldSourceDir, targetPath, "dir");
191
-
192
- await finder.createSymlink(sourceDir, targetPath);
193
-
194
- assert.ok(fs.existsSync(targetPath));
195
- assert.ok(fs.lstatSync(targetPath).isSymbolicLink());
196
- // Should point to new source
197
- assert.strictEqual(fs.readlinkSync(targetPath), sourceDir);
198
- });
199
- });
200
-
201
- describe("createPackageSymlinks", () => {
202
- test("creates symlinks when project root is found", async () => {
203
- // Mock findProjectRoot to return a valid path
204
- const originalFindProjectRoot = finder.findProjectRoot;
205
- finder.findProjectRoot = mock.fn(() => {
206
- const projectRoot = path.join(tempDir, "project");
207
- const packagesDir = path.join(projectRoot, "packages");
208
- fs.mkdirSync(path.join(packagesDir, "libtype"), { recursive: true });
209
- fs.mkdirSync(path.join(packagesDir, "librpc"), { recursive: true });
210
- return projectRoot;
211
- });
212
-
213
- const generatedPath = path.join(tempDir, "generated");
214
-
215
- await finder.createPackageSymlinks(generatedPath);
216
-
217
- // Should have called findProjectRoot
218
- assert.strictEqual(finder.findProjectRoot.mock.calls.length, 1);
219
-
220
- // Restore original method
221
- finder.findProjectRoot = originalFindProjectRoot;
222
- });
223
-
224
- test("creates symlinks for standard packages", async () => {
225
- // Create mock project structure
226
- const projectRoot = path.join(tempDir, "project");
227
- const packagesDir = path.join(projectRoot, "packages");
228
- fs.mkdirSync(path.join(packagesDir, "libtype"), { recursive: true });
229
- fs.mkdirSync(path.join(packagesDir, "librpc"), { recursive: true });
230
-
231
- // Mock findProjectRoot
232
- const originalFindProjectRoot = finder.findProjectRoot;
233
- finder.findProjectRoot = mock.fn(() => projectRoot);
234
-
235
- const generatedPath = path.join(tempDir, "generated");
236
- fs.mkdirSync(generatedPath, { recursive: true });
237
-
238
- await finder.createPackageSymlinks(generatedPath);
239
-
240
- // Check that symlinks were created
241
- const libtypeTarget = path.join(packagesDir, "libtype", "generated");
242
- const librpcTarget = path.join(packagesDir, "librpc", "generated");
243
-
244
- assert.ok(fs.existsSync(libtypeTarget));
245
- assert.ok(fs.lstatSync(libtypeTarget).isSymbolicLink());
246
- assert.ok(fs.existsSync(librpcTarget));
247
- assert.ok(fs.lstatSync(librpcTarget).isSymbolicLink());
248
-
249
- assert.ok(
250
- mockLogger.debug.mock.calls.some((call) =>
251
- call.arguments[1].includes("Created symlink"),
252
- ),
253
- );
254
-
255
- // Restore original method
256
- finder.findProjectRoot = originalFindProjectRoot;
257
- });
258
- });
259
-
260
- describe("findData", () => {
261
- test("finds data/ in CWD via findUpward", () => {
262
- const dataDir = path.join(tempDir, "data");
263
- fs.mkdirSync(dataDir);
264
-
265
- const cwdFinder = new Finder(fsPromises, mockLogger, {
266
- cwd: () => tempDir,
267
- });
268
- const result = cwdFinder.findData("data", "/nonexistent-home");
269
-
270
- assert.strictEqual(result, dataDir);
271
- });
272
-
273
- test("finds data/ in a parent directory via findUpward", () => {
274
- const dataDir = path.join(tempDir, "data");
275
- fs.mkdirSync(dataDir);
276
- const subDir = path.join(tempDir, "products", "pathway");
277
- fs.mkdirSync(subDir, { recursive: true });
278
-
279
- const cwdFinder = new Finder(fsPromises, mockLogger, {
280
- cwd: () => subDir,
281
- });
282
- const result = cwdFinder.findData("data", "/nonexistent-home");
283
-
284
- assert.strictEqual(result, dataDir);
285
- });
286
-
287
- test("falls back to ~/.fit/data/ when CWD traversal fails", () => {
288
- const fakeHome = path.join(tempDir, "fakehome");
289
- const homeFitData = path.join(fakeHome, ".fit", "data");
290
- fs.mkdirSync(homeFitData, { recursive: true });
291
-
292
- const isolatedDir = path.join(tempDir, "isolated");
293
- fs.mkdirSync(isolatedDir);
294
-
295
- const cwdFinder = new Finder(fsPromises, mockLogger, {
296
- cwd: () => isolatedDir,
297
- });
298
- const result = cwdFinder.findData("data", fakeHome);
299
-
300
- assert.strictEqual(result, homeFitData);
301
- });
302
-
303
- test("throws when neither CWD traversal nor HOME fallback finds directory", () => {
304
- const isolatedDir = path.join(tempDir, "isolated");
305
- fs.mkdirSync(isolatedDir);
306
-
307
- const cwdFinder = new Finder(fsPromises, mockLogger, {
308
- cwd: () => isolatedDir,
309
- });
310
-
311
- assert.throws(() => cwdFinder.findData("data", "/nonexistent-home"), {
312
- message: /No data directory found/,
313
- });
314
- });
315
-
316
- test("CWD takes priority over HOME when both exist", () => {
317
- const cwdData = path.join(tempDir, "data");
318
- fs.mkdirSync(cwdData);
319
-
320
- const fakeHome = path.join(tempDir, "fakehome");
321
- const homeFitData = path.join(fakeHome, ".fit", "data");
322
- fs.mkdirSync(homeFitData, { recursive: true });
323
-
324
- const cwdFinder = new Finder(fsPromises, mockLogger, {
325
- cwd: () => tempDir,
326
- });
327
- const result = cwdFinder.findData("data", fakeHome);
328
-
329
- assert.strictEqual(result, cwdData);
330
- });
331
- });
332
-
333
- describe("findPackagePath", () => {
334
- test("finds package in local monorepo structure", () => {
335
- // Create mock monorepo structure
336
- const projectRoot = path.join(tempDir, "project");
337
- const packagePath = path.join(projectRoot, "packages", "libtype");
338
- fs.mkdirSync(packagePath, { recursive: true });
339
-
340
- const result = finder.findPackagePath(projectRoot, "libtype");
341
-
342
- assert.strictEqual(result, packagePath);
343
- });
344
- });
345
-
346
- describe("findGeneratedPath", () => {
347
- test("returns generated directory path for package", () => {
348
- // Create mock structure
349
- const projectRoot = path.join(tempDir, "project");
350
- const packagePath = path.join(projectRoot, "packages", "libtype");
351
- fs.mkdirSync(packagePath, { recursive: true });
352
-
353
- const result = finder.findGeneratedPath(projectRoot, "libtype");
354
-
355
- assert.strictEqual(result, path.join(packagePath, "generated"));
356
- });
357
- });
358
- });
Binary file
Binary file