mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-04-02 07:58:50 +01:00
[Test] [Refactor] [GitHub] Enable no isolate for vitest (#5566)
* Reuse global scene between tests Co-authored-by: PigeonBar <56974298+PigeonBar@users.noreply.github.com> * Add missing each method to mockContainer * Fix select-modifier-phase test * Sanitize overrides before tests Co-authored-by: PigeonBar <56974298+PigeonBar@users.noreply.github.com> * Sanitize overrides before tests Co-authored-by: PigeonBar <56974298+PigeonBar@users.noreply.github.com> * [WIP] fix things * Fix tests not working with --no-isolate * Update npm tests to use no isolate * Update test-shard-template * Update package.json Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --------- Co-authored-by: PigeonBar <56974298+PigeonBar@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
This commit is contained in:
parent
b838d5f775
commit
35e733e87a
2
.github/workflows/test-shard-template.yml
vendored
2
.github/workflows/test-shard-template.yml
vendored
@ -29,4 +29,4 @@ jobs:
|
|||||||
- name: Install Node.js dependencies
|
- name: Install Node.js dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: npx vitest --project ${{ inputs.project }} --shard=${{ inputs.shard }}/${{ inputs.totalShards }} ${{ !runner.debug && '--silent' || '' }}
|
run: npx vitest --project ${{ inputs.project }} --no-isolate --shard=${{ inputs.shard }}/${{ inputs.totalShards }} ${{ !runner.debug && '--silent' || '' }}
|
||||||
|
21
.github/workflows/tests.yml
vendored
21
.github/workflows/tests.yml
vendored
@ -15,29 +15,8 @@ on:
|
|||||||
types: [checks_requested]
|
types: [checks_requested]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-test:
|
|
||||||
name: Run Pre-test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out Git repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: 'recursive'
|
|
||||||
path: tests-action
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- name: Install Node.js dependencies
|
|
||||||
working-directory: tests-action
|
|
||||||
run: npm ci
|
|
||||||
- name: Run Pre-test
|
|
||||||
working-directory: tests-action
|
|
||||||
run: npx vitest run --project pre ${{ !runner.debug && '--silent' || '' }}
|
|
||||||
|
|
||||||
run-tests:
|
run-tests:
|
||||||
name: Run Tests
|
name: Run Tests
|
||||||
needs: [pre-test]
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||||
|
@ -13,7 +13,7 @@ pre-push:
|
|||||||
commands:
|
commands:
|
||||||
biome-lint:
|
biome-lint:
|
||||||
glob: "*.{js,ts,jsx,tsx}"
|
glob: "*.{js,ts,jsx,tsx}"
|
||||||
run: npx @biomejs/biome check --write --reporter=summary {push_files} --no-errors-on-unmatched
|
run: npx @biomejs/biome check --reporter=summary {push_files} --no-errors-on-unmatched
|
||||||
|
|
||||||
post-merge:
|
post-merge:
|
||||||
commands:
|
commands:
|
||||||
|
174
package-lock.json
generated
174
package-lock.json
generated
@ -29,7 +29,7 @@
|
|||||||
"@types/node": "^20.12.13",
|
"@types/node": "^20.12.13",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54",
|
"@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54",
|
||||||
"@typescript-eslint/parser": "^8.0.0-alpha.54",
|
"@typescript-eslint/parser": "^8.0.0-alpha.54",
|
||||||
"@vitest/coverage-istanbul": "^2.1.9",
|
"@vitest/coverage-istanbul": "^3.0.9",
|
||||||
"dependency-cruiser": "^16.3.10",
|
"dependency-cruiser": "^16.3.10",
|
||||||
"eslint": "^9.7.0",
|
"eslint": "^9.7.0",
|
||||||
"eslint-plugin-import-x": "^4.2.1",
|
"eslint-plugin-import-x": "^4.2.1",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"typescript-eslint": "^8.0.0-alpha.54",
|
"typescript-eslint": "^8.0.0-alpha.54",
|
||||||
"vite": "^5.4.14",
|
"vite": "^5.4.14",
|
||||||
"vite-tsconfig-paths": "^4.3.2",
|
"vite-tsconfig-paths": "^4.3.2",
|
||||||
"vitest": "^2.1.9",
|
"vitest": "^3.0.9",
|
||||||
"vitest-canvas-mock": "^0.3.3"
|
"vitest-canvas-mock": "^0.3.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2312,14 +2312,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/coverage-istanbul": {
|
"node_modules/@vitest/coverage-istanbul": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-3.0.9.tgz",
|
||||||
"integrity": "sha512-vdYE4FkC/y2lxcN3Dcj54Bw+ericmDwiex0B8LV5F/YNYEYP1mgVwhPnHwWGAXu38qizkjOuyczKbFTALfzFKw==",
|
"integrity": "sha512-/TXh2qmOhclmVPjOnPTpIO4Xr6l2P5EwyXQygenwq4/ZQ/vPsrz+GCRZF9kBeQi6xrGcHv368Si9PGImWQawVg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@istanbuljs/schema": "^0.1.3",
|
"@istanbuljs/schema": "^0.1.3",
|
||||||
"debug": "^4.3.7",
|
"debug": "^4.4.0",
|
||||||
"istanbul-lib-coverage": "^3.2.2",
|
"istanbul-lib-coverage": "^3.2.2",
|
||||||
"istanbul-lib-instrument": "^6.0.3",
|
"istanbul-lib-instrument": "^6.0.3",
|
||||||
"istanbul-lib-report": "^3.0.1",
|
"istanbul-lib-report": "^3.0.1",
|
||||||
@ -2327,48 +2327,48 @@
|
|||||||
"istanbul-reports": "^3.1.7",
|
"istanbul-reports": "^3.1.7",
|
||||||
"magicast": "^0.3.5",
|
"magicast": "^0.3.5",
|
||||||
"test-exclude": "^7.0.1",
|
"test-exclude": "^7.0.1",
|
||||||
"tinyrainbow": "^1.2.0"
|
"tinyrainbow": "^2.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vitest": "2.1.9"
|
"vitest": "3.0.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/expect": {
|
"node_modules/@vitest/expect": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.9.tgz",
|
||||||
"integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==",
|
"integrity": "sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/spy": "2.1.9",
|
"@vitest/spy": "3.0.9",
|
||||||
"@vitest/utils": "2.1.9",
|
"@vitest/utils": "3.0.9",
|
||||||
"chai": "^5.1.2",
|
"chai": "^5.2.0",
|
||||||
"tinyrainbow": "^1.2.0"
|
"tinyrainbow": "^2.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/mocker": {
|
"node_modules/@vitest/mocker": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.9.tgz",
|
||||||
"integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==",
|
"integrity": "sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/spy": "2.1.9",
|
"@vitest/spy": "3.0.9",
|
||||||
"estree-walker": "^3.0.3",
|
"estree-walker": "^3.0.3",
|
||||||
"magic-string": "^0.30.12"
|
"magic-string": "^0.30.17"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"msw": "^2.4.9",
|
"msw": "^2.4.9",
|
||||||
"vite": "^5.0.0"
|
"vite": "^5.0.0 || ^6.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"msw": {
|
"msw": {
|
||||||
@ -2380,51 +2380,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/pretty-format": {
|
"node_modules/@vitest/pretty-format": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.9.tgz",
|
||||||
"integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==",
|
"integrity": "sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tinyrainbow": "^1.2.0"
|
"tinyrainbow": "^2.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/runner": {
|
"node_modules/@vitest/runner": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.9.tgz",
|
||||||
"integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==",
|
"integrity": "sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/utils": "2.1.9",
|
"@vitest/utils": "3.0.9",
|
||||||
"pathe": "^1.1.2"
|
"pathe": "^2.0.3"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/snapshot": {
|
"node_modules/@vitest/snapshot": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.9.tgz",
|
||||||
"integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==",
|
"integrity": "sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/pretty-format": "2.1.9",
|
"@vitest/pretty-format": "3.0.9",
|
||||||
"magic-string": "^0.30.12",
|
"magic-string": "^0.30.17",
|
||||||
"pathe": "^1.1.2"
|
"pathe": "^2.0.3"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/spy": {
|
"node_modules/@vitest/spy": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.9.tgz",
|
||||||
"integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==",
|
"integrity": "sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -2435,15 +2435,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/utils": {
|
"node_modules/@vitest/utils": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.9.tgz",
|
||||||
"integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==",
|
"integrity": "sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/pretty-format": "2.1.9",
|
"@vitest/pretty-format": "3.0.9",
|
||||||
"loupe": "^3.1.2",
|
"loupe": "^3.1.3",
|
||||||
"tinyrainbow": "^1.2.0"
|
"tinyrainbow": "^2.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
@ -2738,9 +2738,9 @@
|
|||||||
"license": "CC-BY-4.0"
|
"license": "CC-BY-4.0"
|
||||||
},
|
},
|
||||||
"node_modules/chai": {
|
"node_modules/chai": {
|
||||||
"version": "5.1.2",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz",
|
||||||
"integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==",
|
"integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -5450,9 +5450,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pathe": {
|
"node_modules/pathe": {
|
||||||
"version": "1.1.2",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||||
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
|
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@ -6308,9 +6308,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tinyrainbow": {
|
"node_modules/tinyrainbow": {
|
||||||
"version": "1.2.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
|
||||||
"integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==",
|
"integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -6677,23 +6677,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite-node": {
|
"node_modules/vite-node": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.9.tgz",
|
||||||
"integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==",
|
"integrity": "sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cac": "^6.7.14",
|
"cac": "^6.7.14",
|
||||||
"debug": "^4.3.7",
|
"debug": "^4.4.0",
|
||||||
"es-module-lexer": "^1.5.4",
|
"es-module-lexer": "^1.6.0",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^2.0.3",
|
||||||
"vite": "^5.0.0"
|
"vite": "^5.0.0 || ^6.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vite-node": "vite-node.mjs"
|
"vite-node": "vite-node.mjs"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.0.0 || >=20.0.0"
|
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
@ -6720,47 +6720,48 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vitest": {
|
"node_modules/vitest": {
|
||||||
"version": "2.1.9",
|
"version": "3.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz",
|
||||||
"integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==",
|
"integrity": "sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/expect": "2.1.9",
|
"@vitest/expect": "3.0.9",
|
||||||
"@vitest/mocker": "2.1.9",
|
"@vitest/mocker": "3.0.9",
|
||||||
"@vitest/pretty-format": "^2.1.9",
|
"@vitest/pretty-format": "^3.0.9",
|
||||||
"@vitest/runner": "2.1.9",
|
"@vitest/runner": "3.0.9",
|
||||||
"@vitest/snapshot": "2.1.9",
|
"@vitest/snapshot": "3.0.9",
|
||||||
"@vitest/spy": "2.1.9",
|
"@vitest/spy": "3.0.9",
|
||||||
"@vitest/utils": "2.1.9",
|
"@vitest/utils": "3.0.9",
|
||||||
"chai": "^5.1.2",
|
"chai": "^5.2.0",
|
||||||
"debug": "^4.3.7",
|
"debug": "^4.4.0",
|
||||||
"expect-type": "^1.1.0",
|
"expect-type": "^1.1.0",
|
||||||
"magic-string": "^0.30.12",
|
"magic-string": "^0.30.17",
|
||||||
"pathe": "^1.1.2",
|
"pathe": "^2.0.3",
|
||||||
"std-env": "^3.8.0",
|
"std-env": "^3.8.0",
|
||||||
"tinybench": "^2.9.0",
|
"tinybench": "^2.9.0",
|
||||||
"tinyexec": "^0.3.1",
|
"tinyexec": "^0.3.2",
|
||||||
"tinypool": "^1.0.1",
|
"tinypool": "^1.0.2",
|
||||||
"tinyrainbow": "^1.2.0",
|
"tinyrainbow": "^2.0.0",
|
||||||
"vite": "^5.0.0",
|
"vite": "^5.0.0 || ^6.0.0",
|
||||||
"vite-node": "2.1.9",
|
"vite-node": "3.0.9",
|
||||||
"why-is-node-running": "^2.3.0"
|
"why-is-node-running": "^2.3.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vitest": "vitest.mjs"
|
"vitest": "vitest.mjs"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.0.0 || >=20.0.0"
|
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@edge-runtime/vm": "*",
|
"@edge-runtime/vm": "*",
|
||||||
"@types/node": "^18.0.0 || >=20.0.0",
|
"@types/debug": "^4.1.12",
|
||||||
"@vitest/browser": "2.1.9",
|
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
|
||||||
"@vitest/ui": "2.1.9",
|
"@vitest/browser": "3.0.9",
|
||||||
|
"@vitest/ui": "3.0.9",
|
||||||
"happy-dom": "*",
|
"happy-dom": "*",
|
||||||
"jsdom": "*"
|
"jsdom": "*"
|
||||||
},
|
},
|
||||||
@ -6768,6 +6769,9 @@
|
|||||||
"@edge-runtime/vm": {
|
"@edge-runtime/vm": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"@types/debug": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
12
package.json
12
package.json
@ -9,10 +9,10 @@
|
|||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"build:beta": "vite build --mode beta",
|
"build:beta": "vite build --mode beta",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test": "vitest run --project pre && vitest run --project main",
|
"test": "vitest run",
|
||||||
"test:cov": "vitest run --project pre && vitest run --project main --coverage",
|
"test:cov": "vitest run --coverage --no-isolate",
|
||||||
"test:watch": "vitest run --project pre && vitest watch --project main --coverage",
|
"test:watch": "vitest watch --coverage --no-isolate",
|
||||||
"test:silent": "vitest run --project pre && vitest run --project main --silent",
|
"test:silent": "vitest run --silent --no-isolate",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"eslint": "eslint --fix .",
|
"eslint": "eslint --fix .",
|
||||||
"eslint-ci": "eslint .",
|
"eslint-ci": "eslint .",
|
||||||
@ -36,7 +36,7 @@
|
|||||||
"@types/node": "^20.12.13",
|
"@types/node": "^20.12.13",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54",
|
"@typescript-eslint/eslint-plugin": "^8.0.0-alpha.54",
|
||||||
"@typescript-eslint/parser": "^8.0.0-alpha.54",
|
"@typescript-eslint/parser": "^8.0.0-alpha.54",
|
||||||
"@vitest/coverage-istanbul": "^2.1.9",
|
"@vitest/coverage-istanbul": "^3.0.9",
|
||||||
"dependency-cruiser": "^16.3.10",
|
"dependency-cruiser": "^16.3.10",
|
||||||
"eslint": "^9.7.0",
|
"eslint": "^9.7.0",
|
||||||
"eslint-plugin-import-x": "^4.2.1",
|
"eslint-plugin-import-x": "^4.2.1",
|
||||||
@ -50,7 +50,7 @@
|
|||||||
"typescript-eslint": "^8.0.0-alpha.54",
|
"typescript-eslint": "^8.0.0-alpha.54",
|
||||||
"vite": "^5.4.14",
|
"vite": "^5.4.14",
|
||||||
"vite-tsconfig-paths": "^4.3.2",
|
"vite-tsconfig-paths": "^4.3.2",
|
||||||
"vitest": "^2.1.9",
|
"vitest": "^3.0.9",
|
||||||
"vitest-canvas-mock": "^0.3.3"
|
"vitest-canvas-mock": "^0.3.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
16
src/@types/DexData.ts
Normal file
16
src/@types/DexData.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Dex entry for a single Pokemon Species
|
||||||
|
*/
|
||||||
|
export interface DexEntry {
|
||||||
|
seenAttr: bigint;
|
||||||
|
caughtAttr: bigint;
|
||||||
|
natureAttr: number;
|
||||||
|
seenCount: number;
|
||||||
|
caughtCount: number;
|
||||||
|
hatchedCount: number;
|
||||||
|
ivs: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DexData {
|
||||||
|
[key: number]: DexEntry;
|
||||||
|
}
|
@ -1403,7 +1403,10 @@ export default class BattleScene extends SceneBase {
|
|||||||
this.field.add(newTrainer);
|
this.field.add(newTrainer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!this.gameMode.hasTrainers) {
|
if (
|
||||||
|
!this.gameMode.hasTrainers ||
|
||||||
|
(Overrides.DISABLE_STANDARD_TRAINERS_OVERRIDE && isNullOrUndefined(trainerData))
|
||||||
|
) {
|
||||||
newBattleType = BattleType.WILD;
|
newBattleType = BattleType.WILD;
|
||||||
} else if (battleType === undefined) {
|
} else if (battleType === undefined) {
|
||||||
newBattleType = this.gameMode.isWaveTrainer(newWaveIndex, this.arena) ? BattleType.TRAINER : BattleType.WILD;
|
newBattleType = this.gameMode.isWaveTrainer(newWaveIndex, this.arena) ? BattleType.TRAINER : BattleType.WILD;
|
||||||
@ -2721,6 +2724,18 @@ export default class BattleScene extends SceneBase {
|
|||||||
this.phaseQueue.splice(0, this.phaseQueue.length);
|
this.phaseQueue.splice(0, this.phaseQueue.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all phase-related stuff, including all phase queues, the current and standby phases, and a splice index
|
||||||
|
*/
|
||||||
|
clearAllPhases(): void {
|
||||||
|
for (const queue of [this.phaseQueue, this.phaseQueuePrepend, this.conditionalQueue, this.nextCommandPhaseQueue]) {
|
||||||
|
queue.splice(0, queue.length);
|
||||||
|
}
|
||||||
|
this.currentPhase = null;
|
||||||
|
this.standbyPhase = null;
|
||||||
|
this.clearPhaseQueueSplice();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by function unshiftPhase(), sets index to start inserting at current length instead of the end of the array, useful if phaseQueuePrepend gets longer with Phases
|
* Used by function unshiftPhase(), sets index to start inserting at current length instead of the end of the array, useful if phaseQueuePrepend gets longer with Phases
|
||||||
*/
|
*/
|
||||||
|
@ -254,6 +254,11 @@ class DefaultOverrides {
|
|||||||
* Note that, for all items in the array, `count` is not used.
|
* Note that, for all items in the array, `count` is not used.
|
||||||
*/
|
*/
|
||||||
readonly ITEM_REWARD_OVERRIDE: ModifierOverride[] = [];
|
readonly ITEM_REWARD_OVERRIDE: ModifierOverride[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `true`, disable all non-scripted opponent trainer encounters.
|
||||||
|
*/
|
||||||
|
readonly DISABLE_STANDARD_TRAINERS_OVERRIDE: boolean = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultOverrides = new DefaultOverrides();
|
export const defaultOverrides = new DefaultOverrides();
|
||||||
|
@ -98,12 +98,13 @@ export function getDataTypeKey(dataType: GameDataType, slotId = 0): string {
|
|||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case GameDataType.SYSTEM:
|
case GameDataType.SYSTEM:
|
||||||
return "data";
|
return "data";
|
||||||
case GameDataType.SESSION:
|
case GameDataType.SESSION: {
|
||||||
let ret = "sessionData";
|
let ret = "sessionData";
|
||||||
if (slotId) {
|
if (slotId) {
|
||||||
ret += slotId;
|
ret += slotId;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
case GameDataType.SETTINGS:
|
case GameDataType.SETTINGS:
|
||||||
return "settings";
|
return "settings";
|
||||||
case GameDataType.TUTORIALS:
|
case GameDataType.TUTORIALS:
|
||||||
@ -201,39 +202,6 @@ export interface DexEntry {
|
|||||||
ivs: number[];
|
ivs: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DexAttr = {
|
|
||||||
NON_SHINY: 1n,
|
|
||||||
SHINY: 2n,
|
|
||||||
MALE: 4n,
|
|
||||||
FEMALE: 8n,
|
|
||||||
DEFAULT_VARIANT: 16n,
|
|
||||||
VARIANT_2: 32n,
|
|
||||||
VARIANT_3: 64n,
|
|
||||||
DEFAULT_FORM: 128n,
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface DexAttrProps {
|
|
||||||
shiny: boolean;
|
|
||||||
female: boolean;
|
|
||||||
variant: Variant;
|
|
||||||
formIndex: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AbilityAttr = {
|
|
||||||
ABILITY_1: 1,
|
|
||||||
ABILITY_2: 2,
|
|
||||||
ABILITY_HIDDEN: 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RunHistoryData = Record<number, RunEntry>;
|
|
||||||
|
|
||||||
export interface RunEntry {
|
|
||||||
entry: SessionSaveData;
|
|
||||||
isVictory: boolean;
|
|
||||||
/*Automatically set to false at the moment - implementation TBD*/
|
|
||||||
isFavorite: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type StarterMoveset = [Moves] | [Moves, Moves] | [Moves, Moves, Moves] | [Moves, Moves, Moves, Moves];
|
export type StarterMoveset = [Moves] | [Moves, Moves] | [Moves, Moves, Moves] | [Moves, Moves, Moves, Moves];
|
||||||
|
|
||||||
export interface StarterFormMoveData {
|
export interface StarterFormMoveData {
|
||||||
@ -260,6 +228,39 @@ export interface StarterPreferences {
|
|||||||
[key: number]: StarterAttributes;
|
[key: number]: StarterAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DexAttrProps {
|
||||||
|
shiny: boolean;
|
||||||
|
female: boolean;
|
||||||
|
variant: Variant;
|
||||||
|
formIndex: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RunHistoryData = Record<number, RunEntry>;
|
||||||
|
|
||||||
|
export interface RunEntry {
|
||||||
|
entry: SessionSaveData;
|
||||||
|
isVictory: boolean;
|
||||||
|
/*Automatically set to false at the moment - implementation TBD*/
|
||||||
|
isFavorite: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DexAttr = {
|
||||||
|
NON_SHINY: 1n,
|
||||||
|
SHINY: 2n,
|
||||||
|
MALE: 4n,
|
||||||
|
FEMALE: 8n,
|
||||||
|
DEFAULT_VARIANT: 16n,
|
||||||
|
VARIANT_2: 32n,
|
||||||
|
VARIANT_3: 64n,
|
||||||
|
DEFAULT_FORM: 128n,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AbilityAttr = {
|
||||||
|
ABILITY_1: 1,
|
||||||
|
ABILITY_2: 2,
|
||||||
|
ABILITY_HIDDEN: 4,
|
||||||
|
};
|
||||||
|
|
||||||
// the latest data saved/loaded for the Starter Preferences. Required to reduce read/writes. Initialize as "{}", since this is the default value and no data needs to be stored if present.
|
// the latest data saved/loaded for the Starter Preferences. Required to reduce read/writes. Initialize as "{}", since this is the default value and no data needs to be stored if present.
|
||||||
// if they ever add private static variables, move this into StarterPrefs
|
// if they ever add private static variables, move this into StarterPrefs
|
||||||
const StarterPrefers_DEFAULT: string = "{}";
|
const StarterPrefers_DEFAULT: string = "{}";
|
||||||
@ -1553,16 +1554,18 @@ export class GameData {
|
|||||||
try {
|
try {
|
||||||
dataName = GameDataType[dataType].toLowerCase();
|
dataName = GameDataType[dataType].toLowerCase();
|
||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case GameDataType.SYSTEM:
|
case GameDataType.SYSTEM: {
|
||||||
dataStr = this.convertSystemDataStr(dataStr);
|
dataStr = this.convertSystemDataStr(dataStr);
|
||||||
const systemData = this.parseSystemData(dataStr);
|
const systemData = this.parseSystemData(dataStr);
|
||||||
valid = !!systemData.dexData && !!systemData.timestamp;
|
valid = !!systemData.dexData && !!systemData.timestamp;
|
||||||
break;
|
break;
|
||||||
case GameDataType.SESSION:
|
}
|
||||||
|
case GameDataType.SESSION: {
|
||||||
const sessionData = this.parseSessionData(dataStr);
|
const sessionData = this.parseSessionData(dataStr);
|
||||||
valid = !!sessionData.party && !!sessionData.enemyParty && !!sessionData.timestamp;
|
valid = !!sessionData.party && !!sessionData.enemyParty && !!sessionData.timestamp;
|
||||||
break;
|
break;
|
||||||
case GameDataType.RUN_HISTORY:
|
}
|
||||||
|
case GameDataType.RUN_HISTORY: {
|
||||||
const data = JSON.parse(dataStr);
|
const data = JSON.parse(dataStr);
|
||||||
const keys = Object.keys(data);
|
const keys = Object.keys(data);
|
||||||
dataName = i18next.t("menuUiHandler:RUN_HISTORY").toLowerCase();
|
dataName = i18next.t("menuUiHandler:RUN_HISTORY").toLowerCase();
|
||||||
@ -1572,6 +1575,7 @@ export class GameData {
|
|||||||
["isFavorite", "isVictory", "entry"].every(v => entryKeys.includes(v)) && entryKeys.length === 3;
|
["isFavorite", "isVictory", "entry"].every(v => entryKeys.includes(v)) && entryKeys.length === 3;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GameDataType.SETTINGS:
|
case GameDataType.SETTINGS:
|
||||||
case GameDataType.TUTORIALS:
|
case GameDataType.TUTORIALS:
|
||||||
valid = true;
|
valid = true;
|
||||||
|
@ -4553,4 +4553,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
icon.setFrame(species.getIconId(female, formIndex, false, variant));
|
icon.setFrame(species.getIconId(female, formIndex, false, variant));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears this UI's starter preferences.
|
||||||
|
*
|
||||||
|
* Designed to be used for unit tests that utilize this UI.
|
||||||
|
*/
|
||||||
|
clearStarterPreferences() {
|
||||||
|
this.starterPreferences = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ describe("Abilities - Steely Spirit", () => {
|
|||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
const steelySpiritMultiplier = 1.5;
|
const steelySpiritMultiplier = 1.5;
|
||||||
const moveToCheck = Moves.IRON_HEAD;
|
const moveToCheck = Moves.IRON_HEAD;
|
||||||
const ironHeadPower = allMoves[moveToCheck].power;
|
|
||||||
|
let ironHeadPower: number;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -25,6 +26,7 @@ describe("Abilities - Steely Spirit", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
ironHeadPower = allMoves[moveToCheck].power;
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override.battleType("double");
|
game.override.battleType("double");
|
||||||
game.override.enemySpecies(Species.SHUCKLE);
|
game.override.enemySpecies(Species.SHUCKLE);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Moves } from "#app/enums/moves";
|
import { Moves } from "#app/enums/moves";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
@ -12,8 +13,8 @@ describe("Abilities - Supreme Overlord", () => {
|
|||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const move = allMoves[Moves.TACKLE];
|
let move: Move;
|
||||||
const basePower = move.power;
|
let basePower: number;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -26,6 +27,8 @@ describe("Abilities - Supreme Overlord", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
move = allMoves[Moves.TACKLE];
|
||||||
|
basePower = move.power;
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.battleType("single")
|
.battleType("single")
|
||||||
|
@ -32,22 +32,22 @@ describe("Abilities - Unseen Fist", () => {
|
|||||||
game.override.enemyLevel(100);
|
game.override.enemyLevel(100);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should cause a contact move to ignore Protect", () =>
|
it("should cause a contact move to ignore Protect", async () =>
|
||||||
testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, true));
|
await testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, true));
|
||||||
|
|
||||||
it("should not cause a non-contact move to ignore Protect", () =>
|
it("should not cause a non-contact move to ignore Protect", async () =>
|
||||||
testUnseenFistHitResult(game, Moves.ABSORB, Moves.PROTECT, false));
|
await testUnseenFistHitResult(game, Moves.ABSORB, Moves.PROTECT, false));
|
||||||
|
|
||||||
it("should not apply if the source has Long Reach", async () => {
|
it("should not apply if the source has Long Reach", async () => {
|
||||||
game.override.passiveAbility(Abilities.LONG_REACH);
|
game.override.passiveAbility(Abilities.LONG_REACH);
|
||||||
await testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, false);
|
await testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should cause a contact move to ignore Wide Guard", () =>
|
it("should cause a contact move to ignore Wide Guard", async () =>
|
||||||
testUnseenFistHitResult(game, Moves.BREAKING_SWIPE, Moves.WIDE_GUARD, true));
|
await testUnseenFistHitResult(game, Moves.BREAKING_SWIPE, Moves.WIDE_GUARD, true));
|
||||||
|
|
||||||
it("should not cause a non-contact move to ignore Wide Guard", () =>
|
it("should not cause a non-contact move to ignore Wide Guard", async () =>
|
||||||
testUnseenFistHitResult(game, Moves.BULLDOZE, Moves.WIDE_GUARD, false));
|
await testUnseenFistHitResult(game, Moves.BULLDOZE, Moves.WIDE_GUARD, false));
|
||||||
|
|
||||||
it("should cause a contact move to ignore Protect, but not Substitute", async () => {
|
it("should cause a contact move to ignore Protect, but not Substitute", async () => {
|
||||||
game.override.enemyLevel(1);
|
game.override.enemyLevel(1);
|
||||||
|
@ -56,16 +56,21 @@ describe("Abilities - Wonder Skin", () => {
|
|||||||
expect(moveToCheck.calculateBattleAccuracy).toHaveReturnedWith(100);
|
expect(moveToCheck.calculateBattleAccuracy).toHaveReturnedWith(100);
|
||||||
});
|
});
|
||||||
|
|
||||||
const bypassAbilities = [Abilities.MOLD_BREAKER, Abilities.TERAVOLT, Abilities.TURBOBLAZE];
|
const bypassAbilities = [
|
||||||
|
[Abilities.MOLD_BREAKER, "Mold Breaker"],
|
||||||
|
[Abilities.TERAVOLT, "Teravolt"],
|
||||||
|
[Abilities.TURBOBLAZE, "Turboblaze"],
|
||||||
|
];
|
||||||
|
|
||||||
bypassAbilities.forEach(ability => {
|
bypassAbilities.forEach(ability => {
|
||||||
it(`does not affect pokemon with ${allAbilities[ability].name}`, async () => {
|
it(`does not affect pokemon with ${ability[1]}`, async () => {
|
||||||
const moveToCheck = allMoves[Moves.CHARM];
|
const moveToCheck = allMoves[Moves.CHARM];
|
||||||
|
|
||||||
game.override.ability(ability);
|
// @ts-ignore ts doesn't know that ability[0] is an ability and not a string...
|
||||||
|
game.override.ability(ability[0]);
|
||||||
vi.spyOn(moveToCheck, "calculateBattleAccuracy");
|
vi.spyOn(moveToCheck, "calculateBattleAccuracy");
|
||||||
|
|
||||||
await game.startBattle([Species.PIKACHU]);
|
await game.classicMode.startBattle([Species.PIKACHU]);
|
||||||
game.move.select(Moves.CHARM);
|
game.move.select(Moves.CHARM);
|
||||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import { NumberHolder } from "#app/utils";
|
|||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import BattleScene from "#app/battle-scene";
|
import type BattleScene from "#app/battle-scene";
|
||||||
|
|
||||||
describe("check some Achievement related stuff", () => {
|
describe("check some Achievement related stuff", () => {
|
||||||
it("should check Achievement creation", () => {
|
it("should check Achievement creation", () => {
|
||||||
@ -77,6 +77,25 @@ describe("Achv", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("MoneyAchv", () => {
|
describe("MoneyAchv", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
let scene: BattleScene;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
scene = game.scene;
|
||||||
|
});
|
||||||
|
|
||||||
it("should create an instance of MoneyAchv", () => {
|
it("should create an instance of MoneyAchv", () => {
|
||||||
const moneyAchv = new MoneyAchv("", "Test Money Achievement", 10000, "money_icon", 10);
|
const moneyAchv = new MoneyAchv("", "Test Money Achievement", 10000, "money_icon", 10);
|
||||||
expect(moneyAchv).toBeInstanceOf(MoneyAchv);
|
expect(moneyAchv).toBeInstanceOf(MoneyAchv);
|
||||||
@ -85,7 +104,6 @@ describe("MoneyAchv", () => {
|
|||||||
|
|
||||||
it("should validate the achievement based on the money amount", () => {
|
it("should validate the achievement based on the money amount", () => {
|
||||||
const moneyAchv = new MoneyAchv("", "Test Money Achievement", 10000, "money_icon", 10);
|
const moneyAchv = new MoneyAchv("", "Test Money Achievement", 10000, "money_icon", 10);
|
||||||
const scene = new BattleScene();
|
|
||||||
scene.money = 5000;
|
scene.money = 5000;
|
||||||
|
|
||||||
expect(moneyAchv.validate([])).toBe(false);
|
expect(moneyAchv.validate([])).toBe(false);
|
||||||
|
@ -1,22 +1,40 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import type { PokemonTurnData, TurnMove, PokemonMove } from "#app/field/pokemon";
|
import type { PokemonTurnData, TurnMove, PokemonMove } from "#app/field/pokemon";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { MoveResult } from "#app/field/pokemon";
|
import { MoveResult } from "#app/field/pokemon";
|
||||||
import BattleScene from "#app/battle-scene";
|
import type BattleScene from "#app/battle-scene";
|
||||||
import { BattlerTagLapseType, BindTag, SubstituteTag } from "#app/data/battler-tags";
|
import { BattlerTagLapseType, BindTag, SubstituteTag } from "#app/data/battler-tags";
|
||||||
import { Moves } from "#app/enums/moves";
|
import { Moves } from "#app/enums/moves";
|
||||||
import { PokemonAnimType } from "#app/enums/pokemon-anim-type";
|
import { PokemonAnimType } from "#app/enums/pokemon-anim-type";
|
||||||
import * as messages from "#app/messages";
|
import * as messages from "#app/messages";
|
||||||
import { allMoves } from "#app/data/moves/move";
|
import { allMoves } from "#app/data/moves/move";
|
||||||
import type { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import type { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
|
|
||||||
describe("BattlerTag - SubstituteTag", () => {
|
describe("BattlerTag - SubstituteTag", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
});
|
||||||
|
|
||||||
let mockPokemon: Pokemon;
|
let mockPokemon: Pokemon;
|
||||||
|
|
||||||
describe("onAdd behavior", () => {
|
describe("onAdd behavior", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockPokemon = {
|
mockPokemon = {
|
||||||
scene: new BattleScene(),
|
scene: game.scene,
|
||||||
hp: 101,
|
hp: 101,
|
||||||
id: 0,
|
id: 0,
|
||||||
getMaxHp: vi.fn().mockReturnValue(101) as Pokemon["getMaxHp"],
|
getMaxHp: vi.fn().mockReturnValue(101) as Pokemon["getMaxHp"],
|
||||||
@ -77,7 +95,7 @@ describe("BattlerTag - SubstituteTag", () => {
|
|||||||
describe("onRemove behavior", () => {
|
describe("onRemove behavior", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockPokemon = {
|
mockPokemon = {
|
||||||
scene: new BattleScene(),
|
scene: game.scene,
|
||||||
hp: 101,
|
hp: 101,
|
||||||
id: 0,
|
id: 0,
|
||||||
isFainted: vi.fn().mockReturnValue(false) as Pokemon["isFainted"],
|
isFainted: vi.fn().mockReturnValue(false) as Pokemon["isFainted"],
|
||||||
@ -109,7 +127,7 @@ describe("BattlerTag - SubstituteTag", () => {
|
|||||||
describe("lapse behavior", () => {
|
describe("lapse behavior", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockPokemon = {
|
mockPokemon = {
|
||||||
scene: new BattleScene(),
|
scene: game.scene,
|
||||||
hp: 101,
|
hp: 101,
|
||||||
id: 0,
|
id: 0,
|
||||||
turnData: { acted: true } as PokemonTurnData,
|
turnData: { acted: true } as PokemonTurnData,
|
||||||
|
@ -13,17 +13,12 @@ import { Species } from "#enums/species";
|
|||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import { mockI18next } from "#test/testUtils/testUtils";
|
import { mockI18next } from "#test/testUtils/testUtils";
|
||||||
import i18next from "i18next";
|
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
const pokemonName = "PKM";
|
const pokemonName = "PKM";
|
||||||
const sourceText = "SOURCE";
|
const sourceText = "SOURCE";
|
||||||
|
|
||||||
describe("Status Effect Messages", () => {
|
describe("Status Effect Messages", () => {
|
||||||
beforeAll(async () => {
|
|
||||||
await i18next.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("NONE", () => {
|
describe("NONE", () => {
|
||||||
const statusEffect = StatusEffect.NONE;
|
const statusEffect = StatusEffect.NONE;
|
||||||
|
|
||||||
@ -31,7 +26,6 @@ describe("Status Effect Messages", () => {
|
|||||||
mockI18next();
|
mockI18next();
|
||||||
|
|
||||||
const text = getStatusEffectObtainText(statusEffect, pokemonName);
|
const text = getStatusEffectObtainText(statusEffect, pokemonName);
|
||||||
console.log("text:", text);
|
|
||||||
expect(text).toBe("");
|
expect(text).toBe("");
|
||||||
|
|
||||||
const emptySourceText = getStatusEffectObtainText(statusEffect, pokemonName, "");
|
const emptySourceText = getStatusEffectObtainText(statusEffect, pokemonName, "");
|
||||||
|
@ -13,7 +13,7 @@ describe("Moves - Copycat", () => {
|
|||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const randomMoveAttr = allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0];
|
let randomMoveAttr: RandomMoveAttr;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -26,6 +26,7 @@ describe("Moves - Copycat", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
randomMoveAttr = allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.moveset([Moves.COPYCAT, Moves.SPIKY_SHIELD, Moves.SWORDS_DANCE, Moves.SPLASH])
|
.moveset([Moves.COPYCAT, Moves.SPIKY_SHIELD, Moves.SWORDS_DANCE, Moves.SPLASH])
|
||||||
|
@ -3,6 +3,7 @@ import { allMoves } from "#app/data/moves/move";
|
|||||||
import { DamageAnimPhase } from "#app/phases/damage-anim-phase";
|
import { DamageAnimPhase } from "#app/phases/damage-anim-phase";
|
||||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
@ -12,7 +13,7 @@ describe("Moves - Dynamax Cannon", () => {
|
|||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const dynamaxCannon = allMoves[Moves.DYNAMAX_CANNON];
|
let dynamaxCannon: Move;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -25,6 +26,7 @@ describe("Moves - Dynamax Cannon", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
dynamaxCannon = allMoves[Moves.DYNAMAX_CANNON];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
|
|
||||||
game.override.moveset([dynamaxCannon.id]);
|
game.override.moveset([dynamaxCannon.id]);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { allMoves } from "#app/data/moves/move";
|
import { allMoves } from "#app/data/moves/move";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import { DamageAnimPhase } from "#app/phases/damage-anim-phase";
|
import { DamageAnimPhase } from "#app/phases/damage-anim-phase";
|
||||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||||
@ -15,8 +16,8 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
|
|||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const fusionFlare = allMoves[Moves.FUSION_FLARE];
|
let fusionFlare: Move;
|
||||||
const fusionBolt = allMoves[Moves.FUSION_BOLT];
|
let fusionBolt: Move;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -29,6 +30,8 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
fusionFlare = allMoves[Moves.FUSION_FLARE];
|
||||||
|
fusionBolt = allMoves[Moves.FUSION_BOLT];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override.moveset([fusionFlare.id, fusionBolt.id]);
|
game.override.moveset([fusionFlare.id, fusionBolt.id]);
|
||||||
game.override.startingLevel(1);
|
game.override.startingLevel(1);
|
||||||
@ -45,7 +48,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("FUSION_FLARE should double power of subsequent FUSION_BOLT", async () => {
|
it("FUSION_FLARE should double power of subsequent FUSION_BOLT", async () => {
|
||||||
await game.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
||||||
|
|
||||||
game.move.select(fusionFlare.id, 0, BattlerIndex.ENEMY);
|
game.move.select(fusionFlare.id, 0, BattlerIndex.ENEMY);
|
||||||
game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY);
|
game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY);
|
||||||
@ -65,7 +68,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
|
|||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("FUSION_BOLT should double power of subsequent FUSION_FLARE", async () => {
|
it("FUSION_BOLT should double power of subsequent FUSION_FLARE", async () => {
|
||||||
await game.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
||||||
|
|
||||||
game.move.select(fusionBolt.id, 0, BattlerIndex.ENEMY);
|
game.move.select(fusionBolt.id, 0, BattlerIndex.ENEMY);
|
||||||
game.move.select(fusionFlare.id, 1, BattlerIndex.ENEMY);
|
game.move.select(fusionFlare.id, 1, BattlerIndex.ENEMY);
|
||||||
@ -85,7 +88,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
|
|||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
it("FUSION_FLARE should double power of subsequent FUSION_BOLT if a move failed in between", async () => {
|
it("FUSION_FLARE should double power of subsequent FUSION_BOLT if a move failed in between", async () => {
|
||||||
await game.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
||||||
|
|
||||||
game.move.select(fusionFlare.id, 0, BattlerIndex.PLAYER);
|
game.move.select(fusionFlare.id, 0, BattlerIndex.PLAYER);
|
||||||
game.move.select(fusionBolt.id, 1, BattlerIndex.PLAYER);
|
game.move.select(fusionBolt.id, 1, BattlerIndex.PLAYER);
|
||||||
@ -111,7 +114,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
|
|||||||
|
|
||||||
it("FUSION_FLARE should not double power of subsequent FUSION_BOLT if a move succeeded in between", async () => {
|
it("FUSION_FLARE should not double power of subsequent FUSION_BOLT if a move succeeded in between", async () => {
|
||||||
game.override.enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]);
|
game.override.enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]);
|
||||||
await game.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
||||||
|
|
||||||
game.move.select(fusionFlare.id, 0, BattlerIndex.ENEMY);
|
game.move.select(fusionFlare.id, 0, BattlerIndex.ENEMY);
|
||||||
game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY);
|
game.move.select(fusionBolt.id, 1, BattlerIndex.ENEMY);
|
||||||
@ -156,7 +159,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
|
|||||||
|
|
||||||
it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves", async () => {
|
it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves", async () => {
|
||||||
game.override.enemyMoveset([fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id]);
|
game.override.enemyMoveset([fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id]);
|
||||||
await game.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
||||||
|
|
||||||
const party = game.scene.getPlayerParty();
|
const party = game.scene.getPlayerParty();
|
||||||
const enemyParty = game.scene.getEnemyParty();
|
const enemyParty = game.scene.getEnemyParty();
|
||||||
@ -210,7 +213,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
|
|||||||
|
|
||||||
it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves if moves are aimed at allies", async () => {
|
it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves if moves are aimed at allies", async () => {
|
||||||
game.override.enemyMoveset([fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id]);
|
game.override.enemyMoveset([fusionFlare.id, fusionFlare.id, fusionFlare.id, fusionFlare.id]);
|
||||||
await game.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
await game.classicMode.startBattle([Species.ZEKROM, Species.ZEKROM]);
|
||||||
|
|
||||||
const party = game.scene.getPlayerParty();
|
const party = game.scene.getPlayerParty();
|
||||||
const enemyParty = game.scene.getEnemyParty();
|
const enemyParty = game.scene.getEnemyParty();
|
||||||
|
@ -6,12 +6,13 @@ import { Species } from "#enums/species";
|
|||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
|
|
||||||
describe("Moves - Hard Press", () => {
|
describe("Moves - Hard Press", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const moveToCheck = allMoves[Moves.HARD_PRESS];
|
let moveToCheck: Move;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -24,6 +25,7 @@ describe("Moves - Hard Press", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
moveToCheck = allMoves[Moves.HARD_PRESS];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override.battleType("single");
|
game.override.battleType("single");
|
||||||
game.override.ability(Abilities.BALL_FETCH);
|
game.override.ability(Abilities.BALL_FETCH);
|
||||||
|
@ -4,6 +4,7 @@ import { Species } from "#enums/species";
|
|||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import { allMoves } from "#app/data/moves/move";
|
import { allMoves } from "#app/data/moves/move";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
@ -12,8 +13,8 @@ describe("Moves - Last Respects", () => {
|
|||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const move = allMoves[Moves.LAST_RESPECTS];
|
let move: Move;
|
||||||
const basePower = move.power;
|
let basePower: number;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -27,6 +28,8 @@ describe("Moves - Last Respects", () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
|
move = allMoves[Moves.LAST_RESPECTS];
|
||||||
|
basePower = move.power;
|
||||||
game.override
|
game.override
|
||||||
.battleType("single")
|
.battleType("single")
|
||||||
.disableCrits()
|
.disableCrits()
|
||||||
|
@ -13,7 +13,7 @@ describe("Moves - Metronome", () => {
|
|||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const randomMoveAttr = allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0];
|
let randomMoveAttr: RandomMoveAttr;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -26,6 +26,7 @@ describe("Moves - Metronome", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
randomMoveAttr = allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.moveset([Moves.METRONOME, Moves.SPLASH])
|
.moveset([Moves.METRONOME, Moves.SPLASH])
|
||||||
|
@ -3,6 +3,7 @@ import { Abilities } from "#enums/abilities";
|
|||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { allMoves } from "#app/data/moves/move";
|
import { allMoves } from "#app/data/moves/move";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
@ -10,7 +11,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
|
|||||||
describe("Moves - Rage Fist", () => {
|
describe("Moves - Rage Fist", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
const move = allMoves[Moves.RAGE_FIST];
|
let move: Move;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -23,6 +24,7 @@ describe("Moves - Rage Fist", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
move = allMoves[Moves.RAGE_FIST];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.battleType("single")
|
.battleType("single")
|
||||||
|
@ -4,12 +4,13 @@ import GameManager from "#test/testUtils/gameManager";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { allMoves } from "#app/data/moves/move";
|
import { allMoves } from "#app/data/moves/move";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
|
|
||||||
describe("Moves - Retaliate", () => {
|
describe("Moves - Retaliate", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const retaliate = allMoves[Moves.RETALIATE];
|
let retaliate: Move;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -22,6 +23,7 @@ describe("Moves - Retaliate", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
retaliate = allMoves[Moves.RETALIATE];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.battleType("single")
|
.battleType("single")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { allMoves, ShellSideArmCategoryAttr } from "#app/data/moves/move";
|
import { allMoves, ShellSideArmCategoryAttr } from "#app/data/moves/move";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
@ -10,8 +11,8 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
|
|||||||
describe("Moves - Shell Side Arm", () => {
|
describe("Moves - Shell Side Arm", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
const shellSideArm = allMoves[Moves.SHELL_SIDE_ARM];
|
let shellSideArm: Move;
|
||||||
const shellSideArmAttr = shellSideArm.getAttrs(ShellSideArmCategoryAttr)[0];
|
let shellSideArmAttr: ShellSideArmCategoryAttr;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
@ -24,6 +25,8 @@ describe("Moves - Shell Side Arm", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
shellSideArm = allMoves[Moves.SHELL_SIDE_ARM];
|
||||||
|
shellSideArmAttr = shellSideArm.getAttrs(ShellSideArmCategoryAttr)[0];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.moveset([Moves.SHELL_SIDE_ARM, Moves.SPLASH])
|
.moveset([Moves.SHELL_SIDE_ARM, Moves.SPLASH])
|
||||||
|
@ -7,6 +7,7 @@ import { MoveResult } from "#app/field/pokemon";
|
|||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
@ -17,7 +18,7 @@ describe("Moves - Spit Up", () => {
|
|||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
const spitUp = allMoves[Moves.SPIT_UP];
|
let spitUp: Move;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({ type: Phaser.HEADLESS });
|
phaserGame = new Phaser.Game({ type: Phaser.HEADLESS });
|
||||||
@ -28,6 +29,7 @@ describe("Moves - Spit Up", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
spitUp = allMoves[Moves.SPIT_UP];
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
|
|
||||||
game.override.battleType("single");
|
game.override.battleType("single");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import { allMoves, TeraMoveCategoryAttr } from "#app/data/moves/move";
|
import { allMoves, TeraMoveCategoryAttr } from "#app/data/moves/move";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#app/enums/abilities";
|
||||||
import { HitResult } from "#app/field/pokemon";
|
import { HitResult } from "#app/field/pokemon";
|
||||||
@ -13,13 +14,16 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
|
|||||||
describe("Moves - Tera Blast", () => {
|
describe("Moves - Tera Blast", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
const moveToCheck = allMoves[Moves.TERA_BLAST];
|
|
||||||
const teraBlastAttr = moveToCheck.getAttrs(TeraMoveCategoryAttr)[0];
|
let moveToCheck: Move;
|
||||||
|
let teraBlastAttr: TeraMoveCategoryAttr;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
type: Phaser.HEADLESS,
|
type: Phaser.HEADLESS,
|
||||||
});
|
});
|
||||||
|
moveToCheck = allMoves[Moves.TERA_BLAST];
|
||||||
|
teraBlastAttr = moveToCheck.getAttrs(TeraMoveCategoryAttr)[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { allMoves, FlinchAttr, StatStageChangeAttr } from "#app/data/moves/move";
|
import { allMoves, FlinchAttr, StatStageChangeAttr } from "#app/data/moves/move";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
|
import type Move from "#app/data/moves/move";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
@ -9,14 +10,17 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
|
|||||||
describe("Moves - Triple Arrows", () => {
|
describe("Moves - Triple Arrows", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
const tripleArrows = allMoves[Moves.TRIPLE_ARROWS];
|
let tripleArrows: Move;
|
||||||
const flinchAttr = tripleArrows.getAttrs(FlinchAttr)[0];
|
let flinchAttr: FlinchAttr;
|
||||||
const defDropAttr = tripleArrows.getAttrs(StatStageChangeAttr)[0];
|
let defDropAttr: StatStageChangeAttr;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
type: Phaser.HEADLESS,
|
type: Phaser.HEADLESS,
|
||||||
});
|
});
|
||||||
|
tripleArrows = allMoves[Moves.TRIPLE_ARROWS];
|
||||||
|
flinchAttr = tripleArrows.getAttrs(FlinchAttr)[0];
|
||||||
|
defDropAttr = tripleArrows.getAttrs(StatStageChangeAttr)[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -48,16 +48,6 @@ export async function runMysteryEncounterToEnd(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (isBattle) {
|
if (isBattle) {
|
||||||
game.onNextPrompt(
|
|
||||||
"DamageAnimPhase",
|
|
||||||
Mode.MESSAGE,
|
|
||||||
() => {
|
|
||||||
game.setMode(Mode.MESSAGE);
|
|
||||||
game.endPhase();
|
|
||||||
},
|
|
||||||
() => game.isCurrentPhase(CommandPhase),
|
|
||||||
);
|
|
||||||
|
|
||||||
game.onNextPrompt(
|
game.onNextPrompt(
|
||||||
"CheckSwitchPhase",
|
"CheckSwitchPhase",
|
||||||
Mode.CONFIRM,
|
Mode.CONFIRM,
|
||||||
|
@ -31,7 +31,7 @@ describe("Phases", () => {
|
|||||||
it("should start the login phase", async () => {
|
it("should start the login phase", async () => {
|
||||||
const loginPhase = new LoginPhase();
|
const loginPhase = new LoginPhase();
|
||||||
scene.unshiftPhase(loginPhase);
|
scene.unshiftPhase(loginPhase);
|
||||||
await game.phaseInterceptor.run(LoginPhase);
|
await game.phaseInterceptor.to(LoginPhase);
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MESSAGE);
|
expect(scene.ui.getMode()).to.equal(Mode.MESSAGE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -40,7 +40,7 @@ describe("Phases", () => {
|
|||||||
it("should start the title phase", async () => {
|
it("should start the title phase", async () => {
|
||||||
const titlePhase = new TitlePhase();
|
const titlePhase = new TitlePhase();
|
||||||
scene.unshiftPhase(titlePhase);
|
scene.unshiftPhase(titlePhase);
|
||||||
await game.phaseInterceptor.run(TitlePhase);
|
await game.phaseInterceptor.to(TitlePhase);
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.TITLE);
|
expect(scene.ui.getMode()).to.equal(Mode.TITLE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -49,7 +49,7 @@ describe("Phases", () => {
|
|||||||
it("should start the unavailable phase", async () => {
|
it("should start the unavailable phase", async () => {
|
||||||
const unavailablePhase = new UnavailablePhase();
|
const unavailablePhase = new UnavailablePhase();
|
||||||
scene.unshiftPhase(unavailablePhase);
|
scene.unshiftPhase(unavailablePhase);
|
||||||
await game.phaseInterceptor.run(UnavailablePhase);
|
await game.phaseInterceptor.to(UnavailablePhase);
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.UNAVAILABLE);
|
expect(scene.ui.getMode()).to.equal(Mode.UNAVAILABLE);
|
||||||
}, 20000);
|
}, 20000);
|
||||||
});
|
});
|
||||||
|
@ -48,8 +48,8 @@ describe("SelectModifierPhase", () => {
|
|||||||
it("should start a select modifier phase", async () => {
|
it("should start a select modifier phase", async () => {
|
||||||
initSceneWithoutEncounterPhase(scene, [Species.ABRA, Species.VOLCARONA]);
|
initSceneWithoutEncounterPhase(scene, [Species.ABRA, Species.VOLCARONA]);
|
||||||
const selectModifierPhase = new SelectModifierPhase();
|
const selectModifierPhase = new SelectModifierPhase();
|
||||||
scene.pushPhase(selectModifierPhase);
|
scene.unshiftPhase(selectModifierPhase);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.to(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
});
|
});
|
||||||
|
@ -4,11 +4,17 @@ import { PokerogueAccountApi } from "#app/plugins/api/pokerogue-account-api";
|
|||||||
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { initServerForApiTests } from "#test/testUtils/testFileInitialization";
|
||||||
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
const apiBase = getApiBaseUrl();
|
const apiBase = getApiBaseUrl();
|
||||||
const accountApi = new PokerogueAccountApi(apiBase);
|
const accountApi = new PokerogueAccountApi(apiBase);
|
||||||
const { server } = global;
|
let server: SetupServerApi;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
server = await initServerForApiTests();
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
server.resetHandlers();
|
server.resetHandlers();
|
||||||
|
@ -9,11 +9,17 @@ import type {
|
|||||||
import { PokerogueAdminApi } from "#app/plugins/api/pokerogue-admin-api";
|
import { PokerogueAdminApi } from "#app/plugins/api/pokerogue-admin-api";
|
||||||
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { initServerForApiTests } from "#test/testUtils/testFileInitialization";
|
||||||
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
const apiBase = getApiBaseUrl();
|
const apiBase = getApiBaseUrl();
|
||||||
const adminApi = new PokerogueAdminApi(apiBase);
|
const adminApi = new PokerogueAdminApi(apiBase);
|
||||||
const { server } = global;
|
let server: SetupServerApi;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
server = await initServerForApiTests();
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
server.resetHandlers();
|
server.resetHandlers();
|
||||||
|
@ -2,10 +2,16 @@ import type { TitleStatsResponse } from "#app/@types/PokerogueApi";
|
|||||||
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
||||||
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { initServerForApiTests } from "#test/testUtils/testFileInitialization";
|
||||||
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
const apiBase = getApiBaseUrl();
|
const apiBase = getApiBaseUrl();
|
||||||
const { server } = global;
|
let server: SetupServerApi;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
server = await initServerForApiTests();
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
server.resetHandlers();
|
server.resetHandlers();
|
||||||
|
@ -3,11 +3,17 @@ import { PokerogueDailyApi } from "#app/plugins/api/pokerogue-daily-api";
|
|||||||
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
||||||
import { ScoreboardCategory, type RankingEntry } from "#app/ui/daily-run-scoreboard";
|
import { ScoreboardCategory, type RankingEntry } from "#app/ui/daily-run-scoreboard";
|
||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { initServerForApiTests } from "#test/testUtils/testFileInitialization";
|
||||||
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
const apiBase = getApiBaseUrl();
|
const apiBase = getApiBaseUrl();
|
||||||
const dailyApi = new PokerogueDailyApi(apiBase);
|
const dailyApi = new PokerogueDailyApi(apiBase);
|
||||||
const { server } = global;
|
let server: SetupServerApi;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
server = await initServerForApiTests();
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
server.resetHandlers();
|
server.resetHandlers();
|
||||||
|
@ -2,11 +2,17 @@ import type { UpdateAllSavedataRequest } from "#app/@types/PokerogueSavedataApi"
|
|||||||
import { PokerogueSavedataApi } from "#app/plugins/api/pokerogue-savedata-api";
|
import { PokerogueSavedataApi } from "#app/plugins/api/pokerogue-savedata-api";
|
||||||
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { initServerForApiTests } from "#test/testUtils/testFileInitialization";
|
||||||
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
const apiBase = getApiBaseUrl();
|
const apiBase = getApiBaseUrl();
|
||||||
const savedataApi = new PokerogueSavedataApi(apiBase);
|
const savedataApi = new PokerogueSavedataApi(apiBase);
|
||||||
const { server } = global;
|
let server: SetupServerApi;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
server = await initServerForApiTests();
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
server.resetHandlers();
|
server.resetHandlers();
|
||||||
|
@ -10,11 +10,17 @@ import { PokerogueSessionSavedataApi } from "#app/plugins/api/pokerogue-session-
|
|||||||
import type { SessionSaveData } from "#app/system/game-data";
|
import type { SessionSaveData } from "#app/system/game-data";
|
||||||
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { initServerForApiTests } from "#test/testUtils/testFileInitialization";
|
||||||
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
const apiBase = getApiBaseUrl();
|
const apiBase = getApiBaseUrl();
|
||||||
const sessionSavedataApi = new PokerogueSessionSavedataApi(apiBase);
|
const sessionSavedataApi = new PokerogueSessionSavedataApi(apiBase);
|
||||||
const { server } = global;
|
|
||||||
|
let server: SetupServerApi;
|
||||||
|
beforeAll(async () => {
|
||||||
|
server = await initServerForApiTests();
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
server.resetHandlers();
|
server.resetHandlers();
|
||||||
|
@ -6,13 +6,20 @@ import type {
|
|||||||
} from "#app/@types/PokerogueSystemSavedataApi";
|
} from "#app/@types/PokerogueSystemSavedataApi";
|
||||||
import { PokerogueSystemSavedataApi } from "#app/plugins/api/pokerogue-system-savedata-api";
|
import { PokerogueSystemSavedataApi } from "#app/plugins/api/pokerogue-system-savedata-api";
|
||||||
import type { SystemSaveData } from "#app/system/game-data";
|
import type { SystemSaveData } from "#app/system/game-data";
|
||||||
|
import { initServerForApiTests } from "#test/testUtils/testFileInitialization";
|
||||||
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
import { getApiBaseUrl } from "#test/testUtils/testUtils";
|
||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
const apiBase = getApiBaseUrl();
|
const apiBase = getApiBaseUrl();
|
||||||
const systemSavedataApi = new PokerogueSystemSavedataApi(getApiBaseUrl());
|
const systemSavedataApi = new PokerogueSystemSavedataApi(getApiBaseUrl());
|
||||||
const { server } = global;
|
|
||||||
|
let server: SetupServerApi;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
server = await initServerForApiTests();
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
server.resetHandlers();
|
server.resetHandlers();
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import Overrides, { defaultOverrides } from "#app/overrides";
|
|
||||||
import { expect, test } from "vitest";
|
|
||||||
|
|
||||||
test("Overrides are default values", () => {
|
|
||||||
expect(Overrides).toEqual(defaultOverrides);
|
|
||||||
});
|
|
@ -55,6 +55,9 @@ import TextInterceptor from "#test/testUtils/TextInterceptor";
|
|||||||
import { AES, enc } from "crypto-js";
|
import { AES, enc } from "crypto-js";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import { expect, vi } from "vitest";
|
import { expect, vi } from "vitest";
|
||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import type StarterSelectUiHandler from "#app/ui/starter-select-ui-handler";
|
||||||
|
import { MockFetch } from "#test/testUtils/mocks/mockFetch";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to manage the game state and transitions between phases.
|
* Class to manage the game state and transitions between phases.
|
||||||
@ -84,10 +87,34 @@ export default class GameManager {
|
|||||||
ErrorInterceptor.getInstance().clear();
|
ErrorInterceptor.getInstance().clear();
|
||||||
BattleScene.prototype.randBattleSeedInt = (range, min = 0) => min + range - 1; // This simulates a max roll
|
BattleScene.prototype.randBattleSeedInt = (range, min = 0) => min + range - 1; // This simulates a max roll
|
||||||
this.gameWrapper = new GameWrapper(phaserGame, bypassLogin);
|
this.gameWrapper = new GameWrapper(phaserGame, bypassLogin);
|
||||||
this.scene = new BattleScene();
|
|
||||||
|
let firstTimeScene = false;
|
||||||
|
|
||||||
|
if (globalScene) {
|
||||||
|
this.scene = globalScene;
|
||||||
|
} else {
|
||||||
|
this.scene = new BattleScene();
|
||||||
|
this.gameWrapper.setScene(this.scene);
|
||||||
|
firstTimeScene = true;
|
||||||
|
}
|
||||||
|
|
||||||
this.phaseInterceptor = new PhaseInterceptor(this.scene);
|
this.phaseInterceptor = new PhaseInterceptor(this.scene);
|
||||||
|
|
||||||
|
if (!firstTimeScene) {
|
||||||
|
this.scene.reset(false, true);
|
||||||
|
(this.scene.ui.handlers[Mode.STARTER_SELECT] as StarterSelectUiHandler).clearStarterPreferences();
|
||||||
|
this.scene.clearAllPhases();
|
||||||
|
|
||||||
|
// Must be run after phase interceptor has been initialized.
|
||||||
|
|
||||||
|
this.scene.pushPhase(new LoginPhase());
|
||||||
|
this.scene.pushPhase(new TitlePhase());
|
||||||
|
this.scene.shiftPhase();
|
||||||
|
|
||||||
|
this.gameWrapper.scene = this.scene;
|
||||||
|
}
|
||||||
|
|
||||||
this.textInterceptor = new TextInterceptor(this.scene);
|
this.textInterceptor = new TextInterceptor(this.scene);
|
||||||
this.gameWrapper.setScene(this.scene);
|
|
||||||
this.override = new OverridesHelper(this);
|
this.override = new OverridesHelper(this);
|
||||||
this.move = new MoveHelper(this);
|
this.move = new MoveHelper(this);
|
||||||
this.classicMode = new ClassicModeHelper(this);
|
this.classicMode = new ClassicModeHelper(this);
|
||||||
@ -96,9 +123,12 @@ export default class GameManager {
|
|||||||
this.settings = new SettingsHelper(this);
|
this.settings = new SettingsHelper(this);
|
||||||
this.reload = new ReloadHelper(this);
|
this.reload = new ReloadHelper(this);
|
||||||
this.modifiers = new ModifierHelper(this);
|
this.modifiers = new ModifierHelper(this);
|
||||||
|
this.override.sanitizeOverrides();
|
||||||
|
|
||||||
// Disables Mystery Encounters on all tests (can be overridden at test level)
|
// Disables Mystery Encounters on all tests (can be overridden at test level)
|
||||||
this.override.mysteryEncounterChance(0);
|
this.override.mysteryEncounterChance(0);
|
||||||
|
|
||||||
|
global.fetch = vi.fn(MockFetch) as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,11 +6,11 @@ import Pokemon from "#app/field/pokemon";
|
|||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import { blobToString } from "#test/testUtils/gameManagerUtils";
|
import { blobToString } from "#test/testUtils/gameManagerUtils";
|
||||||
import { MockClock } from "#test/testUtils/mocks/mockClock";
|
import { MockClock } from "#test/testUtils/mocks/mockClock";
|
||||||
import mockConsoleLog from "#test/testUtils/mocks/mockConsoleLog";
|
import { MockConsoleLog } from "#test/testUtils/mocks/mockConsoleLog";
|
||||||
import { MockFetch } from "#test/testUtils/mocks/mockFetch";
|
import { MockFetch } from "#test/testUtils/mocks/mockFetch";
|
||||||
import MockLoader from "#test/testUtils/mocks/mockLoader";
|
import MockLoader from "#test/testUtils/mocks/mockLoader";
|
||||||
import mockLocalStorage from "#test/testUtils/mocks/mockLocalStorage";
|
import { mockLocalStorage } from "#test/testUtils/mocks/mockLocalStorage";
|
||||||
import MockImage from "#test/testUtils/mocks/mocksContainer/mockImage";
|
import { MockImage } from "#test/testUtils/mocks/mocksContainer/mockImage";
|
||||||
import MockTextureManager from "#test/testUtils/mocks/mockTextureManager";
|
import MockTextureManager from "#test/testUtils/mocks/mockTextureManager";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
@ -27,18 +27,6 @@ import UpdateList = Phaser.GameObjects.UpdateList;
|
|||||||
import { version } from "../../package.json";
|
import { version } from "../../package.json";
|
||||||
import { MockTimedEventManager } from "./mocks/mockTimedEventManager";
|
import { MockTimedEventManager } from "./mocks/mockTimedEventManager";
|
||||||
|
|
||||||
Object.defineProperty(window, "localStorage", {
|
|
||||||
value: mockLocalStorage(),
|
|
||||||
});
|
|
||||||
Object.defineProperty(window, "console", {
|
|
||||||
value: mockConsoleLog(false),
|
|
||||||
});
|
|
||||||
|
|
||||||
BBCodeText.prototype.destroy = () => null;
|
|
||||||
BBCodeText.prototype.resize = () => null;
|
|
||||||
InputText.prototype.setElement = () => null;
|
|
||||||
InputText.prototype.resize = () => null;
|
|
||||||
Phaser.GameObjects.Image = MockImage;
|
|
||||||
window.URL.createObjectURL = (blob: Blob) => {
|
window.URL.createObjectURL = (blob: Blob) => {
|
||||||
blobToString(blob).then((data: string) => {
|
blobToString(blob).then((data: string) => {
|
||||||
localStorage.setItem("toExport", data);
|
localStorage.setItem("toExport", data);
|
||||||
@ -53,25 +41,6 @@ window.matchMedia = () => ({
|
|||||||
matches: false,
|
matches: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets this object's position relative to another object with a given offset
|
|
||||||
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
|
||||||
* @param x The relative x position
|
|
||||||
* @param y The relative y position
|
|
||||||
*/
|
|
||||||
const setPositionRelative = function (guideObject: any, x: number, y: number) {
|
|
||||||
const offsetX = guideObject.width * (-0.5 + (0.5 - guideObject.originX));
|
|
||||||
const offsetY = guideObject.height * (-0.5 + (0.5 - guideObject.originY));
|
|
||||||
this.setPosition(guideObject.x + offsetX + x, guideObject.y + offsetY + y);
|
|
||||||
};
|
|
||||||
|
|
||||||
Phaser.GameObjects.Container.prototype.setPositionRelative = setPositionRelative;
|
|
||||||
Phaser.GameObjects.Sprite.prototype.setPositionRelative = setPositionRelative;
|
|
||||||
Phaser.GameObjects.Image.prototype.setPositionRelative = setPositionRelative;
|
|
||||||
Phaser.GameObjects.NineSlice.prototype.setPositionRelative = setPositionRelative;
|
|
||||||
Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative;
|
|
||||||
Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative;
|
|
||||||
|
|
||||||
export default class GameWrapper {
|
export default class GameWrapper {
|
||||||
public game: Phaser.Game;
|
public game: Phaser.Game;
|
||||||
public scene: BattleScene;
|
public scene: BattleScene;
|
||||||
|
@ -6,7 +6,7 @@ import type { GameModes } from "#app/game-mode";
|
|||||||
import { getGameMode } from "#app/game-mode";
|
import { getGameMode } from "#app/game-mode";
|
||||||
import type { ModifierOverride } from "#app/modifier/modifier-type";
|
import type { ModifierOverride } from "#app/modifier/modifier-type";
|
||||||
import type { BattleStyle } from "#app/overrides";
|
import type { BattleStyle } from "#app/overrides";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides, { defaultOverrides } from "#app/overrides";
|
||||||
import type { Unlockables } from "#app/system/unlockables";
|
import type { Unlockables } from "#app/system/unlockables";
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
@ -15,8 +15,9 @@ import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import type { WeatherType } from "#enums/weather-type";
|
import type { WeatherType } from "#enums/weather-type";
|
||||||
import { vi } from "vitest";
|
import { expect, vi } from "vitest";
|
||||||
import { GameManagerHelper } from "./gameManagerHelper";
|
import { GameManagerHelper } from "./gameManagerHelper";
|
||||||
|
import { shiftCharCodes } from "#app/utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to handle overrides in tests
|
* Helper to handle overrides in tests
|
||||||
@ -226,12 +227,7 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public disableTrainerWaves(): this {
|
public disableTrainerWaves(): this {
|
||||||
const realFn = getGameMode;
|
vi.spyOn(Overrides, "DISABLE_STANDARD_TRAINERS_OVERRIDE", "get").mockReturnValue(true);
|
||||||
vi.spyOn(GameMode, "getGameMode").mockImplementation((gameMode: GameModes) => {
|
|
||||||
const mode = realFn(gameMode);
|
|
||||||
mode.hasTrainers = false;
|
|
||||||
return mode;
|
|
||||||
});
|
|
||||||
this.log("Standard trainer waves are disabled!");
|
this.log("Standard trainer waves are disabled!");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -263,11 +259,8 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
public seed(seed: string): this {
|
public seed(seed: string): this {
|
||||||
vi.spyOn(this.game.scene, "resetSeed").mockImplementation(() => {
|
// Shift the seed here with a negative wave number, to compensate for `resetSeed()` shifting the seed itself.
|
||||||
this.game.scene.waveSeed = seed;
|
this.game.scene.setSeed(shiftCharCodes(seed, (this.game.scene.currentBattle?.waveIndex ?? 0) * -1));
|
||||||
Phaser.Math.RND.sow([seed]);
|
|
||||||
this.game.scene.rngCounter = 0;
|
|
||||||
});
|
|
||||||
this.game.scene.resetSeed();
|
this.game.scene.resetSeed();
|
||||||
this.log(`Seed set to "${seed}"!`);
|
this.log(`Seed set to "${seed}"!`);
|
||||||
return this;
|
return this;
|
||||||
@ -539,4 +532,14 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
private log(...params: any[]) {
|
private log(...params: any[]) {
|
||||||
console.log("Overrides:", ...params);
|
console.log("Overrides:", ...params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sanitizeOverrides(): void {
|
||||||
|
for (const key of Object.keys(defaultOverrides)) {
|
||||||
|
if (Overrides[key] !== defaultOverrides[key]) {
|
||||||
|
vi.spyOn(Overrides, key as any, "get").mockReturnValue(defaultOverrides[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(Overrides).toEqual(defaultOverrides);
|
||||||
|
this.log("Sanitizing all overrides!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
41
test/testUtils/listenersManager.ts
Normal file
41
test/testUtils/listenersManager.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { expect } from "vitest";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not it is currently the first time running this manager.
|
||||||
|
*/
|
||||||
|
let firstTime = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of listeners that were present during the first time this manager is run.
|
||||||
|
* These initial listeners are needed throughout the entire test suite, so we never remove them.
|
||||||
|
*/
|
||||||
|
const initialListeners: NodeJS.MessageListener[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current listener that is only needed for the current test file.
|
||||||
|
* We plan to delete it during the next test file, when it is no longer needed.
|
||||||
|
*/
|
||||||
|
let currentListener: NodeJS.MessageListener | null;
|
||||||
|
|
||||||
|
export function manageListeners() {
|
||||||
|
if (firstTime) {
|
||||||
|
initialListeners.push(...process.listeners("message"));
|
||||||
|
} else {
|
||||||
|
expect(process.listeners("message").length).toBeLessThan(7);
|
||||||
|
|
||||||
|
// Remove the listener that was used during the previous test file
|
||||||
|
if (currentListener) {
|
||||||
|
process.removeListener("message", currentListener);
|
||||||
|
currentListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the new listener that is being used for the current test file
|
||||||
|
process.listeners("message").forEach(fn => {
|
||||||
|
if (!initialListeners.includes(fn)) {
|
||||||
|
currentListener = fn;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
firstTime = false;
|
||||||
|
}
|
@ -1,82 +1,80 @@
|
|||||||
const MockConsoleLog = (_logDisabled = false, _phaseText = false) => {
|
const originalLog = console.log;
|
||||||
let logs: any[] = [];
|
const originalError = console.error;
|
||||||
const logDisabled: boolean = _logDisabled;
|
const originalDebug = console.debug;
|
||||||
const phaseText: boolean = _phaseText;
|
const originalWarn = console.warn;
|
||||||
const originalLog = console.log;
|
|
||||||
const originalError = console.error;
|
|
||||||
const originalDebug = console.debug;
|
|
||||||
const originalWarn = console.warn;
|
|
||||||
const notified: any[] = [];
|
|
||||||
|
|
||||||
const blacklist = ["Phaser", "variant icon does not exist", 'Texture "%s" not found'];
|
const blacklist = ["Phaser", "variant icon does not exist", 'Texture "%s" not found'];
|
||||||
const whitelist = ["Phase"];
|
const whitelist = ["Phase"];
|
||||||
|
|
||||||
return {
|
export class MockConsoleLog {
|
||||||
log(...args) {
|
constructor(
|
||||||
const argsStr = this.getStr(args);
|
private logDisabled = false,
|
||||||
logs.push(argsStr);
|
private phaseText = false,
|
||||||
if (logDisabled && !phaseText) {
|
) {}
|
||||||
return;
|
private logs: any[] = [];
|
||||||
}
|
private notified: any[] = [];
|
||||||
if ((phaseText && !whitelist.some(b => argsStr.includes(b))) || blacklist.some(b => argsStr.includes(b))) {
|
|
||||||
return;
|
public log(...args) {
|
||||||
}
|
const argsStr = this.getStr(args);
|
||||||
originalLog(args);
|
this.logs.push(argsStr);
|
||||||
},
|
if (this.logDisabled && !this.phaseText) {
|
||||||
error(...args) {
|
return;
|
||||||
const argsStr = this.getStr(args);
|
}
|
||||||
logs.push(argsStr);
|
if ((this.phaseText && !whitelist.some(b => argsStr.includes(b))) || blacklist.some(b => argsStr.includes(b))) {
|
||||||
originalError(args); // Appelle le console.error originel
|
return;
|
||||||
},
|
}
|
||||||
debug(...args) {
|
originalLog(args);
|
||||||
const argsStr = this.getStr(args);
|
}
|
||||||
logs.push(argsStr);
|
public error(...args) {
|
||||||
if (logDisabled && !phaseText) {
|
const argsStr = this.getStr(args);
|
||||||
return;
|
this.logs.push(argsStr);
|
||||||
}
|
originalError(args); // Appelle le console.error originel
|
||||||
if (!whitelist.some(b => argsStr.includes(b)) || blacklist.some(b => argsStr.includes(b))) {
|
}
|
||||||
return;
|
public debug(...args) {
|
||||||
}
|
const argsStr = this.getStr(args);
|
||||||
originalDebug(args);
|
this.logs.push(argsStr);
|
||||||
},
|
if (this.logDisabled && !this.phaseText) {
|
||||||
warn(...args) {
|
return;
|
||||||
const argsStr = this.getStr(args);
|
}
|
||||||
logs.push(args);
|
if (!whitelist.some(b => argsStr.includes(b)) || blacklist.some(b => argsStr.includes(b))) {
|
||||||
if (logDisabled && !phaseText) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
originalDebug(args);
|
||||||
if (!whitelist.some(b => argsStr.includes(b)) || blacklist.some(b => argsStr.includes(b))) {
|
}
|
||||||
return;
|
warn(...args) {
|
||||||
}
|
const argsStr = this.getStr(args);
|
||||||
originalWarn(args);
|
this.logs.push(args);
|
||||||
},
|
if (this.logDisabled && !this.phaseText) {
|
||||||
notify(msg) {
|
return;
|
||||||
originalLog(msg);
|
}
|
||||||
notified.push(msg);
|
if (!whitelist.some(b => argsStr.includes(b)) || blacklist.some(b => argsStr.includes(b))) {
|
||||||
},
|
return;
|
||||||
getLogs() {
|
}
|
||||||
return logs;
|
originalWarn(args);
|
||||||
},
|
}
|
||||||
clearLogs() {
|
notify(msg) {
|
||||||
logs = [];
|
originalLog(msg);
|
||||||
},
|
this.notified.push(msg);
|
||||||
getStr(...args) {
|
}
|
||||||
return args
|
getLogs() {
|
||||||
.map(arg => {
|
return this.logs;
|
||||||
if (typeof arg === "object" && arg !== null) {
|
}
|
||||||
// Handle objects including arrays
|
clearLogs() {
|
||||||
return JSON.stringify(arg, (_key, value) => (typeof value === "bigint" ? value.toString() : value));
|
this.logs = [];
|
||||||
}
|
}
|
||||||
if (typeof arg === "bigint") {
|
getStr(...args) {
|
||||||
// Handle BigInt values
|
return args
|
||||||
return arg.toString();
|
.map(arg => {
|
||||||
}
|
if (typeof arg === "object" && arg !== null) {
|
||||||
// Handle all other types
|
// Handle objects including arrays
|
||||||
|
return JSON.stringify(arg, (_key, value) => (typeof value === "bigint" ? value.toString() : value));
|
||||||
|
}
|
||||||
|
if (typeof arg === "bigint") {
|
||||||
|
// Handle BigInt values
|
||||||
return arg.toString();
|
return arg.toString();
|
||||||
})
|
}
|
||||||
.join(";");
|
return arg.toString();
|
||||||
},
|
})
|
||||||
};
|
.join(";");
|
||||||
};
|
}
|
||||||
|
}
|
||||||
export default MockConsoleLog;
|
|
||||||
|
26
test/testUtils/mocks/mockContextCanvas.ts
Normal file
26
test/testUtils/mocks/mockContextCanvas.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* A minimal stub object to mock HTMLCanvasElement
|
||||||
|
*/
|
||||||
|
export const mockCanvas: any = {
|
||||||
|
width: 0,
|
||||||
|
getContext() {
|
||||||
|
return mockContext;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* A minimal stub object to mock CanvasRenderingContext2D
|
||||||
|
*/
|
||||||
|
export const mockContext: any = {
|
||||||
|
font: "",
|
||||||
|
measureText: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
save: () => {},
|
||||||
|
scale: () => {},
|
||||||
|
clearRect: () => {},
|
||||||
|
fillRect: () => {},
|
||||||
|
fillText: () => {},
|
||||||
|
getImageData: () => {},
|
||||||
|
canvas: mockCanvas,
|
||||||
|
restore: () => {},
|
||||||
|
};
|
@ -1,4 +1,4 @@
|
|||||||
const mockLocalStorage = () => {
|
export const mockLocalStorage = () => {
|
||||||
let store = {} as Storage;
|
let store = {} as Storage;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -23,5 +23,3 @@ const mockLocalStorage = () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default mockLocalStorage;
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import MockContainer from "#test/testUtils/mocks/mocksContainer/mockContainer";
|
import MockContainer from "#test/testUtils/mocks/mocksContainer/mockContainer";
|
||||||
import MockImage from "#test/testUtils/mocks/mocksContainer/mockImage";
|
import { MockImage } from "#test/testUtils/mocks/mocksContainer/mockImage";
|
||||||
import MockNineslice from "#test/testUtils/mocks/mocksContainer/mockNineslice";
|
import MockNineslice from "#test/testUtils/mocks/mocksContainer/mockNineslice";
|
||||||
import MockPolygon from "#test/testUtils/mocks/mocksContainer/mockPolygon";
|
import MockPolygon from "#test/testUtils/mocks/mocksContainer/mockPolygon";
|
||||||
import MockRectangle from "#test/testUtils/mocks/mocksContainer/mockRectangle";
|
import MockRectangle from "#test/testUtils/mocks/mocksContainer/mockRectangle";
|
||||||
|
@ -215,4 +215,10 @@ export default class MockContainer implements MockGameObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
disableInteractive = () => null;
|
disableInteractive = () => null;
|
||||||
|
|
||||||
|
each(method) {
|
||||||
|
for (const item of this.list) {
|
||||||
|
method(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import MockContainer from "#test/testUtils/mocks/mocksContainer/mockContainer";
|
import MockContainer from "#test/testUtils/mocks/mocksContainer/mockContainer";
|
||||||
|
|
||||||
export default class MockImage extends MockContainer {
|
export class MockImage extends MockContainer {
|
||||||
private texture;
|
private texture;
|
||||||
|
|
||||||
constructor(textureManager, x, y, texture) {
|
constructor(textureManager, x, y, texture) {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { off } from "process";
|
||||||
import type { MockGameObject } from "../mockGameObject";
|
import type { MockGameObject } from "../mockGameObject";
|
||||||
|
|
||||||
export default class MockRectangle implements MockGameObject {
|
export default class MockRectangle implements MockGameObject {
|
||||||
@ -72,4 +73,6 @@ export default class MockRectangle implements MockGameObject {
|
|||||||
setScale(_scale) {
|
setScale(_scale) {
|
||||||
// return this.phaserText.setScale(scale);
|
// return this.phaserText.setScale(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
off() {}
|
||||||
}
|
}
|
||||||
|
117
test/testUtils/testFileInitialization.ts
Normal file
117
test/testUtils/testFileInitialization.ts
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import { SESSION_ID_COOKIE_NAME } from "#app/constants";
|
||||||
|
import { initLoggedInUser } from "#app/account";
|
||||||
|
import { initAbilities } from "#app/data/ability";
|
||||||
|
import { initBiomes } from "#app/data/balance/biomes";
|
||||||
|
import { initEggMoves } from "#app/data/balance/egg-moves";
|
||||||
|
import { initPokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
|
import { initMoves } from "#app/data/moves/move";
|
||||||
|
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
|
||||||
|
import { initPokemonForms } from "#app/data/pokemon-forms";
|
||||||
|
import { initSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { initAchievements } from "#app/system/achv";
|
||||||
|
import { initVouchers } from "#app/system/voucher";
|
||||||
|
import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
|
||||||
|
import { setCookie } from "#app/utils";
|
||||||
|
import { blobToString } from "#test/testUtils/gameManagerUtils";
|
||||||
|
import { MockConsoleLog } from "#test/testUtils/mocks/mockConsoleLog";
|
||||||
|
import { mockContext } from "#test/testUtils/mocks/mockContextCanvas";
|
||||||
|
import { mockLocalStorage } from "#test/testUtils/mocks/mockLocalStorage";
|
||||||
|
import { MockImage } from "#test/testUtils/mocks/mocksContainer/mockImage";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import InputText from "phaser3-rex-plugins/plugins/inputtext";
|
||||||
|
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
|
||||||
|
import { manageListeners } from "./listenersManager";
|
||||||
|
|
||||||
|
let wasInitialized = false;
|
||||||
|
/**
|
||||||
|
* An initialization function that is run at the beginning of every test file (via `beforeAll()`).
|
||||||
|
*/
|
||||||
|
export function initTestFile() {
|
||||||
|
// Set the timezone to UTC for tests.
|
||||||
|
process.env.TZ = "UTC";
|
||||||
|
|
||||||
|
Object.defineProperty(window, "localStorage", {
|
||||||
|
value: mockLocalStorage(),
|
||||||
|
});
|
||||||
|
Object.defineProperty(window, "console", {
|
||||||
|
value: new MockConsoleLog(false),
|
||||||
|
});
|
||||||
|
Object.defineProperty(document, "fonts", {
|
||||||
|
writable: true,
|
||||||
|
value: {
|
||||||
|
add: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
BBCodeText.prototype.destroy = () => null;
|
||||||
|
// @ts-ignore
|
||||||
|
BBCodeText.prototype.resize = () => null;
|
||||||
|
InputText.prototype.setElement = () => null as any;
|
||||||
|
InputText.prototype.resize = () => null as any;
|
||||||
|
Phaser.GameObjects.Image = MockImage as any;
|
||||||
|
window.URL.createObjectURL = (blob: Blob) => {
|
||||||
|
blobToString(blob).then((data: string) => {
|
||||||
|
localStorage.setItem("toExport", data);
|
||||||
|
});
|
||||||
|
return null as any;
|
||||||
|
};
|
||||||
|
navigator.getGamepads = () => [];
|
||||||
|
setCookie(SESSION_ID_COOKIE_NAME, "fake_token");
|
||||||
|
|
||||||
|
window.matchMedia = () =>
|
||||||
|
({
|
||||||
|
matches: false,
|
||||||
|
}) as any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets this object's position relative to another object with a given offset
|
||||||
|
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
||||||
|
* @param x The relative x position
|
||||||
|
* @param y The relative y position
|
||||||
|
*/
|
||||||
|
const setPositionRelative = function (guideObject: any, x: number, y: number) {
|
||||||
|
const offsetX = guideObject.width * (-0.5 + (0.5 - guideObject.originX));
|
||||||
|
const offsetY = guideObject.height * (-0.5 + (0.5 - guideObject.originY));
|
||||||
|
this.setPosition(guideObject.x + offsetX + x, guideObject.y + offsetY + y);
|
||||||
|
};
|
||||||
|
|
||||||
|
Phaser.GameObjects.Container.prototype.setPositionRelative = setPositionRelative;
|
||||||
|
Phaser.GameObjects.Sprite.prototype.setPositionRelative = setPositionRelative;
|
||||||
|
Phaser.GameObjects.Image.prototype.setPositionRelative = setPositionRelative;
|
||||||
|
Phaser.GameObjects.NineSlice.prototype.setPositionRelative = setPositionRelative;
|
||||||
|
Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative;
|
||||||
|
Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative;
|
||||||
|
HTMLCanvasElement.prototype.getContext = () => mockContext;
|
||||||
|
|
||||||
|
// Initialize all of these things if and only if they have not been initialized yet
|
||||||
|
// initSpecies();
|
||||||
|
if (!wasInitialized) {
|
||||||
|
wasInitialized = true;
|
||||||
|
initVouchers();
|
||||||
|
initAchievements();
|
||||||
|
initStatsKeys();
|
||||||
|
initPokemonPrevolutions();
|
||||||
|
initBiomes();
|
||||||
|
initEggMoves();
|
||||||
|
initPokemonForms();
|
||||||
|
initSpecies();
|
||||||
|
initMoves();
|
||||||
|
initAbilities();
|
||||||
|
initLoggedInUser();
|
||||||
|
initMysteryEncounters();
|
||||||
|
}
|
||||||
|
|
||||||
|
manageListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the current mock server and initializes a new mock server.
|
||||||
|
* This is run at the beginning of every API test file.
|
||||||
|
*/
|
||||||
|
export async function initServerForApiTests() {
|
||||||
|
global.server?.close();
|
||||||
|
const { setupServer } = await import("msw/node");
|
||||||
|
global.server = setupServer();
|
||||||
|
global.server.listen({ onUnhandledRequest: "error" });
|
||||||
|
return global.server;
|
||||||
|
}
|
@ -14,8 +14,9 @@ import { initVouchers } from "#app/system/voucher";
|
|||||||
import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
|
import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
|
||||||
import { afterAll, beforeAll, vi } from "vitest";
|
import { afterAll, beforeAll, vi } from "vitest";
|
||||||
|
|
||||||
|
import { initTestFile } from "./testUtils/testFileInitialization";
|
||||||
|
|
||||||
/** Set the timezone to UTC for tests. */
|
/** Set the timezone to UTC for tests. */
|
||||||
process.env.TZ = "UTC";
|
|
||||||
|
|
||||||
/** Mock the override import to always return default values, ignoring any custom overrides. */
|
/** Mock the override import to always return default values, ignoring any custom overrides. */
|
||||||
vi.mock("#app/overrides", async importOriginal => {
|
vi.mock("#app/overrides", async importOriginal => {
|
||||||
@ -63,28 +64,10 @@ vi.mock("i18next", async importOriginal => {
|
|||||||
return await importOriginal();
|
return await importOriginal();
|
||||||
});
|
});
|
||||||
|
|
||||||
initVouchers();
|
|
||||||
initAchievements();
|
|
||||||
initStatsKeys();
|
|
||||||
initPokemonPrevolutions();
|
|
||||||
initBiomes();
|
|
||||||
initEggMoves();
|
|
||||||
initPokemonForms();
|
|
||||||
initSpecies();
|
|
||||||
initMoves();
|
|
||||||
initAbilities();
|
|
||||||
initLoggedInUser();
|
|
||||||
initMysteryEncounters();
|
|
||||||
|
|
||||||
global.testFailed = false;
|
global.testFailed = false;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
Object.defineProperty(document, "fonts", {
|
initTestFile();
|
||||||
writable: true,
|
|
||||||
value: {
|
|
||||||
add: () => {},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
|
@ -1,20 +1,31 @@
|
|||||||
import { defineProject } from "vitest/config";
|
import { defineProject } from "vitest/config";
|
||||||
import { defaultConfig } from "./vite.config";
|
import { defaultConfig } from "./vite.config";
|
||||||
|
import { BaseSequencer, type TestSpecification } from "vitest/node";
|
||||||
|
|
||||||
|
function getTestOrder(testName: string): number {
|
||||||
|
if (testName.includes("battle-scene.test.ts")) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (testName.includes("inputs.test.ts")) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
export default defineProject(({ mode }) => ({
|
export default defineProject(({ mode }) => ({
|
||||||
...defaultConfig,
|
...defaultConfig,
|
||||||
test: {
|
test: {
|
||||||
testTimeout: 20000,
|
testTimeout: 20000,
|
||||||
setupFiles: ["./test/fontFace.setup.ts", "./test/vitest.setup.ts"],
|
setupFiles: ["./test/fontFace.setup.ts", "./test/vitest.setup.ts"],
|
||||||
server: {
|
sequence: {
|
||||||
deps: {
|
sequencer: class CustomSequencer extends BaseSequencer {
|
||||||
inline: ["vitest-canvas-mock"],
|
async sort(files: TestSpecification[]) {
|
||||||
//@ts-ignore
|
// use default sorting at first.
|
||||||
optimizer: {
|
files = await super.sort(files);
|
||||||
web: {
|
// Except, forcibly reorder
|
||||||
include: ["vitest-canvas-mock"],
|
|
||||||
},
|
return files.sort((a, b) => getTestOrder(a.moduleId) - getTestOrder(b.moduleId));
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
environment: "jsdom" as const,
|
environment: "jsdom" as const,
|
||||||
@ -34,7 +45,6 @@ export default defineProject(({ mode }) => ({
|
|||||||
},
|
},
|
||||||
name: "main",
|
name: "main",
|
||||||
include: ["./test/**/*.{test,spec}.ts"],
|
include: ["./test/**/*.{test,spec}.ts"],
|
||||||
exclude: ["./test/pre.test.ts"],
|
|
||||||
},
|
},
|
||||||
esbuild: {
|
esbuild: {
|
||||||
pure: mode === "production" ? ["console.log"] : [],
|
pure: mode === "production" ? ["console.log"] : [],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user