Skip to content

Commit 13d1dc1

Browse files
committed
feat(tests): add tests for file-util.ts
1 parent f1db197 commit 13d1dc1

File tree

7 files changed

+355
-18
lines changed

7 files changed

+355
-18
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ on:
33
# a pull request.
44
push:
55
branches:
6-
- master
6+
- main
77
pull_request:
88
types: [opened, synchronize, reopened]
99

__tests__/config.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type InputMap = {
88
[key: string]: string;
99
};
1010

11-
describe('config', () => {
11+
describe('config.ts', () => {
1212
const defaultInputs: InputMap = {
1313
'major-keywords': 'BREAKING CHANGE,!',
1414
'minor-keywords': 'feat,feature',

__tests__/file-util.test.ts

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
import * as fs from 'node:fs';
2+
import * as os from 'node:os';
3+
import * as path from 'node:path';
4+
import { copyModuleContents, removeDirectoryContents, shouldExcludeFile } from '../src/file-util';
5+
6+
describe('file-util.ts', () => {
7+
let tempDir: string;
8+
9+
beforeEach(() => {
10+
// Create a temporary directory before each test
11+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-dir-'));
12+
});
13+
14+
afterEach(() => {
15+
// Remove temporary directory
16+
fs.rmSync(tempDir, { recursive: true });
17+
});
18+
19+
describe('shouldExcludeFile', () => {
20+
it('should exclude file when pattern matches', () => {
21+
const baseDirectory = tempDir;
22+
const filePath = path.join(tempDir, 'file.txt');
23+
const excludePatterns = ['*.txt'];
24+
25+
expect(shouldExcludeFile(baseDirectory, filePath, excludePatterns)).toBe(true);
26+
});
27+
28+
it('should not exclude file when pattern does not match', () => {
29+
const baseDirectory = tempDir;
30+
const filePath = path.join(tempDir, 'file.txt');
31+
const excludePatterns = ['*.js'];
32+
33+
expect(shouldExcludeFile(baseDirectory, filePath, excludePatterns)).toBe(false);
34+
});
35+
36+
it('should handle relative paths correctly', () => {
37+
const baseDirectory = tempDir;
38+
const filePath = path.join(tempDir, 'subdir', 'file.txt');
39+
const excludePatterns = ['subdir/*.txt'];
40+
41+
expect(shouldExcludeFile(baseDirectory, filePath, excludePatterns)).toBe(true);
42+
});
43+
44+
it('should handle exclusion pattern: *.md', () => {
45+
const baseDirectory = tempDir;
46+
const filePath1 = path.join(tempDir, 'README.md');
47+
const filePath2 = path.join(tempDir, 'nested', 'README.md');
48+
const excludePatterns = ['*.md'];
49+
50+
expect(shouldExcludeFile(baseDirectory, filePath1, excludePatterns)).toBe(true);
51+
expect(shouldExcludeFile(baseDirectory, filePath2, excludePatterns)).toBe(true);
52+
});
53+
54+
it('should handle exclusion pattern: **/*.md', () => {
55+
const baseDirectory = tempDir;
56+
const filePath1 = path.join(tempDir, 'README.md');
57+
const filePath2 = path.join(tempDir, 'nested', 'README.md');
58+
const excludePatterns = ['**/*.md'];
59+
60+
expect(shouldExcludeFile(baseDirectory, filePath1, excludePatterns)).toBe(true);
61+
expect(shouldExcludeFile(baseDirectory, filePath2, excludePatterns)).toBe(true);
62+
});
63+
64+
it('should handle exclusion pattern: tests/**', () => {
65+
const baseDirectory = tempDir;
66+
const filePath1 = path.join(tempDir, 'tests/config.test.ts');
67+
const filePath2 = path.join(tempDir, 'tests2/config.test.ts');
68+
const filePath3 = path.join(tempDir, 'tests2/tests/config.test.ts');
69+
const excludePatterns = ['tests/**'];
70+
71+
expect(shouldExcludeFile(baseDirectory, filePath1, excludePatterns)).toBe(true);
72+
expect(shouldExcludeFile(baseDirectory, filePath2, excludePatterns)).toBe(false);
73+
expect(shouldExcludeFile(baseDirectory, filePath3, excludePatterns)).toBe(false);
74+
});
75+
76+
it('should handle exclusion pattern: **/tests/**', () => {
77+
const baseDirectory = tempDir;
78+
const filePath1 = path.join(tempDir, 'tests/config.test.ts');
79+
const filePath2 = path.join(tempDir, 'tests2/config.test.ts');
80+
const filePath3 = path.join(tempDir, 'tests2/tests/config.test.ts');
81+
const excludePatterns = ['**/tests/**'];
82+
83+
expect(shouldExcludeFile(baseDirectory, filePath1, excludePatterns)).toBe(true);
84+
expect(shouldExcludeFile(baseDirectory, filePath2, excludePatterns)).toBe(false);
85+
expect(shouldExcludeFile(baseDirectory, filePath3, excludePatterns)).toBe(true);
86+
});
87+
});
88+
89+
describe('copyModuleContents', () => {
90+
beforeEach(() => {
91+
// Create src and dest directories for every test in this suite
92+
fs.mkdirSync(path.join(tempDir, 'src'), { recursive: true });
93+
fs.mkdirSync(path.join(tempDir, 'dest'), { recursive: true });
94+
});
95+
96+
it('should copy directory contents excluding files that match patterns', () => {
97+
const srcDirectory = path.join(tempDir, 'src');
98+
const destDirectory = path.join(tempDir, 'dest');
99+
const excludePatterns = ['*.txt'];
100+
101+
// Create files in src directory
102+
fs.writeFileSync(path.join(srcDirectory, 'file.txt'), 'Hello World!');
103+
fs.writeFileSync(path.join(srcDirectory, 'file.js'), 'console.log("Hello World!");');
104+
105+
// Now perform the copy operation
106+
copyModuleContents(srcDirectory, destDirectory, excludePatterns);
107+
108+
// Check that the file was copied
109+
expect(fs.existsSync(path.join(destDirectory, 'file.txt'))).toBe(false);
110+
expect(fs.existsSync(path.join(destDirectory, 'file.js'))).toBe(true);
111+
});
112+
113+
it('should handle recursive directory copying', () => {
114+
const srcDirectory = path.join(tempDir, 'src');
115+
const destDirectory = path.join(tempDir, 'dest');
116+
const excludePatterns: string[] = [];
117+
118+
// Create source structure
119+
fs.mkdirSync(path.join(srcDirectory, 'subdir'), { recursive: true });
120+
fs.writeFileSync(path.join(srcDirectory, 'file.txt'), 'Hello World!');
121+
fs.writeFileSync(path.join(srcDirectory, 'subdir', 'file.js'), 'console.log("Hello World!");');
122+
123+
// Perform the copy operation
124+
copyModuleContents(srcDirectory, destDirectory, excludePatterns);
125+
126+
// Validate the destination contents
127+
expect(fs.existsSync(path.join(destDirectory, 'file.txt'))).toBe(true);
128+
expect(fs.existsSync(path.join(destDirectory, 'subdir', 'file.js'))).toBe(true);
129+
});
130+
131+
it('should copy files excluding multiple patterns', () => {
132+
const srcDirectory = path.join(tempDir, 'src');
133+
const destDirectory = path.join(tempDir, 'dest');
134+
const excludePatterns = ['*.txt', '*.js'];
135+
136+
fs.writeFileSync(path.join(srcDirectory, 'file.txt'), 'Hello World!');
137+
fs.writeFileSync(path.join(srcDirectory, 'file.js'), 'console.log("Hello World!");');
138+
fs.writeFileSync(path.join(srcDirectory, 'file.md'), 'This is a markdown file.');
139+
140+
copyModuleContents(srcDirectory, destDirectory, excludePatterns);
141+
142+
expect(fs.existsSync(path.join(destDirectory, 'file.txt'))).toBe(false);
143+
expect(fs.existsSync(path.join(destDirectory, 'file.js'))).toBe(false);
144+
expect(fs.existsSync(path.join(destDirectory, 'file.md'))).toBe(true);
145+
});
146+
147+
it('should handle copying from an empty directory', () => {
148+
const srcDirectory = path.join(tempDir, 'src');
149+
const destDirectory = path.join(tempDir, 'dest');
150+
const excludePatterns = ['*.txt'];
151+
152+
copyModuleContents(srcDirectory, destDirectory, excludePatterns);
153+
154+
// Validate that the destination directory is still empty
155+
expect(fs.readdirSync(destDirectory).length).toBe(0);
156+
});
157+
158+
it('should throw an error if the source directory does not exist', () => {
159+
const nonExistentSrcDirectory = path.join(tempDir, 'non-existent-src');
160+
const destDirectory = path.join(tempDir, 'dest');
161+
const excludePatterns = ['*.txt'];
162+
163+
expect(() => {
164+
copyModuleContents(nonExistentSrcDirectory, destDirectory, excludePatterns);
165+
}).toThrow(); // Assuming your implementation throws an error for non-existent directories
166+
});
167+
168+
it('should copy files that do not match any exclusion patterns', () => {
169+
const srcDirectory = path.join(tempDir, 'src');
170+
const destDirectory = path.join(tempDir, 'dest');
171+
const excludePatterns = ['*.js'];
172+
173+
fs.writeFileSync(path.join(srcDirectory, 'file.txt'), 'Hello World!');
174+
fs.writeFileSync(path.join(srcDirectory, 'file.js'), 'console.log("Hello World!");');
175+
176+
copyModuleContents(srcDirectory, destDirectory, excludePatterns);
177+
178+
expect(fs.existsSync(path.join(destDirectory, 'file.txt'))).toBe(true);
179+
expect(fs.existsSync(path.join(destDirectory, 'file.js'))).toBe(false);
180+
});
181+
182+
it('should overwrite files in the destination if they have the same name and do not match exclusion patterns', () => {
183+
const srcDirectory = path.join(tempDir, 'src');
184+
const destDirectory = path.join(tempDir, 'dest');
185+
const excludePatterns: string[] = [];
186+
187+
fs.writeFileSync(path.join(srcDirectory, 'file.txt'), 'Hello World from source!');
188+
fs.writeFileSync(path.join(destDirectory, 'file.txt'), 'Hello World from destination!');
189+
190+
copyModuleContents(srcDirectory, destDirectory, excludePatterns);
191+
192+
const destContent = fs.readFileSync(path.join(destDirectory, 'file.txt'), 'utf-8');
193+
expect(destContent).toBe('Hello World from source!');
194+
});
195+
});
196+
197+
describe('removeDirectoryContents', () => {
198+
it('should remove directory contents except for specified exceptions', () => {
199+
const directory = path.join(tempDir, 'dir');
200+
const exceptions = ['file.txt'];
201+
202+
fs.mkdirSync(directory);
203+
fs.writeFileSync(path.join(directory, 'file.txt'), 'Hello World!');
204+
fs.writeFileSync(path.join(directory, 'file.js'), 'console.log("Hello World!");');
205+
206+
removeDirectoryContents(directory, exceptions);
207+
208+
expect(fs.existsSync(path.join(directory, 'file.txt'))).toBe(true);
209+
expect(fs.existsSync(path.join(directory, 'file.js'))).toBe(false);
210+
});
211+
212+
it('should handle recursive directory removal', () => {
213+
const directory = path.join(tempDir, 'dir');
214+
const exceptions: string[] = [];
215+
216+
fs.mkdirSync(directory);
217+
fs.mkdirSync(path.join(directory, 'subdir'));
218+
fs.writeFileSync(path.join(directory, 'file.txt'), 'Hello World!');
219+
fs.writeFileSync(path.join(directory, 'subdir', 'file.js'), 'console.log("Hello World!");');
220+
221+
removeDirectoryContents(directory, exceptions);
222+
223+
expect(fs.existsSync(path.join(directory, 'file.txt'))).toBe(false);
224+
expect(fs.existsSync(path.join(directory, 'subdir', 'file.js'))).toBe(false);
225+
});
226+
227+
it('should handle exceptions correctly', () => {
228+
const directory = path.join(tempDir, 'dir');
229+
const exceptions = ['file.txt', 'subdir'];
230+
231+
fs.mkdirSync(directory);
232+
fs.mkdirSync(path.join(directory, 'subdir'));
233+
fs.writeFileSync(path.join(directory, 'file.txt'), 'Hello World!');
234+
fs.writeFileSync(path.join(directory, 'file.js'), 'console.log("Hello World!");');
235+
fs.writeFileSync(path.join(directory, 'subdir', 'file.js'), 'console.log("Hello World!");');
236+
237+
removeDirectoryContents(directory, exceptions);
238+
239+
expect(fs.existsSync(path.join(directory, 'file.txt'))).toBe(true);
240+
expect(fs.existsSync(path.join(directory, 'file.js'))).toBe(false);
241+
expect(fs.existsSync(path.join(directory, 'subdir', 'file.js'))).toBe(true);
242+
});
243+
244+
it('should handle an empty directory', () => {
245+
const directory = path.join(tempDir, 'dir');
246+
const exceptions: string[] = [];
247+
248+
fs.mkdirSync(directory); // Create an empty directory
249+
removeDirectoryContents(directory, exceptions);
250+
251+
// Validate that the directory is still empty
252+
expect(fs.readdirSync(directory).length).toBe(0);
253+
});
254+
255+
it('should not remove if only exceptions are present', () => {
256+
const directory = path.join(tempDir, 'dir');
257+
const exceptions = ['file.txt'];
258+
259+
fs.mkdirSync(directory);
260+
fs.writeFileSync(path.join(directory, 'file.txt'), 'Hello World!');
261+
262+
removeDirectoryContents(directory, exceptions);
263+
264+
expect(fs.existsSync(path.join(directory, 'file.txt'))).toBe(true);
265+
expect(fs.readdirSync(directory).length).toBe(1); // Only the exception should exist
266+
});
267+
268+
it('should handle nested exceptions correctly', () => {
269+
const directory = path.join(tempDir, 'dir');
270+
const exceptions = ['subdir'];
271+
272+
fs.mkdirSync(directory);
273+
fs.mkdirSync(path.join(directory, 'subdir'));
274+
fs.writeFileSync(path.join(directory, 'file.txt'), 'Hello World!');
275+
fs.writeFileSync(path.join(directory, 'subdir', 'file.js'), 'console.log("Hello World!");');
276+
277+
removeDirectoryContents(directory, exceptions);
278+
279+
expect(fs.existsSync(path.join(directory, 'subdir'))).toBe(true);
280+
expect(fs.existsSync(path.join(directory, 'file.txt'))).toBe(false);
281+
expect(fs.existsSync(path.join(directory, 'subdir', 'file.js'))).toBe(true);
282+
});
283+
284+
it('should not throw an error if the directory does not exist', () => {
285+
const nonExistentDirectory = path.join(tempDir, 'non-existent-dir');
286+
const exceptions = ['file.txt'];
287+
288+
expect(() => {
289+
removeDirectoryContents(nonExistentDirectory, exceptions);
290+
}).not.toThrow(); // Ensure no error is thrown
291+
});
292+
293+
it('should handle exceptions that do not exist in the directory', () => {
294+
const directory = path.join(tempDir, 'dir');
295+
const exceptions = ['file.txt'];
296+
297+
fs.mkdirSync(directory);
298+
fs.writeFileSync(path.join(directory, 'file.js'), 'console.log("Hello World!");');
299+
300+
removeDirectoryContents(directory, exceptions);
301+
302+
expect(fs.existsSync(path.join(directory, 'file.js'))).toBe(false);
303+
});
304+
305+
it('should remove directory contents when no exceptions specified', () => {
306+
const directory = path.join(tempDir, 'dir');
307+
308+
fs.mkdirSync(directory);
309+
fs.writeFileSync(path.join(directory, 'file.txt'), 'Hello World!');
310+
fs.writeFileSync(path.join(directory, 'file.js'), 'console.log("Hello World!");');
311+
312+
removeDirectoryContents(directory);
313+
314+
expect(fs.existsSync(path.join(directory, 'file.txt'))).toBe(false);
315+
expect(fs.existsSync(path.join(directory, 'file.js'))).toBe(false);
316+
});
317+
});
318+
});

assets/coverage-badge.svg

Lines changed: 1 addition & 1 deletion
Loading

sonar-project.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
sonar.organization=techpivot
22
sonar.projectKey=terraform-module-releaser
3-
sonar.projectName=Terraform Mmodule Releaser
3+
sonar.projectName=Terraform Module Releaser
44

55
sonar.sourceEncoding=UTF-8
66

0 commit comments

Comments
 (0)