Repository: ember-cli/ember-cli
Pull request #9506 (2021-04-19 20:19:32)

Pass `realPath` as `root` for addons that export a function for its constructor
This fixes a bug where it's possible for addons to have the wrong `root` property. The case for this is when an addon inherits from another addon, so it's not super likely, but I've added a test-case to cover this.


Patch:
diff --git a/lib/models/package-info-cache/package-info.js b/lib/models/package-info-cache/package-info.js
index 2d10470f7..9e4358f7b 100644
--- a/lib/models/package-info-cache/package-info.js
+++ b/lib/models/package-info-cache/package-info.js
@@ -395,7 +395,7 @@ class PackageInfo {
 
     if (typeof module === 'function') {
       ctor = module;
-      ctor.prototype.root = ctor.prototype.root || this.realPath;
+      ctor.prototype.root = this.realPath;
       ctor.prototype.pkg = ctor.prototype.pkg || this.pkg;
     } else {
       const Addon = require('../addon'); // done here because of circular dependency


Test patch:
diff --git a/tests/fixtures/addon/simple/lib/extend-from-addon-directly/index.js b/tests/fixtures/addon/simple/lib/extend-from-addon-directly/index.js
new file mode 100644
index 000000000..03ebd576c
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/extend-from-addon-directly/index.js
@@ -0,0 +1,7 @@
+'use strict';
+
+const Addon = require('../../../../../../lib/models/addon');
+
+module.exports = Addon.extend({
+  name: require('./package').name,
+});
diff --git a/tests/fixtures/addon/simple/lib/extend-from-addon-directly/package.json b/tests/fixtures/addon/simple/lib/extend-from-addon-directly/package.json
new file mode 100644
index 000000000..c7c4edefd
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/extend-from-addon-directly/package.json
@@ -0,0 +1,7 @@
+{
+  "name": "extend-from-addon-directly",
+  "keywords": [
+    "ember-addon"
+  ],
+  "dependencies": {}
+}
\ No newline at end of file
diff --git a/tests/fixtures/addon/simple/lib/odd-inheritance-addon/index.js b/tests/fixtures/addon/simple/lib/odd-inheritance-addon/index.js
new file mode 100644
index 000000000..a2803136e
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/odd-inheritance-addon/index.js
@@ -0,0 +1,7 @@
+'use strict';
+
+const AddonToExtendFrom = require('../extend-from-addon-directly');
+
+module.exports = AddonToExtendFrom.extend({
+  name: require('./package').name,
+});
diff --git a/tests/fixtures/addon/simple/lib/odd-inheritance-addon/package.json b/tests/fixtures/addon/simple/lib/odd-inheritance-addon/package.json
new file mode 100644
index 000000000..a96531aca
--- /dev/null
+++ b/tests/fixtures/addon/simple/lib/odd-inheritance-addon/package.json
@@ -0,0 +1,7 @@
+{
+  "name": "odd-inheritance-addon",
+  "keywords": [
+    "ember-addon"
+  ],
+  "dependencies": {}
+}
\ No newline at end of file
diff --git a/tests/fixtures/addon/simple/package.json b/tests/fixtures/addon/simple/package.json
index ef32076f9..54a32d955 100644
--- a/tests/fixtures/addon/simple/package.json
+++ b/tests/fixtures/addon/simple/package.json
@@ -7,7 +7,9 @@
   "ember-addon": {
     "paths": [
       "./lib/ember-super-button",
-      "./lib/ember-super-button/lib/ember-with-addon-main"
+      "./lib/ember-super-button/lib/ember-with-addon-main",
+      "./lib/extend-from-addon-directly",
+      "./lib/odd-inheritance-addon"
     ]
   },
   "devDependencies": {
diff --git a/tests/unit/models/package-info-cache/package-info-cache-test.js b/tests/unit/models/package-info-cache/package-info-cache-test.js
index 0de1cddc7..0541d4cc0 100644
--- a/tests/unit/models/package-info-cache/package-info-cache-test.js
+++ b/tests/unit/models/package-info-cache/package-info-cache-test.js
@@ -151,11 +151,11 @@ describe('models/package-info-cache/package-info-cache-test.js', function () {
       expect(packageAndErrorNames).to.deep.equal(devDependencyNames);
     });
 
-    it('shows projectPackageInfo has 2 in-repo addons', function () {
+    it('shows projectPackageInfo has 4 in-repo addons', function () {
       let inRepoAddons = projectPackageInfo.inRepoAddons;
 
       expect(inRepoAddons).to.exist;
-      expect(inRepoAddons.length).to.equal(2);
+      expect(inRepoAddons.length).to.equal(4);
 
       expect(inRepoAddons[0].realPath.indexOf(`simple${path.sep}lib${path.sep}ember-super-button`)).to.be.above(0);
       expect(inRepoAddons[0].pkg.name).to.equal('ember-super-button');
@@ -166,6 +166,14 @@ describe('models/package-info-cache/package-info-cache-test.js', function () {
         )
       ).to.be.above(0);
       expect(inRepoAddons[1].pkg.name).to.equal('ember-with-addon-main');
+
+      expect(inRepoAddons[2].realPath.indexOf(`simple${path.sep}lib${path.sep}extend-from-addon-directly`)).to.be.above(
+        0
+      );
+      expect(inRepoAddons[2].pkg.name).to.equal('extend-from-addon-directly');
+
+      expect(inRepoAddons[3].realPath.indexOf(`simple${path.sep}lib${path.sep}odd-inheritance-addon`)).to.be.above(0);
+      expect(inRepoAddons[3].pkg.name).to.equal('odd-inheritance-addon');
     });
 
     it('shows projectPackageInfo has 7 internal addon packages', function () {
@@ -235,6 +243,34 @@ describe('models/package-info-cache/package-info-cache-test.js', function () {
       expect(allPackageInfosForAddonWithMain.length).to.equal(4);
       expect(areAllPackageInfosEqual).to.equal(true);
     });
+
+    it('returns has the correct `root` for addons that export a function for its constructor', function () {
+      project.initializeAddons();
+
+      let inRepoAddons = projectPackageInfo.inRepoAddons;
+
+      let ExtendFromAddonDirectlyConstructor = inRepoAddons[2].getAddonConstructor();
+      let OddInheritanceAddonConstructor = inRepoAddons[3].getAddonConstructor();
+
+      expect(ExtendFromAddonDirectlyConstructor.prototype.root).to.equal(
+        path.resolve(__dirname, '../../../fixtures/addon/simple/lib/extend-from-addon-directly')
+      );
+
+      expect(OddInheritanceAddonConstructor.prototype.root).to.equal(
+        path.resolve(__dirname, '../../../fixtures/addon/simple/lib/odd-inheritance-addon')
+      );
+
+      let extendFromAddonInstance = new ExtendFromAddonDirectlyConstructor(project, project);
+      let oddInheritanceAddonInstance = new OddInheritanceAddonConstructor(project, project);
+
+      expect(extendFromAddonInstance.root).to.equal(
+        path.resolve(__dirname, '../../../fixtures/addon/simple/lib/extend-from-addon-directly')
+      );
+
+      expect(oddInheritanceAddonInstance.root).to.equal(
+        path.resolve(__dirname, '../../../fixtures/addon/simple/lib/odd-inheritance-addon')
+      );
+    });
   });
 
   describe('packageInfo', function () {
diff --git a/tests/unit/models/project-test.js b/tests/unit/models/project-test.js
index 654fa4cec..49f3037f6 100644
--- a/tests/unit/models/project-test.js
+++ b/tests/unit/models/project-test.js
@@ -348,6 +348,8 @@ describe('models/project.js', function () {
         'ember-random-addon',
         'ember-super-button',
         'ember-with-addon-main',
+        'extend-from-addon-directly',
+        'odd-inheritance-addon',
       ];
       expect(Object.keys(project.addonPackages)).to.deep.equal(expected);
     });