An error occurred while loading the file. Please try again.
vcsPluginInterface.spec.js 4.34 KiB
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { VcsUiApp, loadPlugin } from '@vcmap/ui';
import plugin from '../src/index.js';
import packageJSON from '../package.json';
function sleep(ms = 0) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
window.VcsPluginLoaderFunction = (name, module) => ({
  default: () => plugin({ name }, module),
});
const testPropSymbol = Symbol('testProp');
describe('VcsPlugin Interface test', () => {
  let pluginInstance;
  beforeAll(async () => {
    pluginInstance = await loadPlugin(packageJSON.name, {
      name: packageJSON.name,
      entry: '_dev',
    });
  });
  afterAll(() => {
    pluginInstance?.destroy?.();
  });
  describe('name, version, mapVersion', () => {
    it('should return the plugin name from the package.json', () => {
      expect(pluginInstance).to.have.property('name', packageJSON.name);
    });
    it('should return the plugin version from the package.json', () => {
      expect(pluginInstance).to.have.property('version', packageJSON.version);
    });
    it('should return the plugin mapVersion from the package.json', () => {
      expect(pluginInstance).to.have.property(
        'mapVersion',
        packageJSON.mapVersion,
    });
  });
  describe('internationalization', () => {
    it('may provide an i18n object and should provide at least en as fallback language', () => {
      if (pluginInstance?.i18n) {
        expect(pluginInstance?.i18n).to.be.a('object').with.property('en');
    });
    it('should use unscoped, camel-case plugin name as namespace for plugin specific i18n entries', () => {
      if (pluginInstance?.i18n) {
        expect(pluginInstance.i18n).to.be.a('object');
        const [scope, name] = packageJSON.name.split('/');
        const unscopedName = name || scope;
        const camelCaseName = unscopedName.replace(/-./g, (x) =>
          x[1].toUpperCase(),
        Object.values(pluginInstance.i18n).forEach((locale) => {
          expect(locale).to.have.property(camelCaseName);
        });
    });
  });
  describe('plugin hooks', () => {
    it('may implement initialize', () => {
      if (pluginInstance?.initialize) {
expect(pluginInstance.initialize).to.be.a('function'); expect(pluginInstance.initialize(new VcsUiApp(), undefined)).to.not .throw; } }); it('may implement onVcsAppMounted', () => { if (pluginInstance?.onVcsAppMounted) { expect(pluginInstance.onVcsAppMounted).to.be.a('function'); expect(pluginInstance.onVcsAppMounted(new VcsUiApp())).to.not.throw; } }); it('should implement destroy', () => { if (pluginInstance?.destroy) { expect(pluginInstance.destroy).to.be.a('function'); } }); }); describe('options & serialization', () => { it('may return default options', () => { if (pluginInstance?.getDefaultOptions) { expect(pluginInstance.getDefaultOptions()).to.be.a('object'); } }); it('may implement toJSON returning the plugin config', () => { if (pluginInstance?.toJSON) { expect(pluginInstance.toJSON()).to.be.a('object'); } }); }); describe('shadowing a plugin', () => { let app; let pluginInstance2; beforeAll(async () => { app = new VcsUiApp(); app.plugins.add(pluginInstance); pluginInstance2 = await loadPlugin(packageJSON.name, { name: packageJSON.name, version: '2.0.0', entry: '_dev', }); if (pluginInstance2) { pluginInstance2[testPropSymbol] = 'test'; } }); afterAll(() => { pluginInstance2?.destroy?.(); }); it('should override the plugin correctly', () => { expect(() => app.plugins.override(pluginInstance2)).to.not.throw; app.plugins.override(pluginInstance2); expect(app.plugins.getByKey(packageJSON.name)).to.have.property( testPropSymbol, 'test', ); expect(app.plugins.getByKey(packageJSON.name)).to.equal(pluginInstance2); }); it('should reincarnate the plugin correctly', async () => { expect(() => app.plugins.remove(pluginInstance2)).to.not.throw; app.plugins.remove(pluginInstance2); await sleep(0); expect(app.plugins.getByKey(packageJSON.name)).not.to.have.property( testPropSymbol, 'test', );