Skip to content

Commit

Permalink
feat: Added lint command to validate extension source
Browse files Browse the repository at this point in the history
  • Loading branch information
kumar303 committed Jul 20, 2016
1 parent b08de56 commit fb5b974
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"opera"
],
"dependencies": {
"addons-linter": "0.14.0",
"babel-polyfill": "6.9.1",
"bunyan": "1.8.1",
"debounce": "1.0.0",
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* @flow */
import build from './build';
import lint from './lint';
import run from './run';
import sign from './sign';
export default {build, run, sign};
export default {build, lint, run, sign};
28 changes: 28 additions & 0 deletions src/cmd/lint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* @flow */
import {createLinter as defaultLinterCreator} from '../util/es6-modules';
import {createLogger} from '../util/logger';

const log = createLogger(__filename);

export default function lint(
{verbose, sourceDir, selfHosted, boring, output,
metadata, pretty}: Object,
{createLinter=defaultLinterCreator}: Object): Promise {
log.debug(`Running addons-linter on ${sourceDir}`);
const linter = createLinter({
config: {
logLevel: verbose ? 'debug' : 'fatal',
stack: Boolean(verbose),
pretty,
metadata,
output,
boring,
selfHosted,
// This mimics the first command line argument from yargs,
// which should be the directory to the extension.
_: [sourceDir],
},
runAsBinary: true,
});
return linter.run();
}
31 changes: 31 additions & 0 deletions src/program.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,37 @@ Example: $0 --help run.
demand: false,
type: 'boolean',
},
})
.command('lint', 'Validate the web extension source', commands.lint, {
'output': {
alias: 'o',
describe: 'The type of output to generate',
type: 'string',
default: 'text',
choices: ['json', 'text'],
},
'metadata': {
describe: 'Output only metadata as JSON',
type: 'boolean',
default: false,
},
'pretty': {
describe: 'Prettify JSON output',
type: 'boolean',
default: false,
},
'self-hosted': {
describe:
'Your extension will be self-hosted. This disables messages ' +
'related to hosting on addons.mozilla.org.',
type: 'boolean',
default: false,
},
'boring': {
describe: 'Disables colorful shell output',
type: 'boolean',
default: false,
},
});

return program.run(absolutePackageDir, runOptions);
Expand Down
7 changes: 3 additions & 4 deletions src/util/es6-modules.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/*
* This is a terrible and sad place that will hopefully cease to exist soon.
*
* It is a workaround for:
* Flow does not validate any of these imports. This is a workaround for:
* https://github.com/facebook/flow/issues/1448
*/
import ExtendableError from 'es6-error';
import promisify from 'es6-promisify';
import signAddon from 'sign-addon';
import {createInstance as createLinter} from 'addons-linter';

export {promisify, ExtendableError, signAddon};
export {promisify, ExtendableError, signAddon, createLinter};
102 changes: 102 additions & 0 deletions tests/test-cmd/test.lint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* @flow */
import {it, describe} from 'mocha';
import {assert} from 'chai';
import sinon from 'sinon';

import defaultLintCommand from '../../src/cmd/lint';
import {makeSureItFails} from '../helpers';

describe('lint', () => {

function setUp({createLinter} = {}) {
const lintResult = '<lint.run() result placeholder>';
const runLinter = sinon.spy(() => Promise.resolve(lintResult));
if (!createLinter) {
createLinter = sinon.spy(() => {
return {run: runLinter};
});
}
return {
lintResult,
createLinter,
runLinter,
lint: ({...args}) => {
return defaultLintCommand(args, {createLinter});
},
};
}

it('creates and runs a linter', () => {
const {lint, createLinter, runLinter, lintResult} = setUp();
return lint().then((actualLintResult) => {
assert.equal(actualLintResult, lintResult);
assert.equal(createLinter.called, true);
assert.equal(runLinter.called, true);
});
});

it('fails when the linter fails', () => {
const createLinter = () => {
return {
run: () => Promise.reject(new Error('some error from the linter')),
};
};
const {lint} = setUp({createLinter});
return lint().then(makeSureItFails(), (error) => {
assert.match(error.message, /error from the linter/);
});
});

it('runs as a binary', () => {
const {lint, createLinter} = setUp();
return lint().then(() => {
const args = createLinter.firstCall.args[0];
assert.equal(args.runAsBinary, true);
});
});

it('passes sourceDir to the linter', () => {
const {lint, createLinter} = setUp();
return lint({sourceDir: '/some/path'}).then(() => {
const config = createLinter.firstCall.args[0].config;
assert.equal(config._[0], '/some/path');
});
});

it('configures the linter when verbose', () => {
const {lint, createLinter} = setUp();
return lint({verbose: true}).then(() => {
const config = createLinter.firstCall.args[0].config;
assert.equal(config.logLevel, 'debug');
assert.equal(config.stack, true);
});
});

it('configures the linter when not verbose', () => {
const {lint, createLinter} = setUp();
return lint({verbose: false}).then(() => {
const config = createLinter.firstCall.args[0].config;
assert.equal(config.logLevel, 'fatal');
assert.equal(config.stack, false);
});
});

it('passes through linter configuration', () => {
const {lint, createLinter} = setUp();
return lint({
pretty: 'pretty flag',
metadata: 'metadata flag',
output: 'output value',
boring: 'boring flag',
selfHosted: 'self-hosted flag',
}).then(() => {
const config = createLinter.firstCall.args[0].config;
assert.equal(config.pretty, 'pretty flag');
assert.equal(config.metadata, 'metadata flag');
assert.equal(config.output, 'output value');
assert.equal(config.boring, 'boring flag');
assert.equal(config.selfHosted, 'self-hosted flag');
});
});

});

0 comments on commit fb5b974

Please sign in to comment.