diff --git a/.jshintignore b/.eslintignore
similarity index 59%
rename from .jshintignore
rename to .eslintignore
index 0fd4831..3a241f4 100644
--- a/.jshintignore
+++ b/.eslintignore
@@ -1,3 +1,2 @@
coverage
-node_modules
public/js
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..1f67508
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('pa11y-lint-config/eslint/es6');
diff --git a/.jscsrc b/.jscsrc
deleted file mode 100644
index 36dce16..0000000
--- a/.jscsrc
+++ /dev/null
@@ -1,94 +0,0 @@
-{
- "disallowEmptyBlocks": true,
- "disallowImplicitTypeConversion": [
- "binary",
- "boolean",
- "numeric",
- "string"
- ],
- "disallowKeywordsOnNewLine": [
- "catch",
- "else"
- ],
- "disallowMixedSpacesAndTabs": true,
- "disallowMultipleSpaces": true,
- "disallowMultipleVarDecl": true,
- "disallowNewlineBeforeBlockStatements": true,
- "disallowParenthesesAroundArrowParam": true,
- "disallowQuotedKeysInObjects": true,
- "disallowSpaceAfterObjectKeys": {
- "allExcept": [
- "method"
- ]
- },
- "disallowSpaceAfterPrefixUnaryOperators": true,
- "disallowSpaceBeforeComma": true,
- "disallowSpaceBeforeSemicolon": true,
- "disallowSpacesInCallExpression": true,
- "disallowSpacesInFunction": {
- "beforeOpeningRoundBrace": true
- },
- "disallowSpacesInsideArrayBrackets": true,
- "disallowSpacesInsideBrackets": true,
- "disallowSpacesInsideObjectBrackets": true,
- "disallowSpacesInsideParentheses": true,
- "disallowSpacesInsideTemplateStringPlaceholders": true,
- "disallowTrailingComma": true,
- "disallowTrailingWhitespace": true,
- "disallowVar": true,
- "disallowYodaConditions": true,
-
- "maximumLineLength": 100,
-
- "requireArrowFunctions": true,
- "requireBlocksOnNewline": true,
- "requireCamelCaseOrUpperCaseIdentifiers": true,
- "requireCapitalizedConstructors": true,
- "requireCommaBeforeLineBreak": true,
- "requireCurlyBraces": true,
- "requireDotNotation": true,
- "requireFunctionDeclarations": true,
- "requireLineBreakAfterVariableAssignment": true,
- "requireLineFeedAtFileEnd": true,
- "requireObjectKeysOnNewLine": true,
- "requireParenthesesAroundIIFE": true,
- "requireSemicolons": true,
- "requireSpaceAfterBinaryOperators": true,
- "requireSpaceAfterKeywords": [
- "if",
- "else",
- "for",
- "while",
- "do",
- "switch",
- "try",
- "catch"
- ],
- "requireSpaceAfterLineComment": {
- "allExcept": [
- "="
- ]
- },
- "requireSpaceBeforeBinaryOperators": true,
- "requireSpaceBeforeBlockStatements": true,
- "requireSpaceBeforeObjectValues": true,
- "requireSpaceBetweenArguments": true,
- "requireSpacesInConditionalExpression": true,
- "requireSpacesInForStatement": true,
- "requireSpacesInFunction": {
- "beforeOpeningCurlyBrace": true
- },
- "requireTemplateStrings": true,
-
- "validateIndentation": "\t",
- "validateLineBreaks": "LF",
- "validateNewlineAfterArrayElements": true,
- "validateParameterSeparator": ", ",
- "validateQuoteMarks": "'",
-
- "excludeFiles": [
- "coverage",
- "node_modules",
- "public/js"
- ]
-}
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index 4379be2..0000000
--- a/.jshintrc
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "curly": true,
- "eqeqeq": true,
- "esversion": 6,
- "forin": true,
- "globals": {
- "after": true,
- "afterEach": true,
- "before": true,
- "beforeEach": true,
- "describe": true,
- "it": true
- },
- "latedef": "nofunc",
- "maxcomplexity": 6,
- "maxdepth": 2,
- "maxparams": 4,
- "noarg": true,
- "node": true,
- "nonew": true,
- "nonstandard": true,
- "shadow": false,
- "strict": true,
- "undef": true,
- "unused": true
-}
diff --git a/Makefile b/Makefile
index ae277b1..1f4331e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,47 +1,27 @@
+include Makefile.node
-# Color helpers
-C_CYAN=\x1b[34;01m
-C_RESET=\x1b[0m
+# We need to run integration tests recursively
+export INTEGRATION_FLAGS := --recursive
-# Group targets
-all: deps lint test
-ci: lint test
-# Install dependencies
-deps:
- @echo "$(C_CYAN)> installing dependencies$(C_RESET)"
- @npm install
+# Verify tasks
+# ------------
-# Lint JavaScript
-lint: jshint jscs
+# Lint alias for backwards compatibility
+lint: verify
-# Run JSHint
-jshint:
- @echo "$(C_CYAN)> linting javascript$(C_RESET)"
- @./node_modules/.bin/jshint .
-# Run JavaScript Code Style
-jscs:
- @echo "$(C_CYAN)> checking javascript code style$(C_RESET)"
- @./node_modules/.bin/jscs .
-
-# Run all tests
-test: test-integration
-
-# Run integration tests
-test-integration:
- @echo "$(C_CYAN)> running integration tests$(C_RESET)"
- @./node_modules/.bin/mocha ./test/integration --reporter spec --recursive --timeout 5000 --slow 50
+# Client-side asset tasks
+# -----------------------
# Compile LESS
less:
- @echo "$(C_CYAN)> compiling less$(C_RESET)"
- @./node_modules/.bin/lessc -x ./public/less/main.less ./public/css/site.min.css
+ @lessc -x ./public/less/main.less ./public/css/site.min.css
+ @$(TASK_DONE)
# Compile client-side JavaScript
uglify:
- @echo "$(C_CYAN)> compiling client-side JavaScript$(C_RESET)"
- @./node_modules/.bin/uglifyjs \
+ @uglifyjs \
public/js/vendor/jquery/jquery.min.js \
public/js/vendor/bootstrap/js/alert.js \
public/js/vendor/bootstrap/js/dropdown.js \
@@ -55,5 +35,4 @@ uglify:
public/js/vendor/flot/jquery.flot.resize.js \
public/js/site.js \
-o ./public/js/site.min.js
-
-.PHONY: test
+ @$(TASK_DONE)
diff --git a/Makefile.node b/Makefile.node
new file mode 100644
index 0000000..c82b55d
--- /dev/null
+++ b/Makefile.node
@@ -0,0 +1,125 @@
+#
+# Node.js Makefile
+# ================
+#
+# Do not update this file manually – it's maintained separately on GitHub:
+# https://github.com/rowanmanning/makefiles/blob/master/Makefile.node
+#
+# To update to the latest version, run `make update-makefile`.
+#
+
+
+# Meta tasks
+# ----------
+
+.PHONY: test
+
+
+# Useful variables
+# ----------------
+
+NPM_BIN = ./node_modules/.bin
+export PATH := $(NPM_BIN):$(PATH)
+export EXPECTED_COVERAGE := 90
+export INTEGRATION_TIMEOUT := 5000
+export INTEGRATION_SLOW := 4000
+
+
+# Output helpers
+# --------------
+
+TASK_DONE = echo "✓ $@ done"
+
+
+# Group tasks
+# -----------
+
+all: install ci
+ci: verify test
+
+
+# Install tasks
+# -------------
+
+clean:
+ @git clean -fxd
+ @$(TASK_DONE)
+
+install: node_modules
+ @$(TASK_DONE)
+
+node_modules: package.json
+ @npm prune --production=false
+ @npm install
+ @$(TASK_DONE)
+
+
+# Verify tasks
+# ------------
+
+verify: verify-javascript verify-dust verify-spaces
+ @$(TASK_DONE)
+
+verify-javascript: verify-eslint verify-jshint verify-jscs
+ @$(TASK_DONE)
+
+verify-dust:
+ @if [ -e .dustmiterc* ]; then dustmite --path ./view && $(TASK_DONE); fi
+
+verify-eslint:
+ @if [ -e .eslintrc* ]; then eslint . && $(TASK_DONE); fi
+
+verify-jshint:
+ @if [ -e .jshintrc* ]; then jshint . && $(TASK_DONE); fi
+
+verify-jscs:
+ @if [ -e .jscsrc* ]; then jscs . && $(TASK_DONE); fi
+
+verify-spaces:
+ @if [ -e .editorconfig* ] && [ -x $(NPM_BIN)/lintspaces ]; then \
+ git ls-files | xargs lintspaces -e .editorconfig && $(TASK_DONE); \
+ fi
+
+verify-coverage:
+ @if [ -d coverage ]; then \
+ if [ -x $(NPM_BIN)/nyc ]; then \
+ nyc check-coverage --lines $(EXPECTED_COVERAGE) --functions $(EXPECTED_COVERAGE) --branches $(EXPECTED_COVERAGE) && $(TASK_DONE); \
+ else \
+ if [ -x $(NPM_BIN)/istanbul ]; then \
+ istanbul check-coverage --statement $(EXPECTED_COVERAGE) --branch $(EXPECTED_COVERAGE) --function $(EXPECTED_COVERAGE) && $(TASK_DONE); \
+ fi \
+ fi \
+ fi
+
+# Test tasks
+# ----------
+
+test: test-unit-coverage verify-coverage test-integration
+ @$(TASK_DONE)
+
+test-unit:
+ @if [ -d test/unit ]; then mocha test/unit --recursive && $(TASK_DONE); fi
+
+test-unit-coverage:
+ @if [ -d test/unit ]; then \
+ if [ -x $(NPM_BIN)/nyc ]; then \
+ nyc --reporter=text --reporter=html $(NPM_BIN)/_mocha test/unit --recursive && $(TASK_DONE); \
+ else \
+ if [ -x $(NPM_BIN)/istanbul ]; then \
+ istanbul cover $(NPM_BIN)/_mocha -- test/unit --recursive && $(TASK_DONE); \
+ else \
+ make test-unit; \
+ fi \
+ fi \
+ fi
+
+test-integration:
+ @if [ -d test/integration ]; then mocha test/integration --timeout $(INTEGRATION_TIMEOUT) --slow $(INTEGRATION_SLOW) $(INTEGRATION_FLAGS) && $(TASK_DONE); fi
+
+
+# Tooling tasks
+# -------------
+
+update-makefile:
+ @curl -s https://raw.githubusercontent.com/rowanmanning/makefiles/master/Makefile.node > Makefile.node
+ @$(TASK_DONE)
diff --git a/README.md b/README.md
index 8818a48..2984751 100644
--- a/README.md
+++ b/README.md
@@ -87,24 +87,20 @@ Contributing
There are many ways to contribute to Pa11y Dashboard, we cover these in the [contributing guide](CONTRIBUTING.md) for this repo.
-If you're ready to contribute some code, you'll need to clone the repo and get set up as outlined in the [setup guide](#setup).
-
-You'll need to start the application in test mode with:
+If you're ready to contribute some code, you'll need to clone the repo and get set up as outlined in the [setup guide](#setup). You'll then need to start the application in test mode with:
```sh
NODE_ENV=test node index.js
```
-Now you'll be able to run the following commands:
+You'll now be able to run the following commands:
```sh
-make # Run the lint and test tasks together
-make lint # Run linters with the correct config
-make test # Run integration tests
+make verify # Verify all of the code (ESLint)
+make test # Run all tests
+make test-integration # Run the integration tests
```
-Code with lint errors or failing tests will not be accepted, please use the build tools outlined above.
-
To compile the client-side JavaScript and CSS, you'll need the following commands. Compiled code is committed to the repository.
```sh
diff --git a/app.js b/app.js
index 31a3965..1cecea0 100644
--- a/app.js
+++ b/app.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const bodyParser = require('body-parser');
@@ -84,9 +83,9 @@ function initApp(config, callback) {
settings: {}
};
- app.express.use((req, res, next) => {
- res.locals.isHomePage = (req.path === '/');
- res.locals.host = req.hostname;
+ app.express.use((request, response, next) => {
+ response.locals.isHomePage = (request.path === '/');
+ response.locals.host = request.hostname;
next();
});
@@ -105,27 +104,27 @@ function initApp(config, callback) {
}
// Error handling
- app.express.get('*', (req, res) => {
- res.status(404);
- res.render('404');
+ app.express.get('*', (request, response) => {
+ response.status(404);
+ response.render('404');
});
- app.express.use((err, req, res, next) => {
- /* jshint unused: false */
- if (err.code === 'ECONNREFUSED') {
- err = new Error('Could not connect to Pa11y Webservice');
+ app.express.use((error, request, response, next) => {
+ /* eslint no-unused-vars: 'off' */
+ if (error.code === 'ECONNREFUSED') {
+ error = new Error('Could not connect to Pa11y Webservice');
}
- app.emit('route-error', err);
+ app.emit('route-error', error);
if (process.env.NODE_ENV !== 'production') {
- res.locals.error = err;
+ response.locals.error = error;
}
- res.status(500);
- res.render('500');
+ response.status(500);
+ response.render('500');
});
- app.server.listen(config.port, err => {
+ app.server.listen(config.port, error => {
const address = app.server.address();
app.address = `http://${address.address}:${address.port}`;
- callback(err, app);
+ callback(error, app);
});
}
diff --git a/config.js b/config.js
index ffd84ca..a67d5cd 100644
--- a/config.js
+++ b/config.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const fs = require('fs');
diff --git a/data/.eslintrc.js b/data/.eslintrc.js
new file mode 100644
index 0000000..a3d4df7
--- /dev/null
+++ b/data/.eslintrc.js
@@ -0,0 +1,8 @@
+'use strict';
+
+// Clone the main config
+var config = module.exports = JSON.parse(JSON.stringify(require('../.eslintrc')));
+
+// Disable max line length/statements
+config.rules['max-len'] = 'off';
+config.rules['max-statements'] = 'off';
diff --git a/index.js b/index.js
index 8b00f03..e12008f 100644
--- a/index.js
+++ b/index.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const chalk = require('chalk');
@@ -23,15 +22,19 @@ process.on('SIGINT', () => {
process.exit();
});
-require('./app')(config, (err, app) => {
+require('./app')(config, (error, app) => {
+ if (error) {
+ console.error(error.stack);
+ process.exit(1);
+ }
console.log('');
console.log(chalk.underline.magenta('Pa11y Dashboard started'));
console.log(chalk.grey('mode: %s'), process.env.NODE_ENV);
console.log(chalk.grey('uri: %s'), app.address);
- app.on('route-error', err => {
- const stack = (err.stack ? err.stack.split('\n') : [err.message]);
+ app.on('route-error', error => {
+ const stack = (error.stack ? error.stack.split('\n') : [error.message]);
const msg = chalk.red(stack.shift());
console.error('');
console.error(msg);
@@ -40,7 +43,12 @@ require('./app')(config, (err, app) => {
// Start the webservice if required
if (typeof config.webservice === 'object') {
- require('pa11y-webservice')(config.webservice, (err, webservice) => {
+ require('pa11y-webservice')(config.webservice, (error, webservice) => {
+ if (error) {
+ console.error(error.stack);
+ process.exit(1);
+ }
+
console.log('');
console.log(chalk.underline.cyan('Pa11y Webservice started'));
console.log(chalk.grey('mode: %s'), process.env.NODE_ENV);
diff --git a/package.json b/package.json
index d977bfa..b53dcab 100644
--- a/package.json
+++ b/package.json
@@ -38,10 +38,10 @@
"devDependencies": {
"bower": "~1.7",
"cheerio": "~0.20",
- "jscs": "^2",
- "jshint": "^2",
+ "eslint": "^3.18.0",
"less": "~2.7",
"mocha": "^2",
+ "pa11y-lint-config": "^1.0.0",
"proclaim": "^3",
"request": "^2.74",
"uglify-js": "~2.6"
diff --git a/route/index.js b/route/index.js
index dfd031e..2aa46b5 100644
--- a/route/index.js
+++ b/route/index.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const presentTask = require('../view/presenter/task');
@@ -21,14 +20,14 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.get('/', (req, res, next) => {
- app.webservice.tasks.get({lastres: true}, (err, tasks) => {
- if (err) {
- return next(err);
+ app.express.get('/', (request, response, next) => {
+ app.webservice.tasks.get({lastres: true}, (error, tasks) => {
+ if (error) {
+ return next(error);
}
- res.render('index', {
+ response.render('index', {
tasks: tasks.map(presentTask),
- deleted: (typeof req.query.deleted !== 'undefined'),
+ deleted: (typeof request.query.deleted !== 'undefined'),
isHomePage: true
});
});
diff --git a/route/new.js b/route/new.js
index 91bf15b..feebce3 100644
--- a/route/new.js
+++ b/route/new.js
@@ -12,9 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
-/*jshint maxcomplexity:10*/
-
'use strict';
const getStandards = require('../data/standards');
@@ -25,24 +22,24 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.get('/new', (req, res) => {
+ app.express.get('/new', (request, response) => {
const standards = getStandards().map(standard => {
if (standard.title === 'WCAG2AA') {
standard.selected = true;
}
return standard;
});
- res.render('new', {
+ response.render('new', {
standards: standards,
isNewTaskPage: true
});
});
- app.express.post('/new', (req, res) => {
+ app.express.post('/new', (request, response) => {
let parsedActions;
- if (req.body.actions) {
- parsedActions = req.body.actions.split(/[\r\n]+/)
+ if (request.body.actions) {
+ parsedActions = request.body.actions.split(/[\r\n]+/)
.map(action => {
return action.trim();
})
@@ -52,26 +49,26 @@ function route(app) {
}
let parsedHeaders;
- if (req.body.headers) {
- parsedHeaders = httpHeaders(req.body.headers, true);
+ if (request.body.headers) {
+ parsedHeaders = httpHeaders(request.body.headers, true);
}
const newTask = {
- name: req.body.name,
- url: req.body.url,
- standard: req.body.standard,
- ignore: req.body.ignore || [],
- timeout: req.body.timeout || undefined,
- wait: req.body.wait || undefined,
+ name: request.body.name,
+ url: request.body.url,
+ standard: request.body.standard,
+ ignore: request.body.ignore || [],
+ timeout: request.body.timeout || undefined,
+ wait: request.body.wait || undefined,
actions: parsedActions,
- username: req.body.username || undefined,
- password: req.body.password || undefined,
+ username: request.body.username || undefined,
+ password: request.body.password || undefined,
headers: parsedHeaders,
- hideElements: req.body.hideElements || undefined
+ hideElements: request.body.hideElements || undefined
};
- app.webservice.tasks.create(newTask, (err, task) => {
- if (err) {
+ app.webservice.tasks.create(newTask, (error, task) => {
+ if (error) {
const standards = getStandards().map(standard => {
if (standard.title === newTask.standard) {
standard.selected = true;
@@ -84,15 +81,15 @@ function route(app) {
});
return standard;
});
- newTask.actions = req.body.actions;
- newTask.headers = req.body.headers;
- return res.render('new', {
- error: err,
+ newTask.actions = request.body.actions;
+ newTask.headers = request.body.headers;
+ return response.render('new', {
+ error: error,
standards: standards,
task: newTask
});
}
- res.redirect(`/${task.id}?added`);
+ response.redirect(`/${task.id}?added`);
});
});
diff --git a/route/result/download.js b/route/result/download.js
index e232ae3..6b71aff 100644
--- a/route/result/download.js
+++ b/route/result/download.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const moment = require('moment');
@@ -22,20 +21,20 @@ module.exports = route;
// Route definition
function route(app) {
- function getTaskAndResult(req, res, next) {
- app.webservice.task(req.params.id).get({}, (err, task) => {
- if (err) {
+ function getTaskAndResult(request, response, next) {
+ app.webservice.task(request.params.id).get({}, (error, task) => {
+ if (error) {
return next('route');
}
app.webservice
- .task(req.params.id)
- .result(req.params.rid)
- .get({full: true}, (err, result) => {
- if (err) {
+ .task(request.params.id)
+ .result(request.params.rid)
+ .get({full: true}, (error, result) => {
+ if (error) {
return next('route');
}
- res.locals.task = task;
- res.locals.result = result;
+ response.locals.task = task;
+ response.locals.result = result;
next();
});
});
@@ -48,7 +47,7 @@ function route(app) {
task.url
.replace(/^https?:\/\//i, '')
.replace(/\/$/, '')
- .replace(/[^a-z0-9\.\-\_]+/gi, '-'),
+ .replace(/[^a-z0-9.\-_]+/gi, '-'),
'--',
task.standard.toLowerCase(),
'--',
@@ -58,9 +57,9 @@ function route(app) {
].join('');
}
- app.express.get('/:id/:rid.csv', getTaskAndResult, (req, res) => {
- const task = res.locals.task;
- const result = res.locals.result;
+ app.express.get('/:id/:rid.csv', getTaskAndResult, (request, response) => {
+ const task = response.locals.task;
+ const result = response.locals.result;
const rows = ['"code","message","type","context","selector"'];
result.results.forEach(msg => {
rows.push([
@@ -71,18 +70,18 @@ function route(app) {
JSON.stringify(msg.selector)
].join(','));
});
- res.attachment(getDownloadFileName(task, result, 'csv'));
- res.send(rows.join('\n'));
+ response.attachment(getDownloadFileName(task, result, 'csv'));
+ response.send(rows.join('\n'));
});
- app.express.get('/:id/:rid.json', getTaskAndResult, (req, res) => {
- const task = res.locals.task;
- const result = res.locals.result;
- res.attachment(getDownloadFileName(task, result, 'json'));
+ app.express.get('/:id/:rid.json', getTaskAndResult, (request, response) => {
+ const task = response.locals.task;
+ const result = response.locals.result;
+ response.attachment(getDownloadFileName(task, result, 'json'));
delete task.id;
delete result.id;
result.task = task;
- res.send(result);
+ response.send(result);
});
}
diff --git a/route/result/index.js b/route/result/index.js
index 296fb61..a200c32 100644
--- a/route/result/index.js
+++ b/route/result/index.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const presentTask = require('../../view/presenter/task');
@@ -23,19 +22,19 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.get('/:id/:rid', (req, res, next) => {
- app.webservice.task(req.params.id).get({}, (err, task) => {
- if (err) {
+ app.express.get('/:id/:rid', (request, response, next) => {
+ app.webservice.task(request.params.id).get({}, (error, task) => {
+ if (error) {
return next();
}
app.webservice
- .task(req.params.id)
- .result(req.params.rid)
- .get({full: true}, (err, result) => {
- if (err) {
+ .task(request.params.id)
+ .result(request.params.rid)
+ .get({full: true}, (error, result) => {
+ if (error) {
return next();
}
- res.render('result', {
+ response.render('result', {
task: presentTask(task),
mainResult: presentResult(result),
isResultPage: true
diff --git a/route/task/delete.js b/route/task/delete.js
index b7aebc3..6d9d946 100644
--- a/route/task/delete.js
+++ b/route/task/delete.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const presentTask = require('../../view/presenter/task');
@@ -22,24 +21,24 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.get('/:id/delete', (req, res, next) => {
- app.webservice.task(req.params.id).get({}, (err, task) => {
- if (err) {
+ app.express.get('/:id/delete', (request, response, next) => {
+ app.webservice.task(request.params.id).get({}, (error, task) => {
+ if (error) {
return next();
}
- res.render('task/delete', {
+ response.render('task/delete', {
task: presentTask(task),
isTaskSubPage: true
});
});
});
- app.express.post('/:id/delete', (req, res, next) => {
- app.webservice.task(req.params.id).remove(err => {
- if (err) {
+ app.express.post('/:id/delete', (request, response, next) => {
+ app.webservice.task(request.params.id).remove(error => {
+ if (error) {
return next();
}
- res.redirect('/?deleted');
+ response.redirect('/?deleted');
});
});
diff --git a/route/task/edit.js b/route/task/edit.js
index bae572b..3be4277 100644
--- a/route/task/edit.js
+++ b/route/task/edit.js
@@ -12,9 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
-/*jshint maxcomplexity:12*/
-
'use strict';
const presentTask = require('../../view/presenter/task');
@@ -26,9 +23,9 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.get('/:id/edit', (req, res, next) => {
- app.webservice.task(req.params.id).get({}, (err, task) => {
- if (err) {
+ app.express.get('/:id/edit', (request, response, next) => {
+ app.webservice.task(request.params.id).get({}, (error, task) => {
+ if (error) {
return next();
}
const standards = getStandards().map(standard => {
@@ -44,8 +41,8 @@ function route(app) {
return standard;
});
task.actions = (task.actions ? task.actions.join('\n') : '');
- res.render('task/edit', {
- edited: (typeof req.query.edited !== 'undefined'),
+ response.render('task/edit', {
+ edited: (typeof request.query.edited !== 'undefined'),
standards: standards,
task: presentTask(task),
isTaskSubPage: true
@@ -53,18 +50,18 @@ function route(app) {
});
});
- app.express.post('/:id/edit', (req, res, next) => {
- app.webservice.task(req.params.id).get({}, (err, task) => {
- if (err) {
+ app.express.post('/:id/edit', (request, response, next) => {
+ app.webservice.task(request.params.id).get({}, (error, task) => {
+ if (error) {
return next();
}
- const originalActions = req.body.actions;
- const originalHeaders = req.body.headers;
- req.body.ignore = req.body.ignore || [];
- req.body.timeout = req.body.timeout || undefined;
- req.body.wait = req.body.wait || undefined;
- if (req.body.actions) {
- req.body.actions = req.body.actions.split(/[\r\n]+/)
+ const originalActions = request.body.actions;
+ const originalHeaders = request.body.headers;
+ request.body.ignore = request.body.ignore || [];
+ request.body.timeout = request.body.timeout || undefined;
+ request.body.wait = request.body.wait || undefined;
+ if (request.body.actions) {
+ request.body.actions = request.body.actions.split(/[\r\n]+/)
.map(action => {
return action.trim();
})
@@ -72,24 +69,24 @@ function route(app) {
return Boolean(action);
});
}
- if (!req.body.actions) {
- req.body.actions = [];
+ if (!request.body.actions) {
+ request.body.actions = [];
}
- req.body.username = req.body.username || undefined;
- req.body.password = req.body.password || undefined;
- req.body.hideElements = req.body.hideElements || undefined;
- req.body.headers = httpHeaders(req.body.headers || '', true);
- app.webservice.task(req.params.id).edit(req.body, err => {
- if (err) {
- task.name = req.body.name;
- task.ignore = req.body.ignore;
- task.timeout = req.body.timeout;
- task.wait = req.body.wait;
+ request.body.username = request.body.username || undefined;
+ request.body.password = request.body.password || undefined;
+ request.body.hideElements = request.body.hideElements || undefined;
+ request.body.headers = httpHeaders(request.body.headers || '', true);
+ app.webservice.task(request.params.id).edit(request.body, error => {
+ if (error) {
+ task.name = request.body.name;
+ task.ignore = request.body.ignore;
+ task.timeout = request.body.timeout;
+ task.wait = request.body.wait;
task.actions = originalActions;
- task.username = req.body.username;
- task.password = req.body.password;
+ task.username = request.body.username;
+ task.password = request.body.password;
task.headers = originalHeaders;
- task.hideElements = req.body.hideElements;
+ task.hideElements = request.body.hideElements;
const standards = getStandards().map(standard => {
if (standard.title === task.standard) {
standard.selected = true;
@@ -102,14 +99,14 @@ function route(app) {
});
return standard;
});
- return res.render('task/edit', {
- error: err,
+ return response.render('task/edit', {
+ error: error,
standards: standards,
task: task,
isTaskSubPage: true
});
}
- res.redirect(`/${req.params.id}/edit?edited`);
+ response.redirect(`/${request.params.id}/edit?edited`);
});
});
});
diff --git a/route/task/ignore.js b/route/task/ignore.js
index 18b8c8b..2bf4073 100644
--- a/route/task/ignore.js
+++ b/route/task/ignore.js
@@ -5,20 +5,20 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.post('/:id/ignore', (req, res, next) => {
- app.webservice.task(req.params.id).get({}, (err, task) => {
- if (err) {
+ app.express.post('/:id/ignore', (request, response, next) => {
+ app.webservice.task(request.params.id).get({}, (error, task) => {
+ if (error) {
return next();
}
const edit = {
name: task.name,
ignore: task.ignore
};
- if (typeof req.body.rule === 'string') {
- edit.ignore.push(req.body.rule);
+ if (typeof request.body.rule === 'string') {
+ edit.ignore.push(request.body.rule);
}
- app.webservice.task(req.params.id).edit(edit, () => {
- res.redirect(`/${req.params.id}?rule-ignored`);
+ app.webservice.task(request.params.id).edit(edit, () => {
+ response.redirect(`/${request.params.id}?rule-ignored`);
});
});
});
diff --git a/route/task/index.js b/route/task/index.js
index 234e3e1..5c76128 100644
--- a/route/task/index.js
+++ b/route/task/index.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const presentTask = require('../../view/presenter/task');
@@ -24,24 +23,24 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.get('/:id', (req, res, next) => {
- app.webservice.task(req.params.id).get({lastres: true}, (err, task) => {
- if (err) {
+ app.express.get('/:id', (request, response, next) => {
+ app.webservice.task(request.params.id).get({lastres: true}, (error, task) => {
+ if (error) {
return next();
}
- app.webservice.task(req.params.id).results({}, (err, results) => {
- if (err) {
- return next(err);
+ app.webservice.task(request.params.id).results({}, (error, results) => {
+ if (error) {
+ return next(error);
}
const presentedResults = presentResultList(results.map(presentResult));
- res.render('task', {
+ response.render('task', {
task: presentTask(task),
results: presentedResults,
mainResult: task.lastResult || null,
- added: (typeof req.query.added !== 'undefined'),
- running: (typeof req.query.running !== 'undefined'),
- ruleIgnored: (typeof req.query['rule-ignored'] !== 'undefined'),
- ruleUnignored: (typeof req.query['rule-unignored'] !== 'undefined'),
+ added: (typeof request.query.added !== 'undefined'),
+ running: (typeof request.query.running !== 'undefined'),
+ ruleIgnored: (typeof request.query['rule-ignored'] !== 'undefined'),
+ ruleUnignored: (typeof request.query['rule-unignored'] !== 'undefined'),
hasOneResult: (presentedResults.length < 2),
isTaskPage: true
});
diff --git a/route/task/run.js b/route/task/run.js
index b5f85cb..9cb0102 100644
--- a/route/task/run.js
+++ b/route/task/run.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
module.exports = route;
@@ -20,12 +19,12 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.get('/:id/run', (req, res, next) => {
- app.webservice.task(req.params.id).run(err => {
- if (err) {
+ app.express.get('/:id/run', (request, response, next) => {
+ app.webservice.task(request.params.id).run(error => {
+ if (error) {
return next();
}
- res.redirect(`/${req.params.id}?running`);
+ response.redirect(`/${request.params.id}?running`);
});
});
diff --git a/route/task/unignore.js b/route/task/unignore.js
index 412d9e3..6c9e98e 100644
--- a/route/task/unignore.js
+++ b/route/task/unignore.js
@@ -5,21 +5,21 @@ module.exports = route;
// Route definition
function route(app) {
- app.express.post('/:id/unignore', (req, res, next) => {
- app.webservice.task(req.params.id).get({}, (err, task) => {
- if (err) {
+ app.express.post('/:id/unignore', (request, response, next) => {
+ app.webservice.task(request.params.id).get({}, (error, task) => {
+ if (error) {
return next();
}
const edit = {
name: task.name,
ignore: task.ignore
};
- const indexOfRule = edit.ignore.indexOf(req.body.rule);
- if (typeof req.body.rule === 'string' && indexOfRule !== -1) {
+ const indexOfRule = edit.ignore.indexOf(request.body.rule);
+ if (typeof request.body.rule === 'string' && indexOfRule !== -1) {
edit.ignore.splice(indexOfRule, 1);
}
- app.webservice.task(req.params.id).edit(edit, () => {
- res.redirect(`/${req.params.id}?rule-unignored`);
+ app.webservice.task(request.params.id).edit(edit, () => {
+ response.redirect(`/${request.params.id}?rule-unignored`);
});
});
});
diff --git a/test/.eslintrc.js b/test/.eslintrc.js
new file mode 100644
index 0000000..1d1bc36
--- /dev/null
+++ b/test/.eslintrc.js
@@ -0,0 +1,15 @@
+'use strict';
+
+// Clone the main config
+var config = module.exports = JSON.parse(JSON.stringify(require('../.eslintrc')));
+
+// We use `this` all over the integration tests
+config.rules['no-invalid-this'] = 'off';
+
+// Because of our use of `this`, arrow functions
+// aren't really gonna work in the integration tests
+config.rules['prefer-arrow-callback'] = 'off';
+
+// Disable max line length/statements
+config.rules['max-len'] = 'off';
+config.rules['max-statements'] = 'off';
diff --git a/test/integration/helper/navigate.js b/test/integration/helper/navigate.js
index 456a8ec..9294684 100644
--- a/test/integration/helper/navigate.js
+++ b/test/integration/helper/navigate.js
@@ -38,12 +38,15 @@ function createNavigator(baseUrl, store) {
json: opts.json || false,
qs: opts.query,
followAllRedirects: true
- }, function(err, res, body) {
+ }, function(error, response, body) {
+ if (error) {
+ return callback(error);
+ }
store.body = body;
- store.request = res.request;
- store.response = res;
- store.status = res.statusCode;
+ store.request = response.request;
+ store.response = response;
+ store.status = response.statusCode;
if (opts.nonDom) {
store.dom = null;
diff --git a/test/integration/route/index.js b/test/integration/route/index.js
index 18a259b..5ea162c 100644
--- a/test/integration/route/index.js
+++ b/test/integration/route/index.js
@@ -21,11 +21,11 @@ const assert = require('proclaim');
describe.only('GET /', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
diff --git a/test/integration/route/new.js b/test/integration/route/new.js
index b86a30f..e1efba5 100644
--- a/test/integration/route/new.js
+++ b/test/integration/route/new.js
@@ -21,11 +21,11 @@ const assert = require('proclaim');
describe('GET /new', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/new'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -122,7 +122,7 @@ describe('POST /new', function() {
describe('with invalid query', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'POST',
endpoint: '/new',
form: {
@@ -130,7 +130,7 @@ describe('POST /new', function() {
url: ''
}
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -146,7 +146,7 @@ describe('POST /new', function() {
describe('with valid query', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'POST',
endpoint: '/new',
form: {
@@ -155,7 +155,7 @@ describe('POST /new', function() {
standard: 'WCAG2AA'
}
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -163,9 +163,9 @@ describe('POST /new', function() {
});
it('should create the task', function(done) {
- this.webservice.tasks.get({}, function(err, tasks) {
+ this.webservice.tasks.get({}, function(error, tasks) {
assert.strictEqual(tasks.length, 4);
- done();
+ done(error);
});
});
diff --git a/test/integration/route/result/download.js b/test/integration/route/result/download.js
index be22d6c..dd1a3c7 100644
--- a/test/integration/route/result/download.js
+++ b/test/integration/route/result/download.js
@@ -21,12 +21,12 @@ const assert = require('proclaim');
describe('GET //.csv', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/abc000000000000000000001/def000000000000000000001.csv',
nonDom: true
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -42,13 +42,13 @@ describe('GET //.csv', function() {
describe('GET //.json', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/abc000000000000000000001/def000000000000000000001.json',
nonDom: true,
json: true
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
diff --git a/test/integration/route/result/index.js b/test/integration/route/result/index.js
index 3c759a8..7ebafaa 100644
--- a/test/integration/route/result/index.js
+++ b/test/integration/route/result/index.js
@@ -21,11 +21,11 @@ const assert = require('proclaim');
describe('GET //', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/abc000000000000000000001/def000000000000000000001'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
diff --git a/test/integration/route/task/delete.js b/test/integration/route/task/delete.js
index 6298d9e..8b5c257 100644
--- a/test/integration/route/task/delete.js
+++ b/test/integration/route/task/delete.js
@@ -21,11 +21,11 @@ const assert = require('proclaim');
describe('GET //delete', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/abc000000000000000000001/delete'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -48,11 +48,11 @@ describe('GET //delete', function() {
describe('POST //delete', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'POST',
endpoint: '/abc000000000000000000001/delete'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -60,8 +60,8 @@ describe('POST //delete', function() {
});
it('should delete the task', function(done) {
- this.webservice.task('abc000000000000000000001').get({}, function(err) {
- assert.strictEqual(err.message, 'Error 404');
+ this.webservice.task('abc000000000000000000001').get({}, function(error) {
+ assert.strictEqual(error.message, 'Error 404');
done();
});
});
diff --git a/test/integration/route/task/edit.js b/test/integration/route/task/edit.js
index c684035..2eb89e7 100644
--- a/test/integration/route/task/edit.js
+++ b/test/integration/route/task/edit.js
@@ -21,11 +21,11 @@ const assert = require('proclaim');
describe('GET //edit', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/abc000000000000000000001/edit'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -121,7 +121,7 @@ describe('GET //edit', function() {
describe('POST //edit', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'POST',
endpoint: '/abc000000000000000000001/edit',
form: {
@@ -131,7 +131,7 @@ describe('POST //edit', function() {
ignore: ['bar', 'baz']
}
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -139,12 +139,12 @@ describe('POST //edit', function() {
});
it('should edit the task', function(done) {
- this.webservice.task('abc000000000000000000001').get({}, function(err, task) {
+ this.webservice.task('abc000000000000000000001').get({}, function(error, task) {
assert.strictEqual(task.name, 'foo');
assert.strictEqual(task.username, 'newuser');
assert.strictEqual(task.password, 'secure');
assert.deepEqual(task.ignore, ['bar', 'baz']);
- done();
+ done(error);
});
});
diff --git a/test/integration/route/task/index.js b/test/integration/route/task/index.js
index e69eb08..124821d 100644
--- a/test/integration/route/task/index.js
+++ b/test/integration/route/task/index.js
@@ -23,11 +23,11 @@ describe('GET /', function() {
describe('when task has results', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/abc000000000000000000001'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
@@ -82,11 +82,11 @@ describe('GET /', function() {
describe('when task has no results', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/abc000000000000000000003'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
diff --git a/test/integration/route/task/run.js b/test/integration/route/task/run.js
index 5059183..8659669 100644
--- a/test/integration/route/task/run.js
+++ b/test/integration/route/task/run.js
@@ -21,11 +21,11 @@ const assert = require('proclaim');
describe('GET //run', function() {
beforeEach(function(done) {
- const req = {
+ const request = {
method: 'GET',
endpoint: '/abc000000000000000000001/run'
};
- this.navigate(req, done);
+ this.navigate(request, done);
});
it('should send a 200 status', function() {
diff --git a/test/integration/setup.js b/test/integration/setup.js
index 5abfd63..103af94 100644
--- a/test/integration/setup.js
+++ b/test/integration/setup.js
@@ -40,8 +40,8 @@ afterEach(function(done) {
// Check that the test application is running, and exit if not
function assertTestAppIsRunning(url, done) {
- request(url, err => {
- if (err) {
+ request(url, error => {
+ if (error) {
console.error('Error: Test app not started; run with `NODE_ENV=test node index.js`');
process.exit(1);
}
diff --git a/view/helper/date.js b/view/helper/date.js
index a542422..49aea72 100644
--- a/view/helper/date.js
+++ b/view/helper/date.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const moment = require('moment');
diff --git a/view/helper/url.js b/view/helper/url.js
index b823b1e..986d2b0 100644
--- a/view/helper/url.js
+++ b/view/helper/url.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
module.exports = helper;
diff --git a/view/presenter/ignore.js b/view/presenter/ignore.js
index 72f2a16..f5da38d 100644
--- a/view/presenter/ignore.js
+++ b/view/presenter/ignore.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const standardsArray = require('../../data/standards')();
diff --git a/view/presenter/result-list.js b/view/presenter/result-list.js
index 10b340b..3126065 100644
--- a/view/presenter/result-list.js
+++ b/view/presenter/result-list.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const _ = require('underscore');
diff --git a/view/presenter/result.js b/view/presenter/result.js
index a342805..6b53f5c 100644
--- a/view/presenter/result.js
+++ b/view/presenter/result.js
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
'use strict';
const _ = require('underscore');
diff --git a/view/presenter/task.js b/view/presenter/task.js
index d2b34dc..6462b53 100644
--- a/view/presenter/task.js
+++ b/view/presenter/task.js
@@ -12,8 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see .
-
-// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
'use strict';
const presentIgnoreRules = require('./ignore');