Change validator to linter (fix #397)

This commit is contained in:
Matthew Riley MacPherson 2015-12-11 14:36:42 -05:00
Родитель 0aa60ad93a
Коммит 071d2b5540
31 изменённых файлов: 404 добавлений и 405 удалений

Просмотреть файл

@ -19,7 +19,7 @@ deploy:
secure: bVMeDrmxJB7QajecwgqoKlIfdduwUv+qqGrv1ucD9IS9aD2fFUljMruzVxzYzJLgdz1anWHEeuLsVZ4KbCgp8axa/PHKjVOhqglRXvgJezE+d4DuVtbBOXAD4JV+F8DA75ZLCe+sZm94lFa4MKnUiyvwR/v2yyNMQWJL/pZRv87yx/G1i3yBuMzhFaj51DQSWreXyxq+mI5TLvLoWO9jzXtFOCynq+ufFhWw7pUz3/eqwp1VD9YIuUxLsT9U0KJHF4E5flhWl3tq9OYM3k26qs0m7BUYZ5O1dSnXQsODlbSe1PnRs6o1Mex/ZYdN56CdP4+32o1seGWbWHQRzvQuHSR29opqPORuKcyDAbXeUhyoo1V6zguKbXb7++9iSq0CiKLSHMzeuTco7bdpeOZYnWSH1mBi/QMUIg2dp7+0fpRTuBp7+rY2xFzqoRGg16fLotVkZDBwlXkxRTatM0QVvvscAmksPBIZI8xmB2+B0RNLcwBTuQKVeQ7988Bw1oZ94rhIhfKljbhnIzU11Y1sexmV/UzXxiFs/L6wbFr0fI7BTBrfdXAIMWaGQ9uwBCRn2EH9fLx3B3LoEXe7eL84jLgdOgRzR6eQTlkDpwvh9Jf3fbcv1S89pWpwt2CgxtofY/wMO3WpRW6e5fqo83rKwmuAzDuqzRjl+vvoc4IR5yE=
on:
tags: true
repo: mozilla/addons-validator
repo: mozilla/addons-linter
branch: master
after_success: npm run-script publish-rules > /dev/null 2>&1
env:

Просмотреть файл

@ -1,4 +1,4 @@
Thanks for wanting to contribute to Mozilla's Add-ons Validator! You rock! 😊
Thanks for wanting to contribute to Mozilla's Add-ons Linter! You rock! 😊
## Submitting a Pull Request
@ -18,5 +18,5 @@ consistent. You can review the rules in the [`.eslintrc`][eslint] and
Please run the tests locally with `npm test` before you commit.
[eslint]: https://github.com/mozilla/addons-validator/blob/master/.eslintrc
[jscsrc]: https://github.com/mozilla/addons-validator/blob/master/.jscsrc
[eslint]: https://github.com/mozilla/addons-linter/blob/master/.eslintrc
[jscsrc]: https://github.com/mozilla/addons-linter/blob/master/.jscsrc

Просмотреть файл

@ -1,53 +1,53 @@
[![Build Status](https://travis-ci.org/mozilla/addons-validator.svg?branch=master)](https://travis-ci.org/mozilla/addons-validator)
[![Coverage Status](https://coveralls.io/repos/mozilla/addons-validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/mozilla/addons-validator?branch=master)
[![Dependency Status](https://david-dm.org/mozilla/addons-validator.svg)](https://david-dm.org/mozilla/addons-validator)
[![devDependency Status](https://david-dm.org/mozilla/addons-validator/dev-status.svg)](https://david-dm.org/mozilla/addons-validator#info=devDependencies)
[![npm version](https://badge.fury.io/js/addons-validator.svg)](https://badge.fury.io/js/addons-validator)
[![Build Status](https://travis-ci.org/mozilla/addons-linter.svg?branch=master)](https://travis-ci.org/mozilla/addons-linter)
[![Coverage Status](https://coveralls.io/repos/mozilla/addons-linter/badge.svg?branch=master&service=github)](https://coveralls.io/github/mozilla/addons-linter?branch=master)
[![Dependency Status](https://david-dm.org/mozilla/addons-linter.svg)](https://david-dm.org/mozilla/addons-linter)
[![devDependency Status](https://david-dm.org/mozilla/addons-linter/dev-status.svg)](https://david-dm.org/mozilla/addons-linter#info=devDependencies)
[![npm version](https://badge.fury.io/js/addons-linter.svg)](https://badge.fury.io/js/addons-linter)
# addons-validator
# addons-linter
The Add-ons Validator, JS edition.
The Add-ons Linter, JS edition.
Here is the [canonical list of rules](http://mozilla.github.io/addons-validator/) we're working from.
Here is the [canonical list of rules](http://mozilla.github.io/addons-linter/) we're working from.
## Usage
### Command Line
You need node.js to use the add-ons validator.
You need node.js to use the add-ons linter.
To validate your add-on locally, install the validator from
To validate your add-on locally, install the linter from
[npm](http://nodejs.org/):
```
# Install globally so you can use the validator from any directory on
# Install globally so you can use the linter from any directory on
# your machine.
npm install -g addons-validator
npm install -g addons-linter
```
After installation, run the validator and direct it to your add-on file:
After installation, run the linter and direct it to your add-on file:
```
addons-validator my-addon.xpi
addons-linter my-addon.xpi
```
Alternatively you can point it at a directory:
```
addons-validator my/package/dir
addons-linter my/package/dir
```
The addons-validator will check your add-on and show you errors, warnings,
The addons-linter will check your add-on and show you errors, warnings,
and friendly messages for your add-on. If you want more info on the options
you can enable/disable for the command-line app, use the `--help` option:
```
addons-validator --help
addons-linter --help
```
## Development
If you'd like to help us develop the addons-validator, that's great! It's
If you'd like to help us develop the addons-linter, that's great! It's
pretty easy to get started, you just need node.js installed on your machine.
### Quick Start
@ -56,17 +56,17 @@ If you have node.js installed, here's the quick start to getting
your development dependencies installed and building the binary:
```
git clone https://github.com/mozilla/addons-validator.git
cd addons-validator
git clone https://github.com/mozilla/addons-linter.git
cd addons-linter
npm install
npm start
# Leave running to watch for changes or cancel to stop watching.
bin/addons-validator my-addon.xpi
bin/addons-linter my-addon.xpi
```
### Required node version
addons-validator requires node.js v0.12.x or greater. Using nvm is probably the
addons-linter requires node.js v0.12.x or greater. Using nvm is probably the
easiest way to manage multiple node versions side by side. See
[nvm on github](https://github.com/creationix/nvm) for more details.
@ -121,7 +121,7 @@ From the grunt docs:
You can run `npm start` to build the library and then rebuild on file changes.
Once you build the library you can use the CLI in `bin/addons-validator`.
Once you build the library you can use the CLI in `bin/addons-linter`.
### Testing
@ -183,11 +183,11 @@ We use [bunyan](https://github.com/trentm/node-bunyan) for logging:
## Architecture
In a nutshell the way the validator works is to take an add-on
In a nutshell the way the linter works is to take an add-on
package, extract the metadata from the xpi (zip) format and then
process the files it finds through various content scanners.
![Architecture diagram](https://raw.github.com/mozilla/addons-validator/master/docs/diagrams/addon-validator-flow.png)
![Architecture diagram](https://raw.github.com/mozilla/addons-linter/master/docs/diagrams/addon-linter-flow.png)
### Scanners
@ -221,7 +221,7 @@ same message could be an error *or* a warning for example.
### Output
Lastly when the processing is complete the validator will output
Lastly when the processing is complete the linter will output
the collected data as text or JSON.
## Deploys
@ -233,5 +233,5 @@ version number conforms to the [semver][] format eg: `0.2.1`.
After merging the PR, [create a new release][new release] with the same tag
name as your new version. Once the build passes it will deploy. Magic! ✨
[new release]: https://github.com/mozilla/addons-validator/releases/new
[new release]: https://github.com/mozilla/addons-linter/releases/new
[semver]: http://semver.org/

Просмотреть файл

@ -2,5 +2,5 @@
var path = require('path');
var AddonValidator = require('../dist/addons-validator').createInstance();
AddonValidator.run();
var AddonLinter = require('../dist/addons-linter').createInstance();
AddonLinter.run();

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 53 KiB

После

Ширина:  |  Высота:  |  Размер: 53 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 26 KiB

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Просмотреть файл

@ -1,5 +1,5 @@
# Validator Rules
# Linter Rules
This document is automatically published on [github pages](http://mozilla.github.io/addons-validator/).
To update it edit `docs/rules.md` in the

Просмотреть файл

@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<title>Validator Rules</title>
<title>Linter Rules</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="gfm.css">
</head>

Просмотреть файл

@ -1,10 +1,10 @@
{
"name": "addons-validator",
"version": "0.0.8",
"description": "Mozilla addons validator",
"main": "dist/addons-validator.js",
"name": "addons-linter",
"version": "0.0.9",
"description": "Mozilla Add-ons Linter",
"main": "dist/addons-linter.js",
"bin": {
"addons-validator": "bin/addons-validator"
"addons-linter": "bin/addons-linter"
},
"scripts": {
"start": "node -e \"require('grunt').cli()\" null start",
@ -14,14 +14,14 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/mozilla/addons-validator.git"
"url": "git+https://github.com/mozilla/addons-linter.git"
},
"author": "Mozilla Add-ons Team",
"license": "MPL-2.0",
"bugs": {
"url": "https://github.com/mozilla/addons-validator/issues"
"url": "https://github.com/mozilla/addons-linter/issues"
},
"homepage": "https://github.com/mozilla/addons-validator#readme",
"homepage": "https://github.com/mozilla/addons-linter#readme",
"devDependencies": {
"babel-core": "5.8.34",
"babel-eslint": "4.1.6",

Просмотреть файл

@ -19,7 +19,7 @@ export function terminalWidth(_process=process) {
export default argv
.usage('Usage: ./$0 [options] addon-package-or-dir \n\n' +
'Add-ons Validator (JS Edition) v' + version)
'Add-ons Linter (JS Edition) v' + version)
.option('log-level', {
describe: 'The log-level to generate',
type: 'string',

Просмотреть файл

@ -25,7 +25,7 @@ import RDFScanner from 'scanners/rdf';
import { Directory, Xpi } from 'io';
export default class Validator {
export default class Linter {
constructor(config) {
this.config = config;

Просмотреть файл

@ -8,7 +8,7 @@ export function createLogger(_process=process) {
throw new Error(`LOG_LEVEL must be one of ${logLevels.join(', ')}`);
}
return bunyan.createLogger({
name: 'AddonValidatorJS',
name: 'AddonLinterJS',
stream: process.stdout,
level: level,
});

Просмотреть файл

@ -1,11 +1,11 @@
import cli from 'cli';
import Validator from 'validator';
import Linter from 'linter';
import log from 'logger';
import 'babel-core/polyfill';
export function createInstance(config=cli.argv) {
log.level(config.logLevel);
log.info('Creating new validator instance', { config: config });
return new Validator(config);
log.info('Creating new linter instance', { config: config });
return new Linter(config);
}

Просмотреть файл

@ -4,27 +4,27 @@ import * as messages from 'messages';
export function ensureRequiredAttributes($, filename) {
return new Promise((resolve) => {
var validatorMessages = [];
var linterMessages = [];
for (let tag in HTML_TAGS_WITH_REQUIRED_ATTRIBUTES) {
validatorMessages = validatorMessages.concat(
linterMessages = linterMessages.concat(
_ensureAttributesInTag($, tag, HTML_TAGS_WITH_REQUIRED_ATTRIBUTES[tag],
filename));
}
resolve(validatorMessages);
resolve(linterMessages);
});
}
export function _ensureAttributesInTag($, tag, attributes, filename) {
var validatorMessages = [];
var linterMessages = [];
$(tag).each((i, element) => {
for (let attributeName of attributes) {
var errorCode = `${tag}_REQUIRES_${attributeName}`.toUpperCase();
if ($(element).attr(attributeName) === undefined) {
validatorMessages.push({
linterMessages.push({
code: errorCode,
message: messages[errorCode].message,
description: messages[errorCode].description,
@ -36,5 +36,5 @@ export function _ensureAttributesInTag($, tag, attributes, filename) {
}
});
return validatorMessages;
return linterMessages;
}

Просмотреть файл

@ -6,7 +6,7 @@ import * as messages from 'messages';
export function mustNotExist(xmlDoc, filename, {namespace}={}) {
return new Promise((resolve) => {
var bannedTags = RDF_UNALLOWED_TAGS;
var validatorMessages = [];
var linterMessages = [];
var addonIsListed = xmlDoc
.getElementsByTagNameNS(namespace, 'listed').length > 0;
@ -16,7 +16,7 @@ export function mustNotExist(xmlDoc, filename, {namespace}={}) {
}
// Using any banned tag is an error.
validatorMessages = validatorMessages.concat(
linterMessages = linterMessages.concat(
_checkForTags({
xmlDoc: xmlDoc,
namespace: namespace,
@ -28,7 +28,7 @@ export function mustNotExist(xmlDoc, filename, {namespace}={}) {
);
// But using an obsolete tag is just a warning.
validatorMessages = validatorMessages.concat(
linterMessages = linterMessages.concat(
_checkForTags({
xmlDoc: xmlDoc,
namespace: namespace,
@ -39,13 +39,13 @@ export function mustNotExist(xmlDoc, filename, {namespace}={}) {
})
);
resolve(validatorMessages);
resolve(linterMessages);
});
}
export function _checkForTags({xmlDoc, namespace, tags, type, prefix,
filename} = {}) { // jscs:ignore
var validatorMessages = [];
var linterMessages = [];
for (let tag of tags) {
let nodeList = xmlDoc.getElementsByTagNameNS(namespace, tag);
@ -54,7 +54,7 @@ export function _checkForTags({xmlDoc, namespace, tags, type, prefix,
let element = nodeList.item(i);
let errorCode = `${prefix}${tag.toUpperCase()}`;
validatorMessages.push({
linterMessages.push({
code: errorCode,
message: messages[errorCode].message,
description: messages[errorCode].description,
@ -67,5 +67,5 @@ export function _checkForTags({xmlDoc, namespace, tags, type, prefix,
}
}
return validatorMessages;
return linterMessages;
}

Просмотреть файл

@ -8,7 +8,7 @@ export default class BaseScanner {
this.contents = contents;
this.filename = filename;
this.options = options;
this.validatorMessages = [];
this.linterMessages = [];
this._defaultRules = [];
this._parsedContent = null;
this._rulesProcessed = 0;
@ -24,7 +24,7 @@ export default class BaseScanner {
// Ignore private functions exported in rule files.
//
// (These are exported for testing purposes, but we don't want
// to include them in our validator's rules.)
// to include them in our linter's rules.)
var rules = ignorePrivateFunctions(_rules);
for (let rule in rules) {
@ -38,10 +38,10 @@ export default class BaseScanner {
})
.then((ruleResults) => {
for (let messages of ruleResults) {
this.validatorMessages = this.validatorMessages.concat(messages);
this.linterMessages = this.linterMessages.concat(messages);
}
resolve(this.validatorMessages);
resolve(this.linterMessages);
})
.catch(reject);
});

Просмотреть файл

@ -46,7 +46,7 @@ export default class CSSScanner extends BaseScanner {
log.debug('Passing CSS code to rule function "%s"',
cssInstruction, info);
this.validatorMessages = this.validatorMessages.concat(
this.linterMessages = this.linterMessages.concat(
_rules[cssInstruction](cssNode, file, cssOptions));
}
@ -66,7 +66,7 @@ export default class CSSScanner extends BaseScanner {
}
}
resolve(this.validatorMessages);
resolve(this.linterMessages);
})
.catch(reject);
});
@ -81,7 +81,7 @@ export default class CSSScanner extends BaseScanner {
if (!e.reason || e instanceof Error === false) {
return reject(e);
} else {
this.validatorMessages.push(Object.assign({}, CSS_SYNTAX_ERROR, {
this.linterMessages.push(Object.assign({}, CSS_SYNTAX_ERROR, {
type: VALIDATION_ERROR,
// Use the reason for the error as the message.
// e.message includes an absolute path.

Просмотреть файл

@ -15,7 +15,7 @@ export default class JavaScriptScanner {
this.code = code;
this.filename = filename;
this.options = options;
this.validatorMessages = [];
this.linterMessages = [];
this._rulesProcessed = 0;
ensureFilenameExists(this.filename);
@ -65,7 +65,7 @@ export default class JavaScriptScanner {
var messageObj = _messages[message.message];
var code = message.message;
this.validatorMessages.push({
this.linterMessages.push({
code: code,
column: message.column,
description: messageObj.description,
@ -77,7 +77,7 @@ export default class JavaScriptScanner {
});
}
resolve(this.validatorMessages);
resolve(this.linterMessages);
});
}
}

Просмотреть файл

@ -23,12 +23,12 @@ module.exports = {
// travis logs. See https://github.com/tschaub/grunt-gh-pages#optionssilent
silent: true,
base: 'docs/html',
repo: 'git@github.com:mozilla/addons-validator.git',
repo: 'git@github.com:mozilla/addons-linter.git',
user: {
name: process.env.GH_USER,
email: process.env.GH_EMAIL,
},
repo: 'https://' + process.env.GH_TOKEN + '@github.com/mozilla/addons-validator.git', // eslint-disable-line
repo: 'https://' + process.env.GH_TOKEN + '@github.com/mozilla/addons-linter.git', // eslint-disable-line
message: 'Publish rules (auto)' + getDeployMessage(),
},
src: ['**'],

4
tests/fixtures/jslibs/angular-1.2.28.min.js поставляемый
Просмотреть файл

@ -134,8 +134,8 @@ b.length+a,e=b.length);for(;d<e;d++)c.push(b[d]);return c}}function Kc(b){return
if(""===a)return e(function(a,b){return f(a,b)},c);d=b(a);if(d.constant){var m=d();return e(function(a,b){return f(a[m],b[m])},c)}}return e(function(a,b){return f(d(a),d(b))},c)});return wa.call(a).sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(0!==e)return e}return 0},d))}}function Aa(b){N(b)&&(b={link:b});b.restrict=b.restrict||"AC";return aa(b)}function Nc(b,a,c,d){function e(a,c){c=c?"-"+nb(c,"-"):"";d.setClass(b,(a?wb:xb)+c,(a?xb:wb)+c)}var f=this,g=b.parent().controller("form")||
yb,h=0,k=f.$error={},m=[];f.$name=a.name||a.ngForm;f.$dirty=!1;f.$pristine=!0;f.$valid=!0;f.$invalid=!1;g.$addControl(f);b.addClass(Ra);e(!0);f.$addControl=function(a){Ea(a.$name,"input");m.push(a);a.$name&&(f[a.$name]=a)};f.$removeControl=function(a){a.$name&&f[a.$name]===a&&delete f[a.$name];r(k,function(b,c){f.$setValidity(c,!0,a)});Ua(m,a)};f.$setValidity=function(a,b,c){var d=k[a];if(b)d&&(Ua(d,c),d.length||(h--,h||(e(b),f.$valid=!0,f.$invalid=!1),k[a]=!1,e(!0,a),g.$setValidity(a,!0,f)));else{h||
e(b);if(d){if(-1!=Ta(d,c))return}else k[a]=d=[],h++,e(!1,a),g.$setValidity(a,!1,f);d.push(c);f.$valid=!1;f.$invalid=!0}};f.$setDirty=function(){d.removeClass(b,Ra);d.addClass(b,zb);f.$dirty=!0;f.$pristine=!1;g.$setDirty()};f.$setPristine=function(){d.removeClass(b,zb);d.addClass(b,Ra);f.$dirty=!1;f.$pristine=!0;r(m,function(a){a.$setPristine()})}}function ua(b,a,c,d){b.$setValidity(a,c);return c?d:u}function Oc(b,a){var c,d;if(a)for(c=0;c<a.length;++c)if(d=a[c],b[d])return!0;return!1}function Ne(b,
a,c,d,e){T(e)&&(b.$$hasNativeValidators=!0,b.$parsers.push(function(f){if(b.$error[a]||Oc(e,d)||!Oc(e,c))return f;b.$setValidity(a,!1)}))}function Ab(b,a,c,d,e,f){var g=a.prop(Oe),h=a[0].placeholder,k={},m=x(a[0].type);d.$$validityState=g;if(!e.android){var l=!1;a.on("compositionstart",function(a){l=!0});a.on("compositionend",function(){l=!1;n()})}var n=function(e){if(!l){var f=a.val();if(R&&"input"===(e||k).type&&a[0].placeholder!==h)h=a[0].placeholder;else if("password"!==m&&Wa(c.ngTrim||"T")&&
(f=$(f)),e=g&&d.$$hasNativeValidators,d.$viewValue!==f||""===f&&e)b.$root.$$phase?d.$setViewValue(f):b.$apply(function(){d.$setViewValue(f)})}};if(e.hasEvent("input"))a.on("input",n);else{var q,p=function(){q||(q=f.defer(function(){n();q=null}))};a.on("keydown",function(a){a=a.keyCode;91===a||(15<a&&19>a||37<=a&&40>=a)||p()});if(e.hasEvent("paste"))a.on("paste cut",p)}a.on("change",n);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var s=c.ngPattern;s&&((e=s.match(/^\/(.*)\/([gim]*)$/))?
a,c,d,e){T(e)&&(b.$$hasNativeLinters=!0,b.$parsers.push(function(f){if(b.$error[a]||Oc(e,d)||!Oc(e,c))return f;b.$setValidity(a,!1)}))}function Ab(b,a,c,d,e,f){var g=a.prop(Oe),h=a[0].placeholder,k={},m=x(a[0].type);d.$$validityState=g;if(!e.android){var l=!1;a.on("compositionstart",function(a){l=!0});a.on("compositionend",function(){l=!1;n()})}var n=function(e){if(!l){var f=a.val();if(R&&"input"===(e||k).type&&a[0].placeholder!==h)h=a[0].placeholder;else if("password"!==m&&Wa(c.ngTrim||"T")&&
(f=$(f)),e=g&&d.$$hasNativeLinters,d.$viewValue!==f||""===f&&e)b.$root.$$phase?d.$setViewValue(f):b.$apply(function(){d.$setViewValue(f)})}};if(e.hasEvent("input"))a.on("input",n);else{var q,p=function(){q||(q=f.defer(function(){n();q=null}))};a.on("keydown",function(a){a=a.keyCode;91===a||(15<a&&19>a||37<=a&&40>=a)||p()});if(e.hasEvent("paste"))a.on("paste cut",p)}a.on("change",n);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var s=c.ngPattern;s&&((e=s.match(/^\/(.*)\/([gim]*)$/))?
(s=RegExp(e[1],e[2]),e=function(a){return ua(d,"pattern",d.$isEmpty(a)||s.test(a),a)}):e=function(c){var e=b.$eval(s);if(!e||!e.test)throw z("ngPattern")("noregexp",s,e,ia(a));return ua(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var r=U(c.ngMinlength);e=function(a){return ua(d,"minlength",d.$isEmpty(a)||a.length>=r,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var w=U(c.ngMaxlength);e=function(a){return ua(d,"maxlength",d.$isEmpty(a)||
a.length<=w,a)};d.$parsers.push(e);d.$formatters.push(e)}}function Wb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;d<a.length;d++){for(var e=a[d],l=0;l<b.length;l++)if(e==b[l])continue a;c.push(e)}return c}function e(a){if(!L(a)){if(G(a))return a.split(" ");if(T(a)){var b=[];r(a,function(a,c){a&&(b=b.concat(c.split(" ")))});return b}}return a}return{restrict:"AC",link:function(f,g,h){function k(a,b){var c=g.data("$classCounts")||{},d=[];r(a,function(a){if(0<
b||c[a])c[a]=(c[a]||0)+b,c[a]===+(0<b)&&d.push(a)});g.data("$classCounts",c);return d.join(" ")}function m(b){if(!0===a||f.$index%2===a){var m=e(b||[]);if(!l){var p=k(m,1);h.$addClass(p)}else if(!Ca(b,l)){var s=e(l),p=d(m,s),m=d(s,m),m=k(m,-1),p=k(p,1);0===p.length?c.removeClass(g,m):0===m.length?c.addClass(g,p):c.setClass(g,p,m)}}l=ha(b)}var l;f.$watch(h[b],m,!0);h.$observe("class",function(a){m(f.$eval(h[b]))});"ngClass"!==b&&f.$watch("$index",function(c,d){var g=c&1;if(g!==(d&1)){var l=e(f.$eval(h[b]));

Просмотреть файл

@ -1,7 +1,7 @@
import { INSTALL_RDF } from 'const';
import RDFScanner from 'scanners/rdf';
import InstallRdfParser from 'parsers/installrdf';
import Validator from 'validator';
import Linter from 'linter';
import * as messages from 'messages';
import * as constants from 'const';
@ -13,13 +13,13 @@ import { unexpectedSuccess, validRDF } from '../helpers';
describe('InstallRdfParser._getAddonType()', function() {
it('should reject on multiple em:type nodes', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var rdf = validRDF('<em:type>2</em:type><em:type>2</em:type>');
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getAddonType();
})
.then(unexpectedSuccess)
@ -29,30 +29,30 @@ describe('InstallRdfParser._getAddonType()', function() {
});
it('should collect an error on invalid type value', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var rdf = validRDF('<em:type>whatevs</em:type>');
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getAddonType();
})
.then(() => {
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.RDF_TYPE_INVALID.code);
});
});
it('should resolve with mapped type value', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var rdf = validRDF('<em:type>2</em:type>');
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getAddonType();
})
.then((type) => {
@ -62,13 +62,13 @@ describe('InstallRdfParser._getAddonType()', function() {
});
it('should resolve with mapped type value for experiments', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var rdf = validRDF('<em:type>128</em:type>');
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getAddonType();
})
.then((type) => {
@ -78,18 +78,18 @@ describe('InstallRdfParser._getAddonType()', function() {
});
it('should collect a notice if type is missing', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
// Specifying a different tag e.g. not <em:type>.
var rdf = validRDF('<em:name>whatevs</em:name>');
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getAddonType();
})
.then(() => {
var notices = addonValidator.collector.notices;
var notices = addonLinter.collector.notices;
assert.equal(notices.length, 1);
assert.equal(notices[0].code, messages.RDF_TYPE_MISSING.code);
});
@ -112,17 +112,17 @@ describe('InstallRdfParser._getVersion()', function() {
});
it('should collect an error if version is missing', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var rdf = validRDF('<em:version></em:version>');
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getVersion();
})
.then(() => {
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.RDF_VERSION_MISSING.code);
});
@ -145,17 +145,17 @@ describe('InstallRdfParser._getName()', function() {
});
it('should collect an error if name is missing', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var rdf = validRDF('<em:type>1</em:type>');
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getName();
})
.then(() => {
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.RDF_NAME_MISSING.code);
});
@ -179,13 +179,13 @@ describe('InstallRdfParser._getGUID()', function() {
});
it('should return null for guid if not defined', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var rdf = validRDF('<em:type>1</em:type>');
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getGUID();
})
.then((guid) => {
@ -208,18 +208,18 @@ describe('InstallRdfParser._getGUID()', function() {
});
it('should collect an error if top-level GUID is too long', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var longGUID = 'a'.repeat(256);
var rdf = validRDF(`<em:id>${longGUID}</em:id>`);
var rdfScanner = new RDFScanner(rdf, INSTALL_RDF);
return rdfScanner.getContents()
.then((xmlDoc) => {
var installRdfParser = new InstallRdfParser(xmlDoc,
addonValidator.collector);
addonLinter.collector);
return installRdfParser._getGUID();
})
.then((guid) => {
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(guid, longGUID);
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.RDF_GUID_TOO_LONG.code);

Просмотреть файл

@ -1,5 +1,5 @@
import ManifestJSONParser from 'parsers/manifestjson';
import Validator from 'validator';
import Linter from 'linter';
import * as messages from 'messages';
import { PACKAGE_EXTENSION, VALID_MANIFEST_VERSION } from 'const';
@ -10,34 +10,34 @@ import { validManifestJSON } from '../helpers';
describe('ManifestJSONParser._getManifestVersion()', function() {
it('should collect an error on invalid manifest_version value', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var json = validManifestJSON({manifest_version: 'whatever'});
var manifestJSONParser = new ManifestJSONParser(json,
addonValidator.collector);
addonLinter.collector);
var manifestVersion = manifestJSONParser._getManifestVersion();
assert.equal(manifestVersion, null);
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.MANIFEST_VERSION_INVALID.code);
});
it('should collect an error with numeric string value', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var json = validManifestJSON({manifest_version: '1'});
var manifestJSONParser = new ManifestJSONParser(json,
addonValidator.collector);
addonLinter.collector);
var manifestVersion = manifestJSONParser._getManifestVersion();
assert.equal(manifestVersion, null);
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.MANIFEST_VERSION_INVALID.code);
});
it('should have the right manifestVersion', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var json = validManifestJSON();
var manifestJSONParser = new ManifestJSONParser(json,
addonValidator.collector);
addonLinter.collector);
var manifestVersion = manifestJSONParser._getManifestVersion();
assert.equal(manifestVersion, VALID_MANIFEST_VERSION);
});
@ -76,25 +76,25 @@ describe('ManifestJSONParser._getName()', function() {
});
it('should collect an error on missing name value', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var json = validManifestJSON({name: undefined});
var manifestJSONParser = new ManifestJSONParser(json,
addonValidator.collector);
addonLinter.collector);
var name = manifestJSONParser._getName();
assert.equal(name, null);
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.PROP_NAME_MISSING.code);
});
it('should collect an error on non-string name value', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var json = validManifestJSON({name: 1});
var manifestJSONParser = new ManifestJSONParser(json,
addonValidator.collector);
addonLinter.collector);
var name = manifestJSONParser._getName();
assert.equal(name, null);
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.PROP_NAME_INVALID.code);
});
@ -112,25 +112,25 @@ describe('ManifestJSONParser._getVersion()', function() {
});
it('should collect an error on missing version value', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var json = validManifestJSON({version: undefined});
var manifestJSONParser = new ManifestJSONParser(json,
addonValidator.collector);
addonLinter.collector);
var version = manifestJSONParser._getVersion();
assert.equal(version, null);
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.PROP_VERSION_MISSING.code);
});
it('should collect an error on non-string version value', () => {
var addonValidator = new Validator({_: ['bar']});
var addonLinter = new Linter({_: ['bar']});
var json = validManifestJSON({version: 1});
var manifestJSONParser = new ManifestJSONParser(json,
addonValidator.collector);
addonLinter.collector);
var version = manifestJSONParser._getVersion();
assert.equal(version, null);
var errors = addonValidator.collector.errors;
var errors = addonLinter.collector.errors;
assert.equal(errors.length, 1);
assert.equal(errors[0].code, messages.PROP_VERSION_INVALID.code);
});

Просмотреть файл

@ -18,11 +18,11 @@ describe('RDF: mustNotExist', () => {
return rules.mustNotExist(xmlDoc, filename,
rdfScanner.options);
})
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 1);
assert.equal(validatorMessages[0].code,
.then((linterMessages) => {
assert.equal(linterMessages.length, 1);
assert.equal(linterMessages[0].code,
messages.TAG_NOT_ALLOWED_HIDDEN.code);
assert.equal(validatorMessages[0].type, VALIDATION_ERROR);
assert.equal(linterMessages[0].type, VALIDATION_ERROR);
});
});
@ -36,10 +36,10 @@ describe('RDF: mustNotExist', () => {
return rules.mustNotExist(xmlDoc, filename,
rdfScanner.options);
})
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 2);
.then((linterMessages) => {
assert.equal(linterMessages.length, 2);
for (let message of validatorMessages) {
for (let message of linterMessages) {
assert.equal(message.code, messages.TAG_NOT_ALLOWED_HIDDEN.code);
assert.equal(message.type, VALIDATION_ERROR);
}
@ -57,9 +57,9 @@ describe('RDF: mustNotExist', () => {
return rules.mustNotExist(xmlDoc, filename,
rdfScanner.options);
})
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 1);
for (let message of validatorMessages) {
.then((linterMessages) => {
assert.equal(linterMessages.length, 1);
for (let message of linterMessages) {
assert.equal(message.code, messages.TAG_NOT_ALLOWED_UPDATEURL.code);
assert.equal(message.type, VALIDATION_ERROR);
}
@ -75,8 +75,8 @@ describe('RDF: mustNotExist', () => {
return rules.mustNotExist(xmlDoc, filename,
rdfScanner.options);
})
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 0);
.then((linterMessages) => {
assert.equal(linterMessages.length, 0);
});
});
@ -90,18 +90,18 @@ describe('RDF: mustNotExist', () => {
return rules.mustNotExist(xmlDoc, filename,
rdfScanner.options);
})
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 3);
.then((linterMessages) => {
assert.equal(linterMessages.length, 3);
for (let message of validatorMessages) {
for (let message of linterMessages) {
assert.equal(message.type, VALIDATION_WARNING);
}
assert.equal(validatorMessages[0].code,
assert.equal(linterMessages[0].code,
messages.TAG_OBSOLETE_FILE.code);
assert.equal(validatorMessages[1].code,
assert.equal(linterMessages[1].code,
messages.TAG_OBSOLETE_REQUIRES.code);
assert.equal(validatorMessages[2].code,
assert.equal(linterMessages[2].code,
messages.TAG_OBSOLETE_SKIN.code);
});
});
@ -121,11 +121,11 @@ describe('RDF: mustNotExist', () => {
prefix: 'TAG_OBSOLETE_',
});
})
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 1);
assert.equal(validatorMessages[0].code,
.then((linterMessages) => {
assert.equal(linterMessages.length, 1);
assert.equal(linterMessages[0].code,
messages.TAG_OBSOLETE_FILE.code);
assert.equal(validatorMessages[0].type, VALIDATION_NOTICE);
assert.equal(linterMessages[0].type, VALIDATION_NOTICE);
});
});
});

Просмотреть файл

@ -76,9 +76,9 @@ describe('Base Scanner Class', function() {
});
return scanner.scan(fakeRules)
.then((validatorMessages) => {
.then((linterMessages) => {
assert.ok(fakeRules.metadataPassedCheck.called);
assert.equal(validatorMessages.length, 0);
assert.equal(linterMessages.length, 0);
});
});

Просмотреть файл

@ -39,9 +39,9 @@ describe('CSSScanner', () => {
});
return scanner.scan(fakeRules)
.then((validatorMessages) => {
.then((linterMessages) => {
assert.ok(fakeRules.metadataPassCheck.called);
assert.equal(validatorMessages.length, 0);
assert.equal(linterMessages.length, 0);
});
});

Просмотреть файл

@ -16,8 +16,8 @@ describe('HTML', function() {
var htmlScanner = new HTMLScanner(contents, 'index.html');
return htmlScanner.scan()
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 0);
.then((linterMessages) => {
assert.equal(linterMessages.length, 0);
});
});
@ -26,8 +26,8 @@ describe('HTML', function() {
var htmlScanner = new HTMLScanner(contents, 'index.html');
return htmlScanner.scan()
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 0);
.then((linterMessages) => {
assert.equal(linterMessages.length, 0);
});
});
@ -49,12 +49,12 @@ describe('HTML', function() {
.then(($) => {
return rules.ensureRequiredAttributes($, htmlScanner.filename);
})
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 1);
assert.equal(validatorMessages[0].code,
.then((linterMessages) => {
assert.equal(linterMessages.length, 1);
assert.equal(linterMessages[0].code,
messages.PREFWINDOW_REQUIRES_ID.code);
assert.equal(validatorMessages[0].sourceCode, '<prefwindow>');
assert.equal(validatorMessages[0].type, VALIDATION_ERROR);
assert.equal(linterMessages[0].sourceCode, '<prefwindow>');
assert.equal(linterMessages[0].type, VALIDATION_ERROR);
// Make sure there are no errors when an ID is provided.
htmlScanner = new HTMLScanner(goodHTML, 'index.html');
@ -63,8 +63,8 @@ describe('HTML', function() {
.then(($) => {
return rules.ensureRequiredAttributes($, htmlScanner.filename);
})
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 0);
.then((linterMessages) => {
assert.equal(linterMessages.length, 0);
});
});

Просмотреть файл

@ -143,7 +143,6 @@ describe('JavaScript Scanner', function() {
});
});
// Depends on: https://github.com/mozilla/addons-validator/issues/7
it('ignores /*eslint-disable*/ comments', () => {
var code = singleLineString`/*eslint-disable*/
var myDatabase = indexeddb || mozIndexedDB;`;
@ -207,7 +206,7 @@ describe('JavaScript Scanner', function() {
// This test is pretty much copied from ESLint, to make sure dependencies
// don't change behaviour on us.
// https://github.com/mozilla/addons-validator/pull/98#issuecomment-158890847
// https://github.com/mozilla/addons-linter/pull/98#issuecomment-158890847
it('ignores /*global foo*/', () => {
var eslint = ESLint.linter;
var config = { rules: { test: 2 } };

Просмотреть файл

@ -18,8 +18,8 @@ describe('RDF', function() {
var rdfScanner = new RDFScanner(contents, 'install.rdf');
return rdfScanner.scan()
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 0);
.then((linterMessages) => {
assert.equal(linterMessages.length, 0);
});
});
@ -39,8 +39,8 @@ describe('RDF', function() {
var rdfScanner = new RDFScanner(contents, 'install.rdf');
return rdfScanner.scan()
.then((validatorMessages) => {
assert.equal(validatorMessages.length, 0);
.then((linterMessages) => {
assert.equal(linterMessages.length, 0);
});
});

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -22,7 +22,7 @@ module.exports = {
target: 'node',
output: {
path: path.join(__dirname, 'dist'),
filename: 'addons-validator.js',
filename: 'addons-linter.js',
libraryTarget: 'commonjs2',
},
module: {