From 0e9ceb62db5bac54022333bc1847d8a51723c751 Mon Sep 17 00:00:00 2001 From: Jake Champion Date: Tue, 20 Apr 2021 18:05:16 +0100 Subject: [PATCH] Ensure that origami components have package.json.type set to 'module' --- lib/tasks/verify-package-json.js | 4 ++ test/unit/fixtures/o-test/package.json | 1 + test/unit/tasks/verify-package-json.test.js | 80 ++++++++++++++++++++- 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/lib/tasks/verify-package-json.js b/lib/tasks/verify-package-json.js index 1e4ca637..662dc0dc 100644 --- a/lib/tasks/verify-package-json.js +++ b/lib/tasks/verify-package-json.js @@ -95,6 +95,10 @@ async function packageJson(config) { if (exists) { const file = await readFile(packageJsonPath, 'utf8'); const packageJson = JSON.parse(file); + + if (packageJson.type !== 'module') { + result.push('The `type` property is required. It must be the string "module".'); + } if (!validDescription(packageJson.description)) { result.push('A description property is required. It must be a string which describes the component.'); } diff --git a/test/unit/fixtures/o-test/package.json b/test/unit/fixtures/o-test/package.json index ffa260e3..6fca3be0 100644 --- a/test/unit/fixtures/o-test/package.json +++ b/test/unit/fixtures/o-test/package.json @@ -1,5 +1,6 @@ { "name": "@financial-times/o-test", + "type": "module", "version": "1.0.0", "description": "for a fixture", "keywords": [], diff --git a/test/unit/tasks/verify-package-json.test.js b/test/unit/tasks/verify-package-json.test.js index ac561651..d12d5a5a 100644 --- a/test/unit/tasks/verify-package-json.test.js +++ b/test/unit/tasks/verify-package-json.test.js @@ -108,6 +108,7 @@ describe('verify-package-json', function () { proclaim.equal( error.message, 'Failed linting:\n\n' + + 'The `type` property is required. It must be the string "module".\n' + 'A description property is required. It must be a string which describes the component.\n' + 'The keywords property is required. It must be an array. It must contain only strings which relate to the component. It can also be an empty array.\n' + 'The name property is required. It must be within the `@financial-times` namespace and conform to the npmjs specification at https://docs.npmjs.com/cli/v7/configuring-npm/package-json#name.\n' + @@ -118,7 +119,7 @@ describe('verify-package-json', function () { proclaim.deepStrictEqual( console.log.lastCall.args, - ["::error file=package.json,line=1,col=1::Failed linting:%0A%0AA description property is required. It must be a string which describes the component.%0AThe keywords property is required. It must be an array. It must contain only strings which relate to the component. It can also be an empty array.%0AThe name property is required. It must be within the `@financial-times` namespace and conform to the npmjs specification at https://docs.npmjs.com/cli/v7/configuring-npm/package-json#name.%0ABecause the file `main.js` exists, the `browser` property is required. It must have the value `\"main.js\"`.%0A%0AThe package.json file does not conform to the specification at https://origami.ft.com/spec/v2/components/#package-management"] + ["::error file=package.json,line=1,col=1::Failed linting:%0A%0AThe `type` property is required. It must be the string \"module\".%0AA description property is required. It must be a string which describes the component.%0AThe keywords property is required. It must be an array. It must contain only strings which relate to the component. It can also be an empty array.%0AThe name property is required. It must be within the `@financial-times` namespace and conform to the npmjs specification at https://docs.npmjs.com/cli/v7/configuring-npm/package-json#name.%0ABecause the file `main.js` exists, the `browser` property is required. It must have the value `\"main.js\"`.%0A%0AThe package.json file does not conform to the specification at https://origami.ft.com/spec/v2/components/#package-management"] ); } @@ -139,6 +140,7 @@ describe('verify-package-json', function () { proclaim.equal( error.message, 'Failed linting:\n\n' + + 'The `type` property is required. It must be the string "module".\n' + 'A description property is required. It must be a string which describes the component.\n' + 'The keywords property is required. It must be an array. It must contain only strings which relate to the component. It can also be an empty array.\n' + 'The name property is required. It must be within the `@financial-times` namespace and conform to the npmjs specification at https://docs.npmjs.com/cli/v7/configuring-npm/package-json#name.\n' + @@ -148,7 +150,7 @@ describe('verify-package-json', function () { proclaim.calledOnce(console.log); proclaim.deepStrictEqual( console.log.lastCall.args, - ["::error file=package.json,line=1,col=1::Failed linting:%0A%0AA description property is required. It must be a string which describes the component.%0AThe keywords property is required. It must be an array. It must contain only strings which relate to the component. It can also be an empty array.%0AThe name property is required. It must be within the `@financial-times` namespace and conform to the npmjs specification at https://docs.npmjs.com/cli/v7/configuring-npm/package-json#name.%0ABecause the file `main.js` exists, the `browser` property is required. It must have the value `\"main.js\"`.%0A%0AThe package.json file does not conform to the specification at https://origami.ft.com/spec/v2/components/#package-management"] + ["::error file=package.json,line=1,col=1::Failed linting:%0A%0AThe `type` property is required. It must be the string \"module\".%0AA description property is required. It must be a string which describes the component.%0AThe keywords property is required. It must be an array. It must contain only strings which relate to the component. It can also be an empty array.%0AThe name property is required. It must be within the `@financial-times` namespace and conform to the npmjs specification at https://docs.npmjs.com/cli/v7/configuring-npm/package-json#name.%0ABecause the file `main.js` exists, the `browser` property is required. It must have the value `\"main.js\"`.%0A%0AThe package.json file does not conform to the specification at https://origami.ft.com/spec/v2/components/#package-management"] ); } @@ -573,5 +575,79 @@ describe('verify-package-json', function () { }); + context('the type property', function(){ + context('when type exists', function() { + it('should fail if property is not set to `"module"`', async function () { + const packageJSON = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')); + packageJSON.type = "carrot"; + fs.writeFileSync('package.json', JSON.stringify(packageJSON), 'utf8'); + + let errored; + try { + await verifyPackageJson().task(); + errored = false; + } catch (error) { + errored = true; + proclaim.equal( + error.message, + 'Failed linting:\n\n' + + 'The `type` property is required. It must be the string "module".\n\n' + + 'The package.json file does not conform to the specification at https://origami.ft.com/spec/v2/components/#package-management' + ); + proclaim.calledOnce(console.log); + proclaim.deepStrictEqual( + console.log.lastCall.args, + ["::error file=package.json,line=1,col=1::Failed linting:%0A%0AThe `type` property is required. It must be the string \"module\".%0A%0AThe package.json file does not conform to the specification at https://origami.ft.com/spec/v2/components/#package-management"] + ); + } + + if (!errored) { + proclaim.fail('verifyPackageJson().task() did not return a rejected promise', 'verifyPackageJson().task() should have returned a rejected promise'); + } + }); + + it('should pass if property is set to `"module"', async function () { + const packageJSON = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')); + packageJSON.type = 'module'; + fs.writeFileSync('package.json', JSON.stringify(packageJSON), 'utf8'); + + await verifyPackageJson().task(); + proclaim.notCalled(console.log); + }); + }); + + context('when type does not exist', function() { + it('should fail', async function () { + const packageJSON = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')); + delete packageJSON.type; + fs.writeFileSync('package.json', JSON.stringify(packageJSON), 'utf8'); + + let errored; + try { + await verifyPackageJson().task(); + errored = false; + } catch (error) { + errored = true; + proclaim.equal( + error.message, + 'Failed linting:\n\n' + + 'The `type` property is required. It must be the string "module".\n\n' + + 'The package.json file does not conform to the specification at https://origami.ft.com/spec/v2/components/#package-management' + ); + proclaim.calledOnce(console.log); + proclaim.deepStrictEqual( + console.log.lastCall.args, + ["::error file=package.json,line=1,col=1::Failed linting:%0A%0AThe `type` property is required. It must be the string \"module\".%0A%0AThe package.json file does not conform to the specification at https://origami.ft.com/spec/v2/components/#package-management"] + ); + } + + if (!errored) { + proclaim.fail('verifyPackageJson().task() did not return a rejected promise', 'verifyPackageJson().task() should have returned a rejected promise'); + } + }); + }); + + }); + }); });