From bd7d95bfc14c376147255f6dce062e70bb00587f Mon Sep 17 00:00:00 2001 From: ikopeykin Date: Mon, 15 Jul 2019 14:17:12 +0300 Subject: [PATCH] #9391 resolve discussions, AbstractMethodError --- declarations/WebpackOptions.d.ts | 2 +- lib/AbstractMethodError.js | 36 ++++++++++++++++++++++++ lib/util/createHash.js | 42 +++++++++++++--------------- schemas/WebpackOptions.json | 2 +- test/AbstractMethodError.unittest.js | 27 ++++++++++++++++++ 5 files changed, 85 insertions(+), 24 deletions(-) create mode 100644 lib/AbstractMethodError.js create mode 100644 test/AbstractMethodError.unittest.js diff --git a/declarations/WebpackOptions.d.ts b/declarations/WebpackOptions.d.ts index bba927cd2..617bf4513 100644 --- a/declarations/WebpackOptions.d.ts +++ b/declarations/WebpackOptions.d.ts @@ -1094,7 +1094,7 @@ export interface OutputOptions { /** * Algorithm used for generation the hash (see node.js crypto package) */ - hashFunction?: string | (new () => import("../lib/util/createHash").Hash); + hashFunction?: string | import("../lib/util/createHash").HashConstructor; /** * Any string which is added to the hash to salt it */ diff --git a/lib/AbstractMethodError.js b/lib/AbstractMethodError.js new file mode 100644 index 000000000..49c06ee54 --- /dev/null +++ b/lib/AbstractMethodError.js @@ -0,0 +1,36 @@ +"use strict"; + +const WebpackError = require("./WebpackError"); +const CURRENT_METHOD_REGEXP = /at ([a-zA-Z0-9_.]*)/; + +/** + * @param {string=} method method name + * @returns {string} message + */ +function createMessage(method) { + return `Abstract method${method ? " " + method : ""}. Must be overriden.`; +} + +/** + * Error for abstract method + * @example + * class FooClass { + * abstractMethod() { + * throw new AbstractMethodError(); // error message: Abstract method FooClass.abstractMethod. Must be overriden. + * } + * } + * + */ +class AbstractMethodError extends WebpackError { + constructor() { + super(createMessage()); + this.name = "AbstractMethodError"; + /** @type {RegExpMatchArray} */ + const match = this.stack.split("\n")[1].match(CURRENT_METHOD_REGEXP); + if (match && match[1]) { + this.message = createMessage(match[1]); + } + } +} + +module.exports = AbstractMethodError; diff --git a/lib/util/createHash.js b/lib/util/createHash.js index 97f4ca49c..64de510da 100644 --- a/lib/util/createHash.js +++ b/lib/util/createHash.js @@ -4,38 +4,37 @@ */ "use strict"; +const AbstractMethodError = require("../AbstractMethodError"); + const BULK_SIZE = 1000; -class BaseHash { +class Hash { /** * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding} * @param {string|Buffer} data data - * @param {string} [inputEncoding] data encoding - * @returns {BaseHash} updated hash + * @param {string=} inputEncoding data encoding + * @returns {this} updated hash */ update(data, inputEncoding) { - return this; + throw new AbstractMethodError(); } /** * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding} - * @param {string} [encoding] encoding of the return value + * @param {string=} encoding encoding of the return value * @returns {string|Buffer} digest */ digest(encoding) { - return ""; + throw new AbstractMethodError(); } } -/** @typedef {BaseHash} Hash */ -/** @typedef {typeof BaseHash} HashConstructor */ +exports.Hash = Hash; +/** @typedef {typeof Hash} HashConstructor */ -/** - * @extends {BaseHash} - */ -class BulkUpdateDecorator extends BaseHash { +class BulkUpdateDecorator extends Hash { /** - * @param {BaseHash} hash hash + * @param {Hash} hash hash */ constructor(hash) { super(); @@ -46,8 +45,8 @@ class BulkUpdateDecorator extends BaseHash { /** * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding} * @param {string|Buffer} data data - * @param {string} [inputEncoding] data encoding - * @returns {BaseHash} updated hash + * @param {string=} inputEncoding data encoding + * @returns {this} updated hash */ update(data, inputEncoding) { if ( @@ -72,7 +71,7 @@ class BulkUpdateDecorator extends BaseHash { /** * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding} - * @param {string} [encoding] encoding of the return value + * @param {string=} encoding encoding of the return value * @returns {string|Buffer} digest */ digest(encoding) { @@ -88,9 +87,8 @@ class BulkUpdateDecorator extends BaseHash { /** * istanbul ignore next - * @extends {BaseHash} */ -class DebugHash extends BaseHash { +class DebugHash extends Hash { constructor() { super(); this.string = ""; @@ -99,8 +97,8 @@ class DebugHash extends BaseHash { /** * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding} * @param {string|Buffer} data data - * @param {string} [inputEncoding] data encoding - * @returns {BaseHash} updated hash + * @param {string=} inputEncoding data encoding + * @returns {this} updated hash */ update(data, inputEncoding) { if (typeof data !== "string") data = data.toString("utf-8"); @@ -110,7 +108,7 @@ class DebugHash extends BaseHash { /** * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding} - * @param {string} [encoding] encoding of the return value + * @param {string=} encoding encoding of the return value * @returns {string|Buffer} digest */ digest(encoding) { @@ -123,7 +121,7 @@ class DebugHash extends BaseHash { /** * Creates a hash by name or function * @param {string | HashConstructor} algorithm the algorithm name or a constructor creating a hash - * @returns {BaseHash} the hash + * @returns {Hash} the hash */ module.exports = algorithm => { if (typeof algorithm === "function") { diff --git a/schemas/WebpackOptions.json b/schemas/WebpackOptions.json index daafe6004..81ad90937 100644 --- a/schemas/WebpackOptions.json +++ b/schemas/WebpackOptions.json @@ -905,7 +905,7 @@ }, { "instanceof": "Function", - "tsType": "(new () => import('../lib/util/createHash').Hash)" + "tsType": "import('../lib/util/createHash').HashConstructor" } ] }, diff --git a/test/AbstractMethodError.unittest.js b/test/AbstractMethodError.unittest.js new file mode 100644 index 000000000..6b42ec873 --- /dev/null +++ b/test/AbstractMethodError.unittest.js @@ -0,0 +1,27 @@ +"use strict"; + +const AbstractMethodError = require("../lib/AbstractMethodError"); + +describe("WebpackError", () => { + class Foo { + abstractMethod() { + return new AbstractMethodError(); + } + } + + class Child extends Foo {} + + const expectedMessage = "Abstract method $1. Must be overriden."; + + it("Should construct message with caller info", () => { + const fooClassError = new Foo().abstractMethod(); + const childClassError = new Child().abstractMethod(); + + expect(fooClassError.message).toBe( + expectedMessage.replace("$1", "Foo.abstractMethod") + ); + expect(childClassError.message).toBe( + expectedMessage.replace("$1", "Child.abstractMethod") + ); + }); +});