From c522c79c581f2dae480eba7ef889449b03931950 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sat, 12 Aug 2017 12:45:09 -0700 Subject: [PATCH] test: more refactoring of various tests and assert module. --- test/bech32-test.js | 81 ++++------------ test/bip150-test.js | 30 +++++- test/bip151-test.js | 30 +++++- test/block-test.js | 132 +++++++++++++------------- test/http-test.js | 2 +- test/keyring-test.js | 36 +++---- test/mempool-test.js | 2 +- test/util/assert.js | 218 ++++++++++++++++++++++++++++--------------- 8 files changed, 309 insertions(+), 222 deletions(-) diff --git a/test/bech32-test.js b/test/bech32-test.js index 15ff60be..e78f78fc 100644 --- a/test/bech32-test.js +++ b/test/bech32-test.js @@ -128,15 +128,17 @@ function toAddress(hrp, version, program) { } function createProgram(version, program) { - const ver = Buffer.from([version ? version + 0x80 : 0, program.length]); - return Buffer.concat([ver, program]); + const data = Buffer.allocUnsafe(2 + program.length); + data[0] = version ? version + 0x80 : 0; + data[1] = program.length; + program.copy(data, 2); + return data; } describe('Bech32', function() { for (const addr of validChecksums) { it(`should have valid checksum for ${addr}`, () => { - const ret = bech32.deserialize(addr); - assert(ret); + assert(bech32.deserialize(addr)); }); } @@ -160,42 +162,20 @@ describe('Bech32', function() { } } - let ok = ret !== null; + assert(ret !== null); - if (ok) { - const output = createProgram(ret.version, ret.program); - ok = output.equals(script); - } + const output = createProgram(ret.version, ret.program); + assert.bufferEqual(output, script); - if (ok) { - const recreate = toAddress(hrp, ret.version, ret.program); - ok = recreate === addr.toLowerCase(); - } - - assert(ok); + const recreate = toAddress(hrp, ret.version, ret.program); + assert.strictEqual(recreate, addr.toLowerCase()); }); } for (const addr of invalidAddresses) { it(`should have invalid address for ${addr}`, () => { - let ok1 = null; - - try { - ok1 = fromAddress('bc', addr); - } catch (e) { - ok1 = null; - } - - let ok2 = null; - - try { - ok2 = fromAddress('tb', addr); - } catch (e) { - ok2 = null; - } - - const ok = ok1 === null && ok2 === null; - assert(ok); + assert.throws(() => fromAddress('bc', addr)); + assert.throws(() => fromAddress('tb', addr)); }); } @@ -217,41 +197,20 @@ describe('Bech32', function() { } } - let ok = ret !== null; + assert(ret !== null); - if (ok) { - const output = createProgram(ret.version, ret.hash); - ok = output.equals(script); - } + const output = createProgram(ret.version, ret.hash); + assert.bufferEqual(output, script); - if (ok) { - const recreate = ret.toBech32(); - ok = recreate === addr.toLowerCase(); - } - - assert(ok); + const recreate = ret.toBech32(); + assert.strictEqual(recreate, addr.toLowerCase()); }); } for (const addr of invalidAddresses) { it(`should have invalid address for ${addr}`, () => { - let ok1 = null; - - try { - ok1 = Address.fromBech32(addr, 'main'); - } catch (e) { - ok1 = null; - } - - let ok2 = null; - - try { - ok2 = Address.fromBech32(addr, 'testnet'); - } catch (e) { - ok2 = null; - } - - assert(!ok1 && !ok2); + assert.throws(() => Address.fromBech32(addr, 'main')); + assert.throws(() => Address.fromBech32(addr, 'testnet')); }); } }); diff --git a/test/bip150-test.js b/test/bip150-test.js index 40a8bcb6..b78c1587 100644 --- a/test/bip150-test.js +++ b/test/bip150-test.js @@ -66,49 +66,61 @@ describe('BIP150', function() { it('should encrypt payload from client to server', () => { const packet = client.packet('fake', payload()); + let emitted = false; server.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + server.feed(packet); + assert(emitted); }); it('should encrypt payload from server to client', () => { const packet = server.packet('fake', payload()); + let emitted = false; client.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(packet); + assert(emitted); }); it('should encrypt payload from client to server (2)', () => { const packet = client.packet('fake', payload()); + let emitted = false; server.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + server.feed(packet); + assert(emitted); }); it('should encrypt payload from server to client (2)', () => { const packet = server.packet('fake', payload()); + let emitted = false; client.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(packet); + assert(emitted); }); @@ -141,69 +153,85 @@ describe('BIP150', function() { it('should encrypt payload from client to server after rekey', () => { const packet = client.packet('fake', payload()); + let emitted = false; server.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + server.feed(packet); + assert(emitted); }); it('should encrypt payload from server to client after rekey', () => { const packet = server.packet('fake', payload()); + let emitted = false; client.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(packet); + assert(emitted); }); it('should encrypt payload from client to server after rekey (2)', () => { const packet = client.packet('fake', payload()); + let emitted = false; server.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + server.feed(packet); + assert(emitted); }); it('should encrypt payload from server to client after rekey (2)', () => { const packet = server.packet('fake', payload()); + let emitted = false; client.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(packet); + assert(emitted); }); it('should encrypt payloads both ways asynchronously', () => { const spacket = server.packet('fake', payload()); const cpacket = client.packet('fake', payload()); + let cemitted = false; - let semitted = false; client.once('packet', (cmd, body) => { cemitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + + let semitted = false; server.once('packet', (cmd, body) => { semitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(spacket); server.feed(cpacket); + assert(cemitted); assert(semitted); }); diff --git a/test/bip151-test.js b/test/bip151-test.js index fe68fe6c..42e7e86e 100644 --- a/test/bip151-test.js +++ b/test/bip151-test.js @@ -41,49 +41,61 @@ describe('BIP151', function() { it('should encrypt payload from client to server', () => { const packet = client.packet('fake', payload()); + let emitted = false; server.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + server.feed(packet); + assert(emitted); }); it('should encrypt payload from server to client', () => { const packet = server.packet('fake', payload()); + let emitted = false; client.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(packet); + assert(emitted); }); it('should encrypt payload from client to server (2)', () => { const packet = client.packet('fake', payload()); + let emitted = false; server.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + server.feed(packet); + assert(emitted); }); it('should encrypt payload from server to client (2)', () => { const packet = server.packet('fake', payload()); + let emitted = false; client.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(packet); + assert(emitted); }); @@ -116,69 +128,85 @@ describe('BIP151', function() { it('should encrypt payload from client to server after rekey', () => { const packet = client.packet('fake', payload()); + let emitted = false; server.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + server.feed(packet); + assert(emitted); }); it('should encrypt payload from server to client after rekey', () => { const packet = server.packet('fake', payload()); + let emitted = false; client.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(packet); + assert(emitted); }); it('should encrypt payload from client to server after rekey (2)', () => { const packet = client.packet('fake', payload()); + let emitted = false; server.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + server.feed(packet); + assert(emitted); }); it('should encrypt payload from server to client after rekey (2)', () => { const packet = server.packet('fake', payload()); + let emitted = false; client.once('packet', (cmd, body) => { emitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(packet); + assert(emitted); }); it('should encrypt payloads both ways asynchronously', () => { const spacket = server.packet('fake', payload()); const cpacket = client.packet('fake', payload()); + let cemitted = false; - let semitted = false; client.once('packet', (cmd, body) => { cemitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + + let semitted = false; server.once('packet', (cmd, body) => { semitted = true; assert.strictEqual(cmd, 'fake'); assert.bufferEqual(body, payload()); }); + client.feed(spacket); server.feed(cpacket); + assert(cemitted); assert(semitted); }); diff --git a/test/block-test.js b/test/block-test.js index b30c8187..8a12acc5 100644 --- a/test/block-test.js +++ b/test/block-test.js @@ -39,24 +39,22 @@ const undo928828 = fs.readFileSync(`${__dirname}/data/undo928828.raw`); const block1087400 = fs.readFileSync(`${__dirname}/data/block1087400.raw`); const undo1087400 = fs.readFileSync(`${__dirname}/data/undo1087400.raw`); -// Abstract -const mblock = MerkleBlock.fromRaw(merkle300025); -const block = Block.fromRaw(block300025); - describe('Block', function() { this.timeout(10000); it('should parse partial merkle tree', () => { - assert(mblock.verifyPOW()); - assert(mblock.verifyBody()); - assert(mblock.verify()); + const block = MerkleBlock.fromRaw(merkle300025); - const tree = mblock.getTree(); + assert(block.verifyPOW()); + assert(block.verifyBody()); + assert(block.verify()); + + const tree = block.getTree(); assert.strictEqual(tree.matches.length, 2); - assert.strictEqual(mblock.hash('hex'), + assert.strictEqual(block.hash('hex'), '8cc72c02a958de5a8b35a23bb7e3bced8bf840cc0a4e1c820000000000000000'); - assert.strictEqual(mblock.rhash(), + assert.strictEqual(block.rhash(), '0000000000000000821c4e0acc40f88bedbce3b73ba2358b5ade58a9022cc78c'); assert.strictEqual( tree.matches[0].toString('hex'), @@ -67,29 +65,30 @@ describe('Block', function() { }); it('should decode/encode merkle block', () => { - const merkle = MerkleBlock.fromRaw(merkle300025); - merkle.refresh(); - assert.bufferEqual(merkle.toRaw(), merkle300025); - assert.bufferEqual(mblock.toRaw(), merkle300025); + const block = MerkleBlock.fromRaw(merkle300025); + block.refresh(); + assert.bufferEqual(block.toRaw(), merkle300025); }); - it('should be verify merkle block', () => { - const merkle = MerkleBlock.fromRaw(merkle300025); - assert(merkle.verify()); + it('should verify merkle block', () => { + const block = MerkleBlock.fromRaw(merkle300025); + assert(block.verify()); }); it('should be encoded/decoded and still verify', () => { - const raw = mblock.toRaw(); - const merkle = MerkleBlock.fromRaw(raw); - assert.bufferEqual(merkle.toRaw(), raw); - assert(merkle.verify()); + const block1 = MerkleBlock.fromRaw(merkle300025); + const raw = block1.toRaw(); + const block2 = MerkleBlock.fromRaw(raw); + assert.bufferEqual(block2.toRaw(), raw); + assert(block2.verify()); }); it('should be jsonified/unjsonified and still verify', () => { - const json = mblock.toJSON(); - const merkle = MerkleBlock.fromJSON(json); - assert.deepStrictEqual(merkle.toJSON(), json); - assert(merkle.verify()); + const block1 = MerkleBlock.fromRaw(merkle300025); + const json = block1.toJSON(); + const block2 = MerkleBlock.fromJSON(json); + assert.deepStrictEqual(block2.toJSON(), json); + assert(block2.verify()); }); it('should calculate reward properly', () => { @@ -110,12 +109,13 @@ describe('Block', function() { }); it('should parse JSON', () => { - const block = Block.fromJSON(Block.fromRaw(block300025).toJSON()); - assert.strictEqual(block.hash('hex'), + const block1 = Block.fromRaw(block300025); + const block2 = Block.fromJSON(block1.toJSON()); + assert.strictEqual(block2.hash('hex'), '8cc72c02a958de5a8b35a23bb7e3bced8bf840cc0a4e1c820000000000000000'); - assert.strictEqual(block.rhash(), + assert.strictEqual(block2.rhash(), '0000000000000000821c4e0acc40f88bedbce3b73ba2358b5ade58a9022cc78c'); - assert.strictEqual(block.merkleRoot, block.createMerkleRoot('hex')); + assert.strictEqual(block2.merkleRoot, block2.createMerkleRoot('hex')); }); it('should create a merkle block', () => { @@ -129,10 +129,11 @@ describe('Block', function() { filter.add(item1, 'hex'); filter.add(item2, 'hex'); - const merkle = MerkleBlock.fromBlock(block, filter); + const block1 = Block.fromRaw(block300025); + const block2 = MerkleBlock.fromBlock(block1, filter); - assert(merkle.verifyBody()); - assert.bufferEqual(merkle.toRaw(), mblock.toRaw()); + assert(block2.verifyBody()); + assert.bufferEqual(block2.toRaw(), merkle300025); }); it('should verify a historical block', () => { @@ -173,53 +174,56 @@ describe('Block', function() { }); it('should fail with a bad merkle root', () => { - const block2 = new Block(block); - block2.merkleRoot = encoding.NULL_HASH; - block2.refresh(); - assert(!block2.verifyPOW()); - const [, reason] = block2.checkBody(); + const block = Block.fromRaw(block300025); + const merkleRoot = block.merkleRoot; + block.merkleRoot = encoding.NULL_HASH; + block.refresh(); + assert(!block.verifyPOW()); + const [, reason] = block.checkBody(); assert.strictEqual(reason, 'bad-txnmrklroot'); - assert(!block2.verify()); - block2.merkleRoot = block.merkleRoot; - block2.refresh(); - assert(block2.verify()); + assert(!block.verify()); + block.merkleRoot = merkleRoot; + block.refresh(); + assert(block.verify()); }); it('should fail on merkle block with a bad merkle root', () => { - const mblock2 = new MerkleBlock(mblock); - mblock2.merkleRoot = encoding.NULL_HASH; - mblock2.refresh(); - assert(!mblock2.verifyPOW()); - const [, reason] = mblock2.checkBody(); + const block = MerkleBlock.fromRaw(merkle300025); + const merkleRoot = block.merkleRoot; + block.merkleRoot = encoding.NULL_HASH; + block.refresh(); + assert(!block.verifyPOW()); + const [, reason] = block.checkBody(); assert.strictEqual(reason, 'bad-txnmrklroot'); - assert(!mblock2.verify()); - mblock2.merkleRoot = mblock.merkleRoot; - mblock2.refresh(); - assert(mblock2.verify()); + assert(!block.verify()); + block.merkleRoot = merkleRoot; + block.refresh(); + assert(block.verify()); }); it('should fail with a low target', () => { - const block2 = new Block(block); - block2.bits = 403014710; - block2.refresh(); - assert(!block2.verifyPOW()); - assert(block2.verifyBody()); - assert(!block2.verify()); - block2.bits = block.bits; - block2.refresh(); - assert(block2.verify()); + const block = Block.fromRaw(block300025); + const bits = block.bits; + block.bits = 403014710; + block.refresh(); + assert(!block.verifyPOW()); + assert(block.verifyBody()); + assert(!block.verify()); + block.bits = bits; + block.refresh(); + assert(block.verify()); }); it('should fail on duplicate txs', () => { - const block2 = new Block(block); - block2.txs.push(block2.txs[block2.txs.length - 1]); - block2.refresh(); - const [, reason] = block2.checkBody(); + const block = Block.fromRaw(block300025); + block.txs.push(block.txs[block.txs.length - 1]); + block.refresh(); + const [, reason] = block.checkBody(); assert.strictEqual(reason, 'bad-txns-duplicate'); }); it('should verify with headers', () => { - const headers = new Headers(block); + const headers = Headers.fromHead(block300025); assert(headers.verifyPOW()); assert(headers.verifyBody()); assert(headers.verify()); diff --git a/test/http-test.js b/test/http-test.js index e37b3eb8..748f2042 100644 --- a/test/http-test.js +++ b/test/http-test.js @@ -102,7 +102,7 @@ describe('HTTP', function() { assert.strictEqual(balance.confirmed, 0); assert.strictEqual(balance.unconfirmed, 201840); assert(details); - assert.strictEqual(details.hash, tx.rhash()); + assert.strictEqual(details.hash, tx.txid()); }); it('should get balance', async () => { diff --git a/test/keyring-test.js b/test/keyring-test.js index a7b8c0c9..87cc0c2f 100644 --- a/test/keyring-test.js +++ b/test/keyring-test.js @@ -6,47 +6,47 @@ const assert = require('./util/assert'); const KeyRing = require('../lib/primitives/keyring'); +const uncompressed = KeyRing.fromSecret( + '5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss'); + +const compressed = KeyRing.fromSecret( + 'L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1'); + describe('KeyRing', function() { - const ukey = KeyRing.fromSecret( - '5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss'); - - const ckey = KeyRing.fromSecret( - 'L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1'); - - it('check uncompressed public key', () => { + it('should get uncompressed public key', () => { assert.strictEqual( '04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b' + '8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235', - ukey.getPublicKey('hex')); + uncompressed.getPublicKey('hex')); }); - it('check uncompressed public key to address', () => { + it('should get uncompressed public key address', () => { assert.strictEqual( '1HZwkjkeaoZfTSaJxDw6aKkxp45agDiEzN', - ukey.getKeyAddress('base58')); + uncompressed.getKeyAddress('base58')); }); - it('check uncompressed secret', () => { + it('should get uncompressed WIF', () => { assert.strictEqual( '5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss', - ukey.toSecret()); + uncompressed.toSecret()); }); - it('check compressed public key', () => { + it('should get compressed public key', () => { assert.strictEqual( '03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd', - ckey.getPublicKey('hex')); + compressed.getPublicKey('hex')); }); - it('check compressed public key to address', () => { + it('should get compressed public key address', () => { assert.strictEqual( '1F3sAm6ZtwLAUnj7d38pGFxtP3RVEvtsbV', - ckey.getKeyAddress('base58')); + compressed.getKeyAddress('base58')); }); - it('check compressed secret', () => { + it('should get compressed WIF', () => { assert.strictEqual( 'L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1', - ckey.toSecret()); + compressed.toSecret()); }); }); diff --git a/test/mempool-test.js b/test/mempool-test.js index d1af65e5..0fb934fb 100644 --- a/test/mempool-test.js +++ b/test/mempool-test.js @@ -135,7 +135,7 @@ describe('Mempool', function() { await mempool.addTX(t4.toTX()); const balance = mempool.getBalance(); - assert.strictEqual(balance, 70000); // note: funding balance + assert.strictEqual(balance, 70000); } { diff --git a/test/util/assert.js b/test/util/assert.js index 0dfa4121..c3a9e56b 100644 --- a/test/util/assert.js +++ b/test/util/assert.js @@ -3,84 +3,87 @@ const _assert = require('assert'); const util = require('util'); -const assert = function assert(ok, message) { - return _assert(ok, message); +const assert = function assert(value, message) { + if (!value) { + throw new assert.AssertionError({ + message, + actual: value, + expected: true, + operator: '==', + stackStartFunction: assert + }); + } }; Object.setPrototypeOf(assert, _assert); assert.typeOf = function typeOf(value, expected, message) { - const type = _typeOf(value); - if (type !== expected) { + _isString(expected, '`expected` must be a string.', typeOf); + + const actual = _typeOf(value); + + if (actual !== expected) { throw new assert.AssertionError({ - mesage: message, - actual: type, - expected: expected, - operator: '===', + message, + actual, + expected, + operator: 'typeof ==', stackStartFunction: typeOf }); } }; assert.notTypeOf = function notTypeOf(value, expected, message) { - const type = _typeOf(value); - if (type === expected) { + _isString(expected, '`expected` must be a string.', notTypeOf); + + const actual = _typeOf(value); + + if (actual === expected) { throw new assert.AssertionError({ - mesage: message, - actual: type, - expected: expected, - operator: '!==', + message, + actual, + expected, + operator: 'typeof !=', stackStartFunction: notTypeOf }); } }; assert.instanceOf = function instanceOf(object, parent, message) { + _isFunction(parent, '`parent` must be a constructor.', instanceOf); + if (!(object instanceof parent)) { throw new assert.AssertionError({ - mesage: message, - actual: _getConstructor(object), - expected: parent.name, - operator: '===', + message, + actual: _getConstructorName(object), + expected: _getFunctionName(parent), + operator: 'instanceof', stackStartFunction: instanceOf }); } }; assert.notInstanceOf = function notInstanceOf(object, parent, message) { + _isFunction(parent, '`parent` must be a constructor.', notInstanceOf); + if (object instanceof parent) { throw new assert.AssertionError({ - mesage: message, - actual: _getConstructor(object), - expected: parent.name, - operator: '!==', + message, + actual: _getConstructorName(object), + expected: _getFunctionName(parent), + operator: 'not instanceof', stackStartFunction: notInstanceOf }); } }; -assert.isBuffer = function isBuffer(value, message) { - if (!Buffer.isBuffer(value)) { - throw new assert.AssertionError({ - mesage: message, - actual: _typeOf(value), - expected: 'buffer', - operator: '===', - stackStartFunction: isBuffer - }); - } -}; - assert.bufferEqual = function bufferEqual(actual, expected, message) { - assert.isBuffer(actual, message); - assert.isBuffer(expected, message); + _isBuffer(actual, '`actual` must be a buffer.', bufferEqual); + _isBuffer(expected, '`expected` must be a buffer.', bufferEqual); - if (actual === expected) - return; - - if (!actual.equals(expected)) { + if (actual !== expected && !actual.equals(expected)) { throw new assert.AssertionError({ - mesage: message, + message, actual: actual.toString('hex'), expected: expected.toString('hex'), operator: '===', @@ -90,12 +93,12 @@ assert.bufferEqual = function bufferEqual(actual, expected, message) { }; assert.notBufferEqual = function notBufferEqual(actual, expected, message) { - assert.isBuffer(actual, message); - assert.isBuffer(expected, message); + _isBuffer(actual, '`actual` must be a buffer.', notBufferEqual); + _isBuffer(expected, '`expected` must be a buffer.', notBufferEqual); - if (actual.equals(expected)) { + if (actual === expected || actual.equals(expected)) { throw new assert.AssertionError({ - mesage: message, + message, actual: actual.toString('hex'), expected: expected.toString('hex'), operator: '!==', @@ -104,44 +107,109 @@ assert.notBufferEqual = function notBufferEqual(actual, expected, message) { } }; -function _typeOf(value) { - if (value === null) - return 'null'; - - if (util.isDate(value)) - return 'date'; - - if (util.isRegExp(value)) - return 'regexp'; - - if (util.isError(value)) - return 'error'; - - if (Array.isArray(value)) - return 'array'; - - if (Buffer.isBuffer(value)) - return 'buffer'; - - return typeof value; +function _isString(value, message, stackStartFunction) { + if (typeof value !== 'string') { + throw new assert.AssertionError({ + message, + actual: _typeOf(value), + expected: 'string', + operator: 'typeof ==', + stackStartFunction + }); + } } -function _getConstructor(value) { - if (value === undefined) - return 'Undefined'; +function _isFunction(value, message, stackStartFunction) { + if (typeof value !== 'function') { + throw new assert.AssertionError({ + message, + actual: _typeOf(value), + expected: 'function', + operator: 'typeof ==', + stackStartFunction + }); + } +} - if (value === null) +function _isBuffer(value, message, stackStartFunction) { + if (!Buffer.isBuffer(value)) { + throw new assert.AssertionError({ + message, + actual: _typeOf(value), + expected: 'buffer', + operator: 'typeof ==', + stackStartFunction + }); + } +} + +function _typeOf(value) { + const type = typeof value; + + switch (type) { + case 'object': + if (value === null) + return 'null'; + + if (Array.isArray(value)) + return 'array'; + + if (Buffer.isBuffer(value)) + return 'buffer'; + + if (ArrayBuffer.isView(value)) + return 'arraybuffer'; + + if (util.isError(value)) + return 'error'; + + if (util.isDate(value)) + return 'date'; + + if (util.isRegExp(value)) + return 'regexp'; + + break; + case 'number': + if (!isFinite(value)) + return 'nan'; + break; + } + + return type; +} + +function _getConstructorName(object) { + if (object === undefined) + return 'undefined'; + + if (object === null) + return 'null'; + + const proto = Object.getPrototypeOf(object); + + // Should never happen. + if (proto === undefined) + throw new Error('Bad prototype.'); + + // Inherited from `null`. + if (proto === null) return 'Null'; - const proto = Object.getPrototypeOf(value); + // Someone overwrote their + // constructor property? + if (!proto.constructor) + return 'Object'; - if (proto == null) - return 'Null'; + // Non-named constructor function. + if (!proto.constructor.name) + return 'Unknown'; - const ctor = proto.constructor; - const name = ctor ? ctor.name : null; + return proto.constructor.name; +} - return name || 'Unknown'; +function _getFunctionName(func) { + return func.name || 'Unknown'; } module.exports = assert;