Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'import { PluginLoader } from '../plugin-loader'import { PluginRegistry } from '../plugin-registry'import { PluginSettingsStore } from '../plugin-settings-store'import { EnabledStateStore } from '../enabled-state-store'import { createTestApp, createMockDocumentManager, createTestManifest } from './test-utils'import { Plugin } from '../../plugin'import type { App } from '../../app'
class TestBuiltinPlugin extends Plugin { onloadCallCount = 0 onunloadCallCount = 0
async onload(): Promise<void> { this.onloadCallCount++ }
onunload(): void { this.onunloadCallCount++ }}
describe('PluginLoader.registerBuiltinInstance', () => { let app: App let registry: PluginRegistry let settingsStore: PluginSettingsStore let enabledStore: EnabledStateStore let loader: PluginLoader
beforeEach(async () => { localStorage.clear() app = await createTestApp() registry = new PluginRegistry() const dm = createMockDocumentManager() settingsStore = new PluginSettingsStore(dm as any) enabledStore = new EnabledStateStore() loader = new PluginLoader(app, registry, settingsStore, enabledStore) })
afterEach(() => { app.destroy() })
it('registers a built-in instance without enabling it', () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance)
expect(loader.getPluginState('builtin-test')).toBe('disabled') expect(loader.getPlugin('builtin-test')).toBeNull() // Not active, so getPlugin returns null expect(instance.onloadCallCount).toBe(0) // Not loaded yet })
it('includes built-in ID in getPluginIds()', () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance)
expect(loader.getPluginIds()).toContain('builtin-test') })
it('returns manifest via getPluginManifest()', () => { const manifest = createTestManifest({ id: 'builtin-test', name: 'Test Built-in' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance)
expect(loader.getPluginManifest('builtin-test')).toEqual(manifest) })
it('throws if instance already registered', () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance)
expect(() => loader.registerBuiltinInstance(instance)).toThrow( "Plugin 'builtin-test': already registered" ) })
it('allows enabling a registered built-in via enablePlugin()', async () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance) await loader.enablePlugin('builtin-test')
expect(loader.getPluginState('builtin-test')).toBe('active') expect(loader.getPlugin('builtin-test')).toBe(instance) expect(instance.onloadCallCount).toBe(1) })
it('allows disabling then re-enabling a built-in', async () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance) await loader.enablePlugin('builtin-test') expect(instance.onloadCallCount).toBe(1) expect(instance.onunloadCallCount).toBe(0)
loader.disablePlugin('builtin-test') expect(loader.getPluginState('builtin-test')).toBe('disabled') expect(instance.onunloadCallCount).toBe(1)
await loader.enablePlugin('builtin-test') expect(loader.getPluginState('builtin-test')).toBe('active') expect(instance.onloadCallCount).toBe(2) // onload called again on re-enable })
it('cleans up on second disable after re-enable', async () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance) // First cycle await loader.enablePlugin('builtin-test') loader.disablePlugin('builtin-test') expect(instance.onunloadCallCount).toBe(1)
// Second cycle await loader.enablePlugin('builtin-test') loader.disablePlugin('builtin-test') expect(instance.onunloadCallCount).toBe(2) // Must clean up on every cycle })
it('emits plugin-enabled event when enabling', async () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest) const listener = vi.fn() loader.on('plugin-enabled', listener)
loader.registerBuiltinInstance(instance) await loader.enablePlugin('builtin-test')
expect(listener).toHaveBeenCalledWith('builtin-test', instance) })
it('persists enabled state when enabling', async () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance) expect(enabledStore.isEnabled('builtin-test')).toBe(false)
await loader.enablePlugin('builtin-test') expect(enabledStore.isEnabled('builtin-test')).toBe(true)
loader.disablePlugin('builtin-test') expect(enabledStore.isEnabled('builtin-test')).toBe(false) })
describe('isBuiltinPlugin', () => { it('returns true for built-in plugins registered via registerBuiltinInstance', () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance)
expect(loader.isBuiltinPlugin('builtin-test')).toBe(true) })
it('returns false for registry-based plugins', () => { registry.register( createTestManifest({ id: 'registry-plugin' }), 'test://registry-plugin.js' )
expect(loader.isBuiltinPlugin('registry-plugin')).toBe(false) })
it('returns false for unregistered plugin IDs', () => { expect(loader.isBuiltinPlugin('nonexistent')).toBe(false) })
it('returns true even after disabling a built-in plugin', async () => { const manifest = createTestManifest({ id: 'builtin-test' }) const instance = new TestBuiltinPlugin(app, manifest)
loader.registerBuiltinInstance(instance) await loader.enablePlugin('builtin-test') loader.disablePlugin('builtin-test')
expect(loader.isBuiltinPlugin('builtin-test')).toBe(true) }) })
describe('getPluginIds with mixed plugins', () => { it('includes both registry and built-in plugin IDs', () => { // Register a built-in plugin const manifest = createTestManifest({ id: 'builtin-plugin' }) const instance = new TestBuiltinPlugin(app, manifest) loader.registerBuiltinInstance(instance)
// Register a registry-based plugin registry.register( createTestManifest({ id: 'registry-plugin' }), 'test://registry-plugin.js' )
const ids = loader.getPluginIds() expect(ids).toContain('builtin-plugin') expect(ids).toContain('registry-plugin') expect(ids.length).toBe(2) })
it('does not duplicate IDs if somehow registered in both', () => { // This shouldn't happen in practice, but test the deduplication logic const pluginId = 'dual-plugin' // Register in registry first registry.register( createTestManifest({ id: pluginId }), 'test://dual-plugin.js' )
// Try to register as built-in (should throw, so we can't test dedup directly) // But we can verify the ID appears only once when just in registry const ids = loader.getPluginIds() expect(ids.filter(id => id === pluginId).length).toBe(1) }) })})