From bf57a27a9f6f9877472dc2f637592c2f0bcc1527 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Fri, 31 Oct 2025 22:52:44 +0900 Subject: [PATCH 1/5] test: add fixtures for esm plugin tests --- test/fixtures/test-package/esm-export.js | 7 +++++++ test/fixtures/test-package/esm-multiple-export.js | 13 +++++++++++++ test/fixtures/test-package/esm-subclass.js | 14 ++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 test/fixtures/test-package/esm-export.js create mode 100644 test/fixtures/test-package/esm-multiple-export.js create mode 100644 test/fixtures/test-package/esm-subclass.js diff --git a/test/fixtures/test-package/esm-export.js b/test/fixtures/test-package/esm-export.js new file mode 100644 index 000000000..4da61e98d --- /dev/null +++ b/test/fixtures/test-package/esm-export.js @@ -0,0 +1,7 @@ +import { PushActionPlugin } from '@finos/git-proxy/plugin'; + +// test default export (ESM syntax) +export default new PushActionPlugin(async (req, action) => { + console.log('Dummy plugin: ', action); + return action; +}); diff --git a/test/fixtures/test-package/esm-multiple-export.js b/test/fixtures/test-package/esm-multiple-export.js new file mode 100644 index 000000000..a971d6302 --- /dev/null +++ b/test/fixtures/test-package/esm-multiple-export.js @@ -0,0 +1,13 @@ +import { PushActionPlugin, PullActionPlugin } from '@finos/git-proxy/plugin'; + +// test multiple exports (ESM syntax) +export default { + foo: new PushActionPlugin(async (req, action) => { + console.log('PushActionPlugin: ', action); + return action; + }), + bar: new PullActionPlugin(async (req, action) => { + console.log('PullActionPlugin: ', action); + return action; + }), +}; diff --git a/test/fixtures/test-package/esm-subclass.js b/test/fixtures/test-package/esm-subclass.js new file mode 100644 index 000000000..164419d01 --- /dev/null +++ b/test/fixtures/test-package/esm-subclass.js @@ -0,0 +1,14 @@ +import { PushActionPlugin } from '@finos/git-proxy/plugin'; + +class DummyPlugin extends PushActionPlugin { + constructor(exec) { + super(); + this.exec = exec; + } +} + +// test default export (ESM syntax) +export default new DummyPlugin(async (req, action) => { + console.log('Dummy plugin: ', action); + return action; +}); From 282b1f4cf9d97083a916fc4c251d491b0e615b3c Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Fri, 31 Oct 2025 22:52:55 +0900 Subject: [PATCH 2/5] test: add esm plugin tests --- test/plugin/plugin.test.js | 95 +++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/test/plugin/plugin.test.js b/test/plugin/plugin.test.js index c26929136..d5ecc9f76 100644 --- a/test/plugin/plugin.test.js +++ b/test/plugin/plugin.test.js @@ -2,12 +2,7 @@ import chai from 'chai'; import { spawnSync } from 'child_process'; import { rmSync } from 'fs'; import { join } from 'path'; -import { - isCompatiblePlugin, - PullActionPlugin, - PushActionPlugin, - PluginLoader, -} from '../../src/plugin.ts'; +import { isCompatiblePlugin, PushActionPlugin, PluginLoader } from '../../src/plugin.ts'; chai.should(); @@ -22,35 +17,69 @@ describe('loading plugins from packages', function () { spawnSync('npm', ['install'], { cwd: testPackagePath, timeout: 5000 }); }); - it('should load plugins that are the default export (module.exports = pluginObj)', async function () { - const loader = new PluginLoader([join(testPackagePath, 'default-export.js')]); - await loader.load(); - expect(loader.pushPlugins.length).to.equal(1); - expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; - expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))).to - .be.true; - }).timeout(10000); + describe('CommonJS syntax', () => { + it('should load plugins that are the default export (module.exports = pluginObj)', async function () { + const loader = new PluginLoader([join(testPackagePath, 'default-export.js')]); + await loader.load(); + expect(loader.pushPlugins.length).to.equal(1); + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))) + .to.be.true; + }).timeout(10000); - it('should load multiple plugins from a module that match the plugin class (module.exports = { pluginFoo, pluginBar })', async function () { - const loader = new PluginLoader([join(testPackagePath, 'multiple-export.js')]); - await loader.load(); - expect(loader.pushPlugins.length).to.equal(1); - expect(loader.pullPlugins.length).to.equal(1); - expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; - expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))).to - .be.true; - expect(loader.pullPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPullActionPlugin'))).to - .be.true; - }).timeout(10000); + it('should load multiple plugins from a module that match the plugin class (module.exports = { pluginFoo, pluginBar })', async function () { + const loader = new PluginLoader([join(testPackagePath, 'multiple-export.js')]); + await loader.load(); + expect(loader.pushPlugins.length).to.equal(1); + expect(loader.pullPlugins.length).to.equal(1); + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))) + .to.be.true; + expect(loader.pullPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPullActionPlugin'))) + .to.be.true; + }).timeout(10000); - it('should load plugins that are subclassed from plugin classes', async function () { - const loader = new PluginLoader([join(testPackagePath, 'subclass.js')]); - await loader.load(); - expect(loader.pushPlugins.length).to.equal(1); - expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; - expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))).to - .be.true; - }).timeout(10000); + it('should load plugins that are subclassed from plugin classes', async function () { + const loader = new PluginLoader([join(testPackagePath, 'subclass.js')]); + await loader.load(); + expect(loader.pushPlugins.length).to.equal(1); + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))) + .to.be.true; + }).timeout(10000); + }); + + describe('ESM syntax', () => { + it('should load plugins that are the default export (exports default pluginObj)', async function () { + const loader = new PluginLoader([join(testPackagePath, 'esm-export.js')]); + await loader.load(); + expect(loader.pushPlugins.length).to.equal(1); + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))) + .to.be.true; + }).timeout(10000); + + it('should load multiple plugins from a module that match the plugin class (exports default { pluginFoo, pluginBar })', async function () { + const loader = new PluginLoader([join(testPackagePath, 'esm-multiple-export.js')]); + await loader.load(); + expect(loader.pushPlugins.length).to.equal(1); + expect(loader.pullPlugins.length).to.equal(1); + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))) + .to.be.true; + expect(loader.pullPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPullActionPlugin'))) + .to.be.true; + }).timeout(10000); + + it('should load plugins that are subclassed from plugin classes (exports default class DummyPlugin extends PushActionPlugin {})', async function () { + const loader = new PluginLoader([join(testPackagePath, 'esm-subclass.js')]); + await loader.load(); + expect(loader.pushPlugins.length).to.equal(1); + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; + expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p, 'isGitProxyPushActionPlugin'))) + .to.be.true; + }).timeout(10000); + }); it('should not load plugins that are not valid modules', async function () { const loader = new PluginLoader([join(__dirname, './dummy.js')]); From 4664c79eaec493d0bcf733b1ab7e381ea1e6bced Mon Sep 17 00:00:00 2001 From: Juan Escalada <97265671+jescalada@users.noreply.github.com> Date: Mon, 3 Nov 2025 13:20:15 +0900 Subject: [PATCH 3/5] Update test/fixtures/test-package/esm-multiple-export.js Co-authored-by: Thomas Cooper <57812123+coopernetes@users.noreply.github.com> Signed-off-by: Juan Escalada <97265671+jescalada@users.noreply.github.com> --- test/fixtures/test-package/esm-multiple-export.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/fixtures/test-package/esm-multiple-export.js b/test/fixtures/test-package/esm-multiple-export.js index a971d6302..0f0ea43c6 100644 --- a/test/fixtures/test-package/esm-multiple-export.js +++ b/test/fixtures/test-package/esm-multiple-export.js @@ -10,4 +10,9 @@ export default { console.log('PullActionPlugin: ', action); return action; }), + baz: { + exec: (async (req, action) => { + console.log('not a real plugin object'); + }), + }, }; From 5f21d4ffabf7148f64560c6fcf5e85f06aa6cb11 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 5 Nov 2025 21:04:33 +0900 Subject: [PATCH 4/5] test: add non-plugin object to multiple-export.js to test proper PluginLoader behaviour --- test/fixtures/test-package/multiple-export.js | 5 +++++ test/plugin/plugin.test.js | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/test/fixtures/test-package/multiple-export.js b/test/fixtures/test-package/multiple-export.js index 9a6a5544a..672ffde28 100644 --- a/test/fixtures/test-package/multiple-export.js +++ b/test/fixtures/test-package/multiple-export.js @@ -9,4 +9,9 @@ module.exports = { console.log('PullActionPlugin: ', action); return action; }), + baz: { + exec: async (req, action) => { + console.log('not a real plugin object'); + }, + }, }; diff --git a/test/plugin/plugin.test.js b/test/plugin/plugin.test.js index d5ecc9f76..bb1acbdf0 100644 --- a/test/plugin/plugin.test.js +++ b/test/plugin/plugin.test.js @@ -30,6 +30,8 @@ describe('loading plugins from packages', function () { it('should load multiple plugins from a module that match the plugin class (module.exports = { pluginFoo, pluginBar })', async function () { const loader = new PluginLoader([join(testPackagePath, 'multiple-export.js')]); await loader.load(); + + // Should load the foo and bar plugins, but not the baz object which isn't a plugin expect(loader.pushPlugins.length).to.equal(1); expect(loader.pullPlugins.length).to.equal(1); expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; @@ -62,6 +64,8 @@ describe('loading plugins from packages', function () { it('should load multiple plugins from a module that match the plugin class (exports default { pluginFoo, pluginBar })', async function () { const loader = new PluginLoader([join(testPackagePath, 'esm-multiple-export.js')]); await loader.load(); + + // Should load the foo and bar plugins, but not the baz object which isn't a plugin expect(loader.pushPlugins.length).to.equal(1); expect(loader.pullPlugins.length).to.equal(1); expect(loader.pushPlugins.every((p) => isCompatiblePlugin(p))).to.be.true; From eeb05f2a209623046a4a9ccff28f5d7e29975f1e Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 5 Nov 2025 21:04:46 +0900 Subject: [PATCH 5/5] chore: format --- test/fixtures/test-package/esm-multiple-export.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fixtures/test-package/esm-multiple-export.js b/test/fixtures/test-package/esm-multiple-export.js index 0f0ea43c6..fb9c290bc 100644 --- a/test/fixtures/test-package/esm-multiple-export.js +++ b/test/fixtures/test-package/esm-multiple-export.js @@ -11,8 +11,8 @@ export default { return action; }), baz: { - exec: (async (req, action) => { + exec: async (req, action) => { console.log('not a real plugin object'); - }), + }, }, };