├── .eslintrc.cjs ├── .github ├── dependabot.yml ├── icon.png └── workflows │ └── nodejs.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .markdownlint.jsonc ├── .vscode ├── extensions.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── config └── jest-setup.ts ├── jest.config.js ├── jest.d.ts ├── package-lock.json ├── package.json ├── src ├── __tests__ │ └── spies.test.ts ├── extend-expect.ts ├── hooks │ ├── __tests__ │ │ ├── replace-location-node.test.ts │ │ └── replace-location.test.ts │ ├── index.ts │ └── replace-location.ts ├── index.ts ├── matchers │ ├── __tests__ │ │ └── to-be-at.test.ts │ ├── index.ts │ ├── messages.ts │ └── to-be-at.ts ├── setup-hooks.ts └── utils │ ├── __tests__ │ ├── location-mock-relative.test.ts │ └── urlify.test.ts │ ├── index.ts │ ├── location-mock-relative.ts │ └── urlify.ts ├── tsconfig-build.json ├── tsconfig.json └── wallaby.js /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": [ 3 | "evelyn", 4 | ], 5 | 6 | "extends": [ 7 | "plugin:evelyn/default", 8 | "plugin:evelyn/typescript", 9 | ], 10 | 11 | "ignorePatterns": [ 12 | "lib", 13 | "coverage", 14 | ], 15 | 16 | "rules": { 17 | // When passing Location methods, TypeScript will warn that it's unbound, but we're not calling them 18 | "@typescript-eslint/unbound-method": "off", 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | allow: 6 | - dependency-type: production 7 | schedule: 8 | interval: "weekly" 9 | versioning-strategy: widen 10 | commit-message: 11 | prefix: "Upgrade(npm):" 12 | prefix-development: "Upgrade(dev):" 13 | reviewers: 14 | - "evelynhathaway" 15 | assignees: 16 | - "evelynhathaway" 17 | -------------------------------------------------------------------------------- /.github/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evelynhathaway/jest-location-mock/0bd9c82edad684bd14e3902c656a2dec66cc2f6c/.github/icon.png -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: nodejs 2 | 3 | on: push 4 | 5 | jobs: 6 | testing: 7 | runs-on: ubuntu-latest 8 | env: 9 | CI: true 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Use Node.js 18.x 13 | uses: actions/setup-node@v2 14 | with: 15 | node-version: 18.x 16 | 17 | # From: https://help.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows#example-using-the-cache-action 18 | - name: Cache node modules 19 | uses: actions/cache@v2 20 | env: 21 | cache-name: cache-node-modules 22 | with: 23 | path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS 24 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 25 | restore-keys: | 26 | ${{ runner.os }}-build-${{ env.cache-name }}- 27 | ${{ runner.os }}-build- 28 | ${{ runner.os }}- 29 | 30 | - name: Install Dependencies 31 | run: npm ci 32 | 33 | - name: Lint 34 | run: npm run lint 35 | 36 | - name: Test 37 | run: npm test 38 | 39 | - name: Build 40 | run: npm run build 41 | 42 | release: 43 | needs: testing 44 | runs-on: ubuntu-latest 45 | env: 46 | CI: true 47 | steps: 48 | - uses: actions/checkout@v2 49 | - name: Use Node.js 18.x 50 | uses: actions/setup-node@v2 51 | with: 52 | node-version: 18.x 53 | 54 | # From: https://help.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows#example-using-the-cache-action 55 | - name: Cache node modules 56 | uses: actions/cache@v2 57 | env: 58 | cache-name: cache-node-modules 59 | with: 60 | path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS 61 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 62 | restore-keys: | 63 | ${{ runner.os }}-build-${{ env.cache-name }}- 64 | ${{ runner.os }}-build- 65 | ${{ runner.os }}- 66 | 67 | - name: Install Dependencies 68 | run: npm ci 69 | 70 | - name: Build 71 | run: npm run build 72 | 73 | - name: Release 74 | run: npx semantic-release 75 | env: 76 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 77 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 78 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node 2 | node_modules/ 3 | 4 | # IDE 5 | .idea/ 6 | .vscode/* 7 | !.vscode/settings.json 8 | !.vscode/tasks.json 9 | !.vscode/launch.json 10 | !.vscode/extensions.json 11 | 12 | # Built 13 | /dist 14 | /lib 15 | 16 | # Testing 17 | /coverage 18 | 19 | # Other 20 | .cache 21 | /*.log 22 | *.lock 23 | .DS_Store 24 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit "$1" 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no lint-staged 5 | -------------------------------------------------------------------------------- /.markdownlint.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "heading-increment": true, 3 | "no-hard-tabs": false, 4 | "first-line-heading": false, 5 | "heading-style": { 6 | "style": "atx" 7 | }, 8 | "ul-style": { 9 | "style": "dash" 10 | }, 11 | "list-indent": true, 12 | "ul-indent": { 13 | "indent": 4, 14 | "start_indented": false 15 | }, 16 | "no-trailing-spaces": { 17 | "strict": true, 18 | "br_spaces": 2 19 | }, 20 | "no-reversed-links": true, 21 | "no-inline-html": false, 22 | "no-emphasis-as-heading": false, 23 | "no-multiple-blanks": { 24 | "maximum": 2 25 | }, 26 | "line-length": false, 27 | "commands-show-output": true, 28 | "no-missing-space-atx": true, 29 | "no-multiple-space-atx": true, 30 | "blanks-around-headings": true, 31 | "heading-start-left": true, 32 | "no-duplicate-heading": { 33 | "siblings_only": true 34 | }, 35 | "single-title": true, 36 | "no-trailing-punctuation": true, 37 | "no-multiple-space-blockquote": true, 38 | "no-blanks-blockquote": true, 39 | "ol-prefix": { 40 | "style": "one_or_ordered" 41 | }, 42 | "list-marker-space": true, 43 | "blanks-around-fences": { 44 | "list_items": false 45 | }, 46 | "blanks-around-lists": true, 47 | "no-bare-urls": true, 48 | "hr-style": { 49 | "style": "---" 50 | }, 51 | "no-space-in-emphasis": true, 52 | "no-space-in-code": true, 53 | "no-space-in-links": true, 54 | "fenced-code-language": true, 55 | "no-empty-links": true, 56 | "proper-names": { 57 | "names": [ 58 | "JavaScript", 59 | "TypeScript", 60 | "npm", 61 | "Node.js", 62 | "GitHub" 63 | ] 64 | }, 65 | "no-alt-text": true, 66 | "code-block-style": { 67 | "style": "fenced" 68 | }, 69 | "single-trailing-newline": true, 70 | "code-fence-style": { 71 | "style": "backtick" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "streetsidesoftware.code-spell-checker", 4 | "dbaeumer.vscode-eslint", 5 | "davidanson.vscode-markdownlint", 6 | "pflannery.vscode-versionlens", 7 | "wallabyjs.wallaby-vscode", 8 | "redhat.vscode-yaml", 9 | ], 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "eslint.format.enable": true, 4 | "eslint.lintTask.enable": true, 5 | "files.associations": { 6 | ".env": "shellscript", 7 | ".env.*": "shellscript", 8 | }, 9 | "files.eol": "\n", 10 | "files.insertFinalNewline": true, 11 | "files.trimFinalNewlines": true, 12 | "files.trimTrailingWhitespace": true, 13 | "html.format.wrapAttributes": "force-expand-multiline", 14 | "javascript.format.insertSpaceAfterConstructor": true, 15 | "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false, 16 | "javascript.format.insertSpaceBeforeFunctionParenthesis": true, 17 | "javascript.format.semicolons": "insert", 18 | "javascript.preferences.importModuleSpecifierEnding": "minimal", 19 | "javascript.preferences.quoteStyle": "double", 20 | "typescript.format.insertSpaceAfterConstructor": true, 21 | "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false, 22 | "typescript.format.insertSpaceAfterTypeAssertion": true, 23 | "typescript.format.insertSpaceBeforeFunctionParenthesis": true, 24 | "typescript.format.semicolons": "insert", 25 | "typescript.tsdk": "node_modules\\typescript\\lib", 26 | "versionlens.suggestions.showOnStartup": true, 27 | "[javascript]": { 28 | "editor.defaultFormatter": "dbaeumer.vscode-eslint" 29 | }, 30 | "[javascriptreact]": { 31 | "editor.defaultFormatter": "dbaeumer.vscode-eslint" 32 | }, 33 | "[typescript]": { 34 | "editor.defaultFormatter": "dbaeumer.vscode-eslint" 35 | }, 36 | "[typescriptreact]": { 37 | "editor.defaultFormatter": "dbaeumer.vscode-eslint" 38 | }, 39 | } 40 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v2.0.0 4 | 5 | **[`v1.0.10...v2.0.0`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.10...v2.0.0)** - **2023-09-04** 6 | 7 | ### 💥 Breaking 8 | 9 | - Drop support node 17 and < 16.10.0 [`4512b25`](https://github.com/evelynhathaway/jest-location-mock/commit/4512b25) 10 | 11 | ### 📦 Package 12 | 13 | - **dev:** npm update and npm audit fix [`ab8036d`](https://github.com/evelynhathaway/jest-location-mock/commit/ab8036d) 14 | - **npm:** Bump jest-diff from 27.2.0 to 29.6.4 [`830895f`](https://github.com/evelynhathaway/jest-location-mock/commit/830895f) 15 | 16 | ## v1.0.10 17 | 18 | **[`v1.0.9...v1.0.10`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.9...v1.0.10)** - **2023-07-02** 19 | 20 | ### 🐛 Fix 21 | 22 | - Handle undefined window by returning silently [`daa0c6e`](https://github.com/evelynhathaway/jest-location-mock/commit/daa0c6e) 23 | 24 | ### 📦 Package 25 | 26 | - **dev:** Bump @semantic-release/git from 9.0.0 to 9.0.1 [`8c55a37`](https://github.com/evelynhathaway/jest-location-mock/commit/8c55a37) 27 | - **dev:** Bump @types/jest from 26.0.23 to 26.0.24 [`f95bfcc`](https://github.com/evelynhathaway/jest-location-mock/commit/f95bfcc) 28 | - **dev:** Bump @types/jest from 26.0.24 to 27.0.0 [`c0d5a35`](https://github.com/evelynhathaway/jest-location-mock/commit/c0d5a35) 29 | - **dev:** Bump @types/jest from 27.0.0 to 27.0.1 [`91b6038`](https://github.com/evelynhathaway/jest-location-mock/commit/91b6038) 30 | - **dev:** Bump @typescript-eslint/eslint-plugin [`f327db2`](https://github.com/evelynhathaway/jest-location-mock/commit/f327db2) 31 | - **dev:** Bump @typescript-eslint/eslint-plugin [`452d5be`](https://github.com/evelynhathaway/jest-location-mock/commit/452d5be) 32 | - **dev:** Bump @typescript-eslint/eslint-plugin [`ad95aa2`](https://github.com/evelynhathaway/jest-location-mock/commit/ad95aa2) 33 | - **dev:** Bump @typescript-eslint/eslint-plugin [`f79d00c`](https://github.com/evelynhathaway/jest-location-mock/commit/f79d00c) 34 | - **dev:** Bump @typescript-eslint/eslint-plugin [`45f62d8`](https://github.com/evelynhathaway/jest-location-mock/commit/45f62d8) 35 | - **dev:** Bump @typescript-eslint/eslint-plugin [`d409d19`](https://github.com/evelynhathaway/jest-location-mock/commit/d409d19) 36 | - **dev:** Bump @typescript-eslint/eslint-plugin [`14a1d04`](https://github.com/evelynhathaway/jest-location-mock/commit/14a1d04) 37 | - **dev:** Bump @typescript-eslint/eslint-plugin [`8a5feb4`](https://github.com/evelynhathaway/jest-location-mock/commit/8a5feb4) 38 | - **dev:** Bump @typescript-eslint/eslint-plugin [`e11a658`](https://github.com/evelynhathaway/jest-location-mock/commit/e11a658) 39 | - **dev:** Bump @typescript-eslint/eslint-plugin [`43e9626`](https://github.com/evelynhathaway/jest-location-mock/commit/43e9626) 40 | - **dev:** Bump @typescript-eslint/parser from 4.25.0 to 4.26.0 [`b6c207a`](https://github.com/evelynhathaway/jest-location-mock/commit/b6c207a) 41 | - **dev:** Bump @typescript-eslint/parser from 4.26.0 to 4.26.1 [`bd0b78d`](https://github.com/evelynhathaway/jest-location-mock/commit/bd0b78d) 42 | - **dev:** Bump @typescript-eslint/parser from 4.26.1 to 4.28.4 [`6f5376e`](https://github.com/evelynhathaway/jest-location-mock/commit/6f5376e) 43 | - **dev:** Bump @typescript-eslint/parser from 4.28.4 to 4.29.0 [`10c7591`](https://github.com/evelynhathaway/jest-location-mock/commit/10c7591) 44 | - **dev:** Bump @typescript-eslint/parser from 4.29.0 to 4.29.1 [`38c5f48`](https://github.com/evelynhathaway/jest-location-mock/commit/38c5f48) 45 | - **dev:** Bump @typescript-eslint/parser from 4.29.1 to 4.29.2 [`4291b6b`](https://github.com/evelynhathaway/jest-location-mock/commit/4291b6b) 46 | - **dev:** Bump @typescript-eslint/parser from 4.29.2 to 4.29.3 [`459837f`](https://github.com/evelynhathaway/jest-location-mock/commit/459837f) 47 | - **dev:** Bump @typescript-eslint/parser from 4.29.3 to 4.31.0 [`59644b6`](https://github.com/evelynhathaway/jest-location-mock/commit/59644b6) 48 | - **dev:** Bump @typescript-eslint/parser from 4.31.0 to 4.31.1 [`3b6caa3`](https://github.com/evelynhathaway/jest-location-mock/commit/3b6caa3) 49 | - **dev:** Bump commitlint from 12.1.4 to 13.1.0 [`cd99683`](https://github.com/evelynhathaway/jest-location-mock/commit/cd99683) 50 | - **dev:** Bump eslint from 7.27.0 to 7.28.0 [`fc4b555`](https://github.com/evelynhathaway/jest-location-mock/commit/fc4b555) 51 | - **dev:** Bump eslint from 7.28.0 to 7.31.0 [`96c5796`](https://github.com/evelynhathaway/jest-location-mock/commit/96c5796) 52 | - **dev:** Bump eslint from 7.31.0 to 7.32.0 [`f06bd57`](https://github.com/evelynhathaway/jest-location-mock/commit/f06bd57) 53 | - **dev:** Bump eslint-plugin-import from 2.23.4 to 2.24.0 [`8bd1ced`](https://github.com/evelynhathaway/jest-location-mock/commit/8bd1ced) 54 | - **dev:** Bump eslint-plugin-import from 2.24.0 to 2.24.1 [`2a4a678`](https://github.com/evelynhathaway/jest-location-mock/commit/2a4a678) 55 | - **dev:** Bump eslint-plugin-import from 2.24.1 to 2.24.2 [`d76d0c1`](https://github.com/evelynhathaway/jest-location-mock/commit/d76d0c1) 56 | - **dev:** Bump eslint-plugin-regexp from 0.11.0 to 0.13.2 [`80e0f54`](https://github.com/evelynhathaway/jest-location-mock/commit/80e0f54) 57 | - **dev:** Bump eslint-plugin-testing-library from 4.10.1 to 4.11.0 [`c41cdf1`](https://github.com/evelynhathaway/jest-location-mock/commit/c41cdf1) 58 | - **dev:** Bump eslint-plugin-testing-library from 4.11.0 to 4.12.0 [`128a43a`](https://github.com/evelynhathaway/jest-location-mock/commit/128a43a) 59 | - **dev:** Bump eslint-plugin-testing-library from 4.12.0 to 4.12.1 [`1a9de20`](https://github.com/evelynhathaway/jest-location-mock/commit/1a9de20) 60 | - **dev:** Bump eslint-plugin-testing-library from 4.12.1 to 4.12.2 [`0bde84a`](https://github.com/evelynhathaway/jest-location-mock/commit/0bde84a) 61 | - **dev:** Bump eslint-plugin-testing-library from 4.6.0 to 4.10.1 [`681cff7`](https://github.com/evelynhathaway/jest-location-mock/commit/681cff7) 62 | - **dev:** Bump jest from 27.0.3 to 27.0.4 [`7a3f257`](https://github.com/evelynhathaway/jest-location-mock/commit/7a3f257) 63 | - **dev:** Bump jest from 27.0.4 to 27.0.6 [`672a59b`](https://github.com/evelynhathaway/jest-location-mock/commit/672a59b) 64 | - **dev:** Bump jest from 27.0.6 to 27.1.1 [`16bf2d3`](https://github.com/evelynhathaway/jest-location-mock/commit/16bf2d3) 65 | - **dev:** Bump jest from 27.1.1 to 27.2.0 [`a264534`](https://github.com/evelynhathaway/jest-location-mock/commit/a264534) 66 | - **dev:** Bump lint-staged from 11.0.0 to 11.1.1 [`24f483c`](https://github.com/evelynhathaway/jest-location-mock/commit/24f483c) 67 | - **dev:** Bump lint-staged from 11.1.1 to 11.1.2 [`618385e`](https://github.com/evelynhathaway/jest-location-mock/commit/618385e) 68 | - **dev:** Bump semantic-release from 17.4.3 to 17.4.4 [`ca4eb0b`](https://github.com/evelynhathaway/jest-location-mock/commit/ca4eb0b) 69 | - **dev:** Bump semantic-release from 17.4.4 to 17.4.5 [`c76c2e4`](https://github.com/evelynhathaway/jest-location-mock/commit/c76c2e4) 70 | - **dev:** Bump semantic-release from 17.4.5 to 17.4.6 [`4aebfa5`](https://github.com/evelynhathaway/jest-location-mock/commit/4aebfa5) 71 | - **dev:** Bump semantic-release from 17.4.6 to 17.4.7 [`062056f`](https://github.com/evelynhathaway/jest-location-mock/commit/062056f) 72 | - **dev:** Bump sort-package-json from 1.50.0 to 1.51.0 [`93ac06e`](https://github.com/evelynhathaway/jest-location-mock/commit/93ac06e) 73 | - **dev:** Bump ts-jest from 27.0.2 to 27.0.3 [`7591991`](https://github.com/evelynhathaway/jest-location-mock/commit/7591991) 74 | - **dev:** Bump ts-jest from 27.0.3 to 27.0.4 [`f69b805`](https://github.com/evelynhathaway/jest-location-mock/commit/f69b805) 75 | - **dev:** Bump ts-jest from 27.0.4 to 27.0.5 [`a10df76`](https://github.com/evelynhathaway/jest-location-mock/commit/a10df76) 76 | - **dev:** Bump typescript from 4.3.2 to 4.3.5 [`f11512b`](https://github.com/evelynhathaway/jest-location-mock/commit/f11512b) 77 | - **dev:** Bump typescript from 4.3.5 to 4.4.2 [`af4a8ec`](https://github.com/evelynhathaway/jest-location-mock/commit/af4a8ec) 78 | - **dev:** Bump typescript from 4.4.2 to 4.4.3 [`6446303`](https://github.com/evelynhathaway/jest-location-mock/commit/6446303) 79 | 80 | ### 🧹 Internal 81 | 82 | - Add test for Node.js environment, fix lint and meta [`95e04c6`](https://github.com/evelynhathaway/jest-location-mock/commit/95e04c6) 83 | 84 | ## v1.0.9 85 | 86 | **[`v1.0.8...v1.0.9`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.8...v1.0.9)** - **2021-05-31** 87 | 88 | ### 📦 Package 89 | 90 | - **dev:** Bump eslint-plugin-evelyn from 6.2.0 to 6.2.1 [`289f772`](https://github.com/evelynhathaway/jest-location-mock/commit/289f772) 91 | - **dev:** Bump eslint-plugin-import from 2.23.3 to 2.23.4 [`6cc5c74`](https://github.com/evelynhathaway/jest-location-mock/commit/6cc5c74) 92 | - **dev:** Bump eslint-plugin-regexp from 0.10.0 to 0.11.0 [`33140e6`](https://github.com/evelynhathaway/jest-location-mock/commit/33140e6) 93 | - **dev:** Bump jest from 27.0.1 to 27.0.3 [`4c9456b`](https://github.com/evelynhathaway/jest-location-mock/commit/4c9456b) 94 | - **dev:** Bump ts-jest from 27.0.0 to 27.0.1 [`bb9fac7`](https://github.com/evelynhathaway/jest-location-mock/commit/bb9fac7) 95 | - **dev:** Bump ts-jest from 27.0.1 to 27.0.2 [`7f5b322`](https://github.com/evelynhathaway/jest-location-mock/commit/7f5b322) 96 | - **dev:** Update conventional changelog config [`e0cd208`](https://github.com/evelynhathaway/jest-location-mock/commit/e0cd208) 97 | - **prod:** Bump jest-diff from 27.0.1 to 27.0.2 [`b0a1668`](https://github.com/evelynhathaway/jest-location-mock/commit/b0a1668) 98 | 99 | ### 🧹 Internal 100 | 101 | - Fix unsorted changelog release [`86167c7`](https://github.com/evelynhathaway/jest-location-mock/commit/86167c7) 102 | 103 | ## v1.0.8 104 | 105 | **[`v1.0.7...v1.0.8`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.7...v1.0.8)** - **2021-05-26** 106 | 107 | ### 📦 Package 108 | 109 | - **dev:** Bump eslint from 7.26.0 to 7.27.0 ([#13](https://github.com/evelynhathaway/jest-location-mock/issues/13)) [`7a85a45`](https://github.com/evelynhathaway/jest-location-mock/commit/7a85a45) 110 | - **dev:** Bump eslint-plugin-evelyn from 6.1.0 to 6.2.0 ([#17](https://github.com/evelynhathaway/jest-location-mock/issues/17)) [`c7c8adf`](https://github.com/evelynhathaway/jest-location-mock/commit/c7c8adf) 111 | - **dev:** Bump eslint-plugin-import from 2.23.2 to 2.23.3 ([#16](https://github.com/evelynhathaway/jest-location-mock/issues/16)) [`ec7e79c`](https://github.com/evelynhathaway/jest-location-mock/commit/ec7e79c) 112 | - **dev:** Bump eslint-plugin-testing-library from 4.5.0 to 4.6.0 ([#14](https://github.com/evelynhathaway/jest-location-mock/issues/14)) [`cb369fe`](https://github.com/evelynhathaway/jest-location-mock/commit/cb369fe) 113 | - **dev:** npm update [`b1f9faf`](https://github.com/evelynhathaway/jest-location-mock/commit/b1f9faf) 114 | - **dev:** npm update linting plugins [`121e955`](https://github.com/evelynhathaway/jest-location-mock/commit/121e955) 115 | - **dev:** npm update, linting [`3dbec04`](https://github.com/evelynhathaway/jest-location-mock/commit/3dbec04) 116 | - **prod:** Bump jest deps to v27 [`42ce4c2`](https://github.com/evelynhathaway/jest-location-mock/commit/42ce4c2) 117 | 118 | ### 🧹 Internal 119 | 120 | - Change dependabot config [`8380021`](https://github.com/evelynhathaway/jest-location-mock/commit/8380021) 121 | 122 | ## v1.0.7 123 | 124 | **[`v1.0.6...v1.0.7`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.6...v1.0.7)** - **2021-05-18** 125 | 126 | ### 📦 Package 127 | 128 | - **npm:** Bump @typescript-eslint/eslint-plugin [`3bc0303`](https://github.com/evelynhathaway/jest-location-mock/commit/3bc0303) 129 | - **npm:** Bump @typescript-eslint/parser from 4.23.0 to 4.24.0 [`88a6287`](https://github.com/evelynhathaway/jest-location-mock/commit/88a6287) 130 | - **npm:** Bump conventional-changelog-evelyn from 1.2.2 to 1.2.3 [`96b4eab`](https://github.com/evelynhathaway/jest-location-mock/commit/96b4eab) 131 | 132 | ## v1.0.6 133 | 134 | **[`v1.0.5...v1.0.6`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.5...v1.0.6)** - **2021-05-17** 135 | 136 | ### 📄 Documentation 137 | 138 | - **readme:** Update badges [`e0e4c56`](https://github.com/evelynhathaway/jest-location-mock/commit/e0e4c56) 139 | 140 | ## v1.0.5 141 | 142 | **[`v1.0.4...v1.0.5`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.4...v1.0.5)** - **2021-05-17** 143 | 144 | ### 📦 Package 145 | 146 | - **npm:** Bump node-notifier from 8.0.0 to 8.0.2 [`e783967`](https://github.com/evelynhathaway/jest-location-mock/commit/e783967) 147 | 148 | ### Other 149 | 150 | - **test:** Add wallaby config file [`e1c60fe`](https://github.com/evelynhathaway/jest-location-mock/commit/e1c60fe) 151 | 152 | ## v1.0.4 153 | 154 | **[`v1.0.3...v1.0.4`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.3...v1.0.4)** - **2021-05-17** 155 | 156 | ### 📦 Package 157 | 158 | - **npm:** Bump eslint-plugin-testing-library from 3.10.2 to 4.4.0 [`eb01e94`](https://github.com/evelynhathaway/jest-location-mock/commit/eb01e94) 159 | 160 | ## v1.0.3 161 | 162 | **[`v1.0.2...v1.0.3`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.2...v1.0.3)** - **2021-05-17** 163 | 164 | ### 📦 Package 165 | 166 | - **npm:** Update release config [`68be1d3`](https://github.com/evelynhathaway/jest-location-mock/commit/68be1d3) 167 | - npm update [`5a9b188`](https://github.com/evelynhathaway/jest-location-mock/commit/5a9b188) 168 | 169 | ### Other 170 | 171 | - Update GitHub Action workflow [`9852b4c`](https://github.com/evelynhathaway/jest-location-mock/commit/9852b4c) 172 | - Update GitHub Actions workflow [`36735d0`](https://github.com/evelynhathaway/jest-location-mock/commit/36735d0) 173 | 174 | ## v1.0.2 175 | 176 | **[`v1.0.1...v1.0.2`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.1...v1.0.2)** - **2021-02-03** 177 | 178 | ### 🐛 Fix 179 | 180 | - Properly build and extend expect with types [`b201eae`](https://github.com/evelynhathaway/jest-location-mock/commit/b201eae) 181 | - Properly install location mock [`f8a8a08`](https://github.com/evelynhathaway/jest-location-mock/commit/f8a8a08) 182 | 183 | ## v1.0.1 184 | 185 | **[`v1.0.0...v1.0.1`](https://github.com/evelynhathaway/jest-location-mock/compare/v1.0.0...v1.0.1)** - **2020-11-21** 186 | 187 | ### 🐛 Fix 188 | 189 | - Update package.json engines [`c3e380c`](https://github.com/evelynhathaway/jest-location-mock/commit/c3e380c) 190 | 191 | ## v1.0.0 192 | 193 | **2020-11-21** 194 | 195 | ### ✨ Feature 196 | 197 | - Add toBeAt matcher, refactor [`6d9a43d`](https://github.com/evelynhathaway/jest-location-mock/commit/6d9a43d) 198 | - Initial location hooks proof of concept [`82c2120`](https://github.com/evelynhathaway/jest-location-mock/commit/82c2120) 199 | 200 | ### 📄 Documentation 201 | 202 | - Meta update, readme, types, license [`efc9fc5`](https://github.com/evelynhathaway/jest-location-mock/commit/efc9fc5) 203 | 204 | ### 📦 Package 205 | 206 | - npm update [`dd8eff0`](https://github.com/evelynhathaway/jest-location-mock/commit/dd8eff0) 207 | 208 | ### Other 209 | 210 | - Initial noop commit [`6937d8c`](https://github.com/evelynhathaway/jest-location-mock/commit/6937d8c) 211 | - Add CI, release, and build [`f94f240`](https://github.com/evelynhathaway/jest-location-mock/commit/f94f240) 212 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Evelyn Hathaway 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | Jest Location Mock icon 4 | 5 | # Jest Location Mock 6 | 7 | **Jest hooks for JSDOM location mock** 8 | 9 | [![npm version](https://badgen.net/npm/v/jest-location-mock?icon=npm)](https://www.npmjs.com/package/jest-location-mock) 10 | [![check status](https://badgen.net/github/checks/evelynhathaway/jest-location-mock/main?icon=github)](https://github.com/evelynhathaway/jest-location-mock/actions) 11 | [![license: MIT](https://badgen.net/badge/license/MIT/blue)](/LICENSE) 12 | 13 |
14 | 15 | ## Description 16 | 17 | Ever gotten the following error when using `window.location.assign`, `reload`, or `replace`? 18 | 19 | ```txt 20 | Error: Not implemented: navigation (except hash changes) 21 | ``` 22 | 23 | This Jest plugin fixes this error and mocks out `window.location` so it behaves similar to how does in the browser. 24 | 25 | ## Features 26 | 27 | - Mock and control window.location 28 | - Relative URL support 29 | - TypeScript extend expect support 30 | 31 | ## Installation 32 | 33 | ```bash 34 | npm install --save-dev jest-location-mock 35 | ``` 36 | 37 | ## Usage 38 | 39 | To start using Jest Location Mock, extend expect and add hooks by importing the default export in your jest setup file. 40 | 41 | ### Setup 42 | 43 | **`jest.config.js`** 44 | 45 | ```js 46 | module.exports = { 47 | setupFilesAfterEnv: [ 48 | "./config/jest-setup.js" 49 | ] 50 | }; 51 | ``` 52 | 53 | **`config/jest-setup.js`** 54 | 55 | ```js 56 | // Mock `window.location` with Jest spies and extend expect 57 | import "jest-location-mock"; 58 | ``` 59 | 60 | ### Matchers 61 | 62 | #### `expect(location).toBeAt(url, [base])` 63 | 64 | **Throws**: When the URLs have a different absolute `href`. 65 | 66 | | Parameter | Type | Description | 67 | | --------- | ------------------- | ----------------------------------------------------------------------- | 68 | | location | `Location` \| `URL` | Instance of `URL` to check its `href` | 69 | | url | `string` \| `URL` | Relative or absolute `URL` | 70 | | base | `string` \| `URL` | If the `url` parameter is relative, an base URL for the URL constructor | 71 | 72 | ```ts 73 | it("should call assign with a relative url", () => { 74 | window.location.assign("/relative-url"); 75 | expect(window.location).not.toBeAt("/"); 76 | expect(window.location).toBeAt("/relative-url"); 77 | }); 78 | ``` 79 | 80 | ## License 81 | 82 | Copyright Evelyn Hathaway, [MIT License](/LICENSE) 83 | -------------------------------------------------------------------------------- /config/jest-setup.ts: -------------------------------------------------------------------------------- 1 | // Default setup side-effects 2 | import "../src"; 3 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | 4 | module.exports = { 5 | preset: "ts-jest", 6 | clearMocks: true, 7 | collectCoverage: true, 8 | collectCoverageFrom: [ 9 | "src/**/*", 10 | "!src/**/index.ts", 11 | "!**/__tests__/**/*", 12 | ], 13 | coverageThreshold: { 14 | global: { 15 | branches: 100, 16 | functions: 100, 17 | lines: 100, 18 | statements: 100, 19 | }, 20 | }, 21 | testEnvironment: "jsdom", 22 | setupFilesAfterEnv: [ 23 | "./config/jest-setup.ts", 24 | ], 25 | verbose: true, 26 | }; 27 | -------------------------------------------------------------------------------- /jest.d.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line spaced-comment 2 | /// 3 | 4 | declare namespace jest { 5 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 6 | interface Matchers { 7 | toBeAt(url: string | URL, base?: string | URL): R; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest-location-mock", 3 | "version": "2.0.0", 4 | "description": "Jest hooks for JSDOM location mock", 5 | "keywords": [ 6 | "jest", 7 | "jsdom", 8 | "location" 9 | ], 10 | "homepage": "https://github.com/evelynhathaway/jest-location-mock#readme", 11 | "bugs": { 12 | "url": "https://github.com/evelynhathaway/jest-location-mock/issues" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/evelynhathaway/jest-location-mock.git" 17 | }, 18 | "license": "MIT", 19 | "author": "Evelyn Hathaway (https://evelyn.dev)", 20 | "sideEffects": true, 21 | "main": "./lib/index.js", 22 | "types": "./lib/index.d.ts", 23 | "directories": { 24 | "lib": "/lib", 25 | "src": "/src" 26 | }, 27 | "files": [ 28 | "/lib", 29 | "/jest.d.ts" 30 | ], 31 | "scripts": { 32 | "build": "tsc -p ./tsconfig-build.json", 33 | "lint": "eslint ./", 34 | "prepare": "husky install", 35 | "test": "jest" 36 | }, 37 | "commitlint": { 38 | "extends": "./node_modules/conventional-changelog-evelyn/commitlint.config.js" 39 | }, 40 | "lint-staged": { 41 | "**/package.json": "sort-package-json", 42 | "./": "eslint --fix" 43 | }, 44 | "release": { 45 | "extends": "conventional-changelog-evelyn/release.config.js" 46 | }, 47 | "dependencies": { 48 | "@jedmao/location": "^3.0.0", 49 | "jest-diff": "^29.6.4" 50 | }, 51 | "devDependencies": { 52 | "@semantic-release/changelog": "^6.0.3", 53 | "@semantic-release/git": "^10.0.1", 54 | "@types/jest": "^29.5.4", 55 | "@typescript-eslint/eslint-plugin": "^5.60.1", 56 | "@typescript-eslint/parser": "^5.60.1", 57 | "commitlint": "^17.7.1", 58 | "conventional-changelog-evelyn": "^1.3.1", 59 | "eslint": "^8.44.0", 60 | "eslint-plugin-evelyn": "^9.0.0", 61 | "eslint-plugin-unicorn": "^47.0.0", 62 | "husky": "^8.0.3", 63 | "jest": "^29.6.4", 64 | "jest-environment-jsdom": "^29.6.4", 65 | "lint-staged": "^14.0.1", 66 | "semantic-release": "^21.1.1", 67 | "sort-package-json": "^2.5.1", 68 | "ts-jest": "^29.1.1", 69 | "typescript": "^5.2.2" 70 | }, 71 | "engines": { 72 | "node": "^16.10.0 || >=18.0.0" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/__tests__/spies.test.ts: -------------------------------------------------------------------------------- 1 | it("should have spy for assign", () => { 2 | window.location.assign("/relative-url"); 3 | expect(window.location.assign).toHaveBeenCalledWith("/relative-url"); 4 | }); 5 | 6 | it("should have spy for reload", () => { 7 | window.location.reload(); 8 | expect(window.location.reload).toHaveBeenCalled(); 9 | }); 10 | 11 | it("should have spy for replace", () => { 12 | window.location.replace("/relative-url"); 13 | expect(window.location.replace).toHaveBeenCalledWith("/relative-url"); 14 | }); 15 | -------------------------------------------------------------------------------- /src/extend-expect.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/triple-slash-reference, spaced-comment 2 | /// 3 | // eslint-disable-next-line import/namespace 4 | import * as extensions from "./matchers"; 5 | 6 | 7 | expect.extend(extensions); 8 | -------------------------------------------------------------------------------- /src/hooks/__tests__/replace-location-node.test.ts: -------------------------------------------------------------------------------- 1 | /** @jest-environment node */ 2 | describe("when window not defined", () => { 3 | it("should not have changed window", () => { 4 | expect(typeof window).toBe("undefined"); 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /src/hooks/__tests__/replace-location.test.ts: -------------------------------------------------------------------------------- 1 | describe("host environment variable", () => { 2 | // Runs before default hooks 3 | beforeAll(() => { 4 | process.env.HOST = "https://example.com"; 5 | }); 6 | 7 | it("should include the host variable as the base", () => { 8 | window.location.assign("/relative-url"); 9 | expect(window.location.href).toEqual("https://example.com/relative-url"); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./replace-location"; 2 | -------------------------------------------------------------------------------- /src/hooks/replace-location.ts: -------------------------------------------------------------------------------- 1 | import {LocationMockRelative} from "../utils"; 2 | 3 | 4 | export const replaceLocation = (): void => { 5 | // Do nothing if window is not defined 6 | // - Prevents an error when importing this mock in the setup file when some tests use the node test environment instead of JSDOM 7 | if (typeof window === "undefined") { 8 | return; 9 | } 10 | // Set the base URL for relative URLs to `HOST` environment variable, defaults to localhost 11 | const locationMock = new LocationMockRelative(process.env.HOST || "http://localhost/"); 12 | 13 | // Setup Jest spies on the methods for convenience and our matchers 14 | jest.spyOn(locationMock, "assign").mockName("window.location.assign"); 15 | jest.spyOn(locationMock, "reload").mockName("window.location.reload"); 16 | jest.spyOn(locationMock, "replace").mockName("window.location.replace"); 17 | 18 | // Add the property to the Window 19 | // - Only some JSDOM versions support `delete` and `set`, so we use `Object.defineProperty` 20 | Object.defineProperty( 21 | window, 22 | "location", 23 | { 24 | value: locationMock, 25 | configurable: true, 26 | enumerable: true, 27 | writable: true, // Variance from spec, needed for some reason? 28 | }, 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // Side effects 2 | import "./extend-expect"; 3 | import "./setup-hooks"; 4 | 5 | 6 | // Re-exports for additional configuration 7 | export * from "./utils"; 8 | export * from "./hooks"; 9 | // eslint-disable-next-line import/export 10 | export * from "./matchers"; 11 | -------------------------------------------------------------------------------- /src/matchers/__tests__/to-be-at.test.ts: -------------------------------------------------------------------------------- 1 | import {URLS_DO_NOT_MATCH} from "../messages"; 2 | 3 | 4 | describe("assigning", () => { 5 | it("should correctly handle assigning", () => { 6 | window.location.assign("/relative-url"); 7 | expect(window.location).not.toBeAt("/"); 8 | expect(window.location).toBeAt("/relative-url"); 9 | }); 10 | }); 11 | 12 | describe("no actions", () => { 13 | it("should match default path", () => { 14 | expect(window.location).toBeAt("/"); 15 | expect(window.location).not.toBeAt("/relative-url"); 16 | }); 17 | }); 18 | 19 | describe("failures", () => { 20 | it("should fail saying the urls don't match", () => { 21 | expect(() => expect(window.location).toBeAt("/relative-url")).toThrow(URLS_DO_NOT_MATCH); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/matchers/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./to-be-at"; 2 | -------------------------------------------------------------------------------- /src/matchers/messages.ts: -------------------------------------------------------------------------------- 1 | export const URLS_DO_NOT_MATCH = "The received URL doesn't match the expected URL"; 2 | -------------------------------------------------------------------------------- /src/matchers/to-be-at.ts: -------------------------------------------------------------------------------- 1 | import {diffStringsUnified} from "jest-diff"; 2 | import {urlify} from "../utils"; 3 | import {URLS_DO_NOT_MATCH} from "./messages"; 4 | 5 | 6 | export const toBeAt: jest.CustomMatcher = function ( 7 | received: URL, 8 | actual: string | URL, 9 | base?: string | URL, 10 | ) { 11 | const actualURL = urlify(actual, base); 12 | return { 13 | pass: received.href === actualURL.href, 14 | message: () => `${URLS_DO_NOT_MATCH}\n${diffStringsUnified(received.href, actualURL.href)}`, 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /src/setup-hooks.ts: -------------------------------------------------------------------------------- 1 | import {replaceLocation} from "./hooks"; 2 | 3 | 4 | // Setup default hooks configuration 5 | beforeEach(replaceLocation); 6 | -------------------------------------------------------------------------------- /src/utils/__tests__/location-mock-relative.test.ts: -------------------------------------------------------------------------------- 1 | import {LocationMockRelative} from ".."; 2 | 3 | 4 | describe("when inputting a relative url", () => { 5 | it("should be able to assign", () => { 6 | const location = new LocationMockRelative("http://localhost/"); 7 | expect(() => location.assign("/relative-url")).not.toThrow(); 8 | }); 9 | 10 | it("should be able to replace", () => { 11 | const location = new LocationMockRelative("http://localhost/"); 12 | expect(() => location.replace("/relative-url")).not.toThrow(); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/utils/__tests__/urlify.test.ts: -------------------------------------------------------------------------------- 1 | import {urlify} from ".."; 2 | 3 | 4 | it("should make strings url instances", () => { 5 | const url = urlify("http://localhost/"); 6 | expect(url.href).toBe("http://localhost/"); 7 | }); 8 | 9 | it("should make keep url instances the same", () => { 10 | const url = urlify(new URL("http://localhost/another-url")); 11 | expect(url.href).toBe("http://localhost/another-url"); 12 | }); 13 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./location-mock-relative"; 2 | export * from "./urlify"; 3 | -------------------------------------------------------------------------------- /src/utils/location-mock-relative.ts: -------------------------------------------------------------------------------- 1 | import {LocationMock} from "@jedmao/location"; 2 | 3 | 4 | export class LocationMockRelative extends LocationMock implements Location { 5 | assign (url: string): void { 6 | super.assign(this.makeAbsolute(url)); 7 | } 8 | replace (url: string): void { 9 | super.replace(this.makeAbsolute(url)); 10 | } 11 | private makeAbsolute (url: string) { 12 | return new URL(url, this.origin).href; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/utils/urlify.ts: -------------------------------------------------------------------------------- 1 | export const urlify = (actual: string | URL, base: string | URL = "http://localhost/"): URL => actual instanceof URL ? actual : new URL(actual, base); 2 | -------------------------------------------------------------------------------- /tsconfig-build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "**/*.test.*", 5 | "config/" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "target": "es6", 5 | "lib": [ 6 | "dom", 7 | "esnext" 8 | ], 9 | "strict": true, 10 | "esModuleInterop": true, 11 | "outDir": "lib", 12 | "moduleResolution": "node", 13 | "declaration": true, 14 | }, 15 | "include": [ 16 | "src", 17 | "config", 18 | "jest.d.ts", 19 | ], 20 | "exclude": [ 21 | "node_modules", 22 | "lib", 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /wallaby.js: -------------------------------------------------------------------------------- 1 | module.exports = function () { 2 | return { 3 | autoDetect: true, 4 | hints: { 5 | ignoreCoverageForFile: /ignore file coverage|istanbul ignore file/, 6 | }, 7 | reportConsoleErrorAsError: true, 8 | lowCoverageThreshold: 99, 9 | }; 10 | }; 11 | --------------------------------------------------------------------------------