'use strict'; const common = 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 common.expectsError(function() { inherits(A, {}); }, { code: 'ERR_INVALID_ARG_TYPE', type: TypeError, message: 'The "superCtor.prototype" property must be of type Object. ' + 'Received type undefined' }); common.expectsError(function() { inherits(A, null); }, { code: 'ERR_INVALID_ARG_TYPE', type: TypeError, message: 'The "superCtor" argument must be of type Function. ' + 'Received type object' }); common.expectsError(function() { inherits(null, A); }, { code: 'ERR_INVALID_ARG_TYPE', type: TypeError, message: 'The "ctor" argument must be of type Function. Received type object' });