Make tests and implementation interact.
This commit is contained in:
parent
7089178a0d
commit
e0b65ca061
7 changed files with 163 additions and 34 deletions
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
|
@ -2,6 +2,7 @@
|
|||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"gruntfuggly.todo-tree"
|
||||
"gruntfuggly.todo-tree",
|
||||
"eg2.vscode-npm-script"
|
||||
]
|
||||
}
|
||||
|
|
84
package-lock.json
generated
84
package-lock.json
generated
|
@ -110,6 +110,12 @@
|
|||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@types/jasmine": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.2.tgz",
|
||||
"integrity": "sha512-AzfesNFLvOs6Q1mHzIsVJXSeUnqVh4ZHG8ngygKJfbkcSLwzrBVm/LKa+mR8KrOfnWtUL47112gde1MC0IXqpQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/jquery": {
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz",
|
||||
|
@ -610,6 +616,12 @@
|
|||
"readable-stream": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
|
@ -1571,6 +1583,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
|
||||
|
@ -1733,6 +1751,12 @@
|
|||
"integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true
|
||||
},
|
||||
"dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
|
@ -3748,6 +3772,22 @@
|
|||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
},
|
||||
"jasmine": {
|
||||
"version": "3.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.6.3.tgz",
|
||||
"integrity": "sha512-Th91zHsbsALWjDUIiU5d/W5zaYQsZFMPTdeNmi8GivZPmAaUAK8MblSG3yQI4VMGC/abF2us7ex60NH1AAIMTA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.6",
|
||||
"jasmine-core": "~3.6.0"
|
||||
}
|
||||
},
|
||||
"jasmine-core": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.6.0.tgz",
|
||||
"integrity": "sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw==",
|
||||
"dev": true
|
||||
},
|
||||
"js-base64": {
|
||||
"version": "2.6.4",
|
||||
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
|
||||
|
@ -4326,6 +4366,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"make-iterator": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
|
||||
|
@ -5993,6 +6039,24 @@
|
|||
"urix": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.19",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
|
||||
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"source-map-url": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
|
||||
|
@ -6514,6 +6578,20 @@
|
|||
"glob": "^7.1.2"
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
|
||||
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"source-map-support": "^0.5.17",
|
||||
"yn": "3.1.1"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
|
@ -7102,6 +7180,12 @@
|
|||
"object.assign": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"zip-stream": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.0.4.tgz",
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
"clean": "gulp clean && gulp link --clean",
|
||||
"update": "npm install --save-dev git+https://git.f3l.de/dungeonslayers/foundry-pc-types.git#f3l-fixes",
|
||||
"lint": "eslint 'src/**/*.ts' --cache",
|
||||
"lint:fix": "eslint 'src/**/*.ts' --cache --fix"
|
||||
"lint:fix": "eslint 'src/**/*.ts' --cache --fix",
|
||||
"test": "ts-node ./node_modules/jasmine/bin/jasmine"
|
||||
},
|
||||
"author": "",
|
||||
"license": "",
|
||||
"devDependencies": {
|
||||
"@types/jasmine": "^3.6.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.11.0",
|
||||
"@typescript-eslint/parser": "^4.11.0",
|
||||
"archiver": "^5.1.0",
|
||||
|
@ -31,10 +33,12 @@
|
|||
"gulp-sass": "^4.1.0",
|
||||
"gulp-typescript": "^6.0.0-alpha.1",
|
||||
"husky": "^4.3.6",
|
||||
"jasmine": "^3.6.3",
|
||||
"json-stringify-pretty-compact": "^2.0.0",
|
||||
"lint-staged": "^10.5.3",
|
||||
"prettier": "^2.2.1",
|
||||
"sass": "^1.30.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.1.3",
|
||||
"yargs": "^16.2.0"
|
||||
},
|
||||
|
|
19
spec/support/ds4rolls.spec.ts
Normal file
19
spec/support/ds4rolls.spec.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import {
|
||||
rollCheckSingleDie,
|
||||
RollOptions,
|
||||
RollProvider,
|
||||
RollResult,
|
||||
RollResultStatus,
|
||||
} from "../../src/module/rolls/ds4rolls";
|
||||
|
||||
describe("DS4 Rolls", () => {
|
||||
it("Should do a proper single success role", () => {
|
||||
const rollProvider: RollProvider = jasmine.createSpyObj("rollProvider", ["getNextRoll"]);
|
||||
|
||||
rollProvider.getNextRoll = jasmine.createSpy("getNextRoll").and.returnValue(4);
|
||||
|
||||
expect(rollCheckSingleDie(12, new RollOptions(), rollProvider)).toEqual(
|
||||
new RollResult(4, RollResultStatus.SUCCESS, [4]),
|
||||
);
|
||||
});
|
||||
});
|
7
spec/support/jasmine.json
Normal file
7
spec/support/jasmine.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"spec_dir": "spec",
|
||||
"spec_files": ["**/*[sS]pec.ts"],
|
||||
"helpers": ["helpers/**/*.ts"],
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": true
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
export function roll(testValue: number, rollOptions: RollOptions = new RollOptions()): Promise<RollResult> {
|
||||
export function ds4test(testValue: number, rollOptions: RollOptions = new RollOptions()): RollResult {
|
||||
const finalRollValue = testValue;
|
||||
if (finalRollValue <= 20) {
|
||||
return rollCheckSingleDie(finalRollValue, rollOptions);
|
||||
|
@ -7,26 +7,45 @@ export function roll(testValue: number, rollOptions: RollOptions = new RollOptio
|
|||
}
|
||||
}
|
||||
|
||||
async function rollCheckSingleDie(testValue: number, rollOptions: RollOptions): Promise<RollResult> {
|
||||
const roll = new Roll("1d20");
|
||||
roll.roll();
|
||||
export class DS4RollProvider {
|
||||
getNextRoll(): number {
|
||||
return new Roll("1d20").roll().total;
|
||||
}
|
||||
|
||||
const pool = new DicePool({ rolls: [roll] });
|
||||
getNextRolls(amount: number): Array<number> {
|
||||
return Array(amount)
|
||||
.fill(0)
|
||||
.map(() => this.getNextRoll());
|
||||
}
|
||||
}
|
||||
|
||||
if (roll.total <= rollOptions.maxCritSucc) {
|
||||
return createRollResultPromise(testValue, RollResultStatus.CRITICAL_SUCCESS, pool);
|
||||
} else if (roll.total >= rollOptions.minCritFail) {
|
||||
return createRollResultPromise(0, RollResultStatus.CRITICAL_FAILURE, pool);
|
||||
export interface RollProvider {
|
||||
getNextRoll(): number;
|
||||
getNextRolls(number): Array<number>;
|
||||
}
|
||||
|
||||
export function rollCheckSingleDie(
|
||||
testValue: number,
|
||||
rollOptions: RollOptions,
|
||||
provider: RollProvider = new DS4RollProvider(),
|
||||
): RollResult {
|
||||
const roll = provider.getNextRoll();
|
||||
const dice = [roll];
|
||||
|
||||
if (roll <= rollOptions.maxCritSucc) {
|
||||
return createRollResult(testValue, RollResultStatus.CRITICAL_SUCCESS, dice);
|
||||
} else if (roll >= rollOptions.minCritFail) {
|
||||
return createRollResult(0, RollResultStatus.CRITICAL_FAILURE, dice);
|
||||
} else {
|
||||
if (roll.total <= testValue) {
|
||||
return createRollResultPromise(roll.total, RollResultStatus.SUCCESS, pool);
|
||||
if (roll <= testValue) {
|
||||
return createRollResult(roll, RollResultStatus.SUCCESS, dice);
|
||||
} else {
|
||||
return createRollResultPromise(0, RollResultStatus.FAILURE, pool);
|
||||
return createRollResult(0, RollResultStatus.FAILURE, dice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function rollCheckMultipleDice(testValue: number, rollOptions: RollOptions): Promise<RollResult> {
|
||||
function rollCheckMultipleDice(testValue: number, rollOptions: RollOptions): RollResult {
|
||||
const finalCheck = testValue % 20;
|
||||
const numberOfDice = Math.ceil(testValue / 20);
|
||||
const rolls = new Array<Roll>();
|
||||
|
@ -35,23 +54,22 @@ async function rollCheckMultipleDice(testValue: number, rollOptions: RollOptions
|
|||
roll.roll();
|
||||
rolls.concat(roll);
|
||||
}
|
||||
const pool = new DicePool({ rolls: rolls });
|
||||
const dice = rolls.map((r) => r.total);
|
||||
|
||||
const firstResult = rolls[1].total;
|
||||
const firstResult = dice[1];
|
||||
|
||||
// TODO: Special stuff (Gnomes!)
|
||||
if (firstResult == 20) {
|
||||
createRollResultPromise(0, RollResultStatus.CRITICAL_FAILURE, pool);
|
||||
createRollResult(0, RollResultStatus.CRITICAL_FAILURE, dice);
|
||||
}
|
||||
|
||||
const [otherRolls, critSuccesses] = pool.rolls
|
||||
.partition((r) => r.total <= rollOptions.maxCritSucc)
|
||||
.map((a) => a.sort((r1, r2) => r2.total - r1.total));
|
||||
const [otherRolls, critSuccesses] = dice
|
||||
.partition((r) => r <= rollOptions.maxCritSucc)
|
||||
.map((a) => a.sort((r1, r2) => r2 - r1));
|
||||
|
||||
const sortedRolls: DicePool = new DicePool({ rolls: critSuccesses.concat(otherRolls) });
|
||||
const sortedRollResults: Array<number> = critSuccesses.concat(otherRolls);
|
||||
|
||||
const evaluationResult = sortedRolls.rolls
|
||||
.map((r) => r.total)
|
||||
const evaluationResult = sortedRollResults
|
||||
.map((value, index) => {
|
||||
if (index == numberOfDice - 1) {
|
||||
if (value == 1) {
|
||||
|
@ -69,15 +87,11 @@ async function rollCheckMultipleDice(testValue: number, rollOptions: RollOptions
|
|||
})
|
||||
.reduce((a, b) => a + b);
|
||||
|
||||
return createRollResultPromise(evaluationResult, RollResultStatus.SUCCESS, sortedRolls);
|
||||
return createRollResult(evaluationResult, RollResultStatus.SUCCESS, sortedRollResults);
|
||||
}
|
||||
|
||||
function createRollResultPromise(
|
||||
totalValue: number,
|
||||
rollResult: RollResultStatus,
|
||||
dicePool: DicePool,
|
||||
): Promise<RollResult> {
|
||||
return new Promise((resolve) => resolve(new RollResult(totalValue, RollResultStatus.SUCCESS, dicePool)));
|
||||
function createRollResult(totalValue: number, rollResult: RollResultStatus, dice: Array<number>): RollResult {
|
||||
return new RollResult(totalValue, RollResultStatus.SUCCESS, dice);
|
||||
}
|
||||
|
||||
export class RollOptions {
|
||||
|
@ -85,10 +99,10 @@ export class RollOptions {
|
|||
}
|
||||
|
||||
export class RollResult {
|
||||
constructor(public value: number, public status: RollResultStatus, public dice: DicePool) {}
|
||||
constructor(public value: number, public status: RollResultStatus, public dice: Array<number>) {}
|
||||
}
|
||||
|
||||
enum RollResultStatus {
|
||||
export enum RollResultStatus {
|
||||
FAILURE,
|
||||
SUCCESS,
|
||||
CRITICAL_FAILURE,
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["DOM", "ES6", "ES2017"],
|
||||
"types": ["foundry-pc-types"]
|
||||
"types": ["foundry-pc-types", "jasmine"]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue