diff --git a/__mocks__/css/mock-theme-dark-components.js b/__mocks__/css/mock-theme-dark-components.js deleted file mode 100644 index c5560b1294..0000000000 --- a/__mocks__/css/mock-theme-dark-components.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'mock-theme-dark-components'; diff --git a/__mocks__/css/mock-theme-dark-palette.js b/__mocks__/css/mock-theme-dark-palette.js deleted file mode 100644 index 21854c8c09..0000000000 --- a/__mocks__/css/mock-theme-dark-palette.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'mock-theme-dark-palette'; diff --git a/__mocks__/css/mock-theme-dark-semantic-editor.js b/__mocks__/css/mock-theme-dark-semantic-editor.js deleted file mode 100644 index 48ec449051..0000000000 --- a/__mocks__/css/mock-theme-dark-semantic-editor.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'mock-theme-dark-semantic-editor'; diff --git a/__mocks__/css/mock-theme-dark-semantic-grid.js b/__mocks__/css/mock-theme-dark-semantic-grid.js deleted file mode 100644 index a0cf67fa6d..0000000000 --- a/__mocks__/css/mock-theme-dark-semantic-grid.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'mock-theme-dark-semantic-grid'; diff --git a/__mocks__/css/mock-theme-dark-semantic.js b/__mocks__/css/mock-theme-dark-semantic.js deleted file mode 100644 index 1d252429d9..0000000000 --- a/__mocks__/css/mock-theme-dark-semantic.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'mock-theme-dark-semantic'; diff --git a/__mocks__/css/mock-theme-light-palette.js b/__mocks__/css/mock-theme-light-palette.js deleted file mode 100644 index e664d94101..0000000000 --- a/__mocks__/css/mock-theme-light-palette.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'mock-theme-light-palette'; diff --git a/__mocks__/css/mock-theme-spectrum-alias.module.js b/__mocks__/css/mock-theme-spectrum-alias.module.js deleted file mode 100644 index e1b3cb449c..0000000000 --- a/__mocks__/css/mock-theme-spectrum-alias.module.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - 'dh-spectrum-alias': 'mock-dh-spectrum-alias', -}; diff --git a/__mocks__/css/mock-theme-spectrum-overrides.module.js b/__mocks__/css/mock-theme-spectrum-overrides.module.js deleted file mode 100644 index 4788e1aad0..0000000000 --- a/__mocks__/css/mock-theme-spectrum-overrides.module.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - 'dh-spectrum-overrides': 'mock-dh-spectrum-overrides', -}; diff --git a/__mocks__/css/mock-theme-spectrum-palette.module.js b/__mocks__/css/mock-theme-spectrum-palette.module.js deleted file mode 100644 index 0ad7ec6ec2..0000000000 --- a/__mocks__/css/mock-theme-spectrum-palette.module.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - 'dh-spectrum-palette': 'mock-dh-spectrum-palette', -}; diff --git a/jest.config.base.cjs b/jest.config.base.cjs index 69d343c882..b7c6bfff68 100644 --- a/jest.config.base.cjs +++ b/jest.config.base.cjs @@ -2,22 +2,20 @@ const path = require('path'); module.exports = { transform: { - '.(ts|tsx|js|jsx)': ['babel-jest', { rootMode: 'upward' }], + '.(ts|tsx|js|jsx)': [ + 'babel-jest', + { + rootMode: 'upward', + plugins: ['@deephaven/babel-preset/mockCssImportPlugin'], + }, + ], }, // Makes jest transform monaco, but continue ignoring other node_modules. Used for MonacoUtils test transformIgnorePatterns: [ 'node_modules/(?!(monaco-editor|d3-interpolate|d3-color)/)', ], moduleNameMapper: { - 'theme-([^/]+?)\\.css(\\?(?:inline|raw))?$': path.join( - __dirname, - './__mocks__/css/mock-theme-$1.js' - ), '\\.(css|less|scss|sass)$': 'identity-obj-proxy', - '\\.(css|less|scss|sass)\\?(?:inline|raw)$': path.join( - __dirname, - './__mocks__/fileMock.js' - ), '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': path.join(__dirname, './__mocks__/fileMock.js'), '^fira$': 'identity-obj-proxy', diff --git a/packages/babel-preset/mockCssImportPlugin.js b/packages/babel-preset/mockCssImportPlugin.js new file mode 100644 index 0000000000..06ecb68ff5 --- /dev/null +++ b/packages/babel-preset/mockCssImportPlugin.js @@ -0,0 +1,74 @@ +const CSS_INLINE_IMPORT_REGEX = /\.s?css\?(inline|raw)$/; +const CSS_MODULE_IMPORT_REGEX = /([^/]+)\.module\.s?css/; + +/** + * Babel transform plugin to mock CSS imports for unit testing purposes. This + * can be passed to `babel-jest` transform as a plugin. + * + * e.g. + * + * transform: { + * '.(ts|tsx|js|jsx)': [ + * 'babel-jest', + * { + * plugins: [ + * '@deephaven/babel-preset/mockCssImportPlugin', + * ], + * }, + * ], + * }, + */ +module.exports = function mockCssImportPlugin({ types: t }) { + return { + name: 'transform-mock-css-import', + visitor: { + /** Match import declarations */ + ImportDeclaration(path) { + const { node } = path; + + const [, moduleName] = + CSS_MODULE_IMPORT_REGEX.exec(node.source.value) || []; + + // Replace CSS module import with a const object declaration. Object + // will have single key / value derived from the module name. + // e.g. + // import saturn from './saturn.module.css'; + // becomes + // const styles = { 'saturn': 'saturn' }; + if (moduleName) { + const { name } = node.specifiers[0].local; + + path.replaceWith( + t.variableDeclaration('const', [ + t.variableDeclarator( + t.identifier(name), + t.objectExpression([ + t.objectProperty( + t.identifier(`'${moduleName}'`), + t.stringLiteral(moduleName) + ), + ]) + ), + ]) + ); + } + // Replace (s)css imports that have ?inline or ?raw query strings with a + // const variable declaration. + // e.g. + // import './saturn.css?inline'; + // becomes + // const saturn = './saturn.css?inline'; + else if (CSS_INLINE_IMPORT_REGEX.test(node.source.value)) { + const { name } = node.specifiers[0].local; + const { value } = node.source; + + path.replaceWith( + t.variableDeclaration('const', [ + t.variableDeclarator(t.identifier(name), t.stringLiteral(value)), + ]) + ); + } + }, + }, + }; +}; diff --git a/packages/babel-preset/package.json b/packages/babel-preset/package.json index a403440d7a..8414f50ee7 100644 --- a/packages/babel-preset/package.json +++ b/packages/babel-preset/package.json @@ -10,6 +10,10 @@ "author": "Deephaven Data Labs LLC", "license": "Apache-2.0", "main": "./index.js", + "exports": { + ".": "./index.js", + "./mockCssImportPlugin": "./mockCssImportPlugin.js" + }, "dependencies": { "@babel/core": "^7.20.0", "@babel/plugin-proposal-class-properties": "^7.18.0", diff --git a/packages/components/src/__snapshots__/SpectrumUtils.test.ts.snap b/packages/components/src/__snapshots__/SpectrumUtils.test.ts.snap index f5973cdacc..738e8e4ced 100644 --- a/packages/components/src/__snapshots__/SpectrumUtils.test.ts.snap +++ b/packages/components/src/__snapshots__/SpectrumUtils.test.ts.snap @@ -3,10 +3,10 @@ exports[`themeDHDefault should merge Spectrum default with DH custom styles 1`] = ` { "dark": { - "dh-spectrum-alias": "mock-dh-spectrum-alias", - "dh-spectrum-overrides": "mock-dh-spectrum-overrides", - "dh-spectrum-palette": "mock-dh-spectrum-palette", "spectrum--darkest": "spectrum--darkest_256eeb", + "theme-spectrum-alias": "theme-spectrum-alias", + "theme-spectrum-overrides": "theme-spectrum-overrides", + "theme-spectrum-palette": "theme-spectrum-palette", }, "global": { "spectrum": "spectrum_9e130c", @@ -21,10 +21,10 @@ exports[`themeDHDefault should merge Spectrum default with DH custom styles 1`] "spectrum--large": "spectrum--large_c40598", }, "light": { - "dh-spectrum-alias": "mock-dh-spectrum-alias", - "dh-spectrum-overrides": "mock-dh-spectrum-overrides", - "dh-spectrum-palette": "mock-dh-spectrum-palette", "spectrum--light": "spectrum--light_a40724", + "theme-spectrum-alias": "theme-spectrum-alias", + "theme-spectrum-overrides": "theme-spectrum-overrides", + "theme-spectrum-palette": "theme-spectrum-palette", }, "medium": { "spectrum--medium": "spectrum--medium_4b172c", diff --git a/packages/components/src/theme/ThemeUtils.test.ts b/packages/components/src/theme/ThemeUtils.test.ts index bf53d632d8..b0656a1dde 100644 --- a/packages/components/src/theme/ThemeUtils.test.ts +++ b/packages/components/src/theme/ThemeUtils.test.ts @@ -192,17 +192,17 @@ describe('getDefaultBaseThemes', () => { name: 'Default Dark', themeKey: 'default-dark', styleContent: [ - 'mock-theme-dark-palette', - 'mock-theme-dark-semantic', - 'mock-theme-dark-semantic-editor', - 'mock-theme-dark-semantic-grid', - 'mock-theme-dark-components', + './theme-dark-palette.css?raw', + './theme-dark-semantic.css?raw', + './theme-dark-semantic-editor.css?raw', + './theme-dark-semantic-grid.css?raw', + './theme-dark-components.css?raw', ].join('\n'), }, { name: 'Default Light', themeKey: 'default-light', - styleContent: 'mock-theme-light-palette', + styleContent: './theme-light-palette.css?raw', }, ]); }); diff --git a/packages/components/src/theme/__snapshots__/ThemeProvider.test.tsx.snap b/packages/components/src/theme/__snapshots__/ThemeProvider.test.tsx.snap index 30808714c6..274a256866 100644 --- a/packages/components/src/theme/__snapshots__/ThemeProvider.test.tsx.snap +++ b/packages/components/src/theme/__snapshots__/ThemeProvider.test.tsx.snap @@ -6,10 +6,10 @@ exports[`ThemeProvider setSelectedThemeKey: [ [Object] ] should change selected
- mock-theme-dark-palette -mock-theme-dark-semantic -mock-theme-dark-semantic-editor -mock-theme-dark-semantic-grid -mock-theme-dark-components + ./theme-dark-palette.css?raw +./theme-dark-semantic.css?raw +./theme-dark-semantic-editor.css?raw +./theme-dark-semantic-grid.css?raw +./theme-dark-components.css?raw