jan/app/electron/core/plugin-manager/execution/ExtensionPoint.test.js
Louis 20dbc02c03
Refactor Jan into an Electron app (#175)
* hackathon: Refactor Jan into an Electron app

* chore: correct NextJS export output path

* chore: build electron app for all production targets

* fix: correct assetPrefix for production build

* chore: preferences shortcut

* chore: refactor

* chore: refactor into ts

* feature/#52-compile-plugin-with-webpack

* chore: introduce renderer <=> plugins <=> main invocation

* chore: suppress errors - deprecate graphql & next-auth

* chore: data plugin functions

* add llm support

Signed-off-by: James <james@jan.ai>

* chore: update plugin

* chore: introduce data-plugin

* chore: plugin invokes main with args and synchronously

* chore: install db plugin should setup db

* feature: Data Driver Plugin - Load conversations and messages from data plugin

* chore: store text message sent

* chore: shared core services

* feature: inference service

* chore: conversations ordering

* adding model management service

Signed-off-by: James <james@jan.ai>

* chore: strict type

* feature: abstract plugin preferences

* chore: abstract plugin preference

* Revert "chore: strict type"

This reverts commit 9be188d827a0b2e081e9e04b192c323799de5bb5.

* chore: base-plugin styling

* feature: create and delete conversation

* chore: fix plugin search & clean messages

* chore: typing indicator

* chore: refactor useSendChatMessage

* chore: persists inserted id to in-memory messages

* chore: search conversation history

* add delete and download model (#189)

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>

* chore: add empty state for conversation list

* chore: prompt missing extension function & fix app crashes

* chore: prompt user to install required plugins

* chore: add launch background

* chore: relaunch app on model downloaded

* Jan app add installation instruction (#191)

Co-authored-by: Hien To <>

* Chore: rename folder web-client to app (#192)

* Chore: rename folder web-client to app
---------

Co-authored-by: Hien To <>

* revert: add pre-install package

* add progress for downloading model

Signed-off-by: James <james@jan.ai>

* feature: production bundle

* add download progress

Signed-off-by: James <james@jan.ai>

* chore: add new chat function

* fix: electron asar unpack modules & dynamic import

* chore: fix unpack

* chore: fix dev pack

* Add instruction to build dmg file to README.md

* init model dynamically

Signed-off-by: James <james@jan.ai>

---------

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>
Co-authored-by: NamH <NamNh0122@gmail.com>
Co-authored-by: hiento09 <136591877+hiento09@users.noreply.github.com>
Co-authored-by: Hien To <>
2023-09-24 20:42:58 -07:00

117 lines
3.2 KiB
JavaScript

import Ep from './ExtensionPoint'
/** @type {Ep} */
let ep
const changeListener = jest.fn()
const objectRsp = { foo: 'bar' }
const funcRsp = arr => {
arr || (arr = [])
arr.push({ foo: 'baz' })
return arr
}
beforeEach(() => {
ep = new Ep('test-ep')
ep.register('test-ext-obj', objectRsp)
ep.register('test-ext-func', funcRsp, 10)
ep.onRegister('test', changeListener)
})
it('should create a new extension point by providing a name', () => {
expect(ep.name).toEqual('test-ep')
})
it('should register extension with extension point', () => {
expect(ep._extensions).toContainEqual({
name: 'test-ext-func',
response: funcRsp,
priority: 10
})
})
it('should register extension with a default priority of 0 if not provided', () => {
expect(ep._extensions).toContainEqual({
name: 'test-ext-obj',
response: objectRsp,
priority: 0
})
})
it('should execute the change listeners on registering a new extension', () => {
changeListener.mockClear()
ep.register('test-change-listener', true)
expect(changeListener.mock.calls.length).toBeTruthy()
})
it('should unregister an extension with the provided name if it exists', () => {
ep.unregister('test-ext-obj')
expect(ep._extensions).not.toContainEqual(
expect.objectContaining({
name: 'test-ext-obj'
})
)
})
it('should not unregister any extensions if the provided name does not exist', () => {
ep.unregister('test-ext-invalid')
expect(ep._extensions.length).toBe(2)
})
it('should execute the change listeners on unregistering an extension', () => {
changeListener.mockClear()
ep.unregister('test-ext-obj')
expect(changeListener.mock.calls.length).toBeTruthy()
})
it('should empty the registry of all extensions on clearing', () => {
ep.clear()
expect(ep._extensions).toEqual([])
})
it('should execute the change listeners on clearing extensions', () => {
changeListener.mockClear()
ep.clear()
expect(changeListener.mock.calls.length).toBeTruthy()
})
it('should return the relevant extension using the get method', () => {
const ext = ep.get('test-ext-obj')
expect(ext).toEqual({ foo: 'bar' })
})
it('should return the false using the get method if the extension does not exist', () => {
const ext = ep.get('test-ext-invalid')
expect(ext).toBeUndefined()
})
it('should provide an array with all responses, including promises where necessary, using the execute method', async () => {
ep.register('test-ext-async', () => new Promise(resolve => setTimeout(resolve, 0, { foo: 'delayed' })))
const arr = ep.execute([])
const res = await Promise.all(arr)
expect(res).toContainEqual({ foo: 'bar' })
expect(res).toContainEqual([{ foo: 'baz' }])
expect(res).toContainEqual({ foo: 'delayed' })
expect(res.length).toBe(3)
})
it('should provide an array including all responses in priority order, using the executeSerial method provided with an array', async () => {
const res = await ep.executeSerial([])
expect(res).toEqual([{ "foo": "bar" }, { "foo": "baz" }])
})
it('should provide an array including the last response using the executeSerial method provided with something other than an array', async () => {
const res = await ep.executeSerial()
expect(res).toEqual([{ "foo": "baz" }])
})