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

assertly

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

assertly - npm Package Compare versions

Comparing version 1.0.0-beta.2 to 1.0.0-beta.3

docs.js

320

Assert.js
'use strict';
const BE = ['be'];
const ROOT = ['$'];
const TO = ['to'];
const inspect = require('./inspect').inspect;

@@ -13,2 +11,14 @@ const arraySlice = Array.prototype.slice;

function toArray (value) {
if (!value) {
return [];
}
if (!Array.isArray(value)) {
value = [value];
}
return value;
}
/**

@@ -175,133 +185,9 @@ * @class Assert

/**
* Adds assertion methods.
*
* Assert.register({
* to: ['be', 'have', 'include', 'only', 'not'],
*
* lt: {
* test (actual, expected) {
* return actual < expected;
* },
*
* explain (actual, expected) {
* let not = this.modifiers.not ? 'not ' : '';
* return `Expected ${this.actual} to ${not}be less-than ${this.expected}`;
* }
* }
* });
*
* Assert.expect(42).to.be.lt(427);
* // ^^ ^^^
* // actual expected
*/
static register (name, def) {
static getDefaults () {
const A = this;
const P = A.prototype;
if (typeof name !== 'string') {
let names = Object.keys(name);
return this.normalize({
not: 'to',
to: 'not',
names.forEach(key => A.register(key, name[key]));
names = Object.keys(A.entries);
for (let s of names) {
if (s !== '$' && !Object.getOwnPropertyDescriptor(P, s)) {
A._addBit(P, s);
}
}
return;
}
let after, before, entry;
let fn = def;
let t = typeof def;
if (A.tupleRe.test(name)) {
// 'afters.name,alias.befores'
let tuples = name.split(A.tupleRe);
let a = tuples.shift();
name = tuples.shift();
let b = tuples[0];
before = b && b.split(',');
after = a && a.split(',');
}
if (t === 'function') {
def = { fn: fn };
} else {
fn = def.fn;
}
let names = name.split(',');
name = names[0];
after = after || (fn ? (name === 'be' ? TO : BE) : ROOT);
if (after.indexOf('to') > -1 && after.indexOf('not') < 0) {
after = ['not'].concat(after);
}
if (t === 'string' || Array.isArray(def)) {
for (let s of names) {
A._addBit(P, s, name);
//A._getEntry('$').add(s);
for (let a of after) {
entry = A._getEntry(a);
entry.add(s);
}
entry = A._getEntry(s, name);
entry.add(def);
}
return;
}
let wrap = fn && A.wrapAssertion(def);
for (let s of names) {
entry = A._getEntry(s, name);
entry.add(before);
if (fn) {
entry.fn = wrap;
A._addFn(P, s, wrap);
}
else {
A._addBit(P, s, name);
}
for (let a of after) {
entry = A._getEntry(a);
entry.add(s);
}
}
} // register
static report (assertion) {
let failure = assertion.failed;
if (this.log) {
this.log.push(assertion);
}
if (failure) {
this.reportFailure(failure, assertion);
}
}
static reportFailure (msg) {
//console.error(msg);
throw new Error(msg);
}
static setup () {
const A = this;
A.register({
not: ['to'],
to: ['not'],
'to.only': ['have', 'own'],

@@ -520,3 +406,3 @@ 'to.have': ['own', 'only'],

'to.throw' (fn, type) {
let ok = false;
let msg, ok = false;

@@ -528,5 +414,4 @@ try {

ok = true;
msg = e.message;
let msg = e.message;
if (typeof type === 'string') {

@@ -587,4 +472,128 @@ ok = (msg.indexOf(type) > -1);

});
} // setup
} // getDefaults
static normalize (registry) {
let A = this;
let ret = {};
for (let name of Object.keys(registry)) {
let def = registry[name];
let t = typeof def;
if (t === 'function') {
def = {
fn: def
};
}
else if (t === 'string' || Array.isArray(def)) {
def = {
before: def // to: 'be' OR 'to.have': ['only', 'own']
};
}
let after = toArray(def.after);
let before = toArray(def.before);
if (A.tupleRe.test(name)) {
// 'afters.name,alias.befores'
let tuples = name.split(A.tupleRe);
let a = tuples.shift();
name = tuples.shift();
let b = tuples[0];
b = b && b.split(',');
a = a && a.split(',');
before = b ? before.concat(b) : before;
after = a ? after.concat(a) : after;
}
if (!after.length) {
after = [def.fn ? (name === 'be' ? 'to' : 'be') : '$'];
}
if (after.indexOf('to') > -1 && after.indexOf('not') < 0) {
after = ['not'].concat(after);
}
let names = name.split(',');
name = names.shift();
if (def.alias) {
names = names.concat(def.alias); // handle String or String[]
}
ret[name] = {
alias: names.length ? names : [],
after: after,
before: before,
explain: def.explain || null,
fn: def.fn || null,
name: name
};
}
return ret;
}
static register (name, def) {
const A = this;
const P = A.prototype;
const registry = A.normalize((typeof name === 'string') ? { [name] : def } : name);
for (name in registry) {
def = registry[name];
let fn = def.fn && A.wrapAssertion(def);
let names = [name].concat(def.alias);
for (let s of names) {
let entry = A._getEntry(s, name);
entry.add(def.before);
if (fn) {
entry.fn = fn;
A._addFn(P, s, fn);
}
else {
A._addBit(P, s, name);
}
for (let a of def.after) {
entry = A._getEntry(a);
entry.add(s);
}
}
}
let names = Object.keys(A.registry);
for (let s of names) {
if (s !== '$' && !Object.getOwnPropertyDescriptor(P, s)) {
A._addBit(P, s);
}
}
}
static report (assertion) {
let failure = assertion.failed;
if (this.log) {
this.log.push(assertion);
}
if (failure) {
this.reportFailure(failure, assertion);
}
}
static reportFailure (msg) {
//console.error(msg);
throw new Error(msg);
}
static setup () {
let registry = this.getDefaults();
this.register(registry);
}
static wrapAssertion (def) {

@@ -646,6 +655,2 @@ return function (...expected) {

if (Object.getOwnPropertyDescriptor(target, modifier)) {
throw new Error(`Assertion method "${modifier}" already defined`);
}
Object.defineProperty(target, modifier, {

@@ -715,7 +720,7 @@ get () {

let A = this;
let entries = A.hasOwnProperty('entries') ? A.entries : (A.entries = {});
let entry = entries[name];
let registry = A.hasOwnProperty('registry') ? A.registry : (A.registry = {});
let entry = registry[name];
if (!entry && autoCreate !== false) {
entries[name] = entry = new A.Modifier(A, name, canonicalName);
registry[name] = entry = new A.Modifier(A, name, canonicalName);
}

@@ -838,15 +843,6 @@

static print (obj) {
static print (obj, options) {
let t = this.typeOf(obj);
if (t === 'arguments') {
obj = arraySlice.call(obj);
}
else if (t === 'function') {
return obj.$className || obj.name || 'anonymous-function';
}
else if (t === 'date') {
return obj.toISOString();
}
else if (t === 'error') {
if (t === 'error') {
if (obj.message) {

@@ -857,4 +853,4 @@ return `${obj.name}(${this.print(obj.message)})`;

}
else if (t === 'regexp') {
return String(obj);
else if (t === 'arguments') {
obj = arraySlice.call(obj);
}

@@ -868,11 +864,5 @@ else if (t === 'number') {

}
if (!obj && 1 / obj < 0) {
// 0 and -0 are different things... sadly 0 === -0 but we can
// tell them apart by dropping them in a denominator since 0
// produces Infinity and -0 produces -Infinity
return '-0';
}
}
return JSON.stringify(obj);
return inspect(obj, options);
}

@@ -901,4 +891,4 @@

Assert._notArrayLikeRe = /function|string/;
Assert.promiseTypesRe = /function|object/;
Assert._notArrayLikeRe = /^(?:function|string)$/;
Assert.promiseTypesRe = /^(?:function|object)$/;
Assert.rangeRe = /^\s*([\[(])\s*(\d+),\s*(\d+)\s*([\])])\s*$/;

@@ -948,3 +938,3 @@ Assert.tupleRe = /[\.|\/]/;

return this.owner.entries[name];
return this.owner.registry[name];
}

@@ -951,0 +941,0 @@ };

# Extensibility
The [Assert](./Assert.md) class is primarily intended to be created as a worker object
by the public `expect` method. The `Assert` class is also designed, however, to allow
for derivation and customization.
## Registering Customizations
All of the modifiers and assertions are incorporated by the static `register` method.
This method accepts an object that describes the allowed modifiers and their sequence
as well as the assertion functions.
Consider this minimal form:
Assert.register({
to: 'not', // to.not is allowed
not: 'to'. // not.to is allowed
be (actual, expected) {
// "actual" (arguments[0]) is the value passed to expect()
// the rest of the arguments cme from the call to the assertion
return actual === expected;
}
});
The above modifiers (`to` and `not`) and assertion (`be`) have some special handling
in the registration process.
- Modifiers default to being allowed to start the dot-chain.
- Assertions default to following after `be`.
- The `be` assertion defaults to following after `to`.
- Modifiers and asserts that follow `to` can also follow `not`.
### Assertions
With the basics in place, the following adds a new assertion (`throw`):
Assert.register({
'to.throw' (fn, type) {
//...
}
});
The `throw` assertion follows the `to` modifier (it would have defaulted to `be`). The
above enables these assertions:
expect(fn).to.throw(type);
expect(fn).not.to.throw(type);
expect(fn).to.not.throw(type);
### Modifiers
Modifiers are added in the same way:
Assert.register({
'to.randomly': true,
'to,randomly.throw' (fn, type) {
if (this.modifiers.randomly) {
//... hmmm
}
//...
}
});
The above adds the (not very helpful) `randomly` modifier. The first key `to.randomly`
allows `randomly` to follow the `to` modifier (by default it would belong at the start
of the dot-chain). The second key defines the `throw` assertion and it can now be
used after `to` or after `randomly`.
### Advanced Configuration
The value of each property passed to `register` is often a simple value, but its full
and normalized form is an object with the following properties:
- `alias` - The array of alternate names (e.g. "a" and "an").
- `after` - The array of names that this name comes after.
- `before` - The array of names that this name comes before.
- `fn` - The assertion `Function` that will return `true` for success.
- `explain` - The `Function` that will return a string explaining the assertion.
Rewriting the above in fully normal form:
Assert.register({
randomly: {
after: ['to']
},
throw: {
after: ['to', 'randomly'],
fn (fn, type) {
if (this.modifiers.randomly) {
//... hmmm
}
//...
}
}
});
## Adjusting The Defaults
The above examples are overly simplistic since they replace the standard modifiers
and assertions by only registering customizations.
A more realistic approach:
let registry = Assert.getDefaults();
// registry looks like the above object
Assert.register(registry);
This sequence is performed automatically when the first `Assert` instance is created,
but only if no registrations have been made. An easy way to adjust the dot-chains and
make additions or removals is to edit the object returned by `getDefaults`. The object
returned by `getDefaults` is always fully normalized to simplify this task.
## Extending Assert
The `Assert` class can also be extended to make customizations.
class MyAssert extends Assert {
static expect (value) {
return new MyAssert(value);
}
static getDefaults () {
let registry = super.getDefaults();
// hack away
return registry;
}
}
This is similar to adjusting `Assert` itself, but obviously a bit safer if one is
planning to combine test suites with those developed by others (though not a very
common practice).

@@ -101,2 +101,6 @@ # Integration

The `print` method converts the object passed to it into a readable string. This
method is used internally to print the actual and expected parameters in the
`explain` method.
### report

@@ -103,0 +107,0 @@

@@ -63,2 +63,17 @@ # Promises

To see this in action, consider this adjusted version:
it('should work asynchronously', function () {
expect(ajax('something.txt')).to.be('Some text').then(() => {
console.log('A');
});
return expect(2).to.be(2).then(() => {
console.log('B');
});
});
The log statements will appear in "A" then "B" order as a side-effect of the internal
FIFO ordering of asynchronous assertions.
## Custom Promise Implementations

@@ -65,0 +80,0 @@

{
"name": "assertly",
"version": "1.0.0-beta.2",
"version": "1.0.0-beta.3",
"description": "Assert class for BDD-style assertions",

@@ -9,4 +9,4 @@ "main": "Assert.js",

"debugx": "devtool node_modules/mocha/bin/_mocha -qc --break -- --compilers js:babel-core/register --require babel-polyfill ./test/specs/**/*.js",
"debug-print": "devtool print.js",
"print": "node print.js",
"docs": "node docs.js",
"docs-debug": "devtool docs.js",
"test": "mocha ./test/specs/**/*.js",

@@ -13,0 +13,0 @@ "testx": "mocha --compilers js:babel-core/register --require babel-polyfill ./test/specs/**/*.js"

@@ -37,6 +37,3 @@ # assertly

Following are the assertion methods and their common aliases ("aka" = "also known as").
The remainder of this document can be regenerated using:
npm run print >> README.md
### a (aka: "an")

@@ -43,0 +40,0 @@

Sorry, the diff of this file is too big to display

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