'use strict'; require('../common'); const assert = require('assert'); const { inherits } = require('util'); // 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.deepStrictEqual( Object.getOwnPropertyDescriptor(B, 'super_'), { value: A, enumerable: false, configurable: true, writable: true } ); 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(() => { inherits(A, {}); }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "superCtor.prototype" property must be of type object. ' + 'Received undefined' }); assert.throws(() => { inherits(A, null); }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "superCtor" argument must be of type function. ' + 'Received null' }); assert.throws(() => { inherits(null, A); }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "ctor" argument must be of type function. Received null' });