Skip to content

Commit 2f92c24

Browse files
committed
feat(npm-scripts): sort test scripts above other scripts
1 parent e1a0977 commit 2f92c24

4 files changed

Lines changed: 64 additions & 16 deletions

File tree

src/package/scripts/script-comparator.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ function getBaseScriptOf(script) {
1818
return script.replace(/^(?:pre|post)/, '');
1919
}
2020

21+
function getCategoryOrder(base) {
22+
if (base.startsWith('lint:')) return 0;
23+
if ('test:unit' === base) return 1;
24+
if ('test:integration' === base) return 2;
25+
if (base.startsWith('test:')) return 1;
26+
return 3;
27+
}
28+
2129
export default function compareScriptNames(a, b) {
2230
if (isPreScriptFor(a, b)) return -1;
2331
if (isPreScriptFor(b, a)) return 1;
@@ -35,21 +43,8 @@ export default function compareScriptNames(a, b) {
3543
const aBase = getBaseScriptOf(a);
3644
const bBase = getBaseScriptOf(b);
3745

38-
if (aBase.startsWith('lint:') && bBase.startsWith('test:')) {
39-
return -1;
40-
}
41-
42-
if (bBase.startsWith('lint:') && aBase.startsWith('test:')) {
43-
return 1;
44-
}
45-
46-
if (aBase.startsWith('lint:') && !bBase.startsWith('lint:')) {
47-
return -1;
48-
}
49-
50-
if (bBase.startsWith('lint:') && !aBase.startsWith('lint:')) {
51-
return 1;
52-
}
46+
const categoryDiff = getCategoryOrder(aBase) - getCategoryOrder(bBase);
47+
if (0 !== categoryDiff) return 0 > categoryDiff ? -1 : 1;
5348

5449
return a.localeCompare(b);
5550
}

src/package/scripts/script-comparator.test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,14 @@ describe('script name comparator', () => {
6666
expect(compareScriptNames(any.word(), `lint:${any.word()}`)).toEqual(A_AFTER_B);
6767
expect(compareScriptNames(`lint:${any.word()}`, any.word())).toEqual(A_BEFORE_B);
6868
});
69+
70+
it('should sort `test:unit` ahead of `test:integration`', async () => {
71+
expect(compareScriptNames('test:unit', 'test:integration')).toEqual(A_BEFORE_B);
72+
expect(compareScriptNames('test:integration', 'test:unit')).toEqual(A_AFTER_B);
73+
});
74+
75+
it('should sort uncategorized scripts below `test:` scripts', async () => {
76+
expect(compareScriptNames(any.word(), `test:${any.word()}`)).toEqual(A_AFTER_B);
77+
expect(compareScriptNames(`test:${any.word()}`, any.word())).toEqual(A_BEFORE_B);
78+
});
6979
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Feature: Script Ordering
2+
3+
Scenario: ensure scripts are ordered correctly
4+
Given an "npm" lockfile exists
5+
And the project is versioned on GitHub
6+
And the project is of type "Package"
7+
And husky v5 is installed
8+
When the scaffolder results are processed
9+
Then the scripts are ordered correctly

test/integration/features/step_definitions/scripts-steps.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ import {assert} from 'chai';
44
import {Before, Given, Then} from '@cucumber/cucumber';
55

66
Before(function () {
7-
this.existingScripts = {...any.simpleObject(), test: any.string()};
7+
this.existingScripts = {
8+
...any.simpleObject(),
9+
test: any.string(),
10+
'lint:md': any.string(),
11+
prepare: any.string(),
12+
'test:unit': any.string(),
13+
'prelint:publish': 'run-s build',
14+
'test:integration': any.string()
15+
};
816
});
917

1018
Given('no additional scripts are included in the results', async function () {
@@ -63,3 +71,29 @@ Then('the updated test script includes build', async function () {
6371
assert.equal(pretest, 'run-s build');
6472
assert.notInclude(test, 'build');
6573
});
74+
75+
Then('the scripts are ordered correctly', async function () {
76+
const {scripts} = JSON.parse(await fs.readFile(`${process.cwd()}/package.json`, 'utf8'));
77+
const {
78+
test,
79+
'test:unit': testUnit,
80+
'test:integration': testIntegration,
81+
'prelint:publish': prelintPublish,
82+
'lint:md': lintMd,
83+
...otherExistingScripts
84+
} = this.existingScripts;
85+
86+
assert.deepEqual(
87+
Object.keys(scripts),
88+
[
89+
'test',
90+
'lint:lockfile',
91+
'lint:md',
92+
'prelint:publish',
93+
'lint:publish',
94+
'test:unit',
95+
'test:integration',
96+
...Object.keys(otherExistingScripts).sort((a, b) => a.localeCompare(b))
97+
]
98+
);
99+
});

0 commit comments

Comments
 (0)