DEV: Make `modifyClass` native class-aware, add tests (#16111)

This commit is contained in:
Jarek Radosz 2022-11-03 18:10:08 +01:00 committed by GitHub
parent c122c032bb
commit 6e5e696c0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 1 deletions

View File

@ -225,7 +225,15 @@ class PluginApi {
if (canModify(klass, "member", resolverName, changes)) { if (canModify(klass, "member", resolverName, changes)) {
delete changes.pluginId; delete changes.pluginId;
klass.class.reopen(changes);
if (klass.class.reopen) {
klass.class.reopen(changes);
} else {
Object.defineProperties(
klass.class.prototype || klass.class,
Object.getOwnPropertyDescriptors(changes)
);
}
} }
return klass; return klass;

View File

@ -0,0 +1,87 @@
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import EmberObject from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import { withPluginApi } from "discourse/lib/plugin-api";
discourseModule("Unit | Utility | plugin-api", function () {
test("modifyClass works with classic Ember objects", function (assert) {
const TestThingy = EmberObject.extend({
@discourseComputed
prop() {
return "hello";
},
});
this.registry.register("test-thingy:main", TestThingy);
withPluginApi("1.1.0", (api) => {
api.modifyClass("test-thingy:main", {
pluginId: "plugin-api-test",
@discourseComputed
prop() {
return `${this._super(...arguments)} there`;
},
});
});
const thingy = this.container.lookup("test-thingy:main");
assert.strictEqual(thingy.prop, "hello there");
});
test("modifyClass works with native class Ember objects", function (assert) {
class NativeTestThingy extends EmberObject {
@discourseComputed
prop() {
return "howdy";
}
}
this.registry.register("native-test-thingy:main", NativeTestThingy);
withPluginApi("1.1.0", (api) => {
api.modifyClass("native-test-thingy:main", {
pluginId: "plugin-api-test",
@discourseComputed
prop() {
return `${this._super(...arguments)} partner`;
},
});
});
const thingy = this.container.lookup("native-test-thingy:main");
assert.strictEqual(thingy.prop, "howdy partner");
});
test("modifyClass works with native classes", function (assert) {
class ClassTestThingy {
get keep() {
return "hey!";
}
get prop() {
return "top of the morning";
}
}
this.registry.register("class-test-thingy:main", new ClassTestThingy(), {
instantiate: false,
});
withPluginApi("1.1.0", (api) => {
api.modifyClass("class-test-thingy:main", {
pluginId: "plugin-api-test",
get prop() {
return "g'day";
},
});
});
const thingy = this.container.lookup("class-test-thingy:main");
assert.strictEqual(thingy.keep, "hey!");
assert.strictEqual(thingy.prop, "g'day");
});
});