New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ducky

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ducky - npm Package Compare versions

Comparing version 2.1.3 to 2.2.0

lib/ducky.browser.js

4

bower.json
{
"name": "ducky",
"version": "2.1.3",
"version": "2.2.0",
"description": "Duck-Typed Value Handling for JavaScript",
"main": "./lib/ducky.js",
"main": "./lib/ducky.browser.js",
"homepage": "http://duckyjs.com",

@@ -7,0 +7,0 @@ "license": "MIT",

{
"ecmaFeatures": {},
"parser": "babel-eslint",
"env": {
"browser": false,
"node": false,
"node": true,
"amd": false,
"mocha": false,
"mocha": true,
"jasmine": false
},
"globals": {
"expect": true
},
"rules": {

@@ -17,6 +20,7 @@ "no-alert": 2,

"no-catch-shadow": 2,
"no-comma-dangle": 2,
"no-comma-dangle": 0,
"no-cond-assign": 2,
"no-console": 2,
"no-constant-condition": 2,
"no-continue": 0,
"no-control-regex": 2,

@@ -27,2 +31,4 @@ "no-debugger": 2,

"no-dupe-keys": 2,
"no-dupe-args": 2,
"no-duplicate-case": 2,
"no-else-return": 0,

@@ -54,3 +60,3 @@ "no-empty": 2,

"no-lonely-if": 0,
"no-loop-func": 2,
"no-loop-func": 0,
"no-mixed-requires": [0, false],

@@ -72,2 +78,3 @@ "no-mixed-spaces-and-tabs": [2, false],

"no-octal-escape": 2,
"no-param-reassign": 0,
"no-path-concat": 0,

@@ -88,3 +95,3 @@ "no-plusplus": 0,

"no-shadow-restricted-names": 2,
"no-space-before-semi": 2,
"no-space-before-semi": 0,
"no-spaced-func": 2,

@@ -95,6 +102,7 @@ "no-sparse-arrays": 2,

"no-trailing-spaces": 2,
"no-throw-literal": 0,
"no-undef": 2,
"no-undef-init": 2,
"no-undefined": 0,
"no-underscore-dangle": 2,
"no-underscore-dangle": 0,
"no-unreachable": 2,

@@ -109,6 +117,6 @@ "no-unused-expressions": 2,

"no-wrap-func": 2,
"block-scoped-var": 0,
"brace-style": [0, "1tbs"],
"camelcase": 0,
"comma-dangle": [2, "never"],
"comma-spacing": 2,

@@ -122,3 +130,3 @@ "comma-style": 0,

"dot-notation": [2, { "allowKeywords": true }],
"eol-last": 0,
"eol-last": 2,
"eqeqeq": 2,

@@ -128,6 +136,8 @@ "func-names": 0,

"generator-star": 0,
"generator-star-spacing": 0,
"global-strict": [2, "never"],
"guard-for-in": 0,
"handle-callback-err": 0,
"key-spacing": [0, { "beforeColon": false, "afterColon": true }],
"indent": 0,
"key-spacing": [0, { "beforeColon": false, "afterColon": false }],
"max-depth": [0, 4],

@@ -138,6 +148,8 @@ "max-len": [0, 80, 4],

"max-statements": [0, 10],
"new-cap": 2,
"new-cap": 0,
"new-parens": 2,
"newline-after-var": 0,
"one-var": 0,
"operator-assignment": [0, "always"],
"operator-linebreak": 0,
"padded-blocks": 0,

@@ -147,3 +159,4 @@ "quote-props": 0,

"radix": 0,
"semi": 2,
"semi": 0,
"semi-spacing": [2, {"before": false, "after": true}],
"sort-vars": 0,

@@ -153,2 +166,4 @@ "space-after-function-name": [0, "never"],

"space-before-blocks": [0, "always"],
"space-before-function-paren": [0, "always"],
"space-before-function-parentheses": [0, "always"],
"space-in-brackets": [0, "never"],

@@ -155,0 +170,0 @@ "space-in-parens": [0, "never"],

@@ -27,8 +27,7 @@ /*

module.exports = function (grunt) {
grunt.loadNpmTasks("grunt-expand-include");
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-contrib-clean");
grunt.loadNpmTasks("grunt-mocha-test");
grunt.loadNpmTasks("grunt-browserify");
grunt.loadNpmTasks("grunt-eslint");
grunt.loadNpmTasks("grunt-mocha-test");

@@ -38,15 +37,51 @@ grunt.initConfig({

version: grunt.file.readYAML("VERSION.yml"),
"expand-include": {
"ducky": {
src: [ "src/ducky.js" ],
dest: "lib/ducky.js",
browserify: {
"ducky-browser": {
files: {
"lib/ducky.browser.js": [ "src/ducky.js" ]
},
options: {
directiveSyntax: "js",
globalDefines: {
major: "<%= version.major %>",
minor: "<%= version.minor %>",
micro: "<%= version.micro %>",
date: "<%= version.date %>"
transform: [
[ "browserify-replace", { replace: [
{ from: /\$major/g, to: "<%= version.major %>" },
{ from: /\$minor/g, to: "<%= version.minor %>" },
{ from: /\$micro/g, to: "<%= version.micro %>" },
{ from: /\$date/g, to: "<%= version.date %>" }
]}],
"babelify"
],
plugin: [
[ "minifyify", { map: "ducky.browser.map", output: "lib/ducky.browser.map" } ],
[ "browserify-derequire" ],
[ "browserify-header" ]
],
browserifyOptions: {
standalone: "Ducky",
debug: true
}
}
},
"ducky-node": {
files: {
"lib/ducky.node.js": [ "src/ducky.js" ]
},
options: {
transform: [
[ "browserify-replace", { replace: [
{ from: /\$major/g, to: "<%= version.major %>" },
{ from: /\$minor/g, to: "<%= version.minor %>" },
{ from: /\$micro/g, to: "<%= version.micro %>" },
{ from: /\$date/g, to: "<%= version.date %>" }
]}],
"babelify"
],
plugin: [
[ "browserify-derequire" ],
[ "browserify-header" ]
],
browserifyOptions: {
standalone: "Ducky",
debug: false
}
}
}

@@ -58,4 +93,4 @@ },

},
gruntfile: [ "Gruntfile.js" ],
"ducky": [ "lib/ducky.js" ]
gruntfile: [ "Gruntfile.js" ],
"ducky": [ "src/**/*.js" ]
},

@@ -66,3 +101,4 @@ eslint: {

},
target: [ "lib/ducky.js" ],
gruntfile: [ "Gruntfile.js" ],
"ducky": [ "src/**/*.js" ]
},

@@ -77,12 +113,2 @@ mochaTest: {

},
uglify: {
options: {
preserveComments: "some",
report: "min"
},
dist: {
src: "lib/ducky.js",
dest: "lib/ducky.min.js"
}
},
clean: {

@@ -94,4 +120,4 @@ clean: [ "lib/*", "lib" ],

grunt.registerTask("default", [ "expand-include", "jshint", "eslint", "mochaTest", "uglify" ]);
grunt.registerTask("default", [ "jshint", "eslint", "browserify", "mochaTest" ]);
};
{
"esnext": true,
"asi": true,
"maxerr": 200,

@@ -3,0 +5,0 @@ "bitwise": true,

@@ -5,3 +5,3 @@ {

"description": "Duck-Typed Value Handling for JavaScript",
"version": "2.1.3",
"version": "2.2.0",
"license": "MIT",

@@ -23,14 +23,22 @@ "author": {

},
"main": "./lib/ducky.js",
"main": "./lib/ducky.node.js",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-cli": "~0.1.13",
"grunt-contrib-jshint": "~0.11.0",
"grunt-contrib-uglify": "~0.7.0",
"grunt-contrib-jshint": "~0.11.2",
"grunt-contrib-uglify": "~0.9.1",
"grunt-contrib-clean": "~0.6.0",
"grunt-eslint": "~5.1.0",
"grunt-eslint": "~16.0.0",
"babel-eslint": "~3.1.23",
"grunt-browserify": "~3.8.0",
"grunt-mocha-test": "~0.12.7",
"grunt-expand-include": "~0.9.6",
"chai": "~1.10.0",
"chai-fuzzy": "~1.4.0"
"mocha": "~2.2.5",
"chai": "~3.0.0",
"chai-fuzzy": "~1.5.0",
"underscore": "~1.8.3",
"babelify": "~6.1.2",
"minifyify": "~7.0.2",
"browserify-replace": "~0.9.0",
"browserify-header": "~0.9.2",
"browserify-derequire": "~0.9.4"
},

@@ -37,0 +45,0 @@ "dependencies" : {

@@ -25,4 +25,9 @@ /*

/* global $major: false */
/* global $minor: false */
/* global $micro: false */
/* global $date: false */
/* API version */
ducky.version = {
var version = {
major: $major,

@@ -32,3 +37,5 @@ minor: $minor,

date: $date
};
}
export { version }

@@ -26,98 +26,99 @@ /*

/* custom Token class */
var Token = function () {
this.name = "";
this.text = "";
this.tokens = [];
this.pos = 0;
this.len = 0;
};
Token.prototype = {
class Token {
constructor () {
this.name = ""
this.text = ""
this.tokens = []
this.pos = 0
this.len = 0
}
/* setter for caller context name */
setName: function (name) {
this.name = name;
},
setName (name) {
this.name = name
}
/* setter for plain-text input */
setText: function (text) {
this.text = text;
},
setText (text) {
this.text = text
}
/* setter for additional token symbols */
addToken: function (b1, b2, e2, e1, symbol) {
this.tokens.push({ b1: b1, b2: b2, e2: e2, e1: e1, symbol: symbol });
this.len++;
},
addToken (b1, b2, e2, e1, symbol) {
this.tokens.push({ b1: b1, b2: b2, e2: e2, e1: e1, symbol: symbol })
this.len++
}
/* peek at the next token or token at particular offset */
peek: function (offset) {
peek (offset) {
if (typeof offset === "undefined")
offset = 0;
offset = 0
if (offset >= this.len)
throw new Error(this.name + ": parse error: not enough tokens");
return this.tokens[this.pos + offset].symbol;
},
throw new Error(`${this.name}: parse error: not enough tokens`)
return this.tokens[this.pos + offset].symbol
}
/* skip one or more tokens */
skip: function (len) {
skip (len) {
if (typeof len === "undefined")
len = 1;
len = 1
if (len > this.len)
throw new Error(this.name + ": parse error: not enough tokens available to skip: " + this.ctx());
this.pos += len;
this.len -= len;
},
throw new Error(`${this.name}: parse error: not enough tokens available to skip: ${this.ctx()}`)
this.pos += len
this.len -= len
}
/* consume the current token (by expecting it to be a particular symbol) */
consume: function (symbol) {
consume (symbol) {
if (this.len <= 0)
throw new Error(this.name + ": parse error: no more tokens available to consume: " + this.ctx());
throw new Error(`${this.name}: parse error: no more tokens available to consume: ${this.ctx()}`)
if (this.tokens[this.pos].symbol !== symbol)
throw new Error(this.name + ": parse error: expected token symbol \"" + symbol + "\": " + this.ctx());
this.pos++;
this.len--;
},
throw new Error(`${this.name}: parse error: expected token symbol "${symbol}": ${this.ctx()}`)
this.pos++
this.len--
}
/* return a textual description of the token parsing context */
ctx: function (width) {
ctx (width) {
if (typeof width === "undefined")
width = 78;
var tok = this.tokens[this.pos];
width = 78
let tok = this.tokens[this.pos]
/* the current token itself */
var ctx = "<" + this.text.substr(tok.b2, tok.e2 - tok.b2 + 1) + ">";
ctx = this.text.substr(tok.b1, tok.b2 - tok.b1) + ctx;
ctx = ctx + this.text.substr(tok.e2 + 1, tok.e1 - tok.e2);
let ctx = "<" + this.text.substr(tok.b2, tok.e2 - tok.b2 + 1) + ">"
ctx = this.text.substr(tok.b1, tok.b2 - tok.b1) + ctx
ctx = ctx + this.text.substr(tok.e2 + 1, tok.e1 - tok.e2)
/* the previous and following token(s) */
var k = (width - ctx.length);
let k = (width - ctx.length)
if (k > 0) {
k = Math.floor(k / 2);
var i, str;
k = Math.floor(k / 2)
let i, str
if (this.pos > 0) {
/* previous token(s) */
var k1 = 0;
let k1 = 0
for (i = this.pos - 1; i >= 0; i--) {
tok = this.tokens[i];
str = this.text.substr(tok.b1, tok.e1 - tok.b1 + 1);
k1 += str.length;
tok = this.tokens[i]
str = this.text.substr(tok.b1, tok.e1 - tok.b1 + 1)
k1 += str.length
if (k1 > k)
break;
ctx = str + ctx;
break
ctx = str + ctx
}
if (i > 0)
ctx = "[...]" + ctx;
ctx = "[...]" + ctx
}
if (this.len > 1) {
/* following token(s) */
var k2 = 0;
let k2 = 0
for (i = this.pos + 1; i < this.pos + this.len; i++) {
tok = this.tokens[i];
str = this.text.substr(tok.b1, tok.e1 - tok.b1 + 1);
k2 += str.length;
tok = this.tokens[i]
str = this.text.substr(tok.b1, tok.e1 - tok.b1 + 1)
k2 += str.length
if (k2 > k)
break;
ctx = ctx + str;
break
ctx = ctx + str
}
if (i < this.pos + this.len)
ctx = ctx + "[...]";
ctx = ctx + "[...]"
}

@@ -129,6 +130,8 @@ }

.replace(/\n/, "\\n")
.replace(/\t/, "\\t");
return ctx;
.replace(/\t/, "\\t")
return ctx
}
};
}
export { Token }

@@ -27,35 +27,37 @@ /*

/* result and state variables */
var path = [];
var pos = 0;
let path = []
let pos = 0
/* iterate over selection specification */
var m;
var txt = spec;
let m
let txt = spec
while (txt !== "") {
/* case 1: standard path segment */
if ((m = txt.match(/^\s*(?:\.)?\s*([a-zA-Z$0-9_][a-zA-Z$0-9_:-]*)/)) !== null)
path.push(m[1]);
path.push(m[1])
/* case 2: numerical array-style dereference */
else if ((m = txt.match(/^\s*\[\s*(\d+|\*{1,2})\s*\]/)) !== null)
path.push(m[1]);
path.push(m[1])
/* case 3: double-quoted string array-style dereference */
else if ((m = txt.match(/^\s*\[\s*"((?:\\"|.)*?)"\s*\]/)) !== null)
path.push(m[1].replace(/\\"/g, "\""));
path.push(m[1].replace(/\\"/g, "\""))
/* case 4: single-quoted string array-style dereference */
else if ((m = txt.match(/^\s*\[\s*'((?:\\'|.)*?)'\s*\]/)) !== null)
path.push(m[1].replace(/\\'/g, "'"));
path.push(m[1].replace(/\\'/g, "'"))
/* skip all whitespaces between segments */
else if ((m = txt.match(/^\s+$/)) !== null)
break;
break
else
throw new Error("select: parse error: invalid character at: " +
spec.substr(0, pos) + "<" + txt.substr(0, 1) + ">" + txt.substr(1));
spec.substr(0, pos) + "<" + txt.substr(0, 1) + ">" + txt.substr(1))
/* advance parsing position */
pos += m[0].length;
txt = txt.substr(m[0].length);
pos += m[0].length
txt = txt.substr(m[0].length)
}
return path;
};
return path
}
export { select_compile }

@@ -30,13 +30,13 @@ /*

if (arguments.length === 3)
throw new Error("select: cannot set value on empty path");
throw new Error("select: cannot set value on empty path")
else
return obj;
return obj
}
/* step into object graph according to path prefix */
var i = 0;
let i = 0
while (i < path.length - 1) {
if (typeof obj !== "object")
throw new Error("select: cannot further dereference: no more intermediate objects in path");
obj = obj[path[i++]];
throw new Error("select: cannot further dereference: no more intermediate objects in path")
obj = obj[path[i++]]
}

@@ -46,22 +46,24 @@

if (typeof obj !== "object")
throw new Error("select: cannot further dereference: no object at end of path");
var value_old = obj[path[i]];
throw new Error("select: cannot further dereference: no object at end of path")
let value_old = obj[path[i]]
/* optionally set new value */
if (arguments.length === 3) {
var value_new = arguments[2];
let value_new = arguments[2]
if (value_new === undefined) {
/* delete value from collection */
if (obj instanceof Array)
obj.splice(parseInt(path[i], 10), 1);
obj.splice(parseInt(path[i], 10), 1)
else
delete obj[path[i]];
delete obj[path[i]]
}
else
/* set value into collection */
obj[path[i]] = value_new;
obj[path[i]] = value_new
}
return value_old;
};
return value_old
}
export { select_execute }

@@ -25,25 +25,25 @@ /*

import { select_compile } from "./ducky-3-select-1-compile.js"
import { select_execute } from "./ducky-3-select-2-execute.js"
/* the internal compile cache */
var select_cache = {};
let select_cache = {}
/* API function: select an arbitrary value via a path specification
and either get the current value or set the new value */
ducky.select = function (obj, spec, value) {
var select = function (obj, spec, value) {
/* sanity check arguments */
if (arguments.length < 2)
throw new Error("select: invalid number of arguments: \"" +
arguments.length + "\" (minimum of 2 expected)");
throw new Error(`select: invalid number of arguments: ${arguments.length} (minimum of 2 expected)`)
else if (arguments.length > 3)
throw new Error("select: invalid number of arguments: \"" +
arguments.length + "\" (maximum of 3 expected)");
throw new Error(`select: invalid number of arguments: ${arguments.length} (maximum of 3 expected)`)
if (typeof spec !== "string")
throw new Error("select: invalid specification argument: \"" +
spec + "\" (string expected)");
throw new Error(`select: invalid specification argument: "${spec}" (string expected)`)
/* compile select path from specification
or reuse cached pre-compiled selection path */
var path = select_cache[spec];
let path = select_cache[spec]
if (typeof path === "undefined") {
path = select_compile(spec);
select_cache[spec] = path;
path = select_compile(spec)
select_cache[spec] = path
}

@@ -56,31 +56,28 @@

: select_execute(obj, path, value)
);
};
)
}
/* compile a path specification into array of dereferencing steps */
ducky.select.compile = function (spec) {
select.compile = function (spec) {
/* sanity check argument */
if (arguments.length !== 1)
throw new Error("select: invalid number of arguments: \"" +
arguments.length + "\" (exactly 1 expected)");
throw new Error(`select: invalid number of arguments: ${arguments.length} (exactly 1 expected)`)
if (typeof spec !== "string")
throw new Error("select: invalid specification argument: \"" +
spec + "\" (string expected)");
return select_compile.apply(undefined, arguments);
};
throw new Error(`select: invalid specification argument: "${spec}" (string expected)`)
return select_compile.apply(undefined, arguments)
}
/* execute object selection */
ducky.select.execute = function (obj, path) {
select.execute = function (obj, path) {
/* sanity check arguments */
if (arguments.length < 2)
throw new Error("select: invalid number of arguments: \"" +
arguments.length + "\" (minimum of 2 expected)");
throw new Error(`select: invalid number of arguments: ${arguments.length} (minimum of 2 expected)`)
else if (arguments.length > 3)
throw new Error("select: invalid number of arguments: \"" +
arguments.length + "\" (maximum of 3 expected)");
throw new Error(`select: invalid number of arguments: ${arguments.length} (maximum of 3 expected)`)
if (!(typeof path === "object" && path instanceof Array))
throw new Error("select: invalid path argument: \"" +
path + "\" (array expected)");
return select_execute.apply(undefined, arguments);
};
throw new Error(`select: invalid path argument: "${path}" (array expected)`)
return select_execute.apply(undefined, arguments)
}
export { select }

@@ -25,16 +25,18 @@ /*

import { Token } from "./ducky-1-util.js"
/* tokenize the validation specification */
var validate_tokenize = function (spec) {
/* create new Token abstraction */
var token = new Token();
token.setName("validate");
token.setText(spec);
var token = new Token()
token.setName("validate")
token.setText(spec)
/* determine individual token symbols */
var m;
var b = 0;
let m
let b = 0
while (spec !== "") {
m = spec.match(/^(\s*)([^{}\[\]:,?*+()!|\s]+|[{}\[\]:,?*+()!|])(\s*)/);
m = spec.match(/^(\s*)([^{}\[\]:,?*+()!|\s]+|[{}\[\]:,?*+()!|])(\s*)/)
if (m === null)
throw new Error("validate: parse error: cannot further canonicalize: \"" + spec + "\"");
throw new Error(`validate: parse error: cannot further canonicalize: "${spec}"`)
token.addToken(

@@ -46,8 +48,10 @@ b,

m[2]
);
spec = spec.substr(m[0].length);
b += m[0].length;
)
spec = spec.substr(m[0].length)
b += m[0].length
}
return token;
};
return token
}
export { validate_tokenize }

@@ -27,115 +27,115 @@ /*

var validate_parse = {
parse_spec: function (token) {
parse_spec (token) {
if (token.len <= 0)
return null;
var ast;
var symbol = token.peek();
return null
let ast
let symbol = token.peek()
if (symbol === "!")
ast = this.parse_not(token);
ast = this.parse_not(token)
else if (symbol === "(")
ast = this.parse_group(token);
ast = this.parse_group(token)
else if (symbol === "{")
ast = this.parse_hash(token);
ast = this.parse_hash(token)
else if (symbol === "[")
ast = this.parse_array(token);
ast = this.parse_array(token)
else if (symbol.match(/^(?:null|undefined|boolean|number|string|function|object)$/))
ast = this.parse_primary(token);
ast = this.parse_primary(token)
else if (symbol === "any")
ast = this.parse_any(token);
ast = this.parse_any(token)
else if (symbol.match(/^[_a-zA-Z$][_a-zA-Z$0-9]*(?:\.[_a-zA-Z$][_a-zA-Z$0-9]*)*$/))
ast = this.parse_class(token);
ast = this.parse_class(token)
else
throw new Error("validate: parse error: invalid token symbol: \"" + token.ctx() + "\"");
return ast;
throw new Error(`validate: parse error: invalid token symbol: "${token.ctx()}"`)
return ast
},
/* parse boolean "not" operation */
parse_not: function (token) {
token.consume("!");
var ast = this.parse_spec(token); /* RECURSION */
ast = { type: "not", op: ast };
return ast;
parse_not (token) {
token.consume("!")
let ast = this.parse_spec(token) /* RECURSION */
ast = { type: "not", op: ast }
return ast
},
/* parse group (for boolean "or" operation) */
parse_group: function (token) {
token.consume("(");
var ast = this.parse_spec(token);
parse_group (token) {
token.consume("(")
let ast = this.parse_spec(token)
while (token.peek() === "|") {
token.consume("|");
var child = this.parse_spec(token); /* RECURSION */
ast = { type: "or", op1: ast, op2: child };
token.consume("|")
let child = this.parse_spec(token) /* RECURSION */
ast = { type: "or", op1: ast, op2: child }
}
token.consume(")");
return ast;
token.consume(")")
return ast
},
/* parse hash type specification */
parse_hash: function (token) {
token.consume("{");
var elements = [];
parse_hash (token) {
token.consume("{")
let elements = []
while (token.peek() !== "}") {
var key = this.parse_key(token);
var arity = this.parse_arity(token, "?");
token.consume(":");
var spec = this.parse_spec(token); /* RECURSION */
elements.push({ type: "element", key: key, arity: arity, element: spec });
let key = this.parse_key(token)
let arity = this.parse_arity(token, "?")
token.consume(":")
let spec = this.parse_spec(token) /* RECURSION */
elements.push({ type: "element", key: key, arity: arity, element: spec })
if (token.peek() === ",")
token.skip();
token.skip()
else
break;
break
}
var ast = { type: "hash", elements: elements };
token.consume("}");
return ast;
let ast = { type: "hash", elements: elements }
token.consume("}")
return ast
},
/* parse array type specification */
parse_array: function (token) {
token.consume("[");
var elements = [];
parse_array (token) {
token.consume("[")
let elements = []
while (token.peek() !== "]") {
var spec = this.parse_spec(token); /* RECURSION */
var arity = this.parse_arity(token, "?*+");
elements.push({ type: "element", element: spec, arity: arity });
var spec = this.parse_spec(token) /* RECURSION */
var arity = this.parse_arity(token, "?*+")
elements.push({ type: "element", element: spec, arity: arity })
if (token.peek() === ",")
token.skip();
token.skip()
else
break;
break
}
var ast = { type: "array", elements: elements };
token.consume("]");
return ast;
let ast = { type: "array", elements: elements }
token.consume("]")
return ast
},
/* parse primary type specification */
parse_primary: function (token) {
var primary = token.peek();
parse_primary (token) {
let primary = token.peek()
if (!primary.match(/^(?:null|undefined|boolean|number|string|function|object)$/))
throw new Error("validate: parse error: invalid primary type \"" + primary + "\"");
token.skip();
return { type: "primary", name: primary };
throw new Error(`validate: parse error: invalid primary type "${primary}"`)
token.skip()
return { type: "primary", name: primary }
},
/* parse special "any" type specification */
parse_any: function (token) {
var any = token.peek();
parse_any (token) {
let any = token.peek()
if (any !== "any")
throw new Error("validate: parse error: invalid any type \"" + any + "\"");
token.skip();
return { type: "any" };
throw new Error(`validate: parse error: invalid any type "${any}"`)
token.skip()
return { type: "any" }
},
/* parse JavaScript class specification */
parse_class: function (token) {
var clazz = token.peek();
parse_class (token) {
let clazz = token.peek()
if (!clazz.match(/^[_a-zA-Z$][_a-zA-Z$0-9]*(?:\.[_a-zA-Z$][_a-zA-Z$0-9]*)*$/))
throw new Error("validate: parse error: invalid class type \"" + clazz + "\"");
token.skip();
return { type: "class", name: clazz };
throw new Error(`validate: parse error: invalid class type "${clazz}"`)
token.skip()
return { type: "class", name: clazz }
},
/* parse arity specification */
parse_arity: function (token, charset) {
var arity = [ 1, 1 ];
parse_arity (token, charset) {
let arity = [ 1, 1 ]
if ( token.len >= 5

@@ -152,4 +152,4 @@ && token.peek(0) === "{"

: parseInt(token.peek(3), 10))
];
token.skip(5);
]
token.skip(5)
}

@@ -160,22 +160,24 @@ else if (

&& charset.indexOf(token.peek()) >= 0) {
var c = token.peek();
let c = token.peek()
switch (c) {
case "?": arity = [ 0, 1 ]; break;
case "*": arity = [ 0, Number.MAX_VALUE ]; break;
case "+": arity = [ 1, Number.MAX_VALUE ]; break;
case "?": arity = [ 0, 1 ]; break
case "*": arity = [ 0, Number.MAX_VALUE ]; break
case "+": arity = [ 1, Number.MAX_VALUE ]; break
}
token.skip();
token.skip()
}
return arity;
return arity
},
/* parse hash key specification */
parse_key: function (token) {
var key = token.peek();
parse_key (token) {
var key = token.peek()
if (!key.match(/^(?:[_a-zA-Z$][_a-zA-Z$0-9]*|@)$/))
throw new Error("validate: parse error: invalid key \"" + key + "\"");
token.skip();
return key;
throw new Error(`validate: parse error: invalid key "${key}"`)
token.skip()
return key
}
};
}
export { validate_parse }

@@ -25,46 +25,59 @@ /*

import { registered } from "./ducky-2-registry-2-api.js"
var validate_execute = {
/* validate specification (top-level) */
exec_spec: function (value, node) {
var valid = false;
exec_spec (value, node, path, errors) {
let valid = false
if (node !== null) {
switch (node.type) {
case "not": valid = this.exec_not( value, node); break;
case "or": valid = this.exec_or( value, node); break;
case "hash": valid = this.exec_hash( value, node); break;
case "array": valid = this.exec_array( value, node); break;
case "primary": valid = this.exec_primary(value, node); break;
case "class": valid = this.exec_class( value, node); break;
case "any": valid = true; break;
case "not": valid = this.exec_not( value, node, path, errors); break
case "or": valid = this.exec_or( value, node, path, errors); break
case "hash": valid = this.exec_hash( value, node, path, errors); break
case "array": valid = this.exec_array( value, node, path, errors); break
case "primary": valid = this.exec_primary(value, node, path, errors); break
case "class": valid = this.exec_class( value, node, path, errors); break
case "any": valid = true; break
default:
throw new Error("validate: invalid validation AST: " +
"node has unknown type \"" + node.type + "\"");
throw new Error(`validate: invalid validation AST: node has unknown type "${node.type}"`)
}
}
return valid;
return valid
},
/* validate through boolean "not" operation */
exec_not: function (value, node) {
return !this.exec_spec(value, node.op); /* RECURSION */
exec_not (value, node, path, errors) {
let err = errors !== null ? [] : null
let valid = this.exec_spec(value, node.op, path, err) /* RECURSION */
valid = !valid
if (!valid && errors !== null)
err.forEach((e) => errors.push(e))
return valid
},
/* validate through boolean "or" operation */
exec_or: function (value, node) {
return (
this.exec_spec(value, node.op1) /* RECURSION */
|| this.exec_spec(value, node.op2) /* RECURSION */
);
exec_or (value, node, path, errors) {
let [ err1, err2 ] = errors !== null ? [ [], [] ] : [ null, null ]
let valid1 = this.exec_spec(value, node.op1, path, err1) /* RECURSION */
let valid2 = this.exec_spec(value, node.op2, path, err2) /* RECURSION */
let valid = valid1 || valid2
if (!valid && errors !== null) {
err1.forEach((e) => errors.push(e))
err2.forEach((e) => errors.push(e))
}
return valid
},
/* validate hash type */
exec_hash: function (value, node) {
var i, el;
var valid = (typeof value === "object");
var fields = {};
var field;
if (valid) {
exec_hash (value, node, path, errors) {
let i, el
let valid = (typeof value === "object")
let fields = {}
let field
if (!valid && errors !== null)
errors.push(`mismatch at path "${path}": found type "${typeof value}", expected hash`)
else if (valid) {
/* pass 1: ensure that all mandatory fields exist
and determine map of valid fields for pass 2 */
var hasAnyKeys = false;
let hasAnyKeys = false
for (field in value) {

@@ -75,20 +88,28 @@ if ( !Object.hasOwnProperty.call(value, field)

|| field === "prototype" )
continue;
hasAnyKeys = true;
break;
continue
hasAnyKeys = true
break
}
for (i = 0; i < node.elements.length; i++) {
el = node.elements[i];
fields[el.key] = el.element;
el = node.elements[i]
fields[el.key] = el.element
if ( el.arity[0] > 0
&& ( (el.key === "@" && !hasAnyKeys)
|| (el.key !== "@" && typeof value[el.key] === "undefined"))) {
valid = false;
break;
valid = false
if (errors !== null) {
if (el.key === "@")
errors.push(`mismatch at path "${path}": mandatory element under arbitrary key not found`)
else
errors.push(`mismatch at path "${path}": mandatory element under key "${el.key}" not found`)
}
else
break
}
}
}
if (valid) {
if (valid || errors !== null) {
/* pass 2: ensure that no unknown fields exist
and that all existing fields are valid */
let sep = (path !== "" ? "." : "")
for (field in value) {

@@ -99,59 +120,100 @@ if ( !Object.hasOwnProperty.call(value, field)

|| field === "prototype" )
continue;
continue
if ( typeof fields[field] === "undefined"
&& typeof fields["@"] === "undefined"
&& errors !== null )
errors.push(`mismatch at path "${path}": element under key "${field}" unexpected`)
if ( typeof fields[field] !== "undefined"
&& this.exec_spec(value[field], fields[field])) /* RECURSION */
continue;
&& this.exec_spec(value[field], fields[field], `${path}${sep}${field}`, errors)) /* RECURSION */
continue
if ( typeof fields["@"] !== "undefined"
&& this.exec_spec(value[field], fields["@"])) /* RECURSION */
continue;
valid = false;
break;
&& this.exec_spec(value[field], fields["@"], `${path}${sep}${field}`, errors)) /* RECURSION */
continue
valid = false
if (errors === null)
break
}
}
return valid;
return valid
},
/* validate array type */
exec_array: function (value, node) {
var i, el;
var valid = (typeof value === "object" && value instanceof Array);
if (valid) {
var pos = 0;
exec_array (value, node, path, errors) {
let i, el
let valid = (typeof value === "object" && value instanceof Array)
if (!valid && errors !== null)
errors.push(`mismatch at path "${path}": found type "${typeof value}", expected array`)
else if (valid) {
let pos = 0
let err = null
/* iterate over all AST nodes */
for (i = 0; i < node.elements.length; i++) {
el = node.elements[i];
var found = 0;
el = node.elements[i]
let found = 0
err = errors !== null ? [] : null
/* iterate over remaining value elements
- as long as the maximum value is not still reached and
- as long as there are still elements available
- as long as the elements are still valid */
while (found < el.arity[1] && pos < value.length) {
if (!this.exec_spec(value[pos], el.element)) /* RECURSION */
break;
found++;
pos++;
if (!this.exec_spec(value[pos], el.element, `${path}[${pos}]`, err)) /* RECURSION */
break
found++
pos++
}
if (found < el.arity[0]) {
valid = false;
break;
if (errors !== null)
errors.push(`mismatch at path "${path}[${pos}]": ` +
`found only ${found} elements of array element type #${i}, ` +
`expected at least ${el.arity[0]} elements`)
valid = false
break
}
}
if (pos < value.length)
valid = false;
/* if last AST node matched not successfully, report its errors */
if (!valid && err !== null && err.length > 0) {
if (errors !== null)
err.forEach((e) => errors.push(e))
}
/* in case more elements are available without matching nodes */
else if (pos < value.length) {
if (errors !== null)
errors.push(`mismatch at path "${path}": matched only ${pos} elements, ` +
`but ${value.length} elements found`)
valid = false
}
}
return valid;
return valid
},
/* validate standard JavaScript type */
exec_primary: function (value, node) {
return (node.name === "null" && value === null) || (typeof value === node.name);
exec_primary (value, node, path, errors) {
let valid = (node.name === "null" && value === null) || (typeof value === node.name)
if (!valid && errors !== null)
errors.push(`mismatch at path "${path}": found type "${typeof value}", expected primary type "${node.name}"`)
return valid
},
/* validate custom JavaScript type */
exec_class: function (value, node) {
return (
exec_class (value, node, path, errors) {
let type = registered(node.name)
let valid = (
typeof value === "object"
&& (
Object.prototype.toString.call(value) === "[object " + node.name + "]"
|| ( typeof registry[node.name] === "function"
&& value instanceof registry[node.name])
|| ( typeof type === "function"
&& value instanceof type )
)
);
)
if (!valid && errors !== null)
errors.push(`mismatch at path "${path}": found type "${typeof value}", expected class type "${node.name}"`)
return valid
}
};
}
export { validate_execute }

@@ -25,54 +25,61 @@ /*

import { validate_tokenize } from "./ducky-4-validate-1-tokenize.js"
import { validate_parse } from "./ducky-4-validate-2-parse.js"
import { validate_execute } from "./ducky-4-validate-3-execute.js"
/* internal compile cache */
var validate_cache = {};
let validate_cache = {}
/* API function: validate an arbitrary value against a validation DSL */
ducky.validate = function (value, spec) {
var validate = function (value, spec, errors) {
/* sanity check arguments */
if (arguments.length !== 2)
throw new Error("validate: invalid number of arguments: \"" +
arguments.length + "\" (exactly 2 expected)");
if (arguments.length < 2)
throw new Error(`validate: invalid number of arguments: ${arguments.length} (minimum of 2 expected)`)
else if (arguments.length > 3)
throw new Error(`validate: invalid number of arguments: ${arguments.length} (maximum of 3 expected)`)
if (typeof spec !== "string")
throw new Error("validate: invalid specification argument: \"" +
spec + "\" (string expected)");
throw new Error(`validate: invalid specification argument: "${spec}" (string expected)`)
/* compile validation AST from specification
or reuse cached pre-compiled validation AST */
var ast = validate_cache[spec];
var ast = validate_cache[spec]
if (typeof ast === "undefined") {
ast = ducky.validate.compile(spec);
validate_cache[spec] = ast;
ast = validate.compile(spec)
validate_cache[spec] = ast
}
/* execute validation AST against the value */
return ducky.validate.execute(value, ast);
};
return validate.execute(value, ast, errors)
}
ducky.validate.compile = function (spec) {
validate.compile = function (spec) {
/* sanity check arguments */
if (arguments.length !== 1)
throw new Error("validate: invalid number of arguments: \"" +
arguments.length + "\" (exactly 1 expected)");
throw new Error(`validate: invalid number of arguments: ${arguments.length} (exactly 1 expected)`)
if (typeof spec !== "string")
throw new Error("validate: invalid specification argument: \"" +
spec + "\" (string expected)");
throw new Error(`validate: invalid specification argument: "${spec}" (string expected)`)
/* tokenize the specification string into a token stream */
var token = validate_tokenize(spec);
var token = validate_tokenize(spec)
/* parse the token stream into an AST */
var ast = validate_parse.parse_spec(token);
var ast = validate_parse.parse_spec(token)
return ast;
};
return ast
}
ducky.validate.execute = function (value, ast) {
validate.execute = function (value, ast, errors) {
/* sanity check arguments */
if (arguments.length !== 2)
throw new Error("validate: invalid number of arguments: \"" +
arguments.length + "\" (exactly 2 expected)");
if (arguments.length < 2)
throw new Error(`validate: invalid number of arguments: ${arguments.length} (minimum of 2 expected)`)
else if (arguments.length > 3)
throw new Error(`validate: invalid number of arguments: ${arguments.length} (maximum of 3 expected)`)
if (arguments.length < 3 || typeof errors === "undefined")
errors = null
/* execute validation AST against the value */
return validate_execute.exec_spec(value, ast);
};
return validate_execute.exec_spec(value, ast, "", errors)
}
export { validate }

@@ -25,6 +25,8 @@ /*

import { validate } from "./ducky-4-validate-4-api.js"
/* determine or at least guess whether we were called with
positional or name-based parameters */
var params_is_name_based = function (args, spec) {
var name_based = false;
let params_is_name_based = function (args, spec) {
let name_based = false
if ( args.length === 1

@@ -34,40 +36,39 @@ && typeof args[0] === "object") {

"foo({ foo: ..., bar: ...})" */
name_based = true;
name_based = true
/* ...but do not be mislead by a positional use like
"foo(bar)" where "bar" is an arbitrary object! */
for (var name in args[0]) {
for (let name in args[0]) {
if (!Object.hasOwnProperty.call(args[0], name)) {
if (typeof spec[name] === "undefined")
name_based = false;
name_based = false
}
}
}
return name_based;
};
return name_based
}
/* common value validity checking */
var params_check_validity = function (func, param, value, valid, what) {
let params_check_validity = function (func, param, value, valid, what) {
if (typeof valid === "undefined")
return;
if (!ducky.validate(value, valid))
throw new Error(func + ": parameter \"" + param + "\" has " +
what + " " + JSON.stringify(value) + ", which does not validate " +
"against \"" + valid + "\"");
};
return
if (!validate(value, valid))
throw new Error(`${func}: parameter "${param}" has ` +
`${what} ${JSON.stringify(value)}, which does not validate against "${valid}"`)
}
/* API function: flexible parameter handling */
ducky.params = function (func, args, spec) {
var params = function (func, args, spec) {
/* start with a fresh parameter object */
var params = {};
var params = {}
/* handle parameter defaults */
var name;
let name
for (name in spec) {
if (!Object.hasOwnProperty.call(spec, name))
continue;
continue
if (typeof spec[name].def !== "undefined") {
if (typeof spec[name].valid !== "undefined")
params_check_validity(func, name, spec[name].def, spec[name].valid, "default value");
params[name] = spec[name].def;
params_check_validity(func, name, spec[name].def, spec[name].valid, "default value")
params[name] = spec[name].def
}

@@ -78,3 +79,3 @@ }

if (params_is_name_based(args, spec)) {
args = args[0];
args = args[0]

@@ -88,7 +89,7 @@ /*

if (!Object.hasOwnProperty.call(args, name))
continue;
continue
if (typeof spec[name] === "undefined")
throw new Error(func + ": unknown parameter \"" + name + "\"");
params_check_validity(func, name, args[name], spec[name].valid, "value");
params[name] = args[name];
throw new Error(`${func}: unknown parameter "${name}"`)
params_check_validity(func, name, args[name], spec[name].valid, "value")
params[name] = args[name]
}

@@ -99,7 +100,7 @@

if (!Object.hasOwnProperty.call(spec, name))
continue;
continue
if ( typeof spec[name].req !== "undefined"
&& spec[name].req
&& typeof args[name] === "undefined")
throw new Error(func + ": required parameter \"" + name + "\" missing");
throw new Error(`${func}: required parameter "${name}" missing`)
}

@@ -114,14 +115,14 @@ }

and the mapping from parameter position to parameter name */
var positional = 0;
var required = 0;
var pos2name = {};
let positional = 0
let required = 0
let pos2name = {}
for (name in spec) {
if (!Object.hasOwnProperty.call(spec, name))
continue;
continue
if (typeof spec[name].pos !== "undefined") {
pos2name[spec[name].pos] = name;
pos2name[spec[name].pos] = name
if (typeof spec[name].pos === "number")
positional++;
positional++
if (typeof spec[name].req !== "undefined" && spec[name].req)
required++;
required++
}

@@ -132,20 +133,19 @@ }

if (args.length < required)
throw new Error(func + ": invalid number of arguments " +
"(at least " + required + " required)");
throw new Error(`${func}: invalid number of arguments (at least ${required} required)`)
/* pass 2: process parameters in sequence */
var i = 0;
let i = 0
while (i < positional && i < args.length) {
params_check_validity(func, pos2name[i], args[i], spec[pos2name[i]].valid, "value");
params[pos2name[i]] = args[i];
i++;
params_check_validity(func, pos2name[i], args[i], spec[pos2name[i]].valid, "value")
params[pos2name[i]] = args[i]
i++
}
if (i < args.length) {
if (typeof pos2name["..."] === "undefined")
throw new Error(func + ": too many arguments provided");
var rest = [];
throw new Error(`${func}: too many arguments provided`)
let rest = []
while (i < args.length)
rest.push(args[i++]);
params_check_validity(func, pos2name["..."], rest, spec[pos2name["..."]].valid, "value");
params[pos2name["..."]] = rest;
rest.push(args[i++])
params_check_validity(func, pos2name["..."], rest, spec[pos2name["..."]].valid, "value")
params[pos2name["..."]] = rest
}

@@ -155,4 +155,6 @@ }

/* return prepared parameter object */
return params;
};
return params
}
export { params }

@@ -25,30 +25,13 @@ /*!

/* Universal Module Definition (UMD) */
(function (root, name, factory) {
/* global define: false */
/* global module: false */
if (typeof define === "function" && typeof define.amd !== "undefined")
/* AMD environment */
define(name, function () { return factory(root); });
else if (typeof module === "object" && typeof module.exports === "object")
/* CommonJS environment */
module.exports = factory(root);
else
/* Browser environment */
root[name] = factory(root);
}(this, "ducky", function (/* root */) {
var ducky = {};
include("ducky-0-version.js");
include("ducky-1-util.js");
include("ducky-2-registry.js");
include("ducky-3-select-1-compile.js");
include("ducky-3-select-2-execute.js");
include("ducky-3-select-3-api.js");
include("ducky-4-validate-1-tokenize.js");
include("ducky-4-validate-2-parse.js");
include("ducky-4-validate-3-execute.js");
include("ducky-4-validate-4-api.js");
include("ducky-5-params.js");
return ducky;
}));
import { version } from "./ducky-0-version.js"
import { register, unregister } from "./ducky-2-registry-2-api.js"
import { select } from "./ducky-3-select-3-api.js"
import { validate } from "./ducky-4-validate-4-api.js"
import { params } from "./ducky-5-params.js"
export { version }
export { register, unregister }
export { select }
export { validate }
export { params }

@@ -32,7 +32,7 @@ /*

global.chai = require("chai")
chai.use(require("chai-fuzzy"));
chai.use(require("chai-fuzzy"))
global.expect = global.chai.expect
global.chai.config.includeStack = true
var ducky = require("../lib/ducky.js")
var ducky = require("../lib/ducky.node.js")
var version = ducky.version

@@ -48,5 +48,5 @@

expect(version.date ).to.be.a("number").least(20130101)
});
});
})
})
})

@@ -32,7 +32,7 @@ /*

global.chai = require("chai")
chai.use(require("chai-fuzzy"));
chai.use(require("chai-fuzzy"))
global.expect = global.chai.expect
global.chai.config.includeStack = true
var ducky = require("../lib/ducky.js")
var ducky = require("../lib/ducky.node.js")
var select = ducky.select

@@ -49,21 +49,21 @@

}
};
}
it("should correctly get value", function () {
expect(select(obj, "")).to.be.equal(obj);
expect(select(obj, " ")).to.be.equal(obj);
expect(select(obj, "foo")).to.be.equal(obj.foo);
expect(select(obj, "foo.bar")).to.be.equal(obj.foo.bar);
expect(select(obj, "foo.bar.baz[0]")).to.be.equal(obj.foo.bar.baz[0]);
expect(select(obj, "foo.bar.baz[4]")).to.be.equal(obj.foo.bar.baz[4]);
expect(select(obj, "foo['bar'].baz[4]")).to.be.equal(obj.foo.bar.baz[4]);
expect(select(obj, "['foo']['bar'][\"baz\"]['4']")).to.be.equal(obj.foo.bar.baz[4]);
expect(select(obj, " [ 'foo' ] [ 'bar'] [ \"baz\" ][ '4' ] ")).to.be.equal(obj.foo.bar.baz[4]);
});
expect(select(obj, "")).to.be.equal(obj)
expect(select(obj, " ")).to.be.equal(obj)
expect(select(obj, "foo")).to.be.equal(obj.foo)
expect(select(obj, "foo.bar")).to.be.equal(obj.foo.bar)
expect(select(obj, "foo.bar.baz[0]")).to.be.equal(obj.foo.bar.baz[0])
expect(select(obj, "foo.bar.baz[4]")).to.be.equal(obj.foo.bar.baz[4])
expect(select(obj, "foo['bar'].baz[4]")).to.be.equal(obj.foo.bar.baz[4])
expect(select(obj, "['foo']['bar'][\"baz\"]['4']")).to.be.equal(obj.foo.bar.baz[4])
expect(select(obj, " [ 'foo' ] [ 'bar'] [ \"baz\" ][ '4' ] ")).to.be.equal(obj.foo.bar.baz[4])
})
it("should correctly set value", function () {
var old = obj.foo.bar.baz;
expect(select(obj, "foo.bar.baz", { marker: 42 })).to.be.equal(old);
expect(obj).to.be.like({ foo: { bar: { baz: { marker: 42 }, quux: 42 }}});
});
});
var old = obj.foo.bar.baz
expect(select(obj, "foo.bar.baz", { marker: 42 })).to.be.equal(old)
expect(obj).to.be.like({ foo: { bar: { baz: { marker: 42 }, quux: 42 }}})
})
})
})

@@ -32,7 +32,7 @@ /*

global.chai = require("chai")
chai.use(require("chai-fuzzy"));
chai.use(require("chai-fuzzy"))
global.expect = global.chai.expect
global.chai.config.includeStack = true
var ducky = require("../lib/ducky.js")
var ducky = require("../lib/ducky.node.js")
var validate = ducky.validate

@@ -71,5 +71,5 @@

expect(validate(new Foo(), "Foo")).to.be.false
ducky.register("Foo", Foo);
ducky.register("Foo", Foo)
var Quux = function () {}
ducky.register("foo.bar.Quux", Quux);
ducky.register("foo.bar.Quux", Quux)
expect(validate(new Quux(), "foo.bar.Quux")).to.be.true

@@ -125,4 +125,15 @@ })

})
it("should correctly report errors", function () {
var errors = []
expect(validate(true, "string", errors)).to.be.false
expect(errors).to.have.length(1)
expect(errors[0]).to.match(/^mismatch at path "":.*/)
errors = []
expect(validate([ 42, "foo" ], "[ number, boolean ]", errors)).to.be.false
expect(errors).to.have.length(2)
expect(errors[0]).to.match(/^mismatch at path "\[1\]":.*/)
expect(errors[1]).to.match(/^mismatch at path "\[1\]":.*/)
})
})
})

@@ -32,7 +32,7 @@ /*

global.chai = require("chai")
chai.use(require("chai-fuzzy"));
chai.use(require("chai-fuzzy"))
global.expect = global.chai.expect
global.chai.config.includeStack = true
var ducky = require("../lib/ducky.js")
var ducky = require("../lib/ducky.node.js")

@@ -48,10 +48,10 @@ describe("Ducky", function () {

other: { pos: "...", def: [], valid: "[ number* ]" }
});
expect(params.name).to.be.equal("bar");
expect(params.enabled).be.equal(true);
expect(params.spec).be.like([ 42, 7 ]);
expect(params.other).be.like([ 1, 2, 3 ]);
})
expect(params.name).to.be.equal("bar")
expect(params.enabled).be.equal(true)
expect(params.spec).be.like([ 42, 7 ])
expect(params.other).be.like([ 1, 2, 3 ])
};
foo("bar", true, [ 42, 7 ], 1, 2, 3);
foo({ name: "bar", enabled: true, spec: [ 42, 7 ], other: [ 1, 2, 3 ] });
foo("bar", true, [ 42, 7 ], 1, 2, 3)
foo({ name: "bar", enabled: true, spec: [ 42, 7 ], other: [ 1, 2, 3 ] })
expect(function () { foo() }).to.throw(Error)

@@ -58,0 +58,0 @@ expect(function () { foo({ quux: "quux" }) }).to.throw(Error)

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc