Skip to content

Instantly share code, notes, and snippets.

@psqq
Created July 3, 2024 12:23
Show Gist options
  • Save psqq/b1a3e2ff659d7136c17e7f919597ae38 to your computer and use it in GitHub Desktop.
Save psqq/b1a3e2ff659d7136c17e7f919597ae38 to your computer and use it in GitHub Desktop.
// type "node index.mjs" for run
import assert from 'assert';
import test, { describe } from 'node:test';
export default function classes(BasesArg) {
class Bases {
constructor() {
BasesArg.forEach((Base) => Object.assign(this, new Base()));
}
}
function addPrototype(Class) {
if (!Class?.prototype) {
return;
}
const names = Object.getOwnPropertyNames(Class.prototype);
names
.filter((prop) => prop !== 'constructor')
.forEach((prop) => (Bases.prototype[prop] = Class.prototype[prop]));
addPrototype(Object.getPrototypeOf(Class));
}
BasesArg.forEach((Base) => {
addPrototype(Base);
});
return Bases;
}
describe('classes tests', async () => {
test('classes 1', (t) => {
class A {
a() {
return 'a';
}
}
class B extends A {
b() {
return 'b';
}
}
class C extends B {
c() {
return 'c';
}
}
class D {
d() {
return 'd';
}
}
class E extends classes([C, D]) {
constructor() {
super();
}
e() {
return 'e';
}
}
const eObj = new E();
assert.strictEqual(eObj.e(), 'e');
assert.strictEqual(eObj.d(), 'd');
assert.strictEqual(eObj.c(), 'c');
assert.strictEqual(eObj.b(), 'b');
assert.strictEqual(eObj.a(), 'a');
});
test('classes 2', (t) => {
class A {
a() {
return 'a';
}
}
class B extends A {}
class C extends B {
c() {
return 'c';
}
}
class D {
d() {
return 'd';
}
}
class E extends classes([C, D]) {
constructor() {
super();
}
e() {
return 'e';
}
}
const eObj = new E();
assert.strictEqual(eObj.e(), 'e');
assert.strictEqual(eObj.d(), 'd');
assert.strictEqual(eObj.c(), 'c');
assert.strictEqual(eObj.a(), 'a');
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment