utils: custom inspect for objects

This commit is contained in:
Matthew Zipkin 2019-03-04 10:45:51 -08:00
parent 1a18040ad4
commit df4e287817
No known key found for this signature in database
GPG Key ID: E7E2984B6289C93A
43 changed files with 172 additions and 34 deletions

View File

@ -15,6 +15,7 @@ const hash256 = require('bcrypto/lib/hash256');
const util = require('../utils/util');
const Headers = require('../primitives/headers');
const InvItem = require('../primitives/invitem');
const {inspectSymbol} = require('../utils');
/*
* Constants
@ -349,7 +350,7 @@ class ChainEntry {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
const json = this.toJSON();
json.version = json.version.toString(16);
return json;

View File

@ -8,6 +8,7 @@
const assert = require('bsert');
const fixed = require('../utils/fixed');
const {inspectSymbol} = require('../utils');
/**
* Amount
@ -296,7 +297,7 @@ class Amount {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
return `<Amount: ${this.toString()}>`;
}

View File

@ -9,6 +9,7 @@
const assert = require('bsert');
const Address = require('../primitives/address');
const Amount = require('./amount');
const {inspectSymbol} = require('../utils');
/**
* URI
@ -187,7 +188,7 @@ class URI {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
return `<URI: ${this.toString()}>`;
}
}

View File

@ -16,6 +16,7 @@ const sha512 = require('bcrypto/lib/sha512');
const wordlist = require('./wordlist');
const common = require('./common');
const nfkd = require('./nfkd');
const {inspectSymbol} = require('../utils');
/*
* Constants
@ -508,7 +509,7 @@ class Mnemonic {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
return `<Mnemonic: ${this.getPhrase()}>`;
}

View File

@ -19,6 +19,7 @@ const Network = require('../protocol/network');
const NetAddress = require('./netaddress');
const common = require('./common');
const seeds = require('./seeds');
const {inspectSymbol} = require('../utils');
/*
* Constants
@ -1351,7 +1352,7 @@ class HostEntry {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return {
addr: this.addr,
src: this.src,

View File

@ -12,6 +12,7 @@ const IP = require('binet');
const Network = require('../protocol/network');
const util = require('../utils/util');
const common = require('./common');
const {inspectSymbol} = require('../utils');
/**
* Net Address
@ -456,7 +457,7 @@ class NetAddress {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return '<NetAddress:'
+ ` hostname=${this.hostname}`
+ ` services=${this.services.toString(2)}`

View File

@ -26,6 +26,7 @@ const MerkleBlock = require('../primitives/merkleblock');
const TX = require('../primitives/tx');
const {encoding} = bio;
const DUMMY = Buffer.alloc(0);
const {inspectSymbol} = require('../utils');
/**
* Packet types.
@ -1730,7 +1731,7 @@ class RejectPacket extends Packet {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
const code = RejectPacket.codesByVal[this.code] || this.code;
const hash = this.hash ? util.revHex(this.hash) : null;
return '<Reject:'

View File

@ -30,6 +30,7 @@ const Network = require('../protocol/network');
const services = common.services;
const invTypes = InvItem.types;
const packetTypes = packets.types;
const {inspectSymbol} = require('../utils');
/**
* Represents a network peer.
@ -1900,7 +1901,7 @@ class Peer extends EventEmitter {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
return '<Peer:'
+ ` handshake=${this.handshake}`
+ ` host=${this.hostname()}`

View File

@ -32,6 +32,7 @@ const services = common.services;
const invTypes = InvItem.types;
const packetTypes = packets.types;
const scores = HostList.scores;
const {inspectSymbol} = require('../utils');
/**
* Pool
@ -4225,7 +4226,7 @@ class BroadcastItem extends EventEmitter {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
const type = this.type === invTypes.TX ? 'tx' : 'block';
const hash = util.revHex(this.hash);
return `<BroadcastItem: type=${type} hash=${hash}>`;

View File

@ -15,6 +15,7 @@ const hash160 = require('bcrypto/lib/hash160');
const hash256 = require('bcrypto/lib/hash256');
const Network = require('../protocol/network');
const consensus = require('../protocol/consensus');
const {inspectSymbol} = require('../utils');
/*
* Constants
@ -285,7 +286,7 @@ class Address {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return '<Address:'
+ ` type=${this.getType()}`
+ ` version=${this.version}`

View File

@ -20,6 +20,7 @@ const Headers = require('./headers');
const Network = require('../protocol/network');
const util = require('../utils/util');
const {encoding} = bio;
const {inspectSymbol} = require('../utils');
/**
* Block
@ -526,7 +527,7 @@ class Block extends AbstractBlock {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return this.format();
}

View File

@ -15,6 +15,7 @@ const Output = require('./output');
const Network = require('../protocol/network');
const consensus = require('../protocol/consensus');
const Outpoint = require('./outpoint');
const {inspectSymbol} = require('../utils');
/**
* Coin
@ -203,7 +204,7 @@ class Coin extends Output {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return {
type: this.getType(),
version: this.version,

View File

@ -10,6 +10,7 @@
const bio = require('bufio');
const util = require('../utils/util');
const AbstractBlock = require('./abstractblock');
const {inspectSymbol} = require('../utils');
/**
* Headers
@ -233,7 +234,7 @@ class Headers extends AbstractBlock {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return this.format();
}

View File

@ -13,6 +13,7 @@ const Network = require('../protocol/network');
const Script = require('../script/script');
const Witness = require('../script/witness');
const Outpoint = require('./outpoint');
const {inspectSymbol} = require('../utils');
/**
* Input
@ -267,7 +268,7 @@ class Input {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return this.format();
}

View File

@ -18,6 +18,7 @@ const Address = require('./address');
const Output = require('./output');
const secp256k1 = require('bcrypto/lib/secp256k1');
const {encoding} = bio;
const {inspectSymbol} = require('../utils');
/*
* Constants
@ -761,7 +762,7 @@ class KeyRing {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return this.toJSON();
}

View File

@ -17,6 +17,7 @@ const AbstractBlock = require('./abstractblock');
const Headers = require('./headers');
const DUMMY = Buffer.from([0]);
const {encoding} = bio;
const {inspectSymbol} = require('../utils');
/**
* Merkle Block
@ -286,7 +287,7 @@ class MerkleBlock extends AbstractBlock {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return this.format();
}

View File

@ -23,6 +23,7 @@ const policy = require('../protocol/policy');
const Amount = require('../btc/amount');
const Stack = require('../script/stack');
const util = require('../utils/util');
const {inspectSymbol} = require('../utils');
/**
* MTX
@ -1430,7 +1431,7 @@ class MTX extends TX {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return this.format();
}

View File

@ -10,6 +10,7 @@ const assert = require('bsert');
const bio = require('bufio');
const util = require('../utils/util');
const consensus = require('../protocol/consensus');
const {inspectSymbol} = require('../utils');
/**
* Outpoint
@ -321,7 +322,7 @@ class Outpoint {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
return `<Outpoint: ${this.rhash()}/${this.index}>`;
}

View File

@ -15,6 +15,7 @@ const Address = require('../primitives/address');
const Script = require('../script/script');
const consensus = require('../protocol/consensus');
const policy = require('../protocol/policy');
const {inspectSymbol} = require('../utils');
/**
* Represents a transaction output.
@ -187,7 +188,7 @@ class Output {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return {
type: this.getType(),
value: Amount.btc(this.value),

View File

@ -25,6 +25,7 @@ const policy = require('../protocol/policy');
const ScriptError = require('../script/scripterror');
const {encoding} = bio;
const {hashType} = Script;
const {inspectSymbol} = require('../utils');
/**
* TX
@ -2040,7 +2041,7 @@ class TX {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return this.format();
}

View File

@ -10,6 +10,7 @@ const assert = require('bsert');
const bio = require('bufio');
const util = require('../utils/util');
const TX = require('./tx');
const {inspectSymbol} = require('../utils');
/**
* TXMeta
@ -118,7 +119,7 @@ class TXMeta {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return this.format();
}

View File

@ -12,6 +12,7 @@ const binary = require('../utils/binary');
const networks = require('./networks');
const consensus = require('./consensus');
const TimeData = require('./timedata');
const {inspectSymbol} = require('../utils');
/**
* Network
@ -336,7 +337,7 @@ class Network {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
return `<Network: ${this.type}>`;
}

View File

@ -10,6 +10,7 @@
const assert = require('bsert');
const common = require('./common');
const scriptTypes = common.types;
const {inspectSymbol} = require('../utils');
/**
* Witness Program
@ -84,7 +85,7 @@ class Program {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
const data = this.data.toString('hex');
const type = common.typesByVal[this.getType()].toLowerCase();
return `<Program: version=${this.version} data=${data} type=${type}>`;

View File

@ -27,6 +27,7 @@ const Address = require('../primitives/address');
const opcodes = common.opcodes;
const scriptTypes = common.types;
const {encoding} = bio;
const {inspectSymbol} = require('../utils');
/*
* Constants
@ -325,7 +326,7 @@ class Script {
* @returns {String} Human-readable script code.
*/
inspect() {
[inspectSymbol]() {
return `<Script: ${this.toString()}>`;
}

View File

@ -9,6 +9,7 @@
const assert = require('bsert');
const {I64} = require('n64');
const ScriptError = require('./scripterror');
const {inspectSymbol} = require('../utils');
/*
* Constants
@ -201,7 +202,7 @@ class ScriptNum extends I64 {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
return `<ScriptNum: ${this.toString(10)}>`;
}

View File

@ -10,6 +10,7 @@
const assert = require('bsert');
const common = require('./common');
const ScriptNum = require('./scriptnum');
const {inspectSymbol} = require('../utils');
/**
* Stack
@ -80,7 +81,7 @@ class Stack {
* @returns {String} Human-readable stack.
*/
inspect() {
[inspectSymbol]() {
return `<Stack: ${this.toString()}>`;
}

View File

@ -15,6 +15,7 @@ const Address = require('../primitives/address');
const Stack = require('./stack');
const {encoding} = bio;
const scriptTypes = common.types;
const {inspectSymbol} = require('../utils');
/**
* Witness
@ -170,7 +171,7 @@ class Witness extends Stack {
* @returns {String} Human-readable script.
*/
inspect() {
[inspectSymbol]() {
return `<Witness: ${this.toString()}>`;
}

View File

@ -0,0 +1,17 @@
/*!
* utils/index.js - utils for bcoin
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
'use strict';
/**
* @module utils
*/
exports.binary = require('./binary');
exports.fixed = require('./fixed');
exports.util = require('./util');
exports.inspectSymbol = 'inspect';

View File

@ -13,3 +13,6 @@
exports.binary = require('./binary');
exports.fixed = require('./fixed');
exports.util = require('./util');
const {inspect: {custom}} = require('util');
exports.inspectSymbol = custom;

View File

@ -14,6 +14,7 @@ const common = require('./common');
const Script = require('../script/script');
const WalletKey = require('./walletkey');
const {HDPublicKey} = require('../hd/hd');
const {inspectSymbol} = require('../utils');
/**
* Account
@ -772,7 +773,7 @@ class Account {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
const receive = this.receiveAddress();
const change = this.changeAddress();
const nested = this.nestedAddress();

View File

@ -21,6 +21,7 @@ const util = require('../utils/util');
const HDPrivateKey = require('../hd/private');
const Mnemonic = require('../hd/mnemonic');
const {encoding} = bio;
const {inspectSymbol} = require('../utils');
/**
* Master Key
@ -680,7 +681,7 @@ class MasterKey {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
const json = this.toJSON(null, true);
if (this.key)

View File

@ -10,6 +10,7 @@ const assert = require('bsert');
const bio = require('bufio');
const Address = require('../primitives/address');
const {encoding} = bio;
const {inspectSymbol} = require('../utils');
/**
* Path
@ -295,7 +296,7 @@ class Path {
* @returns {String}
*/
inspect() {
[inspectSymbol]() {
return `<Path: ${this.name}:${this.toPath()}>`;
}
}

View File

@ -20,6 +20,7 @@ const layout = require('./layout').txdb;
const consensus = require('../protocol/consensus');
const policy = require('../protocol/policy');
const {TXRecord} = records;
const {inspectSymbol} = require('../utils');
/**
* TXDB
@ -2156,7 +2157,7 @@ class Balance {
* @param {String}
*/
inspect() {
[inspectSymbol]() {
return '<Balance'
+ ` tx=${this.tx}`
+ ` coin=${this.coin}`

View File

@ -30,6 +30,7 @@ const policy = require('../protocol/policy');
const consensus = require('../protocol/consensus');
const {encoding} = bio;
const {Mnemonic} = HD;
const {inspectSymbol} = require('../utils');
/**
* Wallet
@ -2228,7 +2229,7 @@ class Wallet extends EventEmitter {
* @returns {Object}
*/
inspect() {
[inspectSymbol]() {
return {
wid: this.wid,
id: this.id,

View File

@ -85,6 +85,7 @@
"./lib/hd/wordlist": "./lib/hd/wordlist-browser.js",
"./lib/workers/child": "./lib/workers/child-browser.js",
"./lib/workers/parent": "./lib/workers/parent-browser.js",
"./lib/bcoin": "./lib/bcoin-browser.js"
"./lib/bcoin": "./lib/bcoin-browser.js",
"./lib/utils/index.js": "./lib/utils/index-browser.js"
}
}

View File

@ -6,6 +6,7 @@
const Address = require('../lib/primitives/address');
const Script = require('../lib/script/script');
const assert = require('./util/assert');
const nodejsUtil = require('util');
describe('Address', function() {
it('should match mainnet p2pkh address', () => {
@ -182,4 +183,12 @@ describe('Address', function() {
+ 'zdkfs4nce4xj0gdcccefvpysxf3pjxtptv';
assert.throws(() => Address.fromString(addr, 'main'));
});
it('should inspect', () => {
const obj = new Address();
const fmt = nodejsUtil.format(obj);
assert(typeof fmt === 'string');
assert(fmt.includes('Address'));
assert(fmt.includes('str='));
});
});

View File

@ -11,6 +11,7 @@ const Block = require('../lib/primitives/block');
const MerkleBlock = require('../lib/primitives/merkleblock');
const consensus = require('../lib/protocol/consensus');
const Script = require('../lib/script/script');
const nodejsUtil = require('util');
const bip152 = require('../lib/net/bip152');
const CompactBlock = bip152.CompactBlock;
const TXRequest = bip152.TXRequest;
@ -107,7 +108,10 @@ describe('Block', function() {
it('should inspect a block with a witness commitment', () => {
const [block] = block482683.getBlock();
assert(block.inspect());
const fmt = nodejsUtil.format(block);
assert(typeof fmt === 'string');
assert(fmt.includes('Block'));
assert(fmt.includes('commitmentHash'));
});
it('should create a merkle block', () => {

View File

@ -15,6 +15,7 @@ const MemWallet = require('./util/memwallet');
const Network = require('../lib/protocol/network');
const Output = require('../lib/primitives/output');
const common = require('../lib/blockchain/common');
const nodejsUtil = require('util');
const Opcode = require('../lib/script/opcode');
const opcodes = Script.opcodes;
@ -883,6 +884,14 @@ describe('Chain', function() {
assert.strictEqual(await mineBlock(job), 'bad-blk-sigops');
});
it('should inspect ChainEntry', async () => {
const fmt = nodejsUtil.format(tip1);
assert(typeof fmt === 'string');
assert(fmt.includes('hash'));
assert(fmt.includes('version'));
assert(fmt.includes('chainwork'));
});
it('should cleanup', async () => {
await miner.close();
await chain.close();

View File

@ -6,6 +6,7 @@
const Coin = require('../lib/primitives/coin');
const assert = require('./util/assert');
const common = require('../test/util/common');
const nodejsUtil = require('util');
const tx1 = common.readTX('tx1');
const coin1 = common.readFile('coin1.raw');
@ -39,4 +40,12 @@ describe('Coin', function() {
assert.strictEqual(coin.coinbase, false);
assert.strictEqual(coin.index, 0);
});
it('should inspect Coin', () => {
const coin = new Coin();
const fmt = nodejsUtil.format(coin);
assert(typeof fmt === 'string');
assert(fmt.includes('coinbase'));
assert(fmt.includes('script'));
});
});

View File

@ -11,6 +11,7 @@ const HD = require('../lib/hd');
const vectors = require('./data/hd.json');
const vector1 = vectors.vector1;
const vector2 = vectors.vector2;
const nodejsUtil = require('util');
let master = null;
let child = null;
@ -101,6 +102,14 @@ describe('HD', function() {
key.toBase58('main'));
});
it('should inspect Mnemonic', () => {
const mne = new HD.Mnemonic();
const fmt = nodejsUtil.format(mne);
assert(typeof fmt === 'string');
assert(fmt.includes('Mnemonic'));
assert.strictEqual(fmt.split(' ').length, 13);
});
for (const vector of [vector1, vector2]) {
let master = null;

View File

@ -7,6 +7,7 @@ const assert = require('./util/assert');
const common = require('./util/common');
const util = require('../lib/utils/util');
const TX = require('../lib/primitives/tx');
const nodejsUtil = require('util');
const OUTPOINT_SIZE = 36;
describe('Outpoint', () => {
@ -116,4 +117,13 @@ describe('Outpoint', () => {
assert.bufferEqual(fromTX.hash, tx.hash());
assert.strictEqual(fromTX.index, index);
});
it('should inspect Outpoint', () => {
const outpoint = new Outpoint();
const fmt = nodejsUtil.format(outpoint);
assert(typeof fmt === 'string');
assert(fmt.includes('Outpoint'));
assert(fmt.includes(
'0000000000000000000000000000000000000000000000000000000000000000'));
});
});

View File

@ -22,6 +22,7 @@ const KeyRing = require('../lib/primitives/keyring');
const Address = require('../lib/primitives/address');
const BufferWriter = require('bufio').BufferWriter;
const common = require('./util/common');
const nodejsUtil = require('util');
// test files: https://github.com/bitcoin/bitcoin/tree/master/src/test/data
const validTests = require('./data/core-data/tx-valid.json');
@ -1112,4 +1113,13 @@ describe('TX', function() {
assert.strictEqual(value1, value2);
});
it('should inspect TX', () => {
const tx = new TX();
const fmt = nodejsUtil.format(tx);
assert(typeof fmt === 'string');
assert(fmt.includes('hash'));
assert(fmt.includes('version'));
assert(fmt.includes('locktime'));
});
});

View File

@ -19,6 +19,7 @@ const Outpoint = require('../lib/primitives/outpoint');
const Script = require('../lib/script/script');
const HD = require('../lib/hd');
const Wallet = require('../lib/wallet/wallet');
const nodejsUtil = require('util');
const KEY1 = 'xprv9s21ZrQH143K3Aj6xQBymM31Zb4BVc7wxqfUhMZrzewdDVCt'
+ 'qUP9iWfcHgJofs25xbaUpCps9GDXj83NiWvQCAkWQhVj5J4CorfnpKX94AZ';
@ -830,6 +831,30 @@ describe('Wallet', function() {
assert.strictEqual(account.n, 1);
});
it('should inspect Wallet', async () => {
const wallet = await wdb.create();
const fmt = nodejsUtil.format(wallet);
assert(typeof fmt === 'string');
assert(fmt.includes('master'));
assert(fmt.includes('network'));
assert(fmt.includes('accountDepth'));
});
it('should inspect Account', async () => {
const wallet = await wdb.create();
const account = await wallet.createAccount({
name: 'foo'
});
const fmt = nodejsUtil.format(account);
assert(typeof fmt === 'string');
assert(fmt.includes('name'));
assert(fmt.includes('foo'));
assert(fmt.includes('initialized'));
assert(fmt.includes('lookahead'));
});
it('should fail to create duplicate account', async () => {
const wallet = await wdb.create();
const name = 'foo';