Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix gjs/gts bugs for ember-template-imports and ember-cli-babel #408

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ Steps:
}
}
```
## ember-template-imports integration

* in `ember-cli-build.js
```
const app = new EmberApp(defaults, {
'ember-template-imports': {
inline_source_map: true,
},
});
```

## Configuration

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@release-it-plugins/lerna-changelog": "^6.0.0",
"@release-it-plugins/workspaces": "^4.0.0",
"chai-files": "^1.4.0",
"content-tag": "^2.0.1",
"execa": "8.0.1",
"fixturify-project": "~6.0.0",
"fs-extra": "~11.1.1",
Expand Down
6 changes: 1 addition & 5 deletions packages/ember-cli-code-coverage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,13 @@ module.exports = {
return [];
}

let useStringLookupForPlugin = false;
if (opts.embroider === true) {
try {
// Attempt to import the utility @embroider/compat uses in >3.1 to locate the embroider working directory
// the presence of this `locateEmbroiderWorkingDir` method coincides with the shift to utilize `rewritten-app` tmp dir
// eslint-disable-next-line node/no-missing-require
let { locateEmbroiderWorkingDir } = require('@embroider/core');
cwd = path.resolve(locateEmbroiderWorkingDir(cwd), 'rewritten-app');
useStringLookupForPlugin = true;
} catch (err) {
// otherwise, fall back to the method used in embroider <3.1
let {
Expand All @@ -90,9 +88,7 @@ module.exports = {
const IstanbulPlugin = require.resolve('babel-plugin-istanbul');
return [
// String lookup is needed to workaround https://github.com/embroider-build/embroider/issues/1525
useStringLookupForPlugin
? 'ember-cli-code-coverage/lib/gjs-gts-istanbul-ignore-template-plugin'
: require('./lib/gjs-gts-istanbul-ignore-template-plugin'),
path.resolve(__dirname, 'lib/gjs-gts-istanbul-ignore-template-plugin'),
[IstanbulPlugin, { cwd, include: '**/*', exclude, extension }],
];
},
Expand Down
28 changes: 26 additions & 2 deletions packages/ember-cli-code-coverage/lib/attach-middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@ function logError(err, req, res, next) {
next(err);
}

// ember-template-import has weird sourcemaps for gjs/gts
// so we need to do some custom path remapping
// Example `my-app/components/my-app/components/file.gjs` -> `my-app/components/file.gjs`
function normalizePathForTemplateImports(filepath) {
const filepathArray = filepath.split(path.sep);
const lastIndexOfTopDirName = filepathArray.lastIndexOf(filepathArray[0]);

// This means we are dealing with v2 addon test which already has correct path
if (lastIndexOfTopDirName === 0) {
return filepath;
}

const dedupedPathArray = filepathArray.filter(
(_, index) => index >= lastIndexOfTopDirName
);

return dedupedPathArray.join(path.sep);
}

/*
* This function normalizes the relativePath to match what we get from a classical app. Its goal
* is to change any in repo paths like: app-namespace/lib/in-repo-namespace/components/foo.js to
Expand Down Expand Up @@ -78,9 +97,10 @@ function adjustCoverageKey(
namespaceMappings,
modifyAssetLocation
) {
let relativePath = path.relative(root, filepath);

let embroiderTmpPathRegex = /embroider\/.{6}/gm;
let gjsGtsRegex = /\.g[tj]s$/gm;

let relativePath = path.relative(root, filepath);

// we can determine if file is coming from embroider based on how the path looks
if (embroiderTmpPathRegex.test(filepath)) {
Expand All @@ -91,6 +111,10 @@ function adjustCoverageKey(
return filepath;
}

if (gjsGtsRegex.test(relativePath)) {
relativePath = normalizePathForTemplateImports(relativePath);
}

let namespace = relativePath.split(path.sep)[0];
let pathWithoutNamespace = relativePath.split(path.sep).slice(1);
let namespaceKey = namespace;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ const gjsGtsTemplateIgnoreVisitor = {
const { node } = path;
let { callee } = node;

if (callee.name !== 'template') {
// if there is already a `template` variable in scope, content-tag will use `template1` local name and so on.
if (!/^template\d*$/.test(callee.name)) {
return;
}

const callScopeBinding = path.scope.getBinding('template');
const callScopeBinding = path.scope.getBinding(callee.name);

if (
callScopeBinding.kind === 'module' &&
Expand All @@ -50,14 +51,22 @@ module.exports = function () {
visitor: {
Program: {
enter(path, state) {
const filename = state.file.opts.filename;
const inputSourceMap = state.file.inputMap?.sourcemap;

if (!filename?.match(/\.g[tj]s$/)) {
if (!inputSourceMap) {
return;
}

// We need to do early traverse to make sure this runs before istanbuls plugin
path.traverse(gjsGtsTemplateIgnoreVisitor, state);
const sourcePaths = inputSourceMap.sources;

const isGjsGtsFile = sourcePaths.some((source) =>
source.match(/\.g[tj]s$/)
);

if (isGjsGtsFile) {
// We need to do early traverse to make sure this runs before istanbuls plugin
path.traverse(gjsGtsTemplateIgnoreVisitor, state);
}
},
},
},
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ export default template(\`
`;

exports[`gjs-gts-ignore-template-plugin > it does not add istanbul ignore comment before "template" invocation if template is not imported from "@ember/template-compiler" 1`] = `
"import { template } from "@ember/template-compiler";
"import { template as template1 } from "@ember/template-compiler";
import { on } from '@ember/modifier';
let counter = 0;
function bar() {
const template = () => {};
template();
const template1 = () => {};
template1();
counter++;
console.log(counter);
}
/* istanbul ignore next */
export default template(\`
export default template1(\`
<button {{on "click" bar}}>
increment
</button>
Expand All @@ -47,8 +47,6 @@ exports[`gjs-gts-ignore-template-plugin > it skips files if it\`s a regular js f
import { on } from '@ember/modifier';
let counter = 0;
function bar() {
const template = () => {};
template();
counter++;
console.log(counter);
}
Expand All @@ -68,8 +66,6 @@ exports[`gjs-gts-ignore-template-plugin > it skips files if it\`s a regular ts f
import { on } from '@ember/modifier';
let counter = 0;
function bar() {
const template = () => {};
template();
counter++;
console.log(counter);
}
Expand Down