-
-
Save javascripter/54503 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var q; | |
(function () { | |
function forEach(object, fun, self) { | |
for (var k in object) fun.call(self, object[k], k, object); | |
} | |
function generic(source, dest) { | |
// If it isn't generic, transfer to parent(e.g. Array#toString). | |
try {'' + dest;} catch (error) { | |
dest.toString = function () { | |
return source.toString.apply(source, arguments); | |
}; | |
} | |
return dest; | |
}; | |
function clone(object) { | |
return generic(object, {__proto__: object}); | |
} | |
function extend(source, properties) { | |
forEach(properties, function (v, k) {source[k] = v;}); | |
return source; | |
} | |
function create(source, properties) { | |
properties.__proto__ = source; | |
properties.parent = source; | |
return generic(source, properties); | |
} | |
q = create( | |
Object.prototype, {toString: function () {return '[object q]';}}); | |
q.object = create( | |
Object, {clone: clone, extend: extend, create: create, forEach: forEach}); | |
})(); | |
q.fun = q.object.create(Function, { | |
invoke: function (method_name, args) { | |
if (!args) args = []; | |
return function (self) { | |
return self[method_name].apply(self, args); | |
}; | |
}, | |
bind: function (fun, self, args) { | |
if (!args) args = []; | |
return function () { | |
return fun.apply(self, args.concat(q.array.slice(arguments))); | |
}; | |
}, | |
applied: function (fun, self, args) { | |
if (!args) args = []; | |
return function () {return fun.apply(self, args);}; | |
}, | |
compose: function () { | |
var args = arguments; | |
return function (initial) { | |
return q.array.reduceRight( | |
args, function (value, fun) {return fun(value);}, initial); | |
}; | |
} | |
}); | |
q.array = q.object.create(Array, { | |
append: function (array, object) { | |
return this.concat([], array, this.concat([], object)); | |
}, | |
include: function (array, object) { | |
return this.indexOf(array, object) !== -1; | |
}, | |
uniq: function (array) { | |
return this.reduce(array, q.fun.bind( | |
function (unique, object) { | |
if (this.include(unique, object)) return unique; | |
return this.append(unique, object); | |
}, this), []); | |
}, | |
flatten: function (array) { | |
return this.reduce(array, q.fun.bind( | |
function (a, b) { | |
return this.concat(a, b); | |
}, this), []); | |
}, | |
last: function (array) { | |
if (array.length === 0) return undefined; | |
return array[array.length - 1]; | |
} | |
}); | |
q.string = q.object.create(String, { | |
fill: function (format, object) { | |
function injector(m, name) {return object[name];} | |
return format.replace(/{(.*?)}/g, injector); | |
}, | |
gensym: function () { | |
var counter = 0; | |
return function () {return 'gensym_' + (counter++).toString(16);}; | |
}(), | |
w: q.fun.invoke('split', [/\s*/]), | |
escapeHTML: q.fun.compose( | |
q.fun.invoke('replace', [/"/g, '"']), | |
q.fun.invoke('replace', [/</g, '<']), | |
q.fun.invoke('replace', [/>/g, '>']), | |
q.fun.invoke('replace', [/&/g, '&'])) | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
function assert(fun) { | |
var value; | |
try { | |
value = fun(); | |
} catch (ex) { | |
console.error(fun.name, ex, fun.toSource()); | |
return; | |
} | |
if (value) { | |
console.log(fun.name); | |
} else { | |
console.error(fun.name, fun.toSource()); | |
} | |
} | |
assert(function genericToString() { | |
var a = q.object.clone([]); | |
return a.toString() === "" && q.object.toString(); | |
}); | |
assert(function basicClone() { | |
var o = q.object.clone({a: 2, b: 1}); | |
return o.a === 2 && !o.hasOwnProperty("b"); | |
}); | |
assert(function basicExtend() { | |
var o = {a: 1, b: 2}; | |
var p = {a: 2, c: 1}; | |
return q.object.extend(o, p) === o && o.a === 2 && !p.b; | |
}); | |
assert(function basicCreate() { | |
var o = {a: 1}; | |
var p = {}; | |
return q.object.create(o, p) === p && o.a === 1 && p.parent === o; | |
}); | |
assert(function genericToStringWithCreate() { | |
return q.object.create({}, {toString: function () {throw new Error()}}) + ""; | |
}); | |
assert(function basicInvoke() { | |
return q.fun.invoke("toString")(q.object) === q.object.toString(); | |
}); | |
assert(function argsInvoke() { | |
var a = ["a"]; | |
return q.fun.invoke("test", a)(/a/) && q.fun.invoke("test", a)(/a/); | |
}); | |
assert(function basicBind() { | |
var a = []; | |
var f = q.fun.bind(Array.prototype.push, a ,[1]); | |
return f(2, 3) === a.length && a.shift() === 1; | |
}); | |
assert(function basicApplied() { | |
var a = []; | |
q.fun.applied(Array.prototype.push, a, [1]).call(null, 2, 3); | |
return a.length === 1 && a[0] === 1; | |
}); | |
assert(function basicCompose() { | |
var val = q.fun.compose( | |
function (a) { | |
return a + 1; | |
}, | |
function (a) { | |
return a + "x"; | |
} | |
)(0); | |
return val === "0x1"; | |
}); | |
assert(function initialCompose() { | |
return q.fun.compose(function (x) {return x;})() === undefined; | |
}); | |
assert(function inheritedArray() { | |
return q.array.push === Array.push; | |
}); | |
assert(function basicInclude() { | |
return q.array.include([1, 2, 3], 2) && !q.array.include([], undefined) && | |
!q.array.include([new Number(1), null], 1); | |
}); | |
assert(function strictInclude() { | |
var falsy = [undefined, null, false, 0, ""]; | |
return q.array.include(falsy) && !q.array.include(falsy, true) && | |
!q.array.include(falsy, falsy.toString); | |
}); | |
assert(function basicUniq() { | |
var a = [1, 2, 3, 1, 2]; | |
var u = q.array.uniq(a) | |
return u !== a && u[1] === 2; | |
}); | |
assert(function strictUniq() { | |
var a = [new Number(1), new String("a"), null, false, undefined, 0, 1, "a"]; | |
return q.array.uniq(a).length === a.length; | |
}); | |
assert(function basicFlatten() { | |
var a = [[], [1,2], [[1, 2]], 3]; | |
return q.array.flatten(a).length === 4 && !q.array.flatten([]).length && | |
q.array.flatten(a) !== a; | |
}); | |
assert(function basicLast() { | |
return q.array.last([]) === undefined && q.array.last([1, 2]) === 2; | |
}); | |
assert(function basicFill() { | |
return q.string.fill("") === "" && q.string.fill("{0}", ["a"]) == "a" && | |
q.string.fill("{{}}", {"{":1}); | |
}); | |
assert(function basicGensym() { | |
return typeof q.string.gensym() === "string" && | |
q.string.gensym() !== q.string.gensym(); | |
}); | |
assert(function basicW() { | |
var a = q.string.w("a b c"); | |
return q.string.w("").length === 0 && a[1] === "b" && a.length === 3; | |
}); | |
assert(function escapeHTML() { | |
return q.string.escapeHTML("") === "" && | |
q.string.escapeHTML('&"<>&') === "&"<>&amp;"; | |
}); | |
})(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment