diff --git a/.eslintrc.json b/.eslintrc.json index 048adaf2..eff0c1c4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,7 +8,8 @@ "ecmaVersion": "latest" }, "plugins": [ - "@typescript-eslint" + "@typescript-eslint", + "jest-extended" ], "rules": { } diff --git a/.gitignore b/.gitignore index f16346c0..63bbe2fd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ src/**/*.d.ts /playwright-report/ /blob-report/ /playwright/.cache/ +.vscode diff --git a/examples/simpleShapeDepthIndex/index.html b/examples/simpleShapeDepthIndex/index.html new file mode 100644 index 00000000..24aced1b --- /dev/null +++ b/examples/simpleShapeDepthIndex/index.html @@ -0,0 +1,39 @@ + + + + + + + + + \ No newline at end of file diff --git a/jest.config.js b/jest.config.js index 2b09ffc3..fac2d562 100644 --- a/jest.config.js +++ b/jest.config.js @@ -5,5 +5,11 @@ module.exports = { testMatch: ['/test/unit/**/*.test.ts'], setupFiles: [ "jest-canvas-mock" - ] + ], + setupFilesAfterEnv: ["jest-extended/all"], + globals: { + 'ts-jest': { + tsConfig: './test/unit/tsconfig.json' + } + } }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2225c4b6..89139209 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "jest": "^29.7.0", "jest-canvas-mock": "^2.5.2", "jest-environment-jsdom": "^29.7.0", + "jest-extended": "^4.0.2", "ts-jest": "^29.1.1", "ts-loader": "^9.5.1", "typescript": "^5.3.2", @@ -4721,6 +4722,27 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-extended": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-4.0.2.tgz", + "integrity": "sha512-FH7aaPgtGYHc9mRjriS0ZEHYM5/W69tLrFTIdzm+yJgeoCmmrSB/luSfMSqWP9O29QWHPEmJ4qmU6EwsZideog==", + "dev": true, + "dependencies": { + "jest-diff": "^29.0.0", + "jest-get-type": "^29.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "jest": ">=27.2.5" + }, + "peerDependenciesMeta": { + "jest": { + "optional": true + } + } + }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", diff --git a/package.json b/package.json index 30a1c894..36d7d1bf 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "jest": "^29.7.0", "jest-canvas-mock": "^2.5.2", "jest-environment-jsdom": "^29.7.0", + "jest-extended": "^4.0.2", "ts-jest": "^29.1.1", "ts-loader": "^9.5.1", "typescript": "^5.3.2", diff --git a/src/ecs/components/TransformComponent.ts b/src/ecs/components/TransformComponent.ts index ee4c1fd8..36b5142f 100644 --- a/src/ecs/components/TransformComponent.ts +++ b/src/ecs/components/TransformComponent.ts @@ -12,5 +12,6 @@ interface Size2D { export class TransformComponent extends BaseComponent { public position: Position2D = { x: 0, y: 0 }; - public size: Size2D = { width: 0, height: 0 }; + public size: Size2D = { width: 0, height: 0 }; + public depthIndex: number = 0; } \ No newline at end of file diff --git a/src/ecs/systems/RenderSystem.ts b/src/ecs/systems/RenderSystem.ts index 753498f0..1e521426 100644 --- a/src/ecs/systems/RenderSystem.ts +++ b/src/ecs/systems/RenderSystem.ts @@ -14,6 +14,8 @@ export class RenderSystem implements ISystem { } public update(): void { - this.components.forEach(component => component.draw(this.renderer)); + this.components + .sort((prevComponent, currentComponent) => currentComponent.transform.depthIndex - prevComponent.transform.depthIndex) + .forEach(component => component.draw(this.renderer)); } } \ No newline at end of file diff --git a/test/unit/ecs/systems/RenderSystem.test.ts b/test/unit/ecs/systems/RenderSystem.test.ts index 28653793..ae5c0522 100644 --- a/test/unit/ecs/systems/RenderSystem.test.ts +++ b/test/unit/ecs/systems/RenderSystem.test.ts @@ -1,6 +1,8 @@ import { CanvasDevice, RenderSystem, Renderer, ShapeComponent } from "../../../../src"; describe('systems/RenderSystem', () => { + + describe('.registerComponent()', () => { const renderSystem = new RenderSystem(new Renderer(new CanvasDevice())); const myTestShape = new ShapeComponent(); @@ -13,9 +15,14 @@ describe('systems/RenderSystem', () => { }) describe('.update()', () => { - const renderSystem = new RenderSystem(new Renderer(new CanvasDevice())); + + afterEach(() => { + jest.clearAllMocks(); + jest.resetAllMocks(); + }) it('Should draw renderable object', () => { + const renderSystem = new RenderSystem(new Renderer(new CanvasDevice())); const drawSpy = jest.spyOn(ShapeComponent.prototype, 'draw'); renderSystem.registerComponent(new ShapeComponent()); @@ -24,9 +31,26 @@ describe('systems/RenderSystem', () => { renderSystem.update(); expect(drawSpy).toHaveBeenCalledTimes(2); + drawSpy.mockRestore(); }); - it.todo('Should render objects based on their depthIndex in reverse order (0 rendered last)') + it('Should render objects based on their depthIndex in reverse order (0 rendered last)', () => { + const renderSystem = new RenderSystem(new Renderer(new CanvasDevice())); + const component = new ShapeComponent(); + const component2 = new ShapeComponent(); + + component2.transform.depthIndex = 1; + + renderSystem.registerComponent(component); + renderSystem.registerComponent(component2); + + const drawSpy = jest.spyOn(component, 'draw'); + const drawSpy2 = jest.spyOn(component2, 'draw'); + + renderSystem.update(); + + expect(drawSpy2).toHaveBeenCalledBefore(drawSpy); + }); it.todo('Should render object based on their transparency (transparent last)') }) diff --git a/test/unit/tsconfig.json b/test/unit/tsconfig.json new file mode 100644 index 00000000..4521f5a6 --- /dev/null +++ b/test/unit/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2016", + "module": "commonjs", + "baseUrl": "../../", + "esModuleInterop": true, + "strict": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noEmit": true + }, + "files": ["../../node_modules/jest-extended/types/index.d.ts"], + "include": ["./**/*.test.ts"], +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index b843d8f0..73a310f0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -101,5 +101,5 @@ "exclude": [ "./test", "playwright.config.ts" - ] + ], } \ No newline at end of file