diff --git a/lib/errors/spec.js b/lib/errors/spec.js index 2a813e460..5b7493796 100644 --- a/lib/errors/spec.js +++ b/lib/errors/spec.js @@ -34,6 +34,13 @@ module.exports = [{ }, { name: 'InvalidArgumentType', message: format('Invalid Argument for {2}, expected {1} but got ') + '+ typeof arguments[0]', + }, { + name: 'Unit', + message: format('Internal Error on Unit {0}'), + errors: [{ + 'name': 'UnknownCode', + 'message': format('Unrecognized unit code: {0}') + }] }, { name: 'Transaction', message: format('Internal Error on Transaction {0}'), diff --git a/lib/unit.js b/lib/unit.js index 50c699629..6a2bb86ad 100644 --- a/lib/unit.js +++ b/lib/unit.js @@ -1,13 +1,19 @@ 'use strict'; +var errors = require('./errors'); var JSUtil = require('./util/js'); +var UNITS = { + 'BTC' : [1e8, 8], + 'mBTC' : [1e5, 5], + 'uBTC' : [1e2, 2], + 'bits' : [1e2, 2], + 'satoshis' : [1, 0] +}; + /** - * - * Bitcore Unit - * * Utility for handling and converting bitcoins units. The supported units are - * BTC, mBTC, bits and satoshis. A unit instance can be created with an + * BTC, mBTC, bits (also named uBTC) and satoshis. A unit instance can be created with an * amount and a unit code, or alternatively using static methods like {fromBTC}. * You can consult for different representation of a unit instance using it's * {to} method, the fixed unit methods like {toSatoshis} or alternatively using @@ -15,7 +21,6 @@ var JSUtil = require('./util/js'); * * @example * ```javascript - * * var sats = Unit.fromBTC(1.3).toSatoshis(); * var mili = Unit.fromBits(1.3).to(Unit.mBTC); * var btc = new Unit(1.3, Unit.bits).BTC; @@ -45,22 +50,14 @@ function Unit(amount, code) { }; Object.keys(UNITS).forEach(defineAccesor); -}; - -var UNITS = { - 'BTC' : [1e8, 8], - 'mBTC' : [1e5, 5], - 'uBTC' : [1e2, 2], - 'bits' : [1e2, 2], - 'satoshis' : [1, 0] -}; +} Object.keys(UNITS).forEach(function(key) { Unit[key] = key; }); /** - * Will return a Unit instance created from JSON string or object + * Returns a Unit instance created from JSON string or object * * @param {String|Object} json - JSON with keys: amount and code * @returns {Unit} A Unit instance @@ -73,7 +70,7 @@ Unit.fromJSON = function fromJSON(json){ }; /** - * Will return a Unit instance created from an amount in BTC + * Returns a Unit instance created from an amount in BTC * * @param {Number} amount - The amount in BTC * @returns {Unit} A Unit instance @@ -83,7 +80,7 @@ Unit.fromBTC = function(amount) { }; /** - * Will return a Unit instance created from an amount in mBTC + * Returns a Unit instance created from an amount in mBTC * * @param {Number} amount - The amount in mBTC * @returns {Unit} A Unit instance @@ -93,7 +90,7 @@ Unit.fromMilis = function(amount) { }; /** - * Will return a Unit instance created from an amount in bits + * Returns a Unit instance created from an amount in bits * * @param {Number} amount - The amount in bits * @returns {Unit} A Unit instance @@ -103,7 +100,7 @@ Unit.fromMicros = Unit.fromBits = function(amount) { }; /** - * Will return a Unit instance created from an amount in satoshis + * Returns a Unit instance created from an amount in satoshis * * @param {Number} amount - The amount in satoshis * @returns {Unit} A Unit instance @@ -113,26 +110,29 @@ Unit.fromSatoshis = function(amount) { }; Unit.prototype._from = function(amount, code) { - if (!UNITS[code]) throw Error('Unknown unit code'); - + if (!UNITS[code]) { + throw new errors.Unit.UnknownCode(code); + } return parseInt((amount * UNITS[code][0]).toFixed()); }; /** - * Will return the value represented in the specified unit + * Returns the value represented in the specified unit * * @param {string} code - The unit code * @returns {Number} The converted value */ Unit.prototype.to = function(code) { - if (!UNITS[code]) throw Error('Unknown unit code'); + if (!UNITS[code]) { + throw new errors.Unit.UnknownCode(code); + } var value = this._value / UNITS[code][0]; return parseFloat(value.toFixed(UNITS[code][1])); }; /** - * Will return the value represented in BTC + * Returns the value represented in BTC * * @returns {Number} The value converted to BTC */ @@ -141,26 +141,25 @@ Unit.prototype.toBTC = function() { }; /** - * - * Will return the value represented in mBTC + * Returns the value represented in mBTC * * @returns {Number} The value converted to mBTC */ -Unit.prototype.toMilis = function(code) { +Unit.prototype.toMilis = function() { return this.to(Unit.mBTC); }; /** - * Will return the value represented in bits + * Returns the value represented in bits * * @returns {Number} The value converted to bits */ -Unit.prototype.toMicros = Unit.prototype.toBits = function(code) { +Unit.prototype.toMicros = Unit.prototype.toBits = function() { return this.to(Unit.bits); }; /** - * Will return the value represented in satoshis + * Returns the value represented in satoshis * * @returns {Number} The value converted to satoshis */ @@ -169,7 +168,7 @@ Unit.prototype.toSatoshis = function() { }; /** - * Will return a the string representation of the value in satoshis + * Returns a the string representation of the value in satoshis * * @returns {String} the value in satoshis */ @@ -178,7 +177,7 @@ Unit.prototype.toString = function() { }; /** - * Will return a plain object representation of the Unit + * Returns a plain object representation of the Unit * * @returns {Object} An object with the keys: amount and code */ @@ -194,7 +193,7 @@ Unit.prototype.toJSON = function toJSON() { }; /** - * Will return a string formatted for the console + * Returns a string formatted for the console * * @returns {String} the value in satoshis */ diff --git a/test/unit.js b/test/unit.js index 063fa6dd9..ebd42041f 100644 --- a/test/unit.js +++ b/test/unit.js @@ -1,30 +1,36 @@ 'use strict'; var should = require('chai').should(); +var expect = require('chai').expect; + var bitcore = require('..'); +var errors = bitcore.errors; var Unit = bitcore.Unit; describe('Unit', function() { - it('should create an instance', function() { - var unit; - - unit = new Unit(1.2, 'BTC'); - should.exist(unit); - - unit = Unit(1.2, 'BTC'); - should.exist(unit); + it('can be created from a number and unit', function() { + expect(function() { + return new Unit(1.2, 'BTC'); + }).to.not.throw(); }); - it('should have property accesors', function() { + it('no "new" is required for creating an instance', function() { + expect(function() { + return Unit(1.2, 'BTC'); + }).to.not.throw(); + }); + + it('has property accesors "BTC", "mBTC", "uBTC", "bits", and "satoshis"', function() { var unit = new Unit(1.2, 'BTC'); - should.exist(unit.BTC); - should.exist(unit.mBTC); - should.exist(unit.bits); - should.exist(unit.satoshis); + unit.BTC.should.equal(1.2); + unit.mBTC.should.equal(1200); + unit.uBTC.should.equal(1200000); + unit.bits.should.equal(1200000); + unit.satoshis.should.equal(120000000); }); - it('should allow amount as string', function() { + it('a string amount is allowed', function() { var unit; unit = Unit.fromBTC('1.00001'); @@ -56,7 +62,8 @@ describe('Unit', function() { unit.satoshis.should.equal(8999); }); - it('should convert to satoshis correctly', function() { + it('converts to satoshis correctly', function() { + /* jshint maxstatements: 25 */ var unit; unit = Unit.fromBTC(1.3); @@ -80,14 +87,14 @@ describe('Unit', function() { unit.bits.should.equal(0.03); }); - it('should take in count floating point problems', function() { + it('takes into account floating point problems', function() { var unit = Unit.fromBTC(0.00000003); unit.mBTC.should.equal(0.00003); unit.bits.should.equal(0.03); unit.satoshis.should.equal(3); }); - it('should expose unit codes', function() { + it('exposes unit codes', function() { should.exist(Unit.BTC); Unit.BTC.should.equal('BTC'); @@ -101,15 +108,7 @@ describe('Unit', function() { Unit.satoshis.should.equal('satoshis'); }); - it('should expose shorthand conversion methods', function() { - var unit = new Unit(1.3, 'BTC'); - unit.toBTC().should.equal(unit.BTC); - unit.toMilis().should.equal(unit.mBTC); - unit.toBits().should.equal(unit.bits); - unit.toSatoshis().should.equal(unit.satoshis); - }); - - it('should expose a general conversion method', function() { + it('exposes a method that converts to different units', function() { var unit = new Unit(1.3, 'BTC'); unit.to(Unit.BTC).should.equal(unit.BTC); unit.to(Unit.mBTC).should.equal(unit.mBTC); @@ -117,22 +116,44 @@ describe('Unit', function() { unit.to(Unit.satoshis).should.equal(unit.satoshis); }); - it('should have a toString method', function() { + it('exposes shorthand conversion methods', function() { + var unit = new Unit(1.3, 'BTC'); + unit.toBTC().should.equal(unit.BTC); + unit.toMilis().should.equal(unit.mBTC); + unit.toBits().should.equal(unit.bits); + unit.toSatoshis().should.equal(unit.satoshis); + }); + + it('toString works as expected', function() { var unit = new Unit(1.3, 'BTC'); should.exist(unit.toString); unit.toString().should.be.a('string'); }); - it('should input/output JSON', function() { + it('can be imported and exported from/to JSON', function() { var json = JSON.stringify({amount:1.3, code:'BTC'}); var unit = Unit.fromJSON(json); unit.toJSON().should.deep.equal(json); }); - it('should have an inspect method', function() { + it('importing from invalid JSON fails quickly', function() { + expect(function() { + return Unit.fromJSON('ยน'); + }).to.throw(); + }); + + it('inspect method displays nicely', function() { var unit = new Unit(1.3, 'BTC'); - should.exist(unit.inspect); - unit.inspect().should.be.a('string'); + unit.inspect().should.equal(''); + }); + + it('fails when the unit is not recognized', function() { + expect(function() { + return new Unit(100, 'USD'); + }).to.throw(errors.Unit.UnknownCode); + expect(function() { + return new Unit(100, 'BTC').to('USD'); + }).to.throw(errors.Unit.UnknownCode); }); });