|
|
/packages/algorithms/random/src/index.ts
|
0 problems
|
|
|
/packages/algorithms/random/src/random.ts
|
0 problems
|
|
|
/packages/algorithms/random/tests/random.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/algorithms/random/tests/random.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { random } from "@algorithms-random/index"; |
| 2 |
|
| 3 |
describe("random", () => { |
| 4 |
it.each([ |
| 5 |
[1, 10], |
| 6 |
[5, 7], |
| 7 |
[1, 100], |
| 8 |
])("should return a number between %i and %i", (min: number, max: number): void => { |
| 9 |
const result = random(min, max); |
| 10 |
|
| 11 |
expect(result).toBeGreaterThanOrEqual(min); |
| 12 |
expect(result).toBeLessThanOrEqual(max); |
| 13 |
}); |
| 14 |
}); |
| 15 |
|
|
|
|
/packages/algorithms/shuffle/src/index.ts
|
0 problems
|
|
|
/packages/algorithms/shuffle/src/shuffle.ts
|
0 problems
|
|
|
/packages/algorithms/shuffle/tests/shuffle.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/algorithms/shuffle/tests/shuffle.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { shuffle } from "@algorithms-shuffle/index"; |
| 2 |
|
| 3 |
describe("shuffle", () => { |
| 4 |
it("should shuffle an array", (): void => { |
| 5 |
const source = [1, 2, 3]; |
| 6 |
const origin = Object.assign({}, source); |
| 7 |
const result = shuffle<number>(source); |
| 8 |
|
| 9 |
expect(result).not.toEqual(origin); |
| 10 |
}); |
| 11 |
|
| 12 |
it("should return an array", (): void => { |
| 13 |
const source = [1, 2, 3]; |
| 14 |
|
| 15 |
const result = shuffle<number>(source); |
| 16 |
|
| 17 |
expect(Array.isArray(result)).toBeTruthy(); |
| 18 |
}); |
| 19 |
}); |
| 20 |
|
|
|
|
/packages/algorithms/sort/src/bubble.ts
|
0 problems
|
|
|
/packages/algorithms/sort/src/index.ts
|
0 problems
|
|
|
/packages/algorithms/sort/src/insertion.ts
|
0 problems
|
|
|
/packages/algorithms/sort/src/merge.ts
|
0 problems
|
|
|
/packages/algorithms/sort/src/quick.ts
|
0 problems
|
|
|
/packages/algorithms/sort/tests/bubble.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/algorithms/sort/tests/bubble.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { sortBubble } from "@algorithms-sort/index"; |
| 2 |
|
| 3 |
describe("sort bubble", () => { |
| 4 |
it("should sort an array", (): void => { |
| 5 |
const source = [9, 8, 7, 6, 5, 4, 3, 1, 2]; |
| 6 |
const expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]; |
| 7 |
const result = sortBubble<number>(source); |
| 8 |
|
| 9 |
expect(result).toEqual(expected); |
| 10 |
}); |
| 11 |
}); |
| 12 |
|
|
|
|
/packages/algorithms/sort/tests/insertion.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/algorithms/sort/tests/insertion.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { sortInsertion } from "@algorithms-sort/index"; |
| 2 |
|
| 3 |
describe("sort insertion", () => { |
| 4 |
it("should sort an array", (): void => { |
| 5 |
const source = [9, 8, 7, 6, 5, 4, 3, 1, 2]; |
| 6 |
const expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]; |
| 7 |
const result = sortInsertion<number>(source); |
| 8 |
|
| 9 |
expect(result).toEqual(expected); |
| 10 |
}); |
| 11 |
}); |
| 12 |
|
|
|
|
/packages/algorithms/sort/tests/merge.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/algorithms/sort/tests/merge.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { sortMerge } from "@algorithms-sort/index"; |
| 2 |
|
| 3 |
describe("sort merge", () => { |
| 4 |
it("should sort an array", (): void => { |
| 5 |
const source = [9, 8, 7, 6, 5, 4, 3, 1, 2]; |
| 6 |
const expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]; |
| 7 |
const result = sortMerge<number>(source); |
| 8 |
|
| 9 |
expect(result).toEqual(expected); |
| 10 |
}); |
| 11 |
}); |
| 12 |
|
|
|
|
/packages/algorithms/sort/tests/quick.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/algorithms/sort/tests/quick.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { sortQuick } from "@algorithms-sort/index"; |
| 2 |
|
| 3 |
describe("sort quick", () => { |
| 4 |
it("should sort an array", (): void => { |
| 5 |
const source = [9, 8, 7, 6, 5, 4, 3, 1, 2]; |
| 6 |
const expected = [1, 2, 3, 4, 5, 6, 7, 8, 9]; |
| 7 |
const result = sortQuick<number>(source); |
| 8 |
|
| 9 |
expect(result).toEqual(expected); |
| 10 |
}); |
| 11 |
}); |
| 12 |
|
|
|
|
/packages/array/isempty/src/index.ts
|
0 problems
|
|
|
/packages/array/isempty/src/isempty.ts
|
0 problems
|
|
|
/packages/array/isempty/tests/isempty.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/array/isempty/tests/isempty.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { isEmpty } from "@array-isempty/index"; |
| 2 |
|
| 3 |
describe("isEmpty", () => { |
| 4 |
it("should return true if array is empty", (): void => { |
| 5 |
const arr = []; |
| 6 |
|
| 7 |
expect(isEmpty(arr)).toBe(true); |
| 8 |
}); |
| 9 |
|
| 10 |
it("should return false if array is not empty", (): void => { |
| 11 |
const arr = [1, 2, 3]; |
| 12 |
|
| 13 |
expect(isEmpty(arr)).toBe(false); |
| 14 |
}); |
| 15 |
}); |
| 16 |
|
|
|
|
/packages/array/unique/src/index.ts
|
0 problems
|
|
|
/packages/array/unique/src/unique.ts
|
0 problems
|
|
|
/packages/array/unique/tests/unique.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/array/unique/tests/unique.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { unique } from "@array-unique/index"; |
| 2 |
|
| 3 |
describe("unique", () => { |
| 4 |
it("should return unique items in array", (): void => { |
| 5 |
const origin = [1, 2, 3, 4, 1, 2, 5]; |
| 6 |
|
| 7 |
const expected = [1, 2, 3, 4, 5]; |
| 8 |
|
| 9 |
const result = unique(origin); |
| 10 |
|
| 11 |
expect(result).toStrictEqual(expected); |
| 12 |
}); |
| 13 |
}); |
| 14 |
|
|
|
|
/packages/converters/arraytocsv/src/array-to-csv.ts
|
0 problems
|
|
|
/packages/converters/arraytocsv/src/index.ts
|
0 problems
|
|
|
/packages/converters/arraytocsv/tests/array-to-csv.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/converters/arraytocsv/tests/array-to-csv.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { arrayToCsv } from "@converters-arraytocsv/index"; |
| 2 |
|
| 3 |
describe("arrayToCsv", () => { |
| 4 |
it.each([ |
| 5 |
['"a"', [["a"]], ","], |
| 6 |
[ |
| 7 |
'"a","b"\n"c","d"', |
| 8 |
[ |
| 9 |
["a", "b"], |
| 10 |
["c", "d"], |
| 11 |
], |
| 12 |
",", |
| 13 |
], |
| 14 |
[ |
| 15 |
'"a";"b"\n"c";"d"', |
| 16 |
[ |
| 17 |
["a", "b"], |
| 18 |
["c", "d"], |
| 19 |
], |
| 20 |
";", |
| 21 |
], |
| 22 |
[ |
| 23 |
'"a","""b"" great"\n"c",3.1415', |
| 24 |
[ |
| 25 |
["a", '"b" great'], |
| 26 |
["c", 3.1415], |
| 27 |
], |
| 28 |
",", |
| 29 |
], |
| 30 |
])( |
| 31 |
"should return %s csv for %o array and %s delimiter", |
| 32 |
// eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 33 |
(expected: string, arr: any[][], delimiter: string): void => { |
| 34 |
const result = arrayToCsv(arr, delimiter); |
| 35 |
|
| 36 |
expect(result).toBe(expected); |
| 37 |
}, |
| 38 |
); |
| 39 |
|
| 40 |
it("should have ',' as default delimiter", (): void => { |
| 41 |
const expected = '"a","b"'; |
| 42 |
const result = arrayToCsv([["a", "b"]]); |
| 43 |
|
| 44 |
expect(result).toBe(expected); |
| 45 |
}); |
| 46 |
}); |
| 47 |
|
|
|
|
/packages/converters/celsiustofahrenheit/src/celsius-to-fahrenheit.ts
|
0 problems
|
|
|
/packages/converters/celsiustofahrenheit/src/index.ts
|
0 problems
|
|
|
/packages/converters/celsiustofahrenheit/tests/celsiustofahrenheit.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/converters/celsiustofahrenheit/tests/celsiustofahrenheit.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { celsiusToFahrenheit } from "@converters-celsiustofahrenheit/index"; |
| 2 |
|
| 3 |
describe("celsiusToFahrenheit", () => { |
| 4 |
it.each([ |
| 5 |
[-459.67, -273.15], // absolute zero |
| 6 |
[-58, -50], |
| 7 |
[-40, -40], |
| 8 |
[-22, -30], |
| 9 |
[-4, -20], |
| 10 |
[14, -10], |
| 11 |
[32, 0], |
| 12 |
[33.8, 1], |
| 13 |
[69.8, 21], |
| 14 |
[77, 25], |
| 15 |
[86, 30], |
| 16 |
[91.4, 33], |
| 17 |
[98.6, 37], |
| 18 |
[104, 40], |
| 19 |
[212, 100], |
| 20 |
[356, 180], |
| 21 |
])("should return %s fahrenheit for %s celsius", (expected: number, source: number): void => { |
| 22 |
const result = celsiusToFahrenheit(source); |
| 23 |
|
| 24 |
expect(result).toBe(expected); |
| 25 |
}); |
| 26 |
}); |
| 27 |
|
|
|
|
/packages/converters/jsontocsv/src/index.ts
|
0 problems
|
|
|
/packages/converters/jsontocsv/src/json-to-csv.ts
|
0 problems
|
|
|
/packages/converters/jsontocsv/tests/json-to-csv.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/converters/jsontocsv/tests/json-to-csv.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { jsonToCsv } from "@converters-jsontocsv/index"; |
| 2 |
|
| 3 |
describe("JsonToCsv", () => { |
| 4 |
it.each([ |
| 5 |
[ |
| 6 |
'a,b\n"1","2"\n"3","4"\n"6",""\n"","7"', |
| 7 |
[{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }], |
| 8 |
["a", "b"], |
| 9 |
",", |
| 10 |
], |
| 11 |
[ |
| 12 |
'a;b\n"1";"2"\n"3";"4"\n"6";""\n"";"7"', |
| 13 |
[{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }], |
| 14 |
["a", "b"], |
| 15 |
";", |
| 16 |
], |
| 17 |
[ |
| 18 |
'a%b\n"1"%"2"\n"3"%"4"\n"6"%""\n""%"7"', |
| 19 |
[{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }], |
| 20 |
["a", "b"], |
| 21 |
"%", |
| 22 |
], |
| 23 |
])( |
| 24 |
"should return %s csv for %o json, %o colums and %s delimiter", |
| 25 |
// eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 26 |
(expected: string, arr: any[], colums: string[], delimiter: string): void => { |
| 27 |
const result = jsonToCsv(arr, colums, delimiter); |
| 28 |
|
| 29 |
expect(result).toBe(expected); |
| 30 |
}, |
| 31 |
); |
| 32 |
|
| 33 |
it("should have ',' as default delimiter", (): void => { |
| 34 |
const expected = 'a,b\n"1","2"\n"3","4"\n"6",""\n"","7"'; |
| 35 |
const result = jsonToCsv([{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }], ["a", "b"]); |
| 36 |
|
| 37 |
expect(result).toBe(expected); |
| 38 |
}); |
| 39 |
}); |
| 40 |
|
|
|
|
/packages/converters/mapfromobject/src/index.ts
|
0 problems
|
|
|
/packages/converters/mapfromobject/src/mapfromobject.ts
|
0 problems
|
|
|
/packages/converters/mapfromobject/tests/mapfromobject.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/converters/mapfromobject/tests/mapfromobject.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { MapFromObject } from "@converters-mapfromobject/index"; |
| 2 |
|
| 3 |
describe("mapFormObject", () => { |
| 4 |
it("should return object property", () => { |
| 5 |
interface Model { |
| 6 |
firstname: string; |
| 7 |
lastname: string; |
| 8 |
} |
| 9 |
|
| 10 |
const model: Model = { |
| 11 |
firstname: "John", |
| 12 |
lastname: "Doe", |
| 13 |
}; |
| 14 |
|
| 15 |
const modelMap: MapFromObject<Model, keyof Model> = new Map(Object.entries(model)); |
| 16 |
|
| 17 |
expect(modelMap.get("firstname")).toBe(model.firstname); |
| 18 |
expect(modelMap.get("lastname")).toBe(model.lastname); |
| 19 |
}); |
| 20 |
}); |
| 21 |
|
|
|
|
/packages/data/queue/src/index.ts
|
0 problems
|
|
|
/packages/data/queue/tests/queue.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/data/queue/tests/queue.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Queue } from "@data-queue/index"; |
| 2 |
|
| 3 |
describe("Queue", () => { |
| 4 |
describe("push", () => { |
| 5 |
it("should add item in queue store", (): void => { |
| 6 |
const queue = new Queue<string>(); |
| 7 |
|
| 8 |
expect(queue.size()).toBe(0); |
| 9 |
|
| 10 |
queue.push("Some awesome item"); |
| 11 |
|
| 12 |
expect(queue.size()).toBe(1); |
| 13 |
}); |
| 14 |
|
| 15 |
it("should return items number", (): void => { |
| 16 |
const queue = new Queue<string>(); |
| 17 |
|
| 18 |
expect(queue.size()).toBe(0); |
| 19 |
|
| 20 |
const result = queue.push("a new item"); |
| 21 |
|
| 22 |
expect(result).toBe(1); |
| 23 |
}); |
| 24 |
}); |
| 25 |
|
| 26 |
describe("pop", () => { |
| 27 |
it("should remove first inserted item from queue store", (): void => { |
| 28 |
const queue = new Queue<string>(); |
| 29 |
|
| 30 |
expect(queue.size()).toBe(0); |
| 31 |
|
| 32 |
queue.push("My first item"); |
| 33 |
queue.push("My second item"); |
| 34 |
|
| 35 |
expect(queue.size()).toBe(2); |
| 36 |
|
| 37 |
const result = queue.pop(); |
| 38 |
|
| 39 |
expect(queue.size()).toBe(1); |
| 40 |
expect(result).toBe("My first item"); |
| 41 |
}); |
| 42 |
}); |
| 43 |
}); |
| 44 |
|
|
|
|
/packages/data/stack/src/index.ts
|
0 problems
|
|
|
/packages/data/stack/tests/stack.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/data/stack/tests/stack.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Stack } from "@data-stack/index"; |
| 2 |
|
| 3 |
describe("Stack", () => { |
| 4 |
describe("push", () => { |
| 5 |
it("should add item in stack store", (): void => { |
| 6 |
const stack = new Stack<string>(); |
| 7 |
|
| 8 |
expect(stack.size()).toBe(0); |
| 9 |
|
| 10 |
stack.push("Some awesome item"); |
| 11 |
|
| 12 |
expect(stack.size()).toBe(1); |
| 13 |
}); |
| 14 |
|
| 15 |
it("should return items number", (): void => { |
| 16 |
const stack = new Stack<string>(); |
| 17 |
|
| 18 |
expect(stack.size()).toBe(0); |
| 19 |
|
| 20 |
const result = stack.push("Some awesome item"); |
| 21 |
|
| 22 |
expect(result).toBe(1); |
| 23 |
}); |
| 24 |
}); |
| 25 |
|
| 26 |
describe("pop", () => { |
| 27 |
it("should remove last inserted item from stack store", (): void => { |
| 28 |
const stack = new Stack<string>(); |
| 29 |
|
| 30 |
expect(stack.size()).toBe(0); |
| 31 |
|
| 32 |
stack.push("My first item"); |
| 33 |
stack.push("My second item"); |
| 34 |
|
| 35 |
expect(stack.size()).toBe(2); |
| 36 |
|
| 37 |
const result = stack.pop(); |
| 38 |
|
| 39 |
expect(stack.size()).toBe(1); |
| 40 |
expect(result).toBe("My second item"); |
| 41 |
}); |
| 42 |
}); |
| 43 |
|
| 44 |
describe("peek", () => { |
| 45 |
it("should return null if stack is empty", (): void => { |
| 46 |
const stack = new Stack<string>(); |
| 47 |
|
| 48 |
expect(stack.peek()).toBeNull(); |
| 49 |
}); |
| 50 |
|
| 51 |
it("should return last inserted element", (): void => { |
| 52 |
const stack = new Stack<string>(); |
| 53 |
const firstElement = "first"; |
| 54 |
const secondElement = "second"; |
| 55 |
|
| 56 |
stack.push(firstElement); |
| 57 |
stack.push(secondElement); |
| 58 |
|
| 59 |
expect(stack.peek()).toBe(secondElement); |
| 60 |
}); |
| 61 |
|
| 62 |
it("should not remove element from stack", (): void => { |
| 63 |
const stack = new Stack<string>(); |
| 64 |
const firstElement = "first"; |
| 65 |
const secondElement = "second"; |
| 66 |
|
| 67 |
stack.push(firstElement); |
| 68 |
stack.push(secondElement); |
| 69 |
|
| 70 |
expect(stack.size()).toBe(2); |
| 71 |
|
| 72 |
expect(stack.peek()).toBe(secondElement); |
| 73 |
|
| 74 |
expect(stack.size()).toBe(2); |
| 75 |
}); |
| 76 |
}); |
| 77 |
}); |
| 78 |
|
|
|
|
/packages/dates/currenttime/src/current-time.ts
|
0 problems
|
|
|
/packages/dates/currenttime/src/index.ts
|
0 problems
|
|
|
/packages/dates/currenttime/tests/currenttime.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/dates/currenttime/tests/currenttime.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { currentTime } from "@dates-currenttime/index"; |
| 2 |
|
| 3 |
describe("currentTime", () => { |
| 4 |
it("should return current time if not date argument is passed", (): void => { |
| 5 |
const eventDate = new Date("2004-10-24T10:35:15"); |
| 6 |
|
| 7 |
// mockup date |
| 8 |
jest.spyOn(global.Date, "now").mockImplementationOnce(() => eventDate.valueOf()); |
| 9 |
|
| 10 |
const expected = "2004-10-24 10:35:15"; |
| 11 |
const result = currentTime(); |
| 12 |
|
| 13 |
jest.fn().mockClear(); |
| 14 |
|
| 15 |
expect(result).toBe(expected); |
| 16 |
}); |
| 17 |
|
| 18 |
it("should return time of date argument", (): void => { |
| 19 |
const expected = "2021-01-26 12:24:57"; |
| 20 |
const date: Date = new Date(2021, 0, 26, 12, 24, 57); |
| 21 |
|
| 22 |
const result = currentTime(date); |
| 23 |
|
| 24 |
expect(result).toBe(expected); |
| 25 |
}); |
| 26 |
}); |
| 27 |
|
|
|
|
/packages/games/colors/src/random.ts
|
0 problems
|
|
|
/packages/games/colors/tests/color.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/colors/tests/color.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Color } from "@games-colors/index"; |
| 2 |
|
| 3 |
describe("Color", () => { |
| 4 |
it("should be instantiable", () => { |
| 5 |
const model = new Color(1, 2, 3); |
| 6 |
expect(model).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
describe("constructor", (): void => { |
| 10 |
it("constructor should init properties", () => { |
| 11 |
const expected = { |
| 12 |
blue: 1, |
| 13 |
green: 1, |
| 14 |
red: 1, |
| 15 |
}; |
| 16 |
|
| 17 |
const model = new Color(expected.red, expected.green, expected.blue); |
| 18 |
|
| 19 |
expect(model.red).toBe(expected.red); |
| 20 |
expect(model.green).toBe(expected.green); |
| 21 |
expect(model.blue).toBe(expected.blue); |
| 22 |
}); |
| 23 |
}); |
| 24 |
|
| 25 |
it("should convert to RGB", () => { |
| 26 |
const expected = "rgb(1,2,3)"; |
| 27 |
|
| 28 |
const model = new Color(1, 2, 3); |
| 29 |
|
| 30 |
const result = model.toRGB(); |
| 31 |
|
| 32 |
expect(result).toBe(expected); |
| 33 |
}); |
| 34 |
}); |
| 35 |
|
|
|
|
/packages/games/colors/tests/hsbToRgb.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/colors/tests/hsbToRgb.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { hsbToRgb } from "@games-colors/index"; |
| 2 |
|
| 3 |
describe("hsbToRgb", () => { |
| 4 |
it("should return a rgb value", () => { |
| 5 |
const origin = { |
| 6 |
h: 18, |
| 7 |
s: 81, |
| 8 |
b: 99, |
| 9 |
}; |
| 10 |
const result = hsbToRgb(origin.h, origin.s, origin.b); |
| 11 |
|
| 12 |
const expected = [252.45, 109.31084999999996, 47.965499999999984]; |
| 13 |
|
| 14 |
expect(result).toStrictEqual(expected); |
| 15 |
}); |
| 16 |
}); |
| 17 |
|
|
|
|
/packages/games/colors/tests/random.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/colors/tests/random.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { randomColor } from "@games-colors/index"; |
| 2 |
|
| 3 |
describe("random", () => { |
| 4 |
it("should return a 6 string value", () => { |
| 5 |
const value = randomColor(); |
| 6 |
|
| 7 |
expect(value).toHaveLength(6); |
| 8 |
expect(typeof value).toBe("string"); |
| 9 |
}); |
| 10 |
|
| 11 |
it("should return random values", () => { |
| 12 |
const color1 = randomColor(); |
| 13 |
const color2 = randomColor(); |
| 14 |
|
| 15 |
expect(color1).not.toBe(color2); |
| 16 |
}); |
| 17 |
}); |
| 18 |
|
|
|
|
/packages/games/commands/src/index.ts
|
0 problems
|
|
|
/packages/games/commands/src/keys.ts
|
0 problems
|
|
|
/packages/games/commands/tests/keys.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/commands/tests/keys.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Keys } from "@games-commands/index"; |
| 2 |
|
| 3 |
describe("Keys", () => { |
| 4 |
it("should return correct values", () => { |
| 5 |
expect(Keys.DOWN).toEqual("ArrowDown"); |
| 6 |
expect(Keys.LEFT).toEqual("ArrowLeft"); |
| 7 |
expect(Keys.RIGHT).toEqual("ArrowRight"); |
| 8 |
expect(Keys.UP).toEqual("ArrowUp"); |
| 9 |
expect(Keys.ESCAPE).toEqual("Escape"); |
| 10 |
expect(Keys.RETURN).toEqual("Enter"); |
| 11 |
expect(Keys.ROLL).toEqual("KeyR"); |
| 12 |
}); |
| 13 |
}); |
| 14 |
|
|
|
|
/packages/games/console/src/console.ts
|
0 problems
|
|
|
/packages/games/console/src/index.ts
|
0 problems
|
|
|
/packages/games/console/src/interface.ts
|
0 problems
|
|
|
/packages/games/console/src/renderer.ts
|
0 problems
|
|
|
/packages/games/console/tests/console.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/console/tests/console.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { instance, mock, reset, verify } from "ts-mockito"; |
| 2 |
|
| 3 |
import { Console, ConsoleRendererInterface } from "@games-console/index"; |
| 4 |
|
| 5 |
describe("Console", () => { |
| 6 |
const mockRenderer: ConsoleRendererInterface = mock<ConsoleRendererInterface>(); |
| 7 |
|
| 8 |
let rendererMock: ConsoleRendererInterface; |
| 9 |
|
| 10 |
beforeEach(() => { |
| 11 |
rendererMock = instance(mockRenderer); |
| 12 |
}); |
| 13 |
|
| 14 |
afterAll(() => { |
| 15 |
reset(mockRenderer); |
| 16 |
}); |
| 17 |
|
| 18 |
it("should be instantiable", () => { |
| 19 |
expect(new Console(rendererMock)).not.toBeNull(); |
| 20 |
}); |
| 21 |
|
| 22 |
it("should be able to create container", () => { |
| 23 |
const model = new Console(rendererMock); |
| 24 |
const expected = document.createElement("div"); |
| 25 |
expected.classList.add("console"); |
| 26 |
|
| 27 |
expect(model.getContainer()).toStrictEqual(expected); |
| 28 |
}); |
| 29 |
|
| 30 |
describe("append", () => { |
| 31 |
// eslint-disable-next-line jest/expect-expect |
| 32 |
it("should append message to console", () => { |
| 33 |
const renderer = rendererMock; |
| 34 |
const model = new Console(renderer); |
| 35 |
const expected = "some message"; |
| 36 |
|
| 37 |
model.append(expected); |
| 38 |
|
| 39 |
verify(mockRenderer.write(expected)).once(); |
| 40 |
}); |
| 41 |
}); |
| 42 |
}); |
| 43 |
|
|
|
|
/packages/games/console/tests/renderer.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/console/tests/renderer.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import * as dates from "jga-dates-currenttime/dist/current-time.js"; |
| 2 |
|
| 3 |
import { HTMLConsoleRenderer } from "@games-console/index"; |
| 4 |
|
| 5 |
const eventMessage = "Some awesome message"; |
| 6 |
const whenMessage = "1983-01-14 09:35:05"; |
| 7 |
|
| 8 |
describe("HTMLConsoleRenderer", () => { |
| 9 |
beforeEach(() => { |
| 10 |
const currentTimeMock = jest.spyOn(dates, "currentTime"); |
| 11 |
currentTimeMock.mockReturnValue(whenMessage); |
| 12 |
}); |
| 13 |
|
| 14 |
afterAll(() => { |
| 15 |
jest.fn().mockClear(); |
| 16 |
}); |
| 17 |
|
| 18 |
it("should be instantiable", () => { |
| 19 |
const renderer = new HTMLConsoleRenderer(); |
| 20 |
expect(renderer).not.toBeNull(); |
| 21 |
}); |
| 22 |
|
| 23 |
describe("write", () => { |
| 24 |
it("should be able to write a message", () => { |
| 25 |
// Setup document body |
| 26 |
// eslint-disable-next-line xss/no-mixed-html |
| 27 |
document.body.innerHTML = "<div class='console'/>"; |
| 28 |
|
| 29 |
const expected = document.createElement("p"); |
| 30 |
const when = document.createElement("span"); |
| 31 |
when.textContent = whenMessage; |
| 32 |
const what = document.createElement("span"); |
| 33 |
what.textContent = ` - ${eventMessage}`; |
| 34 |
|
| 35 |
expected.appendChild(when); |
| 36 |
expected.appendChild(what); |
| 37 |
|
| 38 |
const renderer = new HTMLConsoleRenderer(); |
| 39 |
renderer.write(eventMessage); |
| 40 |
|
| 41 |
expect(document.getElementsByClassName("console")[0].firstChild).toStrictEqual(expected); |
| 42 |
}); |
| 43 |
|
| 44 |
it("should append message on top if there is allready one", () => { |
| 45 |
// Setup document body |
| 46 |
// eslint-disable-next-line xss/no-mixed-html, no-unsanitized/property |
| 47 |
document.body.innerHTML = `<div class='console'><p><span>${whenMessage} - Previous message</span></p></div>`; |
| 48 |
|
| 49 |
const expected = document.createElement("div"); |
| 50 |
expected.classList.add("console"); |
| 51 |
|
| 52 |
const newMessage = document.createElement("p"); |
| 53 |
const when = document.createElement("span"); |
| 54 |
when.textContent = whenMessage; |
| 55 |
const what = document.createElement("span"); |
| 56 |
what.textContent = ` - ${eventMessage}`; |
| 57 |
|
| 58 |
newMessage.appendChild(when); |
| 59 |
newMessage.appendChild(what); |
| 60 |
|
| 61 |
expected.append(newMessage); |
| 62 |
|
| 63 |
const previousMessage = document.createElement("p"); |
| 64 |
// eslint-disable-next-line xss/no-mixed-html, no-unsanitized/property |
| 65 |
previousMessage.innerHTML = `<span>${whenMessage} - Previous message</span>`; |
| 66 |
|
| 67 |
expected.append(previousMessage); |
| 68 |
|
| 69 |
const renderer = new HTMLConsoleRenderer(); |
| 70 |
renderer.write(eventMessage); |
| 71 |
|
| 72 |
expect(document.getElementsByClassName("console")[0]).toStrictEqual(expected); |
| 73 |
}); |
| 74 |
|
| 75 |
it("should do nothing if there is no console in dom", () => { |
| 76 |
document.body.innerHTML = ""; |
| 77 |
|
| 78 |
const expected = document.createElement("p"); |
| 79 |
const when = document.createElement("span"); |
| 80 |
when.textContent = whenMessage; |
| 81 |
const what = document.createElement("span"); |
| 82 |
what.textContent = ` - ${eventMessage}`; |
| 83 |
|
| 84 |
expected.appendChild(when); |
| 85 |
expected.appendChild(what); |
| 86 |
|
| 87 |
const renderer = new HTMLConsoleRenderer(); |
| 88 |
renderer.write(eventMessage); |
| 89 |
|
| 90 |
expect(document.getElementsByClassName("console")[0]).toBeUndefined(); |
| 91 |
}); |
| 92 |
}); |
| 93 |
}); |
| 94 |
|
|
|
|
/packages/games/dices/src/dice6.ts
|
0 problems
|
|
|
/packages/games/dices/src/diceBase.ts
|
0 problems
|
|
|
/packages/games/dices/src/diceInterface.ts
|
0 problems
|
|
|
/packages/games/dices/src/index.ts
|
0 problems
|
|
|
/packages/games/dices/tests/dice.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/dices/tests/dice.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { DiceAsymmetricMethod, DiceBase } from "@dices/index"; |
| 2 |
|
| 3 |
class ConcreteDice extends DiceBase { |
| 4 |
public constructor(sides: number) { |
| 5 |
super(sides); |
| 6 |
} |
| 7 |
} |
| 8 |
|
| 9 |
describe("Dice", () => { |
| 10 |
it("should be instantiable", () => { |
| 11 |
const dice = new ConcreteDice(6); |
| 12 |
expect(dice).not.toBeNull(); |
| 13 |
}); |
| 14 |
|
| 15 |
it("should return sides number", () => { |
| 16 |
const sides = 10; |
| 17 |
const dice = new ConcreteDice(sides); |
| 18 |
expect(dice.sides).toBe(sides); |
| 19 |
}); |
| 20 |
|
| 21 |
describe("roll", (): void => { |
| 22 |
const rolls = [{ sides: 6 }, { sides: 8 }, { sides: 10 }, { sides: 12 }, { sides: 20 }]; |
| 23 |
|
| 24 |
rolls.forEach((scenario) => { |
| 25 |
test("should return a number between 1 and " + scenario.sides, () => { |
| 26 |
const dice = new ConcreteDice(scenario.sides); |
| 27 |
const result = dice.roll(); |
| 28 |
|
| 29 |
expect(result).toBeGreaterThanOrEqual(1); |
| 30 |
expect(result).toBeLessThanOrEqual(scenario.sides); |
| 31 |
}); |
| 32 |
}); |
| 33 |
}); |
| 34 |
|
| 35 |
describe("asymmetricRoll", (): void => { |
| 36 |
const rolls = [ |
| 37 |
{ |
| 38 |
expected: 1, |
| 39 |
method: DiceAsymmetricMethod.MIN, |
| 40 |
number: 3, |
| 41 |
rolls: [1, 2, 3], |
| 42 |
}, |
| 43 |
{ |
| 44 |
expected: 6, |
| 45 |
method: DiceAsymmetricMethod.MAX, |
| 46 |
number: 3, |
| 47 |
rolls: [2, 4, 6], |
| 48 |
}, |
| 49 |
]; |
| 50 |
|
| 51 |
rolls.forEach((scenario) => { |
| 52 |
test(`with ${scenario.method} should return ${scenario.expected}`, () => { |
| 53 |
const dice = new ConcreteDice(6); |
| 54 |
|
| 55 |
DiceBase.prototype.roll = jest |
| 56 |
.fn() |
| 57 |
.mockReturnValueOnce(scenario.rolls[0]) |
| 58 |
.mockReturnValueOnce(scenario.rolls[1]) |
| 59 |
.mockReturnValueOnce(scenario.rolls[2]); |
| 60 |
|
| 61 |
const result = dice.asymmetricRoll(scenario.method, scenario.number); |
| 62 |
|
| 63 |
expect(result).toBe(scenario.expected); |
| 64 |
|
| 65 |
jest.fn().mockClear(); |
| 66 |
}); |
| 67 |
}); |
| 68 |
}); |
| 69 |
}); |
| 70 |
|
|
|
|
/packages/games/dices/tests/dice6.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/dices/tests/dice6.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Dice6 } from "@dices/index"; |
| 2 |
|
| 3 |
describe("Dice6", (): void => { |
| 4 |
it("should be instantiable", (): void => { |
| 5 |
const dice = new Dice6(); |
| 6 |
expect(dice).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
it("should return 6 as sides number", (): void => { |
| 10 |
const dice = new Dice6(); |
| 11 |
expect(dice.sides).toBe(6); |
| 12 |
}); |
| 13 |
|
| 14 |
describe("roll", (): void => { |
| 15 |
it("should return a number between 1 and 6", () => { |
| 16 |
const dice = new Dice6(); |
| 17 |
const result = dice.roll(); |
| 18 |
|
| 19 |
expect(result).toBeGreaterThanOrEqual(1); |
| 20 |
expect(result).toBeLessThanOrEqual(6); |
| 21 |
}); |
| 22 |
}); |
| 23 |
}); |
| 24 |
|
|
|
|
/packages/games/display/src/display.ts
|
0 problems
|
|
|
/packages/games/display/src/index.ts
|
0 problems
|
|
|
/packages/games/display/tests/display.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/display/tests/display.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import * as ROT from "rot-js"; |
| 2 |
|
| 3 |
import { Glyph } from "jga-games-glyphs"; |
| 4 |
|
| 5 |
import { Display } from "@games-display/index"; |
| 6 |
// import { Display } from "../src"; |
| 7 |
|
| 8 |
describe("Display", () => { |
| 9 |
it("should be instantiable", () => { |
| 10 |
const display = new Display(80, 24); |
| 11 |
expect(display).not.toBeNull(); |
| 12 |
}); |
| 13 |
|
| 14 |
describe("constructor", (): void => { |
| 15 |
it("constructor should init properties", () => { |
| 16 |
const expected = { |
| 17 |
height: 24, |
| 18 |
width: 80, |
| 19 |
}; |
| 20 |
|
| 21 |
const model = new Display(expected.height, expected.width); |
| 22 |
|
| 23 |
expect(model.getHeight()).toBe(expected.height); |
| 24 |
expect(model.getWidth()).toBe(expected.width); |
| 25 |
}); |
| 26 |
}); |
| 27 |
|
| 28 |
it("should be able to clear", () => { |
| 29 |
const clearSpy = jest.spyOn(ROT.Display.prototype, "clear"); |
| 30 |
|
| 31 |
const display = new Display(24, 80); |
| 32 |
display.clear(); |
| 33 |
|
| 34 |
expect(clearSpy).toHaveBeenCalledTimes(1); |
| 35 |
}); |
| 36 |
|
| 37 |
it("should be able to draw", () => { |
| 38 |
const drawSpy = jest.spyOn(ROT.Display.prototype, "draw"); |
| 39 |
const glyph = new Glyph(); |
| 40 |
|
| 41 |
const display = new Display(24, 80); |
| 42 |
display.draw({ x: 0, y: 0 }, glyph); |
| 43 |
|
| 44 |
expect(drawSpy).toHaveBeenCalledTimes(1); |
| 45 |
}); |
| 46 |
|
| 47 |
it("should be able to draw text", () => { |
| 48 |
const drawSpy = jest.spyOn(ROT.Display.prototype, "drawText"); |
| 49 |
|
| 50 |
const display = new Display(24, 80); |
| 51 |
display.drawText({ x: 0, y: 0 }, "Some text"); |
| 52 |
|
| 53 |
expect(drawSpy).toHaveBeenCalledTimes(1); |
| 54 |
}); |
| 55 |
|
| 56 |
it("should be able to retrieve container", () => { |
| 57 |
const containerSpy = jest.spyOn(ROT.Display.prototype, "getContainer"); |
| 58 |
|
| 59 |
const display = new Display(24, 80); |
| 60 |
display.getContainer(); |
| 61 |
|
| 62 |
expect(containerSpy).toHaveBeenCalledTimes(1); |
| 63 |
}); |
| 64 |
}); |
| 65 |
|
|
|
|
/packages/games/engine/src/components/appearance.ts
|
0 problems
|
|
|
/packages/games/engine/src/components/attack.ts
|
0 problems
|
|
|
/packages/games/engine/src/components/damageable.ts
|
0 problems
|
|
|
/packages/games/engine/src/components/enum.ts
|
0 problems
|
|
|
/packages/games/engine/src/components/index.ts
|
0 problems
|
|
|
/packages/games/engine/src/components/moveable.ts
|
0 problems
|
|
|
/packages/games/engine/src/components/position.ts
|
0 problems
|
|
|
/packages/games/engine/src/components/spread.ts
|
0 problems
|
|
|
/packages/games/engine/src/entities/actor.ts
|
0 problems
|
|
|
/packages/games/engine/src/entities/entity.ts
|
0 problems
|
|
|
/packages/games/engine/src/entities/factory.ts
|
0 problems
|
|
|
/packages/games/engine/src/entities/index.ts
|
0 problems
|
|
|
/packages/games/engine/src/entities/player.ts
|
0 problems
|
|
|
/packages/games/engine/src/index.ts
|
0 problems
|
|
|
/packages/games/engine/src/loop.ts
|
0 problems
|
|
|
/packages/games/engine/src/scheduler.ts
|
0 problems
|
|
|
/packages/games/engine/src/systems/damage.ts
|
0 problems
|
|
|
/packages/games/engine/src/systems/draw.ts
|
0 problems
|
|
|
/packages/games/engine/src/systems/index.ts
|
0 problems
|
|
|
/packages/games/engine/src/systems/movement.ts
|
0 problems
|
|
|
/packages/games/engine/src/systems/position.ts
|
0 problems
|
|
|
/packages/games/engine/src/systems/spread.ts
|
0 problems
|
|
|
/packages/games/engine/src/systems/system.ts
|
0 problems
|
|
|
/packages/games/engine/src/world.ts
|
0 problems
|
|
|
/packages/games/engine/tests/components/appearance.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/components/appearance.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Glyph } from "jga-games-glyphs"; |
| 2 |
|
| 3 |
import { AppearanceComponent } from "@games-engine/index"; |
| 4 |
|
| 5 |
describe("Appearance Component", (): void => { |
| 6 |
it("should be instantiable", (): void => { |
| 7 |
const component = new AppearanceComponent(new Glyph()); |
| 8 |
|
| 9 |
expect(component).not.toBeNull(); |
| 10 |
}); |
| 11 |
|
| 12 |
describe("constructor", (): void => { |
| 13 |
it("should init glyph", (): void => { |
| 14 |
const expected = new Glyph(); |
| 15 |
const component = new AppearanceComponent(expected); |
| 16 |
|
| 17 |
expect(component.getGlyph()).toBe(expected); |
| 18 |
}); |
| 19 |
}); |
| 20 |
|
| 21 |
it("should set glyph", (): void => { |
| 22 |
const expected = new Glyph(); |
| 23 |
const component = new AppearanceComponent(expected); |
| 24 |
|
| 25 |
component.setGlyph(expected); |
| 26 |
expect(component.getGlyph()).toBe(expected); |
| 27 |
}); |
| 28 |
}); |
| 29 |
|
|
|
|
/packages/games/engine/tests/components/attack.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/components/attack.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { AttackComponent } from "@games-engine/index"; |
| 2 |
|
| 3 |
describe("Attack Component", (): void => { |
| 4 |
it("should be instantiable", (): void => { |
| 5 |
const component = new AttackComponent(42); |
| 6 |
|
| 7 |
expect(component).not.toBeNull(); |
| 8 |
}); |
| 9 |
|
| 10 |
describe("constructor", () => { |
| 11 |
it("should init attack", () => { |
| 12 |
const expected = 42; |
| 13 |
const component = new AttackComponent(expected); |
| 14 |
|
| 15 |
expect(component.getValue()).toBe(expected); |
| 16 |
}); |
| 17 |
}); |
| 18 |
}); |
| 19 |
|
|
|
|
/packages/games/engine/tests/components/damageable.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/components/damageable.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { DamageableComponent } from "@games-engine/index"; |
| 2 |
|
| 3 |
describe("Damageable Component", (): void => { |
| 4 |
it("should be instantiable", (): void => { |
| 5 |
const component = new DamageableComponent(42); |
| 6 |
|
| 7 |
expect(component).not.toBeNull(); |
| 8 |
}); |
| 9 |
|
| 10 |
describe("constructor", () => { |
| 11 |
it("should init hit points", () => { |
| 12 |
const expected = 42; |
| 13 |
const component = new DamageableComponent(expected); |
| 14 |
|
| 15 |
expect(component.getHitPoints()).toBe(expected); |
| 16 |
}); |
| 17 |
|
| 18 |
it("should init hit points with default value", () => { |
| 19 |
const expected = 1; |
| 20 |
const component = new DamageableComponent(); |
| 21 |
|
| 22 |
expect(component.getHitPoints()).toBe(expected); |
| 23 |
}); |
| 24 |
}); |
| 25 |
|
| 26 |
describe("takeDamage", () => { |
| 27 |
it("should reduce hit points", () => { |
| 28 |
const original = 42; |
| 29 |
const damage = 7; |
| 30 |
const component = new DamageableComponent(original); |
| 31 |
|
| 32 |
const result = component.takeDamage(damage); |
| 33 |
|
| 34 |
expect(result).toBe(original - damage); |
| 35 |
}); |
| 36 |
}); |
| 37 |
}); |
| 38 |
|
|
|
|
/packages/games/engine/tests/components/position.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/components/position.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { PositionComponent } from "@games-engine/index"; |
| 2 |
|
| 3 |
describe("Position Component", (): void => { |
| 4 |
it("should be instantiable", (): void => { |
| 5 |
const component = new PositionComponent(); |
| 6 |
|
| 7 |
expect(component).not.toBeNull(); |
| 8 |
}); |
| 9 |
|
| 10 |
describe("constructor", (): void => { |
| 11 |
it("should init position", (): void => { |
| 12 |
const expected = 42; |
| 13 |
const component = new PositionComponent({ |
| 14 |
x: expected, |
| 15 |
y: expected, |
| 16 |
}); |
| 17 |
|
| 18 |
expect(component.getPosition()).toStrictEqual({ |
| 19 |
x: expected, |
| 20 |
y: expected, |
| 21 |
}); |
| 22 |
}); |
| 23 |
}); |
| 24 |
|
| 25 |
it("should set position", (): void => { |
| 26 |
const expected = 42; |
| 27 |
const component = new PositionComponent(); |
| 28 |
|
| 29 |
component.setPosition({ x: expected, y: expected }); |
| 30 |
expect(component.getPosition()).toStrictEqual({ |
| 31 |
x: expected, |
| 32 |
y: expected, |
| 33 |
}); |
| 34 |
}); |
| 35 |
}); |
| 36 |
|
|
|
|
/packages/games/engine/tests/components/spread.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/components/spread.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { SpreadComponent } from "@games-engine/index"; |
| 2 |
|
| 3 |
describe("Spread Component", (): void => { |
| 4 |
it("should be instantiable", (): void => { |
| 5 |
const component = new SpreadComponent(); |
| 6 |
|
| 7 |
expect(component).not.toBeNull(); |
| 8 |
}); |
| 9 |
|
| 10 |
describe("constructor", (): void => { |
| 11 |
it("should init name", (): void => { |
| 12 |
const expected = "name"; |
| 13 |
const component = new SpreadComponent(expected); |
| 14 |
|
| 15 |
expect(component.getSpreadedName()).toStrictEqual(expected); |
| 16 |
}); |
| 17 |
|
| 18 |
it("should init growth", (): void => { |
| 19 |
const expected = 10; |
| 20 |
const component = new SpreadComponent("name", expected); |
| 21 |
|
| 22 |
expect(component.getRemainingGrowth()).toStrictEqual(expected); |
| 23 |
}); |
| 24 |
|
| 25 |
it("should init growth with default value", (): void => { |
| 26 |
const expected = 5; |
| 27 |
const component = new SpreadComponent("name"); |
| 28 |
|
| 29 |
expect(component.getRemainingGrowth()).toStrictEqual(expected); |
| 30 |
}); |
| 31 |
}); |
| 32 |
|
| 33 |
it("should set growth", (): void => { |
| 34 |
const expected = 4; |
| 35 |
const component = new SpreadComponent("name"); |
| 36 |
|
| 37 |
component.spread(); |
| 38 |
|
| 39 |
expect(component.getRemainingGrowth()).toStrictEqual(expected); |
| 40 |
}); |
| 41 |
}); |
| 42 |
|
|
|
|
/packages/games/engine/tests/entities/actor.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/entities/actor.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Actor, ComponentName, PositionComponent } from "@games-engine/index"; |
| 2 |
|
| 3 |
class ConcreteActor extends Actor {} |
| 4 |
|
| 5 |
describe("Actor", () => { |
| 6 |
it("should be instantiable", () => { |
| 7 |
const actor = new ConcreteActor("42"); |
| 8 |
expect(actor).not.toBeNull(); |
| 9 |
}); |
| 10 |
|
| 11 |
describe("constructor", () => { |
| 12 |
it("should set id", () => { |
| 13 |
const expected = "42"; |
| 14 |
const actor = new ConcreteActor(expected); |
| 15 |
|
| 16 |
expect(actor.getId()).toBe(expected); |
| 17 |
}); |
| 18 |
|
| 19 |
it("should add a PositionComponent", () => { |
| 20 |
const actor = new ConcreteActor("42"); |
| 21 |
|
| 22 |
expect(actor.getComponents().get(ComponentName.POSITION)).toBeInstanceOf(PositionComponent); |
| 23 |
}); |
| 24 |
}); |
| 25 |
}); |
| 26 |
|
|
|
|
/packages/games/engine/tests/entities/entity.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/entities/entity.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Component } from "jga-patterns-ecs"; |
| 2 |
|
| 3 |
import { Entity } from "@games-engine/index"; |
| 4 |
|
| 5 |
class ConcreteComponent extends Component {} |
| 6 |
|
| 7 |
describe("Entity", () => { |
| 8 |
it("should be instantiable", () => { |
| 9 |
const entity = new Entity("42"); |
| 10 |
expect(entity).not.toBeNull(); |
| 11 |
}); |
| 12 |
|
| 13 |
it("should be able to retrieve a component", (): void => { |
| 14 |
const name = "My Awesome Component"; |
| 15 |
const expected = new ConcreteComponent(name); |
| 16 |
const entity = new Entity("42"); |
| 17 |
|
| 18 |
entity.addComponent(expected); |
| 19 |
|
| 20 |
expect(entity.getComponent(name)).toBe(expected); |
| 21 |
}); |
| 22 |
}); |
| 23 |
|
|
|
|
/packages/games/engine/tests/entities/player.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/entities/player.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { |
| 2 |
AppearanceComponent, |
| 3 |
AttackComponent, |
| 4 |
ComponentName, |
| 5 |
DamageableComponent, |
| 6 |
MoveableComponent, |
| 7 |
Player, |
| 8 |
} from "@games-engine/index"; |
| 9 |
|
| 10 |
describe("Player", () => { |
| 11 |
it("should be instantiable", () => { |
| 12 |
const player = new Player("42"); |
| 13 |
expect(player).not.toBeNull(); |
| 14 |
}); |
| 15 |
|
| 16 |
describe("constructor", () => { |
| 17 |
it("should set id", () => { |
| 18 |
const expected = "42"; |
| 19 |
const player = new Player(expected); |
| 20 |
|
| 21 |
expect(player.getId()).toBe(expected); |
| 22 |
}); |
| 23 |
|
| 24 |
it("should add a MoveableComponent", () => { |
| 25 |
const player = new Player("42"); |
| 26 |
|
| 27 |
expect(player.getComponents().get(ComponentName.MOVEABLE)).toBeInstanceOf(MoveableComponent); |
| 28 |
}); |
| 29 |
|
| 30 |
it("should add an AppearanceComponent", () => { |
| 31 |
const player = new Player("42"); |
| 32 |
|
| 33 |
expect(player.getComponents().get(ComponentName.APPEARANCE)).toBeInstanceOf(AppearanceComponent); |
| 34 |
}); |
| 35 |
|
| 36 |
it("should add an AttackComponent", () => { |
| 37 |
const player = new Player("42"); |
| 38 |
|
| 39 |
expect(player.getComponents().get(ComponentName.ATTACK)).toBeInstanceOf(AttackComponent); |
| 40 |
}); |
| 41 |
|
| 42 |
it("should add an DamageableComponent", () => { |
| 43 |
const player = new Player("42"); |
| 44 |
|
| 45 |
expect(player.getComponents().get(ComponentName.DAMAGEABLE)).toBeInstanceOf(DamageableComponent); |
| 46 |
}); |
| 47 |
}); |
| 48 |
}); |
| 49 |
|
|
|
|
/packages/games/engine/tests/loop.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/loop.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { instance, mock, reset } from "ts-mockito"; |
| 2 |
|
| 3 |
import { Entity, Loop, Scheduler } from "@games-engine/index"; |
| 4 |
|
| 5 |
describe("Loop", () => { |
| 6 |
const mockScheduler: Scheduler = mock(Scheduler); |
| 7 |
|
| 8 |
let schedulerMock: Scheduler; |
| 9 |
|
| 10 |
beforeEach(() => { |
| 11 |
schedulerMock = instance(mockScheduler); |
| 12 |
}); |
| 13 |
|
| 14 |
afterAll(() => { |
| 15 |
reset(mockScheduler); |
| 16 |
}); |
| 17 |
|
| 18 |
it("should be instantiable", () => { |
| 19 |
const loop = new Loop(schedulerMock); |
| 20 |
expect(loop).not.toBeNull(); |
| 21 |
}); |
| 22 |
|
| 23 |
describe("lock", () => { |
| 24 |
it("should return an instance of Loop", () => { |
| 25 |
const loop = new Loop(schedulerMock); |
| 26 |
const result = loop.lock(); |
| 27 |
|
| 28 |
expect(result).toBeInstanceOf(Loop); |
| 29 |
}); |
| 30 |
}); |
| 31 |
|
| 32 |
describe("unlock", () => { |
| 33 |
it("should lock if actor has `lockLoop` property", () => { |
| 34 |
const entity = new Entity("123", true); |
| 35 |
const scheduler = new Scheduler(); |
| 36 |
|
| 37 |
scheduler.add(entity); |
| 38 |
|
| 39 |
const loop = new Loop(scheduler); |
| 40 |
|
| 41 |
const result = loop.unlock(); |
| 42 |
|
| 43 |
expect(result).toBeInstanceOf(Loop); |
| 44 |
}); |
| 45 |
}); |
| 46 |
}); |
| 47 |
|
|
|
|
/packages/games/engine/tests/scheduler.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/scheduler.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Entity, Scheduler } from "@games-engine/index"; |
| 2 |
|
| 3 |
describe("Scheduler", () => { |
| 4 |
it("should be instantiable", () => { |
| 5 |
const scheduler = new Scheduler(); |
| 6 |
expect(scheduler).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
it("should be able to add and retrieve an item", () => { |
| 10 |
const entity = new Entity(); |
| 11 |
const scheduler = new Scheduler(); |
| 12 |
|
| 13 |
scheduler.add(entity, true); |
| 14 |
expect(scheduler.next()).toBe(entity); |
| 15 |
}); |
| 16 |
|
| 17 |
it("should be able to remove an item", () => { |
| 18 |
const entity = new Entity(); |
| 19 |
const scheduler = new Scheduler(); |
| 20 |
|
| 21 |
scheduler.add(entity, true); |
| 22 |
scheduler.remove(entity); |
| 23 |
expect(scheduler.next()).toBeNull(); |
| 24 |
}); |
| 25 |
|
| 26 |
it("should be able to clear all items", () => { |
| 27 |
const entity = new Entity(); |
| 28 |
const scheduler = new Scheduler(); |
| 29 |
|
| 30 |
scheduler.add(entity, true); |
| 31 |
scheduler.add(entity, true); |
| 32 |
scheduler.add(entity, true); |
| 33 |
scheduler.clear(); |
| 34 |
expect(scheduler.next()).toBeNull(); |
| 35 |
}); |
| 36 |
|
| 37 |
it("should be able to retrieve time elapsed", () => { |
| 38 |
const scheduler = new Scheduler(); |
| 39 |
|
| 40 |
expect(scheduler.getTime()).not.toBeNull(); |
| 41 |
expect(scheduler.getTime()).toBe(0); |
| 42 |
}); |
| 43 |
}); |
| 44 |
|
|
|
|
/packages/games/engine/tests/systems/damage.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/systems/damage.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { anything, instance, mock, verify, when } from "ts-mockito"; |
| 2 |
|
| 3 |
import { |
| 4 |
Actor, |
| 5 |
AttackComponent, |
| 6 |
ComponentName, |
| 7 |
DamageableComponent, |
| 8 |
DamageSystem, |
| 9 |
Entity, |
| 10 |
World, |
| 11 |
} from "@games-engine/index"; |
| 12 |
|
| 13 |
describe("Damage System", (): void => { |
| 14 |
it("should be instantiable", (): void => { |
| 15 |
const system = new DamageSystem(); |
| 16 |
|
| 17 |
expect(system).not.toBeNull(); |
| 18 |
}); |
| 19 |
|
| 20 |
describe("run", (): void => { |
| 21 |
// eslint-disable-next-line jest/expect-expect |
| 22 |
it("should substract hit points from target", (): void => { |
| 23 |
const attackValue = 7; |
| 24 |
|
| 25 |
const mockAttackComponent: AttackComponent = mock(AttackComponent); |
| 26 |
when(mockAttackComponent.getValue()).thenReturn(attackValue); |
| 27 |
const componentAttackMock: AttackComponent = instance(mockAttackComponent); |
| 28 |
|
| 29 |
const mockAttacker: Actor = mock(Actor); |
| 30 |
when(mockAttacker.getComponent(ComponentName.ATTACK)).thenReturn(componentAttackMock); |
| 31 |
const attackerMock: Actor = instance(mockAttacker); |
| 32 |
|
| 33 |
const mockComponent: DamageableComponent = mock(DamageableComponent); |
| 34 |
when(mockComponent.takeDamage(attackValue)).thenReturn(10); |
| 35 |
const componentMock: DamageableComponent = instance(mockComponent); |
| 36 |
|
| 37 |
const mockTarget: Entity = mock(Entity); |
| 38 |
when(mockTarget.getComponent(ComponentName.DAMAGEABLE)).thenReturn(componentMock); |
| 39 |
const targetMock: Entity = instance(mockTarget); |
| 40 |
|
| 41 |
const mockWorld: World = mock(World); |
| 42 |
const worldMock: World = instance(mockWorld); |
| 43 |
|
| 44 |
const system = new DamageSystem(attackerMock, targetMock, worldMock); |
| 45 |
system.run(worldMock); |
| 46 |
|
| 47 |
verify(mockComponent.takeDamage(attackValue)).once(); |
| 48 |
}); |
| 49 |
|
| 50 |
// eslint-disable-next-line jest/expect-expect |
| 51 |
it("should remove entity from world if target has no more hit points", (): void => { |
| 52 |
const attackValue = 7; |
| 53 |
|
| 54 |
const mockAttackComponent: AttackComponent = mock(AttackComponent); |
| 55 |
when(mockAttackComponent.getValue()).thenReturn(attackValue); |
| 56 |
const componentAttackMock: AttackComponent = instance(mockAttackComponent); |
| 57 |
|
| 58 |
const mockAttacker: Actor = mock(Actor); |
| 59 |
when(mockAttacker.getComponent(ComponentName.ATTACK)).thenReturn(componentAttackMock); |
| 60 |
const attackerMock: Actor = instance(mockAttacker); |
| 61 |
|
| 62 |
const mockComponent: DamageableComponent = mock(DamageableComponent); |
| 63 |
when(mockComponent.takeDamage(attackValue)).thenReturn(0); |
| 64 |
const componentMock: DamageableComponent = instance(mockComponent); |
| 65 |
|
| 66 |
const mockTarget: Entity = mock(Entity); |
| 67 |
when(mockTarget.getComponent(ComponentName.DAMAGEABLE)).thenReturn(componentMock); |
| 68 |
const targetMock: Entity = instance(mockTarget); |
| 69 |
|
| 70 |
const mockWorld: World = mock(World); |
| 71 |
const worldMock: World = instance(mockWorld); |
| 72 |
|
| 73 |
const system = new DamageSystem(attackerMock, targetMock, worldMock); |
| 74 |
system.run(worldMock); |
| 75 |
|
| 76 |
verify(mockWorld.removeEntity(anything())).once(); |
| 77 |
}); |
| 78 |
}); |
| 79 |
}); |
| 80 |
|
|
|
|
/packages/games/engine/tests/systems/draw.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/systems/draw.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Display } from "jga-games-display"; |
| 2 |
import { CharacterGlyph } from "jga-games-glyphs"; |
| 3 |
|
| 4 |
import { AppearanceComponent, DrawSystem, Entity, OffsetInterface, PositionComponent } from "@games-engine/index"; |
| 5 |
|
| 6 |
const appearanceComponent = new AppearanceComponent(new CharacterGlyph()); |
| 7 |
const positionComponent = new PositionComponent(); |
| 8 |
|
| 9 |
const entity = new Entity("42"); |
| 10 |
entity.addComponent(appearanceComponent); |
| 11 |
entity.addComponent(positionComponent); |
| 12 |
const entities: Map<string, Entity> = new Map<string, Entity>(); |
| 13 |
entities.set("42", entity); |
| 14 |
|
| 15 |
const display: Display = new Display(80, 60); |
| 16 |
|
| 17 |
const offset: OffsetInterface = { x: 0, y: 0 }; |
| 18 |
|
| 19 |
describe("Draw System", (): void => { |
| 20 |
it("should be instantiable", (): void => { |
| 21 |
const system = new DrawSystem(entities, display, offset); |
| 22 |
|
| 23 |
expect(system).not.toBeNull(); |
| 24 |
}); |
| 25 |
|
| 26 |
describe("constructor", (): void => { |
| 27 |
it("should init offset", (): void => { |
| 28 |
const system = new DrawSystem(entities, display, offset); |
| 29 |
|
| 30 |
expect(system.getOffset()).toBe(offset); |
| 31 |
}); |
| 32 |
|
| 33 |
it("should set default offset", (): void => { |
| 34 |
const expected = { x: 0, y: 0 }; |
| 35 |
const system = new DrawSystem(entities, display); |
| 36 |
|
| 37 |
expect(system.getOffset()).toStrictEqual(expected); |
| 38 |
}); |
| 39 |
}); |
| 40 |
|
| 41 |
describe("run", (): void => { |
| 42 |
it("should draw entity", (): void => { |
| 43 |
const drawSpy = jest.spyOn(Display.prototype, "draw"); |
| 44 |
|
| 45 |
const system = new DrawSystem(entities, display, offset); |
| 46 |
|
| 47 |
system.run(); |
| 48 |
|
| 49 |
const expectedPosition = { x: 0, y: 0 }; |
| 50 |
const expectedGlyph = appearanceComponent.getGlyph(); |
| 51 |
|
| 52 |
expect(drawSpy).toHaveBeenCalledTimes(1); |
| 53 |
expect(drawSpy).toHaveBeenCalledWith(expectedPosition, expectedGlyph); |
| 54 |
}); |
| 55 |
}); |
| 56 |
}); |
| 57 |
|
|
|
|
/packages/games/engine/tests/systems/movement.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/systems/movement.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { CommandManager } from "jga-patterns-command"; |
| 2 |
import { CellularMapGenerator, GameMap, PositionInterface } from "jga-games-maps"; |
| 3 |
import { FloorTile, NullTile, TileFactory, WallTile } from "jga-games-tiles"; |
| 4 |
import { |
| 5 |
AttackComponent, |
| 6 |
ComponentName, |
| 7 |
DamageableComponent, |
| 8 |
DamageSystem, |
| 9 |
Entity, |
| 10 |
MoveableComponent, |
| 11 |
MoveInterface, |
| 12 |
MovementSystem, |
| 13 |
PositionComponent, |
| 14 |
Scheduler, |
| 15 |
World, |
| 16 |
} from "@games-engine/index"; |
| 17 |
|
| 18 |
const position: PositionInterface = { x: 0, y: 1 }; |
| 19 |
const tileFactory: TileFactory = new TileFactory(); |
| 20 |
const generator: CellularMapGenerator = new CellularMapGenerator(10, 10, tileFactory); |
| 21 |
const map: GameMap = new GameMap({ |
| 22 |
generator, |
| 23 |
height: 10, |
| 24 |
width: 10, |
| 25 |
tileFactory, |
| 26 |
}); |
| 27 |
const entity = new Entity("42"); |
| 28 |
const entities: Map<string, Entity> = new Map<string, Entity>(); |
| 29 |
entities.set("42", entity); |
| 30 |
|
| 31 |
const mapEntity = new Entity("42"); |
| 32 |
mapEntity.addComponent(new PositionComponent({ x: 0, y: 1 })); |
| 33 |
mapEntity.addComponent(new DamageableComponent()); |
| 34 |
const mapEntities = new Map<string, Entity>(); |
| 35 |
mapEntities.set(mapEntity.getId(), mapEntity); |
| 36 |
|
| 37 |
const world = new World(new Scheduler(), map, new CommandManager()); |
| 38 |
|
| 39 |
describe("Movement System", (): void => { |
| 40 |
beforeEach(() => jest.clearAllMocks()); |
| 41 |
|
| 42 |
it("should be instantiable", (): void => { |
| 43 |
const system = new MovementSystem(entities, position, mapEntities); |
| 44 |
|
| 45 |
expect(system).not.toBeNull(); |
| 46 |
}); |
| 47 |
|
| 48 |
describe("constructor", (): void => { |
| 49 |
it("should init position", (): void => { |
| 50 |
const system = new MovementSystem(entities, position, mapEntities); |
| 51 |
|
| 52 |
expect(system.getPosition()).toBe(position); |
| 53 |
}); |
| 54 |
}); |
| 55 |
|
| 56 |
describe("run", (): void => { |
| 57 |
it("should do nothing if can move return false", (): void => { |
| 58 |
const mockEntity = new Entity("42"); |
| 59 |
mockEntity.addComponent(new MoveableComponent()); |
| 60 |
mockEntity.addComponent(new PositionComponent()); |
| 61 |
const mockEntities: Map<string, Entity> = new Map<string, Entity>(); |
| 62 |
mockEntities.set("42", mockEntity); |
| 63 |
|
| 64 |
const system = new MovementSystem(mockEntities, position, mapEntities); |
| 65 |
|
| 66 |
const expectedPosition = system.getEntities().get("42").getComponent(ComponentName.POSITION).getPosition(); |
| 67 |
|
| 68 |
const mockMove: MoveInterface = { |
| 69 |
canMove: false, |
| 70 |
newPosition: expectedPosition, |
| 71 |
}; |
| 72 |
|
| 73 |
const originalImpl = MovementSystem.prototype.canMove; |
| 74 |
|
| 75 |
MovementSystem.prototype.canMove = jest.fn().mockImplementation(() => { |
| 76 |
return mockMove; |
| 77 |
}); |
| 78 |
|
| 79 |
system.run(world); |
| 80 |
|
| 81 |
expect(system.getEntities().get("42").getComponent(ComponentName.POSITION).getPosition()).toBe( |
| 82 |
expectedPosition, |
| 83 |
); |
| 84 |
|
| 85 |
MovementSystem.prototype.canMove = originalImpl; |
| 86 |
}); |
| 87 |
|
| 88 |
it("should set position if can move return true", (): void => { |
| 89 |
const mockEntity = new Entity("42"); |
| 90 |
mockEntity.addComponent(new MoveableComponent()); |
| 91 |
mockEntity.addComponent(new PositionComponent()); |
| 92 |
const mockEntities: Map<string, Entity> = new Map<string, Entity>(); |
| 93 |
mockEntities.set("42", mockEntity); |
| 94 |
|
| 95 |
const mockMove: MoveInterface = { |
| 96 |
canMove: true, |
| 97 |
newPosition: position, |
| 98 |
}; |
| 99 |
|
| 100 |
const originalImpl = MovementSystem.prototype.canMove; |
| 101 |
|
| 102 |
MovementSystem.prototype.canMove = jest.fn().mockImplementation(() => { |
| 103 |
return mockMove; |
| 104 |
}); |
| 105 |
|
| 106 |
const system = new MovementSystem(mockEntities, position, mapEntities); |
| 107 |
|
| 108 |
system.run(world); |
| 109 |
|
| 110 |
expect(system.getEntities().get("42").getComponent(ComponentName.POSITION).getPosition()).toBe(position); |
| 111 |
|
| 112 |
MovementSystem.prototype.canMove = originalImpl; |
| 113 |
}); |
| 114 |
}); |
| 115 |
|
| 116 |
describe("can move", (): void => { |
| 117 |
it("should return false if position is not set", (): void => { |
| 118 |
const system = new MovementSystem(entities, null, mapEntities); |
| 119 |
|
| 120 |
const expected: MoveInterface = { |
| 121 |
canMove: false, |
| 122 |
newPosition: null, |
| 123 |
}; |
| 124 |
|
| 125 |
expect(system.canMove(world)).toStrictEqual(expected); |
| 126 |
}); |
| 127 |
|
| 128 |
it("should return false if map is not set", () => { |
| 129 |
const system = new MovementSystem(entities, position, mapEntities); |
| 130 |
|
| 131 |
const expected: MoveInterface = { |
| 132 |
canMove: false, |
| 133 |
newPosition: position, |
| 134 |
}; |
| 135 |
|
| 136 |
expect(system.canMove(null)).toStrictEqual(expected); |
| 137 |
}); |
| 138 |
|
| 139 |
it("should return false if tile is not set", () => { |
| 140 |
const mockTile = null; |
| 141 |
const mockMap = new GameMap({ |
| 142 |
generator, |
| 143 |
height: 1, |
| 144 |
width: 1, |
| 145 |
tileFactory, |
| 146 |
}); |
| 147 |
|
| 148 |
const mockWorld = new World(new Scheduler(), mockMap, new CommandManager()); |
| 149 |
|
| 150 |
const originalImpl = GameMap.prototype.getTile; |
| 151 |
|
| 152 |
GameMap.prototype.getTile = jest.fn().mockImplementation(() => { |
| 153 |
return mockTile; |
| 154 |
}); |
| 155 |
|
| 156 |
const system = new MovementSystem(entities, position, mapEntities); |
| 157 |
|
| 158 |
const expected: MoveInterface = { |
| 159 |
canMove: false, |
| 160 |
newPosition: position, |
| 161 |
}; |
| 162 |
|
| 163 |
expect(system.canMove(mockWorld)).toStrictEqual(expected); |
| 164 |
|
| 165 |
GameMap.prototype.getTile = originalImpl; |
| 166 |
}); |
| 167 |
|
| 168 |
it("should return true if tile is walkable", () => { |
| 169 |
const mockTile = new FloorTile(); |
| 170 |
const mockMap = new GameMap({ |
| 171 |
generator, |
| 172 |
height: 1, |
| 173 |
width: 1, |
| 174 |
tileFactory, |
| 175 |
}); |
| 176 |
const mockWorld = new World(new Scheduler(), mockMap, new CommandManager()); |
| 177 |
const mapPosition = { x: 0, y: 0 }; |
| 178 |
|
| 179 |
const originalImpl = GameMap.prototype.getTile; |
| 180 |
|
| 181 |
GameMap.prototype.getTile = jest.fn().mockImplementation(() => { |
| 182 |
return mockTile; |
| 183 |
}); |
| 184 |
|
| 185 |
const system = new MovementSystem(entities, mapPosition, mapEntities); |
| 186 |
|
| 187 |
const expected: MoveInterface = { |
| 188 |
canMove: true, |
| 189 |
newPosition: mapPosition, |
| 190 |
}; |
| 191 |
|
| 192 |
expect(system.canMove(mockWorld)).toStrictEqual(expected); |
| 193 |
|
| 194 |
GameMap.prototype.getTile = originalImpl; |
| 195 |
}); |
| 196 |
|
| 197 |
it("should return false if tile is diggable", () => { |
| 198 |
const mockTile = new WallTile(); |
| 199 |
const mockMap = new GameMap({ |
| 200 |
generator, |
| 201 |
height: 2, |
| 202 |
width: 2, |
| 203 |
tileFactory, |
| 204 |
}); |
| 205 |
const mockWorld = new World(new Scheduler(), mockMap, new CommandManager()); |
| 206 |
const mapPosition = { x: 0, y: 0 }; |
| 207 |
|
| 208 |
const originalImpl = GameMap.prototype.getTile; |
| 209 |
|
| 210 |
GameMap.prototype.getTile = jest.fn().mockImplementation(() => { |
| 211 |
return mockTile; |
| 212 |
}); |
| 213 |
|
| 214 |
const system = new MovementSystem(entities, mapPosition, mapEntities); |
| 215 |
|
| 216 |
const expected: MoveInterface = { |
| 217 |
canMove: false, |
| 218 |
newPosition: mapPosition, |
| 219 |
}; |
| 220 |
|
| 221 |
expect(system.canMove(mockWorld)).toStrictEqual(expected); |
| 222 |
|
| 223 |
GameMap.prototype.getTile = originalImpl; |
| 224 |
}); |
| 225 |
|
| 226 |
it("should return false if tile is not walkable and not diggable", () => { |
| 227 |
const mockTile = new NullTile(); |
| 228 |
const mockMap = new GameMap({ |
| 229 |
generator, |
| 230 |
height: 1, |
| 231 |
width: 1, |
| 232 |
tileFactory, |
| 233 |
}); |
| 234 |
const mockWorld = new World(new Scheduler(), mockMap, new CommandManager()); |
| 235 |
const mapPosition = { x: 0, y: 0 }; |
| 236 |
|
| 237 |
const originalImpl = GameMap.prototype.getTile; |
| 238 |
|
| 239 |
GameMap.prototype.getTile = jest.fn().mockImplementation(() => { |
| 240 |
return mockTile; |
| 241 |
}); |
| 242 |
|
| 243 |
const system = new MovementSystem(entities, mapPosition, mapEntities); |
| 244 |
|
| 245 |
const expected: MoveInterface = { |
| 246 |
canMove: false, |
| 247 |
newPosition: mapPosition, |
| 248 |
}; |
| 249 |
|
| 250 |
expect(system.canMove(mockWorld)).toStrictEqual(expected); |
| 251 |
|
| 252 |
GameMap.prototype.getTile = originalImpl; |
| 253 |
}); |
| 254 |
|
| 255 |
it("should attack if there is a target on selected position", () => { |
| 256 |
const damageSystemSpy = jest.spyOn(DamageSystem.prototype, "run"); |
| 257 |
|
| 258 |
const mockTile = new FloorTile(); |
| 259 |
const mockMap = new GameMap({ |
| 260 |
generator, |
| 261 |
height: 2, |
| 262 |
width: 2, |
| 263 |
tileFactory, |
| 264 |
}); |
| 265 |
const mockWorld = new World(new Scheduler(), mockMap, new CommandManager()); |
| 266 |
const mapPosition = { x: 0, y: 1 }; |
| 267 |
const targetEntity = new Entity("42"); |
| 268 |
targetEntity.addComponent(new PositionComponent({ x: 0, y: 0 })); |
| 269 |
targetEntity.addComponent(new MoveableComponent()); |
| 270 |
targetEntity.addComponent(new AttackComponent(10)); |
| 271 |
const targetEntitites = new Map<string, Entity>(); |
| 272 |
targetEntitites.set(targetEntity.getId(), targetEntity); |
| 273 |
|
| 274 |
const originalImpl = GameMap.prototype.getTile; |
| 275 |
|
| 276 |
GameMap.prototype.getTile = jest.fn().mockImplementation(() => { |
| 277 |
return mockTile; |
| 278 |
}); |
| 279 |
|
| 280 |
const system = new MovementSystem(targetEntitites, mapPosition, mapEntities); |
| 281 |
|
| 282 |
const expected: MoveInterface = { |
| 283 |
canMove: false, |
| 284 |
newPosition: mapPosition, |
| 285 |
}; |
| 286 |
|
| 287 |
expect(system.canMove(mockWorld)).toStrictEqual(expected); |
| 288 |
expect(damageSystemSpy).toHaveBeenCalledWith(mockWorld); |
| 289 |
|
| 290 |
GameMap.prototype.getTile = originalImpl; |
| 291 |
}); |
| 292 |
|
| 293 |
it("should do nothing if actor has no attack component", () => { |
| 294 |
const damageSystemSpy = jest.spyOn(DamageSystem.prototype, "run"); |
| 295 |
|
| 296 |
const mockTile = new FloorTile(); |
| 297 |
const mockMap = new GameMap({ |
| 298 |
generator, |
| 299 |
height: 2, |
| 300 |
width: 2, |
| 301 |
tileFactory, |
| 302 |
}); |
| 303 |
const mockWorld = new World(new Scheduler(), mockMap, new CommandManager()); |
| 304 |
const mapPosition = { x: 0, y: 1 }; |
| 305 |
const targetEntity = new Entity("42"); |
| 306 |
targetEntity.addComponent(new PositionComponent({ x: 0, y: 0 })); |
| 307 |
targetEntity.addComponent(new MoveableComponent()); |
| 308 |
|
| 309 |
const targetEntitites = new Map<string, Entity>(); |
| 310 |
targetEntitites.set(targetEntity.getId(), targetEntity); |
| 311 |
|
| 312 |
const originalImpl = GameMap.prototype.getTile; |
| 313 |
|
| 314 |
GameMap.prototype.getTile = jest.fn().mockImplementation(() => { |
| 315 |
return mockTile; |
| 316 |
}); |
| 317 |
|
| 318 |
const system = new MovementSystem(targetEntitites, mapPosition, mapEntities); |
| 319 |
|
| 320 |
const expected: MoveInterface = { |
| 321 |
canMove: false, |
| 322 |
newPosition: mapPosition, |
| 323 |
}; |
| 324 |
|
| 325 |
expect(system.canMove(mockWorld)).toStrictEqual(expected); |
| 326 |
expect(damageSystemSpy).not.toHaveBeenCalled(); |
| 327 |
|
| 328 |
GameMap.prototype.getTile = originalImpl; |
| 329 |
}); |
| 330 |
|
| 331 |
it("should do nothing if target has no damageable component", () => { |
| 332 |
const damageSystemSpy = jest.spyOn(DamageSystem.prototype, "run"); |
| 333 |
|
| 334 |
const mockTile = new FloorTile(); |
| 335 |
const mockMap = new GameMap({ |
| 336 |
generator, |
| 337 |
height: 2, |
| 338 |
width: 2, |
| 339 |
tileFactory, |
| 340 |
}); |
| 341 |
const mockWorld = new World(new Scheduler(), mockMap, new CommandManager()); |
| 342 |
const mapPosition = { x: 0, y: 1 }; |
| 343 |
const targetEntity = new Entity("42"); |
| 344 |
targetEntity.addComponent(new PositionComponent({ x: 0, y: 0 })); |
| 345 |
targetEntity.addComponent(new MoveableComponent()); |
| 346 |
targetEntity.addComponent(new AttackComponent(10)); |
| 347 |
|
| 348 |
const targetEntitites = new Map<string, Entity>(); |
| 349 |
targetEntitites.set(targetEntity.getId(), targetEntity); |
| 350 |
|
| 351 |
const target = new Entity("42"); |
| 352 |
target.addComponent(new PositionComponent({ x: 0, y: 1 })); |
| 353 |
|
| 354 |
const mapTarget = new Map<string, Entity>(); |
| 355 |
mapTarget.set(target.getId(), target); |
| 356 |
|
| 357 |
const originalImpl = GameMap.prototype.getTile; |
| 358 |
|
| 359 |
GameMap.prototype.getTile = jest.fn().mockImplementation(() => { |
| 360 |
return mockTile; |
| 361 |
}); |
| 362 |
|
| 363 |
const system = new MovementSystem(targetEntitites, mapPosition, mapTarget); |
| 364 |
|
| 365 |
const expected: MoveInterface = { |
| 366 |
canMove: false, |
| 367 |
newPosition: mapPosition, |
| 368 |
}; |
| 369 |
|
| 370 |
expect(system.canMove(mockWorld)).toStrictEqual(expected); |
| 371 |
expect(damageSystemSpy).not.toHaveBeenCalled(); |
| 372 |
|
| 373 |
GameMap.prototype.getTile = originalImpl; |
| 374 |
}); |
| 375 |
}); |
| 376 |
}); |
| 377 |
|
|
|
|
/packages/games/engine/tests/systems/position.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/systems/position.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { ComponentName, Entity, PositionComponent, PositionInterface, PositionSystem } from "@games-engine/index"; |
| 2 |
|
| 3 |
const position: PositionInterface = { x: 0, y: 0 }; |
| 4 |
const entity = new Entity("42"); |
| 5 |
entity.addComponent(new PositionComponent()); |
| 6 |
const entities: Map<string, Entity> = new Map<string, Entity>(); |
| 7 |
entities.set("42", entity); |
| 8 |
|
| 9 |
describe("Position System", (): void => { |
| 10 |
it("should be instantiable", (): void => { |
| 11 |
const system = new PositionSystem(entities, position); |
| 12 |
|
| 13 |
expect(system).not.toBeNull(); |
| 14 |
}); |
| 15 |
|
| 16 |
describe("constructor", (): void => { |
| 17 |
it("should set position", (): void => { |
| 18 |
const system = new PositionSystem(entities, position); |
| 19 |
|
| 20 |
expect(system.getPosition()).toBe(position); |
| 21 |
}); |
| 22 |
}); |
| 23 |
|
| 24 |
describe("run", (): void => { |
| 25 |
it("should set position for each entity", (): void => { |
| 26 |
const system = new PositionSystem(entities, position); |
| 27 |
|
| 28 |
system.run(); |
| 29 |
|
| 30 |
const entity = system.getEntities().get("42"); |
| 31 |
|
| 32 |
expect(entity.getComponent(ComponentName.POSITION).getPosition()).toBe(position); |
| 33 |
}); |
| 34 |
}); |
| 35 |
}); |
| 36 |
|
|
|
|
/packages/games/engine/tests/systems/spread.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/systems/spread.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { anything, instance, mock, when } from "ts-mockito"; |
| 2 |
|
| 3 |
import { random } from "jga-algorithms-random"; |
| 4 |
|
| 5 |
jest.mock("jga-algorithms-random/src/random"); |
| 6 |
|
| 7 |
import { |
| 8 |
ComponentName, |
| 9 |
Entity, |
| 10 |
EntityFactory, |
| 11 |
PositionComponent, |
| 12 |
SpreadComponent, |
| 13 |
SpreadSystem, |
| 14 |
World, |
| 15 |
} from "@games-engine/index"; |
| 16 |
|
| 17 |
describe("Spread System", () => { |
| 18 |
beforeEach(() => { |
| 19 |
random.prototype = jest.fn().mockReturnValue(20); |
| 20 |
}); |
| 21 |
|
| 22 |
afterAll(() => { |
| 23 |
jest.fn().mockClear(); |
| 24 |
}); |
| 25 |
|
| 26 |
it("should be instantiable", (): void => { |
| 27 |
const system = new SpreadSystem([]); |
| 28 |
|
| 29 |
expect(system).not.toBeNull(); |
| 30 |
}); |
| 31 |
|
| 32 |
describe("run", (): void => { |
| 33 |
// eslint-disable-next-line jest/expect-expect |
| 34 |
it("should spread entity", (): void => { |
| 35 |
const mockPositionComponent: PositionComponent = mock(PositionComponent); |
| 36 |
when(mockPositionComponent.setPosition(anything())).thenReturn(null); |
| 37 |
const positionComponentMock: PositionComponent = instance(mockPositionComponent); |
| 38 |
|
| 39 |
const mockSpreadComponent: SpreadComponent = mock(SpreadComponent); |
| 40 |
when(mockSpreadComponent.getName()).thenReturn("Spread"); |
| 41 |
when(mockSpreadComponent.getRemainingGrowth()).thenReturn(5); |
| 42 |
when(mockSpreadComponent.spread()).thenReturn(null); |
| 43 |
const spreadComponentMock: SpreadComponent = instance(mockSpreadComponent); |
| 44 |
|
| 45 |
const mockEntity: Entity = mock(Entity); |
| 46 |
when(mockEntity.getComponent(ComponentName.POSITION)).thenReturn(positionComponentMock); |
| 47 |
when(mockEntity.getComponent(ComponentName.SPREAD)).thenReturn(spreadComponentMock); |
| 48 |
const entityMock: Entity = instance(mockEntity); |
| 49 |
|
| 50 |
const mockFactory: EntityFactory = mock(EntityFactory); |
| 51 |
when(mockFactory.create(anything())).thenReturn(entityMock); |
| 52 |
const factoryMock: EntityFactory = instance(mockFactory); |
| 53 |
|
| 54 |
const mockWord: World = mock(World); |
| 55 |
when(mockWord.isEmptyFloor(anything())).thenReturn(true); |
| 56 |
when(mockWord.getEntityFactory()).thenReturn(factoryMock); |
| 57 |
const worldMock: World = instance(mockWord); |
| 58 |
|
| 59 |
const entity = new Entity("42"); |
| 60 |
entity.addComponent(spreadComponentMock); |
| 61 |
const entities: Map<string, Entity> = new Map<string, Entity>(); |
| 62 |
entities.set("42", entity); |
| 63 |
|
| 64 |
const system = new SpreadSystem(entities); |
| 65 |
|
| 66 |
system.run(worldMock); |
| 67 |
}); |
| 68 |
}); |
| 69 |
}); |
| 70 |
|
|
|
|
/packages/games/engine/tests/world.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/engine/tests/world.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { anything, anyNumber, instance, mock, reset, spy, verify, when } from "ts-mockito"; |
| 2 |
|
| 3 |
import { Command, CommandManager } from "jga-patterns-command"; |
| 4 |
|
| 5 |
import { FloorTile, Tile, TileFactory, WallTile } from "jga-games-tiles"; |
| 6 |
|
| 7 |
import { GameMap } from "jga-games-maps"; |
| 8 |
|
| 9 |
import { World, Entity, EntityFactory, Loop, Player, PositionComponent, Scheduler, System } from "@games-engine/index"; |
| 10 |
|
| 11 |
class ConcreteSystem extends System { |
| 12 |
// eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 13 |
public run(map?: GameMap): void { |
| 14 |
console.log(`run ConcreteSystem`); |
| 15 |
} |
| 16 |
} |
| 17 |
|
| 18 |
describe("World", () => { |
| 19 |
const mockMap: GameMap = mock(GameMap); |
| 20 |
const mockTileFactory: TileFactory = mock<TileFactory>(); |
| 21 |
const mockTile: Tile = mock(Tile); |
| 22 |
const mockCommandManager: CommandManager = mock<CommandManager>(); |
| 23 |
const mockEntityFactory: EntityFactory = mock(EntityFactory); |
| 24 |
|
| 25 |
let gameMapMock: GameMap; |
| 26 |
let tileFactoryMock: TileFactory; |
| 27 |
let tileMock: Tile; |
| 28 |
let commandManagerMock: CommandManager; |
| 29 |
let entityFactoryMock: EntityFactory; |
| 30 |
|
| 31 |
beforeEach(() => { |
| 32 |
tileMock = instance(mockTile); |
| 33 |
tileMock.isWalkable = true; |
| 34 |
|
| 35 |
when(mockMap.getTile({ x: anyNumber(), y: anyNumber() })).thenReturn(tileMock); |
| 36 |
when(mockMap.getHeight()).thenReturn(1); |
| 37 |
when(mockMap.getWidth()).thenReturn(1); |
| 38 |
|
| 39 |
gameMapMock = instance(mockMap); |
| 40 |
tileFactoryMock = instance(mockTileFactory); |
| 41 |
commandManagerMock = instance(mockCommandManager); |
| 42 |
entityFactoryMock = instance(mockEntityFactory); |
| 43 |
}); |
| 44 |
|
| 45 |
afterAll(() => { |
| 46 |
reset(mockMap); |
| 47 |
reset(mockTileFactory); |
| 48 |
reset(mockTile); |
| 49 |
reset(mockCommandManager); |
| 50 |
reset(mockEntityFactory); |
| 51 |
}); |
| 52 |
|
| 53 |
it("should be instantiable", () => { |
| 54 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 55 |
expect(engine).not.toBeNull(); |
| 56 |
}); |
| 57 |
|
| 58 |
it("should be able to retrieve map", () => { |
| 59 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 60 |
expect(engine.getMap()).toBe(gameMapMock); |
| 61 |
}); |
| 62 |
|
| 63 |
it("can create and retrieve player", () => { |
| 64 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 65 |
|
| 66 |
const spiedEngine = spy(engine); |
| 67 |
when(spiedEngine.getRandomFloorPosition()).thenReturn({ x: 0, y: 0 }); |
| 68 |
|
| 69 |
engine.createPlayer(); |
| 70 |
const player = engine.getPlayer(); |
| 71 |
|
| 72 |
expect(player).toBeInstanceOf(Player); |
| 73 |
}); |
| 74 |
|
| 75 |
it("add an entity when creating a player", () => { |
| 76 |
const floorTile = new FloorTile(); |
| 77 |
const wallTile = new WallTile(); |
| 78 |
|
| 79 |
const map = new GameMap({ |
| 80 |
height: 1, |
| 81 |
tileFactory: tileFactoryMock, |
| 82 |
tiles: [[floorTile], [wallTile]], |
| 83 |
width: 2, |
| 84 |
}); |
| 85 |
|
| 86 |
const engine = new World(new Scheduler(), map, commandManagerMock, entityFactoryMock); |
| 87 |
const spiedEngine = spy(engine); |
| 88 |
when(spiedEngine.getRandomFloorPosition()).thenReturn({ x: 0, y: 0 }); |
| 89 |
|
| 90 |
expect(engine.getEntities().size).toBe(0); |
| 91 |
|
| 92 |
engine.createPlayer(); |
| 93 |
|
| 94 |
expect(engine.getEntities().size).toBe(1); |
| 95 |
}); |
| 96 |
|
| 97 |
it("should be able to add and remove an entity", () => { |
| 98 |
const floorTile = new FloorTile(); |
| 99 |
const wallTile = new WallTile(); |
| 100 |
|
| 101 |
const map = new GameMap({ |
| 102 |
height: 1, |
| 103 |
tileFactory: tileFactoryMock, |
| 104 |
tiles: [[floorTile], [wallTile]], |
| 105 |
width: 2, |
| 106 |
}); |
| 107 |
|
| 108 |
const engine = new World(new Scheduler(), map, commandManagerMock, entityFactoryMock); |
| 109 |
|
| 110 |
expect(engine.getEntities().size).toBe(0); |
| 111 |
|
| 112 |
const entity = new Entity("42"); |
| 113 |
|
| 114 |
engine.addEntity(entity); |
| 115 |
|
| 116 |
expect(engine.getEntities().size).toBe(1); |
| 117 |
|
| 118 |
engine.removeEntity(entity); |
| 119 |
|
| 120 |
expect(engine.getEntities().size).toBe(0); |
| 121 |
}); |
| 122 |
|
| 123 |
describe("lock", () => { |
| 124 |
it("should call `Loop.lock`", () => { |
| 125 |
const loopLockSpy = jest.spyOn(Loop.prototype, "lock"); |
| 126 |
|
| 127 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 128 |
|
| 129 |
engine.lock(); |
| 130 |
|
| 131 |
expect(loopLockSpy).toHaveBeenCalled(); |
| 132 |
}); |
| 133 |
}); |
| 134 |
|
| 135 |
describe("unlock", () => { |
| 136 |
it("should call `Loop.unlock`", () => { |
| 137 |
const loopLockSpy = jest.spyOn(Loop.prototype, "unlock"); |
| 138 |
|
| 139 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 140 |
|
| 141 |
engine.unlock(); |
| 142 |
|
| 143 |
expect(loopLockSpy).toHaveBeenCalled(); |
| 144 |
}); |
| 145 |
}); |
| 146 |
|
| 147 |
describe("mainLoop", () => { |
| 148 |
it("should call `act` for each actor", () => { |
| 149 |
const entity = new Entity("42"); |
| 150 |
const entity1 = new Entity("43"); |
| 151 |
const entity2 = new Entity("44"); |
| 152 |
const entitySpy = jest.spyOn(Entity.prototype, "act"); |
| 153 |
const schedulerSpy = jest.spyOn(Scheduler.prototype, "next"); |
| 154 |
|
| 155 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 156 |
|
| 157 |
engine.addEntity(entity); |
| 158 |
engine.addEntity(entity1); |
| 159 |
engine.addEntity(entity2); |
| 160 |
|
| 161 |
engine.mainLoop(); |
| 162 |
|
| 163 |
expect(entitySpy).toHaveBeenCalledTimes(3); |
| 164 |
expect(schedulerSpy).toHaveBeenCalledTimes(4); |
| 165 |
}); |
| 166 |
}); |
| 167 |
|
| 168 |
describe("process", () => { |
| 169 |
// eslint-disable-next-line jest/expect-expect |
| 170 |
it("should run systems", () => { |
| 171 |
const mockSystem: ConcreteSystem = mock(ConcreteSystem); |
| 172 |
|
| 173 |
when(mockSystem.run(anything())).thenReturn(null); |
| 174 |
|
| 175 |
const systemMock = instance(mockSystem); |
| 176 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 177 |
|
| 178 |
engine.registerSystems([systemMock]); |
| 179 |
|
| 180 |
engine.process(); |
| 181 |
|
| 182 |
verify(mockSystem.run(anything())).once(); |
| 183 |
}); |
| 184 |
}); |
| 185 |
|
| 186 |
describe("run", () => { |
| 187 |
// eslint-disable-next-line jest/expect-expect |
| 188 |
it("should run a system", () => { |
| 189 |
const mockSystem: ConcreteSystem = mock(ConcreteSystem); |
| 190 |
|
| 191 |
when(mockSystem.run(anything())).thenReturn(null); |
| 192 |
|
| 193 |
const systemMock = instance(mockSystem); |
| 194 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 195 |
|
| 196 |
engine.run(systemMock); |
| 197 |
|
| 198 |
verify(mockSystem.run(anything())).once(); |
| 199 |
}); |
| 200 |
}); |
| 201 |
|
| 202 |
describe("execute", () => { |
| 203 |
// eslint-disable-next-line jest/expect-expect |
| 204 |
it("should call command manager execute", () => { |
| 205 |
const mockCommand: Command = mock(Command); |
| 206 |
const engine = new World(new Scheduler(), gameMapMock, commandManagerMock, entityFactoryMock); |
| 207 |
|
| 208 |
const commandMock = instance(mockCommand); |
| 209 |
|
| 210 |
engine.execute(commandMock); |
| 211 |
|
| 212 |
verify(mockCommandManager.execute(commandMock)).once(); |
| 213 |
}); |
| 214 |
}); |
| 215 |
|
| 216 |
describe("addEntityAtRandomPosition", () => { |
| 217 |
it("should add a new entity if it has `PositionComponent`", () => { |
| 218 |
const floorTile = new FloorTile(); |
| 219 |
const wallTile = new WallTile(); |
| 220 |
|
| 221 |
const addEntitySpy = jest.spyOn(World.prototype, "addEntity"); |
| 222 |
const schedulerAddSpy = jest.spyOn(Scheduler.prototype, "add"); |
| 223 |
|
| 224 |
const mockComponent: PositionComponent = mock(PositionComponent); |
| 225 |
const mockEntity: Entity = mock(Entity); |
| 226 |
|
| 227 |
when(mockComponent.setPosition(anything())).thenReturn(); |
| 228 |
|
| 229 |
const componentMock = instance(mockComponent); |
| 230 |
|
| 231 |
when(mockEntity.hasComponent(anything())).thenReturn(true); |
| 232 |
when(mockEntity.getComponent(anything())).thenReturn(componentMock); |
| 233 |
|
| 234 |
const entityMock1 = instance(mockEntity); |
| 235 |
// const entityMock2 = instance(mockEntity); |
| 236 |
|
| 237 |
const map = new GameMap({ |
| 238 |
height: 1, |
| 239 |
tileFactory: tileFactoryMock, |
| 240 |
tiles: [[floorTile], [wallTile]], |
| 241 |
width: 2, |
| 242 |
}); |
| 243 |
|
| 244 |
const engine = new World(new Scheduler(), map, commandManagerMock, entityFactoryMock); |
| 245 |
const spiedEngine = spy(engine); |
| 246 |
when(spiedEngine.getRandomFloorPosition()).thenReturn({ x: 0, y: 0 }); |
| 247 |
|
| 248 |
expect(engine.getEntities().size).toBe(0); |
| 249 |
|
| 250 |
const result = engine.addEntityAtRandomPosition(entityMock1); |
| 251 |
|
| 252 |
expect(addEntitySpy).toHaveBeenCalledWith(entityMock1, false); |
| 253 |
expect(schedulerAddSpy).toHaveBeenCalledWith(entityMock1, false); |
| 254 |
expect(result.size).toBe(1); |
| 255 |
}); |
| 256 |
|
| 257 |
it("should do nothing if entity has no `PositionComponent`", () => { |
| 258 |
const floorTile = new FloorTile(); |
| 259 |
const wallTile = new WallTile(); |
| 260 |
|
| 261 |
const map = new GameMap({ |
| 262 |
height: 1, |
| 263 |
tileFactory: tileFactoryMock, |
| 264 |
tiles: [[floorTile], [wallTile]], |
| 265 |
width: 2, |
| 266 |
}); |
| 267 |
|
| 268 |
const mockEntity: Entity = mock(Entity); |
| 269 |
|
| 270 |
when(mockEntity.hasComponent(anything())).thenReturn(false); |
| 271 |
|
| 272 |
const entityMock = instance(mockEntity); |
| 273 |
|
| 274 |
const engine = new World(new Scheduler(), map, commandManagerMock, entityFactoryMock); |
| 275 |
|
| 276 |
expect(engine.getEntities().size).toBe(0); |
| 277 |
|
| 278 |
const result = engine.addEntityAtRandomPosition(entityMock); |
| 279 |
|
| 280 |
expect(result.size).toBe(0); |
| 281 |
}); |
| 282 |
}); |
| 283 |
|
| 284 |
describe("getRandomFloorPosition", (): void => { |
| 285 |
it("should return a walkable tile", (): void => { |
| 286 |
const floorTile = new FloorTile(); |
| 287 |
const wallTile = new WallTile(); |
| 288 |
|
| 289 |
const map = new GameMap({ |
| 290 |
height: 1, |
| 291 |
tileFactory: tileFactoryMock, |
| 292 |
tiles: [[floorTile], [wallTile]], |
| 293 |
width: 2, |
| 294 |
}); |
| 295 |
|
| 296 |
const engine = new World(new Scheduler(), map, commandManagerMock, entityFactoryMock); |
| 297 |
|
| 298 |
const result = engine.getRandomFloorPosition(); |
| 299 |
const tile = engine.getMap().getTile(result); |
| 300 |
|
| 301 |
expect(tile).toBe(floorTile); |
| 302 |
}); |
| 303 |
|
| 304 |
it("should be called again if target is not empty", (): void => { |
| 305 |
const floorTile = new FloorTile(); |
| 306 |
const wallTile = new WallTile(); |
| 307 |
|
| 308 |
const mockMapR: GameMap = mock(GameMap); |
| 309 |
when(mockMapR.getTiles()).thenReturn([[wallTile, wallTile, floorTile]]); |
| 310 |
when(mockMapR.getTile(anything())).thenReturn(wallTile).thenReturn(floorTile); |
| 311 |
when(mockMapR.getHeight()).thenReturn(1); |
| 312 |
when(mockMapR.getWidth()).thenReturn(3); |
| 313 |
|
| 314 |
const gameMapMockR: GameMap = instance(mockMapR); |
| 315 |
|
| 316 |
const engine = new World(new Scheduler(), gameMapMockR, commandManagerMock, entityFactoryMock); |
| 317 |
|
| 318 |
const result = engine.getRandomFloorPosition(); |
| 319 |
|
| 320 |
const tile = engine.getMap().getTile(result); |
| 321 |
|
| 322 |
expect(tile).toBe(floorTile); |
| 323 |
|
| 324 |
reset(mockMapR); |
| 325 |
}); |
| 326 |
}); |
| 327 |
}); |
| 328 |
|
|
|
|
/packages/games/glyphs/src/character.ts
|
0 problems
|
|
|
/packages/games/glyphs/src/floor.ts
|
0 problems
|
|
|
/packages/games/glyphs/src/glyph.ts
|
0 problems
|
|
|
/packages/games/glyphs/src/index.ts
|
0 problems
|
|
|
/packages/games/glyphs/src/wall.ts
|
0 problems
|
|
|
/packages/games/glyphs/tests/character.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/glyphs/tests/character.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { CharacterGlyph } from "@games-glyphs/index"; |
| 2 |
|
| 3 |
describe("CharacterGlyph", () => { |
| 4 |
it("should be instantiable", () => { |
| 5 |
const glyph = new CharacterGlyph(); |
| 6 |
expect(glyph).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
describe("constructor", () => { |
| 10 |
it("should set char", () => { |
| 11 |
const glyph = new CharacterGlyph(); |
| 12 |
expect(glyph.getChar()).toBe("@"); |
| 13 |
}); |
| 14 |
|
| 15 |
it("should set background", () => { |
| 16 |
const glyph = new CharacterGlyph(); |
| 17 |
expect(glyph.getBackground()).toBe("white"); |
| 18 |
}); |
| 19 |
|
| 20 |
it("should set foreground", () => { |
| 21 |
const glyph = new CharacterGlyph(); |
| 22 |
expect(glyph.getForeground()).toBe("black"); |
| 23 |
}); |
| 24 |
}); |
| 25 |
}); |
| 26 |
|
|
|
|
/packages/games/glyphs/tests/floor.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/glyphs/tests/floor.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { FloorGlyph } from "@games-glyphs/index"; |
| 2 |
|
| 3 |
describe("FloorGlyph", () => { |
| 4 |
it("should be instantiable", () => { |
| 5 |
const glyph = new FloorGlyph(); |
| 6 |
expect(glyph).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
describe("constructor", () => { |
| 10 |
it("should set char", () => { |
| 11 |
const glyph = new FloorGlyph(); |
| 12 |
expect(glyph.getChar()).toBe("."); |
| 13 |
}); |
| 14 |
|
| 15 |
it("should set background", () => { |
| 16 |
const glyph = new FloorGlyph(); |
| 17 |
expect(glyph.getBackground()).toBe("white"); |
| 18 |
}); |
| 19 |
|
| 20 |
it("should set foreground", () => { |
| 21 |
const glyph = new FloorGlyph(); |
| 22 |
expect(glyph.getForeground()).toBe("black"); |
| 23 |
}); |
| 24 |
}); |
| 25 |
}); |
| 26 |
|
|
|
|
/packages/games/glyphs/tests/glyph.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/glyphs/tests/glyph.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import each from "jest-each"; |
| 2 |
import { Glyph } from "@games-glyphs/index"; |
| 3 |
|
| 4 |
describe("Glyph", () => { |
| 5 |
it("should be instantiable", () => { |
| 6 |
const glyph = new Glyph(); |
| 7 |
expect(glyph).not.toBeNull(); |
| 8 |
}); |
| 9 |
|
| 10 |
describe("constructor", () => { |
| 11 |
each([ |
| 12 |
[[" ", "white", "black"], null], |
| 13 |
[ |
| 14 |
["@", "red", "blue"], |
| 15 |
["@", "red", "blue"], |
| 16 |
], |
| 17 |
]).test(" should init properties", (expected, params) => { |
| 18 |
let glyph = new Glyph(); |
| 19 |
|
| 20 |
if (null !== params) { |
| 21 |
glyph = new Glyph(params[0], params[1], params[2]); |
| 22 |
} |
| 23 |
|
| 24 |
expect(glyph.getChar()).toBe(expected[0]); |
| 25 |
expect(glyph.getBackground()).toBe(expected[1]); |
| 26 |
expect(glyph.getForeground()).toBe(expected[2]); |
| 27 |
}); |
| 28 |
}); |
| 29 |
|
| 30 |
it("should be able to retrieve char", () => { |
| 31 |
const expected = "@"; |
| 32 |
const glyph = new Glyph(expected); |
| 33 |
|
| 34 |
expect(glyph.getChar()).toBe(expected); |
| 35 |
}); |
| 36 |
|
| 37 |
it("should be able to retrieve background", () => { |
| 38 |
const expected = "black"; |
| 39 |
const glyph = new Glyph("", expected); |
| 40 |
|
| 41 |
expect(glyph.getBackground()).toBe(expected); |
| 42 |
}); |
| 43 |
|
| 44 |
it("should be able to retrieve foreground", () => { |
| 45 |
const expected = "white"; |
| 46 |
const glyph = new Glyph("", "black", expected); |
| 47 |
|
| 48 |
expect(glyph.getForeground()).toBe(expected); |
| 49 |
}); |
| 50 |
}); |
| 51 |
|
|
|
|
/packages/games/glyphs/tests/wall.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/glyphs/tests/wall.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { WallGlyph } from "@games-glyphs/index"; |
| 2 |
|
| 3 |
describe("WallGlyph", () => { |
| 4 |
it("should be instantiable", () => { |
| 5 |
const glyph = new WallGlyph(); |
| 6 |
expect(glyph).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
describe("constructor", () => { |
| 10 |
it("should set char", () => { |
| 11 |
const glyph = new WallGlyph(); |
| 12 |
expect(glyph.getChar()).toBe("#"); |
| 13 |
}); |
| 14 |
|
| 15 |
it("should set background", () => { |
| 16 |
const glyph = new WallGlyph(); |
| 17 |
expect(glyph.getBackground()).toBe("goldenrod"); |
| 18 |
}); |
| 19 |
|
| 20 |
it("should set foreground", () => { |
| 21 |
const glyph = new WallGlyph(); |
| 22 |
expect(glyph.getForeground()).toBe("black"); |
| 23 |
}); |
| 24 |
}); |
| 25 |
}); |
| 26 |
|
|
|
|
/packages/games/maps/src/enums.ts
|
0 problems
|
|
|
/packages/games/maps/src/generator-cellular.ts
|
0 problems
|
|
|
/packages/games/maps/src/index.ts
|
0 problems
|
|
|
/packages/games/maps/src/interfaces.ts
|
0 problems
|
|
|
/packages/games/maps/src/map.ts
|
0 problems
|
|
|
/packages/games/maps/tests/directions.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/maps/tests/directions.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Directions } from "@games-maps/index"; |
| 2 |
|
| 3 |
describe("Directions", () => { |
| 4 |
it("should return correct values", () => { |
| 5 |
expect(Directions.DOWN).toEqual("down"); |
| 6 |
expect(Directions.LEFT).toEqual("left"); |
| 7 |
expect(Directions.RIGHT).toEqual("right"); |
| 8 |
expect(Directions.UP).toEqual("up"); |
| 9 |
}); |
| 10 |
}); |
| 11 |
|
|
|
|
/packages/games/maps/tests/generator-cellular.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/maps/tests/generator-cellular.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { TileFactory, TileInterface } from "jga-games-tiles"; |
| 2 |
|
| 3 |
import { CellularMapGenerator } from "@games-maps/index"; |
| 4 |
|
| 5 |
const width = 80; |
| 6 |
const height = 60; |
| 7 |
const tileFactory: TileFactory = new TileFactory(); |
| 8 |
|
| 9 |
// eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 10 |
function instanceOfTileInterface(object: any): object is TileInterface { |
| 11 |
return "isDiggable" in object && "isWalkable" in object && "getGlyph" in object; |
| 12 |
} |
| 13 |
|
| 14 |
describe("CellularMapGenerator", (): void => { |
| 15 |
it("should be instantiable", (): void => { |
| 16 |
const generator = new CellularMapGenerator(width, height, tileFactory); |
| 17 |
expect(generator).not.toBeNull(); |
| 18 |
}); |
| 19 |
|
| 20 |
describe("generate", (): void => { |
| 21 |
it("should return tiles array", (): void => { |
| 22 |
const generator = new CellularMapGenerator(width, height, tileFactory); |
| 23 |
|
| 24 |
const result = generator.generate(); |
| 25 |
|
| 26 |
expect(Array.isArray(result)).toBeTruthy(); |
| 27 |
expect(result).toHaveLength(width); |
| 28 |
expect(result[0]).toHaveLength(height); |
| 29 |
expect(instanceOfTileInterface(result[0][0])).toBeTruthy(); |
| 30 |
}); |
| 31 |
}); |
| 32 |
}); |
| 33 |
|
|
|
|
/packages/games/maps/tests/map.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/maps/tests/map.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { instance, mock, reset, verify, when } from "ts-mockito"; |
| 2 |
|
| 3 |
import { FloorTile, NullTile, TileFactory, TileInterface, WallTile } from "jga-games-tiles"; |
| 4 |
|
| 5 |
import { GameMap, MapGeneratorInterface } from "@games-maps/index"; |
| 6 |
|
| 7 |
describe("GameMap", () => { |
| 8 |
const mockFactory: TileFactory = mock<TileFactory>(); |
| 9 |
const mockGenerator: MapGeneratorInterface = mock<MapGeneratorInterface>(); |
| 10 |
const nullTile: TileInterface = new NullTile(); |
| 11 |
|
| 12 |
let generatorMock: MapGeneratorInterface; |
| 13 |
let factoryMock: TileFactory; |
| 14 |
|
| 15 |
beforeEach(() => { |
| 16 |
generatorMock = instance(mockGenerator); |
| 17 |
|
| 18 |
when(mockFactory.create("null")).thenReturn(nullTile); |
| 19 |
factoryMock = instance(mockFactory); |
| 20 |
}); |
| 21 |
|
| 22 |
afterAll(() => { |
| 23 |
reset(mockFactory); |
| 24 |
reset(mockGenerator); |
| 25 |
}); |
| 26 |
|
| 27 |
describe("constructor", () => { |
| 28 |
it("should use generator if set and tiles are empty", () => { |
| 29 |
const map = new GameMap({ |
| 30 |
generator: generatorMock, |
| 31 |
height: 1, |
| 32 |
tileFactory: factoryMock, |
| 33 |
tiles: [], |
| 34 |
width: 1, |
| 35 |
}); |
| 36 |
|
| 37 |
verify(mockGenerator.generate()).once(); |
| 38 |
|
| 39 |
expect(map).not.toBeNull(); |
| 40 |
}); |
| 41 |
}); |
| 42 |
|
| 43 |
it("should be instantiable", () => { |
| 44 |
const map = new GameMap({ |
| 45 |
height: 1, |
| 46 |
tileFactory: factoryMock, |
| 47 |
width: 1, |
| 48 |
}); |
| 49 |
expect(map).not.toBeNull(); |
| 50 |
}); |
| 51 |
|
| 52 |
it("should be able to retrieve tiles", () => { |
| 53 |
const wallTile = new WallTile(); |
| 54 |
const expected: TileInterface[][] = [[wallTile, wallTile, wallTile, wallTile, wallTile]]; |
| 55 |
|
| 56 |
const map = new GameMap({ |
| 57 |
height: 1, |
| 58 |
tileFactory: factoryMock, |
| 59 |
tiles: expected, |
| 60 |
width: 5, |
| 61 |
}); |
| 62 |
|
| 63 |
expect(map.getTiles()).toStrictEqual(expected); |
| 64 |
}); |
| 65 |
|
| 66 |
it("should be able to retrieve tiles witdh", () => { |
| 67 |
const expected = 5; |
| 68 |
|
| 69 |
const map = new GameMap({ |
| 70 |
height: 1, |
| 71 |
tileFactory: factoryMock, |
| 72 |
width: 5, |
| 73 |
}); |
| 74 |
expect(map.getWidth()).toBe(expected); |
| 75 |
}); |
| 76 |
|
| 77 |
it("should be able to retrieve tiles height", () => { |
| 78 |
const expected = 5; |
| 79 |
|
| 80 |
const map = new GameMap({ |
| 81 |
height: expected, |
| 82 |
tileFactory: factoryMock, |
| 83 |
width: 1, |
| 84 |
}); |
| 85 |
expect(map.getHeight()).toBe(expected); |
| 86 |
}); |
| 87 |
|
| 88 |
describe("getTile", (): void => { |
| 89 |
it("should create null tile if there is none at position selected", (): void => { |
| 90 |
const map = new GameMap({ |
| 91 |
height: 1, |
| 92 |
tileFactory: factoryMock, |
| 93 |
width: 1, |
| 94 |
}); |
| 95 |
|
| 96 |
expect(map.getTile({ x: 10, y: 10 })).toBeInstanceOf(NullTile); |
| 97 |
}); |
| 98 |
}); |
| 99 |
|
| 100 |
describe("dig", (): void => { |
| 101 |
it("should change tile to floor if its diggable", (): void => { |
| 102 |
const mockTile = new WallTile(); |
| 103 |
|
| 104 |
const map = new GameMap({ |
| 105 |
height: 1, |
| 106 |
tileFactory: factoryMock, |
| 107 |
tiles: [[mockTile]], |
| 108 |
width: 1, |
| 109 |
}); |
| 110 |
map.dig({ x: 0, y: 0 }); |
| 111 |
|
| 112 |
expect(map.getTile({ x: 0, y: 0 })).toBeInstanceOf(FloorTile); |
| 113 |
}); |
| 114 |
|
| 115 |
it("should do nothing if tile is not diggable", (): void => { |
| 116 |
const mockTile = new FloorTile(); |
| 117 |
|
| 118 |
const map = new GameMap({ |
| 119 |
height: 1, |
| 120 |
tileFactory: factoryMock, |
| 121 |
tiles: [[mockTile]], |
| 122 |
width: 1, |
| 123 |
}); |
| 124 |
|
| 125 |
const originalTiles = map.getTiles(); |
| 126 |
|
| 127 |
map.dig({ x: 0, y: 0 }); |
| 128 |
|
| 129 |
expect(map.getTiles()).toStrictEqual(originalTiles); |
| 130 |
}); |
| 131 |
}); |
| 132 |
}); |
| 133 |
|
|
|
|
/packages/games/mc-api/src/app.controller.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/app.module.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/app.service.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/main.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/models/encounter.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/models/enums.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/models/hero.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/models/index.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/models/modular-set.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/models/pack.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/models/scenario.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/encounters/encounter.entity.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/encounters/encounters.module.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/heroes/hero.entity.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/heroes/heroes.module.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/heroes/heroes.service.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/modular-sets/modular-set.entity.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/modular-sets/modular-sets.module.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/modular-sets/modular-sets.service.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/scenarios/scenario.entity.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/scenarios/scenarios.module.ts
|
0 problems
|
|
|
/packages/games/mc-api/src/modules/scenarios/scenarios.service.ts
|
0 problems
|
|
|
/packages/games/mc/src/index.ts
|
7 problems (5 errors, 2 warnings)
|
| Line |
Source |
| 1 |
import { random } from "jga-algorithms-random"; |
| 2 |
|
| 3 |
import { |
| 4 |
DifficultyEnum, |
| 5 |
Encounter, |
| 6 |
Hero, |
| 7 |
HeroEnum, |
| 8 |
ModularSet, |
| 9 |
ModularSetEnum, |
| Warning |
Row 10, Column 5: "'ModuleEnum' is defined but never used."
@typescript-eslint/no-unused-vars
|
| 10 |
ModuleEnum, |
| 11 |
ResultEnum, |
| 12 |
Scenario, |
| 13 |
ScenarioEnum, |
| 14 |
} from "./@models"; |
| 15 |
import { EncountersService, HeroesService, ModularSetsService, ScenariosService } from "./services"; |
| 16 |
|
| 17 |
window.onload = async (): Promise<void> => { |
| 18 |
const body = document.querySelector("body") as HTMLBodyElement; |
| 19 |
const data: [Encounter[], Hero[], ModularSet[], Scenario[]] = await load(); |
| 20 |
|
| 21 |
const encounters: Encounter[] = data[0]; |
| 22 |
const heroes: Hero[] = data[1]; |
| 23 |
const modules: ModularSet[] = data[2]; |
| 24 |
const scenarios: Scenario[] = data[3]; |
| 25 |
|
| 26 |
loadRandomizer(body, encounters, heroes, scenarios, modules); |
| 27 |
loadEncounters(body, encounters); |
| 28 |
loadStats(body, encounters, heroes, scenarios); |
| 29 |
loadProgression(body, heroes, scenarios, encounters); |
| 30 |
loadProgressionEncounters(body, encounters, heroes, scenarios, modules); |
| 31 |
loadData(body, heroes, modules, scenarios); |
| 32 |
}; |
| 33 |
|
| 34 |
const load = async (): Promise<[Encounter[], Hero[], ModularSet[], Scenario[]]> => { |
| 35 |
// load json data |
| 36 |
const encountersService = new EncountersService(); |
| 37 |
const encounters = await encountersService.load(); |
| 38 |
|
| 39 |
const heroesService = new HeroesService(); |
| 40 |
const heroes = await heroesService.load(); |
| 41 |
|
| 42 |
const modulesService = new ModularSetsService(); |
| 43 |
const modules = await modulesService.load(); |
| 44 |
|
| 45 |
const scenariosService = new ScenariosService(); |
| 46 |
const scenarios = await scenariosService.load(); |
| 47 |
|
| 48 |
return [encounters, heroes, modules, scenarios]; |
| 49 |
}; |
| 50 |
|
| 51 |
const createTitle = (title: string, body: HTMLBodyElement) => { |
| 52 |
const header = document.createElement("h2"); |
| 53 |
header.innerText = title; |
| 54 |
|
| 55 |
body.appendChild(header); |
| 56 |
}; |
| 57 |
|
| 58 |
const createSubTitle = (title: string, body: HTMLBodyElement) => { |
| 59 |
const header = document.createElement("h3"); |
| 60 |
header.innerText = title; |
| 61 |
|
| 62 |
body.appendChild(header); |
| 63 |
}; |
| 64 |
|
| 65 |
const createSection = (title: string, data: Hero[] | Scenario[] | ModularSet[], body: HTMLBodyElement) => { |
| 66 |
createSubTitle(title, body); |
| 67 |
|
| 68 |
const section = document.createElement("section"); |
| 69 |
|
| 70 |
const list = document.createElement("ul"); |
| 71 |
|
| 72 |
data.forEach((item) => { |
| 73 |
const element = document.createElement("li"); |
| 74 |
element.innerText = `${item.name}`; |
| 75 |
|
| 76 |
list.appendChild(element); |
| 77 |
}); |
| 78 |
|
| 79 |
section.appendChild(list); |
| 80 |
|
| 81 |
body.appendChild(section); |
| 82 |
}; |
| 83 |
|
| 84 |
const createStatsTable = ( |
| 85 |
data: Map<string, number>, |
| 86 |
source: Hero[] | Scenario[], |
| 87 |
wins: Map<string, number>, |
| 88 |
body: HTMLBodyElement, |
| 89 |
) => { |
| 90 |
const table = document.createElement("table"); |
| 91 |
|
| 92 |
source.forEach((item) => { |
| 93 |
const itemLine = document.createElement("tr"); |
| 94 |
const itemName = document.createElement("td"); |
| 95 |
const itemCount = document.createElement("td"); |
| 96 |
const itemRate = document.createElement("td"); |
| 97 |
|
| 98 |
const gameNumber = (data.has(item.name) ? data.get(item.name) : 0) as number; |
| 99 |
const winRate = ( |
| 100 |
gameNumber !== 0 ? ((wins.has(item.name) ? wins.get(item.name) : 0) / gameNumber) * 100 : 0 |
| 101 |
) as number; |
| 102 |
|
| 103 |
itemName.innerText = item.name; |
| 104 |
itemCount.innerText = gameNumber.toString(); |
| 105 |
itemRate.innerText = ` (${winRate.toFixed(0).toString()} %) `; |
| 106 |
|
| 107 |
itemLine.appendChild(itemName); |
| 108 |
itemLine.appendChild(itemCount); |
| 109 |
itemLine.appendChild(itemRate); |
| 110 |
|
| 111 |
table.appendChild(itemLine); |
| 112 |
}); |
| 113 |
|
| 114 |
body.appendChild(table); |
| 115 |
}; |
| 116 |
|
| 117 |
const loadRandomizer = ( |
| 118 |
body: HTMLBodyElement, |
| 119 |
encounters: Encounter[], |
| 120 |
heroes: Hero[], |
| 121 |
scenarios: Scenario[], |
| 122 |
modules: ModularSet[], |
| Error |
Row 123, Column 3: "Refactor this function to reduce its Cognitive Complexity from 39 to the 15 allowed."
sonarjs/cognitive-complexity
|
| 123 |
) => { |
| 124 |
createTitle("Randomizer", body); |
| 125 |
|
| 126 |
const gamesHeroes = encounters |
| 127 |
.flatMap((encounter) => [encounter.hero1, encounter.hero2]) |
| 128 |
.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); |
| 129 |
|
| 130 |
const gamesModularSets = encounters |
| 131 |
.map((encounter) => encounter.module) |
| 132 |
.map((module) => module) |
| 133 |
.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); |
| 134 |
|
| 135 |
const gamesScenarios = encounters |
| 136 |
.map((encounter) => encounter.scenario) |
| 137 |
.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); |
| 138 |
|
| 139 |
const base = encounters.length * 5; |
| 140 |
|
| 141 |
const weightedScenarios: Scenario[] = []; |
| 142 |
const weightedModularSets: ModularSet[] = []; |
| 143 |
const weightedHeroes: Hero[] = []; |
| 144 |
|
| 145 |
scenarios.forEach((scenario) => { |
| 146 |
const pastOccurrences = gamesScenarios.has(scenario.name) ? gamesScenarios.get(scenario.name) : 0; |
| 147 |
|
| 148 |
for (let i = 0; i < base - pastOccurrences; i++) { |
| 149 |
weightedScenarios.push(scenario); |
| 150 |
} |
| 151 |
}); |
| 152 |
|
| 153 |
modules.forEach((module) => { |
| 154 |
const pastOccurrences = gamesModularSets.has(module.name) ? gamesModularSets.get(module.name) : 0; |
| 155 |
|
| 156 |
for (let i = 0; i < base - pastOccurrences; i++) { |
| 157 |
weightedModularSets.push(module); |
| 158 |
} |
| 159 |
}); |
| 160 |
|
| 161 |
heroes.forEach((hero) => { |
| 162 |
const pastOccurrences = gamesHeroes.has(hero.name) ? gamesHeroes.get(hero.name) : 0; |
| 163 |
|
| 164 |
for (let i = 0; i < base - pastOccurrences; i++) { |
| 165 |
weightedHeroes.push(hero); |
| 166 |
} |
| 167 |
}); |
| 168 |
|
| 169 |
createSubTitle("Scenario", body); |
| 170 |
const randomScenario = weightedScenarios[random(0, weightedScenarios.length - 1)]; |
| 171 |
const scenarioElement = document.createElement("select"); |
| 172 |
const scenarioOption = document.createElement("option"); |
| 173 |
|
| 174 |
scenarioElement.appendChild(scenarioOption); |
| 175 |
|
| 176 |
for (const item in ScenarioEnum) { |
| 177 |
const option = document.createElement("option"); |
| 178 |
option.value = ScenarioEnum[item]; |
| 179 |
option.innerText = ScenarioEnum[item]; |
| 180 |
|
| 181 |
if (randomScenario.name === ScenarioEnum[item]) { |
| 182 |
option.selected = true; |
| 183 |
} |
| 184 |
|
| 185 |
scenarioElement.appendChild(option); |
| 186 |
} |
| 187 |
body.appendChild(scenarioElement); |
| 188 |
|
| 189 |
createSubTitle("ModularSet", body); |
| 190 |
const randomModularSet = weightedModularSets[random(0, weightedModularSets.length - 1)]; |
| 191 |
const moduleElement = document.createElement("select"); |
| 192 |
const moduleOption = document.createElement("option"); |
| 193 |
|
| 194 |
moduleElement.appendChild(moduleOption); |
| 195 |
|
| 196 |
for (const item in ModularSetEnum) { |
| 197 |
const option = document.createElement("option"); |
| 198 |
option.value = ModularSetEnum[item]; |
| 199 |
option.innerText = ModularSetEnum[item]; |
| 200 |
|
| 201 |
if (randomModularSet.name === ModularSetEnum[item]) { |
| 202 |
option.selected = true; |
| 203 |
} |
| 204 |
|
| 205 |
moduleElement.appendChild(option); |
| 206 |
} |
| 207 |
body.appendChild(moduleElement); |
| 208 |
|
| 209 |
createSubTitle("Hero1", body); |
| 210 |
const randomHero1 = weightedHeroes[random(0, weightedHeroes.length - 1)]; |
| 211 |
const hero1Element = document.createElement("select"); |
| 212 |
const hero1Option = document.createElement("option"); |
| 213 |
|
| 214 |
hero1Element.appendChild(hero1Option); |
| 215 |
|
| 216 |
for (const item in HeroEnum) { |
| 217 |
const option = document.createElement("option"); |
| 218 |
option.value = HeroEnum[item]; |
| 219 |
option.innerText = HeroEnum[item]; |
| 220 |
|
| 221 |
if (randomHero1.name === HeroEnum[item]) { |
| 222 |
option.selected = true; |
| 223 |
} |
| 224 |
|
| 225 |
hero1Element.appendChild(option); |
| 226 |
} |
| 227 |
body.appendChild(hero1Element); |
| 228 |
|
| 229 |
createSubTitle("Hero2", body); |
| 230 |
const randomHero2 = weightedHeroes[random(0, weightedHeroes.length - 1)]; |
| 231 |
const hero2Element = document.createElement("select"); |
| 232 |
const hero2Option = document.createElement("option"); |
| 233 |
|
| 234 |
hero2Element.appendChild(hero2Option); |
| 235 |
|
| 236 |
for (const item in HeroEnum) { |
| 237 |
const option = document.createElement("option"); |
| 238 |
option.value = HeroEnum[item]; |
| 239 |
option.innerText = HeroEnum[item]; |
| 240 |
|
| 241 |
if (randomHero2.name === HeroEnum[item]) { |
| 242 |
option.selected = true; |
| 243 |
} |
| 244 |
|
| 245 |
hero2Element.appendChild(option); |
| 246 |
} |
| 247 |
|
| 248 |
body.appendChild(hero2Element); |
| 249 |
|
| 250 |
createSubTitle("Hero3", body); |
| 251 |
const hero3Element = document.createElement("select"); |
| 252 |
const hero3Option = document.createElement("option"); |
| 253 |
|
| 254 |
hero3Element.appendChild(hero3Option); |
| 255 |
|
| 256 |
for (const item in HeroEnum) { |
| 257 |
const option = document.createElement("option"); |
| 258 |
option.value = HeroEnum[item]; |
| 259 |
option.innerText = HeroEnum[item]; |
| 260 |
|
| 261 |
hero3Element.appendChild(option); |
| 262 |
} |
| 263 |
|
| 264 |
body.appendChild(hero3Element); |
| 265 |
|
| 266 |
createSubTitle("Hero4", body); |
| 267 |
|
| 268 |
const hero4Element = document.createElement("select"); |
| 269 |
const hero4Option = document.createElement("option"); |
| 270 |
|
| 271 |
hero4Element.appendChild(hero4Option); |
| 272 |
|
| 273 |
for (const item in HeroEnum) { |
| 274 |
const option = document.createElement("option"); |
| 275 |
option.value = HeroEnum[item]; |
| 276 |
option.innerText = HeroEnum[item]; |
| 277 |
|
| 278 |
hero4Element.appendChild(option); |
| 279 |
} |
| 280 |
|
| 281 |
body.appendChild(hero4Element); |
| 282 |
|
| 283 |
createSubTitle("Difficulty", body); |
| 284 |
const difficultyElement = document.createElement("select"); |
| 285 |
const difficultyOption = document.createElement("option"); |
| 286 |
|
| 287 |
difficultyElement.appendChild(difficultyOption); |
| 288 |
|
| 289 |
for (const item in DifficultyEnum) { |
| 290 |
const option = document.createElement("option"); |
| 291 |
option.value = DifficultyEnum[item]; |
| 292 |
option.innerText = DifficultyEnum[item]; |
| 293 |
|
| 294 |
if (DifficultyEnum[item] === DifficultyEnum.STANDARD) { |
| 295 |
option.selected = true; |
| 296 |
} |
| 297 |
|
| 298 |
difficultyElement.appendChild(option); |
| 299 |
} |
| 300 |
|
| 301 |
body.appendChild(difficultyElement); |
| 302 |
|
| 303 |
createSubTitle("Result", body); |
| 304 |
const resultElement = document.createElement("select"); |
| 305 |
const option = document.createElement("option"); |
| 306 |
|
| 307 |
resultElement.appendChild(option); |
| 308 |
|
| 309 |
for (const item in ResultEnum) { |
| 310 |
const option = document.createElement("option"); |
| 311 |
option.value = ResultEnum[item]; |
| 312 |
option.innerText = ResultEnum[item]; |
| 313 |
|
| 314 |
resultElement.appendChild(option); |
| 315 |
} |
| 316 |
|
| 317 |
body.appendChild(resultElement); |
| 318 |
|
| 319 |
createSubTitle("Add", body); |
| 320 |
const button = document.createElement("button"); |
| 321 |
button.type = "button"; |
| 322 |
button.innerText = "Add encounter !"; |
| 323 |
button.onclick = () => { |
| 324 |
const encounter = new Encounter({ |
| 325 |
id: null, |
| 326 |
scenario: scenarioElement.value, |
| 327 |
module: moduleElement.value, |
| 328 |
hero1: hero1Element.value, |
| 329 |
hero2: hero2Element.value !== "" ? hero2Element.value : null, |
| 330 |
hero3: hero3Element.value !== "" ? hero3Element.value : null, |
| 331 |
hero4: hero4Element.value !== "" ? hero4Element.value : null, |
| 332 |
difficulty: difficultyElement.value, |
| 333 |
result: resultElement.value, |
| 334 |
}); |
| 335 |
|
| 336 |
console.log(encounter); |
| 337 |
|
| 338 |
const encountersService = new EncountersService(); |
| 339 |
encountersService.save(encounter).then((result) => { |
| 340 |
console.log(result); |
| 341 |
|
| 342 |
window.location.reload(); |
| 343 |
}); |
| 344 |
}; |
| 345 |
|
| 346 |
body.appendChild(button); |
| 347 |
}; |
| 348 |
|
| 349 |
const loadEncounters = (body: HTMLBodyElement, encounters: Encounter[]) => { |
| 350 |
createTitle("Encounters", body); |
| 351 |
|
| 352 |
const table = document.createElement("table"); |
| 353 |
|
| 354 |
const firstRow = document.createElement("tr"); |
| 355 |
|
| 356 |
const scenario = document.createElement("th"); |
| 357 |
scenario.innerText = "Scenario"; |
| 358 |
|
| 359 |
const module = document.createElement("th"); |
| 360 |
module.innerText = "ModularSet"; |
| 361 |
|
| 362 |
const difficulty = document.createElement("th"); |
| 363 |
difficulty.innerText = "Difficulty"; |
| 364 |
|
| 365 |
const hero1 = document.createElement("th"); |
| 366 |
hero1.innerText = "Hero 1"; |
| 367 |
|
| 368 |
const hero2 = document.createElement("th"); |
| 369 |
hero2.innerText = "Hero 2"; |
| 370 |
|
| 371 |
const hero3 = document.createElement("th"); |
| 372 |
hero3.innerText = "Hero 3"; |
| 373 |
|
| 374 |
const hero4 = document.createElement("th"); |
| 375 |
hero4.innerText = "Hero 4"; |
| 376 |
|
| 377 |
const result = document.createElement("th"); |
| 378 |
result.innerText = "Result"; |
| 379 |
|
| 380 |
firstRow.appendChild(scenario); |
| 381 |
firstRow.appendChild(module); |
| 382 |
firstRow.appendChild(difficulty); |
| 383 |
firstRow.appendChild(hero1); |
| 384 |
firstRow.appendChild(hero2); |
| 385 |
firstRow.appendChild(hero3); |
| 386 |
firstRow.appendChild(hero4); |
| 387 |
firstRow.appendChild(result); |
| 388 |
|
| 389 |
table.appendChild(firstRow); |
| 390 |
|
| 391 |
// load encounters |
| 392 |
encounters.forEach((encounter) => { |
| 393 |
const row = document.createElement("tr"); |
| 394 |
|
| 395 |
const scenario = document.createElement("td"); |
| 396 |
scenario.innerText = encounter.scenario as string; |
| 397 |
|
| 398 |
const module = document.createElement("td"); |
| 399 |
module.innerText = encounter.module as string; |
| 400 |
|
| 401 |
const difficulty = document.createElement("td"); |
| 402 |
difficulty.innerText = encounter.difficulty; |
| 403 |
|
| 404 |
const hero1 = document.createElement("td"); |
| 405 |
hero1.innerText = encounter.hero1 as string; |
| 406 |
|
| 407 |
const hero2 = document.createElement("td"); |
| 408 |
hero2.innerText = encounter.hero2 || ("" as string); |
| 409 |
|
| 410 |
const hero3 = document.createElement("td"); |
| 411 |
hero3.innerText = encounter.hero3 || ("" as string); |
| 412 |
|
| 413 |
const hero4 = document.createElement("td"); |
| 414 |
hero4.innerText = encounter.hero4 || ("" as string); |
| 415 |
|
| 416 |
const result = document.createElement("td"); |
| 417 |
result.innerText = encounter.result; |
| 418 |
|
| 419 |
row.appendChild(scenario); |
| 420 |
row.appendChild(module); |
| 421 |
row.appendChild(difficulty); |
| 422 |
row.appendChild(hero1); |
| 423 |
row.appendChild(hero2); |
| 424 |
row.appendChild(hero3); |
| 425 |
row.appendChild(hero4); |
| 426 |
row.appendChild(result); |
| 427 |
|
| 428 |
table.appendChild(row); |
| 429 |
}); |
| 430 |
|
| 431 |
body.appendChild(table); |
| 432 |
}; |
| 433 |
|
| 434 |
const loadStats = (body: HTMLBodyElement, encounters: Encounter[], heroes: Hero[], scenarios: Scenario[]) => { |
| 435 |
createTitle("Stats", body); |
| 436 |
|
| 437 |
// games |
| 438 |
createSubTitle("Games", body); |
| 439 |
const games = document.createElement("div"); |
| 440 |
games.innerText = encounters.length.toString(); |
| 441 |
|
| 442 |
body.appendChild(games); |
| 443 |
|
| 444 |
// games by hero |
| 445 |
createSubTitle("Games / Heroes / Win %", body); |
| 446 |
const gamesHeroes = encounters |
| 447 |
.flatMap((encounter) => [encounter.hero1, encounter.hero2, encounter.hero3, encounter.hero4]) |
| 448 |
.map((hero) => hero) |
| 449 |
.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); |
| 450 |
|
| 451 |
const gamesHeroesWins = encounters |
| 452 |
.filter((encounter) => encounter.result === ResultEnum.WON) |
| 453 |
.flatMap((encounter) => [encounter.hero1, encounter.hero2, encounter.hero3, encounter.hero4]) |
| 454 |
.map((hero) => hero) |
| 455 |
.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); |
| 456 |
|
| 457 |
createStatsTable(gamesHeroes, heroes, gamesHeroesWins, body); |
| 458 |
|
| 459 |
// games by scenario |
| 460 |
createSubTitle("Games / Scenarios / Win %", body); |
| 461 |
const gamesScenarios = encounters |
| 462 |
.map((encounter) => encounter.scenario) |
| 463 |
.map((scenario) => scenario) |
| 464 |
.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); |
| 465 |
|
| 466 |
const gamesScenariosWins = encounters |
| 467 |
.filter((encounter) => encounter.result === ResultEnum.WON) |
| 468 |
.map((encounter) => encounter.scenario) |
| 469 |
.map((scenario) => scenario) |
| 470 |
.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); |
| 471 |
|
| 472 |
createStatsTable(gamesScenarios, scenarios, gamesScenariosWins, body); |
| 473 |
|
| 474 |
// number of heroes by games |
| 475 |
createSubTitle("Number of heroes / Games", body); |
| 476 |
const nbHeroesGames = encounters.reduce((acc, e) => { |
| 477 |
const nbHeroes = 1 + (null != e.hero2 ? 1 : 0) + (null != e.hero3 ? 1 : 0) + (null != e.hero4 ? 1 : 0); |
| 478 |
|
| 479 |
acc.set(nbHeroes, (acc.get(nbHeroes) || 0) + 1); |
| 480 |
|
| 481 |
return acc; |
| 482 |
}, new Map()); |
| 483 |
|
| 484 |
const tableHeroesGames = document.createElement("table"); |
| 485 |
|
| 486 |
new Map([...nbHeroesGames].sort()).forEach((value, key) => { |
| 487 |
const itemLine = document.createElement("tr"); |
| 488 |
const itemName = document.createElement("td"); |
| 489 |
const itemCount = document.createElement("td"); |
| 490 |
|
| 491 |
itemName.innerText = key; |
| 492 |
itemCount.innerText = `${value} (${((value / encounters.length) * 100).toFixed(0)} %)`; |
| 493 |
|
| 494 |
itemLine.appendChild(itemName); |
| 495 |
itemLine.appendChild(itemCount); |
| 496 |
|
| 497 |
tableHeroesGames.appendChild(itemLine); |
| 498 |
}); |
| 499 |
|
| 500 |
body.appendChild(tableHeroesGames); |
| 501 |
|
| 502 |
// results |
| 503 |
createSubTitle("Results", body); |
| 504 |
const gamesResults = encounters |
| 505 |
.map((encounter) => encounter.result) |
| 506 |
.sort() |
| 507 |
.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map()); |
| 508 |
|
| 509 |
const tableResults = document.createElement("table"); |
| 510 |
|
| 511 |
gamesResults.forEach((value, key) => { |
| 512 |
const itemLine = document.createElement("tr"); |
| 513 |
const itemName = document.createElement("td"); |
| 514 |
const itemCount = document.createElement("td"); |
| 515 |
|
| 516 |
itemName.innerText = key; |
| 517 |
itemCount.innerText = |
| 518 |
key === ResultEnum.WON ? `${value} (${((value / encounters.length) * 100).toFixed(0)} %)` : value; |
| 519 |
|
| 520 |
itemLine.appendChild(itemName); |
| 521 |
itemLine.appendChild(itemCount); |
| 522 |
|
| 523 |
tableResults.appendChild(itemLine); |
| 524 |
}); |
| 525 |
|
| 526 |
body.appendChild(tableResults); |
| 527 |
}; |
| 528 |
|
| 529 |
const loadProgression = (body: HTMLBodyElement, heroes: Hero[], scenarios: Scenario[], encounters: Encounter[]) => { |
| 530 |
createTitle("Progression", body); |
| 531 |
|
| 532 |
const table = document.createElement("table"); |
| 533 |
|
| 534 |
const progressionTargets = new Map<string, number>(); |
| 535 |
|
| 536 |
// first row |
| 537 |
const firstRow = document.createElement("tr"); |
| 538 |
firstRow.appendChild(document.createElement("td")); |
| 539 |
|
| 540 |
// load scenarios |
| 541 |
scenarios.forEach((scenario) => { |
| 542 |
const td = document.createElement("th"); |
| 543 |
td.innerText = scenario.name; |
| 544 |
|
| 545 |
progressionTargets.set(scenario.name, 0); |
| 546 |
|
| 547 |
firstRow.append(td); |
| 548 |
}); |
| 549 |
|
| 550 |
table.appendChild(firstRow); |
| 551 |
|
| 552 |
const encountersHeroes = encounters |
| 553 |
.filter((encounter) => encounter.result === "Won") |
| 554 |
.reduce((acc, e) => { |
| 555 |
if (!acc.has(e.hero1)) { |
| 556 |
acc.set(e.hero1, new Set()); |
| 557 |
} |
| 558 |
if (!acc.has(e.hero2)) { |
| 559 |
acc.set(e.hero2, new Set()); |
| 560 |
} |
| 561 |
if (!acc.has(e.hero3)) { |
| 562 |
acc.set(e.hero3, new Set()); |
| 563 |
} |
| 564 |
if (!acc.has(e.hero4)) { |
| 565 |
acc.set(e.hero4, new Set()); |
| 566 |
} |
| 567 |
|
| 568 |
acc.get(e.hero1).add(e.scenario); |
| 569 |
acc.get(e.hero2).add(e.scenario); |
| 570 |
acc.get(e.hero3).add(e.scenario); |
| 571 |
acc.get(e.hero4).add(e.scenario); |
| 572 |
|
| 573 |
return acc; |
| 574 |
}, new Map()); |
| 575 |
|
| 576 |
// load heroes |
| 577 |
heroes.forEach((hero) => { |
| 578 |
const row = document.createElement("tr"); |
| 579 |
|
| 580 |
const firstCol = document.createElement("th"); |
| 581 |
firstCol.innerText = hero.name; |
| 582 |
|
| 583 |
row.appendChild(firstCol); |
| 584 |
|
| 585 |
scenarios.forEach((scenario) => { |
| 586 |
const td = document.createElement("td"); |
| 587 |
|
| 588 |
const heroEncounter = encountersHeroes.get(hero.name); |
| 589 |
if (null != heroEncounter && heroEncounter.has(scenario.name)) { |
| 590 |
td.innerText = "✓"; |
| 591 |
if (progressionTargets.has(scenario.name)) { |
| 592 |
progressionTargets.set(scenario.name, progressionTargets.get(scenario.name) + 1); |
| 593 |
} |
| 594 |
} |
| 595 |
|
| 596 |
row.append(td); |
| 597 |
}); |
| 598 |
|
| 599 |
table.appendChild(row); |
| 600 |
}); |
| 601 |
|
| 602 |
// Show Progression |
| 603 |
const progressionRow = document.createElement("tr"); |
| 604 |
progressionRow.appendChild(document.createElement("td")); |
| 605 |
|
| 606 |
scenarios.forEach((scenario) => { |
| 607 |
const progressionTh = document.createElement("th"); |
| 608 |
|
| 609 |
const progession = ((progressionTargets.get(scenario.name) / heroes.length) * 100).toFixed(0); |
| 610 |
|
| 611 |
progressionTh.innerText = `${progession} %`; |
| 612 |
|
| 613 |
progressionRow.appendChild(progressionTh); |
| 614 |
}); |
| 615 |
|
| 616 |
table.appendChild(progressionRow); |
| 617 |
|
| 618 |
body.appendChild(table); |
| 619 |
}; |
| 620 |
|
| 621 |
const loadData = (body: HTMLBodyElement, heroes: Hero[], modules: ModularSet[], scenarios: Scenario[]) => { |
| 622 |
createTitle("Data", body); |
| 623 |
|
| 624 |
// display heroes |
| 625 |
const heroesData = heroes.map((hero) => { |
| 626 |
hero.name = `${hero.name} (${hero.aspects.join("/")})`; |
| 627 |
|
| 628 |
return hero; |
| 629 |
}); |
| 630 |
createSection("Heroes", heroesData, body); |
| 631 |
// display Scenarios |
| 632 |
createSection("Scenarios", scenarios, body); |
| 633 |
// display Modular sets |
| 634 |
createSection("Modular Encounter Sets", modules, body); |
| 635 |
}; |
| 636 |
|
| 637 |
const loadProgressionEncounters = ( |
| 638 |
body: HTMLBodyElement, |
| 639 |
encounters: Encounter[], |
| 640 |
heroes: Hero[], |
| 641 |
scenarios: Scenario[], |
| Warning |
Row 642, Column 5: "'modules' is defined but never used."
@typescript-eslint/no-unused-vars
|
| 642 |
modules: ModularSet[], |
| 643 |
) => { |
| 644 |
const scenariosWinEncounters = encounters |
| 645 |
.filter((encounter) => encounter.result === ResultEnum.WON) |
| 646 |
.reduce((acc, e) => { |
| 647 |
if (!acc.has(e.scenario)) { |
| 648 |
acc.set(e.scenario, []); |
| 649 |
} |
| 650 |
|
| 651 |
const newHeroes = acc.get(e.scenario); |
| 652 |
[e] |
| 653 |
.flatMap((encounter) => [encounter.hero1, encounter.hero2, encounter.hero3, encounter.hero4]) |
| 654 |
.filter((hero) => null !== hero) |
| 655 |
.filter((hero, i, array) => array.indexOf(hero) === i) |
| 656 |
.forEach((hero) => newHeroes.push(hero)); |
| 657 |
|
| 658 |
acc.set(e.scenario, newHeroes.sort()); |
| 659 |
|
| 660 |
return acc; |
| 661 |
}, new Map()); |
| 662 |
|
| 663 |
const scenariosLostEncounters = encounters |
| 664 |
.filter((encounter) => encounter.result !== ResultEnum.WON) |
| 665 |
.reduce((acc, e) => { |
| 666 |
if (!acc.has(e.scenario)) { |
| 667 |
acc.set(e.scenario, []); |
| 668 |
} |
| 669 |
|
| 670 |
const lostHeroes = acc.get(e.scenario); |
| 671 |
[e] |
| 672 |
.flatMap((encounter) => [encounter.hero1, encounter.hero2, encounter.hero3, encounter.hero4]) |
| 673 |
.filter((hero) => null !== hero) |
| 674 |
.filter((hero, i, array) => array.indexOf(hero) === i) |
| 675 |
.forEach((hero) => { |
| 676 |
if ( |
| 677 |
!scenariosWinEncounters.has(e.scenario) || |
| 678 |
!scenariosWinEncounters.get(e.scenario).includes(hero) |
| 679 |
) { |
| 680 |
lostHeroes.push(hero); |
| 681 |
} |
| 682 |
}); |
| 683 |
|
| 684 |
acc.set(e.scenario, lostHeroes.sort()); |
| 685 |
|
| 686 |
return acc; |
| 687 |
}, new Map()); |
| 688 |
|
| 689 |
const progressionsEncounters: Map<Scenario, Partial<Encounter>[]> = new Map(); |
| 690 |
scenarios.forEach((scenario) => { |
| 691 |
heroes.forEach((hero) => { |
| 692 |
if ( |
| 693 |
!scenariosWinEncounters.has(scenario.name) || |
| 694 |
!scenariosWinEncounters.get(scenario.name).includes(hero.name) |
| 695 |
) { |
| 696 |
if (!progressionsEncounters.has(scenario)) { |
| 697 |
progressionsEncounters.set(scenario, []); |
| 698 |
} |
| 699 |
|
| 700 |
const tryHeroes = progressionsEncounters.get(scenario) as Partial<Encounter>[]; |
| 701 |
tryHeroes.push({ |
| 702 |
scenario: scenario.name as ScenarioEnum, |
| Error |
Row 703, Column 28: "Insert `⏎·······················`"
prettier/prettier
|
| 703 |
module: null !== scenario.defaultModularSets ? scenario.defaultModularSets[0] : ModularSetEnum.STANDARD, // TODO enable multiple modules |
| 704 |
difficulty: DifficultyEnum.STANDARD, |
| 705 |
hero1: hero.name, |
| 706 |
}); |
| 707 |
|
| 708 |
progressionsEncounters.set(scenario, tryHeroes); |
| 709 |
} |
| 710 |
}); |
| 711 |
}); |
| 712 |
|
| Error |
Row 713, Column 5: "console.table() is not supported in IE 9"
compat/compat
|
| 713 |
console.table(scenariosLostEncounters); |
| Error |
Row 714, Column 5: "console.table() is not supported in IE 9"
compat/compat
|
| 714 |
console.table(scenariosWinEncounters); |
| Error |
Row 715, Column 5: "console.table() is not supported in IE 9"
compat/compat
|
| 715 |
console.table(progressionsEncounters); |
| 716 |
|
| 717 |
createTitle("Suggested encounters", body); |
| 718 |
|
| 719 |
const table = document.createElement("table"); |
| 720 |
const firstRow = document.createElement("tr"); |
| 721 |
const scenario = document.createElement("th"); |
| 722 |
scenario.innerText = "Scenario"; |
| 723 |
const module = document.createElement("th"); |
| 724 |
module.innerText = "ModularSet"; |
| 725 |
const difficulty = document.createElement("th"); |
| 726 |
difficulty.innerText = "Difficulty"; |
| 727 |
const hero1 = document.createElement("th"); |
| 728 |
hero1.innerText = "Hero 1"; |
| 729 |
|
| 730 |
firstRow.appendChild(scenario); |
| 731 |
firstRow.appendChild(module); |
| 732 |
firstRow.appendChild(difficulty); |
| 733 |
firstRow.appendChild(hero1); |
| 734 |
|
| 735 |
table.appendChild(firstRow); |
| 736 |
|
| 737 |
// load encounters |
| 738 |
progressionsEncounters.forEach((scenario) => { |
| 739 |
scenario.forEach((encounter) => { |
| 740 |
const row = document.createElement("tr"); |
| 741 |
|
| 742 |
const scenario = document.createElement("td"); |
| 743 |
scenario.innerText = encounter.scenario as string; |
| 744 |
|
| 745 |
const module = document.createElement("td"); |
| 746 |
module.innerText = encounter.module as string; |
| 747 |
|
| 748 |
const difficulty = document.createElement("td"); |
| 749 |
difficulty.innerText = encounter.difficulty; |
| 750 |
|
| 751 |
const hero1 = document.createElement("td"); |
| 752 |
hero1.innerText = encounter.hero1 as string; |
| 753 |
|
| 754 |
row.appendChild(scenario); |
| 755 |
row.appendChild(module); |
| 756 |
row.appendChild(difficulty); |
| 757 |
row.appendChild(hero1); |
| 758 |
|
| 759 |
table.appendChild(row); |
| 760 |
}); |
| 761 |
}); |
| 762 |
|
| 763 |
body.appendChild(table); |
| 764 |
|
| 765 |
// console.table(scenariosWinEncounters); |
| 766 |
// console.table(progressionsEncounters); |
| 767 |
// console.table(scenariosWinEncounters); |
| 768 |
// console.table(scenariosLostEncounters); |
| 769 |
}; |
| 770 |
|
|
|
|
/packages/games/mc/src/services/encounters.ts
|
0 problems
|
|
|
/packages/games/mc/src/services/heroes.ts
|
0 problems
|
|
|
/packages/games/mc/src/services/index.ts
|
0 problems
|
|
|
/packages/games/mc/src/services/modular-sets.ts
|
0 problems
|
|
|
/packages/games/mc/src/services/packs.ts
|
0 problems
|
|
|
/packages/games/mc/src/services/scenarios.ts
|
0 problems
|
|
|
/packages/games/opend6-dices/src/difficulty.ts
|
0 problems
|
|
|
/packages/games/opend6-dices/src/index.ts
|
0 problems
|
|
|
/packages/games/opend6-dices/src/roll.ts
|
0 problems
|
|
|
/packages/games/opend6-dices/tests/difficulty.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/opend6-dices/tests/difficulty.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { getDifficulty } from "@opend6-dices/index"; |
| 2 |
|
| 3 |
const difficultyVE = "Very Easy"; |
| 4 |
const difficultyE = "Easy"; |
| 5 |
const difficultyM = "Moderate"; |
| 6 |
const difficultyD = "Difficult"; |
| 7 |
const difficultyVD = "Very Difficult"; |
| 8 |
const difficultyH = "Heroic"; |
| 9 |
|
| 10 |
describe("Difficulty", () => { |
| 11 |
const difficulties = [ |
| 12 |
{ expected: { label: difficultyVE, dieCode: "1", meanResult: 1 }, target: 1 }, |
| 13 |
{ expected: { label: difficultyVE, dieCode: "2", meanResult: 2 }, target: 2 }, |
| 14 |
{ expected: { label: difficultyVE, dieCode: "3", meanResult: 3 }, target: 3 }, |
| 15 |
{ expected: { label: difficultyVE, dieCode: "1D", meanResult: 3.5 }, target: 4 }, |
| 16 |
{ expected: { label: difficultyVE, dieCode: "1D+1", meanResult: 4.5 }, target: 5 }, |
| 17 |
{ expected: { label: difficultyE, dieCode: "1D+2", meanResult: 5.5 }, target: 6 }, |
| 18 |
{ expected: { label: difficultyE, dieCode: "2D", meanResult: 7 }, target: 7 }, |
| 19 |
{ expected: { label: difficultyE, dieCode: "2D+1", meanResult: 8 }, target: 8 }, |
| 20 |
{ expected: { label: difficultyE, dieCode: "2D+2", meanResult: 9 }, target: 9 }, |
| 21 |
{ expected: { label: difficultyE, dieCode: "2D+3", meanResult: 10 }, target: 10 }, |
| 22 |
{ expected: { label: difficultyM, dieCode: "3D", meanResult: 10.5 }, target: 11 }, |
| 23 |
{ expected: { label: difficultyM, dieCode: "3D+1", meanResult: 11.5 }, target: 12 }, |
| 24 |
{ expected: { label: difficultyM, dieCode: "3D+2", meanResult: 12.5 }, target: 13 }, |
| 25 |
{ expected: { label: difficultyM, dieCode: "4D", meanResult: 14 }, target: 14 }, |
| 26 |
{ expected: { label: difficultyM, dieCode: "4D+1", meanResult: 15 }, target: 15 }, |
| 27 |
{ expected: { label: difficultyD, dieCode: "4D+2", meanResult: 16 }, target: 16 }, |
| 28 |
{ expected: { label: difficultyD, dieCode: "4D+3", meanResult: 17 }, target: 17 }, |
| 29 |
{ expected: { label: difficultyD, dieCode: "5D", meanResult: 17.5 }, target: 18 }, |
| 30 |
{ expected: { label: difficultyD, dieCode: "5D+1", meanResult: 18.5 }, target: 19 }, |
| 31 |
{ expected: { label: difficultyD, dieCode: "5D+2", meanResult: 19.5 }, target: 20 }, |
| 32 |
{ expected: { label: difficultyVD, dieCode: "6D", meanResult: 21 }, target: 21 }, |
| 33 |
{ expected: { label: difficultyVD, dieCode: "6D+1", meanResult: 22 }, target: 22 }, |
| 34 |
{ expected: { label: difficultyVD, dieCode: "6D+2", meanResult: 23 }, target: 23 }, |
| 35 |
{ expected: { label: difficultyVD, dieCode: "6D+3", meanResult: 24 }, target: 24 }, |
| 36 |
{ expected: { label: difficultyVD, dieCode: "7D", meanResult: 24.5 }, target: 25 }, |
| 37 |
{ expected: { label: difficultyH, dieCode: "7D+1", meanResult: 25.5 }, target: 26 }, |
| 38 |
{ expected: { label: difficultyH, dieCode: "7D+2", meanResult: 26.5 }, target: 27 }, |
| 39 |
{ expected: { label: difficultyH, dieCode: "8D", meanResult: 28 }, target: 28 }, |
| 40 |
{ expected: { label: difficultyH, dieCode: "8D+1", meanResult: 29 }, target: 29 }, |
| 41 |
{ expected: { label: difficultyH, dieCode: "8D+2", meanResult: 30 }, target: 30 }, |
| 42 |
]; |
| 43 |
|
| 44 |
difficulties.forEach((difficulty) => { |
| 45 |
it(`should return ${difficulty.expected} for ${difficulty.target}`, () => { |
| 46 |
const result = getDifficulty(difficulty.target); |
| 47 |
|
| 48 |
expect(result).toStrictEqual(difficulty.expected); |
| 49 |
}); |
| 50 |
}); |
| 51 |
}); |
| 52 |
|
|
|
|
/packages/games/opend6-dices/tests/roll.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/opend6-dices/tests/roll.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Roll } from "@opend6-dices/index"; |
| 2 |
import { Dice6 } from "jga-games-dices"; |
| 3 |
|
| 4 |
jest.mock("jga-games-dices/src/dice6"); |
| 5 |
|
| 6 |
beforeEach(() => { |
| 7 |
Dice6.prototype.roll = jest.fn().mockReturnValue(3); |
| 8 |
}); |
| 9 |
|
| 10 |
afterAll(() => { |
| 11 |
jest.fn().mockClear(); |
| 12 |
}); |
| 13 |
|
| 14 |
describe("Roll", () => { |
| 15 |
it("should be instantiable", () => { |
| 16 |
const roll = new Roll("d6"); |
| 17 |
expect(roll).not.toBeNull(); |
| 18 |
}); |
| 19 |
|
| 20 |
it("should be able to set and retrieve dice", () => { |
| 21 |
const dice = new Dice6(); |
| 22 |
|
| 23 |
const roll = new Roll("d6"); |
| 24 |
|
| 25 |
expect(JSON.stringify(roll.dice)).toBe(JSON.stringify(dice)); |
| 26 |
}); |
| 27 |
|
| 28 |
const rolls = [ |
| 29 |
{ verbose: "4d6", number: 4, sides: 6, modifier: 0, expected: 12 }, |
| 30 |
{ verbose: "4d6+5", number: 4, sides: 6, modifier: 5, expected: 17 }, |
| 31 |
{ verbose: "4D6+5", number: 4, sides: 6, modifier: 5, expected: 17 }, |
| 32 |
{ |
| 33 |
expected: 9, |
| 34 |
modifier: -3, |
| 35 |
number: 4, |
| 36 |
sides: 6, |
| 37 |
verbose: "4d6-3", |
| 38 |
}, |
| 39 |
{ verbose: "d6-3", number: 1, sides: 6, modifier: -3, expected: 1 }, |
| 40 |
{ |
| 41 |
expected: 3, |
| 42 |
modifier: 0, |
| 43 |
number: 1, |
| 44 |
sides: 6, |
| 45 |
verbose: "unrecognized", |
| 46 |
}, |
| 47 |
{ |
| 48 |
expected: 3, |
| 49 |
modifier: 0, |
| 50 |
number: 1, |
| 51 |
sides: 6, |
| 52 |
verbose: null, |
| 53 |
}, |
| 54 |
{ |
| 55 |
expected: 3, |
| 56 |
modifier: 0, |
| 57 |
number: 1, |
| 58 |
sides: 6, |
| 59 |
verbose: "", |
| 60 |
}, |
| 61 |
]; |
| 62 |
|
| 63 |
rolls.forEach((scenario) => { |
| 64 |
it("should be correctly initialized", () => { |
| 65 |
const roll = new Roll(scenario.verbose); |
| 66 |
|
| 67 |
expect(roll.diceSides).toBe(scenario.sides); |
| 68 |
expect(roll.diceNumber).toBe(scenario.number); |
| 69 |
expect(roll.modifier).toBe(scenario.modifier); |
| 70 |
}); |
| 71 |
}); |
| 72 |
|
| 73 |
rolls.forEach((scenario) => { |
| 74 |
it("should have a result of " + scenario.expected, () => { |
| 75 |
const roll = new Roll(scenario.verbose); |
| 76 |
|
| 77 |
const result = roll.getResult(); |
| 78 |
|
| 79 |
// eslint-disable-next-line jest/no-conditional-expect |
| 80 |
expect(result).toBe(scenario.expected); |
| 81 |
}); |
| 82 |
}); |
| 83 |
|
| 84 |
const resolves = [ |
| 85 |
{ result: 4, target: 5, expected: false }, |
| 86 |
{ result: 4, target: 4, expected: true }, |
| 87 |
{ result: 4, target: 3, expected: true }, |
| 88 |
]; |
| 89 |
|
| 90 |
resolves.forEach((scenario) => { |
| 91 |
it("should be able to resolve", () => { |
| 92 |
Dice6.prototype.roll = jest.fn().mockReturnValue(scenario.result); |
| 93 |
|
| 94 |
const roll = new Roll("d6"); |
| 95 |
expect(roll.resolve(scenario.target)).toBe(scenario.expected); |
| 96 |
}); |
| 97 |
}); |
| 98 |
|
| 99 |
it("should be a critical failure is wild die return 1 and result should be 1", () => { |
| 100 |
Dice6.prototype.roll = jest.fn().mockReturnValue(1); |
| 101 |
|
| 102 |
const roll = new Roll("d6"); |
| 103 |
|
| 104 |
const result = roll.getResult(); |
| 105 |
const failure = roll.isCriticalFailure(); |
| 106 |
const success = roll.isCriticalSuccess(); |
| 107 |
|
| 108 |
expect(result).toBe(Roll.CRITICAL_FAILURE); |
| 109 |
expect(failure).toBeTruthy(); |
| 110 |
expect(success).toBeFalsy(); |
| 111 |
}); |
| 112 |
|
| 113 |
it("should be a critical success is wild die return 6 and result should be greater than 6", () => { |
| 114 |
Dice6.prototype.roll = jest.fn().mockReturnValueOnce(6).mockReturnValue(3); |
| 115 |
|
| 116 |
const roll = new Roll("d6"); |
| 117 |
|
| 118 |
const result = roll.getResult(); |
| 119 |
const failure = roll.isCriticalFailure(); |
| 120 |
const success = roll.isCriticalSuccess(); |
| 121 |
|
| 122 |
expect(result).toBeGreaterThanOrEqual(Roll.CRITICAL_SUCCESS); |
| 123 |
expect(failure).toBeFalsy(); |
| 124 |
expect(success).toBeTruthy(); |
| 125 |
}); |
| 126 |
|
| 127 |
it("should always return a result greater or equal to 1", () => { |
| 128 |
const roll = new Roll("d6"); |
| 129 |
|
| 130 |
const prototypeBackup = Dice6.prototype.roll; |
| 131 |
|
| 132 |
Dice6.prototype.roll = jest.fn().mockReturnValue(0); |
| 133 |
|
| 134 |
expect(roll.getResult()).toEqual(1); |
| 135 |
|
| 136 |
Dice6.prototype.roll = prototypeBackup; |
| 137 |
}); |
| 138 |
}); |
| 139 |
|
|
|
|
/packages/games/roguelike/src/game/commands/index.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/commands/move.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/commands/roll.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/engine/entitites/factory.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/engine/entitites/fungus.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/engine/entitites/index.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/engine/index.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/game.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/index.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/screens/factory.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/screens/index.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/screens/lose.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/screens/play.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/screens/start.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/game/screens/win.ts
|
0 problems
|
|
|
/packages/games/roguelike/src/index.ts
|
0 problems
|
|
|
/packages/games/roguelike/tests/commands/move.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/commands/move.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { anything, instance, mock, reset, when } from "ts-mockito"; |
| 2 |
|
| 3 |
import { Actor, ComponentName, Engine, Entity } from "jga-games-engine"; |
| 4 |
import { GlyphInterface } from "jga-games-glyphs"; |
| 5 |
import { Directions, GameMap, PositionInterface } from "jga-games-maps"; |
| 6 |
import { TileInterface } from "jga-games-tiles"; |
| 7 |
import { Component } from "jga-patterns-ecs"; |
| 8 |
|
| 9 |
import { MoveCommand } from "@roguelike/index"; |
| 10 |
|
| 11 |
describe("Move Command", () => { |
| 12 |
let glyphMock: GlyphInterface; |
| 13 |
let tileMock: TileInterface; |
| 14 |
let gameMapMock: GameMap; |
| 15 |
let engineMock: Engine; |
| 16 |
let playerMock: Actor; |
| 17 |
let componentMock: Component; |
| 18 |
|
| 19 |
const mockGlyph: GlyphInterface = mock<GlyphInterface>(); |
| 20 |
const mockTile: TileInterface = mock<TileInterface>(); |
| 21 |
const mockGameMap: GameMap = mock<GameMap>(); |
| 22 |
const mockEngine: Engine = mock<Engine>(); |
| 23 |
const mockPlayer: Actor = mock<Actor>(); |
| 24 |
const mockComponent: Component = mock<Component>(); |
| 25 |
|
| 26 |
const initialPosition: PositionInterface = { x: 2, y: 2 }; |
| 27 |
|
| 28 |
beforeEach(() => { |
| 29 |
when(mockTile.getGlyph()).thenReturn(glyphMock); |
| 30 |
|
| 31 |
glyphMock = instance(mockGlyph); |
| 32 |
tileMock = instance(mockTile); |
| 33 |
|
| 34 |
when(mockComponent.getPosition()).thenReturn(initialPosition); |
| 35 |
componentMock = instance(mockComponent); |
| 36 |
|
| 37 |
when(mockPlayer.getComponent(ComponentName.POSITION)).thenReturn(componentMock); |
| 38 |
|
| 39 |
playerMock = instance(mockPlayer); |
| 40 |
|
| 41 |
when(mockGameMap.getTile(anything())).thenReturn(tileMock); |
| 42 |
when(mockGameMap.getWidth()).thenReturn(10); |
| 43 |
when(mockGameMap.getHeight()).thenReturn(10); |
| 44 |
|
| 45 |
gameMapMock = instance(mockGameMap); |
| 46 |
|
| 47 |
when(mockEngine.getPlayer()).thenReturn(playerMock); |
| 48 |
when(mockEngine.getMap()).thenReturn(gameMapMock); |
| 49 |
when(mockEngine.getEntities()).thenReturn(new Map<string, Entity>()); |
| 50 |
when(mockEngine.process(anything())).thenReturn(null); |
| 51 |
|
| 52 |
engineMock = instance(mockEngine); |
| 53 |
|
| 54 |
jest.clearAllMocks(); |
| 55 |
}); |
| 56 |
|
| 57 |
afterEach(() => { |
| 58 |
reset(mockGlyph); |
| 59 |
reset(mockTile); |
| 60 |
reset(mockComponent); |
| 61 |
reset(mockPlayer); |
| 62 |
reset(mockGameMap); |
| 63 |
reset(mockEngine); |
| 64 |
}); |
| 65 |
|
| 66 |
describe("execute", () => { |
| 67 |
it("should return a message", () => { |
| 68 |
const result = new MoveCommand().execute(); |
| 69 |
|
| 70 |
expect(result.message).toContain(`Move =>`); |
| 71 |
}); |
| 72 |
|
| 73 |
it("should return a result", () => { |
| 74 |
const result = new MoveCommand().execute(); |
| 75 |
|
| 76 |
expect(result.result).toBeDefined(); |
| 77 |
}); |
| 78 |
}); |
| 79 |
|
| 80 |
describe("move", () => { |
| 81 |
it("should be able to move `down`", () => { |
| 82 |
const command = new MoveCommand(playerMock, Directions.DOWN, engineMock); |
| 83 |
|
| 84 |
const action = command.execute(); |
| 85 |
|
| 86 |
expect(action.result).toEqual({ x: 2, y: 3 }); |
| 87 |
}); |
| 88 |
|
| 89 |
it("should be able to move `left`", () => { |
| 90 |
const command = new MoveCommand(playerMock, Directions.LEFT, engineMock); |
| 91 |
|
| 92 |
const action = command.execute(); |
| 93 |
|
| 94 |
expect(action.result).toEqual({ x: 1, y: 2 }); |
| 95 |
}); |
| 96 |
|
| 97 |
it("should be able to move `right`", () => { |
| 98 |
const command = new MoveCommand(playerMock, Directions.RIGHT, engineMock); |
| 99 |
|
| 100 |
const action = command.execute(); |
| 101 |
|
| 102 |
expect(action.result).toEqual({ x: 3, y: 2 }); |
| 103 |
}); |
| 104 |
|
| 105 |
it("should be able to move `up`", () => { |
| 106 |
const command = new MoveCommand(playerMock, Directions.UP, engineMock); |
| 107 |
|
| 108 |
const action = command.execute(); |
| 109 |
|
| 110 |
expect(action.result).toEqual({ x: 2, y: 1 }); |
| 111 |
}); |
| 112 |
|
| 113 |
it("should not move if directions is unknown", () => { |
| 114 |
const command = new MoveCommand(playerMock, "nowhere", engineMock); |
| 115 |
|
| 116 |
const action = command.execute(); |
| 117 |
|
| 118 |
expect(action.result).toBeNull(); |
| 119 |
}); |
| 120 |
}); |
| 121 |
|
| 122 |
describe("undo", () => { |
| 123 |
it("should be able to move back `down`", () => { |
| 124 |
const command = new MoveCommand(playerMock, Directions.DOWN, engineMock); |
| 125 |
|
| 126 |
const undo = command.undo(); |
| 127 |
expect(undo.result).toEqual({ x: 2, y: 1 }); |
| 128 |
}); |
| 129 |
|
| 130 |
it("should be able to move back `left`", () => { |
| 131 |
const command = new MoveCommand(playerMock, Directions.LEFT, engineMock); |
| 132 |
|
| 133 |
const undo = command.undo(); |
| 134 |
expect(undo.result).toEqual({ x: 3, y: 2 }); |
| 135 |
}); |
| 136 |
|
| 137 |
it("should be able to move back `right`", () => { |
| 138 |
const command = new MoveCommand(playerMock, Directions.RIGHT, engineMock); |
| 139 |
|
| 140 |
const undo = command.undo(); |
| 141 |
expect(undo.result).toEqual({ x: 1, y: 2 }); |
| 142 |
}); |
| 143 |
|
| 144 |
it("should be able to move back `up`", () => { |
| 145 |
const command = new MoveCommand(playerMock, Directions.UP, engineMock); |
| 146 |
|
| 147 |
const undo = command.undo(); |
| 148 |
expect(undo.result).toEqual({ x: 2, y: 3 }); |
| 149 |
}); |
| 150 |
|
| 151 |
// eslint-disable-next-line sonarjs/no-identical-functions |
| 152 |
it("should not move back if directions is unknown", () => { |
| 153 |
const command = new MoveCommand(playerMock, "nowhere", engineMock); |
| 154 |
|
| 155 |
const undo = command.undo(); |
| 156 |
expect(undo.result).toBeNull(); |
| 157 |
}); |
| 158 |
}); |
| 159 |
}); |
| 160 |
|
|
|
|
/packages/games/roguelike/tests/commands/roll.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/commands/roll.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { RollCommand } from "@roguelike/index"; |
| 2 |
|
| 3 |
describe("Roll Command", () => { |
| 4 |
describe("execute", () => { |
| 5 |
it("should return a message", () => { |
| 6 |
const result = new RollCommand().execute(); |
| 7 |
|
| 8 |
expect(result.message).toContain(`Roll =>`); |
| 9 |
}); |
| 10 |
|
| 11 |
it("should return a result", () => { |
| 12 |
const result = new RollCommand().execute(); |
| 13 |
|
| 14 |
expect(result.result).toBeDefined(); |
| 15 |
}); |
| 16 |
}); |
| 17 |
|
| 18 |
describe("undo", () => { |
| 19 |
it("should return null", () => { |
| 20 |
const result = new RollCommand().undo(); |
| 21 |
|
| 22 |
expect(result).toBeNull(); |
| 23 |
}); |
| 24 |
}); |
| 25 |
}); |
| 26 |
|
|
|
|
/packages/games/roguelike/tests/engine/entities/factory.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/engine/entities/factory.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import each from "jest-each"; |
| 2 |
|
| 3 |
import { EntityFactory } from "@roguelike/index"; |
| 4 |
|
| 5 |
describe("Entity Factory", () => { |
| 6 |
it("should be instantiable", () => { |
| 7 |
const factory = new EntityFactory(); |
| 8 |
expect(factory).not.toBeNull(); |
| 9 |
}); |
| 10 |
|
| 11 |
describe("create", () => { |
| 12 |
each([["Fungus"], ["Entity"]]).test("`%s` should return entity of type `%s`", (expected) => { |
| 13 |
const factory = new EntityFactory(); |
| 14 |
|
| 15 |
const result = factory.create("42", expected); |
| 16 |
|
| 17 |
expect(result.constructor.name).toBe(expected); |
| 18 |
}); |
| 19 |
}); |
| 20 |
}); |
| 21 |
|
|
|
|
/packages/games/roguelike/tests/engine/entities/fungus.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/engine/entities/fungus.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { |
| 2 |
AppearanceComponent, |
| 3 |
AttackComponent, |
| 4 |
ComponentName, |
| 5 |
DamageableComponent, |
| 6 |
SpreadComponent, |
| 7 |
} from "jga-games-engine"; |
| 8 |
import { Fungus } from "@roguelike/index"; |
| 9 |
|
| 10 |
describe("Fungus", () => { |
| 11 |
it("should be instantiable", () => { |
| 12 |
const entity = new Fungus("42"); |
| 13 |
expect(entity).not.toBeNull(); |
| 14 |
}); |
| 15 |
|
| 16 |
describe("constructor", () => { |
| 17 |
it("should set id", () => { |
| 18 |
const entity = new Fungus("42"); |
| 19 |
|
| 20 |
expect(entity.getId()).not.toBeNull(); |
| 21 |
}); |
| 22 |
|
| 23 |
it("should add an AppearanceComponent", () => { |
| 24 |
const entity = new Fungus("42"); |
| 25 |
|
| 26 |
expect(entity.getComponents().get(ComponentName.APPEARANCE)).toBeInstanceOf(AppearanceComponent); |
| 27 |
}); |
| 28 |
|
| 29 |
it("should add an AttackComponent", () => { |
| 30 |
const entity = new Fungus("42"); |
| 31 |
|
| 32 |
expect(entity.getComponents().get(ComponentName.ATTACK)).toBeInstanceOf(AttackComponent); |
| 33 |
}); |
| 34 |
|
| 35 |
it("should add an DamageableComponent", () => { |
| 36 |
const entity = new Fungus("42"); |
| 37 |
|
| 38 |
expect(entity.getComponents().get(ComponentName.DAMAGEABLE)).toBeInstanceOf(DamageableComponent); |
| 39 |
}); |
| 40 |
|
| 41 |
it("should add an SpreadComponent", () => { |
| 42 |
const entity = new Fungus("42"); |
| 43 |
|
| 44 |
expect(entity.getComponents().get(ComponentName.SPREAD)).toBeInstanceOf(SpreadComponent); |
| 45 |
}); |
| 46 |
}); |
| 47 |
}); |
| 48 |
|
|
|
|
/packages/games/roguelike/tests/game.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/game.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { instance, mock, reset } from "ts-mockito"; |
| 2 |
|
| 3 |
import { GameMap } from "jga-games-maps"; |
| 4 |
|
| 5 |
import { Console } from "jga-games-console"; |
| 6 |
|
| 7 |
import { Display } from "jga-games-display"; |
| 8 |
|
| 9 |
import { World, Scheduler } from "jga-games-engine"; |
| 10 |
|
| 11 |
import { Game, StartScreen } from "@roguelike/index"; |
| 12 |
|
| 13 |
const consoleSpy = jest.spyOn(Console.prototype, "append"); |
| 14 |
|
| 15 |
describe("Game", () => { |
| 16 |
let mockMap: GameMap; |
| 17 |
let mockDisplay: Display; |
| 18 |
let gameMapMock: GameMap; |
| 19 |
let displayMock: Display; |
| 20 |
|
| 21 |
beforeEach(() => { |
| 22 |
mockMap = mock<GameMap>(); |
| 23 |
mockDisplay = mock<Display>(); |
| 24 |
|
| 25 |
gameMapMock = instance(mockMap); |
| 26 |
displayMock = instance(mockDisplay); |
| 27 |
}); |
| 28 |
|
| 29 |
afterAll(() => { |
| 30 |
reset(mockMap); |
| 31 |
reset(mockDisplay); |
| 32 |
}); |
| 33 |
|
| 34 |
it("should be instantiable", () => { |
| 35 |
const game = new Game(); |
| 36 |
expect(game).not.toBeNull(); |
| 37 |
}); |
| 38 |
|
| 39 |
describe("constructor", (): void => { |
| 40 |
it("should set display", () => { |
| 41 |
const game = new Game(); |
| 42 |
expect(game.getDisplay()).toBeInstanceOf(Display); |
| 43 |
}); |
| 44 |
|
| 45 |
it("should set current screen", () => { |
| 46 |
const game = new Game(); |
| 47 |
expect(game.getCurrentScreen()).toBeInstanceOf(StartScreen); |
| 48 |
}); |
| 49 |
}); |
| 50 |
|
| 51 |
describe("switchScreen", (): void => { |
| 52 |
it("should be able to switch screen", () => { |
| 53 |
const screenEnterSpy = jest.spyOn(StartScreen.prototype, "enter"); |
| 54 |
const screenRenderSpy = jest.spyOn(StartScreen.prototype, "render"); |
| 55 |
|
| 56 |
const screen = new StartScreen(new World(new Scheduler(), gameMapMock), displayMock); |
| 57 |
|
| 58 |
const game = new Game(); |
| 59 |
game.switchScreen(screen); |
| 60 |
|
| 61 |
expect(screenEnterSpy).toHaveBeenCalledTimes(1); |
| 62 |
expect(screenRenderSpy).toHaveBeenCalledTimes(2); |
| 63 |
expect(consoleSpy).toHaveBeenCalled(); |
| 64 |
}); |
| 65 |
|
| 66 |
it("on switch screen previous screen is exited", () => { |
| 67 |
const screenExitSpy = jest.spyOn(StartScreen.prototype, "exit"); |
| 68 |
const screenEnterSpy = jest.spyOn(StartScreen.prototype, "enter"); |
| 69 |
const screenRenderSpy = jest.spyOn(StartScreen.prototype, "render"); |
| 70 |
|
| 71 |
const screen = new StartScreen(new World(new Scheduler(), gameMapMock), displayMock); |
| 72 |
|
| 73 |
const game = new Game(); |
| 74 |
game.switchScreen(screen); |
| 75 |
game.switchScreen(screen); |
| 76 |
|
| 77 |
expect(screenExitSpy).toHaveBeenCalledTimes(2); |
| 78 |
expect(screenEnterSpy).toHaveBeenCalledTimes(3); |
| 79 |
expect(screenRenderSpy).toHaveBeenCalledTimes(5); |
| 80 |
expect(consoleSpy).toHaveBeenCalled(); |
| 81 |
}); |
| 82 |
}); |
| 83 |
|
| 84 |
describe("handleInput", (): void => { |
| 85 |
it("should render screen", (): void => { |
| 86 |
// const screenHandleInput = jest.spyOn(StartScreen.prototype, "handleInput"); |
| 87 |
const screenRenderSpy = jest.spyOn(StartScreen.prototype, "render"); |
| 88 |
// const game = new Game(); |
| 89 |
|
| 90 |
const keyboardEvent = new KeyboardEvent("keydown", { code: "Enter" }); |
| 91 |
|
| 92 |
window.dispatchEvent(keyboardEvent); |
| 93 |
|
| 94 |
// game.handleInput("keydown"); |
| 95 |
|
| 96 |
// expect(screenHandleInput).toHaveBeenCalledWith("keydown", { code: "Enter" }); |
| 97 |
expect(screenRenderSpy).toHaveBeenCalled(); |
| 98 |
}); |
| 99 |
|
| 100 |
it("should switch screen if screen.handleInput returns a new screen name", (): void => { |
| 101 |
StartScreen.prototype.handleInput = jest.fn().mockReturnValue("PlayScreen"); |
| 102 |
|
| 103 |
const gameSwitchScreenSpy = jest.spyOn(Game.prototype, "switchScreen"); |
| 104 |
const screenRenderSpy = jest.spyOn(StartScreen.prototype, "render"); |
| 105 |
// const game = new Game(); |
| 106 |
|
| 107 |
const keyboardEvent = new KeyboardEvent("keydown", { code: "Enter" }); |
| 108 |
|
| 109 |
window.dispatchEvent(keyboardEvent); |
| 110 |
|
| 111 |
// game.handleInput("keydown"); |
| 112 |
|
| 113 |
expect(gameSwitchScreenSpy).toHaveBeenCalled(); |
| 114 |
expect(screenRenderSpy).toHaveBeenCalled(); |
| 115 |
}); |
| 116 |
|
| 117 |
it("should not switch screen if screen.handleInput returns null", (): void => { |
| 118 |
StartScreen.prototype.handleInput = jest.fn().mockReturnValue(null); |
| 119 |
|
| 120 |
const gameSwitchScreenSpy = jest.spyOn(Game.prototype, "switchScreen"); |
| 121 |
const screenRenderSpy = jest.spyOn(StartScreen.prototype, "render"); |
| 122 |
// const game = new Game(); |
| 123 |
|
| 124 |
const keyboardEvent = new KeyboardEvent("keydown", { code: "Enter" }); |
| 125 |
|
| 126 |
window.dispatchEvent(keyboardEvent); |
| 127 |
|
| 128 |
// game.handleInput("keydown"); |
| 129 |
|
| 130 |
expect(gameSwitchScreenSpy).toHaveBeenCalled(); |
| 131 |
expect(screenRenderSpy).toHaveBeenCalled(); |
| 132 |
}); |
| 133 |
}); |
| 134 |
}); |
| 135 |
|
|
|
|
/packages/games/roguelike/tests/main.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/main.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Display } from "jga-games-display"; |
| 2 |
|
| 3 |
import { Game } from "./../src/game/game"; |
| 4 |
|
| 5 |
// eslint-disable-next-line import/no-named-as-default |
| 6 |
import main, { init } from "./../src/index"; |
| 7 |
|
| 8 |
jest.mock("./../src/game/game"); |
| 9 |
|
| 10 |
beforeEach(() => { |
| 11 |
Game.prototype.getDisplay = jest.fn().mockImplementation(() => new Display(80, 60)); |
| 12 |
}); |
| 13 |
|
| 14 |
afterEach(() => { |
| 15 |
jest.fn().mockClear(); |
| 16 |
}); |
| 17 |
|
| 18 |
describe("init", (): void => { |
| 19 |
it("should be called on window load", (): void => { |
| 20 |
const initSpy = jest.spyOn(main, "init"); |
| 21 |
const event = new Event("load"); |
| 22 |
|
| 23 |
window.dispatchEvent(event); |
| 24 |
|
| 25 |
expect(initSpy).toHaveBeenCalled(); |
| 26 |
|
| 27 |
initSpy.mockRestore(); |
| 28 |
}); |
| 29 |
|
| 30 |
it("should create a new game", (): void => { |
| 31 |
init(); |
| 32 |
|
| 33 |
expect(Game).toHaveBeenCalled(); |
| 34 |
}); |
| 35 |
}); |
| 36 |
|
|
|
|
/packages/games/roguelike/tests/screens/factory.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/screens/factory.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import each from "jest-each"; |
| 2 |
|
| 3 |
import { World } from "jga-games-engine"; |
| 4 |
|
| 5 |
import { |
| 6 |
ScreenFactoryCreateParamsInterface, |
| 7 |
LoseScreen, |
| 8 |
PlayScreen, |
| 9 |
ScreenFactory, |
| 10 |
StartScreen, |
| 11 |
WinScreen, |
| 12 |
} from "@roguelike/index"; |
| 13 |
|
| 14 |
const manager = new World(); |
| 15 |
|
| 16 |
describe("Screen factory", () => { |
| 17 |
it("should be instantiable", () => { |
| 18 |
const factory = new ScreenFactory(); |
| 19 |
expect(factory).not.toBeNull(); |
| 20 |
}); |
| 21 |
|
| 22 |
describe("create", () => { |
| 23 |
each([ |
| 24 |
[new LoseScreen(manager), ["lose", manager]], |
| 25 |
[new PlayScreen(manager), ["play", manager]], |
| 26 |
[new StartScreen(manager), ["start", manager]], |
| 27 |
[new WinScreen(manager), ["win", manager]], |
| 28 |
[new StartScreen(manager), ["somescreen", manager]], |
| 29 |
[new StartScreen(manager), ["", manager]], |
| 30 |
]).test("should create appropriate screen", (expected, params) => { |
| 31 |
const factory = new ScreenFactory(); |
| 32 |
const createParams: ScreenFactoryCreateParamsInterface = { |
| 33 |
engine: params[1], |
| 34 |
type: params[0], |
| 35 |
}; |
| 36 |
const result = factory.create(createParams); |
| 37 |
|
| 38 |
expect(result.constructor.name).toEqual(expected.constructor.name); |
| 39 |
}); |
| 40 |
}); |
| 41 |
}); |
| 42 |
|
|
|
|
/packages/games/roguelike/tests/screens/lose.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/screens/lose.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import each from "jest-each"; |
| 2 |
|
| 3 |
import { anyString, anything, instance, mock, reset, verify } from "ts-mockito"; |
| 4 |
|
| 5 |
import { Keys } from "jga-games-commands"; |
| 6 |
import { Display } from "jga-games-display"; |
| 7 |
import { World, Scheduler } from "jga-games-engine"; |
| 8 |
import { GameMap } from "jga-games-maps"; |
| 9 |
|
| 10 |
import { LoseScreen } from "@roguelike/index"; |
| 11 |
|
| 12 |
describe("LoseScreen", () => { |
| 13 |
const consoleSpy = jest.spyOn(global.console, "log"); |
| 14 |
|
| 15 |
let gameMapMock: GameMap; |
| 16 |
let displayMock: Display; |
| 17 |
let engine: World; |
| 18 |
|
| 19 |
const mockGameMap: GameMap = mock<GameMap>(); |
| 20 |
const mockDisplay: Display = mock<Display>(); |
| 21 |
|
| 22 |
beforeEach(() => { |
| 23 |
consoleSpy.mockClear(); |
| 24 |
|
| 25 |
gameMapMock = instance(mockGameMap); |
| 26 |
displayMock = instance(mockDisplay); |
| 27 |
|
| 28 |
engine = new World(new Scheduler(), gameMapMock); |
| 29 |
}); |
| 30 |
|
| 31 |
afterAll(() => { |
| 32 |
reset(mockGameMap); |
| 33 |
reset(mockDisplay); |
| 34 |
}); |
| 35 |
|
| 36 |
it("should be instantiable", () => { |
| 37 |
const screen = new LoseScreen(engine, displayMock); |
| 38 |
expect(screen).not.toBeNull(); |
| 39 |
}); |
| 40 |
|
| 41 |
// eslint-disable-next-line jest/expect-expect |
| 42 |
it("should be able to render", () => { |
| 43 |
// const displaySpy = jest.spyOn(Display.prototype, "drawText"); |
| 44 |
const screen = new LoseScreen(engine, displayMock); |
| 45 |
|
| 46 |
screen.render(); |
| 47 |
|
| 48 |
verify(mockDisplay.drawText(anything(), anyString())).times(22); |
| 49 |
}); |
| 50 |
|
| 51 |
describe("handleInput", () => { |
| 52 |
each([ |
| 53 |
[ |
| 54 |
null, |
| 55 |
{ |
| 56 |
data: {}, |
| 57 |
type: "keydown", |
| 58 |
}, |
| 59 |
], |
| 60 |
[ |
| 61 |
null, |
| 62 |
{ |
| 63 |
data: { keyCode: Keys.RETURN }, |
| 64 |
type: "keydown", |
| 65 |
}, |
| 66 |
], |
| 67 |
]).test(" should return appropriate value", (expected, params) => { |
| 68 |
const screen = new LoseScreen(engine, displayMock); |
| 69 |
|
| 70 |
const result = screen.handleInput(params); |
| 71 |
|
| 72 |
expect(result).toEqual(expected); |
| 73 |
}); |
| 74 |
}); |
| 75 |
}); |
| 76 |
|
|
|
|
/packages/games/roguelike/tests/screens/play.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/screens/play.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import each from "jest-each"; |
| 2 |
|
| 3 |
import { anything, instance, mock, reset, spy, verify, when } from "ts-mockito"; |
| 4 |
|
| 5 |
import { CommandManager } from "jga-patterns-command"; |
| 6 |
import { ComponentName, World, Scheduler } from "jga-games-engine"; |
| 7 |
import { Directions, GameMap } from "jga-games-maps"; |
| 8 |
import { Display } from "jga-games-display"; |
| 9 |
import { GlyphInterface } from "jga-games-glyphs"; |
| 10 |
import { Keys } from "jga-games-commands"; |
| 11 |
|
| 12 |
import { TileInterface } from "jga-games-tiles"; |
| 13 |
|
| 14 |
import { EntityFactory, MoveCommand, PlayScreen } from "@roguelike/index"; |
| 15 |
|
| 16 |
describe("PlayScreen", () => { |
| 17 |
let glyphMock: GlyphInterface; |
| 18 |
let tileMock: TileInterface; |
| 19 |
let gameMapMock: GameMap; |
| 20 |
let engine: World; |
| 21 |
let displayMock: Display; |
| 22 |
|
| 23 |
const mockDisplay: Display = mock<Display>(); |
| 24 |
const mockGlyph: GlyphInterface = mock<GlyphInterface>(); |
| 25 |
const mockTile: TileInterface = mock<TileInterface>(); |
| 26 |
const mockGameMap: GameMap = mock<GameMap>(); |
| 27 |
|
| 28 |
beforeEach(() => { |
| 29 |
when(mockTile.getGlyph()).thenReturn(glyphMock); |
| 30 |
|
| 31 |
displayMock = instance(mockDisplay); |
| 32 |
glyphMock = instance(mockGlyph); |
| 33 |
tileMock = instance(mockTile); |
| 34 |
|
| 35 |
when(mockGameMap.getTile(anything())).thenReturn(tileMock); |
| 36 |
|
| 37 |
gameMapMock = instance(mockGameMap); |
| 38 |
|
| 39 |
engine = new World(new Scheduler(), gameMapMock, new CommandManager(), new EntityFactory()); |
| 40 |
const spiedEngine = spy(engine); |
| 41 |
when(spiedEngine.getRandomFloorPosition()).thenReturn({ x: 0, y: 0 }); |
| 42 |
|
| 43 |
engine.createPlayer(); |
| 44 |
|
| 45 |
jest.clearAllMocks(); |
| 46 |
}); |
| 47 |
|
| 48 |
afterAll(() => { |
| 49 |
reset(mockDisplay); |
| 50 |
reset(mockGlyph); |
| 51 |
reset(mockTile); |
| 52 |
reset(mockGameMap); |
| 53 |
}); |
| 54 |
|
| 55 |
it("should be instantiable", () => { |
| 56 |
const screen = new PlayScreen(engine, displayMock); |
| 57 |
expect(screen).not.toBeNull(); |
| 58 |
}); |
| 59 |
|
| 60 |
// eslint-disable-next-line jest/expect-expect |
| 61 |
it("should be able to render", () => { |
| 62 |
const screen = new PlayScreen(engine, displayMock); |
| 63 |
|
| 64 |
screen.enter(); |
| 65 |
screen.render(new Display(24, 80)); |
| 66 |
|
| 67 |
verify(mockDisplay.draw(anything(), anything())).times(11); |
| 68 |
}); |
| 69 |
|
| 70 |
it("should be able to retrieve current x position", () => { |
| 71 |
const screen = new PlayScreen(engine, displayMock); |
| 72 |
const player = engine.getPlayer(); |
| 73 |
const expected = player.getComponent(ComponentName.POSITION).getPosition().x; |
| 74 |
|
| 75 |
expect(screen.getCurrentX()).toBe(expected); |
| 76 |
}); |
| 77 |
|
| 78 |
it("should be able to retrieve current y position", () => { |
| 79 |
const screen = new PlayScreen(engine, displayMock); |
| 80 |
const player = engine.getPlayer(); |
| 81 |
const expected = player.getComponent(ComponentName.POSITION).getPosition().y; |
| 82 |
|
| 83 |
expect(screen.getCurrentY()).toBe(expected); |
| 84 |
}); |
| 85 |
|
| 86 |
describe("exit", () => { |
| 87 |
it("should return void", () => { |
| 88 |
const screen = new PlayScreen(engine, displayMock); |
| 89 |
|
| 90 |
expect(screen.exit()).toBeUndefined(); |
| 91 |
}); |
| 92 |
}); |
| 93 |
|
| 94 |
describe("handleInput", () => { |
| 95 |
it("should return null if `inputType` is different from `keydown`", () => { |
| 96 |
const screen = new PlayScreen(engine, displayMock); |
| 97 |
|
| 98 |
expect(screen.handleInput("keyup")).toBeNull(); |
| 99 |
}); |
| 100 |
|
| 101 |
it("should return null if `code` is not mapped", () => { |
| 102 |
const screen = new PlayScreen(engine, displayMock); |
| 103 |
|
| 104 |
expect(screen.handleInput("keydown", { code: "Digit8" })).toBeNull(); |
| 105 |
}); |
| 106 |
|
| 107 |
it("should roll if `code` is `KeyR`", () => { |
| 108 |
// const engineExecuteSpy = jest.spyOn(World.prototype, "execute"); |
| 109 |
const screenNotifySpy = jest.spyOn(PlayScreen.prototype, "notify"); |
| 110 |
const screen = new PlayScreen(engine, displayMock); |
| 111 |
|
| 112 |
screen.handleInput("keydown", { code: "KeyR" }); |
| 113 |
|
| 114 |
// expect(engineExecuteSpy).toHaveBeenCalledTimes(1); |
| 115 |
expect(screenNotifySpy).toHaveBeenCalledTimes(1); |
| 116 |
}); |
| 117 |
|
| 118 |
each([ |
| 119 |
[Keys.ESCAPE, "lose"], |
| 120 |
[Keys.RETURN, "win"], |
| 121 |
]).test("code `%s` should return `%s`", (code, expected) => { |
| 122 |
const screen = new PlayScreen(engine, displayMock); |
| 123 |
const result = screen.handleInput("keydown", { code }); |
| 124 |
|
| 125 |
expect(result).toBe(expected); |
| 126 |
}); |
| 127 |
|
| 128 |
each([ |
| 129 |
[Keys.UP, Directions.UP], |
| 130 |
[Keys.DOWN, Directions.DOWN], |
| 131 |
[Keys.LEFT, Directions.LEFT], |
| 132 |
[Keys.RIGHT, Directions.RIGHT], |
| 133 |
]).test("code `%s` should move `%s`", (code, direction) => { |
| 134 |
// const engineExecuteSpy = jest.spyOn(World.prototype, "execute"); |
| 135 |
// const expectedCommand = new MoveCommand(engine.getPlayer(), direction, engine); |
| 136 |
const screenNotifySpy = jest.spyOn(PlayScreen.prototype, "notify"); |
| 137 |
|
| 138 |
const screen = new PlayScreen(engine, displayMock); |
| 139 |
|
| 140 |
screen.handleInput("keydown", { code }); |
| 141 |
|
| 142 |
// expect(engineExecuteSpy).toHaveBeenCalledWith(expectedCommand); |
| 143 |
expect(screenNotifySpy).toHaveBeenCalledTimes(1); |
| 144 |
}); |
| 145 |
}); |
| 146 |
}); |
| 147 |
|
|
|
|
/packages/games/roguelike/tests/screens/start.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/screens/start.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import each from "jest-each"; |
| 2 |
|
| 3 |
import { anything, instance, mock, verify, anyString, reset } from "ts-mockito"; |
| 4 |
|
| 5 |
import { Keys } from "jga-games-commands"; |
| 6 |
import { Display } from "jga-games-display"; |
| 7 |
import { World, Scheduler } from "jga-games-engine"; |
| 8 |
import { GameMap } from "jga-games-maps"; |
| 9 |
|
| 10 |
import { StartScreen } from "@roguelike/index"; |
| 11 |
|
| 12 |
describe("StartScreen", () => { |
| 13 |
const consoleSpy = jest.spyOn(global.console, "log"); |
| 14 |
|
| 15 |
let gameMapMock: GameMap; |
| 16 |
let displayMock: Display; |
| 17 |
let engine: World; |
| 18 |
const mockGameMap: GameMap = mock<GameMap>(); |
| 19 |
const mockDisplay: Display = mock<Display>(); |
| 20 |
|
| 21 |
beforeEach(() => { |
| 22 |
consoleSpy.mockClear(); |
| 23 |
|
| 24 |
gameMapMock = instance(mockGameMap); |
| 25 |
displayMock = instance(mockDisplay); |
| 26 |
|
| 27 |
engine = new World(new Scheduler(), gameMapMock); |
| 28 |
}); |
| 29 |
|
| 30 |
afterAll(() => { |
| 31 |
reset(mockGameMap); |
| 32 |
reset(mockDisplay); |
| 33 |
}); |
| 34 |
|
| 35 |
it("should be instantiable", () => { |
| 36 |
const screen = new StartScreen(engine, displayMock); |
| 37 |
expect(screen).not.toBeNull(); |
| 38 |
}); |
| 39 |
|
| 40 |
// eslint-disable-next-line jest/expect-expect |
| 41 |
it("should be able to render", () => { |
| 42 |
const screen = new StartScreen(engine, displayMock); |
| 43 |
|
| 44 |
screen.render(); |
| 45 |
|
| 46 |
verify(mockDisplay.drawText(anything(), anyString())).twice(); |
| 47 |
}); |
| 48 |
|
| 49 |
describe("handleInput", () => { |
| 50 |
each([ |
| 51 |
[ |
| 52 |
null, |
| 53 |
{ |
| 54 |
data: {}, |
| 55 |
type: "keydown", |
| 56 |
}, |
| 57 |
], |
| 58 |
[ |
| 59 |
"play", |
| 60 |
{ |
| 61 |
data: { code: Keys.RETURN }, |
| 62 |
type: "keydown", |
| 63 |
}, |
| 64 |
], |
| 65 |
[ |
| 66 |
null, |
| 67 |
{ |
| 68 |
data: { code: Keys.UP }, |
| 69 |
type: "keyup", |
| 70 |
}, |
| 71 |
], |
| 72 |
]).test(" should return appropriate value", (expected, params) => { |
| 73 |
const screen = new StartScreen(engine, displayMock); |
| 74 |
|
| 75 |
const result = screen.handleInput(params.type, params.data); |
| 76 |
|
| 77 |
expect(result).toEqual(expected); |
| 78 |
}); |
| 79 |
}); |
| 80 |
}); |
| 81 |
|
|
|
|
/packages/games/roguelike/tests/screens/win.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/roguelike/tests/screens/win.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import each from "jest-each"; |
| 2 |
|
| 3 |
import { anything, instance, mock, verify, anyString, reset } from "ts-mockito"; |
| 4 |
|
| 5 |
import { Keys } from "jga-games-commands"; |
| 6 |
import { Display } from "jga-games-display"; |
| 7 |
import { GameMap } from "jga-games-maps"; |
| 8 |
import { World, Scheduler } from "jga-games-engine"; |
| 9 |
|
| 10 |
import { WinScreen } from "@roguelike/index"; |
| 11 |
|
| 12 |
describe("WinScreen", () => { |
| 13 |
const consoleSpy = jest.spyOn(global.console, "log"); |
| 14 |
|
| 15 |
let gameMapMock: GameMap; |
| 16 |
let displayMock: Display; |
| 17 |
let engine: World; |
| 18 |
|
| 19 |
const mockGameMap: GameMap = mock<GameMap>(); |
| 20 |
const mockDisplay: Display = mock<Display>(); |
| 21 |
|
| 22 |
beforeEach(() => { |
| 23 |
consoleSpy.mockClear(); |
| 24 |
|
| 25 |
gameMapMock = instance(mockGameMap); |
| 26 |
displayMock = instance(mockDisplay); |
| 27 |
|
| 28 |
engine = new World(new Scheduler(), gameMapMock); |
| 29 |
}); |
| 30 |
|
| 31 |
afterAll(() => { |
| 32 |
reset(mockGameMap); |
| 33 |
reset(mockDisplay); |
| 34 |
}); |
| 35 |
|
| 36 |
it("should be instantiable", () => { |
| 37 |
const screen = new WinScreen(engine, displayMock); |
| 38 |
expect(screen).not.toBeNull(); |
| 39 |
}); |
| 40 |
|
| 41 |
// eslint-disable-next-line jest/expect-expect |
| 42 |
it("should be able to render", () => { |
| 43 |
const screen = new WinScreen(engine, displayMock); |
| 44 |
|
| 45 |
screen.render(); |
| 46 |
|
| 47 |
verify(mockDisplay.drawText(anything(), anyString())).times(22); |
| 48 |
}); |
| 49 |
|
| 50 |
describe("handleInput", () => { |
| 51 |
each([ |
| 52 |
[ |
| 53 |
null, |
| 54 |
{ |
| 55 |
data: {}, |
| 56 |
type: "keydown", |
| 57 |
}, |
| 58 |
], |
| 59 |
[ |
| 60 |
null, |
| 61 |
{ |
| 62 |
data: { keyCode: Keys.RETURN }, |
| 63 |
type: "keydown", |
| 64 |
}, |
| 65 |
], |
| 66 |
]).test(" should return appropriate value", (expected, params) => { |
| 67 |
const screen = new WinScreen(engine, displayMock); |
| 68 |
|
| 69 |
const result = screen.handleInput(params); |
| 70 |
|
| 71 |
expect(result).toEqual(expected); |
| 72 |
}); |
| 73 |
}); |
| 74 |
}); |
| 75 |
|
|
|
|
/packages/games/screens/src/index.ts
|
0 problems
|
|
|
/packages/games/screens/src/interface.ts
|
0 problems
|
|
|
/packages/games/screens/src/observer.ts
|
0 problems
|
|
|
/packages/games/screens/src/screen.ts
|
0 problems
|
|
|
/packages/games/screens/tests/observer.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/screens/tests/observer.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Console, ConsoleInterface, ConsoleRendererInterface, HTMLConsoleRenderer } from "jga-games-console"; |
| 2 |
|
| 3 |
import { ObservableInterface, ObserverInterface } from "jga-patterns-observer"; |
| 4 |
|
| 5 |
import { ScreenObserver } from "@games-screens/index"; |
| 6 |
|
| 7 |
class Observable implements ObservableInterface { |
| 8 |
// eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 9 |
public attach(observer: ObserverInterface): void { |
| 10 |
/** nothing to do */ |
| 11 |
} |
| 12 |
// eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 13 |
public detach(observer: ObserverInterface): void { |
| 14 |
/** nothing to do */ |
| 15 |
} |
| 16 |
// eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 17 |
public notify(message: string): void { |
| 18 |
/** nothing to do */ |
| 19 |
} |
| 20 |
} |
| 21 |
|
| 22 |
class ConsoleMock implements ConsoleInterface { |
| 23 |
// eslint-disable-next-line @typescript-eslint/no-unused-vars |
| 24 |
public append(message: string): void { |
| 25 |
/** nothing to do */ |
| 26 |
} |
| 27 |
public getContainer(): HTMLElement | null { |
| 28 |
return null; |
| 29 |
} |
| 30 |
public getRenderer(): ConsoleRendererInterface { |
| 31 |
return new HTMLConsoleRenderer(); |
| 32 |
} |
| 33 |
} |
| 34 |
|
| 35 |
jest.mock("jga-games-console/dist/console.js"); |
| 36 |
|
| 37 |
describe("Screen Observer", () => { |
| 38 |
it("should be instantiable", () => { |
| 39 |
const observer = new ScreenObserver(); |
| 40 |
expect(observer).not.toBeNull(); |
| 41 |
}); |
| 42 |
|
| 43 |
describe("update", () => { |
| 44 |
it("should send message to console", () => { |
| 45 |
const mockConsole = jest.fn(); |
| 46 |
mockConsole.mockReturnValue(new ConsoleMock()); |
| 47 |
|
| 48 |
Console.getInstance = mockConsole; |
| 49 |
|
| 50 |
const consoleAppendSpy = jest.spyOn(ConsoleMock.prototype, "append"); |
| 51 |
|
| 52 |
const message = "My Awesome Message"; |
| 53 |
|
| 54 |
const observer = new ScreenObserver(new ConsoleMock()); |
| 55 |
observer.update(new Observable(), message); |
| 56 |
|
| 57 |
expect(consoleAppendSpy).toHaveBeenNthCalledWith(1, `[Observable] ${message}`); |
| 58 |
}); |
| 59 |
}); |
| 60 |
}); |
| 61 |
|
|
|
|
/packages/games/screens/tests/screen.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/screens/tests/screen.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { ObserverInterface } from "jga-patterns-observer"; |
| 2 |
|
| 3 |
import { World } from "jga-games-engine"; |
| 4 |
|
| 5 |
import { Screen } from "@games-screens/index"; |
| 6 |
|
| 7 |
class ConcreteScreen extends Screen {} |
| 8 |
|
| 9 |
class Observer implements ObserverInterface {} |
| 10 |
|
| 11 |
const engine = new World(); |
| 12 |
|
| 13 |
describe("Screen", (): void => { |
| 14 |
afterEach(() => jest.restoreAllMocks()); |
| 15 |
|
| 16 |
it("should be able to attach and detach observer", (): void => { |
| 17 |
const observer = new Observer(); |
| 18 |
const screen = new ConcreteScreen("Screen", engine); |
| 19 |
|
| 20 |
// there is one observer attached at the beginning |
| 21 |
expect(screen.getObservers()).toHaveLength(1); |
| 22 |
|
| 23 |
screen.attach(observer); |
| 24 |
expect(screen.getObservers()).toHaveLength(2); |
| 25 |
|
| 26 |
screen.detach(observer); |
| 27 |
expect(screen.getObservers()).toHaveLength(1); |
| 28 |
}); |
| 29 |
|
| 30 |
describe("enter", () => { |
| 31 |
it("should call notify", () => { |
| 32 |
const screen = new ConcreteScreen("Screen", engine); |
| 33 |
const notifySpy = jest.spyOn(ConcreteScreen.prototype, "notify"); |
| 34 |
|
| 35 |
screen.enter(); |
| 36 |
|
| 37 |
expect(notifySpy).toHaveBeenNthCalledWith(1, `Enter Screen screen`); |
| 38 |
}); |
| 39 |
}); |
| 40 |
|
| 41 |
describe("exit", () => { |
| 42 |
it("should call notify", () => { |
| 43 |
const screen = new ConcreteScreen("Screen", engine); |
| 44 |
const notifySpy = jest.spyOn(ConcreteScreen.prototype, "notify"); |
| 45 |
|
| 46 |
screen.exit(); |
| 47 |
|
| 48 |
expect(notifySpy).toHaveBeenNthCalledWith(1, `Exit Screen screen`); |
| 49 |
}); |
| 50 |
}); |
| 51 |
}); |
| 52 |
|
|
|
|
/packages/games/tiles/src/factory.ts
|
0 problems
|
|
|
/packages/games/tiles/src/floor.ts
|
0 problems
|
|
|
/packages/games/tiles/src/index.ts
|
0 problems
|
|
|
/packages/games/tiles/src/null.ts
|
0 problems
|
|
|
/packages/games/tiles/src/tile.ts
|
0 problems
|
|
|
/packages/games/tiles/src/wall.ts
|
0 problems
|
|
|
/packages/games/tiles/tests/factory.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/tiles/tests/factory.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import each from "jest-each"; |
| 2 |
|
| 3 |
import { TileFactory, FloorTile, NullTile, WallTile } from "@games-tiles/index"; |
| 4 |
|
| 5 |
describe("Tile factory", () => { |
| 6 |
it("should be instantiable", () => { |
| 7 |
const factory = new TileFactory(); |
| 8 |
expect(factory).not.toBeNull(); |
| 9 |
}); |
| 10 |
|
| 11 |
describe("create", () => { |
| 12 |
each([ |
| 13 |
[new FloorTile(), "floor"], |
| 14 |
[new NullTile(), "null"], |
| 15 |
[new WallTile(), "wall"], |
| 16 |
[new NullTile(), "someTile"], |
| 17 |
[new NullTile(), null], |
| 18 |
[new NullTile(), ""], |
| 19 |
]).test(" should be able to create appropriate tile", (expected, params) => { |
| 20 |
const factory = new TileFactory(); |
| 21 |
const result = factory.create(params); |
| 22 |
|
| 23 |
expect(result).toEqual(expected); |
| 24 |
}); |
| 25 |
}); |
| 26 |
}); |
| 27 |
|
|
|
|
/packages/games/tiles/tests/floor.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/tiles/tests/floor.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { FloorTile } from "@games-tiles/index"; |
| 2 |
|
| 3 |
describe("FloorTile", () => { |
| 4 |
it("should be instantiable", () => { |
| 5 |
const tile = new FloorTile(); |
| 6 |
expect(tile).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
it("glyph char should be '.'", () => { |
| 10 |
const expected = "."; |
| 11 |
const tile = new FloorTile(); |
| 12 |
expect(tile.getGlyph().getChar()).toBe(expected); |
| 13 |
}); |
| 14 |
|
| 15 |
describe("constructor", () => { |
| 16 |
it("should set `isDiggable`", () => { |
| 17 |
const isDiggable = false; |
| 18 |
const tile = new FloorTile(); |
| 19 |
|
| 20 |
expect(tile.isDiggable).toBe(isDiggable); |
| 21 |
}); |
| 22 |
|
| 23 |
it("should set `isWalkable`", () => { |
| 24 |
const isWalkable = true; |
| 25 |
const tile = new FloorTile(); |
| 26 |
|
| 27 |
expect(tile.isWalkable).toBe(isWalkable); |
| 28 |
}); |
| 29 |
}); |
| 30 |
}); |
| 31 |
|
|
|
|
/packages/games/tiles/tests/null.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/tiles/tests/null.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { NullTile } from "@games-tiles/index"; |
| 2 |
|
| 3 |
describe("NullTile", () => { |
| 4 |
it("should be instantiable", () => { |
| 5 |
const tile = new NullTile(); |
| 6 |
expect(tile).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
it("should be initialized with default glyph", () => { |
| 10 |
const tile = new NullTile(); |
| 11 |
expect(tile.getGlyph()).not.toBeNull(); |
| 12 |
expect(tile.getGlyph().getChar()).toBe(" "); |
| 13 |
expect(tile.getGlyph().getBackground()).toBe("white"); |
| 14 |
expect(tile.getGlyph().getForeground()).toBe("black"); |
| 15 |
}); |
| 16 |
}); |
| 17 |
|
|
|
|
/packages/games/tiles/tests/tile.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/tiles/tests/tile.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Glyph } from "jga-games-glyphs"; |
| 2 |
|
| 3 |
import { Tile } from "@games-tiles/index"; |
| 4 |
|
| 5 |
class ConcreteTile extends Tile {} |
| 6 |
|
| 7 |
describe("Tile", () => { |
| 8 |
it("should be instantiable", () => { |
| 9 |
const tile = new ConcreteTile(new Glyph()); |
| 10 |
expect(tile).not.toBeNull(); |
| 11 |
}); |
| 12 |
|
| 13 |
it("should be able to retrieve glyph", () => { |
| 14 |
const expected = new Glyph(); |
| 15 |
const tile = new ConcreteTile(expected); |
| 16 |
expect(tile.getGlyph()).toBe(expected); |
| 17 |
}); |
| 18 |
|
| 19 |
it("should be able to retrieve isDiggable", () => { |
| 20 |
const expected = true; |
| 21 |
const tile = new ConcreteTile(new Glyph(), true); |
| 22 |
expect(tile.isDiggable).toBe(expected); |
| 23 |
}); |
| 24 |
|
| 25 |
it("should be able to retrieve isWalkable", () => { |
| 26 |
const expected = true; |
| 27 |
const tile = new ConcreteTile(new Glyph(), false, true); |
| 28 |
expect(tile.isWalkable).toBe(expected); |
| 29 |
}); |
| 30 |
|
| 31 |
it("should have a default value for `isDiggable`", () => { |
| 32 |
const expected = false; |
| 33 |
const tile = new ConcreteTile(new Glyph()); |
| 34 |
|
| 35 |
expect(tile.isDiggable).toBe(expected); |
| 36 |
}); |
| 37 |
|
| 38 |
it("should have a default value for `isWalkable`", () => { |
| 39 |
const expected = false; |
| 40 |
const tile = new ConcreteTile(new Glyph()); |
| 41 |
|
| 42 |
expect(tile.isWalkable).toBe(expected); |
| 43 |
}); |
| 44 |
}); |
| 45 |
|
|
|
|
/packages/games/tiles/tests/wall.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/games/tiles/tests/wall.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { WallGlyph } from "jga-games-glyphs"; |
| 2 |
|
| 3 |
import { WallTile } from "@games-tiles/index"; |
| 4 |
|
| 5 |
describe("WallTile", () => { |
| 6 |
it("should be instantiable", () => { |
| 7 |
const tile = new WallTile(); |
| 8 |
expect(tile).not.toBeNull(); |
| 9 |
}); |
| 10 |
|
| 11 |
it("glyph char should be '.'", () => { |
| 12 |
const expected = "#"; |
| 13 |
const tile = new WallTile(); |
| 14 |
expect(tile.getGlyph().getChar()).toBe(expected); |
| 15 |
}); |
| 16 |
|
| 17 |
it("glyph background should be 'goldenrod'", () => { |
| 18 |
const expected = "goldenrod"; |
| 19 |
const tile = new WallTile(); |
| 20 |
expect(tile.getGlyph().getBackground()).toBe(expected); |
| 21 |
}); |
| 22 |
|
| 23 |
it("should have WallGlyph as glyph", () => { |
| 24 |
const tile = new WallTile(); |
| 25 |
expect(tile.getGlyph()).toBeInstanceOf(WallGlyph); |
| 26 |
}); |
| 27 |
|
| 28 |
it("should be diggable", () => { |
| 29 |
const tile = new WallTile(); |
| 30 |
expect(tile.isDiggable).toBe(true); |
| 31 |
}); |
| 32 |
|
| 33 |
it("should not be walkable", () => { |
| 34 |
const tile = new WallTile(); |
| 35 |
expect(tile.isWalkable).toBe(false); |
| 36 |
}); |
| 37 |
}); |
| 38 |
|
|
|
|
/packages/generators/boolean/src/boolean.ts
|
0 problems
|
|
|
/packages/generators/boolean/src/index.ts
|
0 problems
|
|
|
/packages/generators/boolean/tests/boolean.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/generators/boolean/tests/boolean.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { randomBoolean } from "@generators-boolean/index"; |
| 2 |
|
| 3 |
describe("boolean", () => { |
| 4 |
it("should return a boolean", (): void => { |
| 5 |
const result = randomBoolean(); |
| 6 |
|
| 7 |
expect(typeof result).toBe("boolean"); |
| 8 |
}); |
| 9 |
}); |
| 10 |
|
|
|
|
/packages/generators/uuid/src/index.ts
|
0 problems
|
|
|
/packages/generators/uuid/src/uuid.ts
|
0 problems
|
|
|
/packages/generators/uuid/tests/uuid.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/generators/uuid/tests/uuid.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { uuid } from "@generators-uuid/index"; |
| 2 |
|
| 3 |
describe("uuid", () => { |
| 4 |
it("should return a uuid string", (): void => { |
| 5 |
const result = uuid(); |
| 6 |
|
| 7 |
expect(result).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i); |
| 8 |
}); |
| 9 |
}); |
| 10 |
|
|
|
|
/packages/models/models/src/index.ts
|
0 problems
|
|
|
/packages/models/models/src/interfaces/index.ts
|
0 problems
|
|
|
/packages/models/models/src/interfaces/person.ts
|
0 problems
|
|
|
/packages/models/models/src/models/index.ts
|
0 problems
|
|
|
/packages/models/models/src/models/person.ts
|
0 problems
|
|
|
/packages/models/models/tests/models/person.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/models/models/tests/models/person.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Person, PersonModel } from "@models/index"; |
| 2 |
|
| 3 |
describe("PersonModel", () => { |
| 4 |
it("should be instantiable", () => { |
| 5 |
const person: Person = { |
| 6 |
address: "Somewhere", |
| 7 |
emailAddress: "john.doe@pm.me", |
| 8 |
firstName: "John", |
| 9 |
lastName: "Doe", |
| 10 |
phoneNumber: "+86 131 2292 5256", |
| 11 |
}; |
| 12 |
|
| 13 |
const model = new PersonModel(person); |
| 14 |
expect(model).not.toBeNull(); |
| 15 |
}); |
| 16 |
|
| 17 |
describe("constructor", (): void => { |
| 18 |
it("should init properties", () => { |
| 19 |
const expected = { |
| 20 |
address: "Somewhere", |
| 21 |
emailAddress: "john.doe@pm.me", |
| 22 |
firstName: "John", |
| 23 |
lastName: "Doe", |
| 24 |
phoneNumber: "+86 131 2292 5256", |
| 25 |
}; |
| 26 |
|
| 27 |
const person: Person = expected; |
| 28 |
|
| 29 |
const model = new PersonModel(person); |
| 30 |
|
| 31 |
expect(model.address).toBe(expected.address); |
| 32 |
expect(model.emailAddress).toBe(expected.emailAddress); |
| 33 |
expect(model.firstName).toBe(expected.firstName); |
| 34 |
expect(model.lastName).toBe(expected.lastName); |
| 35 |
expect(model.phoneNumber).toBe(expected.phoneNumber); |
| 36 |
}); |
| 37 |
}); |
| 38 |
}); |
| 39 |
|
|
|
|
/packages/patterns/command/src/command.ts
|
0 problems
|
|
|
/packages/patterns/command/src/index.ts
|
0 problems
|
|
|
/packages/patterns/command/src/manager.ts
|
0 problems
|
|
|
/packages/patterns/command/tests/command.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/command/tests/command.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Command, CommandManager, CommandResultInterface } from "@patterns-command/index"; |
| 2 |
|
| 3 |
class Target { |
| 4 |
public action() { |
| 5 |
//nothing to do |
| 6 |
} |
| 7 |
|
| 8 |
public cancel() { |
| 9 |
// nothing to do |
| 10 |
} |
| 11 |
} |
| 12 |
|
| 13 |
class ConcreteCommand extends Command { |
| 14 |
protected target: Target; |
| 15 |
|
| 16 |
public constructor(target: Target) { |
| 17 |
super(); |
| 18 |
this.target = target; |
| 19 |
} |
| 20 |
|
| 21 |
public execute(): CommandResultInterface { |
| 22 |
const result = this.target.action(); |
| 23 |
|
| 24 |
return { message: "ok", result }; |
| 25 |
} |
| 26 |
|
| 27 |
public undo(): void { |
| 28 |
this.target.cancel(); |
| 29 |
} |
| 30 |
} |
| 31 |
|
| 32 |
describe("Command Manager", () => { |
| 33 |
beforeEach(() => jest.resetAllMocks()); |
| 34 |
|
| 35 |
it("should be instantiable", () => { |
| 36 |
const manager = new CommandManager(); |
| 37 |
|
| 38 |
expect(manager).not.toBeNull(); |
| 39 |
}); |
| 40 |
|
| 41 |
it("should be able to execute a command", () => { |
| 42 |
const executeSpy = jest.spyOn(ConcreteCommand.prototype, "execute"); |
| 43 |
const actionSpy = jest.spyOn(Target.prototype, "action"); |
| 44 |
|
| 45 |
const target = new Target(); |
| 46 |
|
| 47 |
const manager = new CommandManager(); |
| 48 |
manager.execute(new ConcreteCommand(target)); |
| 49 |
|
| 50 |
expect(executeSpy).toHaveBeenCalledTimes(1); |
| 51 |
expect(actionSpy).toHaveBeenCalledTimes(1); |
| 52 |
}); |
| 53 |
|
| 54 |
describe("redo", () => { |
| 55 |
it("should be able to redo a command", () => { |
| 56 |
const executeSpy = jest.spyOn(ConcreteCommand.prototype, "execute"); |
| 57 |
|
| 58 |
const target = new Target(); |
| 59 |
|
| 60 |
const manager = new CommandManager(); |
| 61 |
manager.execute(new ConcreteCommand(target)); |
| 62 |
manager.redo(); |
| 63 |
|
| 64 |
expect(executeSpy).toHaveBeenCalledTimes(2); |
| 65 |
}); |
| 66 |
|
| 67 |
it("should do nothing if no command has been executed before", () => { |
| 68 |
const executeSpy = jest.spyOn(ConcreteCommand.prototype, "execute"); |
| 69 |
|
| 70 |
const manager = new CommandManager(); |
| 71 |
manager.redo(); |
| 72 |
|
| 73 |
expect(executeSpy).not.toHaveBeenCalled(); |
| 74 |
}); |
| 75 |
}); |
| 76 |
|
| 77 |
describe("undo", () => { |
| 78 |
it("should be able to undo a command", () => { |
| 79 |
const undoSpy = jest.spyOn(ConcreteCommand.prototype, "undo"); |
| 80 |
const cancelSpy = jest.spyOn(Target.prototype, "cancel"); |
| 81 |
|
| 82 |
const target = new Target(); |
| 83 |
|
| 84 |
const manager = new CommandManager(); |
| 85 |
manager.execute(new ConcreteCommand(target)); |
| 86 |
manager.undo(); |
| 87 |
|
| 88 |
expect(undoSpy).toHaveBeenCalledTimes(1); |
| 89 |
expect(cancelSpy).toHaveBeenCalledTimes(1); |
| 90 |
}); |
| 91 |
|
| 92 |
it("should do nothing if no command has been executed before", () => { |
| 93 |
const undoSpy = jest.spyOn(ConcreteCommand.prototype, "undo"); |
| 94 |
|
| 95 |
const manager = new CommandManager(); |
| 96 |
manager.undo(); |
| 97 |
|
| 98 |
expect(undoSpy).not.toHaveBeenCalled(); |
| 99 |
}); |
| 100 |
}); |
| 101 |
}); |
| 102 |
|
|
|
|
/packages/patterns/ecs/src/component.ts
|
0 problems
|
|
|
/packages/patterns/ecs/src/entity.ts
|
0 problems
|
|
|
/packages/patterns/ecs/src/index.ts
|
0 problems
|
|
|
/packages/patterns/ecs/src/system.ts
|
0 problems
|
|
|
/packages/patterns/ecs/src/world.ts
|
0 problems
|
|
|
/packages/patterns/ecs/tests/component.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/ecs/tests/component.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Component } from "@patterns-ecs/index"; |
| 2 |
|
| 3 |
class ConcreteComponent extends Component {} |
| 4 |
|
| 5 |
describe("Component", (): void => { |
| 6 |
it("should be instantiable", (): void => { |
| 7 |
const component = new ConcreteComponent("My awesome component"); |
| 8 |
|
| 9 |
expect(component).not.toBeNull(); |
| 10 |
}); |
| 11 |
|
| 12 |
describe("constructor", (): void => { |
| 13 |
it("should init name", (): void => { |
| 14 |
const expected = "My awesome component"; |
| 15 |
const component = new ConcreteComponent(expected); |
| 16 |
|
| 17 |
expect(component.getName()).toBe(expected); |
| 18 |
}); |
| 19 |
}); |
| 20 |
}); |
| 21 |
|
|
|
|
/packages/patterns/ecs/tests/entity.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/ecs/tests/entity.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { instance, mock, reset, when } from "ts-mockito"; |
| 2 |
|
| 3 |
import { Component, ComponentInterface, Entity } from "@patterns-ecs/index"; |
| 4 |
|
| 5 |
const uuid = "2c5ea4c0-4067-11e9-8bad-9b1deb4d3b7d"; |
| 6 |
|
| 7 |
describe("Entity", (): void => { |
| 8 |
const componentName: ComponentInterface = "My awesome component"; |
| 9 |
const mockComponent: ComponentInterface = mock(Component); |
| 10 |
when(mockComponent.getName()).thenReturn(componentName); |
| 11 |
|
| 12 |
let componentMock: ComponentInterface; |
| 13 |
|
| 14 |
beforeEach(() => { |
| 15 |
componentMock = instance(mockComponent); |
| 16 |
}); |
| 17 |
|
| 18 |
afterAll(() => { |
| 19 |
reset(mockComponent); |
| 20 |
}); |
| 21 |
|
| 22 |
it("should be instantiable", (): void => { |
| 23 |
const entity = new Entity(uuid); |
| 24 |
|
| 25 |
expect(entity).not.toBeNull(); |
| 26 |
}); |
| 27 |
|
| 28 |
describe("constructor", (): void => { |
| 29 |
it("should init id", (): void => { |
| 30 |
const expected = uuid; |
| 31 |
const entity = new Entity(uuid); |
| 32 |
|
| 33 |
expect(entity.getId()).toBe(expected); |
| 34 |
}); |
| 35 |
|
| 36 |
it("should have empty components on init", (): void => { |
| 37 |
const expected = new Map<string, ComponentInterface>(); |
| 38 |
const entity = new Entity(uuid); |
| 39 |
|
| 40 |
expect(entity.getComponents()).toStrictEqual(expected); |
| 41 |
}); |
| 42 |
}); |
| 43 |
|
| 44 |
it("should be able to add component", (): void => { |
| 45 |
const component = componentMock; |
| 46 |
const expected = new Map<string, ComponentInterface>(); |
| 47 |
expected.set(component.getName(), component); |
| 48 |
const entity = new Entity(uuid); |
| 49 |
entity.addComponent(component); |
| 50 |
|
| 51 |
expect(entity.getComponents()).toStrictEqual(expected); |
| 52 |
}); |
| 53 |
|
| 54 |
describe("removeComponent", (): void => { |
| 55 |
it("should be able to remove component", (): void => { |
| 56 |
const component = componentMock; |
| 57 |
const expected1 = new Map<string, ComponentInterface>(); |
| 58 |
expected1.set(component.getName(), component); |
| 59 |
const expected2 = new Map<string, ComponentInterface>(); |
| 60 |
const entity = new Entity(uuid); |
| 61 |
entity.addComponent(component); |
| 62 |
|
| 63 |
expect(entity.getComponents()).toStrictEqual(expected1); |
| 64 |
|
| 65 |
entity.removeComponent(component); |
| 66 |
|
| 67 |
expect(entity.getComponents()).toStrictEqual(expected2); |
| 68 |
}); |
| 69 |
|
| 70 |
it("should do nothing if component is not found", (): void => { |
| 71 |
const component = componentMock; |
| 72 |
|
| 73 |
const expected = new Map<string, ComponentInterface>(); |
| 74 |
|
| 75 |
const entity = new Entity(uuid); |
| 76 |
entity.removeComponent(component); |
| 77 |
|
| 78 |
expect(entity.getComponents()).toStrictEqual(expected); |
| 79 |
}); |
| 80 |
}); |
| 81 |
|
| 82 |
it("should be able to find if a component is present", (): void => { |
| 83 |
const component = componentMock; |
| 84 |
const entity = new Entity(uuid); |
| 85 |
|
| 86 |
entity.addComponent(component); |
| 87 |
|
| 88 |
expect(entity.hasComponent(componentName)).toBe(true); |
| 89 |
}); |
| 90 |
|
| 91 |
it("should be able to retrieve a component", (): void => { |
| 92 |
const expected = componentMock; |
| 93 |
const entity = new Entity(uuid); |
| 94 |
|
| 95 |
entity.addComponent(expected); |
| 96 |
|
| 97 |
expect(entity.getComponent(componentName)).toBe(expected); |
| 98 |
}); |
| 99 |
}); |
| 100 |
|
|
|
|
/packages/patterns/ecs/tests/world.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/ecs/tests/world.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { anything, instance, mock, reset, verify, when } from "ts-mockito"; |
| 2 |
|
| 3 |
import { World, Entity, System } from "@patterns-ecs/index"; |
| 4 |
|
| 5 |
describe("World", (): void => { |
| 6 |
const mockSystem: System = mock(System); |
| 7 |
when(mockSystem.getEntities()).thenReturn(null); |
| 8 |
|
| 9 |
let systemMock: System; |
| 10 |
|
| 11 |
beforeEach(() => { |
| 12 |
systemMock = instance(mockSystem); |
| 13 |
}); |
| 14 |
|
| 15 |
afterAll(() => { |
| 16 |
reset(mockSystem); |
| 17 |
}); |
| 18 |
|
| 19 |
it("should be instantiable", (): void => { |
| 20 |
const manager = new World(); |
| 21 |
|
| 22 |
expect(manager).not.toBeNull(); |
| 23 |
}); |
| 24 |
|
| 25 |
describe("constructor", (): void => { |
| 26 |
it("should be init with empty entities", (): void => { |
| 27 |
const manager = new World(); |
| 28 |
|
| 29 |
expect(manager.getEntities().size).toBe(0); |
| 30 |
}); |
| 31 |
|
| 32 |
it("should be init with empty systems", (): void => { |
| 33 |
const manager = new World(); |
| 34 |
|
| 35 |
expect(manager.getSystems().size).toBe(0); |
| 36 |
}); |
| 37 |
}); |
| 38 |
|
| 39 |
describe("createEntity", (): void => { |
| 40 |
it("should be able to create entity", (): void => { |
| 41 |
const manager = new World(); |
| 42 |
manager.createEntity(); |
| 43 |
|
| 44 |
expect(manager.getEntities().size).toBe(1); |
| 45 |
}); |
| 46 |
|
| 47 |
it("should generate an id for newly created entity", (): void => { |
| 48 |
const manager = new World(); |
| 49 |
const entity = manager.createEntity(); |
| 50 |
|
| 51 |
expect(entity.getId()).not.toBeNull(); |
| 52 |
}); |
| 53 |
}); |
| 54 |
|
| 55 |
describe("removeEntity", (): void => { |
| 56 |
it("should be able to remove entity", (): void => { |
| 57 |
const manager = new World(); |
| 58 |
const entity = manager.createEntity(); |
| 59 |
|
| 60 |
expect(entity).not.toBeNull(); |
| 61 |
expect(entity).toBeInstanceOf(Entity); |
| 62 |
expect(manager.getEntities().size).toBe(1); |
| 63 |
|
| 64 |
manager.removeEntity(entity); |
| 65 |
expect(manager.getEntities().size).toBe(0); |
| 66 |
}); |
| 67 |
|
| 68 |
it("should do nothing when trying to remove unknown entity", (): void => { |
| 69 |
const manager = new World(); |
| 70 |
const entity = manager.createEntity(); |
| 71 |
|
| 72 |
expect(entity).not.toBeNull(); |
| 73 |
expect(entity).toBeInstanceOf(Entity); |
| 74 |
expect(manager.getEntities().size).toBe(1); |
| 75 |
|
| 76 |
manager.removeEntity(new Entity("1024")); |
| 77 |
expect(manager.getEntities().size).toBe(1); |
| 78 |
}); |
| 79 |
}); |
| 80 |
|
| 81 |
// eslint-disable-next-line jest/expect-expect |
| 82 |
it("should be able to process systems", (): void => { |
| 83 |
const manager = new World(); |
| 84 |
manager.registerSystems([systemMock]); |
| 85 |
|
| 86 |
manager.process(); |
| 87 |
verify(mockSystem.run(anything())).once(); |
| 88 |
}); |
| 89 |
|
| 90 |
it("should be able to registers systems", (): void => { |
| 91 |
const manager = new World(); |
| 92 |
|
| 93 |
expect(manager.getSystems().size).toBe(0); |
| 94 |
|
| 95 |
manager.registerSystems([mockSystem]); |
| 96 |
|
| 97 |
expect(manager.getSystems().size).toBe(1); |
| 98 |
expect(manager.getSystems().values().next().value).toBe(mockSystem); |
| 99 |
}); |
| 100 |
}); |
| 101 |
|
|
|
|
/packages/patterns/factory/src/factory.ts
|
0 problems
|
|
|
/packages/patterns/factory/src/index.ts
|
0 problems
|
|
|
/packages/patterns/factory/tests/factory.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/factory/tests/factory.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { AbstractFactory } from "@patterns-factory/index"; |
| 2 |
|
| 3 |
class ConcreteObject {} |
| 4 |
|
| 5 |
class ConcreteFactory extends AbstractFactory<ConcreteObject, string> { |
| 6 |
public create(params: string): ConcreteObject { |
| 7 |
if (null !== params) { |
| 8 |
return new ConcreteObject(); |
| 9 |
} |
| 10 |
} |
| 11 |
} |
| 12 |
|
| 13 |
describe("AbstractFactory", () => { |
| 14 |
describe("create", () => { |
| 15 |
it("should return an object", (): void => { |
| 16 |
const factory = new ConcreteFactory(); |
| 17 |
const result = factory.create("42"); |
| 18 |
|
| 19 |
expect(result).toBeInstanceOf(ConcreteObject); |
| 20 |
}); |
| 21 |
}); |
| 22 |
}); |
| 23 |
|
|
|
|
/packages/patterns/iterator/src/index.ts
|
0 problems
|
|
|
/packages/patterns/iterator/src/iterable.ts
|
0 problems
|
|
|
/packages/patterns/iterator/src/iterator.ts
|
0 problems
|
|
|
/packages/patterns/iterator/tests/iterable.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/iterator/tests/iterable.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Iterable, Iterator } from "@patterns-iterator/index"; |
| 2 |
|
| 3 |
describe("Iterable", () => { |
| 4 |
describe("createIterator", () => { |
| 5 |
it("should return an iterator", () => { |
| 6 |
const iterable = new Iterable<number>([]); |
| 7 |
const iterator = iterable.createIterator(); |
| 8 |
expect(iterator).not.toBeNull(); |
| 9 |
expect(iterator).toBeInstanceOf(Iterator); |
| 10 |
}); |
| 11 |
}); |
| 12 |
}); |
| 13 |
|
|
|
|
/packages/patterns/iterator/tests/iterator.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/iterator/tests/iterator.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Iterator } from "@patterns-iterator/index"; |
| 2 |
|
| 3 |
describe("Iterator", () => { |
| 4 |
describe("hasNext", () => { |
| 5 |
it("should return null when collection is empty", () => { |
| 6 |
const iterator = new Iterator<number>([]); |
| 7 |
|
| 8 |
expect(iterator.hasNext()).toBeFalsy(); |
| 9 |
}); |
| 10 |
|
| 11 |
it("should return true if there is some elements in collection", () => { |
| 12 |
const iterator = new Iterator<number>([1, 2, 3]); |
| 13 |
|
| 14 |
expect(iterator.hasNext()).toBeTruthy(); |
| 15 |
}); |
| 16 |
|
| 17 |
it("should return false when reaching the end of the collection", () => { |
| 18 |
const iterator = new Iterator<number>([1, 2, 3]); |
| 19 |
|
| 20 |
iterator.next(); |
| 21 |
iterator.next(); |
| 22 |
iterator.next(); |
| 23 |
expect(iterator.hasNext()).toBeFalsy(); |
| 24 |
}); |
| 25 |
}); |
| 26 |
|
| 27 |
describe("next", () => { |
| 28 |
it("should return next value in collection", () => { |
| 29 |
const expected = [4, 5, 6]; |
| 30 |
const iterator = new Iterator<number>(expected); |
| 31 |
|
| 32 |
expect(iterator.next()).toEqual(expected[0]); |
| 33 |
expect(iterator.next()).toEqual(expected[1]); |
| 34 |
expect(iterator.next()).toEqual(expected[2]); |
| 35 |
expect(iterator.next()).toBeNull(); |
| 36 |
}); |
| 37 |
}); |
| 38 |
}); |
| 39 |
|
|
|
|
/packages/patterns/money/src/account.ts
|
0 problems
|
|
|
/packages/patterns/money/src/currency.ts
|
0 problems
|
|
|
/packages/patterns/money/src/index.ts
|
0 problems
|
|
|
/packages/patterns/money/src/money.ts
|
0 problems
|
|
|
/packages/patterns/money/tests/account.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/money/tests/account.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Account, Currency, Money } from "@patterns-money/index"; |
| 2 |
|
| 3 |
describe("Account", (): void => { |
| 4 |
it("should be instantiable", (): void => { |
| 5 |
const model = new Account(42); |
| 6 |
expect(model).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
describe("constructor", (): void => { |
| 10 |
it("should set id", (): void => { |
| 11 |
const expected = 42; |
| 12 |
const model = new Account(expected); |
| 13 |
|
| 14 |
expect(model.getId()).toBe(expected); |
| 15 |
}); |
| 16 |
}); |
| 17 |
|
| 18 |
describe("deposit", (): void => { |
| 19 |
it("can add money to account", (): void => { |
| 20 |
const expectedAmount = 123; |
| 21 |
const model = new Account(42); |
| 22 |
|
| 23 |
const currency = new Currency(100, "EUR"); |
| 24 |
expect(model.getBalance(currency)).toBe(0); |
| 25 |
|
| 26 |
const money = new Money(expectedAmount, currency); |
| 27 |
const result = model.deposit(money); |
| 28 |
|
| 29 |
expect(model.getBalance(currency)).toBe(expectedAmount); |
| 30 |
expect(result).toBe(expectedAmount); |
| 31 |
}); |
| 32 |
|
| 33 |
it("should sum money amounts", (): void => { |
| 34 |
const expectedAmount = 123; |
| 35 |
const model = new Account(42); |
| 36 |
|
| 37 |
const currency = new Currency(100, "EUR"); |
| 38 |
expect(model.getBalance(currency)).toBe(0); |
| 39 |
|
| 40 |
const money = new Money(expectedAmount, currency); |
| 41 |
let result = model.deposit(money); |
| 42 |
|
| 43 |
expect(model.getBalance(currency)).toBe(expectedAmount); |
| 44 |
expect(result).toBe(expectedAmount); |
| 45 |
|
| 46 |
result = model.deposit(money); |
| 47 |
|
| 48 |
expect(model.getBalance(currency)).toBe(expectedAmount * 2); |
| 49 |
expect(result).toBe(expectedAmount * 2); |
| 50 |
}); |
| 51 |
}); |
| 52 |
|
| 53 |
describe("withdraw", (): void => { |
| 54 |
it("can withdraw money from account", (): void => { |
| 55 |
const model = new Account(42); |
| 56 |
|
| 57 |
const currency = new Currency(100, "EUR"); |
| 58 |
|
| 59 |
const moneyDeposit = new Money(100, currency); |
| 60 |
model.deposit(moneyDeposit); |
| 61 |
|
| 62 |
const moneyWithdraw = new Money(41, currency); |
| 63 |
const result = model.withdraw(moneyWithdraw); |
| 64 |
|
| 65 |
expect(model.getBalance(currency)).toBe(moneyDeposit.getAmount() - moneyWithdraw.getAmount()); |
| 66 |
expect(result).toBe(moneyDeposit.getAmount() - moneyWithdraw.getAmount()); |
| 67 |
}); |
| 68 |
|
| 69 |
it("should throw an exception if account has no balance for currency", (): void => { |
| 70 |
const model = new Account(42); |
| 71 |
|
| 72 |
const currency = new Currency(100, "EUR"); |
| 73 |
|
| 74 |
const money = new Money(41, currency); |
| 75 |
|
| 76 |
expect(() => { |
| 77 |
model.withdraw(money); |
| 78 |
}).toThrow(`This account has no currency ${currency.getStringRepresentation()}`); |
| 79 |
}); |
| 80 |
|
| 81 |
it("should throw an exception if account has not enough balance for currency", (): void => { |
| 82 |
const model = new Account(42); |
| 83 |
|
| 84 |
const currency = new Currency(100, "EUR"); |
| 85 |
|
| 86 |
const moneyDeposit = new Money(100, currency); |
| 87 |
model.deposit(moneyDeposit); |
| 88 |
|
| 89 |
const moneyWithdraw = new Money(1024, currency); |
| 90 |
|
| 91 |
expect(() => { |
| 92 |
model.withdraw(moneyWithdraw); |
| 93 |
}).toThrow(`Balance is not enough for this withdraw`); |
| 94 |
}); |
| 95 |
}); |
| 96 |
}); |
| 97 |
|
|
|
|
/packages/patterns/money/tests/currency.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/money/tests/currency.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Currency } from "@patterns-money/index"; |
| 2 |
|
| 3 |
describe("Currency", () => { |
| 4 |
it("should be instantiable", (): void => { |
| 5 |
const model = new Currency(); |
| 6 |
expect(model).not.toBeNull(); |
| 7 |
}); |
| 8 |
|
| 9 |
describe("constructor", (): void => { |
| 10 |
it("should init cent factor", (): void => { |
| 11 |
const expected = 100; |
| 12 |
const model = new Currency(expected); |
| 13 |
|
| 14 |
expect(model.getCentFactor()).toBe(expected); |
| 15 |
}); |
| 16 |
|
| 17 |
it("should init string representation", (): void => { |
| 18 |
const expected = "EUR"; |
| 19 |
const model = new Currency(100, expected); |
| 20 |
|
| 21 |
expect(model.getStringRepresentation()).toBe(expected); |
| 22 |
}); |
| 23 |
}); |
| 24 |
}); |
| 25 |
|
|
|
|
/packages/patterns/money/tests/money.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/money/tests/money.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { instance, mock, reset } from "ts-mockito"; |
| 2 |
|
| 3 |
import { CurrencyInterface, Money } from "@patterns-money/index"; |
| 4 |
|
| 5 |
describe("Money", () => { |
| 6 |
const mockCurrencyEUR: CurrencyInterface = mock(CurrencyInterface); |
| 7 |
let currencyMockEUR: CurrencyInterface; |
| 8 |
|
| 9 |
const mockCurrencyUSD: CurrencyInterface = mock(CurrencyInterface); |
| 10 |
let currencyMockUSD: CurrencyInterface; |
| 11 |
|
| 12 |
beforeEach(() => { |
| 13 |
currencyMockEUR = instance(mockCurrencyEUR); |
| 14 |
currencyMockUSD = instance(mockCurrencyUSD); |
| 15 |
}); |
| 16 |
|
| 17 |
afterAll(() => { |
| 18 |
reset(mockCurrencyEUR); |
| 19 |
reset(mockCurrencyUSD); |
| 20 |
}); |
| 21 |
|
| 22 |
it("should be instantiable", (): void => { |
| 23 |
const model = new Money(); |
| 24 |
expect(model).not.toBeNull(); |
| 25 |
}); |
| 26 |
|
| 27 |
describe("constructor", (): void => { |
| 28 |
it("should init amount", (): void => { |
| 29 |
const expected = 42; |
| 30 |
const model = new Money(expected); |
| 31 |
|
| 32 |
expect(model.getAmount()).toBe(expected); |
| 33 |
}); |
| 34 |
|
| 35 |
it("should init currency", (): void => { |
| 36 |
const expected = currencyMockEUR; |
| 37 |
const model = new Money(42, expected); |
| 38 |
|
| 39 |
expect(model.getCurrency()).toBe(expected); |
| 40 |
}); |
| 41 |
}); |
| 42 |
|
| 43 |
describe("mathematical operations", (): void => { |
| 44 |
describe("add", (): void => { |
| 45 |
it("can add amount", (): void => { |
| 46 |
const amount1 = 100; |
| 47 |
const amount2 = 200; |
| 48 |
const model = new Money(amount1, currencyMockEUR); |
| 49 |
const model1 = new Money(amount2, currencyMockEUR); |
| 50 |
|
| 51 |
model.add(model1); |
| 52 |
|
| 53 |
expect(model.getAmount()).toBe(amount1 + amount2); |
| 54 |
}); |
| 55 |
|
| 56 |
it("should return addition amount", (): void => { |
| 57 |
const amount1 = 100; |
| 58 |
const amount2 = 200; |
| 59 |
const model = new Money(amount1, currencyMockEUR); |
| 60 |
const model1 = new Money(amount2, currencyMockEUR); |
| 61 |
|
| 62 |
const result = model.add(model1); |
| 63 |
|
| 64 |
expect(result).toBe(amount1 + amount2); |
| 65 |
}); |
| 66 |
|
| 67 |
it("should throw an exception if both moneys does not use same currency", (): void => { |
| 68 |
expect(() => { |
| 69 |
const amount1 = 100; |
| 70 |
const amount2 = 200; |
| 71 |
const model = new Money(amount1, currencyMockEUR); |
| 72 |
const model1 = new Money(amount2, currencyMockUSD); |
| 73 |
|
| 74 |
model.add(model1); |
| 75 |
}).toThrow("Operation is only permitted on same currency"); |
| 76 |
}); |
| 77 |
}); |
| 78 |
|
| 79 |
describe("substract", (): void => { |
| 80 |
it("can substract amount", (): void => { |
| 81 |
const amount1 = 200; |
| 82 |
const amount2 = 100; |
| 83 |
const model = new Money(amount1, currencyMockEUR); |
| 84 |
const model1 = new Money(amount2, currencyMockEUR); |
| 85 |
|
| 86 |
model.substract(model1); |
| 87 |
|
| 88 |
expect(model.getAmount()).toBe(amount1 - amount2); |
| 89 |
}); |
| 90 |
|
| 91 |
it("should return substraction amount", (): void => { |
| 92 |
const amount1 = 200; |
| 93 |
const amount2 = 100; |
| 94 |
const model = new Money(amount1, currencyMockEUR); |
| 95 |
const model1 = new Money(amount2, currencyMockEUR); |
| 96 |
|
| 97 |
const result = model.substract(model1); |
| 98 |
|
| 99 |
expect(result).toBe(amount1 - amount2); |
| 100 |
}); |
| 101 |
|
| 102 |
it("should throw an exception if both moneys does not use same currency", (): void => { |
| 103 |
expect(() => { |
| 104 |
const amount1 = 200; |
| 105 |
const amount2 = 100; |
| 106 |
const model = new Money(amount1, currencyMockEUR); |
| 107 |
const model1 = new Money(amount2, currencyMockUSD); |
| 108 |
|
| 109 |
model.substract(model1); |
| 110 |
}).toThrow("Operation is only permitted on same currency"); |
| 111 |
}); |
| 112 |
|
| 113 |
it("should throw an exception if amount is not enough", (): void => { |
| 114 |
expect(() => { |
| 115 |
const amount1 = 100; |
| 116 |
const amount2 = 200; |
| 117 |
const model = new Money(amount1, currencyMockEUR); |
| 118 |
const model1 = new Money(amount2, currencyMockEUR); |
| 119 |
|
| 120 |
model.substract(model1); |
| 121 |
}).toThrow("Operation not possible, amount is not enough"); |
| 122 |
}); |
| 123 |
}); |
| 124 |
|
| 125 |
describe("multiply", (): void => { |
| 126 |
it("can multiply amount", (): void => { |
| 127 |
const amount = 100; |
| 128 |
const multiplier = 2; |
| 129 |
const model = new Money(amount, currencyMockEUR); |
| 130 |
|
| 131 |
model.multiply(multiplier); |
| 132 |
|
| 133 |
expect(model.getAmount()).toBe(amount * multiplier); |
| 134 |
}); |
| 135 |
|
| 136 |
it("should return multiplication amount", (): void => { |
| 137 |
const amount = 100; |
| 138 |
const multiplier = 2; |
| 139 |
const model = new Money(amount, currencyMockEUR); |
| 140 |
|
| 141 |
const result = model.multiply(multiplier); |
| 142 |
|
| 143 |
expect(result).toBe(amount * multiplier); |
| 144 |
}); |
| 145 |
}); |
| 146 |
|
| 147 |
describe("divide", (): void => { |
| 148 |
it("can divide amount", (): void => { |
| 149 |
const amount = 100; |
| 150 |
const divider = 2; |
| 151 |
const model = new Money(amount, currencyMockEUR); |
| 152 |
|
| 153 |
model.divide(divider); |
| 154 |
|
| 155 |
expect(model.getAmount()).toBe(amount / divider); |
| 156 |
}); |
| 157 |
|
| 158 |
it("should return division amount", (): void => { |
| 159 |
const amount = 100; |
| 160 |
const divider = 2; |
| 161 |
const model = new Money(amount, currencyMockEUR); |
| 162 |
|
| 163 |
const result = model.divide(divider); |
| 164 |
|
| 165 |
expect(result).toBe(amount / divider); |
| 166 |
}); |
| 167 |
|
| 168 |
it("should throw an exception if divider is inferior or equal to 0", (): void => { |
| 169 |
expect(() => { |
| 170 |
const model = new Money(100, currencyMockEUR); |
| 171 |
|
| 172 |
model.divide(0); |
| 173 |
}).toThrow("Operation not possible, divider should be greater than 0"); |
| 174 |
}); |
| 175 |
}); |
| 176 |
}); |
| 177 |
|
| 178 |
describe("object comparison", (): void => { |
| 179 |
it("can compare objects equality", (): void => { |
| 180 |
const amount = 100; |
| 181 |
const model1 = new Money(amount, currencyMockEUR); |
| 182 |
const model2 = new Money(amount, currencyMockEUR); |
| 183 |
|
| 184 |
expect(model1.isEqualTo(model2)).toBeTruthy(); |
| 185 |
}); |
| 186 |
|
| 187 |
it("can say object is greater than other", (): void => { |
| 188 |
const model1 = new Money(100, currencyMockEUR); |
| 189 |
const model2 = new Money(50, currencyMockEUR); |
| 190 |
|
| 191 |
expect(model1.greaterThan(model2)).toBeTruthy(); |
| 192 |
}); |
| 193 |
|
| 194 |
it("can say object is greater or equal than other", (): void => { |
| 195 |
const model1 = new Money(100, currencyMockEUR); |
| 196 |
const model2 = new Money(50, currencyMockEUR); |
| 197 |
const model3 = new Money(100, currencyMockEUR); |
| 198 |
|
| 199 |
expect(model1.greaterOrEqualThan(model2)).toBeTruthy(); |
| 200 |
expect(model1.greaterOrEqualThan(model3)).toBeTruthy(); |
| 201 |
}); |
| 202 |
|
| 203 |
it("can say object is lower than other", (): void => { |
| 204 |
const model1 = new Money(100, currencyMockEUR); |
| 205 |
const model2 = new Money(150, currencyMockEUR); |
| 206 |
|
| 207 |
expect(model1.lowerThan(model2)).toBeTruthy(); |
| 208 |
}); |
| 209 |
|
| 210 |
it("can say object is lower or equal than other", (): void => { |
| 211 |
const model1 = new Money(50, currencyMockEUR); |
| 212 |
const model2 = new Money(50, currencyMockEUR); |
| 213 |
const model3 = new Money(100, currencyMockEUR); |
| 214 |
|
| 215 |
expect(model1.lowerOrEqualThan(model2)).toBeTruthy(); |
| 216 |
expect(model1.lowerOrEqualThan(model3)).toBeTruthy(); |
| 217 |
}); |
| 218 |
}); |
| 219 |
}); |
| 220 |
|
|
|
|
/packages/patterns/observer/src/index.ts
|
0 problems
|
|
|
/packages/patterns/observer/src/observer.ts
|
0 problems
|
|
|
/packages/patterns/observer/tests/observer.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/observer/tests/observer.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { instance, mock, reset, verify } from "ts-mockito"; |
| 2 |
|
| 3 |
import { Observable, ObserverInterface } from "@patterns-observer/index"; |
| 4 |
|
| 5 |
class ConcreteObservable extends Observable { |
| 6 |
public getObservers(): ObserverInterface[] { |
| 7 |
return this.observers; |
| 8 |
} |
| 9 |
} |
| 10 |
|
| 11 |
describe("Observer Pattern", (): void => { |
| 12 |
const mockObserver: ObserverInterface = mock<ObserverInterface>(); |
| 13 |
|
| 14 |
let observerMock: ObserverInterface; |
| 15 |
|
| 16 |
beforeEach(() => { |
| 17 |
observerMock = instance(mockObserver); |
| 18 |
}); |
| 19 |
|
| 20 |
afterAll(() => { |
| 21 |
reset(mockObserver); |
| 22 |
}); |
| 23 |
|
| 24 |
describe("Observable", (): void => { |
| 25 |
it("should be instantiable", (): void => { |
| 26 |
const model = new ConcreteObservable(); |
| 27 |
expect(model).not.toBeNull(); |
| 28 |
}); |
| 29 |
|
| 30 |
describe("attach", (): void => { |
| 31 |
it("should be able to attach new observer", (): void => { |
| 32 |
const model = new ConcreteObservable(); |
| 33 |
expect(model.getObservers()).toHaveLength(0); |
| 34 |
|
| 35 |
const observer = observerMock; |
| 36 |
model.attach(observer); |
| 37 |
expect(model.getObservers()).toHaveLength(1); |
| 38 |
expect(model.getObservers()[0]).toBe(observer); |
| 39 |
}); |
| 40 |
|
| 41 |
it("should return the number of observers", (): void => { |
| 42 |
const model = new ConcreteObservable(); |
| 43 |
expect(model.getObservers()).toHaveLength(0); |
| 44 |
|
| 45 |
const observer = observerMock; |
| 46 |
const result = model.attach(observer); |
| 47 |
|
| 48 |
expect(result).toBe(1); |
| 49 |
}); |
| 50 |
}); |
| 51 |
|
| 52 |
describe("detach", (): void => { |
| 53 |
it("should be able to detach observer", (): void => { |
| 54 |
const model = new ConcreteObservable(); |
| 55 |
expect(model.getObservers()).toHaveLength(0); |
| 56 |
|
| 57 |
const observer = observerMock; |
| 58 |
model.attach(observer); |
| 59 |
expect(model.getObservers()).toHaveLength(1); |
| 60 |
|
| 61 |
model.detach(observer); |
| 62 |
expect(model.getObservers()).toHaveLength(0); |
| 63 |
}); |
| 64 |
|
| 65 |
it("should return removed observer", (): void => { |
| 66 |
const model = new ConcreteObservable(); |
| 67 |
|
| 68 |
const observer = observerMock; |
| 69 |
const observer1 = observerMock; |
| 70 |
model.attach(observer); |
| 71 |
model.attach(observer1); |
| 72 |
|
| 73 |
const result = model.detach(observer); |
| 74 |
|
| 75 |
expect(result[0]).toBe(observer); |
| 76 |
}); |
| 77 |
}); |
| 78 |
|
| 79 |
it("should be able to notify observers", (): void => { |
| 80 |
const model = new ConcreteObservable(); |
| 81 |
const observer = observerMock; |
| 82 |
const eventMsg = "new event"; |
| 83 |
|
| 84 |
model.attach(observer); |
| 85 |
|
| 86 |
model.notify(eventMsg); |
| 87 |
|
| 88 |
verify(mockObserver.update(model, eventMsg)).once(); |
| 89 |
|
| 90 |
expect(true).toBeTruthy(); |
| 91 |
}); |
| 92 |
}); |
| 93 |
|
| 94 |
describe("Observer", (): void => { |
| 95 |
it("should be instantiable", (): void => { |
| 96 |
const model = new ConcreteObservable(); |
| 97 |
expect(model).not.toBeNull(); |
| 98 |
}); |
| 99 |
}); |
| 100 |
}); |
| 101 |
|
|
|
|
/packages/patterns/singleton/src/index.ts
|
0 problems
|
|
|
/packages/patterns/singleton/src/singleton.ts
|
0 problems
|
|
|
/packages/patterns/singleton/tests/singleton.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/patterns/singleton/tests/singleton.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { Singleton } from "@patterns-singleton/index"; |
| 2 |
|
| 3 |
describe("Singleton", () => { |
| 4 |
describe("getInstance", () => { |
| 5 |
it("should return a singleton object", (): void => { |
| 6 |
const result = Singleton.getInstance(); |
| 7 |
|
| 8 |
expect(result).toBeInstanceOf(Singleton); |
| 9 |
}); |
| 10 |
|
| 11 |
it("should always return the same object", (): void => { |
| 12 |
const result1 = Singleton.getInstance(); |
| 13 |
const result2 = Singleton.getInstance(); |
| 14 |
|
| 15 |
expect(result1).toStrictEqual(result2); |
| 16 |
}); |
| 17 |
}); |
| 18 |
}); |
| 19 |
|
|
|
|
/packages/strings/capitalize/src/capitalize.ts
|
0 problems
|
|
|
/packages/strings/capitalize/src/index.ts
|
0 problems
|
|
|
/packages/strings/capitalize/tests/capitalize.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/strings/capitalize/tests/capitalize.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { capitalize } from "@strings-capitalize/index"; |
| 2 |
|
| 3 |
describe("capitalize", () => { |
| 4 |
it.each([ |
| 5 |
["Foobar", "foobar"], |
| 6 |
["Foobar", "Foobar"], |
| 7 |
["FooBar", "fooBar"], |
| 8 |
])("should return %s for %s", (expected: string, source: string): void => { |
| 9 |
const result = capitalize(source); |
| 10 |
|
| 11 |
expect(result).toBe(expected); |
| 12 |
}); |
| 13 |
|
| 14 |
it("should lower the rest of the string", (): void => { |
| 15 |
const result = capitalize("aZeRtY", true); |
| 16 |
|
| 17 |
expect(result).toBe("Azerty"); |
| 18 |
}); |
| 19 |
}); |
| 20 |
|
|
|
|
/packages/strings/leftpad/src/index.ts
|
0 problems
|
|
|
/packages/strings/leftpad/src/leftpad.ts
|
0 problems
|
|
|
/packages/strings/leftpad/tests/leftpad.spec.ts
|
1 problem (1 error, 0 warnings)
|
| Severity |
Rule |
| Error |
Row , Column : "Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: packages/strings/leftpad/tests/leftpad.spec.ts.
The file must be included in at least one of the projects provided."
|
| Line |
Source |
| 1 |
import { leftPad } from "@strings-leftpad/index"; |
| 2 |
|
| 3 |
describe("leftpad", () => { |
| 4 |
it.each([ |
| 5 |
["000001", "1", 6, "0"], |
| 6 |
["123456", "123456", 6, "0"], |
| 7 |
["1234567", "1234567", 2, "0"], |
| 8 |
])( |
| 9 |
"should return %s for %s with length %n and %s char", |
| 10 |
(expected: string, origin: string, length: number, char: string): void => { |
| 11 |
const result = leftPad(origin, length, char); |
| 12 |
|
| 13 |
expect(result).toBe(expected); |
| 14 |
}, |
| 15 |
); |
| 16 |
|
| 17 |
it("should use '0' as default char", () => { |
| 18 |
const expected = "000123"; |
| 19 |
const result = leftPad("123", 6); |
| 20 |
|
| 21 |
expect(result).toBe(expected); |
| 22 |
}); |
| 23 |
}); |
| 24 |
|
|
|
|
/packages/ui/collapse/src/global.d.ts
|
0 problems
|
|
|
/packages/ui/collapse/src/main.ts
|
0 problems
|
|
|
/packages/ui/tabs/src/global.d.ts
|
0 problems
|
|
|
/packages/ui/tabs/src/main.ts
|
0 problems
|