diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5859c688..96baadc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,3 +36,5 @@ jobs: run: npm run test - name: Build Test Site run: cd test-site; npm run build + - name: Test Test Site + run: cd test-site; npm run test diff --git a/README.md b/README.md index f986a271..267624c6 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ Once the change matures, we recommend moving over to the pre-configured [npm wor To do so, check this repository out into the site's `packages/` directory. Then, run `npm run dev:packages` from the site's root directory: this will watch-build any workspace check-outs and start the dev server, picking up changes automatically. If any apps (such as `frontend-app-instructor-dashboard`) require corresponding changes, you can check them out into the `packages/` directory as siblings to `frontend-base`. See [Local development with workspaces](https://github.com/openedx/frontend-template-site#local-development-with-workspaces) for full setup details. +Checkouts in `packages/` are excluded from an app's Jest crawl, so running the app's test suite there behaves the same as it does against a published `frontend-base`. + ### Continuous integration In addition to running lint and the test suite, Github CI builds the included `test-site` against a packed tarball of `frontend-base`. This verifies that the library still works end-to-end as a real dependency of a consuming site. diff --git a/docs/how_tos/migrate-frontend-app.md b/docs/how_tos/migrate-frontend-app.md index d81bb8da..cf4639ee 100644 --- a/docs/how_tos/migrate-frontend-app.md +++ b/docs/how_tos/migrate-frontend-app.md @@ -403,6 +403,18 @@ module.exports = createConfig('test', { }) ``` +Note that `createConfig` merges with `webpack-merge`, so any array you pass is appended to the base config's array rather than replacing it. To replace one, mutate the result: + +```js +const config = createConfig('test', { /* ... */ }); + +config.modulePathIgnorePatterns = ['/dist/']; + +module.exports = config; +``` + +If all of your tests live under `src/`, consider adding `roots: ['/src']` as well. It narrows the crawl further, which speeds up startup. Be careful: `roots` also filters test discovery, so any suite outside it is skipped silently. Apps that keep tests in a `plugins/` directory or similar should list those directories too. + Jest test suites that test React components that import SVG and other assets (such as PNGs) must add mocks for those filetypes. This can be accomplished by adding module name mappers to jest.config.js. Just make sure they come before the `@src` alias, which must also be added here if you're using it: ```js @@ -1083,6 +1095,8 @@ Add the workspaces field to package.json This tells npm to look in ``packages/`` for local overrides of published packages. The ``packages/`` directory is gitignored (see the `.gitignore` step above), since it contains development-only bind-mounted checkouts. +``createConfig('test')`` excludes ``packages/`` from Jest's crawl for the same reason: a checkout there is a dependency, not part of your app, and Jest would otherwise register its manual mocks and collect its test suites as if they were yours. + Add a turbo.site.json file -------------------------- diff --git a/runtime/__mocks__/universal-cookie.js b/runtime/__mocks__/universal-cookie.js deleted file mode 100644 index c6b3efad..00000000 --- a/runtime/__mocks__/universal-cookie.js +++ /dev/null @@ -1,6 +0,0 @@ -const mockCookiesImplementation = { - get: jest.fn(), - remove: jest.fn(), -}; - -module.exports = () => mockCookiesImplementation; diff --git a/runtime/i18n/lib.test.js b/runtime/i18n/lib.test.js index c62d259c..bdd27269 100644 --- a/runtime/i18n/lib.test.js +++ b/runtime/i18n/lib.test.js @@ -15,8 +15,6 @@ import { import { getSiteConfig, mergeSiteConfig, setSiteConfig } from '../config'; -jest.mock('universal-cookie'); - describe('lib', () => { const defaultSiteConfig = cloneDeep(getSiteConfig()); diff --git a/runtime/jest.config.js b/runtime/jest.config.js index dc221e49..4baa48d7 100644 --- a/runtime/jest.config.js +++ b/runtime/jest.config.js @@ -3,8 +3,8 @@ module.exports = { '/setupTest.js', ], moduleNameMapper: { - '\\.svg$': '/__mocks__/svg.js', - '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/testMocks/svg.js', + '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/testMocks/file.js', '\\.(css|scss)$': require.resolve('identity-obj-proxy'), 'site.config': '/site.config.test.tsx', }, diff --git a/runtime/__mocks__/file.js b/runtime/testMocks/file.js similarity index 100% rename from runtime/__mocks__/file.js rename to runtime/testMocks/file.js diff --git a/runtime/__mocks__/svg.js b/runtime/testMocks/svg.js similarity index 100% rename from runtime/__mocks__/svg.js rename to runtime/testMocks/svg.js diff --git a/shell/__mocks__/universal-cookie.js b/shell/__mocks__/universal-cookie.js deleted file mode 100644 index c6b3efad..00000000 --- a/shell/__mocks__/universal-cookie.js +++ /dev/null @@ -1,6 +0,0 @@ -const mockCookiesImplementation = { - get: jest.fn(), - remove: jest.fn(), -}; - -module.exports = () => mockCookiesImplementation; diff --git a/shell/jest.config.js b/shell/jest.config.js index 20f2b543..4b2dc8f0 100644 --- a/shell/jest.config.js +++ b/shell/jest.config.js @@ -3,8 +3,8 @@ module.exports = { './setupTest.js', ], moduleNameMapper: { - '\\.svg$': '/__mocks__/svg.js', - '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/__mocks__/file.js', + '\\.svg$': '/testMocks/svg.js', + '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/testMocks/file.js', '\\.(css|scss)$': require.resolve('identity-obj-proxy'), 'site.config': '/site.config.test.tsx', }, diff --git a/shell/__mocks__/file.js b/shell/testMocks/file.js similarity index 100% rename from shell/__mocks__/file.js rename to shell/testMocks/file.js diff --git a/shell/__mocks__/svg.js b/shell/testMocks/svg.js similarity index 100% rename from shell/__mocks__/svg.js rename to shell/testMocks/svg.js diff --git a/test-site/babel.config.js b/test-site/babel.config.js new file mode 100644 index 00000000..ba714ec4 --- /dev/null +++ b/test-site/babel.config.js @@ -0,0 +1,3 @@ +const { createConfig } = require('@openedx/frontend-base/tools'); + +module.exports = createConfig('babel'); diff --git a/test-site/jest.config.js b/test-site/jest.config.js new file mode 100644 index 00000000..9b9c7bc5 --- /dev/null +++ b/test-site/jest.config.js @@ -0,0 +1,11 @@ +const { createConfig } = require('@openedx/frontend-base/tools'); + +module.exports = createConfig('test', { + setupFilesAfterEnv: [ + '/src/setupTest.js', + ], + moduleNameMapper: { + '\\.svg$': '/src/__mocks__/svg.js', + '\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/src/__mocks__/file.js', + }, +}); diff --git a/test-site/package-lock.json b/test-site/package-lock.json index 073fbf78..100fe8d4 100644 --- a/test-site/package-lock.json +++ b/test-site/package-lock.json @@ -18,9 +18,19 @@ }, "devDependencies": { "@edx/browserslist-config": "^1.5.0", - "@openedx/frontend-dev-utils": "^1.0.0" + "@openedx/frontend-dev-utils": "^1.0.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.3.0", + "@types/jest": "^29.5.14" } }, + "node_modules/@adobe/css-tools": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", @@ -5275,6 +5285,131 @@ "react": "^18 || ^19" } }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@testing-library/dom/node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.3", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.3.tgz", + "integrity": "sha512-Uo193NgQbPMz6lrrhtRQQFcMC6Re/ELLFbbuVL30WDlZxlpZf9/lMHTAVxPRLw1q1iu9OJmR1c2BLiENRstdBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@tokens-studio/sd-transforms": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@tokens-studio/sd-transforms/-/sd-transforms-1.3.0.tgz", @@ -5310,6 +5445,14 @@ "node": ">= 10" } }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -5548,6 +5691,17 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jest": { + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, "node_modules/@types/jsdom": { "version": "20.0.1", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", @@ -8135,6 +8289,13 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -8679,6 +8840,14 @@ "node": ">=0.10.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -11357,6 +11526,16 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -13644,6 +13823,16 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/mini-css-extract-plugin": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz", @@ -16608,6 +16797,20 @@ "node": "*" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reduce-function-call": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz", @@ -18470,6 +18673,19 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", diff --git a/test-site/package.json b/test-site/package.json index 7beb0122..fa3e26f8 100644 --- a/test-site/package.json +++ b/test-site/package.json @@ -8,7 +8,8 @@ "dev": "openedx dev", "dev:autoinstall": "PORT=8080 FRONTEND_BASE_DIR=.. devutils-dev-with-autoinstall", "lint": "openedx lint .", - "serve": "openedx serve" + "serve": "openedx serve", + "test": "openedx test" }, "keywords": [], "author": "Open edX Community", @@ -23,6 +24,9 @@ }, "devDependencies": { "@edx/browserslist-config": "^1.5.0", - "@openedx/frontend-dev-utils": "^1.0.0" + "@openedx/frontend-dev-utils": "^1.0.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.3.0", + "@types/jest": "^29.5.14" } } diff --git a/test-site/site.config.test.tsx b/test-site/site.config.test.tsx new file mode 100644 index 00000000..f49d86f6 --- /dev/null +++ b/test-site/site.config.test.tsx @@ -0,0 +1,19 @@ +import { EnvironmentTypes, SiteConfig } from '@openedx/frontend-base'; + +import { examplePageConfig } from './src'; + +const siteConfig: SiteConfig = { + siteId: 'test', + siteName: 'Test Site', + baseUrl: 'http://localhost:8080', + lmsBaseUrl: 'http://localhost:18000', + loginUrl: 'http://localhost:18000/login', + logoutUrl: 'http://localhost:18000/logout', + + environment: EnvironmentTypes.TEST, + apps: [ + examplePageConfig, + ], +}; + +export default siteConfig; diff --git a/test-site/src/__mocks__/file.js b/test-site/src/__mocks__/file.js new file mode 100644 index 00000000..b7104adf --- /dev/null +++ b/test-site/src/__mocks__/file.js @@ -0,0 +1 @@ +export default 'FileMock'; diff --git a/test-site/src/__mocks__/svg.js b/test-site/src/__mocks__/svg.js new file mode 100644 index 00000000..ee700a08 --- /dev/null +++ b/test-site/src/__mocks__/svg.js @@ -0,0 +1 @@ +export default 'SvgURL'; diff --git a/test-site/src/example-page/Image.test.tsx b/test-site/src/example-page/Image.test.tsx new file mode 100644 index 00000000..d96b6043 --- /dev/null +++ b/test-site/src/example-page/Image.test.tsx @@ -0,0 +1,12 @@ +import { render, screen } from '@testing-library/react'; + +import appleUrl from './apple.svg'; +import Image from './Image'; + +describe('Image', () => { + it('renders with the asset url supplied by the svg mock', () => { + render(An apple); + + expect(screen.getByAltText('An apple')).toHaveAttribute('src', 'SvgURL'); + }); +}); diff --git a/test-site/src/setupTest.js b/test-site/src/setupTest.js new file mode 100644 index 00000000..3b487449 --- /dev/null +++ b/test-site/src/setupTest.js @@ -0,0 +1,6 @@ +import '@testing-library/jest-dom'; + +import siteConfig from 'site.config'; +import { mergeSiteConfig } from '@openedx/frontend-base'; + +mergeSiteConfig(siteConfig); diff --git a/test-site/src/siteConfig.test.ts b/test-site/src/siteConfig.test.ts new file mode 100644 index 00000000..de89a692 --- /dev/null +++ b/test-site/src/siteConfig.test.ts @@ -0,0 +1,10 @@ +import { getSiteConfig } from '@openedx/frontend-base'; + +describe('site config', () => { + it('is merged from site.config.test.tsx before the suite runs', () => { + const siteConfig = getSiteConfig(); + + expect(siteConfig.siteId).toBe('test'); + expect(siteConfig.apps).toHaveLength(1); + }); +}); diff --git a/test-site/tsconfig.json b/test-site/tsconfig.json index 7d6ea2fa..8687ab27 100644 --- a/test-site/tsconfig.json +++ b/test-site/tsconfig.json @@ -5,6 +5,7 @@ "outDir": "dist" }, "include": [ + "babel.config.js", "eslint.config.js", "jest.config.js", "site.config.*.tsx", diff --git a/tools/config-helpers/createConfig.test.ts b/tools/config-helpers/createConfig.test.ts new file mode 100644 index 00000000..8a0d906f --- /dev/null +++ b/tools/config-helpers/createConfig.test.ts @@ -0,0 +1,26 @@ +import { ConfigTypes } from '../types'; +import createConfig from './createConfig'; + +describe('createConfig', () => { + describe('test config', () => { + it('excludes the packages directory from the module and test path crawls', () => { + const config = createConfig(ConfigTypes.TEST); + + expect(config.modulePathIgnorePatterns).toContain('/packages/'); + expect(config.testPathIgnorePatterns).toContain('/packages/'); + }); + + it('appends to the base arrays rather than replacing them', () => { + const config = createConfig(ConfigTypes.TEST, { + testPathIgnorePatterns: [ + '/src/setupTest.js', + ], + }); + + expect(config.testPathIgnorePatterns).toEqual([ + ...createConfig(ConfigTypes.TEST).testPathIgnorePatterns, + '/src/setupTest.js', + ]); + }); + }); +}); diff --git a/tools/eslint/base.eslint.config.js b/tools/eslint/base.eslint.config.js index 24214a06..b6d65fe7 100644 --- a/tools/eslint/base.eslint.config.js +++ b/tools/eslint/base.eslint.config.js @@ -22,6 +22,7 @@ module.exports = tseslint.config( 'dist/*', 'node_modules/*', '**/__mocks__/*', + '**/testMocks/*', '**/__snapshots__/*', ], }, diff --git a/tools/jest/jest.config.js b/tools/jest/jest.config.js index 017f4243..aae155ee 100644 --- a/tools/jest/jest.config.js +++ b/tools/jest/jest.config.js @@ -19,12 +19,20 @@ module.exports = { transformIgnorePatterns: [ '/node_modules/(?!(@openedx|@edx|react-intl|@formatjs|intl-messageformat)/)', ], + /* + * 'packages/' holds gitignored, bind-mounted checkouts used for local + * development. Excluding it here keeps jest-haste-map from crawling those + * checkouts, which would otherwise register their manual mocks and collect + * their test suites as if they belonged to this app. + */ modulePathIgnorePatterns: [ '/dist/', + '/packages/', ], testPathIgnorePatterns: [ '/site.config.test.tsx', '/node_modules/', '/dist/', + '/packages/', ], }; diff --git a/tsconfig.build.json b/tsconfig.build.json index 4bf171fb..9abcce48 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -21,7 +21,8 @@ "**/*.test.jsx", "**/*.test.ts", "**/*.test.tsx", - "**/__mocks__/**/*" + "**/__mocks__/**/*", + "**/testMocks/**/*" ], "references": [ { "path": "./tools/tsconfig.build.json" }