diff --git a/packages/@lwc/jest-preset/README.md b/packages/@lwc/jest-preset/README.md index 6d2bf2a0..32c8c68a 100644 --- a/packages/@lwc/jest-preset/README.md +++ b/packages/@lwc/jest-preset/README.md @@ -14,23 +14,23 @@ yarn add --dev @lwc/jest-preset @lwc/compiler @lwc/engine-dom @lwc/synthetic-sha Add the preset to your `jest.config.js` like so: - ```json - { - "jest": { - "preset": "@lwc/jest-preset" - } - } - ``` +```json +{ + "jest": { + "preset": "@lwc/jest-preset" + } +} +``` Then, update the `moduleNameMapper` entry in `jest.config.js` to point to where your LWC components live. For example, use the following to map all components in the `example` and `other` namespaces: - ```json - { - "moduleNameMapper": { - "^(example|other)/(.+)$": "/src/test/modules/$1/$2/$2" - } - } - ``` +```json +{ + "moduleNameMapper": { + "^(example|other)/(.+)$": "/src/test/modules/$1/$2/$2" + } +} +``` #### nativeShadow @@ -42,7 +42,7 @@ By default, this preset is configured to run the tests with synthetic shadow DOM "lwc-jest": { "nativeShadow": true } - }, + } } ``` diff --git a/packages/@lwc/jest-preset/src/setup.js b/packages/@lwc/jest-preset/src/setup.js index 5f0be3b9..dcfd9c59 100644 --- a/packages/@lwc/jest-preset/src/setup.js +++ b/packages/@lwc/jest-preset/src/setup.js @@ -1,5 +1,5 @@ -const config = global['lwc-jest'] || {} -const { nativeShadow } = config +const config = global['lwc-jest'] || {}; +const { nativeShadow } = config; if (!nativeShadow) { require('@lwc/synthetic-shadow/dist/synthetic-shadow.js'); diff --git a/packages/@lwc/jest-transformer/src/index.js b/packages/@lwc/jest-transformer/src/index.js index 376db9a4..8b57a610 100644 --- a/packages/@lwc/jest-transformer/src/index.js +++ b/packages/@lwc/jest-transformer/src/index.js @@ -113,7 +113,7 @@ module.exports = { getCacheKey(sourceText, sourcePath, ...rest) { let configString; let transformConfig; - + if (rest.length === 1) { // Handle jest@27 arguments // type getCacheKey = (sourceText: string, sourcePath: string, options: { configString: string }) => string; diff --git a/packages/@lwc/jest-transformer/src/transforms/__tests__/site-scoped-import.test.js b/packages/@lwc/jest-transformer/src/transforms/__tests__/site-scoped-import.test.js index 4e31d9b8..309363fc 100644 --- a/packages/@lwc/jest-transformer/src/transforms/__tests__/site-scoped-import.test.js +++ b/packages/@lwc/jest-transformer/src/transforms/__tests__/site-scoped-import.test.js @@ -42,4 +42,100 @@ describe('@salesforce/site/Id import', () => { } ` ); + + test( + 'throws error if using named import', + ` + import { id } from '@salesforce/site/Id'; + `, + undefined, + 'Invalid import from @salesforce/site/Id' + ); + + test( + 'throws error if renamed default imports', + ` + import { default as id } from '@salesforce/site/Id'; + `, + undefined, + 'Invalid import from @salesforce/site/Id' + ); + + test( + 'throws error if renamed multiple default imports', + ` + import { default as id, foo } from '@salesforce/site/Id'; + `, + undefined, + 'Invalid import from @salesforce/site/Id' + ); +}); + +describe('@salesforce/site/activeLanguages import', () => { + test( + 'does default transformation', + ` + import activeLanguages from '@salesforce/site/activeLanguages'; +`, + ` + let activeLanguages; + + try { + activeLanguages = require("@salesforce/site/activeLanguages").default; + } catch (e) { + activeLanguages = [{ + code: 'en-US', + label: 'English (US)' + }]; + } +` + ); + + test( + 'allows non-@salesforce/site/activeLanguages named imports', + ` + import { otherNamed } from './something-valid'; + import activeLanguages from '@salesforce/site/activeLanguages'; +`, + ` + import { otherNamed } from './something-valid'; + let activeLanguages; + + try { + activeLanguages = require("@salesforce/site/activeLanguages").default; + } catch (e) { + activeLanguages = [{ + code: 'en-US', + label: 'English (US)' + }]; + } +` + ); + + test( + 'throws error if using named import', + ` + import { activeLanguages } from '@salesforce/site/activeLanguages'; +`, + undefined, + 'Invalid import from @salesforce/site/activeLanguages' + ); + + test( + 'throws error if renamed default imports', + ` + import { default as activeLanguages } from '@salesforce/site/activeLanguages'; +`, + undefined, + 'Invalid import from @salesforce/site/activeLanguages' + ); + + test( + 'throws error if renamed multiple default imports', + ` + import { default as activeLanguages, foo } from '@salesforce/site/activeLanguages'; +`, + undefined, + 'Invalid import from @salesforce/site/activeLanguages' + ); }); diff --git a/packages/@lwc/jest-transformer/src/transforms/site-scoped-import.js b/packages/@lwc/jest-transformer/src/transforms/site-scoped-import.js index ec74aa67..32747ffa 100644 --- a/packages/@lwc/jest-transformer/src/transforms/site-scoped-import.js +++ b/packages/@lwc/jest-transformer/src/transforms/site-scoped-import.js @@ -4,25 +4,55 @@ * SPDX-License-Identifier: MIT * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ -const { stringScopedImportTransform } = require('./utils'); +const babelTemplate = require('@babel/template').default; +const { getImportInfo, stringScopedImportTransform } = require('./utils'); -/* - * We use the full path to `Id` instead of `@salesforce/site` like other transforms - * because only retrieving the id is currently supported. This will need to be updated - * if more properties are exposed. - */ -const SITE_ID_IMPORT_IDENTIFIER = '@salesforce/site/Id'; +const SITE_ID_IMPORT_IDENTIFIER = '@salesforce/site/'; const DEFAULT_ID = '005000000000000000'; +const siteActiveLanguagesTemplate = babelTemplate(` + let RESOURCE_NAME; + try { + RESOURCE_NAME = require(IMPORT_SOURCE).default; + } catch (e) { + RESOURCE_NAME = [{ code: 'en-US', label: 'English (US)' }]; + } +`); + +function siteActiveLanguagesScopedImportTransform(t, path) { + const { importSource, resourceNames } = getImportInfo(path); + const defaultImport = resourceNames[0]; + + path.replaceWithMultiple( + siteActiveLanguagesTemplate({ + RESOURCE_NAME: t.identifier(defaultImport), + IMPORT_SOURCE: t.stringLiteral(importSource), + }) + ); +} + module.exports = function ({ types: t }) { return { visitor: { ImportDeclaration(path) { - if (path.get('source.value').node.startsWith(SITE_ID_IMPORT_IDENTIFIER)) { - stringScopedImportTransform(t, path, SITE_ID_IMPORT_IDENTIFIER, DEFAULT_ID); + const importId = path.get('source.value').node; + if (importId.startsWith(SITE_ID_IMPORT_IDENTIFIER)) { + siteScopedImportTransform(t, path, importId); } }, }, }; }; + +function siteScopedImportTransform(t, path, importId) { + importId = importId.substring(SITE_ID_IMPORT_IDENTIFIER.length); + switch (importId) { + case 'activeLanguages': + siteActiveLanguagesScopedImportTransform(t, path); + break; + case 'Id': + stringScopedImportTransform(t, path, importId, DEFAULT_ID); + break; + } +} diff --git a/test/src/modules/smoke/shadow/__tests__/shadow.spec.js b/test/src/modules/smoke/shadow/__tests__/shadow.spec.js index 89089f4d..c8ca25dd 100644 --- a/test/src/modules/smoke/shadow/__tests__/shadow.spec.js +++ b/test/src/modules/smoke/shadow/__tests__/shadow.spec.js @@ -10,12 +10,17 @@ describe('shadow DOM', () => { if (global['lwc-jest'].nativeShadow) { it('should be using native shadow DOM', () => { // sniff for JSOM's ShadowRoot implementation - expect(ShadowRoot.prototype.constructor.toString()).not.toContain('function SyntheticShadowRoot'); + expect(ShadowRoot.prototype.constructor.toString()).not.toContain( + 'function SyntheticShadowRoot' + ); }); - } else { // synthetic shadow + } else { + // synthetic shadow it('should be using synthetic shadow DOM', () => { // sniff for @lwc/synthetic shadow - expect(ShadowRoot.prototype.constructor.toString()).toContain('function SyntheticShadowRoot'); + expect(ShadowRoot.prototype.constructor.toString()).toContain( + 'function SyntheticShadowRoot' + ); }); } -}) +});