@corva/create-app 0.123.0 → 0.125.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/common/ui/config/vite/corva-vite-config.mjs +551 -0
- package/common/ui/devApp.js +1 -0
- package/common/ui/index.html +17 -0
- package/common/ui/isolatedApp.js +1 -0
- package/common/ui/public/DevCenterIsolatedAppPage.html +26 -0
- package/common/ui/public/favicon.ico +0 -0
- package/common/ui/vite.config.mjs +4 -0
- package/common/ui/vitest.global-setup.js +4 -0
- package/common/ui/vitest.setup.js +26 -0
- package/lib/commands/create.js +4 -0
- package/lib/constants/package.js +26 -57
- package/lib/flows/steps/zip-file-list-resolve.js +9 -0
- package/lib/helpers/utils.js +2 -2
- package/package.json +1 -1
- package/template_extensions/corva/.eslintrc +4 -0
- package/template_extensions/corva/.github/workflows/feat-fix.yml +1 -0
- package/templates/ui/javascript/.eslintrc +7 -2
- package/templates/ui/javascript/AGENTS.md +13 -11
- package/templates/ui/javascript/src/{App.completion.js → App.completion.jsx} +3 -3
- package/templates/ui/javascript/src/{App.drilling.js → App.drilling.jsx} +3 -3
- package/templates/ui/javascript/src/{AppSettings.js → AppSettings.jsx} +1 -1
- package/templates/ui/javascript/src/__tests__/{AppSettings.test.js → AppSettings.test.jsx} +1 -1
- package/templates/ui/typescript/.eslintrc +4 -0
- package/templates/ui/typescript/AGENTS.md +11 -8
- package/templates/ui/typescript/src/App.completion.tsx +1 -1
- package/templates/ui/typescript/src/App.drilling.tsx +1 -1
- package/templates/ui/typescript/src/__tests__/AppSettings.test.tsx +1 -1
- package/templates/ui/typescript/tsconfig.json +17 -4
- package/templates/ui/javascript/config/jest/babelTransform.js +0 -16
- package/templates/ui/javascript/config/jest/cssTransform.js +0 -16
- package/templates/ui/javascript/config/jest/fileTransform.js +0 -48
- package/templates/ui/javascript/config/jest/globalSetup.js +0 -5
- package/templates/ui/javascript/config/jest/setupTests.js +0 -33
- package/templates/ui/javascript/config-overrides.js +0 -10
- package/templates/ui/typescript/config/jest/babelTransform.js +0 -16
- package/templates/ui/typescript/config/jest/cssTransform.js +0 -16
- package/templates/ui/typescript/config/jest/fileTransform.js +0 -48
- package/templates/ui/typescript/config/jest/globalSetup.js +0 -5
- package/templates/ui/typescript/config/jest/setupTests.js +0 -33
- package/templates/ui/typescript/config-overrides.js +0 -10
- /package/templates/ui/javascript/src/{App.scss → App.module.scss} +0 -0
- /package/templates/ui/javascript/src/__tests__/{App.test.js → App.test.jsx} +0 -0
- /package/templates/ui/javascript/src/__tests__/{TestsExample.test.js → TestsExample.test.jsx} +0 -0
- /package/templates/ui/typescript/src/{App.scss → App.module.scss} +0 -0
package/lib/constants/package.js
CHANGED
|
@@ -23,33 +23,38 @@ const uiDependencies = {
|
|
|
23
23
|
const jsUiDevDependencies = {
|
|
24
24
|
'@corva/dc-platform-shared': 'latest',
|
|
25
25
|
'@corva/eslint-config-browser': '0.2.2',
|
|
26
|
-
|
|
27
|
-
'@testing-library/
|
|
28
|
-
'@testing-library/
|
|
29
|
-
'
|
|
30
|
-
'
|
|
26
|
+
// @testing-library/react 16 moved this from a dependency to a peer
|
|
27
|
+
'@testing-library/dom': '10.4.1',
|
|
28
|
+
'@testing-library/jest-dom': '7.0.1',
|
|
29
|
+
'@testing-library/react': '16.3.2',
|
|
30
|
+
'@testing-library/user-event': '14.6.6',
|
|
31
|
+
'@vitejs/plugin-react': '6.1.1',
|
|
32
|
+
'@vitest/coverage-v8': '4.1.11',
|
|
33
|
+
'dotenv': '16.4.7',
|
|
34
|
+
'dotenv-expand': '11.0.7',
|
|
31
35
|
'eslint': '7.32.0',
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'
|
|
36
|
+
'jsdom': '22.1.0',
|
|
37
|
+
'postcss-preset-env': '11.3.0',
|
|
38
|
+
'rollup-plugin-license': '3.6.0',
|
|
39
|
+
'sass-embedded': '1.100.0',
|
|
40
|
+
'terser': '5.47.1',
|
|
41
|
+
'vite': '8.3.0',
|
|
42
|
+
'vite-plugin-static-copy': '4.1.0',
|
|
43
|
+
'vitest': '4.1.11',
|
|
35
44
|
};
|
|
36
45
|
|
|
37
46
|
const tsUiDevDependencies = {
|
|
38
47
|
...jsUiDevDependencies,
|
|
39
|
-
'@
|
|
40
|
-
// 4.17.7+ uses `infer X extends`, unparsable by this template's typescript 4.6.3
|
|
41
|
-
'@types/lodash': '4.17.5',
|
|
48
|
+
'@types/lodash': '^4.17.25',
|
|
42
49
|
'@types/material-ui': '0.21.9',
|
|
43
50
|
'@types/minimatch': '3.0.5',
|
|
44
51
|
'@types/mime': '3.0.1',
|
|
45
|
-
'@types/node': '
|
|
52
|
+
'@types/node': '24.12.2',
|
|
46
53
|
'@types/react': '18.2.42',
|
|
47
54
|
'@types/react-dom': '^18.2',
|
|
48
|
-
'@types/jest': '^27.0.1',
|
|
49
55
|
'@typescript-eslint/eslint-plugin': '^4.31.2',
|
|
50
56
|
'@typescript-eslint/parser': '^4.31.2',
|
|
51
|
-
'
|
|
52
|
-
'typescript': '4.6.3',
|
|
57
|
+
'typescript': '^5.9.3',
|
|
53
58
|
};
|
|
54
59
|
|
|
55
60
|
const corvaUiExtension = {
|
|
@@ -87,13 +92,13 @@ function applyUiExtension(packageJson, extensionNames) {
|
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
const uiScripts = {
|
|
90
|
-
build: '
|
|
91
|
-
start: '
|
|
95
|
+
build: 'vite build',
|
|
96
|
+
start: 'vite --open',
|
|
92
97
|
zip: 'create-corva-app zip .',
|
|
93
|
-
lint: 'eslint --cache ./src/',
|
|
98
|
+
lint: 'eslint --cache --ext .js,.jsx,.ts,.tsx ./src/',
|
|
94
99
|
release: 'create-corva-app release .',
|
|
95
|
-
test: '
|
|
96
|
-
coverage: '
|
|
100
|
+
test: 'vitest run',
|
|
101
|
+
coverage: 'vitest run --coverage',
|
|
97
102
|
};
|
|
98
103
|
|
|
99
104
|
const uiPackage = {
|
|
@@ -102,43 +107,6 @@ const uiPackage = {
|
|
|
102
107
|
'scripts': uiScripts,
|
|
103
108
|
'dependencies': uiDependencies,
|
|
104
109
|
'devDependencies': jsUiDevDependencies,
|
|
105
|
-
'jest': {
|
|
106
|
-
roots: ['<rootDir>/src'],
|
|
107
|
-
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts'],
|
|
108
|
-
coverageThreshold: {
|
|
109
|
-
global: {
|
|
110
|
-
branches: 60,
|
|
111
|
-
functions: 60,
|
|
112
|
-
lines: 60,
|
|
113
|
-
statements: 60,
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
setupFilesAfterEnv: ['<rootDir>/config/jest/setupTests.js'],
|
|
117
|
-
globalSetup: '<rootDir>/config/jest/globalSetup.js',
|
|
118
|
-
testMatch: ['<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}', '<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}'],
|
|
119
|
-
testEnvironment: 'jsdom',
|
|
120
|
-
transform: {
|
|
121
|
-
'^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': '<rootDir>/config/jest/babelTransform.js',
|
|
122
|
-
'^.+\\.css$': '<rootDir>/config/jest/cssTransform.js',
|
|
123
|
-
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': '<rootDir>/config/jest/fileTransform.js',
|
|
124
|
-
},
|
|
125
|
-
transformIgnorePatterns: [
|
|
126
|
-
'/node_modules/(?!.*@babel/runtime|@icon-park/react/es).+\\.(js|jsx|mjs|cjs|ts|tsx)$',
|
|
127
|
-
'^.+\\.(css|sass|scss)$',
|
|
128
|
-
],
|
|
129
|
-
modulePaths: [],
|
|
130
|
-
moduleNameMapper: {
|
|
131
|
-
'~(.*)': '<rootDir>/src/$1',
|
|
132
|
-
'^.+\\.(css|sass|scss)$': 'identity-obj-proxy',
|
|
133
|
-
// @corva/ui's ImageViewer imports photoswipe (ESM-only); stub it so app
|
|
134
|
-
// tests can import @corva/ui without a module-resolution/ESM failure.
|
|
135
|
-
'^photoswipe/lightbox$': 'identity-obj-proxy',
|
|
136
|
-
'^photoswipe$': 'identity-obj-proxy',
|
|
137
|
-
'@corva/ui(.*)': '@corva/ui/cjs-bundle/$1',
|
|
138
|
-
},
|
|
139
|
-
watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],
|
|
140
|
-
resetMocks: true,
|
|
141
|
-
},
|
|
142
110
|
'lint-staged': {
|
|
143
111
|
'src/**/*.{js,jsx,ts,tsx}': 'eslint --fix',
|
|
144
112
|
},
|
|
@@ -150,6 +118,7 @@ const uiPackage = {
|
|
|
150
118
|
|
|
151
119
|
const tsUiPackage = {
|
|
152
120
|
...uiPackage,
|
|
121
|
+
scripts: { ...uiScripts, typecheck: 'tsc --noEmit' },
|
|
153
122
|
devDependencies: tsUiDevDependencies,
|
|
154
123
|
// todo: temporary solution, ref https://github.com/oppia/oppia/issues/22283#issuecomment-2756641371
|
|
155
124
|
resolutions: {
|
|
@@ -110,7 +110,15 @@ const resolveDataToZipUiApp = async (itemsToZip = [], { options, pkg, dirName, m
|
|
|
110
110
|
|
|
111
111
|
itemsToZip.push(
|
|
112
112
|
'manifest.json',
|
|
113
|
+
// both build systems are listed: missing entries are filtered out in
|
|
114
|
+
// createZipArchive, so one CLI serves webpack apps and Vite apps alike
|
|
113
115
|
'config-overrides.js',
|
|
116
|
+
'vite.config.mjs',
|
|
117
|
+
'index.html',
|
|
118
|
+
'devApp.js',
|
|
119
|
+
'isolatedApp.js',
|
|
120
|
+
'vitest.setup.js',
|
|
121
|
+
'vitest.global-setup.js',
|
|
114
122
|
'eslint.config.js',
|
|
115
123
|
'eslint.config.mjs',
|
|
116
124
|
'tsconfig.json',
|
|
@@ -125,6 +133,7 @@ const resolveDataToZipUiApp = async (itemsToZip = [], { options, pkg, dirName, m
|
|
|
125
133
|
},
|
|
126
134
|
...(await transformPatternsIntoFileNames(dirName, ['src/**/*'], options.ignoredFiles)),
|
|
127
135
|
...(await transformPatternsIntoFileNames(dirName, ['config/**/*'], options.ignoredFiles)),
|
|
136
|
+
...(await transformPatternsIntoFileNames(dirName, ['public/**/*'], options.ignoredFiles)),
|
|
128
137
|
);
|
|
129
138
|
|
|
130
139
|
if (options.appKey) {
|
package/lib/helpers/utils.js
CHANGED
|
@@ -7,7 +7,7 @@ export const addUiAppFile = (templateFolder, root, runtime, manifest, opts) => {
|
|
|
7
7
|
try {
|
|
8
8
|
logger.log(chalk.green('adding app file'));
|
|
9
9
|
|
|
10
|
-
const fileExtension = runtime.language === 'typescript' ? 'tsx' : '
|
|
10
|
+
const fileExtension = runtime.language === 'typescript' ? 'tsx' : 'jsx';
|
|
11
11
|
|
|
12
12
|
const segment =
|
|
13
13
|
{
|
|
@@ -29,7 +29,7 @@ export const getExcludedFiles = (manifest) => {
|
|
|
29
29
|
const excludedFiles = ['.ruff_cache', '.venv', '.pytest_cache', '__pycache__'];
|
|
30
30
|
|
|
31
31
|
if (manifest.isUi()) {
|
|
32
|
-
return [...excludedFiles, 'App.drilling.
|
|
32
|
+
return [...excludedFiles, 'App.drilling.jsx', 'App.completion.jsx', 'App.drilling.tsx', 'App.completion.tsx'];
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
return excludedFiles;
|
package/package.json
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"root": true,
|
|
3
3
|
"extends": "@corva/eslint-config-browser",
|
|
4
|
+
"overrides": [
|
|
5
|
+
{
|
|
6
|
+
"files": ["**/__tests__/**", "*.{spec,test}.{js,jsx,ts,tsx}"],
|
|
7
|
+
"globals": { "vi": "readonly" }
|
|
8
|
+
}
|
|
9
|
+
],
|
|
4
10
|
"parserOptions": {
|
|
5
11
|
"requireConfigFile": false,
|
|
6
12
|
"babelOptions": {
|
|
7
|
-
"presets": ["@babel/preset-react"]
|
|
8
|
-
"plugins": ["@babel/plugin-proposal-class-properties"]
|
|
13
|
+
"presets": ["@babel/preset-react"]
|
|
9
14
|
}
|
|
10
15
|
}
|
|
11
16
|
}
|
|
@@ -10,22 +10,24 @@ These constraints are enforced by the platform. Violating them breaks the build
|
|
|
10
10
|
1. **Root export** — `src/index.js` MUST default-export `{ component: App, settings: AppSettings }`. The component may also be a `ParentApp` wrapper (e.g., `{ component: ParentApp, settings: AppSettings }`) that wraps `App` with Context.Providers and prop initialization. This is the platform loader contract.
|
|
11
11
|
2. **UI components** — Use only `@corva/ui` components. Import from `@corva/ui/componentsV2`; fall back to `@corva/ui/components` only when a V2 version doesn't exist yet. `@material-ui/core` v4 is available as the underlying library.
|
|
12
12
|
3. **HTTP clients** — Use `corvaDataAPI` / `corvaAPI` from `@corva/ui/clients` for all network requests.
|
|
13
|
-
4. **Do not rename or delete** `App.
|
|
13
|
+
4. **Do not rename or delete** `App.jsx`, `AppSettings.jsx`, or `index.js` — they are platform entry points.
|
|
14
14
|
|
|
15
15
|
## Project Structure
|
|
16
16
|
|
|
17
17
|
```
|
|
18
18
|
src/
|
|
19
|
-
App.
|
|
20
|
-
AppSettings.
|
|
19
|
+
App.jsx — Main app component (default export required)
|
|
20
|
+
AppSettings.jsx — Settings panel component (default export required)
|
|
21
21
|
index.js — Root export: { component, settings }
|
|
22
22
|
constants.js — Default settings values
|
|
23
|
-
App.scss — Component styles
|
|
24
|
-
__tests__/ —
|
|
23
|
+
App.module.scss — Component styles
|
|
24
|
+
__tests__/ — Vitest test files
|
|
25
25
|
__mocks__/ — Mock data (mockAppProps.js, mockAppSettingsProps.js)
|
|
26
26
|
assets/ — Static assets (SVGs, images)
|
|
27
|
-
config/
|
|
28
|
-
config
|
|
27
|
+
config/vite/ — Shared Corva Vite config
|
|
28
|
+
vite.config.mjs — Vite entry config
|
|
29
|
+
vitest.setup.js — Test environment setup
|
|
30
|
+
index.html — Dev server host page
|
|
29
31
|
manifest.json — Corva platform app metadata (generated at scaffold time)
|
|
30
32
|
```
|
|
31
33
|
|
|
@@ -98,7 +100,7 @@ transition: transition(color, background-color);
|
|
|
98
100
|
**Import in component:**
|
|
99
101
|
|
|
100
102
|
```javascript
|
|
101
|
-
import styles from './App.scss';
|
|
103
|
+
import styles from './App.module.scss';
|
|
102
104
|
// Use: <div className={styles.container}>
|
|
103
105
|
```
|
|
104
106
|
|
|
@@ -265,11 +267,11 @@ General rules:
|
|
|
265
267
|
|
|
266
268
|
## Testing
|
|
267
269
|
|
|
268
|
-
- **Framework:**
|
|
270
|
+
- **Framework:** Vitest + React Testing Library
|
|
269
271
|
- **Wrapper:** Use `AppTestWrapper` from `@corva/ui/testing` to wrap components
|
|
270
|
-
- **Mocking:** Mock network requests (
|
|
272
|
+
- **Mocking:** Mock network requests (`vi.mock`/`vi.fn` or msw), never call real APIs
|
|
271
273
|
- **Timezone:** UTC is enforced (`process.env.TZ = 'UTC'`)
|
|
272
|
-
- **Mocked globals:** `ResizeObserver`, `MutationObserver` (in `
|
|
274
|
+
- **Mocked globals:** `ResizeObserver`, `MutationObserver` (in `vitest.setup.js`)
|
|
273
275
|
|
|
274
276
|
## Commands
|
|
275
277
|
|
|
@@ -4,7 +4,7 @@ import { useAppCommons } from '@corva/ui/effects';
|
|
|
4
4
|
import { DEFAULT_SETTINGS } from './constants';
|
|
5
5
|
import logo from './assets/logo.svg';
|
|
6
6
|
|
|
7
|
-
import styles from './App.scss';
|
|
7
|
+
import styles from './App.module.scss';
|
|
8
8
|
|
|
9
9
|
const App = () => {
|
|
10
10
|
const { appKey, fracFleet, well, wells, appSettings } = useAppCommons();
|
|
@@ -19,7 +19,7 @@ const App = () => {
|
|
|
19
19
|
<div className={styles.container}>
|
|
20
20
|
<img src={logo} alt="logo" className={styles.logo} />
|
|
21
21
|
<p>
|
|
22
|
-
Edit <code>src/App.
|
|
22
|
+
Edit <code>src/App.jsx</code> and save to reload.
|
|
23
23
|
<br />
|
|
24
24
|
<br />
|
|
25
25
|
</p>
|
|
@@ -47,6 +47,6 @@ const App = () => {
|
|
|
47
47
|
);
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
// Important: Do not change root component default export (App.
|
|
50
|
+
// Important: Do not change root component default export (App.jsx). Use it as container
|
|
51
51
|
// for your App. It's required to make build and zip scripts work as expected;
|
|
52
52
|
export default App;
|
|
@@ -4,7 +4,7 @@ import { useAppCommons } from '@corva/ui/effects';
|
|
|
4
4
|
import { DEFAULT_SETTINGS } from './constants';
|
|
5
5
|
import logo from './assets/logo.svg';
|
|
6
6
|
|
|
7
|
-
import styles from './App.scss';
|
|
7
|
+
import styles from './App.module.scss';
|
|
8
8
|
|
|
9
9
|
const App = () => {
|
|
10
10
|
const { appKey, rig, well, appSettings } = useAppCommons();
|
|
@@ -16,7 +16,7 @@ const App = () => {
|
|
|
16
16
|
<div className={styles.container}>
|
|
17
17
|
<img src={logo} alt="logo" className={styles.logo} />
|
|
18
18
|
<p>
|
|
19
|
-
Edit <code>src/App.
|
|
19
|
+
Edit <code>src/App.jsx</code> and save to reload.
|
|
20
20
|
<br />
|
|
21
21
|
<br />
|
|
22
22
|
</p>
|
|
@@ -44,6 +44,6 @@ const App = () => {
|
|
|
44
44
|
);
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
// Important: Do not change root component default export (App.
|
|
47
|
+
// Important: Do not change root component default export (App.jsx). Use it as container
|
|
48
48
|
// for your App. It's required to make build and zip scripts work as expected;
|
|
49
49
|
export default App;
|
|
@@ -23,6 +23,6 @@ const AppSettings = () => {
|
|
|
23
23
|
);
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
// Important: Do not change root component default export (AppSettings.
|
|
26
|
+
// Important: Do not change root component default export (AppSettings.jsx). Use it as container
|
|
27
27
|
// for your App Settings. It's required to make build and zip scripts work as expected;
|
|
28
28
|
export default AppSettings;
|
|
@@ -6,7 +6,7 @@ import AppSettings from '../AppSettings';
|
|
|
6
6
|
|
|
7
7
|
describe('<AppSettings />', () => {
|
|
8
8
|
it('should call onChange with a changed setting on settings change', async () => {
|
|
9
|
-
const handleSettingChange =
|
|
9
|
+
const handleSettingChange = vi.fn();
|
|
10
10
|
|
|
11
11
|
render(
|
|
12
12
|
<AppTestWrapper
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
},
|
|
11
11
|
"extends": ["@corva/eslint-config-browser"],
|
|
12
12
|
"overrides": [
|
|
13
|
+
{
|
|
14
|
+
"files": ["**/__tests__/**", "*.{spec,test}.{js,jsx,ts,tsx}"],
|
|
15
|
+
"globals": { "vi": "readonly" }
|
|
16
|
+
},
|
|
13
17
|
{
|
|
14
18
|
"files": ["*.ts", "*.tsx"],
|
|
15
19
|
"extends": ["@corva/eslint-config-browser", "plugin:@typescript-eslint/recommended"],
|
|
@@ -22,12 +22,14 @@ src/
|
|
|
22
22
|
constants.ts — Default settings values
|
|
23
23
|
types.ts — Custom app settings interface
|
|
24
24
|
custom.d.ts — Module declarations for CSS/SVG imports
|
|
25
|
-
App.scss — Component styles (SCSS modules)
|
|
26
|
-
__tests__/ —
|
|
25
|
+
App.module.scss — Component styles (SCSS modules)
|
|
26
|
+
__tests__/ — Vitest test files
|
|
27
27
|
__mocks__/mockData.ts — Mock data for tests
|
|
28
28
|
assets/ — Static assets (SVGs, images)
|
|
29
|
-
config/
|
|
30
|
-
config
|
|
29
|
+
config/vite/ — Shared Corva Vite config
|
|
30
|
+
vite.config.mjs — Vite entry config
|
|
31
|
+
vitest.setup.js — Test environment setup
|
|
32
|
+
index.html — Dev server host page
|
|
31
33
|
tsconfig.json — TypeScript configuration
|
|
32
34
|
manifest.json — Corva platform app metadata (generated at scaffold time)
|
|
33
35
|
```
|
|
@@ -117,7 +119,7 @@ transition: transition(color, background-color);
|
|
|
117
119
|
**Import in component:**
|
|
118
120
|
|
|
119
121
|
```typescript
|
|
120
|
-
import styles from './App.scss';
|
|
122
|
+
import styles from './App.module.scss';
|
|
121
123
|
// Use: <div className={styles.container}>
|
|
122
124
|
```
|
|
123
125
|
|
|
@@ -295,12 +297,12 @@ General rules:
|
|
|
295
297
|
|
|
296
298
|
## Testing
|
|
297
299
|
|
|
298
|
-
- **Framework:**
|
|
300
|
+
- **Framework:** Vitest + React Testing Library
|
|
299
301
|
- **Wrapper:** Use `AppTestWrapper` from `@corva/ui/testing` to wrap components — it provides `useAppCommons()` context
|
|
300
302
|
- **Pattern:** Pass data via `AppTestWrapper` props, render components with no props
|
|
301
|
-
- **Mocking:** Mock network requests (
|
|
303
|
+
- **Mocking:** Mock network requests (`vi.mock`/`vi.fn` or msw), never call real APIs
|
|
302
304
|
- **Timezone:** UTC is enforced (`process.env.TZ = 'UTC'`)
|
|
303
|
-
- **Mocked globals:** `ResizeObserver`, `MutationObserver` (in `
|
|
305
|
+
- **Mocked globals:** `ResizeObserver`, `MutationObserver` (in `vitest.setup.js`)
|
|
304
306
|
|
|
305
307
|
```tsx
|
|
306
308
|
// Test pattern — data flows through AppTestWrapper context
|
|
@@ -318,6 +320,7 @@ yarn start Dev server at http://app.local.corva.ai:8080/
|
|
|
318
320
|
yarn build Production bundle
|
|
319
321
|
yarn test Run tests
|
|
320
322
|
yarn lint ESLint check
|
|
323
|
+
yarn typecheck Type check (the build does not typecheck)
|
|
321
324
|
yarn zip Create deployment ZIP
|
|
322
325
|
yarn release Release to Corva platform
|
|
323
326
|
```
|
|
@@ -4,7 +4,7 @@ import { useAppCommons } from '@corva/ui/effects';
|
|
|
4
4
|
import { DEFAULT_SETTINGS } from './constants';
|
|
5
5
|
import logo from './assets/logo.svg';
|
|
6
6
|
|
|
7
|
-
import styles from './App.scss';
|
|
7
|
+
import styles from './App.module.scss';
|
|
8
8
|
|
|
9
9
|
const App = () => {
|
|
10
10
|
const { appKey, fracFleet, well, wells, appSettings } = useAppCommons();
|
|
@@ -4,7 +4,7 @@ import { useAppCommons } from '@corva/ui/effects';
|
|
|
4
4
|
import { DEFAULT_SETTINGS } from './constants';
|
|
5
5
|
import logo from './assets/logo.svg';
|
|
6
6
|
|
|
7
|
-
import styles from './App.scss';
|
|
7
|
+
import styles from './App.module.scss';
|
|
8
8
|
|
|
9
9
|
const App = () => {
|
|
10
10
|
const { appKey, rig, well, appSettings } = useAppCommons();
|
|
@@ -6,7 +6,7 @@ import AppSettings from '../AppSettings';
|
|
|
6
6
|
|
|
7
7
|
describe('<AppSettings />', () => {
|
|
8
8
|
it('should call onChange with a changed setting on settings change', async () => {
|
|
9
|
-
const handleSettingChange =
|
|
9
|
+
const handleSettingChange = vi.fn();
|
|
10
10
|
|
|
11
11
|
render(
|
|
12
12
|
<AppTestWrapper
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends": "@tsconfig/create-react-app/tsconfig.json",
|
|
3
2
|
"compilerOptions": {
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"types": ["vite/client", "vitest/globals", "@testing-library/jest-dom/vitest"],
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"paths": { "~/*": ["./src/*"] }
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"]
|
|
7
20
|
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
const babelJest = require('babel-jest').default;
|
|
4
|
-
|
|
5
|
-
module.exports = babelJest.createTransformer({
|
|
6
|
-
presets: [
|
|
7
|
-
[
|
|
8
|
-
require.resolve('babel-preset-react-app'),
|
|
9
|
-
{
|
|
10
|
-
runtime: 'automatic',
|
|
11
|
-
},
|
|
12
|
-
],
|
|
13
|
-
],
|
|
14
|
-
babelrc: false,
|
|
15
|
-
configFile: false,
|
|
16
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
// This is a custom Jest transformer turning style imports into empty objects.
|
|
4
|
-
// http://facebook.github.io/jest/docs/en/webpack.html
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
process() {
|
|
8
|
-
return {
|
|
9
|
-
code: 'module.exports = {};',
|
|
10
|
-
};
|
|
11
|
-
},
|
|
12
|
-
getCacheKey() {
|
|
13
|
-
// The output is always the same.
|
|
14
|
-
return 'cssTransform';
|
|
15
|
-
},
|
|
16
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
// This is a custom Jest transformer turning file imports into filenames.
|
|
6
|
-
// http://facebook.github.io/jest/docs/en/webpack.html
|
|
7
|
-
|
|
8
|
-
const toPascalCase = str => {
|
|
9
|
-
const allWordsIterator = str.matchAll(/\w+/g);
|
|
10
|
-
|
|
11
|
-
return Array.from(allWordsIterator).reduce((acc, matchResult) => {
|
|
12
|
-
const word = matchResult[0];
|
|
13
|
-
return acc + word[0].toUpperCase() + word.slice(1).toLowerCase();
|
|
14
|
-
}, '');
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
module.exports = {
|
|
18
|
-
process(src, filename) {
|
|
19
|
-
const assetFilename = JSON.stringify(path.basename(filename));
|
|
20
|
-
|
|
21
|
-
if (filename.match(/\.svg$/)) {
|
|
22
|
-
// Based on how SVGR generates a component name:
|
|
23
|
-
// https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
|
|
24
|
-
const pascalCaseFilename = toPascalCase(path.parse(filename).name);
|
|
25
|
-
const componentName = `Svg${pascalCaseFilename}`;
|
|
26
|
-
return {
|
|
27
|
-
code: `const React = require('react');
|
|
28
|
-
module.exports = {
|
|
29
|
-
__esModule: true,
|
|
30
|
-
default: ${assetFilename},
|
|
31
|
-
ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
|
|
32
|
-
return {
|
|
33
|
-
$$typeof: Symbol.for('react.element'),
|
|
34
|
-
type: 'svg',
|
|
35
|
-
ref: ref,
|
|
36
|
-
key: null,
|
|
37
|
-
props: Object.assign({}, props, {
|
|
38
|
-
children: ${assetFilename}
|
|
39
|
-
})
|
|
40
|
-
};
|
|
41
|
-
}),
|
|
42
|
-
};`,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return { code: `module.exports = ${assetFilename};` };
|
|
47
|
-
},
|
|
48
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
|
4
|
-
// allows you to do things like:
|
|
5
|
-
// expect(element).toHaveTextContent(/react/i)
|
|
6
|
-
// learn more: https://github.com/testing-library/jest-dom
|
|
7
|
-
// eslint-disable-next-line
|
|
8
|
-
import '@testing-library/jest-dom/extend-expect';
|
|
9
|
-
import { TextEncoder, TextDecoder } from 'util';
|
|
10
|
-
|
|
11
|
-
Object.assign(global, { TextDecoder, TextEncoder });
|
|
12
|
-
|
|
13
|
-
// Set UTC timezone for tests to not use the environment timezone
|
|
14
|
-
process.env.TZ = 'UTC';
|
|
15
|
-
|
|
16
|
-
// Mock ResizeObserver & MutationObserver
|
|
17
|
-
class FakeObserver {
|
|
18
|
-
observe() {}
|
|
19
|
-
unobserve() {}
|
|
20
|
-
disconnect() {}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
global.ResizeObserver = FakeObserver;
|
|
24
|
-
global.MutationObserver = FakeObserver;
|
|
25
|
-
|
|
26
|
-
// Suppressing "Could not parse CSS stylesheet" from JSDOM
|
|
27
|
-
const originalConsoleError = global.console.error;
|
|
28
|
-
global.console.error = (message, ...optionalParams) => {
|
|
29
|
-
if (message.includes('Could not parse CSS stylesheet')) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
originalConsoleError(message, ...optionalParams);
|
|
33
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
const { getWebpackConfig } = require('@corva/dc-platform-shared/cjs');
|
|
2
|
-
const { merge } = require('webpack-merge');
|
|
3
|
-
|
|
4
|
-
module.exports = (env, argv) => {
|
|
5
|
-
return merge(
|
|
6
|
-
getWebpackConfig(env, argv),
|
|
7
|
-
// NOTE: Custom webpack 5 plugins and module rules can be provided here
|
|
8
|
-
{}
|
|
9
|
-
);
|
|
10
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
const babelJest = require('babel-jest').default;
|
|
4
|
-
|
|
5
|
-
module.exports = babelJest.createTransformer({
|
|
6
|
-
presets: [
|
|
7
|
-
[
|
|
8
|
-
require.resolve('babel-preset-react-app'),
|
|
9
|
-
{
|
|
10
|
-
runtime: 'automatic',
|
|
11
|
-
},
|
|
12
|
-
],
|
|
13
|
-
],
|
|
14
|
-
babelrc: false,
|
|
15
|
-
configFile: false,
|
|
16
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
// This is a custom Jest transformer turning style imports into empty objects.
|
|
4
|
-
// http://facebook.github.io/jest/docs/en/webpack.html
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
process() {
|
|
8
|
-
return {
|
|
9
|
-
code: 'module.exports = {};',
|
|
10
|
-
};
|
|
11
|
-
},
|
|
12
|
-
getCacheKey() {
|
|
13
|
-
// The output is always the same.
|
|
14
|
-
return 'cssTransform';
|
|
15
|
-
},
|
|
16
|
-
};
|