Skip to content

Commit

Permalink
Improved tests (#130)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
tclindner committed Sep 22, 2019
1 parent d5ff372 commit 13a86b2
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 167 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -8,6 +8,7 @@
[![CircleCI](https://circleci.com/gh/tclindner/npm-package-json-lint.svg?style=svg)](https://circleci.com/gh/tclindner/npm-package-json-lint)
[![Dependency Status](https://david-dm.org/tclindner/npm-package-json-lint.svg?style=flat-square)](https://david-dm.org/tclindner/npm-package-json-lint)
[![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)
[![Netlify Status](https://api.netlify.com/api/v1/badges/e76a30d9-13f0-4691-a49b-454570589de2/deploy-status)](https://app.netlify.com/sites/npmpackagejsonlint/deploys)


## What is npm-package-json-lint?
Expand Down
10 changes: 5 additions & 5 deletions jest.config.js
@@ -1,13 +1,13 @@
module.exports = {
clearMocks: true,
collectCoverage: true,
collectCoverageFrom: ['src/**/*.js'],
collectCoverageFrom: ['src/**/*.js', '!src/cli.js'],
coverageThreshold: {
global: {
branches: 87,
functions: 91,
lines: 92,
statements: 92
branches: 97,
functions: 100,
lines: 99,
statements: 99
}
},
restoreMocks: true,
Expand Down
14 changes: 7 additions & 7 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "npm-package-json-lint",
"version": "4.0.0-beta.2",
"version": "4.0.0-beta.3",
"description": "Configurable linter for package.json files.",
"keywords": [
"lint",
Expand Down Expand Up @@ -35,28 +35,28 @@
"test:ci": "jest --runInBand"
},
"dependencies": {
"ajv": "^6.10.0",
"ajv": "^6.10.2",
"ajv-errors": "^1.0.1",
"chalk": "^2.4.2",
"cosmiconfig": "^5.2.1",
"debug": "^4.1.1",
"globby": "^10.0.1",
"ignore": "^5.1.2",
"ignore": "^5.1.4",
"is-plain-obj": "^2.0.0",
"log-symbols": "^3.0.0",
"meow": "^5.0.0",
"plur": "^3.1.1",
"semver": "^6.1.1",
"semver": "^6.3.0",
"strip-json-comments": "^3.0.1"
},
"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-tc": "^6.5.0",
"eslint-formatter-pretty": "^2.1.1",
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.1",
"figures": "^3.0.0",
"jest": "^24.8.0",
"jest": "^24.9.0",
"npm-package-json-lint-config-default": "^2.0.0",
"npm-package-json-lint-config-tc": "^2.2.0",
"prettier": "^1.18.2"
Expand Down
8 changes: 5 additions & 3 deletions src/Config.js
@@ -1,7 +1,7 @@
const debug = require('debug')('npm-package-json-lint:Config');
const cosmiconfig = require('cosmiconfig');

// const ConfigValidator = require('./config/ConfigValidator');
const configValidator = require('./config/ConfigValidator');
const cosmicConfigTransformer = require('./config/cosmicConfigTransformer');
const applyExtendsIfSpecified = require('./config/applyExtendsIfSpecified');
const applyOverrides = require('./config/applyOverrides');
Expand All @@ -20,15 +20,17 @@ class Config {
* @param {Object} config The user passed config object.
* @param {string} configFile The user passed configFile path.
* @param {string} configBaseDirectory The base directory that config should be pulled from.
* @param {Object} rules Rules object
*/
constructor(cwd, config, configFile, configBaseDirectory) {
constructor(cwd, config, configFile, configBaseDirectory, rules) {
if (config) {
this.config = applyExtendsIfSpecified(config, 'PassedConfig');
}

this.cwd = cwd;
this.configFile = configFile;
this.configBaseDirectory = configBaseDirectory;
this.rules = rules;
this.explorer = cosmiconfig('npmpackagejsonlint', {
transform: cosmicConfigTransformer.transform(cwd, configBaseDirectory)
});
Expand Down Expand Up @@ -77,7 +79,7 @@ class Config {

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

// ConfigValidator.validateRules(config, 'cli', this.linter);
configValidator.validateRules(config, 'cli', this.rules);

return config;
}
Expand Down
8 changes: 2 additions & 6 deletions src/NpmPackageJsonLint.js
Expand Up @@ -100,14 +100,10 @@ class NpmPackageJsonLint {

this.version = pkg.version;

// if (this.options.rules && Object.keys(this.options.rules).length) {
// ConfigValidator.validateRules(this.options.rules, 'cli', this.linter);
// }

this.configHelper = new Config(this.cwd, config, configFile, configBaseDirectory);

this.rules = new Rules();
this.rules.load();

this.configHelper = new Config(this.cwd, config, configFile, configBaseDirectory, this.rules);
}

/**
Expand Down
67 changes: 32 additions & 35 deletions src/config/ConfigValidator.js
Expand Up @@ -106,44 +106,41 @@ const validateRule = (ruleModule, ruleName, userConfig, source) => {
};

/**
* Public ConfigValidator class
* @class
* Validates only the rules of a config object
*
* @param {Object} rulesConfig The rules config object to validate.
* @param {String} source The name of the configuration source to report in any errors.
* @param {Object} rules Rules object
* @returns {undefined} No return
* @static
*/
class ConfigValidator {
/**
* Validates entire config object, including top-level properties.
*
* @param {Object} config The config object to validate.
* @param {String} source The name of the configuration source to report in any errors.
* @param {NpmPackageJsonLint} linterContext Linter context
* @returns {undefined} No return
* @static
*/
static validate(config, source, linterContext) {
ConfigSchema.isConfigObjectSchemaValid(config, source);
ConfigValidator.validateRules(config.rules, source, linterContext);
const validateRules = (rulesConfig, source, rules) => {
if (!rulesConfig) {
return;
}

/**
* Validates only the rules of a config object
*
* @param {Object} rulesConfig The rules config object to validate.
* @param {String} source The name of the configuration source to report in any errors.
* @param {NpmPackageJsonLint} linterContext Linter context
* @returns {undefined} No return
* @static
*/
static validateRules(rulesConfig, source, linterContext) {
if (!rulesConfig) {
return;
}
Object.keys(rulesConfig).forEach(ruleName => {
const ruleModule = rules.get(ruleName);

Object.keys(rulesConfig).forEach(ruleName => {
const ruleModule = linterContext.getRule(ruleName);
validateRule(ruleModule, ruleName, rulesConfig[ruleName], source);
});
};

validateRule(ruleModule, ruleName, rulesConfig[ruleName], source);
});
}
}
/**
* Validates entire config object, including top-level properties.
*
* @param {Object} config The config object to validate.
* @param {String} source The name of the configuration source to report in any errors.
* @param {Object} rules Rules object
* @returns {undefined} No return
* @static
*/
const validate = (config, source, rules) => {
ConfigSchema.isConfigObjectSchemaValid(config, source);
validateRules(config.rules, source, rules);
};

module.exports = ConfigValidator;
module.exports = {
validate,
validateRules
};
6 changes: 6 additions & 0 deletions test/fixtures/extendsLocalInvalid/.npmpackagejsonlintrc.md
@@ -0,0 +1,6 @@
{
"extends": "./npmpackagejsonlint.config.js",
"rules": {
"require-author": "error"
}
}
2 changes: 1 addition & 1 deletion test/unit/cli.test.js → test/integration/cli.test.js 100755 → 100644
Expand Up @@ -38,7 +38,7 @@ const threeRunTimeException = 3;
const {env} = process;
env.FORCE_COLOR = 0;

describe('cli Unit Tests', () => {
describe('cli Integration Tests', () => {
describe('when the help command is run', () => {
const expected = `
Configurable linter for package.json files.
Expand Down
46 changes: 21 additions & 25 deletions test/unit/Config.test.js
Expand Up @@ -2,6 +2,10 @@ const cosmiconfig = require('cosmiconfig');
const Config = require('./../../src/Config');
const applyOverrides = require('../../src/config/applyOverrides');
const applyExtendsIfSpecified = require('../../src/config/applyExtendsIfSpecified');
const Rules = require('../../src/Rules');

const rules = new Rules();
rules.load();

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

const loadSyncMock = jest.fn().mockReturnValue({
rules: {
'require-version': 'error',
'require-name': 'error',
'require-scripts': 'error'
}
'require-version': 'error',
'require-name': 'error',
'require-scripts': 'error'
});
const searchSyncMock = jest.fn();

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

const configObj = new Config(cwd, config, configFile, configBaseDirectory);
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);

const expectedConfigObj = {
rules: {
'require-version': 'error',
'require-name': 'error',
'require-scripts': 'error'
}
'require-version': 'error',
'require-name': 'error',
'require-scripts': 'error'
};
const filePath = './package.json';
const result = configObj.getConfigForFile(filePath);
Expand All @@ -62,11 +62,9 @@ describe('Config Unit Tests', () => {

const loadSyncMock = jest.fn();
const searchSyncMock = jest.fn().mockReturnValue({
rules: {
'require-version': 'error',
'require-name': 'error',
'require-scripts': 'error'
}
'require-version': 'error',
'require-name': 'error',
'require-scripts': 'error'
});

cosmiconfig.mockImplementation(() => {
Expand All @@ -76,14 +74,12 @@ describe('Config Unit Tests', () => {
};
});

const configObj = new Config(cwd, config, configFile, configBaseDirectory);
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);

const expectedConfigObj = {
rules: {
'require-version': 'error',
'require-name': 'error',
'require-scripts': 'error'
}
'require-version': 'error',
'require-name': 'error',
'require-scripts': 'error'
};
const filePath = './package.json';
const result = configObj.getConfigForFile(filePath);
Expand Down Expand Up @@ -114,7 +110,7 @@ describe('Config Unit Tests', () => {
};
});

const configObj = new Config(cwd, config, configFile, configBaseDirectory);
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);

const filePath = './package.json';

Expand All @@ -141,7 +137,7 @@ describe('Config Unit Tests', () => {
};
});

const configObj = new Config(cwd, config, configFile, configBaseDirectory);
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);

const filePath = './package.json';

Expand Down Expand Up @@ -202,7 +198,7 @@ describe('Config Unit Tests', () => {
'require-scripts': 'error'
});

const configObj = new Config(cwd, config, configFile, configBaseDirectory);
const configObj = new Config(cwd, config, configFile, configBaseDirectory, rules);

const expectedConfigObj = {
'require-version': 'error',
Expand Down
9 changes: 9 additions & 0 deletions test/unit/api.test.js
@@ -0,0 +1,9 @@
const api = require('../../src/api');

jest.mock('../../src/NpmPackageJsonLint');

describe('api Unit Tests', () => {
test('NpmPackageJsonLint should be exported', () => {
expect(api).toHaveProperty('NpmPackageJsonLint');
});
});

0 comments on commit 13a86b2

Please sign in to comment.