From 16815d0fc3083eb86c76e02b79fd3bcf4bd0951a Mon Sep 17 00:00:00 2001 From: Travis Hoover Date: Mon, 22 Nov 2021 12:16:01 -0800 Subject: [PATCH 1/2] Adding `customAdjustment` config option Allow customizing how the file path adjustment works by passing a function as an option. --- README.md | 17 +++++++------ packages/ember-cli-code-coverage/index.js | 25 ++++++++----------- .../lib/attach-middleware.js | 20 ++++++++++++--- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index d5434fe8..323a354e 100644 --- a/README.md +++ b/README.md @@ -201,18 +201,21 @@ QUnit.done(async () => { }); ``` -Under the hood, `ember-cli-code-coverage` creates a mapping of app and addon namespaces to their actual on disk locations. While in general this -works correctly in the rare execption you can customize this via: +Under the hood, `ember-cli-code-coverage` attempts to "de-namespacify" paths into their real on disk location inside of +`project.root` (ie give a namespaced path like lib/inrepo/components/foo.js would live in lib/inrepo/addon/components/foo.js). It makes +some assumptions (where files live in in-repo addons vs app code for example) and sometimes those assumptions might not hold. Passing a +function `customAdjustment` will allow you to override where a file actually lives inside of your project. ```js const app = new EmberApp(defaults, { 'ember-cli-code-coverage': { - namespaceOverride(item, namespace) { - if (item.name === 'common') { - namespace.set(item.name, 'some-full-path/addon'); - namespace.set(path.join(item.name, 'test-support'), 'some-full-path/addon-test-support'); - return true; + customAdjustment(root, relativePath) { + // here is an example of saying that `component/foo.js` actually + // lives in `lib/common/app/foo.js` on disk. + if (fs.existsSync(path.join(root, 'lib/inrepo/app', relativePath))) { + return path.join('lib/common/app', relativePath); } + return false; }, }, diff --git a/packages/ember-cli-code-coverage/index.js b/packages/ember-cli-code-coverage/index.js index 3cb4a6e7..569fd77b 100644 --- a/packages/ember-cli-code-coverage/index.js +++ b/packages/ember-cli-code-coverage/index.js @@ -74,24 +74,19 @@ module.exports = { included(app) { this._super.included.apply(this, arguments); let config = app.options[this.name] || {}; - this.namespaceOverride = config && config.namespaceOverride; + this.customAdjustment = config && config.customAdjustment; }, - buildNamespaceMappings(namespaceOverride) { + buildNamespaceMappings() { let rootNamespaceMappings = new Map(); - function recurse(item, namespaceOverride) { - let override = false; - if (namespaceOverride) { - override = namespaceOverride(item, rootNamespaceMappings); - } - - if (item.isEmberCLIProject && item.isEmberCLIProject() && !override) { + function recurse(item) { + if (item.isEmberCLIProject && item.isEmberCLIProject()) { let projectConfig = item.config(process.env.EMBER_ENV); rootNamespaceMappings.set( projectConfig.modulePrefix, path.join(item.root, 'app') ); - } else if (item.treePaths && !override) { + } else if (item.treePaths) { let addonPath = path.join(item.root, item.treePaths.addon); let addonTestSupportPath = path.join( item.root, @@ -103,10 +98,10 @@ module.exports = { addonTestSupportPath ); } - item.addons.forEach((i) => recurse(i, namespaceOverride)); + item.addons.forEach((i) => recurse(i)); } - recurse(this.project, namespaceOverride); + recurse(this.project); // this adds a "default" lookup to the namespace in the event that there is no // namespace. this comes up under embroider depending on the app structure of @@ -130,7 +125,8 @@ module.exports = { configPath: this.project.configPath(), root: this.project.root, fileLookup: this.fileLookup, - namespaceMappings: this.buildNamespaceMappings(this.namespaceOverride), + namespaceMappings: this.buildNamespaceMappings(), + customAdjustment: this.customAdjustment, }); }, @@ -139,7 +135,8 @@ module.exports = { configPath: this.project.configPath(), root: this.project.root, fileLookup: this.fileLookup, - namespaceMappings: this.buildNamespaceMappings(this.namespaceOverride), + namespaceMappings: this.buildNamespaceMappings(), + customAdjustment: this.customAdjustment, }; // if we're running `ember test --server` use the `serverMiddleware`. if (process.argv.includes('--server') || process.argv.includes('-s')) { diff --git a/packages/ember-cli-code-coverage/lib/attach-middleware.js b/packages/ember-cli-code-coverage/lib/attach-middleware.js index a45401f2..89f82ca6 100644 --- a/packages/ember-cli-code-coverage/lib/attach-middleware.js +++ b/packages/ember-cli-code-coverage/lib/attach-middleware.js @@ -62,7 +62,12 @@ function normalizeRelativePath(root, filepath) { * where as in Classic it will be the "actual" app like: `/Users/x/y/z/ember-test-app/ember-test-app/components/foo.js` * both of these absolute paths should be converted into `app/components/foo.js` */ -function adjustCoverageKey(root, filepath, namespaceMappings) { +function adjustCoverageKey( + root, + filepath, + namespaceMappings, + customAdjustment +) { let relativePath = path.relative(root, filepath); let embroiderTmpPathRegex = /embroider\/.{6}/gm; @@ -81,6 +86,14 @@ function adjustCoverageKey(root, filepath, namespaceMappings) { pathWithoutNamespace = pathWithoutNamespace.slice(1); } + if (customAdjustment) { + let customPath = customAdjustment(root, relativePath, filepath); + + if (customPath) { + return customPath; + } + } + if (namespaceMappings.has(namespaceKey)) { return path.join( ...[namespaceMappings.get(namespaceKey), ...pathWithoutNamespace] @@ -94,12 +107,13 @@ function adjustCoverageKey(root, filepath, namespaceMappings) { } function adjustCoverage(coverage, options) { - let { root, namespaceMappings } = options; + let { root, namespaceMappings, customAdjustment } = options; const adjustedCoverage = Object.keys(coverage).reduce((memo, filePath) => { let relativeToProjectRoot = adjustCoverageKey( root, filePath, - namespaceMappings + namespaceMappings, + customAdjustment ); coverage[filePath].path = path.relative(root, relativeToProjectRoot); memo[path.relative(root, relativeToProjectRoot)] = coverage[filePath]; From 48fb3a96f6bb840cc316012234e7f9e68061937a Mon Sep 17 00:00:00 2001 From: Travis Hoover Date: Tue, 30 Nov 2021 10:05:29 -0800 Subject: [PATCH 2/2] addressing PR comments --- README.md | 5 +++-- packages/ember-cli-code-coverage/index.js | 6 +++--- .../lib/attach-middleware.js | 15 ++++++++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 323a354e..9b3bcc7c 100644 --- a/README.md +++ b/README.md @@ -204,12 +204,13 @@ QUnit.done(async () => { Under the hood, `ember-cli-code-coverage` attempts to "de-namespacify" paths into their real on disk location inside of `project.root` (ie give a namespaced path like lib/inrepo/components/foo.js would live in lib/inrepo/addon/components/foo.js). It makes some assumptions (where files live in in-repo addons vs app code for example) and sometimes those assumptions might not hold. Passing a -function `customAdjustment` will allow you to override where a file actually lives inside of your project. +function `modifyAssetLocation` will allow you to override where a file actually lives inside of your project. The returned string should +be relative to your project root. ```js const app = new EmberApp(defaults, { 'ember-cli-code-coverage': { - customAdjustment(root, relativePath) { + modifyAssetLocation(root, relativePath) { // here is an example of saying that `component/foo.js` actually // lives in `lib/common/app/foo.js` on disk. if (fs.existsSync(path.join(root, 'lib/inrepo/app', relativePath))) { diff --git a/packages/ember-cli-code-coverage/index.js b/packages/ember-cli-code-coverage/index.js index 569fd77b..35918811 100644 --- a/packages/ember-cli-code-coverage/index.js +++ b/packages/ember-cli-code-coverage/index.js @@ -74,7 +74,7 @@ module.exports = { included(app) { this._super.included.apply(this, arguments); let config = app.options[this.name] || {}; - this.customAdjustment = config && config.customAdjustment; + this.modifyAssetLocation = config && config.modifyAssetLocation; }, buildNamespaceMappings() { @@ -126,7 +126,7 @@ module.exports = { root: this.project.root, fileLookup: this.fileLookup, namespaceMappings: this.buildNamespaceMappings(), - customAdjustment: this.customAdjustment, + modifyAssetLocation: this.modifyAssetLocation, }); }, @@ -136,7 +136,7 @@ module.exports = { root: this.project.root, fileLookup: this.fileLookup, namespaceMappings: this.buildNamespaceMappings(), - customAdjustment: this.customAdjustment, + modifyAssetLocation: this.modifyAssetLocation, }; // if we're running `ember test --server` use the `serverMiddleware`. if (process.argv.includes('--server') || process.argv.includes('-s')) { diff --git a/packages/ember-cli-code-coverage/lib/attach-middleware.js b/packages/ember-cli-code-coverage/lib/attach-middleware.js index 89f82ca6..39b0887c 100644 --- a/packages/ember-cli-code-coverage/lib/attach-middleware.js +++ b/packages/ember-cli-code-coverage/lib/attach-middleware.js @@ -66,7 +66,7 @@ function adjustCoverageKey( root, filepath, namespaceMappings, - customAdjustment + modifyAssetLocation ) { let relativePath = path.relative(root, filepath); let embroiderTmpPathRegex = /embroider\/.{6}/gm; @@ -86,8 +86,13 @@ function adjustCoverageKey( pathWithoutNamespace = pathWithoutNamespace.slice(1); } - if (customAdjustment) { - let customPath = customAdjustment(root, relativePath, filepath); + if (modifyAssetLocation) { + let customPath = modifyAssetLocation( + root, + relativePath, + filepath, + namespaceMappings + ); if (customPath) { return customPath; @@ -107,13 +112,13 @@ function adjustCoverageKey( } function adjustCoverage(coverage, options) { - let { root, namespaceMappings, customAdjustment } = options; + let { root, namespaceMappings, modifyAssetLocation } = options; const adjustedCoverage = Object.keys(coverage).reduce((memo, filePath) => { let relativeToProjectRoot = adjustCoverageKey( root, filePath, namespaceMappings, - customAdjustment + modifyAssetLocation ); coverage[filePath].path = path.relative(root, relativeToProjectRoot); memo[path.relative(root, relativeToProjectRoot)] = coverage[filePath];