-
Notifications
You must be signed in to change notification settings - Fork 109
Add support for gjs/gts files #405
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -154,6 +154,8 @@ Configuration is optional. It should be put in a file at `config/coverage.js` (` | |||||
|
|
||||||
| - `excludes`: Defaults to `['*/mirage/**/*']`. An array of globs to exclude from instrumentation. Useful to exclude files from coverage statistics. | ||||||
|
|
||||||
| - `extension`: Defaults to `['.gjs', '.gts', '.js', '.ts', '.cjs', '.mjs', '.mts', '.cts']`. Tell Istanbul to instrument only files with the provided extensions. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vstefanovic97 should this actually be
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @SergeAstapov well in the code it really is |
||||||
|
|
||||||
| - `coverageFolder`: Defaults to `coverage`. A folder relative to the root of your project to store coverage results. | ||||||
|
|
||||||
| - `parallel`: Defaults to `false`. Should be set to true if parallel testing is being used for separate test runs, for example when using [ember-exam](https://github.com/trentmwillis/ember-exam) with the `--partition` flag. This will generate the coverage reports in directories suffixed with `_<random_string>` to avoid overwriting other threads reports. These reports can be joined by using the `ember coverage-merge` command (potentially as part of the [posttest hook](https://docs.npmjs.com/misc/scripts) in your `package.json`). | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| "test": "vitest" | ||
| }, | ||
| "devDependencies": { | ||
| "@babel/core": "^7.23.9", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vstefanovic97 why is this needed in the root of monorepo? I guess each package that needs it should declare such kind of dependency.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's used in tests here
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, now I see - |
||
| "@release-it-plugins/lerna-changelog": "^6.0.0", | ||
| "@release-it-plugins/workspaces": "^4.0.0", | ||
| "chai-files": "^1.4.0", | ||
|
|
@@ -46,6 +47,6 @@ | |
| "version": "2.0.3", | ||
| "volta": { | ||
| "node": "16.20.2", | ||
| "pnpm": "8.10.2" | ||
| "pnpm": "8.15.1" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,16 @@ module.exports = { | |
| buildBabelPlugin(opts = {}) { | ||
| let cwd = opts.cwd || process.cwd(); | ||
| let exclude = ['*/mirage/**/*', '*/node_modules/**/*']; | ||
| let extension = [ | ||
| '.gjs', | ||
| '.gts', | ||
| '.js', | ||
| '.ts', | ||
| '.cjs', | ||
| '.mjs', | ||
| '.mts', | ||
| '.cts', | ||
| ]; | ||
| let coverageEnvVar = 'COVERAGE'; | ||
| let configBase = 'config'; | ||
|
|
||
|
|
@@ -48,19 +58,25 @@ module.exports = { | |
| if (config.coverageEnvVar) { | ||
| coverageEnvVar = config.coverageEnvVar; | ||
| } | ||
|
|
||
| if (config.extension) { | ||
RobbieTheWagner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| extension = config.extension; | ||
| } | ||
| } | ||
|
|
||
| if (process.env[coverageEnvVar] !== 'true') { | ||
| 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 { | ||
|
|
@@ -72,7 +88,13 @@ module.exports = { | |
| } | ||
|
|
||
| const IstanbulPlugin = require.resolve('babel-plugin-istanbul'); | ||
| return [[IstanbulPlugin, { cwd, include: '**/*', exclude }]]; | ||
| return [ | ||
| // String lookup is needed to workaround https://github.com/embroider-build/embroider/issues/1525 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As it turns out... We're going to require string lookup eventually, and forbid passing JS references. JS references are not parallizable, but string references are! (it's a babel thing 🤷 )
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hey @NullVoxPopuli are there any problems or situations where this string lookup might not work? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. one thing you could try is using a path.resolve('the-string-you-have'); // returns absolute string, so no matter who is requiring, their resolve isn't local to who is doing the requiring |
||
| useStringLookupForPlugin | ||
RobbieTheWagner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ? 'ember-cli-code-coverage/lib/gjs-gts-istanbul-ignore-template-plugin' | ||
| : require('./lib/gjs-gts-istanbul-ignore-template-plugin'), | ||
| [IstanbulPlugin, { cwd, include: '**/*', exclude, extension }], | ||
| ]; | ||
| }, | ||
|
|
||
| includedCommands() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| /** | ||
| * When gjs/gts is converted to js it looks like this | ||
| * | ||
| * @example | ||
| * template(` | ||
| * <div> | ||
| * template code | ||
| * </div>` | ||
| * , { | ||
| * eval() { | ||
| * return eval(arguments[0]); | ||
| * } | ||
| *}); | ||
| * | ||
| * The problem is Istanbul's babel plugin will try to instrument the `eval` method which can skew coverage results. | ||
| * In order to avoid this we add this plugin to add Istanbul ignore comments above `eval` to make sure it won't be instrumented by babel | ||
| */ | ||
| const gjsGtsTemplateIgnoreVisitor = { | ||
RobbieTheWagner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| CallExpression(path) { | ||
| const { node } = path; | ||
| let { callee } = node; | ||
|
|
||
| if (callee.name !== 'template') { | ||
| return; | ||
| } | ||
|
|
||
| const callScopeBinding = path.scope.getBinding('template'); | ||
|
|
||
| if ( | ||
| callScopeBinding.kind === 'module' && | ||
| callScopeBinding.path.parent.source.value === '@ember/template-compiler' | ||
| ) { | ||
| const babelIgnoreComment = { | ||
| type: 'CommentBlock', | ||
| value: ' istanbul ignore next ', | ||
| }; | ||
|
|
||
| if (!path.findParent((path) => path.isStatement()).node.leadingComments) { | ||
| path.findParent((path) => path.isStatement()).node.leadingComments = []; | ||
| } | ||
| path | ||
| .findParent((path) => path.isStatement()) | ||
| .node.leadingComments.push(babelIgnoreComment); | ||
| } | ||
| }, | ||
| }; | ||
|
|
||
| module.exports = function () { | ||
| return { | ||
| visitor: { | ||
| Program: { | ||
| enter(path, state) { | ||
| const filename = state.file.opts.filename; | ||
|
|
||
| if (!filename?.match(/\.g[tj]s$/)) { | ||
| return; | ||
| } | ||
|
|
||
| // We need to do early traverse to make sure this runs before istanbuls plugin | ||
| path.traverse(gjsGtsTemplateIgnoreVisitor, state); | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| }; | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.