Skip to content

Commit 992b640

Browse files
committed
Addresses code reviews
1 parent eb49673 commit 992b640

File tree

4 files changed

+32
-92
lines changed

4 files changed

+32
-92
lines changed

src/m365/spfx/commands/project/project-azuredevops-pipeline-add.spec.ts

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe(commands.PROJECT_AZUREDEVOPS_PIPELINE_ADD, () => {
1818
let log: any[];
1919
let logger: Logger;
2020
let commandInfo: CommandInfo;
21-
const projectPath: string = path.resolve('/fake/path/to/test-project');
21+
const projectPath: string = path.resolve('/test-project');
2222

2323
before(() => {
2424
sinon.stub(telemetry, 'trackEvent').resolves();
@@ -183,7 +183,7 @@ describe(commands.PROJECT_AZUREDEVOPS_PIPELINE_ADD, () => {
183183
throw `Invalid path: ${fakePath}`;
184184
});
185185

186-
sinon.stub(command as any, 'getProjectVersion').returns('');
186+
sinon.stub(command as any, 'getProjectVersion').returns(undefined);
187187

188188
sinon.stub(fs, 'writeFileSync').throws(new Error('writeFileSync failed'));
189189

@@ -250,36 +250,4 @@ describe(commands.PROJECT_AZUREDEVOPS_PIPELINE_ADD, () => {
250250
await assert.rejects(command.action(logger, { options: {} } as any),
251251
new CommandError('writeFileSync failed'));
252252
});
253-
254-
it('handles unexpected non-error value', async () => {
255-
sinon.stub(command as any, 'getProjectRoot').returns(projectPath);
256-
257-
sinon.stub(fs, 'readFileSync').callsFake((filePath, options) => {
258-
if (filePath.toString() === path.join(projectPath, 'package.json') && options === 'utf-8') {
259-
return '{"name": "test"}';
260-
}
261-
262-
throw `Invalid path: ${filePath}`;
263-
});
264-
265-
sinon.stub(fs, 'existsSync').callsFake((fakePath) => {
266-
if (fakePath.toString() === path.join(projectPath, '.azuredevops')) {
267-
return true;
268-
}
269-
else if (fakePath.toString() === path.join(projectPath, '.azuredevops', 'pipelines')) {
270-
return true;
271-
}
272-
273-
throw `Invalid path: ${fakePath}`;
274-
});
275-
276-
sinon.stub(command as any, 'getProjectVersion').returns('1.21.1');
277-
278-
sinon.stub(fs, 'writeFileSync').callsFake(() => {
279-
throw 'string failure';
280-
});
281-
282-
await assert.rejects(command.action(logger, { options: {} } as any),
283-
new CommandError('string failure'));
284-
});
285253
});

src/m365/spfx/commands/project/project-github-workflow-add.spec.ts

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,7 @@ describe(commands.PROJECT_GITHUB_WORKFLOW_ADD, () => {
188188

189189
sinon.stub(fs, 'writeFileSync').throws(new Error('writeFileSync failed'));
190190

191-
await assert.rejects(command.action(logger, { options: {} }),
192-
(err: any) => {
193-
if (err instanceof CommandError && err.message.includes('Unable to determine the version')) {
194-
return true;
195-
}
196-
return false;
197-
});
191+
await assert.rejects(command.action(logger, { options: {} }), new CommandError('Unable to determine the version of the current SharePoint Framework project. Could not find the correct version based on the version property in the .yo-rc.json file.'));
198192

199193
});
200194

@@ -224,13 +218,7 @@ describe(commands.PROJECT_GITHUB_WORKFLOW_ADD, () => {
224218

225219
sinon.stub(fs, 'writeFileSync').throws(new Error('writeFileSync failed'));
226220

227-
await assert.rejects(command.action(logger, { options: {} }),
228-
(err: any) => {
229-
if (err instanceof CommandError && err.message.includes('Could not find Node version')) {
230-
return true;
231-
}
232-
return false;
233-
});
221+
await assert.rejects(command.action(logger, { options: {} }), new CommandError("Could not find Node version for version '99.99.99' of SharePoint Framework."));
234222
});
235223

236224
it('handles unexpected error', async () => {
@@ -257,43 +245,11 @@ describe(commands.PROJECT_GITHUB_WORKFLOW_ADD, () => {
257245

258246
sinon.stub(command as any, 'getProjectVersion').returns('1.21.1');
259247

260-
sinon.stub(fs, 'writeFileSync').callsFake(() => {
261-
throw new Error('writeFileSync failed');
262-
});
248+
sinon.stub(fs, 'writeFileSync').throws(
249+
new Error('writeFileSync failed')
250+
);
263251

264252
await assert.rejects(command.action(logger, { options: {} } as any),
265253
new CommandError('writeFileSync failed'));
266254
});
267-
268-
it('handles unexpected non-error value', async () => {
269-
sinon.stub(command as any, 'getProjectRoot').returns(projectPath);
270-
271-
sinon.stub(fs, 'readFileSync').callsFake((filePath, options) => {
272-
if (filePath.toString() === path.join(projectPath, 'package.json') && options === 'utf-8') {
273-
return '{"name": "test"}';
274-
}
275-
276-
throw `Invalid path: ${filePath}`;
277-
});
278-
279-
sinon.stub(fs, 'existsSync').callsFake((fakePath) => {
280-
if (fakePath.toString() === path.join(projectPath, '.github')) {
281-
return true;
282-
}
283-
else if (fakePath.toString() === path.join(projectPath, '.github', 'workflows')) {
284-
return true;
285-
}
286-
287-
throw `Invalid path: ${fakePath}`;
288-
});
289-
290-
sinon.stub(command as any, 'getProjectVersion').returns('1.21.1');
291-
292-
sinon.stub(fs, 'writeFileSync').callsFake(() => {
293-
throw 'string failure';
294-
});
295-
296-
await assert.rejects(command.action(logger, { options: {} } as any),
297-
new CommandError('string failure'));
298-
});
299255
});

src/utils/spfx.spec.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,12 @@ describe('utils/spfx', () => {
4545

4646
it('returns correct Node version when only minor version differ', () => {
4747
const version = spfx.getHighestNodeVersion('8.1 || 8.2');
48-
assert.strictEqual(version, '8.x');
48+
assert.strictEqual(version, '8.2.x');
49+
});
50+
51+
it('returns correct Node version when only minor version differ - reverse case', () => {
52+
const version = spfx.getHighestNodeVersion('8.2 || 8.1');
53+
assert.strictEqual(version, '8.2.x');
4954
});
5055

5156
it('returns highest major for disjoint ranges', () => {
@@ -75,7 +80,7 @@ describe('utils/spfx', () => {
7580

7681
it('returns correct version for exact version without operator', () => {
7782
const version = spfx.getHighestNodeVersion('16.13.0');
78-
assert.strictEqual(version, '16.x');
83+
assert.strictEqual(version, '16.13.0');
7984
});
8085

8186
it('returns highest version when mixing < and <= operators', () => {
@@ -90,8 +95,4 @@ describe('utils/spfx', () => {
9095
it('throws when range cannot be normalized', () => {
9196
assert.throws(() => spfx.getHighestNodeVersion('invalid-range'), new Error("Unable to resolve the highest Node version for range 'invalid-range'."));
9297
});
93-
94-
it('throws when no valid ranges found', () => {
95-
assert.throws(() => spfx.getHighestNodeVersion('invalid-string'), new Error("Unable to resolve the highest Node version for range 'invalid-string'."));
96-
});
9798
});

src/utils/spfx.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Range, validRange } from 'semver';
1+
import { Range, coerce, gt, validRange } from 'semver';
22
import { Project } from '../m365/spfx/commands/project/project-model/index.js';
33

44
export const spfx = {
@@ -30,6 +30,21 @@ export const spfx = {
3030
let highestMajor: number | null = null;
3131
let exactVersion: string | null = null;
3232

33+
const simpleVersionPattern = /^\d+(\.\d+(\.\d+)?)?$/;
34+
if (ranges.every(r => simpleVersionPattern.test(r))) {
35+
const highest = ranges.reduce((best, curr) =>
36+
gt(coerce(curr)!, coerce(best)!) ? curr : best
37+
);
38+
const parts = highest.split('.');
39+
if (parts.length >= 3) {
40+
return highest;
41+
}
42+
43+
if (parts.length === 2) {
44+
return `${highest}.x`;
45+
}
46+
}
47+
3348
for (const rangeString of ranges) {
3449
const normalized = validRange(rangeString);
3550
if (!normalized) {
@@ -54,8 +69,8 @@ export const spfx = {
5469
exactVersion = comparator.semver.version;
5570
}
5671
}
57-
else if (comparator.operator === '>=' || comparator.operator === '>' || comparator.operator === '') {
58-
// For lower bounds or exact versions, use the major version
72+
else if (comparator.operator === '>=' || comparator.operator === '>') {
73+
// For lower bounds use the major version
5974
maxMajor = Math.max(maxMajor, comparator.semver.major);
6075
}
6176
}

0 commit comments

Comments
 (0)