From 78fc63be2783d874d1c38240bf0d2f44d610fe25 Mon Sep 17 00:00:00 2001 From: n1ru4l Date: Tue, 20 Apr 2021 13:52:14 +0200 Subject: [PATCH 1/6] feat: allow passing a custom random function to createDiceRoller that is then passed down to the roll fucntion as a function argument. This makes mocking the random function in tests easier. --- README.md | 4 +--- src/createDiceRoller.ts | 5 +++-- src/rollDice.ts | 4 ++-- src/rules/__test__/simpleDieRoll.test.ts | 3 ++- src/rules/simpleDieRoll.ts | 3 +-- src/rules/types.ts | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 54fb833..f7a3d6d 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,6 @@ Let's say we want to add a rule to allow us to use `d%` instead of `d100`. We ca ```js // A convenience function for rolling a dice. You can use something else if you want -import { random } from '@airjp73/dice-notation'; - const myRule = { // Regex to pass to the parser regex: /\d+d%/, @@ -59,7 +57,7 @@ const myRule = { // Takes the data returned from `tokenize` and returns an array of rolls // this is so we can see what every individual dice roll was if we want - roll: ({ numDice }) => { + roll: ({ numDice }, random) => { const rolls = []; for (let i = 0; i < numDice; i++) { rolls.push(random(1, 100)); diff --git a/src/createDiceRoller.ts b/src/createDiceRoller.ts index 8e80b02..f7439a5 100644 --- a/src/createDiceRoller.ts +++ b/src/createDiceRoller.ts @@ -6,15 +6,16 @@ import createRoll from './roll'; import createTokenize from './tokenize'; import simpleDieRoll from './rules/simpleDieRoll'; import constant from './rules/constant'; +import defaultRandom from "./util/random" export const defaultPlugins = { [simpleDieRoll.typeConstant]: simpleDieRoll, [constant.typeConstant]: constant, }; -function createDiceRoller(plugins: Plugins = defaultPlugins) { +function createDiceRoller(plugins: Plugins = defaultPlugins, random = defaultRandom) { const tokenize = createTokenize(plugins); - const rollDice = createRollDice(plugins); + const rollDice = createRollDice(plugins, random); const tallyRolls = createTallyRolls(plugins); return { diff --git a/src/rollDice.ts b/src/rollDice.ts index f2d1e3a..bf47afb 100644 --- a/src/rollDice.ts +++ b/src/rollDice.ts @@ -1,7 +1,7 @@ import { Plugins, RollResults } from './rules/types'; import { CoreTokenTypes, Token } from './tokens'; -function createRollDice(plugins: Plugins) { +function createRollDice(plugins: Plugins, random: (min: number, max: number) => number) { function rollDice(tokens: Token[]): RollResults { return tokens.map(token => { switch (token.type) { @@ -10,7 +10,7 @@ function createRollDice(plugins: Plugins) { case CoreTokenTypes.Operator: return null; case CoreTokenTypes.DiceRoll: - return plugins[token.detailType].roll(token.detail); + return plugins[token.detailType].roll(token.detail, random); } }); } diff --git a/src/rules/__test__/simpleDieRoll.test.ts b/src/rules/__test__/simpleDieRoll.test.ts index 0473476..228a102 100644 --- a/src/rules/__test__/simpleDieRoll.test.ts +++ b/src/rules/__test__/simpleDieRoll.test.ts @@ -1,3 +1,4 @@ +import { random } from '../../index'; import simpleDieRoll from '../simpleDieRoll'; describe('simpleDieRoll', () => { @@ -12,7 +13,7 @@ describe('simpleDieRoll', () => { describe('roll', () => { it('should return an array with one number for each dice rolled', () => { - const rolls = simpleDieRoll.roll({ count: 25, numSides: 6 }); + const rolls = simpleDieRoll.roll({ count: 25, numSides: 6 }, random); expect(rolls).toHaveLength(25); rolls.forEach(val => { expect(val).toBeLessThanOrEqual(6); diff --git a/src/rules/simpleDieRoll.ts b/src/rules/simpleDieRoll.ts index d052359..de45cd9 100644 --- a/src/rules/simpleDieRoll.ts +++ b/src/rules/simpleDieRoll.ts @@ -1,5 +1,4 @@ import { DiceRule } from './types'; -import random from '../util/random'; export const SIMPLE_DIE_ROLL = '_SimpleDieRoll'; @@ -15,7 +14,7 @@ const simpleDieRoll: DiceRule = { const [count, numSides] = raw.split('d').map(num => parseInt(num)); return { count, numSides }; }, - roll: ({ count, numSides }) => + roll: ({ count, numSides }, random) => new Array(count).fill(0).map(() => random(1, numSides)), calculateValue: (token, rolls) => rolls.reduce((agg, num) => agg + num, 0), }; diff --git a/src/rules/types.ts b/src/rules/types.ts index 848ba46..9d58b3c 100644 --- a/src/rules/types.ts +++ b/src/rules/types.ts @@ -6,7 +6,7 @@ export interface DiceRule { regex: RegExp; typeConstant: string; tokenize: (raw: string) => T; - roll: (token: T) => Rolls; + roll: (token: T, random: (min: number, max: number) => number) => Rolls; calculateValue: (token: T, rolls: number[]) => number; } From e60ccf3438092945f34775f76d4bbe11a6e3d882 Mon Sep 17 00:00:00 2001 From: n1ru4l Date: Wed, 21 Apr 2021 08:24:03 +0200 Subject: [PATCH 2/6] feat: export more typescript types --- src/index.ts | 4 ++++ src/rollDice.ts | 3 ++- src/rules/types.ts | 4 +++- src/util/random.ts | 2 ++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5d8cda0..b338f47 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,10 @@ import createDiceRoller from './createDiceRoller'; export { default as createDiceRoller } from './createDiceRoller'; export { default as withPlugins } from './withPlugins'; export { default as random } from './util/random'; +export type { Random } from "./util/random" +export type { Plugins, DiceRule, Rolls, RollResults } from "./rules/types" +export type { SimpleDiceRollToken } from "./rules/simpleDieRoll" +export type { BaseToken, OpenParenToken, CloseParenToken, OperatorToken, DiceRollToken, Token } from "./tokens" export const { tokenize, diff --git a/src/rollDice.ts b/src/rollDice.ts index bf47afb..9c26e5a 100644 --- a/src/rollDice.ts +++ b/src/rollDice.ts @@ -1,7 +1,8 @@ import { Plugins, RollResults } from './rules/types'; import { CoreTokenTypes, Token } from './tokens'; +import { Random } from './util/random'; -function createRollDice(plugins: Plugins, random: (min: number, max: number) => number) { +function createRollDice(plugins: Plugins, random: Random) { function rollDice(tokens: Token[]): RollResults { return tokens.map(token => { switch (token.type) { diff --git a/src/rules/types.ts b/src/rules/types.ts index 9d58b3c..9ab2b41 100644 --- a/src/rules/types.ts +++ b/src/rules/types.ts @@ -1,3 +1,5 @@ +import { Random } from "../util/random"; + export interface Plugins { [key: string]: DiceRule; } @@ -6,7 +8,7 @@ export interface DiceRule { regex: RegExp; typeConstant: string; tokenize: (raw: string) => T; - roll: (token: T, random: (min: number, max: number) => number) => Rolls; + roll: (token: T, random: Random) => Rolls; calculateValue: (token: T, rolls: number[]) => number; } diff --git a/src/util/random.ts b/src/util/random.ts index 1cf89b5..7a67e09 100644 --- a/src/util/random.ts +++ b/src/util/random.ts @@ -1,3 +1,5 @@ +export type Random = (min: number, max: number) => number + function random(min: number, max: number): number { return Math.floor(Math.random() * Math.floor(max - min + 1)) + min; } From 15f400ca0053f7606f50a099ebbe45fb2ac0fa44 Mon Sep 17 00:00:00 2001 From: n1ru4l Date: Wed, 21 Apr 2021 08:45:01 +0200 Subject: [PATCH 3/6] feat: allow passing a custom Random function to withPlugins as the last parameter via function overloading --- src/withPlugins.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/withPlugins.ts b/src/withPlugins.ts index df7a5b6..024e045 100644 --- a/src/withPlugins.ts +++ b/src/withPlugins.ts @@ -1,9 +1,20 @@ import { Plugins, DiceRule } from './rules/types'; import createDiceRoller, { defaultPlugins } from './createDiceRoller'; +import defaultRandom, { Random } from "./util/random" -function withPlugins(...plugins: DiceRule[]) { +function withPlugins(...plugins: DiceRule[]): ReturnType +function withPlugins(plugins: DiceRule[], random?: Random): ReturnType +function withPlugins(...args: any[]): ReturnType { + let plugins: DiceRule[]; + let random = defaultRandom + if (Array.isArray(args[0])) { + plugins = args[0] + random = args[1] ?? defaultRandom + } else { + plugins = args + } const customPlugins: Plugins = {}; - plugins.forEach(plugin => { + plugins.forEach((plugin) => { customPlugins[plugin.typeConstant] = plugin; }); From d632c749f816c45db9e04149ada977c04dd92224 Mon Sep 17 00:00:00 2001 From: n1ru4l Date: Wed, 21 Apr 2021 09:46:51 +0200 Subject: [PATCH 4/6] chore: add missing semicolons --- src/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index b338f47..38a66d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,10 +3,10 @@ import createDiceRoller from './createDiceRoller'; export { default as createDiceRoller } from './createDiceRoller'; export { default as withPlugins } from './withPlugins'; export { default as random } from './util/random'; -export type { Random } from "./util/random" -export type { Plugins, DiceRule, Rolls, RollResults } from "./rules/types" -export type { SimpleDiceRollToken } from "./rules/simpleDieRoll" -export type { BaseToken, OpenParenToken, CloseParenToken, OperatorToken, DiceRollToken, Token } from "./tokens" +export type { Random } from "./util/random"; +export type { Plugins, DiceRule, Rolls, RollResults } from "./rules/types"; +export type { SimpleDiceRollToken } from "./rules/simpleDieRoll"; +export type { BaseToken, OpenParenToken, CloseParenToken, OperatorToken, DiceRollToken, Token } from "./tokens"; export const { tokenize, From 78b8481875a39082d96c28492e4423d12e29b4d2 Mon Sep 17 00:00:00 2001 From: n1ru4l Date: Wed, 21 Apr 2021 10:07:07 +0200 Subject: [PATCH 5/6] chore: update typescript for type re-exporting --- package-lock.json | 34 +++++++++++++--------------------- package.json | 2 +- src/createDiceRoller.ts | 2 ++ src/index.ts | 2 ++ 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 760ae83..fdb6111 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3361,9 +3361,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "mixin-deep": { @@ -3388,20 +3388,12 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } + "minimist": "^1.2.5" } }, "moo": { @@ -4619,9 +4611,9 @@ } }, "typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", "dev": true }, "union-value": { @@ -4875,9 +4867,9 @@ } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index d55ddb3..b521b9a 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@types/moo": "^0.5.1", "jest": "^24.9.0", "ts-jest": "^24.3.0", - "typescript": "^3.7.5" + "typescript": "^4.2.4" }, "dependencies": { "moo": "^0.5.1" diff --git a/src/createDiceRoller.ts b/src/createDiceRoller.ts index f7439a5..b404078 100644 --- a/src/createDiceRoller.ts +++ b/src/createDiceRoller.ts @@ -27,4 +27,6 @@ function createDiceRoller(plugins: Plugins = defaultPlugins, random = defaultRan }; } +export type DiceRoller = ReturnType + export default createDiceRoller; diff --git a/src/index.ts b/src/index.ts index 38a66d6..7a0c4d1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,8 @@ import createDiceRoller from './createDiceRoller'; export { default as createDiceRoller } from './createDiceRoller'; export { default as withPlugins } from './withPlugins'; export { default as random } from './util/random'; + +export type { DiceRoller } from './createDiceRoller'; export type { Random } from "./util/random"; export type { Plugins, DiceRule, Rolls, RollResults } from "./rules/types"; export type { SimpleDiceRollToken } from "./rules/simpleDieRoll"; From 68a01aeab19c10e1ad48807a4f9e4ad5c336607c Mon Sep 17 00:00:00 2001 From: n1ru4l Date: Wed, 21 Apr 2021 10:34:02 +0200 Subject: [PATCH 6/6] refactor: use || instead of ?? --- src/withPlugins.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/withPlugins.ts b/src/withPlugins.ts index 024e045..1b9ad96 100644 --- a/src/withPlugins.ts +++ b/src/withPlugins.ts @@ -9,7 +9,7 @@ function withPlugins(...args: any[]): ReturnType { let random = defaultRandom if (Array.isArray(args[0])) { plugins = args[0] - random = args[1] ?? defaultRandom + random = args[1] || defaultRandom } else { plugins = args }