+156
| /*jslint indent: 2*/ | ||
| /*global require: true, module: true, describe: true, it: true, beforeEach: true, __dirname: true */ | ||
| (function () { | ||
| 'use strict'; | ||
| var exec = require('child_process').exec, | ||
| should = require('should'), | ||
| Roll = require('../lib'), | ||
| FakeRandom = require('./fake-random'), | ||
| random = new FakeRandom([ // can only test this library if we make things not actually random | ||
| 0.24, // 20 * .24 => 4.8 => 5 | ||
| 0.62, // 20 * .62 => 12.4 => 13 | ||
| 0.51, // 20 * .51 => 10.2 => 11 | ||
| 0.13, // 20 * .13 => 2.6 => 3 | ||
| 0.66 // 20 * .66 => 13.2 => 14 | ||
| ]), | ||
| roll = new Roll(random.next.bind(random)); | ||
| describe('roll', function () { | ||
| beforeEach(random.reset.bind(random)); | ||
| describe('multiroll', function () { | ||
| it('1d20+1d20', function () { | ||
| var result = roll.roll('1d20+1d20'); | ||
| result.result.should.equal(18); | ||
| }); | ||
| it('d20+1d20', function () { | ||
| var result = roll.roll('d20+1d20'); | ||
| result.result.should.equal(18); | ||
| }); | ||
| it('1d20+d20', function () { | ||
| var result = roll.roll('1d20+d20'); | ||
| result.result.should.equal(18); | ||
| }); | ||
| it('d20+d20', function () { | ||
| var result = roll.roll('d20+d20'); | ||
| result.result.should.equal(18); | ||
| }); | ||
| }); | ||
| it('d20', function () { | ||
| var result = roll.roll('d20'); | ||
| result.rolled.length.should.equal(1); | ||
| result.rolled[0].should.equal(5); | ||
| result.result.should.equal(5); | ||
| }); | ||
| it('d%', function () { | ||
| var result = roll.roll('d%'); | ||
| result.rolled.length.should.equal(1); | ||
| result.rolled[0].should.equal(25); | ||
| result.result.should.equal(25); | ||
| }); | ||
| it('2d20', function () { | ||
| var result = roll.roll('2d20'); | ||
| result.rolled.length.should.equal(2); | ||
| result.rolled[0].should.equal(5); | ||
| result.rolled[1].should.equal(13); | ||
| result.result.should.equal(18); | ||
| }); | ||
| it('2d20+3', function () { | ||
| var result = roll.roll('2d20+3'); | ||
| result.result.should.equal(21); // SUM + 3 | ||
| }); | ||
| it('2d20-3', function () { | ||
| var result = roll.roll('2d20-3'); | ||
| result.result.should.equal(15); // SUM - 3 | ||
| }); | ||
| it('2d20*3', function () { | ||
| var result = roll.roll('2d20*3'); | ||
| result.result.should.equal(54); // SUM * 3 | ||
| }); | ||
| it('2d20/3', function () { | ||
| var result = roll.roll('2d20/3'); | ||
| result.result.should.equal(6); // SUM / 3 | ||
| }); | ||
| it('5d20b1', function () { | ||
| var result = roll.roll('5d20b1'); | ||
| result.result.should.equal(14); | ||
| }); | ||
| it('5d20b2', function () { | ||
| var result = roll.roll('5d20b2'); | ||
| result.calculations[1].length.should.equal(2); | ||
| result.calculations[1][0].should.equal(14); | ||
| result.calculations[1][1].should.equal(13); | ||
| result.result.should.equal(27); // 14 + 13 | ||
| }); | ||
| it('5d20w1', function () { | ||
| var result = roll.roll('5d20w1'); | ||
| result.result.should.equal(3); | ||
| }); | ||
| it('5d20w2', function () { | ||
| var result = roll.roll('5d20w2'); | ||
| result.calculations[1].length.should.equal(2); | ||
| result.calculations[1][0].should.equal(3); | ||
| result.calculations[1][1].should.equal(5); | ||
| result.result.should.equal(8); // 3 + 5 | ||
| }); | ||
| it('validates input', function (done) { | ||
| try { | ||
| roll.roll('garbage'); | ||
| done('Should not be reachable.'); | ||
| } catch (e) { | ||
| should.exist(e); | ||
| e.name.should.eql('InvalidInputError'); | ||
| e.message.should.eql('"garbage" is not a valid input string for node-roll.'); | ||
| e.input.should.eql('garbage'); | ||
| done(); | ||
| } | ||
| }); | ||
| it('exposes validation', function () { | ||
| roll.validate('2d20+3').should.equal(true); | ||
| roll.validate('garbage').should.equal(false); | ||
| }); | ||
| it('bin/roll garbage', function (done) { | ||
| exec(__dirname + '/../bin/roll garbage', function (err, stdout, stderr) { | ||
| if (err) { | ||
| should.exist(err); | ||
| stderr.should.eql('"garbage" is not a valid input string for node-roll.\n'); | ||
| return done(); | ||
| } | ||
| done('Should not be reachable.'); | ||
| }); | ||
| }); | ||
| it('bin/roll 2d20', function (done) { | ||
| exec(__dirname + '/../bin/roll 2d20', function (err, stdout, stderr) { | ||
| if (err) { | ||
| return done(err); | ||
| } | ||
| /^\d+\n$/.test(stdout).should.eql(true); | ||
| done(); | ||
| }); | ||
| }); | ||
| }); | ||
| }()); | ||
+45
-8
@@ -9,4 +9,6 @@ /*jslint indent: 2*/ | ||
| transformationKeys = require('./keys'), | ||
| regex = /^(\d*)d(\d+|\%)(([\+\-\/\*bw])(\d+))?$/, | ||
| roll; | ||
| regex = /^(\d*)d(\d+|\%)(([\+\-\/\*bw])(\d+))?(([\+\-\/\*])(\d+|(\d*)d(\d+|\%)(([\+\-\/\*bw])(\d+))?))*$/, | ||
| roll, | ||
| cleaner, | ||
| sumResult = false; | ||
@@ -32,9 +34,27 @@ roll = function (random) { | ||
| hasTransformation = !!match[3], // 2d20+3 => true | ||
| operator = match[4], // 2d20+3 => "+" | ||
| transformationParameter = match[5]; // 2d20+3 => 3 | ||
| operator, | ||
| transformationParameter, | ||
| transforms = [], | ||
| opIndex = 0, | ||
| segments = s.split(/[\+\-]/); | ||
| if (segments[0].indexOf('b') > -1) { | ||
| transforms.push(transformationKeys[match[4]](parseInt(match[5], 10))); | ||
| } | ||
| for (var seg = 1; seg < segments.length; seg++) { | ||
| opIndex += segments[seg - 1].length; | ||
| operator = s[opIndex]; // 2d20+3 => "+" | ||
| opIndex += 1; | ||
| transformationParameter = segments[seg]; // 2d20+3 => 3 | ||
| if (transformationParameter.indexOf('d') > -1) { | ||
| transforms.push(transformationKeys[operator](parseInt(this.roll(transformationParameter).result, 10))); | ||
| } else { | ||
| transforms.push(transformationKeys[operator](parseInt(transformationParameter, 10))); | ||
| } | ||
| } | ||
| return { | ||
| quantity: quantity ? parseInt(quantity, 10) : 1, | ||
| sides: sides === '%' ? 100 : parseInt(sides, 10), | ||
| transformations: hasTransformation ? transformationKeys[operator](parseInt(transformationParameter, 10)) : ['sum'], | ||
| transformations: hasTransformation || transforms.length > 0 ? transforms.length > 0 ? transforms : transformationKeys[match[4]](parseInt(match[5], 10)) : ['sum'], | ||
| toString: function () { | ||
@@ -62,3 +82,4 @@ return s; | ||
| var transformationFunction, | ||
| transformationAdditionalParameter; | ||
| transformationAdditionalParameter, | ||
| sumParam = false; | ||
@@ -70,6 +91,17 @@ if (typeof transformation === 'function') { // lets you pass something custom in | ||
| } else if (transformation instanceof Array) { // ["add", 3] | ||
| if (transformation[0] instanceof Array) { | ||
| sumResult = true; | ||
| cleaner = transformation[1]; | ||
| transformation = transformation[0]; | ||
| } else if (transformation[1] instanceof Array) { | ||
| sumParam = true; | ||
| cleaner = transformation[0]; | ||
| transformation = transformation[1]; | ||
| } | ||
| transformationFunction = transformationFunctions[transformation[0]]; // fn for "add" | ||
| transformationAdditionalParameter = transformation[1]; // 3 | ||
| transformationAdditionalParameter = transformation[1]; | ||
| } | ||
| if (sumParam === true && previous[0] instanceof Array){ | ||
| previous[0] = transformationFunctions[cleaner](previous[0]); | ||
| } | ||
| previous.unshift(transformationFunction(previous[0], transformationAdditionalParameter)); | ||
@@ -79,2 +111,7 @@ return previous; | ||
| if (sumResult === true && calculations[0] instanceof Array) { | ||
| calculations[1] = calculations[0]; | ||
| calculations[0] = transformationFunctions[cleaner](calculations[0]); | ||
| } | ||
| return { | ||
@@ -81,0 +118,0 @@ input: input, |
+1
-1
| { | ||
| "name": "roll", | ||
| "version": "1.0.0", | ||
| "version": "1.1.0", | ||
| "author": "Troy Goode <troygoode@gmail.com> (https://github.com/troygoode/)", | ||
@@ -5,0 +5,0 @@ "description": "node.js package for rolling dice and adding modifiers. ex: 2d6+1", |
-132
| /*jslint indent: 2*/ | ||
| /*global require: true, module: true, describe: true, it: true, beforeEach: true, __dirname: true */ | ||
| (function () { | ||
| 'use strict'; | ||
| var exec = require('child_process').exec, | ||
| should = require('should'), | ||
| Roll = require('../lib'), | ||
| FakeRandom = require('./fake-random'), | ||
| random = new FakeRandom([ // can only test this library if we make things not actually random | ||
| 0.24, // 20 * .24 => 4.8 => 5 | ||
| 0.62, // 20 * .62 => 12.4 => 13 | ||
| 0.51, // 20 * .51 => 10.2 => 11 | ||
| 0.13, // 20 * .13 => 2.6 => 3 | ||
| 0.66 // 20 * .66 => 13.2 => 14 | ||
| ]), | ||
| roll = new Roll(random.next.bind(random)); | ||
| describe('roll', function () { | ||
| beforeEach(random.reset.bind(random)); | ||
| it('d20', function () { | ||
| var result = roll.roll('d20'); | ||
| result.rolled.length.should.equal(1); | ||
| result.rolled[0].should.equal(5); | ||
| result.result.should.equal(5); | ||
| }); | ||
| it('d%', function () { | ||
| var result = roll.roll('d%'); | ||
| result.rolled.length.should.equal(1); | ||
| result.rolled[0].should.equal(25); | ||
| result.result.should.equal(25); | ||
| }); | ||
| it('2d20', function () { | ||
| var result = roll.roll('2d20'); | ||
| result.rolled.length.should.equal(2); | ||
| result.rolled[0].should.equal(5); | ||
| result.rolled[1].should.equal(13); | ||
| result.result.should.equal(18); | ||
| }); | ||
| it('2d20+3', function () { | ||
| var result = roll.roll('2d20+3'); | ||
| result.result.should.equal(21); // SUM + 3 | ||
| }); | ||
| it('2d20-3', function () { | ||
| var result = roll.roll('2d20-3'); | ||
| result.result.should.equal(15); // SUM - 3 | ||
| }); | ||
| it('2d20*3', function () { | ||
| var result = roll.roll('2d20*3'); | ||
| result.result.should.equal(54); // SUM * 3 | ||
| }); | ||
| it('2d20/3', function () { | ||
| var result = roll.roll('2d20/3'); | ||
| result.result.should.equal(6); // SUM / 3 | ||
| }); | ||
| it('5d20b1', function () { | ||
| var result = roll.roll('5d20b1'); | ||
| result.result.should.equal(14); | ||
| }); | ||
| it('5d20b2', function () { | ||
| var result = roll.roll('5d20b2'); | ||
| result.calculations[1].length.should.equal(2); | ||
| result.calculations[1][0].should.equal(14); | ||
| result.calculations[1][1].should.equal(13); | ||
| result.result.should.equal(27); // 14 + 13 | ||
| }); | ||
| it('5d20w1', function () { | ||
| var result = roll.roll('5d20w1'); | ||
| result.result.should.equal(3); | ||
| }); | ||
| it('5d20w2', function () { | ||
| var result = roll.roll('5d20w2'); | ||
| result.calculations[1].length.should.equal(2); | ||
| result.calculations[1][0].should.equal(3); | ||
| result.calculations[1][1].should.equal(5); | ||
| result.result.should.equal(8); // 3 + 5 | ||
| }); | ||
| it('validates input', function (done) { | ||
| try { | ||
| roll.roll('garbage'); | ||
| done('Should not be reachable.'); | ||
| } catch (e) { | ||
| should.exist(e); | ||
| e.name.should.eql('InvalidInputError'); | ||
| e.message.should.eql('"garbage" is not a valid input string for node-roll.'); | ||
| e.input.should.eql('garbage'); | ||
| done(); | ||
| } | ||
| }); | ||
| it('exposes validation', function () { | ||
| roll.validate('2d20+3').should.equal(true); | ||
| roll.validate('garbage').should.equal(false); | ||
| }); | ||
| it('bin/roll garbage', function (done) { | ||
| exec(__dirname + '/../bin/roll garbage', function (err, stdout, stderr) { | ||
| if (err) { | ||
| should.exist(err); | ||
| stderr.should.eql('"garbage" is not a valid input string for node-roll.\n'); | ||
| return done(); | ||
| } | ||
| done('Should not be reachable.'); | ||
| }); | ||
| }); | ||
| it('bin/roll 2d20', function (done) { | ||
| exec(__dirname + '/../bin/roll 2d20', function (err, stdout, stderr) { | ||
| if (err) { | ||
| return done(err); | ||
| } | ||
| /^\d+\n$/.test(stdout).should.eql(true); | ||
| done(); | ||
| }); | ||
| }); | ||
| }); | ||
| }()); | ||
Sorry, the diff of this file is not supported yet
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
18391
13.85%392
15.98%162
4.52%1
-50%