From 8195a8b0897b981dafaf4d4cb0d5efe056b825a0 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:46:17 -0700 Subject: [PATCH] feat: export test plugins --- index.d.ts | 18 +++++++++++------ index.test-d.ts | 20 ++++++------------- package.json | 7 +++++-- plugins/bar/index.d.ts | 8 ++++++++ plugins/bar/index.js | 5 +++++ plugins/foo/index.d.ts | 8 ++++++++ plugins/foo/index.js | 5 +++++ plugins/void/index.d.ts | 3 +++ plugins/void/index.js | 3 +++ test/base.test.js | 43 ++++++++++++++--------------------------- 10 files changed, 69 insertions(+), 51 deletions(-) create mode 100644 plugins/bar/index.d.ts create mode 100644 plugins/bar/index.js create mode 100644 plugins/foo/index.d.ts create mode 100644 plugins/foo/index.js create mode 100644 plugins/void/index.d.ts create mode 100644 plugins/void/index.js diff --git a/index.d.ts b/index.d.ts index 3c3cadf..8a920c8 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,10 +1,16 @@ -declare type Options = { - [key: string]: unknown; -}; +export declare namespace Base { + type Options = { + [key: string]: unknown; + }; +} + declare type ApiExtension = { [key: string]: unknown; }; -declare type Plugin = (instance: Base, options: Options) => ApiExtension | void; +declare type Plugin = ( + instance: Base, + options: Base.Options +) => ApiExtension | void; declare type Constructor = new (...args: any[]) => T; /** @@ -24,7 +30,7 @@ declare type ReturnTypeOf = ? UnionToIntersection, void>> : never; -export declare class Base { +export declare class Base { static plugins: Plugin[]; static plugin< S extends Constructor & { @@ -40,7 +46,7 @@ export declare class Base { plugins: any[]; } & Constructor & ReturnTypeOf>>; static defaults< - TDefaults extends Options, + TDefaults extends Base.Options, S extends Constructor> >( this: S, diff --git a/index.test-d.ts b/index.test-d.ts index 4ce594b..f8fcddc 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,20 +1,9 @@ import { expectType } from "tsd"; import { Base } from "./index.js"; -const fooPlugin = () => { - return { - foo: "foo", - }; -}; -const barPlugin = () => { - return { - bar: "bar", - }; -}; - -const voidPlugin = () => { - // returns void -}; +import { fooPlugin } from "./plugins/foo/index.js"; +import { barPlugin } from "./plugins/bar/index.js"; +import { voidPlugin } from "./plugins/void/index.js"; const base = new Base(); @@ -56,3 +45,6 @@ const baseWithVoidAndNonVoidPlugins = new BaseWithVoidAndNonVoidPlugins(); expectType(baseWithVoidAndNonVoidPlugins.foo); expectType(baseWithVoidAndNonVoidPlugins.bar); + +// @ts-expect-error unknown properties cannot be used, see #31 +baseWithVoidAndNonVoidPlugins.unknown; diff --git a/package.json b/package.json index 1b6d2f1..c7d095e 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,13 @@ { "name": "javascript-plugin-architecture-with-typescript-definitions", "version": "0.0.0-development", - "type": "module", "description": "Plugin architecture example with full TypeScript support", + "type": "module", "exports": { - "./": "./index.js" + ".": "./index.js", + "./plugins/foo": "./plugins/foo/index.js", + "./plugins/bar": "./plugins/bar/index.js", + "./plugins/void": "./plugins/void/index.js" }, "types": "./index.d.ts", "scripts": { diff --git a/plugins/bar/index.d.ts b/plugins/bar/index.d.ts new file mode 100644 index 0000000..252c245 --- /dev/null +++ b/plugins/bar/index.d.ts @@ -0,0 +1,8 @@ +import { Base } from "../../index.js"; + +export function barPlugin( + base: Base, + options: Base.Options +): { + bar: string; +}; diff --git a/plugins/bar/index.js b/plugins/bar/index.js new file mode 100644 index 0000000..4e1cdf7 --- /dev/null +++ b/plugins/bar/index.js @@ -0,0 +1,5 @@ +export function barPlugin() { + return { + bar: "bar", + }; +} diff --git a/plugins/foo/index.d.ts b/plugins/foo/index.d.ts new file mode 100644 index 0000000..9f20afd --- /dev/null +++ b/plugins/foo/index.d.ts @@ -0,0 +1,8 @@ +import { Base } from "../../index.js"; + +export function fooPlugin( + base: Base, + options: Base.Options +): { + foo: string; +}; diff --git a/plugins/foo/index.js b/plugins/foo/index.js new file mode 100644 index 0000000..dfcd04b --- /dev/null +++ b/plugins/foo/index.js @@ -0,0 +1,5 @@ +export function fooPlugin() { + return { + foo: "foo", + }; +} diff --git a/plugins/void/index.d.ts b/plugins/void/index.d.ts new file mode 100644 index 0000000..959882f --- /dev/null +++ b/plugins/void/index.d.ts @@ -0,0 +1,3 @@ +import { Base } from "../../index.js"; + +export function voidPlugin(base: Base, options: Base.Options): void; diff --git a/plugins/void/index.js b/plugins/void/index.js new file mode 100644 index 0000000..76d6eb6 --- /dev/null +++ b/plugins/void/index.js @@ -0,0 +1,3 @@ +export function voidPlugin() { + // returns void +} diff --git a/test/base.test.js b/test/base.test.js index 4f8cfe8..619521f 100644 --- a/test/base.test.js +++ b/test/base.test.js @@ -2,47 +2,32 @@ import { test } from "uvu"; import * as assert from "uvu/assert"; import { Base } from "../index.js"; - -const fooPlugin = (test) => { - return { - foo: () => "foo", - }; -}; -const barPlugin = (test) => { - return { - bar: () => "bar", - }; -}; -const pluginWithEmptyObjectReturn = (test) => { - return {}; -}; +import { fooPlugin } from "../plugins/foo/index.js"; +import { barPlugin } from "../plugins/bar/index.js"; +import { voidPlugin } from "../plugins/void/index.js"; test(".plugin(fooPlugin)", () => { const FooTest = Base.plugin(fooPlugin); const fooTest = new FooTest(); - assert.equal(fooTest.foo(), "foo"); + assert.equal(fooTest.foo, "foo"); }); test(".plugin(fooPlugin, barPlugin)", () => { const FooBarTest = Base.plugin(fooPlugin, barPlugin); const fooBarTest = new FooBarTest(); - assert.equal(fooBarTest.foo(), "foo"); - assert.equal(fooBarTest.bar(), "bar"); + assert.equal(fooBarTest.foo, "foo"); + assert.equal(fooBarTest.bar, "bar"); }); -test(".plugin(fooPlugin, barPlugin, pluginWithVoidReturn)", () => { - const FooBarTest = Base.plugin( - fooPlugin, - barPlugin, - pluginWithEmptyObjectReturn - ); +test(".plugin(fooPlugin, barPlugin, voidPlugin)", () => { + const FooBarTest = Base.plugin(fooPlugin, barPlugin, voidPlugin); const fooBarTest = new FooBarTest(); - assert.equal(fooBarTest.foo(), "foo"); - assert.equal(fooBarTest.bar(), "bar"); + assert.equal(fooBarTest.foo, "foo"); + assert.equal(fooBarTest.bar, "bar"); }); test(".plugin(fooPlugin).plugin(barPlugin)", () => { const FooBarTest = Base.plugin(fooPlugin).plugin(barPlugin); const fooBarTest = new FooBarTest(); - assert.equal(fooBarTest.foo(), "foo"); - assert.equal(fooBarTest.bar(), "bar"); + assert.equal(fooBarTest.foo, "foo"); + assert.equal(fooBarTest.bar, "bar"); }); test(".defaults({foo: 'bar'})", () => { const BaseWithDefaults = Base.defaults({ foo: "bar" }); @@ -63,9 +48,9 @@ test(".plugin().defaults()", () => { const instance1 = new BaseWithPluginAndDefaults(); const instance2 = new BaseWithDefaultsAndPlugin(); - assert.equal(instance1.foo(), "foo"); + assert.equal(instance1.foo, "foo"); assert.equal(instance1.options, { baz: "daz" }); - assert.equal(instance2.foo(), "foo"); + assert.equal(instance2.foo, "foo"); assert.equal(instance2.options, { baz: "daz" }); });