Permalink
Browse files

util, refactor: make inherits more compact with node.js (#380)

  • Loading branch information...
ngot authored and xicilion committed Nov 14, 2017
1 parent 7b200e8 commit 197375424c9326ac54841118a21f63fd5f9ed9d8
Showing with 100 additions and 20 deletions.
  1. +10 −12 fibjs/src/util/util.cpp
  2. +90 −8 test/util_test.js
View
@@ -18,25 +18,23 @@ DECLARE_MODULE(util);
result_t util_base::inherits(v8::Local<v8::Value> constructor,
v8::Local<v8::Value> superConstructor)
{
if (!constructor->IsObject() || !superConstructor->IsObject())
if (!constructor->IsObject() || !superConstructor->IsObject()
|| constructor->IsNullOrUndefined() || superConstructor->IsNullOrUndefined())
return CALL_E_TYPEMISMATCH;
v8::Local<v8::Object> _constructor = v8::Local<v8::Object>::Cast(constructor);
v8::Local<v8::Object> _superConstructor = v8::Local<v8::Object>::Cast(superConstructor);
Isolate* isolate = Isolate::current();
v8::Local<v8::Function> temp = v8::Function::New(isolate->m_isolate, NULL);
temp->Set(isolate->NewString("prototype"),
_superConstructor->Get(isolate->NewString("prototype")));
v8::Local<v8::Object> proto = temp->NewInstance();
v8::Local<v8::Object> _constructor = constructor.As<v8::Object>();
v8::Local<v8::Object> _superConstructor = superConstructor.As<v8::Object>();
proto->Set(isolate->NewString("constructor"), _constructor);
v8::Local<v8::Object> constructor_proto = (_constructor->Get(isolate->NewString("prototype"))).As<v8::Object>();
v8::Local<v8::Object> superConstructor_proto = (_superConstructor->Get(isolate->NewString("prototype"))).As<v8::Object>();
_constructor->Set(isolate->NewString("prototype"), proto);
_constructor->Set(isolate->NewString("super_"), _superConstructor);
if (superConstructor_proto->IsUndefined())
return CALL_E_TYPEMISMATCH;
_constructor->Set(isolate->NewString("super_"), _superConstructor);
constructor_proto->Set(isolate->NewString("__proto__"), superConstructor_proto);
return 0;
}
View
@@ -8,6 +8,7 @@ var os = require('os');
describe('util', () => {
it("inherits", () => {
const inherits = util.inherits;
function Child() {
console.log("in child");
}
@@ -16,16 +17,97 @@ describe('util', () => {
console.log("in parent");
}
util.inherits(Child, Parent);
inherits(Child, Parent);
var c = new Child();
var child = new Child();
assert.ok(c.constructor === Child)
assert.ok(c.constructor.super_ === Parent)
assert.ok(Object.getPrototypeOf(c) === Child.prototype)
assert.ok(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype)
assert.ok(c instanceof Child)
assert.ok(c instanceof Parent)
assert.ok(child.constructor === Child)
assert.ok(child.constructor.super_ === Parent)
assert.ok(Object.getPrototypeOf(child) === Child.prototype)
assert.ok(Object.getPrototypeOf(Object.getPrototypeOf(child)) === Parent.prototype)
assert.ok(child instanceof Child)
assert.ok(child instanceof Parent)
// super constructor
function A() {
this._a = 'a';
}
A.prototype.a = function() { return this._a; };
// one level of inheritance
function B(value) {
A.call(this);
this._b = value;
}
inherits(B, A);
B.prototype.b = function() { return this._b; };
assert.strictEqual(B.super_, A);
const b = new B('b');
assert.strictEqual(b.a(), 'a');
assert.strictEqual(b.b(), 'b');
assert.strictEqual(b.constructor, B);
// two levels of inheritance
function C() {
B.call(this, 'b');
this._c = 'c';
}
inherits(C, B);
C.prototype.c = function() { return this._c; };
C.prototype.getValue = function() { return this.a() + this.b() + this.c(); };
assert.strictEqual(C.super_, B);
const c = new C();
assert.strictEqual(c.getValue(), 'abc');
assert.strictEqual(c.constructor, C);
// inherits can be called after setting prototype properties
function D() {
C.call(this);
this._d = 'd';
}
D.prototype.d = function() { return this._d; };
inherits(D, C);
assert.strictEqual(D.super_, C);
const d = new D();
assert.strictEqual(d.c(), 'c');
assert.strictEqual(d.d(), 'd');
assert.strictEqual(d.constructor, D);
// ES6 classes can inherit from a constructor function
class E {
constructor() {
D.call(this);
this._e = 'e';
}
e() { return this._e; }
}
inherits(E, D);
assert.strictEqual(E.super_, D);
const e = new E();
assert.strictEqual(e.getValue(), 'abc');
assert.strictEqual(e.d(), 'd');
assert.strictEqual(e.e(), 'e');
assert.strictEqual(e.constructor, E);
// should throw with invalid arguments
assert.throws(function() {
inherits(A, {});
});
assert.throws(function() {
inherits(A, null);
});
assert.throws(function() {
inherits(null, A);
});
});
it("isEmpty", () => {

0 comments on commit 1973754

Please sign in to comment.