From 75b67b8fb7fc4df21267b98f0c9daeeb1130b824 Mon Sep 17 00:00:00 2001 From: Jeroen de Bruijn <62570005+jdbruijn@users.noreply.github.com> Date: Fri, 22 Jan 2021 08:09:37 +0100 Subject: [PATCH] fix(load): use `Rule | AsyncRule | SyncRule` as rule value type in `Plugin` (#2146) Use `Rule | AsyncRule | SyncRule` instead of `Rule` so plugin developers don't need to cast every non-default rule's value to `Rule`, but can define and assign their rules as `Rule | AsyncRule | SyncRule` instead. --- .../load/src/utils/load-plugin.test.ts | 49 +++++++++++++++++++ @commitlint/types/src/load.ts | 10 +++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/@commitlint/load/src/utils/load-plugin.test.ts b/@commitlint/load/src/utils/load-plugin.test.ts index abe9b74bc6..7c78d87f2f 100644 --- a/@commitlint/load/src/utils/load-plugin.test.ts +++ b/@commitlint/load/src/utils/load-plugin.test.ts @@ -1,4 +1,5 @@ import loadPlugin from './load-plugin'; +import {AsyncRule, Plugin, Rule, SyncRule} from '@commitlint/types'; jest.mock('commitlint-plugin-example', () => ({example: true}), { virtual: true, @@ -8,6 +9,39 @@ jest.mock('@scope/commitlint-plugin-example', () => ({scope: true}), { virtual: true, }); +jest.mock( + 'commitlint-plugin-rule', + (): Plugin => { + const rule: Rule = (_parsed, when, _value) => { + return [when === 'never']; + }; + return {rules: {rule}}; + }, + {virtual: true} +); + +jest.mock( + 'commitlint-plugin-sync-rule', + (): Plugin => { + const syncRule: SyncRule = (_parsed, when, _value) => { + return [when === 'never']; + }; + return {rules: {syncRule}}; + }, + {virtual: true} +); + +jest.mock( + 'commitlint-plugin-async-rule', + (): Plugin => { + const asyncRule: AsyncRule = (_parsed, when, _value) => { + return new Promise(() => [when === 'never']); + }; + return {rules: {asyncRule}}; + }, + {virtual: true} +); + test('should load a plugin when referenced by short name', () => { const plugins = loadPlugin({}, 'example'); expect(plugins['example']).toBe(require('commitlint-plugin-example')); @@ -18,6 +52,21 @@ test('should load a plugin when referenced by long name', () => { expect(plugins['example']).toBe(require('commitlint-plugin-example')); }); +test('should load a plugin with a rule', () => { + const plugins = loadPlugin({}, 'commitlint-plugin-rule'); + expect(plugins['rule']).toBe(require('commitlint-plugin-rule')); +}); + +test('should load a plugin with a sync rule', () => { + const plugins = loadPlugin({}, 'commitlint-plugin-sync-rule'); + expect(plugins['sync-rule']).toBe(require('commitlint-plugin-sync-rule')); +}); + +test('should load a plugin with an async rule', () => { + const plugins = loadPlugin({}, 'commitlint-plugin-async-rule'); + expect(plugins['async-rule']).toBe(require('commitlint-plugin-async-rule')); +}); + test('should throw an error when a plugin has whitespace', () => { expect(() => loadPlugin({}, 'whitespace ')).toThrow( "Whitespace found in plugin name 'whitespace '" diff --git a/@commitlint/types/src/load.ts b/@commitlint/types/src/load.ts index 481b477e0f..fa08e9982e 100644 --- a/@commitlint/types/src/load.ts +++ b/@commitlint/types/src/load.ts @@ -1,10 +1,16 @@ -import {Rule, RulesConfig, RuleConfigQuality} from './rules'; +import { + Rule, + RulesConfig, + RuleConfigQuality, + AsyncRule, + SyncRule, +} from './rules'; export type PluginRecords = Record; export interface Plugin { rules: { - [ruleName: string]: Rule; + [ruleName: string]: Rule | AsyncRule | SyncRule; }; }