Skip to content

Commit

Permalink
added basic action alias support, and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Anthropohedron committed Apr 12, 2015
1 parent 81f8d30 commit 62d118b
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 6 deletions.
113 changes: 108 additions & 5 deletions lib/actions.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,118 @@
/*jslint vars: true, white: true, plusplus: true, todo: true */
"use strict";

var actionRE = /(?:^|\s)([\-+])([\-a-z]+)(?:{([^}]+)})?(?=\s|$)/g;
var supportedActionsMap = {
"add-header": "multi",
"block": "param",
"client-header-filter": "multi",
"client-header-tagger": "multi",
"content-type-overwrite": "param",
"crunch-client-header": "multi",
"crunch-if-none-match": "bool",
"crunch-incoming-cookies": "bool",
"crunch-server-header": "multi",
"crunch-outgoing-cookies": "bool",
"deanimate-gifs": "param",
"fast-redirects": "param",
"filter": "multi",
"force-text-mode": "bool",
"handle-as-empty-document": "bool",
"handle-as-image": "bool",
"hide-accept-language": "param",
"hide-content-disposition": "param",
"hide-if-modified-since": "param",
"hide-referrer": "param",
"hide-user-agent": "param",
"limit-cookie-lifetime": "param",
"overwrite-last-modified": "param",
"prevent-compression": "bool",
"redirect": "param",
"server-header-filter": "multi",
"server-header-tagger": "multi",
"session-cookies-only": "bool",
"set-image-blocker": "param"
};
var supportedActions = (function() {
var action, actions = [];
for (action in supportedActionsMap) {
if (supportedActionsMap.hasOwnProperty(action)) {
actions.push(action);
}
}
return actions;
}());

var aliases = {};
exports.clearAliases = function clearAliases() { aliases = {}; };
function isKnownAlias(alias) {
return aliases.hasOwnProperty(alias);
};
exports.isKnownAlias = isKnownAlias;

// returns whether we overwrote an existing alias
function registerAlias(alias, configs, noValidation) {
var exists = aliases.hasOwnProperty(alias);
if (!noValidation) {
configs.forEach(function(config) {
var name = config.name;
if (name === "negate") {
name = config.negatedName;
if (!supportedActionsMap.hasOwnProperty(name)) {
throw new Error("Unknown (negated) action: " + name);
}
} else if (!(supportedActionsMap.hasOwnProperty(name) ||
aliases.hasOwnProperty(name))) {
throw new Error("Unknown action/alias: " + name);
}
});
}
// easy way to deep copy the configs array
aliases[alias] = JSON.parse(JSON.stringify(configs));
return exists;
}
exports.registerAlias = registerAlias;

var actionRE = new RegExp("(?:^|\\s)(?:([\\-+])(" +
supportedActions.join("|") +
")(?:{([^}]+)})?|([\\-+]?[a-z\\-]+))(?=\\s|$)", "gi");
var emptyActionsRE = /^\s*\{\s*\}\s*$/;

function toActionConfig(line, negation, name, param, alias) {
var cfg;
if (negation === "-") {
cfg = {
actionLine: line.trim(),
negatedName: name,
param: param,
name: 'negate'
};
} else if (alias) {
if (isKnownAlias(alias)) {
cfg = {
actionLine: line.trim(),
configs: aliases[alias],
name: alias
};
} else {
// don't remove because we didn't parse it
return line;
}
} else {
// no name validation because it came from the RegExp match
cfg = {
actionLine: line.trim(),
param: param,
name: name
};
}
this.push(cfg);
return "";
}

function parseActions(actionsClause) {
var actions = [];
var remainder = actionsClause.replace(actionRE, function() {
actions.push(Array.prototype.slice.call(arguments, 1));
return "";
});
var remainder = actionsClause.replace(actionRE,
toActionConfig.bind(actions));
if (!emptyActionsRE.test(remainder)) {
throw new Error("Malformed actions clause:\n\n" + actionsClause);
}
Expand Down
23 changes: 22 additions & 1 deletion test/test-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,32 @@ exports["test parse valid"] = function(assert) {
"+block{nothing}",
"-handle-as-image",
"}"
].join("\n"));
].join(" "));
assert.ok(actions, "Actions were parsed");
assert.strictEqual(actions.length, 2, "Correct number of actions");
};

exports["test parse register alias"] = function(assert) {
var actionsClause = [
"{",
"+block{nothing}",
"foo",
"-handle-as-image",
"}"
].join(" ");
assert.throws(function() {
actionMgr.parseActions(actionsClause);
}, "Unrecognized alias inside braces");
actionMgr.registerAlias("foo", [{
name: "filter",
param: "foo"
}]);
actions = actionMgr.parseActions(actionsClause);
assert.ok(actions, "Actions with alias were parsed");
assert.strictEqual(actions.length, 3, "Correct number of actions");
actionMgr.clearAliases();
};

exports["test parse invalid"] = function(assert) {
assert.throws(function() {
actionMgr.parseActions("{ foo +block{nothing} -handle-as-image }");
Expand Down

0 comments on commit 62d118b

Please sign in to comment.