Add #fetch Utility function
The #fetch utility acts in (roughly) the same way as Ruby's Hash#fetch function. This addition should hopefully make constructors more rigorous and help to prevent a few classes of errors.
This commit is contained in:
parent
af8cfbe333
commit
6f42b061b3
55
lib/utils.js
55
lib/utils.js
|
@ -183,6 +183,61 @@ var Utils = module.exports = {
|
|||
};
|
||||
},
|
||||
|
||||
// Public: Analogue to Ruby's Hash#fetch method for looking up object
|
||||
// properties.
|
||||
//
|
||||
// obj - object to do property lookup on
|
||||
// property - string property name to attempt to look up
|
||||
// fallback - either:
|
||||
// - a fallback value to return if `property` can't be found
|
||||
// - a function to be executed if `property` can't be found. The function
|
||||
// will be passed `property` as an argument.
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// var object = { property: "hello world" };
|
||||
// fetch(object, "property");
|
||||
// //=> "hello world"
|
||||
//
|
||||
// fetch(object, "notaproperty", "default value");
|
||||
// //=> "default value"
|
||||
//
|
||||
// var notFound = function(prop) { return prop + " not found!" };
|
||||
// fetch(object, "notaproperty", notFound)
|
||||
// // "notaproperty not found!"
|
||||
//
|
||||
// var badFallback = function(prop) { prop + " not found!" };
|
||||
// fetch(object, "notaproperty", badFallback)
|
||||
// // Error: no return value from provided callback function
|
||||
//
|
||||
// fetch(object, "notaproperty");
|
||||
// // Error: key not found: "notaproperty"
|
||||
//
|
||||
// Returns the value of obj[property], a fallback value, or the results of
|
||||
// running 'fallback'. If the property isn't found, and 'fallback' hasn't been
|
||||
// provided, will throw an error.
|
||||
fetch: function(obj, property, fallback) {
|
||||
if (obj.hasOwnProperty(property)) {
|
||||
return obj[property];
|
||||
}
|
||||
|
||||
if (fallback === void 0) {
|
||||
throw new Error('key not found: "' + property + '"');
|
||||
}
|
||||
|
||||
if (typeof(fallback) === 'function') {
|
||||
var value = fallback(property);
|
||||
|
||||
if (value === void 0) {
|
||||
throw new Error('no return value from provided fallback function');
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return fallback;
|
||||
},
|
||||
|
||||
// Public: Adds necessary utils to global namespace, along with base class
|
||||
// extensions.
|
||||
//
|
||||
|
|
|
@ -222,4 +222,52 @@ describe("Utils", function() {
|
|||
expect(proxy.boundMethod("Hello", "World")).to.eql(["Hello", "World"]);
|
||||
})
|
||||
});
|
||||
|
||||
describe("#fetch", function() {
|
||||
var fetch = utils.fetch,
|
||||
obj = { property: 'hello world', 'false': false, 'null': null };
|
||||
|
||||
context("if the property exists on the object", function() {
|
||||
it("returns the value", function() {
|
||||
expect(fetch(obj, 'property')).to.be.eql('hello world');
|
||||
expect(fetch(obj, 'false')).to.be.eql(false);
|
||||
expect(fetch(obj, 'null')).to.be.eql(null);
|
||||
});
|
||||
});
|
||||
|
||||
context("if the property doesn't exist on the object", function() {
|
||||
context("and no fallback value has been provided", function() {
|
||||
it("throws an Error", function() {
|
||||
var fn = function() { return fetch(obj, "notaproperty"); };
|
||||
expect(fn).to.throw(Error, 'key not found: "notaproperty"');
|
||||
});
|
||||
});
|
||||
|
||||
context("and a fallback value has been provided", function() {
|
||||
it('returns the fallback value', function() {
|
||||
expect(fetch(obj, 'notakey', 'fallback')).to.be.eql('fallback');
|
||||
});
|
||||
});
|
||||
|
||||
context("and a fallback function has been provided", function() {
|
||||
context("if the function has no return value", function() {
|
||||
it("throws an Error", function() {
|
||||
var fn = function() { fetch(obj, 'notakey', function() {}); },
|
||||
str = 'no return value from provided fallback function';
|
||||
|
||||
expect(fn).to.throw(Error, str);
|
||||
});
|
||||
});
|
||||
|
||||
context("if the function returns a value", function() {
|
||||
it("returns the value returned by the fallback function", function() {
|
||||
var fn = function(key) { return "Couldn't find " + key },
|
||||
value = "Couldn't find notakey";
|
||||
|
||||
expect(fetch(obj, 'notakey', fn)).to.be.eql(value);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue