Skip to content

Commit

Permalink
Implement rule to flag use of alert (fixes #10)
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Jul 4, 2013
1 parent 076db40 commit 967fcd5
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 4 deletions.
1 change: 1 addition & 0 deletions config/eslint.json
@@ -1,6 +1,7 @@
{
"rules": {

"no-alert": 1,
"no-arg": 1,
"no-console": 1,
"no-debugger": 1,
Expand Down
15 changes: 11 additions & 4 deletions lib/rules.js
Expand Up @@ -13,6 +13,12 @@
var fs = require("fs"),
path = require("path");

//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------

var JS_EXT = ".js";

//------------------------------------------------------------------------------
// Privates
//------------------------------------------------------------------------------
Expand All @@ -26,12 +32,12 @@ var rules = {};
exports.load = function(directory) {

try {
var fullPath = path.join(__dirname, directory),
var fullPath = path.resolve(process.cwd(), directory),
files = fs.readdirSync(fullPath);

files.forEach(function(file) {
if (path.extname(file) === ".js") {
var ruleId = file.replace(".js", "");
if (path.extname(file) === JS_EXT) {
var ruleId = file.replace(JS_EXT, "");
rules[ruleId] = require(path.join(fullPath, ruleId));
}
});
Expand All @@ -50,4 +56,5 @@ exports.get = function(ruleId) {
// Initialization
//------------------------------------------------------------------------------

exports.load("./rules");
// loads built-in rules
exports.load(path.join(__dirname, "./rules"));
51 changes: 51 additions & 0 deletions lib/rules/no-alert.js
@@ -0,0 +1,51 @@
/**
* @fileoverview Rule to flag use of alert, confirm, prompt
* @author Nicholas C. Zakas
*/

/*jshint node:true*/

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

function matchProhibited(name) {
return name.match(/^(alert|confirm|prompt)$/);
}


//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {

return {

"CallExpression": function(node) {

var result;

// without window.
if (node.callee.type === "Identifier") {

result = matchProhibited(node.callee.name);

if (result) {
context.report(node, "Unexpected " + result[1] + ".");
}

} else if (node.callee.type === "MemberExpression") {

result = matchProhibited(node.callee.property.name);

if (result && node.callee.object.name === "window") {
context.report(node, "Unexpected " + result[1] + ".");
}

}

}
};

};
179 changes: 179 additions & 0 deletions tests/lib/rules/no-alert.js
@@ -0,0 +1,179 @@
/**
* @fileoverview Tests for no-alert rule.
* @author Nicholas C. Zakas
*/

/*jshint node:true*/

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

var vows = require("vows"),
assert = require("assert"),
sinon = require("sinon"),
eslint = require("../../../lib/eslint");

//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------

var RULE_ID = "no-alert";

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

vows.describe(RULE_ID).addBatch({

"when evaluating 'alert(foo)'": {

topic: "alert(foo)",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Unexpected alert.");
assert.include(messages[0].node.type, "CallExpression");
assert.include(messages[0].node.callee.name, "alert");
}
},

"when evaluating 'window.alert(foo)'": {

topic: "window.alert(foo)",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Unexpected alert.");
assert.include(messages[0].node.type, "CallExpression");
assert.include(messages[0].node.callee.property.name, "alert");
}
},

"when evaluating 'confirm(foo)'": {

topic: "confirm(foo)",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Unexpected confirm.");
assert.include(messages[0].node.type, "CallExpression");
assert.include(messages[0].node.callee.name, "confirm");
}
},

"when evaluating 'window.confirm(foo)'": {

topic: "window.confirm(foo)",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Unexpected confirm.");
assert.include(messages[0].node.type, "CallExpression");
assert.include(messages[0].node.callee.property.name, "confirm");
}
},

"when evaluating 'prompt(foo)'": {

topic: "prompt(foo)",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Unexpected prompt.");
assert.include(messages[0].node.type, "CallExpression");
assert.include(messages[0].node.callee.name, "prompt");
}
},

"when evaluating 'window.prompt(foo)'": {

topic: "window.prompt(foo)",

"should report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 1);
assert.equal(messages[0].ruleId, RULE_ID);
assert.equal(messages[0].message, "Unexpected prompt.");
assert.include(messages[0].node.type, "CallExpression");
assert.include(messages[0].node.callee.property.name, "prompt");
}
},

"when evaluating 'foo.alert(foo)'": {

topic: "foo.alert(foo)",

"should not report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 0);
}
},

"when evaluating 'foo.confirm(foo)'": {

topic: "foo.confirm(foo)",

"should not report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 0);
}
},

"when evaluating 'foo.prompt(foo)'": {

topic: "foo.prompt(foo)",

"should not report a violation": function(topic) {
var config = { rules: {} };
config.rules[RULE_ID] = 1;

var messages = eslint.verify(topic, config);

assert.equal(messages.length, 0);
}
}

}).export(module);

0 comments on commit 967fcd5

Please sign in to comment.