Skip to content

Instantly share code, notes, and snippets.

@AutoSponge
Last active December 14, 2015 21:59
Show Gist options
  • Save AutoSponge/5155322 to your computer and use it in GitHub Desktop.
Save AutoSponge/5155322 to your computer and use it in GitHub Desktop.
(function (global, pubsub, cache) {
function push(prop) {
return function (val) {
this[prop].push(val);
return this;
};
}
function fire(data) {
var proceed = true;
this.start.every(function (fn) {
return !fn(data) && (proceed = false);
});
if (proceed) {
this.stop.some(function (fn) {
return fn(data) && !(proceed = false);
});
}
if (proceed) {
this.action.forEach(function (fn) {
fn(data);
});
}
}
function Feature(description) {
if (!(this instanceof Feature)) {
return new Feature(description);
}
this.description = description;
this.start = [];
this.stop = [];
this.action = [];
this.fire = fire.bind(this);
this.topic = null;
cache[description] = this;
}
Feature.get = function (description) {
return cache[description];
};
Feature.mung = function (prop, rename) {
this.prototype[rename] = this.prototype[prop];
return this;
};
Feature.prototype = {
given: push("start"),
unless: push("stop"),
then: push("action"),
until: function (topic) {
var self = this;
pubsub.subscribe(topic, function () {
pubsub.unsubscribe(self.topic, self.fire);
});
return this;
},
when: function (topic) {
this.topic = topic;
pubsub.subscribe(topic, this.fire);
return this;
}
};
Feature.mung("given", "and")
.mung("unless", "or");
global.Feature = Feature;
}(this, pubsub, {}));
Feature("run FeatA under the right conditions")
.given(function (data) {return typeof data === "number";})
.and(function (data) {return !!data;})
.when("FeatA")
.then(function(data){console.log("pass", data);})
.unless(function (data) {return data === 1})
.or(function (data) {return data%2 === 0})
.until("stopFeatA");
pubsub.publish("FeatA", 3) //pass 3
.publish("FeatA", 1) //nothing
.publish("FeatA", 2) //nothing
.publish("stopFeatA")
.publish("FeatA", 3) //nothing
Feature.get("run FeatA under the right conditions").fire(3); //pass 3
(function (global, cache) {
global.pubsub = {
publish: function (topic, data) {
(cache[topic] || []).forEach(function (sub) {
sub(data);
});
return this;
},
subscribe: function (topic, fn) {
(cache[topic] = cache[topic] || []).push(fn);
return this;
},
unsubscribe: function (topic, fn) {
(cache[topic] || []).some(function (sub, i, arr) {
return sub === fn && !!(arr.splice(i, 1));
});
return this;
}
};
}(this, {}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment