chromabrew
Version:
Predict the color of a batch of beer, and convert between known color values and web-friendly hex.
201 lines (161 loc) • 6.74 kB
JavaScript
let assert = require('assert');
let chromabrew = require('./index.js');
const ERROR_CORRECTION_FACTOR = 1e3;
describe('chromabrew', function () {
it('has Batch property', function () {
assert(chromabrew.Batch instanceof Function);
});
it('is a function which returns a Batch instance', function () {
assert(chromabrew instanceof Function);
let batch = chromabrew({});
assert(batch instanceof chromabrew.Batch);
});
});
describe('Batch', function () {
describe('Constructor', function () {
let batches = [
{ in: { srm: 10 }, out: { srm: 10, ebc: 10 * 1.97, l: (10 + 0.6) / 1.35 } },
{ in: { ebc: 10 }, out: { srm: 10 / 1.97, ebc: 10, l: (10 / 1.97 + 0.6) / 1.35 } },
{ in: { srm: 4, calculator: 'daniels' }, out: { 'srm("daniels")': 8.4, mcu: 0 }, msg: 'minimum value for selected calculator' },
{ in: { srm: 4, calculator: 'mosher' }, out: { 'srm("mosher")': 4.7, mcu: 0 }, msg: 'minimum value for selected calculator' },
{ in: { batch: { volume: 1, ingredients: [{ l: 10, w: 1 }, { l: 20, w: 1 }] } } },
{ in: { batch: { volume: 1, ingredients: [{ l: 10, w: 1 }, { l: 20, w: 1 }], litres: true } } },
{ in: { batch: { volume: 1, ingredients: [{ l: 10, w: 1 }, { l: 20, w: 1 }], kilograms: true } } },
{ in: { batch: { volume: 1, ingredients: [{ l: 10, w: 1 }, { l: 20, w: 1 }], metric: true } } },
];
batches.forEach(function (batch) {
describe(`given input ${ JSON.stringify(batch.in) }`, function () {
let instance = chromabrew(batch.in);
it('mcu is a non-negative number', function () {
// this is a test of internals (mcu must always be defined), but is more clear than a test of exact output values
let result = instance.mcu();
assert.equal(typeof result, 'number');
assert(result >= 0);
});
if (batch.out) {
if (Object.keys(batch.out).length) {
Object.keys(batch.out).forEach(function (key) {
it(`${ key } is ${ batch.out[key] }${ batch.msg ? ` [${ batch.msg }]` : '' }`, function () {
let actual = eval(`instance.${ key + (key.endsWith(')') ? '' : '()') }`);
let expected = batch.out[key];
if (typeof actual === 'number' && typeof expected === 'number') {
// correct floating point errors
actual = Math.round(actual * ERROR_CORRECTION_FACTOR) / ERROR_CORRECTION_FACTOR;
expected = Math.round(expected * ERROR_CORRECTION_FACTOR) / ERROR_CORRECTION_FACTOR;
}
assert.equal(actual, expected);
});
});
} else {
it('has specified output');
}
}
});
})
});
describe('#mcu', function () {
let instance = chromabrew({ srm: 4 });
it('returns number', function () {
assert.equal(typeof instance.mcu(), 'number');
});
});
describe('#srm', function () {
let instance = chromabrew({ srm: 4 });
it('returns number', function () {
assert.equal(typeof instance.srm(), 'number');
});
it('accepts optional calculator which defaults to "morey"', function () {
assert.doesNotThrow(instance.srm.bind(instance));
Object.keys(chromabrew.Batch.mcu).forEach(function (calculator) {
assert[calculator === 'morey' ? 'equal' : 'notEqual'](instance.srm(calculator), instance.srm());
});
});
});
describe('#ebc', function () {
let instance = chromabrew({ srm: 4 });
it('returns number', function () {
assert.equal(typeof instance.ebc(), 'number');
});
it('accepts optional calculator which defaults to "morey"', function () {
assert.doesNotThrow(instance.ebc.bind(instance));
Object.keys(chromabrew.Batch.mcu).forEach(function (calculator) {
assert[calculator === 'morey' ? 'equal' : 'notEqual'](instance.ebc(calculator), instance.ebc());
});
});
});
describe('#lovibond', function () {
let instance = chromabrew({ srm: 4 });
it('returns number', function () {
assert.equal(typeof instance.lovibond(), 'number');
});
it('accepts optional calculator which defaults to "morey"', function () {
assert.doesNotThrow(instance.lovibond.bind(instance));
Object.keys(chromabrew.Batch.mcu).forEach(function (calculator) {
assert[calculator === 'morey' ? 'equal' : 'notEqual'](instance.lovibond(calculator), instance.lovibond());
});
});
});
describe('#hex', function () {
let instance = chromabrew({ srm: 4 });
it('returns hex string', function () {
let result = instance.hex();
assert.equal(typeof result, 'string');
assert(result.match(/^#[A-F0-9]{6}$/));
});
it('accepts optional calculator which defaults to "morey"', function () {
assert.doesNotThrow(instance.hex.bind(instance));
Object.keys(chromabrew.Batch.mcu).forEach(function (calculator) {
assert[calculator === 'morey' ? 'equal' : 'notEqual'](instance.hex(calculator), instance.hex());
});
});
});
describe('#l', function () {
it('aliases #lovibond', function () {
assert.equal(chromabrew.Batch.prototype.l, chromabrew.Batch.prototype.lovibond);
});
});
describe('::mcu', function () {
describe('#morey', function () {
it('returns number', function () {
assert.equal(typeof chromabrew.Batch.mcu.morey(30), 'number');
});
});
describe('#daniels', function () {
it('returns number', function () {
assert.equal(typeof chromabrew.Batch.mcu.daniels(30), 'number');
});
});
describe('#mosher', function () {
it('returns number', function () {
assert.equal(typeof chromabrew.Batch.mcu.mosher(30), 'number');
});
});
describe('#barry', function () {
it('returns number', function () {
assert.equal(typeof chromabrew.Batch.mcu.barry(30), 'number');
});
});
});
describe('::srm', function () {
describe('#morey', function () {
it('returns number', function () {
assert.equal(typeof chromabrew.Batch.srm.morey(30), 'number');
});
});
describe('#daniels', function () {
it('returns number', function () {
assert.equal(typeof chromabrew.Batch.srm.daniels(30), 'number');
});
});
describe('#mosher', function () {
it('returns number', function () {
assert.equal(typeof chromabrew.Batch.srm.mosher(30), 'number');
});
});
describe('#barry', function () {
it('returns number', function () {
assert.equal(typeof chromabrew.Batch.srm.barry(30), 'number');
});
});
});
});