1'use strict'; 2 3require('../common'); 4const assert = require('assert'); 5const { inherits } = require('util'); 6 7// Super constructor 8function A() { 9 this._a = 'a'; 10} 11A.prototype.a = function() { return this._a; }; 12 13// One level of inheritance 14function B(value) { 15 A.call(this); 16 this._b = value; 17} 18inherits(B, A); 19B.prototype.b = function() { return this._b; }; 20 21assert.deepStrictEqual( 22 Object.getOwnPropertyDescriptor(B, 'super_'), 23 { 24 value: A, 25 enumerable: false, 26 configurable: true, 27 writable: true 28 } 29); 30 31const b = new B('b'); 32assert.strictEqual(b.a(), 'a'); 33assert.strictEqual(b.b(), 'b'); 34assert.strictEqual(b.constructor, B); 35 36// Two levels of inheritance 37function C() { 38 B.call(this, 'b'); 39 this._c = 'c'; 40} 41inherits(C, B); 42C.prototype.c = function() { return this._c; }; 43C.prototype.getValue = function() { return this.a() + this.b() + this.c(); }; 44 45assert.strictEqual(C.super_, B); 46 47const c = new C(); 48assert.strictEqual(c.getValue(), 'abc'); 49assert.strictEqual(c.constructor, C); 50 51// Inherits can be called after setting prototype properties 52function D() { 53 C.call(this); 54 this._d = 'd'; 55} 56 57D.prototype.d = function() { return this._d; }; 58inherits(D, C); 59 60assert.strictEqual(D.super_, C); 61 62const d = new D(); 63assert.strictEqual(d.c(), 'c'); 64assert.strictEqual(d.d(), 'd'); 65assert.strictEqual(d.constructor, D); 66 67// ES6 classes can inherit from a constructor function 68class E { 69 constructor() { 70 D.call(this); 71 this._e = 'e'; 72 } 73 e() { return this._e; } 74} 75inherits(E, D); 76 77assert.strictEqual(E.super_, D); 78 79const e = new E(); 80assert.strictEqual(e.getValue(), 'abc'); 81assert.strictEqual(e.d(), 'd'); 82assert.strictEqual(e.e(), 'e'); 83assert.strictEqual(e.constructor, E); 84 85// Should throw with invalid arguments 86assert.throws(() => { 87 inherits(A, {}); 88}, { 89 code: 'ERR_INVALID_ARG_TYPE', 90 name: 'TypeError', 91 message: 'The "superCtor.prototype" property must be of type object. ' + 92 'Received undefined' 93}); 94 95assert.throws(() => { 96 inherits(A, null); 97}, { 98 code: 'ERR_INVALID_ARG_TYPE', 99 name: 'TypeError', 100 message: 'The "superCtor" argument must be of type function. ' + 101 'Received null' 102}); 103 104assert.throws(() => { 105 inherits(null, A); 106}, { 107 code: 'ERR_INVALID_ARG_TYPE', 108 name: 'TypeError', 109 message: 'The "ctor" argument must be of type function. Received null' 110}); 111