From 01ce6c3e3c1de722371e1e152586e88de6006f7c Mon Sep 17 00:00:00 2001 From: apapko Date: Fri, 22 Feb 2019 09:07:37 -0800 Subject: [PATCH] feat: add apexContinuation transformer (#1074) --- packages/@lwc/jest-transformer/src/index.js | 2 + .../apex-continuation-scoped-import.test.js | 45 ++++++++++++++++++ .../apex-continuation-scoped-import.js | 46 +++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 packages/@lwc/jest-transformer/src/transforms/__tests__/apex-continuation-scoped-import.test.js create mode 100644 packages/@lwc/jest-transformer/src/transforms/apex-continuation-scoped-import.js diff --git a/packages/@lwc/jest-transformer/src/index.js b/packages/@lwc/jest-transformer/src/index.js index bca3cafc5c..7cadb830b1 100644 --- a/packages/@lwc/jest-transformer/src/index.js +++ b/packages/@lwc/jest-transformer/src/index.js @@ -14,6 +14,7 @@ const engineVersion = require('@lwc/engine/package.json').version; const compilerVersion = require('@lwc/compiler/package.json').version; const { waitForPromise } = require('./utils'); const apexScopedImport = require('./transforms/apex-scoped-import'); +const apexContinuationScopedImport = require('./transforms/apex-continuation-scoped-import'); const i18nScopedImport = require('./transforms/i18n-scoped-import'); const labelScopedImport = require('./transforms/label-scoped-import'); const resourceScopedImport = require('./transforms/resource-scoped-import'); @@ -29,6 +30,7 @@ const BABEL_CONFIG = { "plugins": [ babelCommonJs, apexScopedImport, + apexContinuationScopedImport, i18nScopedImport, labelScopedImport, contentAssetUrlScopedImport, diff --git a/packages/@lwc/jest-transformer/src/transforms/__tests__/apex-continuation-scoped-import.test.js b/packages/@lwc/jest-transformer/src/transforms/__tests__/apex-continuation-scoped-import.test.js new file mode 100644 index 0000000000..7b6d2290dd --- /dev/null +++ b/packages/@lwc/jest-transformer/src/transforms/__tests__/apex-continuation-scoped-import.test.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ +const test = require('./utils/test-transform').test( + require('../apex-continuation-scoped-import') +); + +describe('@salesforce/apexContinuation import', () => { + test('does default transformation', ` + import myMethod from '@salesforce/apexContinuation/FooController.fooMethod'; + `, ` + let myMethod; + + try { + myMethod = require("@salesforce/apexContinuation/FooController.fooMethod").default; + } catch (e) { + global.__lwcJestMock_myMethod = global.__lwcJestMock_myMethod || function () { + return Promise.resolve(); + }; + + myMethod = global.__lwcJestMock_myMethod; + } + `); + + test('allows non-@salesforce/apexContinuation named imports', ` + import { otherNamed } from './something-valid'; + import myMethod from '@salesforce/apexContinuation/FooController.fooMethod'; + `, ` + import { otherNamed } from './something-valid'; + let myMethod; + + try { + myMethod = require("@salesforce/apexContinuation/FooController.fooMethod").default; + } catch (e) { + global.__lwcJestMock_myMethod = global.__lwcJestMock_myMethod || function () { + return Promise.resolve(); + }; + + myMethod = global.__lwcJestMock_myMethod; + } + `); +}); diff --git a/packages/@lwc/jest-transformer/src/transforms/apex-continuation-scoped-import.js b/packages/@lwc/jest-transformer/src/transforms/apex-continuation-scoped-import.js new file mode 100644 index 0000000000..45a841a378 --- /dev/null +++ b/packages/@lwc/jest-transformer/src/transforms/apex-continuation-scoped-import.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ +const babelTemplate = require('@babel/template').default; +const { getImportInfo } = require('./utils'); + +const APEX_CONTINUATION_IMPORT_IDENTIFIER = '@salesforce/apexContinuation'; + +/* + * Apex imports can be used as @wire ids or called directly. If used as a @wire + * id, it must be the same object in the component under test and the test case + * itself. Due to this requirement, we save the mock to the global object to be + * shared. + */ +const resolvedPromiseTemplate = babelTemplate(` + let RESOURCE_NAME; + try { + RESOURCE_NAME = require(IMPORT_SOURCE).default; + } catch (e) { + global.MOCK_NAME = global.MOCK_NAME || function() { return Promise.resolve(); }; + RESOURCE_NAME = global.MOCK_NAME; + } +`); + +module.exports = function ({ types: t }) { + return { + visitor: { + ImportDeclaration(path) { + const { importSource, resourceNames } = getImportInfo(path, true); + + if (importSource.startsWith(APEX_CONTINUATION_IMPORT_IDENTIFIER)) { + // importing anything after '@salesforce/apexContinuation' means they're getting a single Apex method as the default import + // e.g. `import myMethod from '@salesforce/apexContinuation/FooController.fooMethod';` + path.replaceWithMultiple(resolvedPromiseTemplate({ + RESOURCE_NAME: t.identifier(resourceNames[0]), + IMPORT_SOURCE: t.stringLiteral(importSource), + MOCK_NAME: `__lwcJestMock_${resourceNames[0]}`, + })); + } + } + } + }; +};