Skip to content

Commit d842fc4

Browse files
test: add coverage for utility modules (#718)
* test: add coverage for utility modules Add tests for enforceArray, withExt, lazy, isPlainObject, deepMerge, and populate — all previously untested pure utility functions. * fixup: address review feedback - Simplify enforceArray tests to two cases (array vs non-array) - Remove redundant multiple-substitutions test for populate
1 parent 7e3f5d2 commit d842fc4

File tree

4 files changed

+125
-0
lines changed

4 files changed

+125
-0
lines changed

src/utils/__tests__/array.test.mjs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict';
2+
3+
import assert from 'node:assert/strict';
4+
import { describe, it } from 'node:test';
5+
6+
import { enforceArray } from '../array.mjs';
7+
8+
describe('enforceArray', () => {
9+
it('should return the same array if given an array', () => {
10+
const input = [1, 2, 3];
11+
assert.strictEqual(enforceArray(input), input);
12+
});
13+
14+
it('should wrap a non-array value in an array', () => {
15+
assert.deepStrictEqual(enforceArray('hello'), ['hello']);
16+
});
17+
});

src/utils/__tests__/file.test.mjs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
import assert from 'node:assert/strict';
4+
import { describe, it } from 'node:test';
5+
6+
import { withExt } from '../file.mjs';
7+
8+
describe('withExt', () => {
9+
it('should replace an existing extension', () => {
10+
assert.strictEqual(withExt('file.md', 'html'), 'file.html');
11+
assert.strictEqual(withExt('path/to/file.md', 'json'), 'path/to/file.json');
12+
});
13+
14+
it('should add an extension when there is none', () => {
15+
assert.strictEqual(withExt('file', 'html'), 'file.html');
16+
});
17+
18+
it('should strip the extension when ext is empty', () => {
19+
assert.strictEqual(withExt('file.md', ''), 'file');
20+
assert.strictEqual(withExt('file.md'), 'file');
21+
});
22+
23+
it('should handle files with multiple dots', () => {
24+
assert.strictEqual(withExt('file.test.mjs', 'js'), 'file.test.js');
25+
});
26+
});

src/utils/__tests__/misc.test.mjs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
3+
import assert from 'node:assert/strict';
4+
import { describe, it } from 'node:test';
5+
6+
import { lazy, isPlainObject, deepMerge } from '../misc.mjs';
7+
8+
describe('lazy', () => {
9+
it('should call the function only once and cache the result', () => {
10+
let callCount = 0;
11+
const fn = lazy(() => {
12+
callCount++;
13+
return 42;
14+
});
15+
16+
assert.strictEqual(fn(), 42);
17+
assert.strictEqual(fn(), 42);
18+
assert.strictEqual(callCount, 1);
19+
});
20+
});
21+
22+
describe('isPlainObject', () => {
23+
it('should return true for plain objects', () => {
24+
assert.strictEqual(isPlainObject({}), true);
25+
assert.strictEqual(isPlainObject({ a: 1 }), true);
26+
});
27+
28+
it('should return false for arrays', () => {
29+
assert.strictEqual(isPlainObject([]), false);
30+
assert.strictEqual(isPlainObject([1, 2]), false);
31+
});
32+
33+
it('should return false for null and primitives', () => {
34+
assert.strictEqual(isPlainObject(null), false);
35+
assert.strictEqual(isPlainObject(undefined), false);
36+
assert.strictEqual(isPlainObject(42), false);
37+
assert.strictEqual(isPlainObject('string'), false);
38+
});
39+
});
40+
41+
describe('deepMerge', () => {
42+
it('should merge flat objects with source taking precedence over base', () => {
43+
const result = deepMerge({ a: 1, b: 2 }, { b: 10, c: 3 });
44+
assert.deepStrictEqual(result, { a: 1, b: 2, c: 3 });
45+
});
46+
47+
it('should merge nested objects recursively', () => {
48+
const result = deepMerge({ nested: { a: 1 } }, { nested: { b: 2 } });
49+
assert.deepStrictEqual(result, { nested: { a: 1, b: 2 } });
50+
});
51+
52+
it('should use base values when source values are undefined', () => {
53+
const result = deepMerge({ a: undefined }, { a: 'base' });
54+
assert.deepStrictEqual(result, { a: 'base' });
55+
});
56+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
import assert from 'node:assert/strict';
4+
import { describe, it } from 'node:test';
5+
6+
import { populate } from '../templates.mjs';
7+
8+
describe('populate', () => {
9+
it('should substitute template variables from config', () => {
10+
const result = populate('https://github.com/{repository}/blob/{ref}/', {
11+
repository: 'nodejs/node',
12+
ref: 'main',
13+
});
14+
assert.strictEqual(result, 'https://github.com/nodejs/node/blob/main/');
15+
});
16+
17+
it('should use fallback when config value is missing', () => {
18+
const result = populate('{name|unknown}', {});
19+
assert.strictEqual(result, 'unknown');
20+
});
21+
22+
it('should leave the placeholder as-is when no value or fallback', () => {
23+
const result = populate('{missing}', {});
24+
assert.strictEqual(result, '{missing}');
25+
});
26+
});

0 commit comments

Comments
 (0)