UNPKG

probable

Version:

Utilities for creating and using probability tables.

383 lines (336 loc) 11 kB
/* global suite test */ // These tests need to be run with the "--ui tdd" switch. // They should be run after the server (app.js) has been started. var assert = require('assert'); var probable = require('../probable'); var seedrandom = require('seedrandom'); // var _ = require('lodash'); var settings = { rangeTableAParams: [[[0, 80], 'a'], [[81, 95], 'b'], [[96, 100], 'c']], rangeTableBParams: { success: 20, doover: 5, failure: 30 } }; suite('roll', function rollSuite() { test('should roll results that are within 0 and 5.', function rollD6(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.roll(6); assert.ok(result >= 0); assert.ok(result < 6); } testDone(); }); var maxInt = 9007199254740992; test('should roll results that are within 0 and maxInt - 1.', function rollD6(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.roll(maxInt); // console.log(result); assert.ok(result >= 0); assert.ok(result < maxInt); } testDone(); }); test('should roll 0 when rolling a 0-sided die.', function rollD6(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.roll(0); assert.ok(result === 0); } testDone(); }); test('should roll 0 when rolling a 1-sided die.', function rollD6(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.roll(1); assert.ok(result === 0); } testDone(); }); }); suite('rollDie', function rollDieSuite() { test('should roll results that are within 1 and 6, inclusive.', function rollD6(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.rollDie(6); assert.ok(result >= 1); assert.ok(result <= 6); } testDone(); }); var maxInt = 9007199254740992; test('should roll results that are within 1 and maxInt, inclusive.', function rollD6(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.rollDie(maxInt); // console.log(result); assert.ok(result >= 1); assert.ok(result <= maxInt); } testDone(); }); test('should roll 0 when rolling a 0-sided die.', function rollD6(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.rollDie(0); assert.ok(result === 0); } testDone(); }); test('should roll 1 when rolling a 1-sided die.', function rollD6(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.rollDie(1); assert.ok(result === 1); } testDone(); }); }); suite('pickFromArray', function pickFromArraySuite() { test('should return the emptyArrayDefault when picking from an empty array.', function pickFromEmpty(testDone) { assert.equal(probable.pickFromArray([], 'Empty'), 'Empty'); testDone(); }); test('should return the emptyArrayDefault when picking from a non-array.', function pickFromNonArray(testDone) { assert.equal(probable.pickFromArray({}, 'Empty'), 'Empty'); testDone(); }); test('should return the emptyArrayDefault when picking from undefined', function pickFromUndefined(testDone) { assert.equal(probable.pickFromArray(undefined, 'Empty'), 'Empty'); testDone(); }); test( 'should always return the same result when picking from a ' + 'single-element array', function pickFromSingleElementArray(testDone) { for (var i = 0; i < 10; ++i) { assert.equal(probable.pickFromArray(['hay']), 'hay'); } testDone(); } ); test( 'should always return an element in the array when picking from a ' + 'two-element array', function pickFromTwoElementArray(testDone) { for (var i = 0; i < 100; ++i) { var result = probable.pickFromArray(['hay', 'guys']); assert.ok(result === 'hay' || result === 'guys'); } testDone(); } ); test( 'should always return an element in the array when picking from a ' + 'multi-element array', function pickFromBiggerArray(testDone) { var array = []; for (var j = 0; j < 1000; ++j) { array.push(probable.roll(10000)); } for (var i = 0; i < 100; ++i) { var result = probable.pickFromArray(array); assert.ok(array.indexOf(result) > -1); } testDone(); } ); }); suite('createRangeTable', function createRangeTableSuite() { test('should create a rangeTable', function createRangeTableTest(testDone) { var table = probable.createRangeTable(settings.rangeTableAParams); assert.equal(typeof table, 'object'); assert.equal(table.length, 101); var outcome; for (var i = 0; i <= 100; ++i) { outcome = table.outcomeAtIndex(i); var expectedValue = 'a'; if (i > 80 && i < 96) { expectedValue = 'b'; } else if (i >= 96) { expectedValue = 'c'; } assert.equal(expectedValue, outcome); } for (var j = 0; j <= 100; ++j) { outcome = table.roll(); assert.ok(outcome === 'a' || outcome === 'b' || outcome === 'c'); // TODO: Make sure the outcome distribution is reasonable. } assert.equal(table.length, 101); testDone(); }); }); suite('createRangeTableFromDict', function createRangeTableFromDictSuite() { test('should create a rangeTable from a dict', function createRangeTableFromDictTest(testDone) { var outcome; var table = probable.createRangeTableFromDict(settings.rangeTableBParams); assert.equal(typeof table, 'object'); assert.equal(table.length, 55); for (var i = 0; i < 55; ++i) { outcome = table.outcomeAtIndex(i); var expectedValue = 'failure'; if (i > 29 && i < 50) { expectedValue = 'success'; } else if (i >= 50) { expectedValue = 'doover'; } assert.equal(expectedValue, outcome); } for (var j = 0; j <= 100; ++j) { outcome = table.roll(); assert.ok( outcome === 'failure' || outcome === 'success' || outcome === 'doover' ); // TODO: Make sure the outcome distribution is reasonable. } testDone(); }); }); suite('Custom probable', function customRandomSuite() { test('should use custom random fn', function customRandomTest(testDone) { var altprob = probable.createProbable({ random: function notSoRandom() { return 0.5; } }); for (var i = 0; i < 100; ++i) { assert.equal(altprob.roll(3), 1); } var table = altprob.createRangeTable(settings.rangeTableAParams); for (var j = 0; j <= 100; ++j) { var outcome = table.roll(); assert.equal(outcome, 'a'); } testDone(); }); }); suite('convertDictToRangesAndOutcomePairs', function convertSuite() { test('should return an array of arrays, sorted by size', function convertTest() { var pairs = probable.convertDictToRangesAndOutcomePairs({ second: 25, first: 50, fourth: 10, third: 20 }); assert.deepEqual(pairs, [ [[0, 49], 'first'], [[50, 74], 'second'], [[75, 94], 'third'], [[95, 104], 'fourth'] ]); }); }); suite('getCartesianProduct', function crossArraysSuite() { test('should combine every element in array A with every element in array B', function crossArraysTest() { var a = ['a', 'b', 'c', 'd']; var b = [0, 1, 2]; assert.deepEqual(probable.getCartesianProduct([a, b]), [ ['a', 0], ['a', 1], ['a', 2], ['b', 0], ['b', 1], ['b', 2], ['c', 0], ['c', 1], ['c', 2], ['d', 0], ['d', 1], ['d', 2] ]); }); test('should gemerate an empty array if one of the params is an empty array', function crossEmptyArrayTest() { var a = ['a', 'b', 'c', 'd']; var b = []; assert.deepEqual(probable.getCartesianProduct([a, b]), []); }); test('cross array with one-element array', function crossOneElementArrayTest() { var a = ['a', 'b', 'c', 'd']; var b = [100]; assert.deepEqual(probable.getCartesianProduct([a, b]), [ ['a', 100], ['b', 100], ['c', 100], ['d', 100] ]); }); test('should get the Cartesian product of three arrays', function threeArrayCartesianProductTest() { var product = probable.getCartesianProduct([ [null, 'a', 'b'], ['omega', 'gamma'], [null, 1, 2] ]); assert.deepEqual(product, [ [null, 'omega', null], [null, 'omega', 1], [null, 'omega', 2], [null, 'gamma', null], [null, 'gamma', 1], [null, 'gamma', 2], ['a', 'omega', null], ['a', 'omega', 1], ['a', 'omega', 2], ['a', 'gamma', null], ['a', 'gamma', 1], ['a', 'gamma', 2], ['b', 'omega', null], ['b', 'omega', 1], ['b', 'omega', 2], ['b', 'gamma', null], ['b', 'gamma', 1], ['b', 'gamma', 2] ]); }); test('should get the Cartesian product of four arrays', function fourArrayCartesianProductTest() { var product = probable.getCartesianProduct([ [null, 'a', 'b'], ['omega', 'gamma'], [null, 1, 2], ['Bonus Cat', 'Dr. Wily'] ]); assert.deepEqual(product, [ [null, 'omega', null, 'Bonus Cat'], [null, 'omega', null, 'Dr. Wily'], [null, 'omega', 1, 'Bonus Cat'], [null, 'omega', 1, 'Dr. Wily'], [null, 'omega', 2, 'Bonus Cat'], [null, 'omega', 2, 'Dr. Wily'], [null, 'gamma', null, 'Bonus Cat'], [null, 'gamma', null, 'Dr. Wily'], [null, 'gamma', 1, 'Bonus Cat'], [null, 'gamma', 1, 'Dr. Wily'], [null, 'gamma', 2, 'Bonus Cat'], [null, 'gamma', 2, 'Dr. Wily'], ['a', 'omega', null, 'Bonus Cat'], ['a', 'omega', null, 'Dr. Wily'], ['a', 'omega', 1, 'Bonus Cat'], ['a', 'omega', 1, 'Dr. Wily'], ['a', 'omega', 2, 'Bonus Cat'], ['a', 'omega', 2, 'Dr. Wily'], ['a', 'gamma', null, 'Bonus Cat'], ['a', 'gamma', null, 'Dr. Wily'], ['a', 'gamma', 1, 'Bonus Cat'], ['a', 'gamma', 1, 'Dr. Wily'], ['a', 'gamma', 2, 'Bonus Cat'], ['a', 'gamma', 2, 'Dr. Wily'], ['b', 'omega', null, 'Bonus Cat'], ['b', 'omega', null, 'Dr. Wily'], ['b', 'omega', 1, 'Bonus Cat'], ['b', 'omega', 1, 'Dr. Wily'], ['b', 'omega', 2, 'Bonus Cat'], ['b', 'omega', 2, 'Dr. Wily'], ['b', 'gamma', null, 'Bonus Cat'], ['b', 'gamma', null, 'Dr. Wily'], ['b', 'gamma', 1, 'Bonus Cat'], ['b', 'gamma', 1, 'Dr. Wily'], ['b', 'gamma', 2, 'Bonus Cat'], ['b', 'gamma', 2, 'Dr. Wily'] ]); }); }); suite('Shuffle', function shuffleSuite() { test('should shuffle', function shuffleTest(testDone) { var prob = probable.createProbable({ random: seedrandom('shuffleupagus') }); var shuffled = prob.shuffle([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]); assert.deepEqual(shuffled, [5, 1, 12, 10, 6, 7, 2, 8, 4, 3, 11, 9, 0]); testDone(); }); });