Skip to content

Commit e4d6065

Browse files
committed
feat(scripts): add initial version of sorting
1 parent 6d2b51e commit e4d6065

File tree

7 files changed

+101
-5
lines changed

7 files changed

+101
-5
lines changed

src/package/property-sorter.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import sortProperties from 'sort-object-keys';
1+
import sortObjectKeys from 'sort-object-keys';
22

3-
export default function (packageContents) {
4-
return sortProperties(
3+
export default function sortProperties(packageContents) {
4+
return sortObjectKeys(
55
packageContents,
66
[
77
'name',

src/package/scripts/lifter.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import updateTestScript from './test-script-updater.js';
2+
import sortScripts from './scripts-sorter.js';
23

34
export default function ({existingScripts, scripts}) {
45
return {
5-
scripts: updateTestScript({...existingScripts, ...scripts}),
6+
scripts: sortScripts(updateTestScript({...existingScripts, ...scripts})),
67
dependencies: {
78
javascript: {
89
development: ['npm-run-all2'],

src/package/scripts/lifter.test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,23 @@ import {when} from 'vitest-when';
33
import {describe, expect, it, vi} from 'vitest';
44

55
import updateTestScript from './test-script-updater.js';
6+
import sortScripts from './scripts-sorter.js';
67
import liftScripts from './lifter.js';
78

9+
vi.mock('./scripts-sorter.js');
810
vi.mock('./test-script-updater.js');
911

1012
describe('package.json scripts lifter', () => {
1113
it('should merge the provided scripts with the existing scripts', () => {
1214
const existingScripts = any.simpleObject();
1315
const scripts = any.simpleObject();
1416
const updatedScripts = any.simpleObject();
17+
const sortedScripts = any.simpleObject();
1518
when(updateTestScript).calledWith({...existingScripts, ...scripts}).thenReturn(updatedScripts);
19+
when(sortScripts).calledWith(updatedScripts).thenReturn(sortedScripts);
1620

1721
expect(liftScripts({existingScripts, scripts})).toEqual({
18-
scripts: updatedScripts,
22+
scripts: sortedScripts,
1923
dependencies: {
2024
javascript: {
2125
development: ['npm-run-all2'],
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function sortTestScript() {
2+
return -1;
3+
}
4+
5+
function isPreScriptFor(a, b) {
6+
return a.startsWith('pre') && a.slice(3) === b;
7+
}
8+
9+
export default function compareScriptNames(a, b) {
10+
if (isPreScriptFor(a, b)) {
11+
return -1;
12+
}
13+
14+
if (isPreScriptFor(b, a)) {
15+
return 1;
16+
}
17+
18+
if ('test' === a) {
19+
return sortTestScript(a, b);
20+
}
21+
22+
if ('test' === b) {
23+
return -sortTestScript(b, a);
24+
}
25+
26+
if (a.startsWith('lint:') && b.startsWith('test:')) {
27+
return -1;
28+
}
29+
30+
if (b.startsWith('lint:') && a.startsWith('test:')) {
31+
return 1;
32+
}
33+
34+
return 0;
35+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {describe, it, expect} from 'vitest';
2+
import any from '@travi/any';
3+
4+
import compareScriptNames from './script-comparator.js';
5+
6+
describe('script name comparator', () => {
7+
it('should consider undefined sort orders as equivalent', async () => {
8+
expect(compareScriptNames(any.word(), any.word())).toEqual(0);
9+
});
10+
11+
it('should sort `pre` scripts ahead of their related scripts', async () => {
12+
const baseScriptName = any.word();
13+
expect(compareScriptNames(`pre${baseScriptName}`, baseScriptName)).toEqual(-1);
14+
expect(compareScriptNames(baseScriptName, `pre${baseScriptName}`)).toEqual(1);
15+
16+
expect(compareScriptNames('pretest', 'test')).toEqual(-1);
17+
expect(compareScriptNames('test', 'pretest')).toEqual(1);
18+
});
19+
20+
it('should sort the `test` script ahead of any sub-test scripts', async () => {
21+
expect(compareScriptNames('test', `test:${any.word()}`)).toEqual(-1);
22+
expect(compareScriptNames(`test:${any.word()}`, 'test')).toEqual(1);
23+
});
24+
25+
it('should sort `lint:` scripts above `test:` scripts', async () => {
26+
expect(compareScriptNames(`lint:${any.word()}`, `test:${any.word()}`)).toEqual(-1);
27+
expect(compareScriptNames(`test:${any.word()}`, `lint:${any.word()}`)).toEqual(1);
28+
});
29+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import sortObjectKeys from 'sort-object-keys';
2+
3+
import compareScriptNames from './script-comparator.js';
4+
5+
export default function sortScripts(scripts) {
6+
return sortObjectKeys(scripts, compareScriptNames);
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import sortObjectKeys from 'sort-object-keys';
2+
3+
import {it, describe, expect, vi} from 'vitest';
4+
import {when} from 'vitest-when';
5+
import any from '@travi/any';
6+
7+
import compareScriptNames from './script-comparator.js';
8+
import sortScripts from './scripts-sorter.js';
9+
10+
vi.mock('sort-object-keys');
11+
12+
describe('npm scripts sorter', () => {
13+
it('should sort the scripts based on the defined order', async () => {
14+
const unsortedScripts = any.simpleObject();
15+
const sortedScripts = any.simpleObject();
16+
when(sortObjectKeys).calledWith(unsortedScripts, compareScriptNames).thenReturn(sortedScripts);
17+
18+
expect(sortScripts(unsortedScripts)).toEqual(sortedScripts);
19+
});
20+
});

0 commit comments

Comments
 (0)