Skip to content

Commit 13a86b2

Browse files
authored
Improved tests (#130)
* Create cosmicConfigTransformer.test.js * Add config validation * Add test fixtures * Moves cli test to integration tests * Create api.test.js * Add Netlify badge * Up coverage threshold * Improve test coverage * Bump deps * Update cli.test.js
1 parent d5ff372 commit 13a86b2

File tree

13 files changed

+283
-167
lines changed

13 files changed

+283
-167
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
[![CircleCI](https://circleci.com/gh/tclindner/npm-package-json-lint.svg?style=svg)](https://circleci.com/gh/tclindner/npm-package-json-lint)
99
[![Dependency Status](https://david-dm.org/tclindner/npm-package-json-lint.svg?style=flat-square)](https://david-dm.org/tclindner/npm-package-json-lint)
1010
[![devDependency Status](https://david-dm.org/tclindner/npm-package-json-lint/dev-status.svg?style=flat-square)](https://david-dm.org/tclindner/npm-package-json-lint#info=devDependencies)
11+
[![Netlify Status](https://api.netlify.com/api/v1/badges/e76a30d9-13f0-4691-a49b-454570589de2/deploy-status)](https://app.netlify.com/sites/npmpackagejsonlint/deploys)
1112

1213

1314
## What is npm-package-json-lint?

jest.config.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
module.exports = {
22
clearMocks: true,
33
collectCoverage: true,
4-
collectCoverageFrom: ['src/**/*.js'],
4+
collectCoverageFrom: ['src/**/*.js', '!src/cli.js'],
55
coverageThreshold: {
66
global: {
7-
branches: 87,
8-
functions: 91,
9-
lines: 92,
10-
statements: 92
7+
branches: 97,
8+
functions: 100,
9+
lines: 99,
10+
statements: 99
1111
}
1212
},
1313
restoreMocks: true,

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "npm-package-json-lint",
3-
"version": "4.0.0-beta.2",
3+
"version": "4.0.0-beta.3",
44
"description": "Configurable linter for package.json files.",
55
"keywords": [
66
"lint",
@@ -35,28 +35,28 @@
3535
"test:ci": "jest --runInBand"
3636
},
3737
"dependencies": {
38-
"ajv": "^6.10.0",
38+
"ajv": "^6.10.2",
3939
"ajv-errors": "^1.0.1",
4040
"chalk": "^2.4.2",
4141
"cosmiconfig": "^5.2.1",
4242
"debug": "^4.1.1",
4343
"globby": "^10.0.1",
44-
"ignore": "^5.1.2",
44+
"ignore": "^5.1.4",
4545
"is-plain-obj": "^2.0.0",
4646
"log-symbols": "^3.0.0",
4747
"meow": "^5.0.0",
4848
"plur": "^3.1.1",
49-
"semver": "^6.1.1",
49+
"semver": "^6.3.0",
5050
"strip-json-comments": "^3.0.1"
5151
},
5252
"devDependencies": {
5353
"eslint": "^5.16.0",
5454
"eslint-config-tc": "^6.5.0",
5555
"eslint-formatter-pretty": "^2.1.1",
56-
"eslint-plugin-import": "^2.17.3",
57-
"eslint-plugin-prettier": "^3.1.0",
56+
"eslint-plugin-import": "^2.18.2",
57+
"eslint-plugin-prettier": "^3.1.1",
5858
"figures": "^3.0.0",
59-
"jest": "^24.8.0",
59+
"jest": "^24.9.0",
6060
"npm-package-json-lint-config-default": "^2.0.0",
6161
"npm-package-json-lint-config-tc": "^2.2.0",
6262
"prettier": "^1.18.2"

src/Config.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const debug = require('debug')('npm-package-json-lint:Config');
22
const cosmiconfig = require('cosmiconfig');
33

4-
// const ConfigValidator = require('./config/ConfigValidator');
4+
const configValidator = require('./config/ConfigValidator');
55
const cosmicConfigTransformer = require('./config/cosmicConfigTransformer');
66
const applyExtendsIfSpecified = require('./config/applyExtendsIfSpecified');
77
const applyOverrides = require('./config/applyOverrides');
@@ -20,15 +20,17 @@ class Config {
2020
* @param {Object} config The user passed config object.
2121
* @param {string} configFile The user passed configFile path.
2222
* @param {string} configBaseDirectory The base directory that config should be pulled from.
23+
* @param {Object} rules Rules object
2324
*/
24-
constructor(cwd, config, configFile, configBaseDirectory) {
25+
constructor(cwd, config, configFile, configBaseDirectory, rules) {
2526
if (config) {
2627
this.config = applyExtendsIfSpecified(config, 'PassedConfig');
2728
}
2829

2930
this.cwd = cwd;
3031
this.configFile = configFile;
3132
this.configBaseDirectory = configBaseDirectory;
33+
this.rules = rules;
3234
this.explorer = cosmiconfig('npmpackagejsonlint', {
3335
transform: cosmicConfigTransformer.transform(cwd, configBaseDirectory)
3436
});
@@ -77,7 +79,7 @@ class Config {
7779

7880
debug(`Overrides applied for ${filePath}`);
7981

80-
// ConfigValidator.validateRules(config, 'cli', this.linter);
82+
configValidator.validateRules(config, 'cli', this.rules);
8183

8284
return config;
8385
}

src/NpmPackageJsonLint.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,10 @@ class NpmPackageJsonLint {
100100

101101
this.version = pkg.version;
102102

103-
// if (this.options.rules && Object.keys(this.options.rules).length) {
104-
// ConfigValidator.validateRules(this.options.rules, 'cli', this.linter);
105-
// }
106-
107-
this.configHelper = new Config(this.cwd, config, configFile, configBaseDirectory);
108-
109103
this.rules = new Rules();
110104
this.rules.load();
105+
106+
this.configHelper = new Config(this.cwd, config, configFile, configBaseDirectory, this.rules);
111107
}
112108

113109
/**

src/config/ConfigValidator.js

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -106,44 +106,41 @@ const validateRule = (ruleModule, ruleName, userConfig, source) => {
106106
};
107107

108108
/**
109-
* Public ConfigValidator class
110-
* @class
109+
* Validates only the rules of a config object
110+
*
111+
* @param {Object} rulesConfig The rules config object to validate.
112+
* @param {String} source The name of the configuration source to report in any errors.
113+
* @param {Object} rules Rules object
114+
* @returns {undefined} No return
115+
* @static
111116
*/
112-
class ConfigValidator {
113-
/**
114-
* Validates entire config object, including top-level properties.
115-
*
116-
* @param {Object} config The config object to validate.
117-
* @param {String} source The name of the configuration source to report in any errors.
118-
* @param {NpmPackageJsonLint} linterContext Linter context
119-
* @returns {undefined} No return
120-
* @static
121-
*/
122-
static validate(config, source, linterContext) {
123-
ConfigSchema.isConfigObjectSchemaValid(config, source);
124-
ConfigValidator.validateRules(config.rules, source, linterContext);
117+
const validateRules = (rulesConfig, source, rules) => {
118+
if (!rulesConfig) {
119+
return;
125120
}
126121

127-
/**
128-
* Validates only the rules of a config object
129-
*
130-
* @param {Object} rulesConfig The rules config object to validate.
131-
* @param {String} source The name of the configuration source to report in any errors.
132-
* @param {NpmPackageJsonLint} linterContext Linter context
133-
* @returns {undefined} No return
134-
* @static
135-
*/
136-
static validateRules(rulesConfig, source, linterContext) {
137-
if (!rulesConfig) {
138-
return;
139-
}
122+
Object.keys(rulesConfig).forEach(ruleName => {
123+
const ruleModule = rules.get(ruleName);
140124

141-
Object.keys(rulesConfig).forEach(ruleName => {
142-
const ruleModule = linterContext.getRule(ruleName);
125+
validateRule(ruleModule, ruleName, rulesConfig[ruleName], source);
126+
});
127+
};
143128

144-
validateRule(ruleModule, ruleName, rulesConfig[ruleName], source);
145-
});
146-
}
147-
}
129+
/**
130+
* Validates entire config object, including top-level properties.
131+
*
132+
* @param {Object} config The config object to validate.
133+
* @param {String} source The name of the configuration source to report in any errors.
134+
* @param {Object} rules Rules object
135+
* @returns {undefined} No return
136+
* @static
137+
*/
138+
const validate = (config, source, rules) => {
139+
ConfigSchema.isConfigObjectSchemaValid(config, source);
140+
validateRules(config.rules, source, rules);
141+
};
148142

149-
module.exports = ConfigValidator;
143+
module.exports = {
144+
validate,
145+
validateRules
146+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "./npmpackagejsonlint.config.js",
3+
"rules": {
4+
"require-author": "error"
5+
}
6+
}

test/unit/cli.test.js renamed to test/integration/cli.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const threeRunTimeException = 3;
3838
const {env} = process;
3939
env.FORCE_COLOR = 0;
4040

41-
describe('cli Unit Tests', () => {
41+
describe('cli Integration Tests', () => {
4242
describe('when the help command is run', () => {
4343
const expected = `
4444
Configurable linter for package.json files.

test/unit/Config.test.js

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ const cosmiconfig = require('cosmiconfig');
22
const Config = require('./../../src/Config');
33
const applyOverrides = require('../../src/config/applyOverrides');
44
const applyExtendsIfSpecified = require('../../src/config/applyExtendsIfSpecified');
5+
const Rules = require('../../src/Rules');
6+
7+
const rules = new Rules();
8+
rules.load();
59

610
jest.mock('cosmiconfig');
711
jest.mock('../../src/config/applyOverrides');
@@ -17,11 +21,9 @@ describe('Config Unit Tests', () => {
1721
const configBaseDirectory = '';
1822

1923
const loadSyncMock = jest.fn().mockReturnValue({
20-
rules: {
21-
'require-version': 'error',
22-
'require-name': 'error',
23-
'require-scripts': 'error'
24-
}
24+
'require-version': 'error',
25+
'require-name': 'error',
26+
'require-scripts': 'error'
2527
});
2628
const searchSyncMock = jest.fn();
2729

@@ -32,14 +34,12 @@ describe('Config Unit Tests', () => {
3234
};
3335
});
3436

35-
const configObj = new Config(cwd, config, configFile, configBaseDirectory);
37+
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);
3638

3739
const expectedConfigObj = {
38-
rules: {
39-
'require-version': 'error',
40-
'require-name': 'error',
41-
'require-scripts': 'error'
42-
}
40+
'require-version': 'error',
41+
'require-name': 'error',
42+
'require-scripts': 'error'
4343
};
4444
const filePath = './package.json';
4545
const result = configObj.getConfigForFile(filePath);
@@ -62,11 +62,9 @@ describe('Config Unit Tests', () => {
6262

6363
const loadSyncMock = jest.fn();
6464
const searchSyncMock = jest.fn().mockReturnValue({
65-
rules: {
66-
'require-version': 'error',
67-
'require-name': 'error',
68-
'require-scripts': 'error'
69-
}
65+
'require-version': 'error',
66+
'require-name': 'error',
67+
'require-scripts': 'error'
7068
});
7169

7270
cosmiconfig.mockImplementation(() => {
@@ -76,14 +74,12 @@ describe('Config Unit Tests', () => {
7674
};
7775
});
7876

79-
const configObj = new Config(cwd, config, configFile, configBaseDirectory);
77+
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);
8078

8179
const expectedConfigObj = {
82-
rules: {
83-
'require-version': 'error',
84-
'require-name': 'error',
85-
'require-scripts': 'error'
86-
}
80+
'require-version': 'error',
81+
'require-name': 'error',
82+
'require-scripts': 'error'
8783
};
8884
const filePath = './package.json';
8985
const result = configObj.getConfigForFile(filePath);
@@ -114,7 +110,7 @@ describe('Config Unit Tests', () => {
114110
};
115111
});
116112

117-
const configObj = new Config(cwd, config, configFile, configBaseDirectory);
113+
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);
118114

119115
const filePath = './package.json';
120116

@@ -141,7 +137,7 @@ describe('Config Unit Tests', () => {
141137
};
142138
});
143139

144-
const configObj = new Config(cwd, config, configFile, configBaseDirectory);
140+
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);
145141

146142
const filePath = './package.json';
147143

@@ -202,7 +198,7 @@ describe('Config Unit Tests', () => {
202198
'require-scripts': 'error'
203199
});
204200

205-
const configObj = new Config(cwd, config, configFile, configBaseDirectory);
201+
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);
206202

207203
const expectedConfigObj = {
208204
'require-version': 'error',

test/unit/api.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const api = require('../../src/api');
2+
3+
jest.mock('../../src/NpmPackageJsonLint');
4+
5+
describe('api Unit Tests', () => {
6+
test('NpmPackageJsonLint should be exported', () => {
7+
expect(api).toHaveProperty('NpmPackageJsonLint');
8+
});
9+
});

0 commit comments

Comments
 (0)