krl-stdlib
Advanced tools
Comparing version 0.5.6 to 0.6.0
module.exports = { | ||
"env": { | ||
"es6": true,//only for generator functions | ||
"browser": true, | ||
@@ -9,3 +10,3 @@ "node": true, | ||
"rules": { | ||
"indent": "off", | ||
"indent": ["error", 4], | ||
"no-console": "off", | ||
@@ -12,0 +13,0 @@ "quotes": ["error", "double"], |
{ | ||
"name": "krl-stdlib", | ||
"version": "0.5.6", | ||
"version": "0.6.0", | ||
"description": "Standard library for KRL", | ||
@@ -9,3 +9,3 @@ "main": "src/index.js", | ||
"lint": "eslint src/ && echo lint-ok", | ||
"test": "npm run lint -s && node src/tests.js | tap-min" | ||
"test": "npm run lint -s && node src/tests.js" | ||
}, | ||
@@ -28,5 +28,5 @@ "repository": { | ||
"devDependencies": { | ||
"co-callback": "^1.2.0", | ||
"eslint": "^3.0.1", | ||
"onchange": "^2.5.0", | ||
"tap-min": "^1.1.0", | ||
"tape": "^4.6.0" | ||
@@ -33,0 +33,0 @@ }, |
633
src/index.js
@@ -5,63 +5,77 @@ var _ = require("lodash"); | ||
var iterBase = function*(val, iter){ | ||
var should_continue; | ||
if(_.isArray(val)){ | ||
var i; | ||
for(i = 0; i < val.length; i++){ | ||
should_continue = yield iter(val[i], i, val); | ||
if(!should_continue) break; | ||
} | ||
}else{ | ||
var key; | ||
for(key in val){ | ||
if(_.has(val, key)){ | ||
should_continue = yield iter(val[key], key, val); | ||
if(!should_continue) break; | ||
} | ||
} | ||
} | ||
}; | ||
var stdlib = {}; | ||
var defVarArgOp = function(op, reducer){ | ||
stdlib[op] = function(){ | ||
if(arguments.length === 1){ | ||
return; | ||
} | ||
var r = arguments[1]; | ||
if(op === "-" && arguments.length === 2){ | ||
return -r; | ||
} | ||
var i; | ||
for(i = 2; i < arguments.length; i++){ | ||
r = reducer(r, arguments[i]); | ||
} | ||
return r; | ||
}; | ||
stdlib[op] = function(){ | ||
if(arguments.length === 1){ | ||
return; | ||
} | ||
var r = arguments[1]; | ||
if(op === "-" && arguments.length === 2){ | ||
return -r; | ||
} | ||
var i; | ||
for(i = 2; i < arguments.length; i++){ | ||
r = reducer(r, arguments[i]); | ||
} | ||
return r; | ||
}; | ||
}; | ||
var krlLambda = function(ctx, fn){ | ||
return function(){ | ||
return fn(ctx, _.toArray(arguments)); | ||
}; | ||
}; | ||
defVarArgOp("<", function(r, a){ | ||
return r < a; | ||
return r < a; | ||
}); | ||
defVarArgOp(">", function(r, a){ | ||
return r > a; | ||
return r > a; | ||
}); | ||
defVarArgOp("<=", function(r, a){ | ||
return r <= a; | ||
return r <= a; | ||
}); | ||
defVarArgOp(">=", function(r, a){ | ||
return r >= a; | ||
return r >= a; | ||
}); | ||
defVarArgOp("==", function(r, a){ | ||
return r === a; | ||
return r === a; | ||
}); | ||
defVarArgOp("!=", function(r, a){ | ||
return r !== a; | ||
return r !== a; | ||
}); | ||
defVarArgOp("+", function(r, a){ | ||
return r + a; | ||
return r + a; | ||
}); | ||
defVarArgOp("-", function(r, a){ | ||
return r - a; | ||
return r - a; | ||
}); | ||
defVarArgOp("*", function(r, a){ | ||
return r * a; | ||
return r * a; | ||
}); | ||
defVarArgOp("/", function(r, a){ | ||
return r / a; | ||
return r / a; | ||
}); | ||
defVarArgOp("%", function(r, a){ | ||
return r % a; | ||
return r % a; | ||
}); | ||
stdlib.beesting = function(ctx, val){ | ||
return val + ""; | ||
return val + ""; | ||
}; | ||
@@ -74,87 +88,87 @@ | ||
stdlib["><"] = function(ctx, obj, val){ | ||
if(_.isArray(obj)){ | ||
return _.indexOf(obj,val) >= 0; | ||
}else if(_.isPlainObject(obj)){ | ||
return _.indexOf(_.keys(obj),val) >= 0; | ||
}else{ | ||
return false; | ||
} | ||
if(_.isArray(obj)){ | ||
return _.indexOf(obj,val) >= 0; | ||
}else if(_.isPlainObject(obj)){ | ||
return _.indexOf(_.keys(obj),val) >= 0; | ||
}else{ | ||
return false; | ||
} | ||
}; | ||
stdlib.as = function(ctx, val, type){ | ||
var val_type = stdlib["typeof"](ctx, val); | ||
if(val_type === type){ | ||
return val; | ||
} | ||
if(type === "Boolean"){ | ||
if(val === "false"){ | ||
return false; | ||
var val_type = stdlib["typeof"](ctx, val); | ||
if(val_type === type){ | ||
return val; | ||
} | ||
return !!val; | ||
} | ||
if(val_type === "String"){ | ||
if(type === "Number"){ | ||
return parseFloat(val) || 0; | ||
}else if(type === "RegExp"){ | ||
return new RegExp(val); | ||
if(type === "Boolean"){ | ||
if(val === "false"){ | ||
return false; | ||
} | ||
return !!val; | ||
} | ||
}else if(val_type === "Number"){ | ||
if(type === "String"){ | ||
return val + ""; | ||
if(val_type === "String"){ | ||
if(type === "Number"){ | ||
return parseFloat(val) || 0; | ||
}else if(type === "RegExp"){ | ||
return new RegExp(val); | ||
} | ||
}else if(val_type === "Number"){ | ||
if(type === "String"){ | ||
return val + ""; | ||
} | ||
}else if(val_type === "Boolean"){// eslint-disable-line | ||
}else if(val_type === "Null"){// eslint-disable-line | ||
}else if(val_type === "RegExp"){ | ||
if(type === "String"){ | ||
return val.source; | ||
} | ||
}else if(val_type === "Array"){// eslint-disable-line | ||
}else if(val_type === "Map"){// eslint-disable-line | ||
} | ||
}else if(val_type === "Boolean"){// eslint-disable-line | ||
}else if(val_type === "Null"){// eslint-disable-line | ||
}else if(val_type === "RegExp"){ | ||
if(type === "String"){ | ||
return val.source; | ||
} | ||
}else if(val_type === "Array"){// eslint-disable-line | ||
}else if(val_type === "Map"){// eslint-disable-line | ||
} | ||
throw new Error("Cannot use .as(\""+type+"\") operator with " + JSON.stringify(val)); | ||
throw new Error("Cannot use .as(\""+type+"\") operator with " + JSON.stringify(val)); | ||
}; | ||
stdlib.isnull = function(ctx, val){ | ||
return val === null || val === undefined || _.isNaN(val); | ||
return val === null || val === undefined || _.isNaN(val); | ||
}; | ||
stdlib.klog = function(ctx, val, message){ | ||
ctx.emit("klog", val, message); | ||
return val; | ||
ctx.emit("klog", val, message); | ||
return val; | ||
}; | ||
stdlib["typeof"] = function(ctx, val){ | ||
if(_.isString(val)){ | ||
return "String"; | ||
}else if(_.isNumber(val) && !_.isNaN(val)){ | ||
return "Number"; | ||
}else if(val === true || val === false){ | ||
return "Boolean"; | ||
}else if(stdlib.isnull(ctx, val)){ | ||
return "Null"; | ||
}else if(_.isRegExp(val)){ | ||
return "RegExp"; | ||
}else if(_.isArray(val)){ | ||
return "Array"; | ||
}else if(_.isPlainObject(val)){ | ||
return "Map"; | ||
} | ||
//should we throw up? | ||
if(_.isString(val)){ | ||
return "String"; | ||
}else if(_.isNumber(val) && !_.isNaN(val)){ | ||
return "Number"; | ||
}else if(val === true || val === false){ | ||
return "Boolean"; | ||
}else if(stdlib.isnull(ctx, val)){ | ||
return "Null"; | ||
}else if(_.isRegExp(val)){ | ||
return "RegExp"; | ||
}else if(_.isArray(val)){ | ||
return "Array"; | ||
}else if(_.isPlainObject(val)){ | ||
return "Map"; | ||
} | ||
//should we throw up? | ||
}; | ||
stdlib.sprintf = function(ctx, val, template){ | ||
if(_.isNumber(val)){ | ||
return template.replace(/%d/g, val + ""); | ||
}else if(_.isString(val)){ | ||
return template.replace(/%s/g, val); | ||
} | ||
return template; | ||
if(_.isNumber(val)){ | ||
return template.replace(/%d/g, val + ""); | ||
}else if(_.isString(val)){ | ||
return template.replace(/%s/g, val); | ||
} | ||
return template; | ||
}; | ||
stdlib.defaultsTo = function(ctx, val,defaultVal,message){ | ||
if(_.size(val) === 0){ | ||
if(message !== undefined) ctx.emit("debug", "[DEFAULTSTO] " + message); | ||
return defaultVal; | ||
} else { | ||
return val; | ||
} | ||
if(_.size(val) === 0){ | ||
if(message !== undefined) ctx.emit("debug", "[DEFAULTSTO] " + message); | ||
return defaultVal; | ||
} else { | ||
return val; | ||
} | ||
}; | ||
@@ -164,6 +178,6 @@ | ||
stdlib.chr = function(ctx, val){ | ||
return String.fromCharCode(val); | ||
return String.fromCharCode(val); | ||
}; | ||
stdlib.range = function(ctx, val, end){ | ||
return _.range(val, end + 1); | ||
return _.range(val, end + 1); | ||
}; | ||
@@ -173,269 +187,338 @@ | ||
stdlib.capitalize = function(ctx, val){ | ||
return val[0].toUpperCase() + val.slice(1); | ||
return val[0].toUpperCase() + val.slice(1); | ||
}; | ||
stdlib.decode = function(ctx, val){ | ||
return JSON.parse(val); | ||
return JSON.parse(val); | ||
}; | ||
stdlib.extract = function(ctx, val, regex){ | ||
var r = val.match(regex); | ||
if(!r){ | ||
return []; | ||
} | ||
if(regex.global){ | ||
return r; | ||
} | ||
return r.slice(1); | ||
var r = val.match(regex); | ||
if(!r){ | ||
return []; | ||
} | ||
if(regex.global){ | ||
return r; | ||
} | ||
return r.slice(1); | ||
}; | ||
stdlib.lc = function(ctx, val){ | ||
return val.toLowerCase(); | ||
return val.toLowerCase(); | ||
}; | ||
stdlib.match = function(ctx, val, regex){ | ||
return regex.test(val); | ||
return regex.test(val); | ||
}; | ||
stdlib.ord = function(ctx, val){ | ||
var code = val.charCodeAt(0); | ||
return _.isNaN(code) ? undefined : code; | ||
var code = val.charCodeAt(0); | ||
return _.isNaN(code) ? undefined : code; | ||
}; | ||
stdlib.replace = function(ctx, val, regex, replacement){ | ||
return val.replace(regex, replacement); | ||
return val.replace(regex, replacement); | ||
}; | ||
stdlib.split = function(ctx, val, split_on){ | ||
return val.split(split_on); | ||
return val.split(split_on); | ||
}; | ||
stdlib.substr = function(ctx, val, start, len){ | ||
if(start > val.length){ | ||
return; | ||
} | ||
var end; | ||
if(len === undefined){ | ||
end = val.length; | ||
}else{ | ||
if(len > 0){ | ||
end = start + len; | ||
if(start > val.length){ | ||
return; | ||
} | ||
var end; | ||
if(len === undefined){ | ||
end = val.length; | ||
}else{ | ||
end = val.length + len; | ||
if(len > 0){ | ||
end = start + len; | ||
}else{ | ||
end = val.length + len; | ||
} | ||
} | ||
} | ||
return val.substring(start, end); | ||
return val.substring(start, end); | ||
}; | ||
stdlib.uc = function(ctx, val){ | ||
return val.toUpperCase(); | ||
return val.toUpperCase(); | ||
}; | ||
//Collection operators////////////////////////////////////////////////////////// | ||
stdlib.all = function(ctx, val, iter){ | ||
iter = krlLambda(ctx, iter); | ||
return _.every(val, iter); | ||
stdlib.all = function*(ctx, val, iter){ | ||
var broke = false; | ||
yield iterBase(val, function*(v, k, obj){ | ||
var r = yield iter(ctx, [v, k, obj]); | ||
if(!r){ | ||
broke = true; | ||
return false;//stop | ||
} | ||
return true; | ||
}); | ||
return !broke; | ||
}; | ||
stdlib.notall = function(ctx, val, iter){ | ||
iter = krlLambda(ctx, iter); | ||
return _.some(val, _.negate(iter)); | ||
stdlib.notall = function*(ctx, val, iter){ | ||
return !(yield stdlib.all(ctx, val, iter)); | ||
}; | ||
stdlib.any = function(ctx, val, iter){ | ||
iter = krlLambda(ctx, iter); | ||
return _.some(val, iter); | ||
stdlib.any = function*(ctx, val, iter){ | ||
var broke = false; | ||
yield iterBase(val, function*(v, k, obj){ | ||
var r = yield iter(ctx, [v, k, obj]); | ||
if(r){ | ||
broke = true; | ||
return false;//stop | ||
} | ||
return true; | ||
}); | ||
return broke; | ||
}; | ||
stdlib.none = function(ctx, val, iter){ | ||
iter = krlLambda(ctx, iter); | ||
return _.every(val, _.negate(iter)); | ||
stdlib.none = function*(ctx, val, iter){ | ||
return !(yield stdlib.any(ctx, val, iter)); | ||
}; | ||
stdlib.append = function(ctx, val, others){ | ||
return _.concat.apply(void 0, _.tail(_.toArray(arguments))); | ||
return _.concat.apply(void 0, _.tail(_.toArray(arguments))); | ||
}; | ||
stdlib.collect = function(ctx, val, iter){ | ||
iter = krlLambda(ctx, iter); | ||
return _.groupBy(val, iter); | ||
stdlib.collect = function*(ctx, val, iter){ | ||
var grouped = {}; | ||
yield iterBase(val, function*(v, k, obj){ | ||
var r = yield iter(ctx, [v, k, obj]); | ||
if(!grouped.hasOwnProperty(r)){ | ||
grouped[r] = []; | ||
} | ||
grouped[r].push(v); | ||
return true; | ||
}); | ||
return grouped; | ||
}; | ||
stdlib.filter = function(ctx, val, iter){ | ||
iter = krlLambda(ctx, iter); | ||
if(_.isPlainObject(val)){ | ||
var r = {}; | ||
_.each(val, function(v, k, o){ | ||
if(iter(v, k, o)){ | ||
r[k] = v; | ||
} | ||
stdlib.filter = function*(ctx, val, iter){ | ||
var is_array = _.isArray(val); | ||
var rslt = is_array ? [] : {}; | ||
yield iterBase(val, function*(v, k, obj){ | ||
var r = yield iter(ctx, [v, k, obj]); | ||
if(r){ | ||
if(is_array){ | ||
rslt.push(v); | ||
}else{ | ||
rslt[k] = v; | ||
} | ||
} | ||
return true; | ||
}); | ||
return r; | ||
} | ||
return _.filter(val, iter); | ||
return rslt; | ||
}; | ||
stdlib.head = function(ctx, val){ | ||
return _.head(val); | ||
return _.head(val); | ||
}; | ||
stdlib.tail = function(ctx, val){ | ||
return _.tail(val); | ||
return _.tail(val); | ||
}; | ||
stdlib.index = function(ctx, val, elm){ | ||
return _.indexOf(val, elm); | ||
return _.indexOf(val, elm); | ||
}; | ||
stdlib.join = function(ctx, val, str){ | ||
return _.join(val, str); | ||
return _.join(val, str); | ||
}; | ||
stdlib.length = function(ctx, val){ | ||
return _.size(val); | ||
return _.size(val); | ||
}; | ||
stdlib.map = function(ctx, val, iter){ | ||
iter = krlLambda(ctx, iter); | ||
if(_.isPlainObject(val)){ | ||
return _.mapValues(val, iter); | ||
} | ||
return _.map(val, iter); | ||
stdlib.map = function*(ctx, val, iter){ | ||
var is_array = _.isArray(val); | ||
var rslt = is_array ? [] : {}; | ||
yield iterBase(val, function*(v, k, obj){ | ||
var r = yield iter(ctx, [v, k, obj]); | ||
if(is_array){ | ||
rslt.push(r); | ||
}else{ | ||
rslt[k] = r; | ||
} | ||
return true; | ||
}); | ||
return rslt; | ||
}; | ||
stdlib.pairwise = function(ctx){ | ||
var args = _.tail(_.toArray(arguments)); | ||
args[args.length - 1] = krlLambda(ctx, args[args.length - 1]); | ||
return _.zipWith.apply(void 0, args); | ||
stdlib.pairwise = function*(/*ctx, val..., iter*/){ | ||
var args = _.toArray(arguments); | ||
var ctx = args[0]; | ||
var iter = args[args.length - 1]; | ||
args = args.slice(1, args.length - 1); | ||
var max_len = _.max(_.map(args, _.size)); | ||
var r = []; | ||
var i; | ||
var j; | ||
var args2; | ||
for(i = 0; i < max_len; i++){ | ||
args2 = []; | ||
for(j = 0; j < args.length; j++){ | ||
args2.push(args[j][i]); | ||
} | ||
r.push(yield iter(ctx, args2)); | ||
} | ||
return r; | ||
}; | ||
stdlib.reduce = function(ctx, val, iter, dflt){ | ||
iter = krlLambda(ctx, iter); | ||
if(_.size(val) === 0){ | ||
if(arguments.length < 4){ | ||
return 0; | ||
stdlib.reduce = function*(ctx, val, iter, dflt){ | ||
var no_default = arguments.length < 4; | ||
if(_.size(val) === 0){ | ||
return no_default ? 0 : dflt; | ||
} | ||
return dflt; | ||
} | ||
if(_.size(val) === 1){ | ||
if(arguments.length < 4){ | ||
return _.head(val); | ||
if(_.size(val) === 1){ | ||
if(no_default){ | ||
return _.head(val); | ||
} | ||
return iter(ctx, [dflt, _.head(val)]); | ||
} | ||
return iter(dflt, _.head(val)); | ||
} | ||
if(arguments.length < 4){ | ||
return _.reduce(val, iter); | ||
} | ||
return _.reduce(val, iter, dflt); | ||
var acc = dflt; | ||
var is_first = true; | ||
yield iterBase(val, function*(v, k, obj){ | ||
if(is_first && no_default){ | ||
is_first = false; | ||
acc = v; | ||
return true;//continue | ||
} | ||
acc = yield iter(ctx, [acc, v, k, obj]); | ||
return true;//continue | ||
}); | ||
return acc; | ||
}; | ||
stdlib.reverse = function(ctx, val){ | ||
return _.reverse(_.clone(val)); | ||
return _.reverse(_.clone(val)); | ||
}; | ||
stdlib.slice = function(ctx, val, start, end){ | ||
if(start < 0 || start > _.size(val)){ | ||
return; | ||
} | ||
if(arguments.length < 4){ | ||
return _.slice(val, 0, start + 1); | ||
} | ||
if(end < 0 || end > _.size(val)){ | ||
return; | ||
} | ||
return _.slice(val, start, end + 1); | ||
if(start < 0 || start > _.size(val)){ | ||
return; | ||
} | ||
if(arguments.length < 4){ | ||
return _.slice(val, 0, start + 1); | ||
} | ||
if(end < 0 || end > _.size(val)){ | ||
return; | ||
} | ||
return _.slice(val, start, end + 1); | ||
}; | ||
stdlib.splice = function(ctx, val, start, n_elms, value){ | ||
var part1 = _.slice(val, 0, start); | ||
var part2 = _.slice(val, start + n_elms); | ||
if(arguments.length < 5){ | ||
return _.concat(part1, part2); | ||
} | ||
return _.concat(part1, value, part2); | ||
var part1 = _.slice(val, 0, start); | ||
var part2 = _.slice(val, start + n_elms); | ||
if(arguments.length < 5){ | ||
return _.concat(part1, part2); | ||
} | ||
return _.concat(part1, value, part2); | ||
}; | ||
stdlib.sort = (function(){ | ||
var sorters = { | ||
"numeric": function(a, b){ | ||
return a < b ? -1 : (a == b ? 0 : 1); | ||
}, | ||
"ciremun": function(a, b){ | ||
return a < b ? 1 : (a == b ? 0 : -1); | ||
} | ||
}; | ||
return function(ctx, val, sort_by){ | ||
if(sort_by === "reverse"){ | ||
//TODO optimize by making a "reverse" sorter function | ||
return _.clone(val).sort().reverse(); | ||
} | ||
var iter; | ||
if(_.isFunction(sort_by)){ | ||
iter = krlLambda(ctx, sort_by); | ||
}else if(_.has(sorters, sort_by)){ | ||
iter = sorters[sort_by]; | ||
} | ||
return _.clone(val).sort(iter); | ||
}; | ||
var sorters = { | ||
"numeric": function(a, b){ | ||
return a < b ? -1 : (a == b ? 0 : 1); | ||
}, | ||
"ciremun": function(a, b){ | ||
return a < b ? 1 : (a == b ? 0 : -1); | ||
} | ||
}; | ||
var swap = function(arr, i, j){ | ||
var temp = arr[i]; | ||
arr[i] = arr[j]; | ||
arr[j] = temp; | ||
}; | ||
return function*(ctx, val, sort_by){ | ||
if(sort_by === "reverse"){ | ||
//TODO optimize by making a "reverse" sorter function | ||
return _.clone(val).sort().reverse(); | ||
}else if(_.has(sorters, sort_by)){ | ||
return _.clone(val).sort(sorters[sort_by]); | ||
}else if(!_.isFunction(sort_by)){ | ||
return _.clone(val).sort(); | ||
} | ||
var sorted = _.clone(val); | ||
var i, j, a, b; | ||
var len = sorted.length; | ||
for (i = len - 1; i >= 0; i--){ | ||
for(j = 1; j <= i; j++){ | ||
a = sorted[j-1]; | ||
b = sorted[j]; | ||
if((yield sort_by(ctx, [a, b])) > 0){ | ||
swap(sorted, j-1, j); | ||
} | ||
} | ||
} | ||
return sorted; | ||
}; | ||
}()); | ||
stdlib["delete"] = function(ctx, val, path){ | ||
//TODO optimize | ||
var n_val = _.cloneDeep(val); | ||
_.unset(n_val, path); | ||
return n_val; | ||
//TODO optimize | ||
var n_val = _.cloneDeep(val); | ||
_.unset(n_val, path); | ||
return n_val; | ||
}; | ||
stdlib.put = function(ctx, val, path, to_set){ | ||
if(arguments.length < 4){ | ||
return _.assign({}, val, path); | ||
} | ||
//TODO optimize | ||
var n_val = _.cloneDeep(val); | ||
_.update(n_val, path, function(at_p){ | ||
return _.assign(at_p, to_set); | ||
}); | ||
return n_val; | ||
if(arguments.length < 4){ | ||
return _.assign({}, val, path); | ||
} | ||
//TODO optimize | ||
var n_val = _.cloneDeep(val); | ||
_.update(n_val, path, function(at_p){ | ||
return _.assign(at_p, to_set); | ||
}); | ||
return n_val; | ||
}; | ||
stdlib.encode = function(ctx, val){ | ||
//TODO options??? | ||
return JSON.stringify(val); | ||
//TODO options??? | ||
return JSON.stringify(val); | ||
}; | ||
stdlib.keys = function(ctx, val, path){ | ||
if(path){ | ||
return _.keys(_.get(val, path)); | ||
} | ||
return _.keys(val); | ||
if(path){ | ||
return _.keys(_.get(val, path)); | ||
} | ||
return _.keys(val); | ||
}; | ||
stdlib.values = function(ctx, val, path){ | ||
if(path){ | ||
return _.values(_.get(val, path)); | ||
} | ||
return _.values(val); | ||
if(path){ | ||
return _.values(_.get(val, path)); | ||
} | ||
return _.values(val); | ||
}; | ||
stdlib.intersection = function(ctx, a, b){ | ||
return _.intersection(a, b); | ||
return _.intersection(a, b); | ||
}; | ||
stdlib.union = function(ctx, a, b){ | ||
return _.unionWith(a, b, _.isEqual); | ||
return _.unionWith(a, b, _.isEqual); | ||
}; | ||
stdlib.difference = function(ctx, a, b){ | ||
return _.differenceWith(a, b, _.isEqual); | ||
return _.differenceWith(a, b, _.isEqual); | ||
}; | ||
stdlib.has = function(ctx, val, other){ | ||
return _.every(other, function(e){ | ||
return _.includes(val, e); | ||
}); | ||
return _.every(other, function(e){ | ||
return _.includes(val, e); | ||
}); | ||
}; | ||
stdlib.once = function(ctx, val){ | ||
//TODO optimize | ||
var r = []; | ||
_.each(_.groupBy(val), function(group){ | ||
if(_.size(group) === 1){ | ||
r.push(_.head(group)); | ||
} | ||
}); | ||
return r; | ||
//TODO optimize | ||
var r = []; | ||
_.each(_.groupBy(val), function(group){ | ||
if(_.size(group) === 1){ | ||
r.push(_.head(group)); | ||
} | ||
}); | ||
return r; | ||
}; | ||
stdlib.duplicates = function(ctx, val){ | ||
//TODO optimize | ||
var r = []; | ||
_.each(_.groupBy(val), function(group){ | ||
if(_.size(group) > 1){ | ||
r.push(_.head(group)); | ||
} | ||
}); | ||
return r; | ||
//TODO optimize | ||
var r = []; | ||
_.each(_.groupBy(val), function(group){ | ||
if(_.size(group) > 1){ | ||
r.push(_.head(group)); | ||
} | ||
}); | ||
return r; | ||
}; | ||
stdlib.randomWord = function(ctx){ | ||
return randomWords(); | ||
return randomWords(); | ||
}; | ||
stdlib.uuid = function(ctx){ | ||
return cuid(); | ||
return cuid(); | ||
}; | ||
stdlib.unique = function(ctx, val){ | ||
return _.uniq(val); | ||
return _.uniq(val); | ||
}; | ||
stdlib["get"] = function(ctx, obj, path) { | ||
return _.get(obj,path); | ||
return _.get(obj,path); | ||
}; | ||
stdlib["set"] = function(ctx, obj, path, val) { | ||
//TODO optimize | ||
return _.set(_.cloneDeep(obj), path, val); | ||
//TODO optimize | ||
return _.set(_.cloneDeep(obj), path, val); | ||
}; | ||
module.exports = stdlib; |
649
src/tests.js
var _ = require("lodash"); | ||
var cocb = require("co-callback"); | ||
var test = require("tape"); | ||
var stdlib = require("./"); | ||
var ylibFn = function(fn_name, args){ | ||
args = [defaultCTX].concat(args); | ||
var fn = stdlib[fn_name]; | ||
if(cocb.isGeneratorFunction(fn)){ | ||
return cocb.promiseRun(function*(){ | ||
return yield fn.apply(void 0, args); | ||
}); | ||
} | ||
return new Promise(function(resolve, reject){ | ||
try{ | ||
resolve(fn.apply(void 0, args)); | ||
}catch(err){ | ||
reject(err); | ||
} | ||
}); | ||
}; | ||
var assertThrows = function(t, fn, args){ | ||
try{ | ||
fn.apply(null, args); | ||
t.fail(); | ||
}catch(e){ | ||
t.ok(true); | ||
} | ||
try{ | ||
fn.apply(null, args); | ||
t.fail(); | ||
}catch(e){ | ||
t.ok(true); | ||
} | ||
}; | ||
var defaultCTX = { | ||
emit: _.noop | ||
emit: _.noop | ||
}; | ||
var testFn = function(t, fn, args, expected, message){ | ||
//wrap lambdas as KRL Closures | ||
args = _.map(args, function(arg){ | ||
if(_.isFunction(arg)){ | ||
return function(ctx, args){ | ||
return arg.apply(this, args); | ||
}; | ||
} | ||
return arg; | ||
}); | ||
t.deepEquals(stdlib[fn].apply(null, [defaultCTX].concat(args)), expected, message); | ||
//wrap lambdas as KRL Closures | ||
args = _.map(args, function(arg){ | ||
if(_.isFunction(arg)){ | ||
return function(ctx, args){ | ||
return arg.apply(this, args); | ||
}; | ||
} | ||
return arg; | ||
}); | ||
t.deepEquals(stdlib[fn].apply(null, [defaultCTX].concat(args)), expected, message); | ||
}; | ||
var mkTf = function(t){ | ||
return function*(fn, args, expected, message){ | ||
args = _.map(args, function(arg){ | ||
if(cocb.isGeneratorFunction(arg)){ | ||
return function*(ctx, args){ | ||
return yield arg.apply(this, args); | ||
}; | ||
}else if(_.isFunction(arg)){ | ||
return cocb.toYieldable(function(ctx, args, callback){ | ||
var data; | ||
try{ | ||
data = arg.apply(this, args); | ||
}catch(err){ | ||
callback(err); | ||
return; | ||
} | ||
callback(null, data); | ||
}); | ||
} | ||
return arg; | ||
}); | ||
t.deepEquals( | ||
yield ylibFn(fn, args), | ||
expected, | ||
message | ||
); | ||
}; | ||
}; | ||
var ytest = function(msg, body){ | ||
test(msg, function(t){ | ||
var tf = _.partial(testFn, t); | ||
var ytf = mkTf(t); | ||
cocb.run(body(t, ytf, tf), t.end); | ||
}); | ||
}; | ||
test("general operators", function(t){ | ||
var tf = _.partial(testFn, t); | ||
tf("+", [], void 0); | ||
tf("+", [1], 1); | ||
tf("+", [1, 2], 3); | ||
tf("+", [1, 2, 3], 6); | ||
tf("-", [1, 2, 3], -4); | ||
tf("-", [4, 1], 3); | ||
tf("-", [2], -2); | ||
var tf = _.partial(testFn, t); | ||
tf("+", [], void 0); | ||
tf("+", [1], 1); | ||
tf("+", [1, 2], 3); | ||
tf("+", [1, 2, 3], 6); | ||
tf("-", [1, 2, 3], -4); | ||
tf("-", [4, 1], 3); | ||
tf("-", [2], -2); | ||
tf("<", [1, 3], true); | ||
tf("<", [3, 1], false); | ||
tf("<", [1, 3], true); | ||
tf("<", [3, 1], false); | ||
tf("*", [5, 2], 10); | ||
tf("/", [4, 2], 2); | ||
tf("%", [4, 2], 0); | ||
tf("*", [5, 2], 10); | ||
tf("/", [4, 2], 2); | ||
tf("%", [4, 2], 0); | ||
t.end(); | ||
t.end(); | ||
}); | ||
@@ -53,308 +109,313 @@ | ||
var tf = _.partial(testFn, t); | ||
tf("as", [1, "String"], "1"); | ||
var tf = _.partial(testFn, t); | ||
tf("as", [1, "String"], "1"); | ||
tf("as", [1, "String"], "1"); | ||
tf("as", [.32, "String"], "0.32"); | ||
assertThrows(t, stdlib.as, [defaultCTX, NaN, "String"]); | ||
tf("as", ["-1.23", "Number"], -1.23); | ||
t.equals(stdlib.as(defaultCTX, "^a.*z$", "RegExp").source, /^a.*z$/.source); | ||
tf("as", [42, "Number"], 42); | ||
tf("as", ["str", "String"], "str"); | ||
var test_regex = /^a.*z$/; | ||
tf("as", [test_regex, "RegExp"], test_regex); | ||
tf("as", ["true", "Boolean"], true); | ||
tf("as", ["false", "Boolean"], false); | ||
tf("as", [0, "Boolean"], false); | ||
tf("as", [1, "String"], "1"); | ||
tf("as", [.32, "String"], "0.32"); | ||
assertThrows(t, stdlib.as, [defaultCTX, NaN, "String"]); | ||
tf("as", ["-1.23", "Number"], -1.23); | ||
t.equals(stdlib.as(defaultCTX, "^a.*z$", "RegExp").source, /^a.*z$/.source); | ||
tf("as", [42, "Number"], 42); | ||
tf("as", ["str", "String"], "str"); | ||
var test_regex = /^a.*z$/; | ||
tf("as", [test_regex, "RegExp"], test_regex); | ||
tf("as", ["true", "Boolean"], true); | ||
tf("as", ["false", "Boolean"], false); | ||
tf("as", [0, "Boolean"], false); | ||
tf("isnull", [], true); | ||
tf("isnull", [void 0], true); | ||
tf("isnull", [null], true); | ||
tf("isnull", [NaN], true); | ||
tf("isnull", [false], false); | ||
tf("isnull", [0], false); | ||
tf("isnull", [""], false); | ||
tf("isnull", [{}], false); | ||
tf("isnull", [], true); | ||
tf("isnull", [void 0], true); | ||
tf("isnull", [null], true); | ||
tf("isnull", [NaN], true); | ||
tf("isnull", [false], false); | ||
tf("isnull", [0], false); | ||
tf("isnull", [""], false); | ||
tf("isnull", [{}], false); | ||
tf("typeof", [""], "String"); | ||
tf("typeof", [0], "Number"); | ||
tf("typeof", [-.01], "Number"); | ||
tf("typeof", [10e10], "Number"); | ||
tf("typeof", [true], "Boolean"); | ||
tf("typeof", [false], "Boolean"); | ||
tf("typeof", [void 0], "Null"); | ||
tf("typeof", [null], "Null"); | ||
tf("typeof", [NaN], "Null"); | ||
tf("typeof", [/a/], "RegExp"); | ||
tf("typeof", [[]], "Array"); | ||
tf("typeof", [{}], "Map"); | ||
tf("typeof", [""], "String"); | ||
tf("typeof", [0], "Number"); | ||
tf("typeof", [-.01], "Number"); | ||
tf("typeof", [10e10], "Number"); | ||
tf("typeof", [true], "Boolean"); | ||
tf("typeof", [false], "Boolean"); | ||
tf("typeof", [void 0], "Null"); | ||
tf("typeof", [null], "Null"); | ||
tf("typeof", [NaN], "Null"); | ||
tf("typeof", [/a/], "RegExp"); | ||
tf("typeof", [[]], "Array"); | ||
tf("typeof", [{}], "Map"); | ||
t.end(); | ||
t.end(); | ||
}); | ||
test("Number operators", function(t){ | ||
var tf = _.partial(testFn, t); | ||
var tf = _.partial(testFn, t); | ||
tf("chr", [74], "J"); | ||
tf("chr", [74], "J"); | ||
tf("range", [0, 0], [0]); | ||
tf("range", [0, 10], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); | ||
tf("range", [0, 0], [0]); | ||
tf("range", [0, 10], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); | ||
tf("sprintf", [.25, "That is %d"], "That is 0.25"); | ||
tf("sprintf", [.25, "That is %d"], "That is 0.25"); | ||
t.end(); | ||
t.end(); | ||
}); | ||
test("String operators", function(t){ | ||
var tf = _.partial(testFn, t); | ||
var tf = _.partial(testFn, t); | ||
tf("sprintf", ["Bob", "Hi %s!"], "Hi Bob!"); | ||
tf("sprintf", ["Bob", "Hi %s!"], "Hi Bob!"); | ||
tf("capitalize", ["lower"], "Lower"); | ||
tf("capitalize", ["lower"], "Lower"); | ||
tf("decode", ["[1,2,3]"], [1, 2, 3]); | ||
tf("decode", ["[1,2,3]"], [1, 2, 3]); | ||
tf("extract", ["3 + 2 - 1", /([0-9])/g], ["3", "2", "1"]); | ||
tf("extract", ["no-match", /([0-9])/g], []); | ||
tf("extract", ["This is a string", /(is)/], ["is"]); | ||
tf("extract", ["This is a string", /(s.+).*(.ing)/], ["s is a st", "ring"]); | ||
tf("extract", ["This is a string", /(boot)/], []); | ||
tf("extract", ["I like cheese", /like (\w+)/], ["cheese"]); | ||
tf("extract", ["I like cheese", /(e)/g], ["e", "e", "e", "e"]); | ||
tf("extract", ["3 + 2 - 1", /([0-9])/g], ["3", "2", "1"]); | ||
tf("extract", ["no-match", /([0-9])/g], []); | ||
tf("extract", ["This is a string", /(is)/], ["is"]); | ||
tf("extract", ["This is a string", /(s.+).*(.ing)/], ["s is a st", "ring"]); | ||
tf("extract", ["This is a string", /(boot)/], []); | ||
tf("extract", ["I like cheese", /like (\w+)/], ["cheese"]); | ||
tf("extract", ["I like cheese", /(e)/g], ["e", "e", "e", "e"]); | ||
tf("lc", ["UppER"], "upper"); | ||
tf("lc", ["UppER"], "upper"); | ||
tf("match", ["3 + 2 - 1", /([0-9])/g], true); | ||
tf("match", ["no-match", /([0-9])/g], false); | ||
tf("match", ["3 + 2 - 1", /([0-9])/g], true); | ||
tf("match", ["no-match", /([0-9])/g], false); | ||
tf("ord", [""], void 0); | ||
tf("ord", ["a"], 97); | ||
tf("ord", ["bill"], 98); | ||
tf("ord", [""], void 0); | ||
tf("ord", ["a"], 97); | ||
tf("ord", ["bill"], 98); | ||
tf("replace", ["William", /W/, "B"], "Billiam"); | ||
tf("replace", ["William", /W/, "B"], "Billiam"); | ||
tf("split", ["a;b;3;4;", /;/], ["a", "b", "3", "4", ""]); | ||
tf("split", ["a;b;3;4;", /;/], ["a", "b", "3", "4", ""]); | ||
tf("substr", ["This is a string", 5], "is a string"); | ||
tf("substr", ["This is a string", 5, 4], "is a"); | ||
tf("substr", ["This is a string", 5, -5], "is a s"); | ||
tf("substr", ["This is a string", 25], void 0); | ||
tf("substr", ["This is a string", 5], "is a string"); | ||
tf("substr", ["This is a string", 5, 4], "is a"); | ||
tf("substr", ["This is a string", 5, -5], "is a s"); | ||
tf("substr", ["This is a string", 25], void 0); | ||
tf("uc", ["loWer"], "LOWER"); | ||
tf("uc", ["loWer"], "LOWER"); | ||
t.end(); | ||
t.end(); | ||
}); | ||
test("Collection operators", function(t){ | ||
var tf = _.partial(testFn, t); | ||
ytest("Collection operators", function*(t, ytf, tf){ | ||
var a = [3, 4, 5]; | ||
var a = [3, 4, 5]; | ||
var obj = { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": {"bar": {"10": "I like cheese"}} | ||
}; | ||
var obj2 = {"a": 1, "b": 2, "c": 3}; | ||
var assertObjNotMutated = function(){ | ||
t.deepEquals(obj, { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": {"bar": {"10": "I like cheese"}} | ||
}, "should not be mutated"); | ||
t.deepEquals(obj2, {"a": 1, "b": 2, "c": 3}, "should not be mutated"); | ||
}; | ||
var obj = { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": {"bar": {"10": "I like cheese"}} | ||
}; | ||
var obj2 = {"a": 1, "b": 2, "c": 3}; | ||
var assertObjNotMutated = function(){ | ||
t.deepEquals(obj, { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": {"bar": {"10": "I like cheese"}} | ||
}, "should not be mutated"); | ||
t.deepEquals(obj2, {"a": 1, "b": 2, "c": 3}, "should not be mutated"); | ||
}; | ||
tf("><",[obj,"pi"],true); | ||
tf("><",[obj,"a"],false); | ||
assertObjNotMutated(); | ||
tf("><",[[5, 6, 7],6],true); | ||
tf("><",[[5, 6, 7],3],false); | ||
tf("><",[obj,"pi"],true); | ||
tf("><",[obj,"a"],false); | ||
assertObjNotMutated(); | ||
tf("><",[[5, 6, 7],6],true); | ||
tf("><",[[5, 6, 7],3],false); | ||
var exp = [ | ||
["all", true, false, false], | ||
["notall", false, true, true], | ||
["any", true, true, false], | ||
["none", false, false, true] | ||
]; | ||
var i; | ||
for(i=0; i < exp.length; i++){ | ||
yield ytf(exp[i][0], [a, function(x){return x < 10;}], exp[i][1]); | ||
yield ytf(exp[i][0], [a, function(x){return x > 3;}], exp[i][2]); | ||
yield ytf(exp[i][0], [a, function(x){return x > 10;}], exp[i][3]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
} | ||
_.each({ | ||
"all": [ true, false, false], | ||
"notall": [false, true, true], | ||
"any": [ true, true, false], | ||
"none": [false, false, true] | ||
}, function(expected, fn){ | ||
tf(fn, [a, function(x){return x < 10;}], expected[0]); | ||
tf(fn, [a, function(x){return x > 3;}], expected[1]); | ||
tf(fn, [a, function(x){return x > 10;}], expected[2]); | ||
tf("append", [a, [6]], [3, 4, 5, 6]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
}); | ||
tf("append", [["a", "b"], ["c", "d"]], ["a", "b", "c", "d"]); | ||
tf("append", [["a", "b"], 10, 11], ["a", "b", 10, 11]); | ||
tf("append", [10, 11], [10, 11]); | ||
tf("append", [a, [6]], [3, 4, 5, 6]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("append", [["a", "b"], ["c", "d"]], ["a", "b", "c", "d"]); | ||
tf("append", [["a", "b"], 10, 11], ["a", "b", 10, 11]); | ||
tf("append", [10, 11], [10, 11]); | ||
yield ytf("collect", [[7, 4, 3, 5, 2, 1, 6], function(a){ | ||
return (a < 5) ? "x" : "y"; | ||
}], { | ||
"x": [4,3,2,1], | ||
"y": [7,5,6] | ||
}); | ||
tf("collect", [[7, 4, 3, 5, 2, 1, 6], function(a){ | ||
return (a < 5) ? "x" : "y"; | ||
}], { | ||
"x": [4,3,2,1], | ||
"y": [7,5,6] | ||
}); | ||
yield ytf("filter", [a, function(x){return x < 5;}], [3, 4]); | ||
yield ytf("filter", [a, function(x){return x !== 4;}], [3, 5]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
yield ytf("filter", [obj2, function(v, k){return v < 3;}], {"a":1,"b":2}); | ||
yield ytf("filter", [obj2, function(v, k){return k === "b";}], {"b":2}); | ||
assertObjNotMutated(); | ||
tf("filter", [a, function(x){return x < 5;}], [3, 4]); | ||
tf("filter", [a, function(x){return x !== 4;}], [3, 5]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("filter", [obj2, function(v, k){return v < 3;}], {"a":1,"b":2}); | ||
tf("filter", [obj2, function(v, k){return k === "b";}], {"b":2}); | ||
assertObjNotMutated(); | ||
tf("head", [a], 3); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("head", [[]], void 0); | ||
tf("head", [a], 3); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("head", [[]], void 0); | ||
tf("tail", [a], [4, 5]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("tail", [[]], []); | ||
tf("tail", [a], [4, 5]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("tail", [[]], []); | ||
tf("index", [a, 5], 2); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("index", [a, 5], 2); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("join", [a, ";"], "3;4;5"); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("join", [a, ";"], "3;4;5"); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("length", [a], 3); | ||
tf("length", [a], 3); | ||
yield ytf("map", [a, function(x){return x + 2;}], [5, 6, 7]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
yield ytf("map", [obj2, function(x){return x + 2;}], {"a":3,"b":4,"c":5}); | ||
assertObjNotMutated(); | ||
tf("map", [a, function(x){return x + 2;}], [5, 6, 7]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("map", [obj2, function(x){return x + 2;}], {"a":3,"b":4,"c":5}); | ||
assertObjNotMutated(); | ||
yield ytf("pairwise", [a, [6, 7, 8], function(x, y){return x + y;}], [9, 11, 13]); | ||
yield ytf("pairwise", [a, "abcdef".split(""), function(x, y){return x + y;}], [ | ||
"3a", | ||
"4b", | ||
"5c", | ||
"undefinedd", | ||
"undefinede", | ||
"undefinedf", | ||
]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("pairwise", [a, [6, 7, 8], function(x, y){return x + y;}], [9, 11, 13]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
yield ytf("reduce", [a, function(a,b){return a+b;}], 12); | ||
yield ytf("reduce", [a, function(a,b){return a+b;}, 10], 22); | ||
yield ytf("reduce", [a, function(a,b){return a-b;}], -6); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
yield ytf("reduce", [[], function(a,b){return a+b;}], 0); | ||
yield ytf("reduce", [[], function(a,b){return a+b;}, 15], 15); | ||
yield ytf("reduce", [[76], function(a,b){return a+b;}], 76); | ||
yield ytf("reduce", [[76], function(a,b){return a+b;}, 15], 91); | ||
tf("reduce", [a, function(a,b){return a+b;}], 12); | ||
tf("reduce", [a, function(a,b){return a+b;}, 10], 22); | ||
tf("reduce", [a, function(a,b){return a-b;}], -6); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("reduce", [[], function(a,b){return a+b;}], 0); | ||
tf("reduce", [[], function(a,b){return a+b;}, 15], 15); | ||
tf("reduce", [[76], function(a,b){return a+b;}], 76); | ||
tf("reduce", [[76], function(a,b){return a+b;}, 15], 91); | ||
tf("reverse", [a], [5, 4, 3]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
tf("reverse", [a], [5, 4, 3]); | ||
t.deepEquals(a, [3, 4, 5], "should not be mutated"); | ||
var vegies = ["corn","tomato","tomato","tomato","sprouts","lettuce","sprouts"]; | ||
tf("slice", [vegies, 1, 4], ["tomato","tomato","tomato","sprouts"]); | ||
tf("slice", [vegies, 2], ["corn","tomato","tomato"]); | ||
tf("slice", [vegies, 14], void 0); | ||
tf("slice", [vegies, 0, 0], ["corn"]); | ||
var vegies = ["corn","tomato","tomato","tomato","sprouts","lettuce","sprouts"]; | ||
tf("slice", [vegies, 1, 4], ["tomato","tomato","tomato","sprouts"]); | ||
tf("slice", [vegies, 2], ["corn","tomato","tomato"]); | ||
tf("slice", [vegies, 14], void 0); | ||
tf("slice", [vegies, 0, 0], ["corn"]); | ||
tf("splice", [vegies, 1, 4], ["corn","lettuce","sprouts"]); | ||
tf("splice", [vegies, 2, 0, ["corn", "tomato"]], ["corn","tomato","corn","tomato","tomato","tomato","sprouts","lettuce","sprouts"]); | ||
tf("splice", [vegies, 2, 0, "liver"], ["corn","tomato","liver","tomato","tomato","sprouts","lettuce","sprouts"]); | ||
tf("splice", [vegies, 2, 2, "liver"], ["corn","tomato","liver","sprouts","lettuce","sprouts"]); | ||
tf("splice", [vegies, 1, 10], ["corn"]); | ||
tf("splice", [vegies, 1, 10, "liver"], ["corn", "liver"]); | ||
t.deepEquals(vegies, ["corn","tomato","tomato","tomato","sprouts","lettuce","sprouts"], "should not be mutated"); | ||
tf("splice", [vegies, 1, 4], ["corn","lettuce","sprouts"]); | ||
tf("splice", [vegies, 2, 0, ["corn", "tomato"]], ["corn","tomato","corn","tomato","tomato","tomato","sprouts","lettuce","sprouts"]); | ||
tf("splice", [vegies, 2, 0, "liver"], ["corn","tomato","liver","tomato","tomato","sprouts","lettuce","sprouts"]); | ||
tf("splice", [vegies, 2, 2, "liver"], ["corn","tomato","liver","sprouts","lettuce","sprouts"]); | ||
tf("splice", [vegies, 1, 10], ["corn"]); | ||
tf("splice", [vegies, 1, 10, "liver"], ["corn", "liver"]); | ||
t.deepEquals(vegies, ["corn","tomato","tomato","tomato","sprouts","lettuce","sprouts"], "should not be mutated"); | ||
var to_sort = [5, 3, 4, 1, 12]; | ||
yield ytf("sort", [to_sort], [1, 12, 3, 4, 5]); | ||
yield ytf("sort", [to_sort, "reverse"], [5, 4, 3, 12, 1]); | ||
yield ytf("sort", [to_sort, "numeric"], [1, 3, 4, 5, 12]); | ||
yield ytf("sort", [to_sort, "ciremun"], [12, 5, 4, 3, 1]); | ||
yield ytf("sort", [to_sort, function(a, b){ | ||
return a < b ? -1 : (a == b ? 0 : 1); | ||
}], [1, 3, 4, 5, 12]); | ||
t.deepEquals(to_sort, [5, 3, 4, 1, 12], "should not be mutated"); | ||
var to_sort = [5, 3, 4, 1, 12]; | ||
tf("sort", [to_sort], [1, 12, 3, 4, 5]); | ||
tf("sort", [to_sort, "reverse"], [5, 4, 3, 12, 1]); | ||
tf("sort", [to_sort, "numeric"], [1, 3, 4, 5, 12]); | ||
tf("sort", [to_sort, "ciremun"], [12, 5, 4, 3, 1]); | ||
tf("sort", [to_sort, function(a, b){ | ||
return a < b ? -1 : (a == b ? 0 : 1); | ||
}], [1, 3, 4, 5, 12]); | ||
t.deepEquals(to_sort, [5, 3, 4, 1, 12], "should not be mutated"); | ||
tf("delete", [obj, ["foo", "bar", 10]], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": {"bar": {}}//or "foo": {} ??? | ||
}); | ||
assertObjNotMutated(); | ||
tf("delete", [obj, ["foo", "bar", 10]], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": {"bar": {}}//or "foo": {} ??? | ||
}); | ||
assertObjNotMutated(); | ||
tf("encode", [{blah: 1}], "{\"blah\":1}"); | ||
tf("encode", [[1, 2]], "[1,2]"); | ||
tf("encode", [{blah: 1}], "{\"blah\":1}"); | ||
tf("encode", [[1, 2]], "[1,2]"); | ||
tf("keys", [obj], ["colors", "pi", "foo"]); | ||
tf("keys", [obj, ["foo", "bar"]], ["10"]); | ||
assertObjNotMutated(); | ||
tf("keys", [obj], ["colors", "pi", "foo"]); | ||
tf("keys", [obj, ["foo", "bar"]], ["10"]); | ||
assertObjNotMutated(); | ||
tf("values", [obj], [ | ||
"many", | ||
[3, 1, 4, 1, 5, 6, 9], | ||
{"bar": {"10": "I like cheese"}} | ||
]); | ||
tf("values", [obj, ["foo", "bar"]], ["I like cheese"]); | ||
assertObjNotMutated(); | ||
tf("values", [obj], [ | ||
"many", | ||
[3, 1, 4, 1, 5, 6, 9], | ||
{"bar": {"10": "I like cheese"}} | ||
]); | ||
tf("values", [obj, ["foo", "bar"]], ["I like cheese"]); | ||
assertObjNotMutated(); | ||
tf("put", [obj, ["foo"], {baz: "qux"}], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "I like cheese"}, | ||
"baz": "qux" | ||
} | ||
}); | ||
tf("put", [obj, {flop: 12}], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": {"bar": {"10": "I like cheese"}}, | ||
"flop": 12 | ||
}); | ||
assertObjNotMutated(); | ||
tf("put", [obj, ["foo"], {baz: "qux"}], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "I like cheese"}, | ||
"baz": "qux" | ||
} | ||
}); | ||
tf("put", [obj, {flop: 12}], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": {"bar": {"10": "I like cheese"}}, | ||
"flop": 12 | ||
}); | ||
assertObjNotMutated(); | ||
tf("get", [obj, ["foo", "bar", "10"]], "I like cheese"); | ||
tf("get", [obj, "colors"], "many"); | ||
assertObjNotMutated(); | ||
tf("get", [obj, ["foo", "bar", "10"]], "I like cheese"); | ||
tf("get", [obj, "colors"], "many"); | ||
assertObjNotMutated(); | ||
tf("set", [obj, ["foo", "baz"], "qux"], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "I like cheese"}, | ||
"baz": "qux" | ||
} | ||
}); | ||
tf("set", [obj, "flop", 12], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "I like cheese"} | ||
}, | ||
"flop": 12 | ||
}); | ||
tf("set", [obj, "colors", ["R", "G", "B"]], { | ||
"colors": ["R", "G", "B"], | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "I like cheese"} | ||
} | ||
}); | ||
tf("set", [obj, ["foo", "bar", "10"], "modified a sub object"], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "modified a sub object"} | ||
} | ||
}); | ||
assertObjNotMutated(); | ||
tf("set", [obj, ["foo", "baz"], "qux"], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "I like cheese"}, | ||
"baz": "qux" | ||
} | ||
}); | ||
tf("set", [obj, "flop", 12], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "I like cheese"} | ||
}, | ||
"flop": 12 | ||
}); | ||
tf("set", [obj, "colors", ["R", "G", "B"]], { | ||
"colors": ["R", "G", "B"], | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "I like cheese"} | ||
} | ||
}); | ||
tf("set", [obj, ["foo", "bar", "10"], "modified a sub object"], { | ||
"colors": "many", | ||
"pi": [3, 1, 4, 1, 5, 6, 9], | ||
"foo": { | ||
"bar": {"10": "modified a sub object"} | ||
} | ||
}); | ||
assertObjNotMutated(); | ||
tf("intersection", [[2, 1], [2, 3]], [2]); | ||
tf("intersection", [[2, 1], [2, 3]], [2]); | ||
tf("union", [[2], [1, 2]], [2, 1]); | ||
tf("union", [[1, 2], [1, 4]], [1, 2, 4]); | ||
tf("union", [[{"x":2}], [{"x":1}, {"x":2}]], [{"x":2}, {"x":1}]); | ||
tf("union", [[2], [1, 2]], [2, 1]); | ||
tf("union", [[1, 2], [1, 4]], [1, 2, 4]); | ||
tf("union", [[{"x":2}], [{"x":1}, {"x":2}]], [{"x":2}, {"x":1}]); | ||
tf("difference", [[2, 1], [2, 3]], [1]); | ||
tf("difference", [[{"x":2}, {"x":1}], [{"x":2}, {"x":3}]], [{"x":1}]); | ||
tf("difference", [[2, 1], [2, 3]], [1]); | ||
tf("difference", [[{"x":2}, {"x":1}], [{"x":2}, {"x":3}]], [{"x":1}]); | ||
tf("has", [[1, 2, 3, 4], [4, 2]], true); | ||
tf("has", [[1, 2, 3, 4], [4, 5]], false); | ||
tf("has", [[1, 2, 3, 4], [4, 2]], true); | ||
tf("has", [[1, 2, 3, 4], [4, 5]], false); | ||
tf("once", [[1, 2, 1, 3, 4, 4]], [2, 3]); | ||
tf("once", [[1, 2, 1, 3, 4, 4]], [2, 3]); | ||
tf("duplicates", [[1, 2, 1, 3, 4, 4]], [1, 4]); | ||
tf("duplicates", [[1, 2, 1, 3, 4, 4]], [1, 4]); | ||
tf("unique", [[1, 2, 1, 3, 4, 4]], [1, 2, 3, 4]); | ||
t.end(); | ||
tf("unique", [[1, 2, 1, 3, 4, 4]], [1, 2, 3, 4]); | ||
}); | ||
@@ -371,24 +432,24 @@ | ||
test("klog", function(t){ | ||
t.plan(3); | ||
stdlib.klog({ | ||
emit: function(kind, val, message){ | ||
t.equals(kind, "klog"); | ||
t.equals(val, 42); | ||
t.equals(message, "message 1"); | ||
} | ||
}, 42, "message 1"); | ||
t.plan(3); | ||
stdlib.klog({ | ||
emit: function(kind, val, message){ | ||
t.equals(kind, "klog"); | ||
t.equals(val, 42); | ||
t.equals(message, "message 1"); | ||
} | ||
}, 42, "message 1"); | ||
}); | ||
test("defaultsTo - testing debug logging", function(t){ | ||
t.plan(5); | ||
var ctx = { | ||
emit: function(kind, message){ | ||
t.equals(kind, "debug"); | ||
t.equals(message,"[DEFAULTSTO] message 2"); | ||
} | ||
}; | ||
t.plan(5); | ||
var ctx = { | ||
emit: function(kind, message){ | ||
t.equals(kind, "debug"); | ||
t.equals(message,"[DEFAULTSTO] message 2"); | ||
} | ||
}; | ||
t.equals(stdlib.defaultsTo(ctx, "not needed", 42, "message 2"), "not needed"); | ||
t.equals(stdlib.defaultsTo(ctx, "", 42), 42, "no message to log"); | ||
t.equals(stdlib.defaultsTo(ctx, "", 42, "message 2"), 42, "should emit debug"); | ||
t.equals(stdlib.defaultsTo(ctx, "not needed", 42, "message 2"), "not needed"); | ||
t.equals(stdlib.defaultsTo(ctx, "", 42), 42, "no message to log"); | ||
t.equals(stdlib.defaultsTo(ctx, "", 42, "message 2"), 42, "should emit debug"); | ||
}); |
Sorry, the diff of this file is not supported yet
29892
911