test: add missing tests (#3716)
This commit is contained in:
parent
5b7f0c1308
commit
c5e0c93ab4
@ -6,4 +6,12 @@ module.exports = {
|
||||
'@/(.*)': '<rootDir>/src/$1',
|
||||
},
|
||||
runner: './testRunner.js',
|
||||
transform: {
|
||||
"^.+\\.tsx?$": [
|
||||
"ts-jest",
|
||||
{
|
||||
diagnostics: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
8
core/src/browser/extensions/assistant.test.ts
Normal file
8
core/src/browser/extensions/assistant.test.ts
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
import { AssistantExtension } from './assistant';
|
||||
import { ExtensionTypeEnum } from '../extension';
|
||||
|
||||
it('should return the correct type', () => {
|
||||
const extension = new AssistantExtension();
|
||||
expect(extension.type()).toBe(ExtensionTypeEnum.Assistant);
|
||||
});
|
||||
45
core/src/browser/extensions/inference.test.ts
Normal file
45
core/src/browser/extensions/inference.test.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { MessageRequest, ThreadMessage } from '../../types'
|
||||
import { BaseExtension, ExtensionTypeEnum } from '../extension'
|
||||
import { InferenceExtension } from './'
|
||||
|
||||
// Mock the MessageRequest and ThreadMessage types
|
||||
type MockMessageRequest = {
|
||||
text: string
|
||||
}
|
||||
|
||||
type MockThreadMessage = {
|
||||
text: string
|
||||
userId: string
|
||||
}
|
||||
|
||||
// Mock the BaseExtension class
|
||||
class MockBaseExtension extends BaseExtension {
|
||||
type(): ExtensionTypeEnum | undefined {
|
||||
return ExtensionTypeEnum.Base
|
||||
}
|
||||
}
|
||||
|
||||
// Create a mock implementation of InferenceExtension
|
||||
class MockInferenceExtension extends InferenceExtension {
|
||||
async inference(data: MessageRequest): Promise<ThreadMessage> {
|
||||
return { text: 'Mock response', userId: '123' } as unknown as ThreadMessage
|
||||
}
|
||||
}
|
||||
|
||||
describe('InferenceExtension', () => {
|
||||
let inferenceExtension: InferenceExtension
|
||||
|
||||
beforeEach(() => {
|
||||
inferenceExtension = new MockInferenceExtension()
|
||||
})
|
||||
|
||||
it('should have the correct type', () => {
|
||||
expect(inferenceExtension.type()).toBe(ExtensionTypeEnum.Inference)
|
||||
})
|
||||
|
||||
it('should implement the inference method', async () => {
|
||||
const messageRequest: MessageRequest = { text: 'Hello' } as unknown as MessageRequest
|
||||
const result = await inferenceExtension.inference(messageRequest)
|
||||
expect(result).toEqual({ text: 'Mock response', userId: '123' } as unknown as ThreadMessage)
|
||||
})
|
||||
})
|
||||
42
core/src/browser/extensions/monitoring.test.ts
Normal file
42
core/src/browser/extensions/monitoring.test.ts
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
import { ExtensionTypeEnum } from '../extension';
|
||||
import { MonitoringExtension } from './monitoring';
|
||||
|
||||
it('should have the correct type', () => {
|
||||
class TestMonitoringExtension extends MonitoringExtension {
|
||||
getGpuSetting(): Promise<GpuSetting | undefined> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getResourcesInfo(): Promise<any> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getCurrentLoad(): Promise<any> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getOsInfo(): Promise<OperatingSystemInfo> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
const monitoringExtension = new TestMonitoringExtension();
|
||||
expect(monitoringExtension.type()).toBe(ExtensionTypeEnum.SystemMonitoring);
|
||||
});
|
||||
|
||||
|
||||
it('should create an instance of MonitoringExtension', () => {
|
||||
class TestMonitoringExtension extends MonitoringExtension {
|
||||
getGpuSetting(): Promise<GpuSetting | undefined> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getResourcesInfo(): Promise<any> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getCurrentLoad(): Promise<any> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getOsInfo(): Promise<OperatingSystemInfo> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
const monitoringExtension = new TestMonitoringExtension();
|
||||
expect(monitoringExtension).toBeInstanceOf(MonitoringExtension);
|
||||
});
|
||||
5
core/src/browser/tools/index.test.ts
Normal file
5
core/src/browser/tools/index.test.ts
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
it('should not throw any errors when imported', () => {
|
||||
expect(() => require('./index')).not.toThrow();
|
||||
})
|
||||
@ -52,4 +52,12 @@ it('should skip processing for disabled tools', async () => {
|
||||
|
||||
const result = await manager.process(request, tools)
|
||||
expect(result).toBe(request)
|
||||
})
|
||||
})
|
||||
|
||||
it('should throw an error when process is called without implementation', () => {
|
||||
class TestTool extends InferenceTool {
|
||||
name = 'testTool'
|
||||
}
|
||||
const tool = new TestTool()
|
||||
expect(() => tool.process({} as MessageRequest)).toThrowError()
|
||||
})
|
||||
|
||||
7
core/src/index.test.ts
Normal file
7
core/src/index.test.ts
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
it('should declare global object core when importing the module and then deleting it', () => {
|
||||
import('./index');
|
||||
delete globalThis.core;
|
||||
expect(typeof globalThis.core).toBe('undefined');
|
||||
});
|
||||
7
core/src/node/api/index.test.ts
Normal file
7
core/src/node/api/index.test.ts
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
import * as restfulV1 from './restful/v1';
|
||||
|
||||
it('should re-export from restful/v1', () => {
|
||||
const restfulV1Exports = require('./restful/v1');
|
||||
expect(restfulV1Exports).toBeDefined();
|
||||
})
|
||||
6
core/src/node/api/processors/Processor.test.ts
Normal file
6
core/src/node/api/processors/Processor.test.ts
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
import { Processor } from './Processor';
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(Processor).toBeDefined();
|
||||
});
|
||||
@ -7,3 +7,34 @@ it('should call function associated with key in process method', () => {
|
||||
extension.process('testKey', 'arg1', 'arg2');
|
||||
expect(mockFunc).toHaveBeenCalledWith('arg1', 'arg2');
|
||||
});
|
||||
|
||||
|
||||
it('should_handle_empty_extension_list_for_install', async () => {
|
||||
jest.mock('../../extension/store', () => ({
|
||||
installExtensions: jest.fn(() => Promise.resolve([])),
|
||||
}));
|
||||
const extension = new Extension();
|
||||
const result = await extension.installExtension([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
|
||||
it('should_handle_empty_extension_list_for_update', async () => {
|
||||
jest.mock('../../extension/store', () => ({
|
||||
getExtension: jest.fn(() => ({ update: jest.fn(() => Promise.resolve(true)) })),
|
||||
}));
|
||||
const extension = new Extension();
|
||||
const result = await extension.updateExtension([]);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
|
||||
it('should_handle_empty_extension_list', async () => {
|
||||
jest.mock('../../extension/store', () => ({
|
||||
getExtension: jest.fn(() => ({ uninstall: jest.fn(() => Promise.resolve(true)) })),
|
||||
removeExtension: jest.fn(),
|
||||
}));
|
||||
const extension = new Extension();
|
||||
const result = await extension.uninstallExtension([]);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
6
core/src/node/api/restful/helper/consts.test.ts
Normal file
6
core/src/node/api/restful/helper/consts.test.ts
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
import { NITRO_DEFAULT_PORT } from './consts';
|
||||
|
||||
it('should test NITRO_DEFAULT_PORT', () => {
|
||||
expect(NITRO_DEFAULT_PORT).toBe(3928);
|
||||
});
|
||||
@ -1,6 +1,8 @@
|
||||
import { getEngineConfiguration } from './config';
|
||||
import { getAppConfigurations, defaultAppConfig } from './config';
|
||||
|
||||
import { getJanExtensionsPath } from './config';
|
||||
import { getJanDataFolderPath } from './config';
|
||||
it('should return undefined for invalid engine ID', async () => {
|
||||
const config = await getEngineConfiguration('invalid_engine');
|
||||
expect(config).toBeUndefined();
|
||||
@ -12,3 +14,15 @@ it('should return default config when CI is e2e', () => {
|
||||
const config = getAppConfigurations();
|
||||
expect(config).toEqual(defaultAppConfig());
|
||||
});
|
||||
|
||||
|
||||
it('should return extensions path when retrieved successfully', () => {
|
||||
const extensionsPath = getJanExtensionsPath();
|
||||
expect(extensionsPath).not.toBeUndefined();
|
||||
});
|
||||
|
||||
|
||||
it('should return data folder path when retrieved successfully', () => {
|
||||
const dataFolderPath = getJanDataFolderPath();
|
||||
expect(dataFolderPath).not.toBeUndefined();
|
||||
});
|
||||
|
||||
9
core/src/types/message/messageEntity.test.ts
Normal file
9
core/src/types/message/messageEntity.test.ts
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
import { MessageStatus } from './messageEntity';
|
||||
|
||||
it('should have correct values', () => {
|
||||
expect(MessageStatus.Ready).toBe('ready');
|
||||
expect(MessageStatus.Pending).toBe('pending');
|
||||
expect(MessageStatus.Error).toBe('error');
|
||||
expect(MessageStatus.Stopped).toBe('stopped');
|
||||
})
|
||||
6
core/src/types/miscellaneous/systemResourceInfo.test.ts
Normal file
6
core/src/types/miscellaneous/systemResourceInfo.test.ts
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
import { SupportedPlatforms } from './systemResourceInfo';
|
||||
|
||||
it('should contain the correct values', () => {
|
||||
expect(SupportedPlatforms).toEqual(['win32', 'linux', 'darwin']);
|
||||
});
|
||||
16
core/src/types/monitoring/index.test.ts
Normal file
16
core/src/types/monitoring/index.test.ts
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
import * as monitoringInterface from './monitoringInterface';
|
||||
import * as resourceInfo from './resourceInfo';
|
||||
|
||||
import * as index from './index';
|
||||
import * as monitoringInterface from './monitoringInterface';
|
||||
import * as resourceInfo from './resourceInfo';
|
||||
|
||||
it('should re-export all symbols from monitoringInterface and resourceInfo', () => {
|
||||
for (const key in monitoringInterface) {
|
||||
expect(index[key]).toBe(monitoringInterface[key]);
|
||||
}
|
||||
for (const key in resourceInfo) {
|
||||
expect(index[key]).toBe(resourceInfo[key]);
|
||||
}
|
||||
});
|
||||
5
core/src/types/setting/index.test.ts
Normal file
5
core/src/types/setting/index.test.ts
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
it('should not throw any errors', () => {
|
||||
expect(() => require('./index')).not.toThrow();
|
||||
});
|
||||
19
core/src/types/setting/settingComponent.test.ts
Normal file
19
core/src/types/setting/settingComponent.test.ts
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
import { createSettingComponent } from './settingComponent';
|
||||
|
||||
it('should throw an error when creating a setting component with invalid controller type', () => {
|
||||
const props: SettingComponentProps = {
|
||||
key: 'invalidControllerKey',
|
||||
title: 'Invalid Controller Title',
|
||||
description: 'Invalid Controller Description',
|
||||
controllerType: 'invalid' as any,
|
||||
controllerProps: {
|
||||
placeholder: 'Enter text',
|
||||
value: 'Initial Value',
|
||||
type: 'text',
|
||||
textAlign: 'left',
|
||||
inputActions: ['unobscure'],
|
||||
},
|
||||
};
|
||||
expect(() => createSettingComponent(props)).toThrowError();
|
||||
});
|
||||
6
core/src/types/thread/threadEvent.test.ts
Normal file
6
core/src/types/thread/threadEvent.test.ts
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
import { ThreadEvent } from './threadEvent';
|
||||
|
||||
it('should have the correct values', () => {
|
||||
expect(ThreadEvent.OnThreadStarted).toBe('OnThreadStarted');
|
||||
});
|
||||
18
electron/jest.config.js
Normal file
18
electron/jest.config.js
Normal file
@ -0,0 +1,18 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
collectCoverageFrom: ['src/**/*.{ts,tsx}'],
|
||||
modulePathIgnorePatterns: ['<rootDir>/tests'],
|
||||
moduleNameMapper: {
|
||||
'@/(.*)': '<rootDir>/src/$1',
|
||||
},
|
||||
runner: './testRunner.js',
|
||||
transform: {
|
||||
'^.+\\.tsx?$': [
|
||||
'ts-jest',
|
||||
{
|
||||
diagnostics: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
10
electron/testRunner.js
Normal file
10
electron/testRunner.js
Normal file
@ -0,0 +1,10 @@
|
||||
const jestRunner = require('jest-runner');
|
||||
|
||||
class EmptyTestFileRunner extends jestRunner.default {
|
||||
async runTests(tests, watcher, onStart, onResult, onFailure, options) {
|
||||
const nonEmptyTests = tests.filter(test => test.context.hasteFS.getSize(test.path) > 0);
|
||||
return super.runTests(nonEmptyTests, watcher, onStart, onResult, onFailure, options);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EmptyTestFileRunner;
|
||||
@ -18,6 +18,14 @@ const config = {
|
||||
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||
runner: './testRunner.js',
|
||||
collectCoverageFrom: ['./**/*.{ts,tsx}'],
|
||||
transform: {
|
||||
"^.+\\.tsx?$": [
|
||||
"ts-jest",
|
||||
{
|
||||
diagnostics: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/72926763/5078746
|
||||
|
||||
8
web/utils/base64.test.ts
Normal file
8
web/utils/base64.test.ts
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
import { getBase64 } from './base64';
|
||||
|
||||
test('getBase64_converts_file_to_base64', async () => {
|
||||
const file = new File(['test'], 'test.txt', { type: 'text/plain' });
|
||||
const base64String = await getBase64(file);
|
||||
expect(base64String).toBe('data:text/plain;base64,dGVzdA==');
|
||||
});
|
||||
33
web/utils/converter.test.ts
Normal file
33
web/utils/converter.test.ts
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
import { formatDownloadSpeed } from './converter';
|
||||
import { formatExtensionsName } from './converter';
|
||||
import { formatTwoDigits } from './converter';
|
||||
|
||||
test('formatDownloadSpeed_should_return_correct_output_when_input_is_undefined', () => {
|
||||
expect(formatDownloadSpeed(undefined)).toBe('0B/s');
|
||||
});
|
||||
|
||||
|
||||
test('formatExtensionsName_should_return_correct_output_for_string_with_janhq_and_dash', () => {
|
||||
expect(formatExtensionsName('@janhq/extension-name')).toBe('extension name');
|
||||
});
|
||||
|
||||
|
||||
test('formatTwoDigits_should_return_correct_output_for_single_digit_number', () => {
|
||||
expect(formatTwoDigits(5)).toBe('5.00');
|
||||
});
|
||||
|
||||
|
||||
test('formatDownloadSpeed_should_return_correct_output_for_gigabytes', () => {
|
||||
expect(formatDownloadSpeed(1500000000)).toBe('1.40GB/s');
|
||||
});
|
||||
|
||||
|
||||
test('formatDownloadSpeed_should_return_correct_output_for_megabytes', () => {
|
||||
expect(formatDownloadSpeed(1500000)).toBe('1.43MB/s');
|
||||
});
|
||||
|
||||
|
||||
test('formatDownloadSpeed_should_return_correct_output_for_kilobytes', () => {
|
||||
expect(formatDownloadSpeed(1500)).toBe('1.46KB/s');
|
||||
});
|
||||
@ -1,5 +1,7 @@
|
||||
// web/utils/modelParam.test.ts
|
||||
import { normalizeValue, validationRules } from './modelParam'
|
||||
import { extractModelLoadParams } from './modelParam';
|
||||
import { extractInferenceParams } from './modelParam';
|
||||
|
||||
describe('validationRules', () => {
|
||||
it('should validate temperature correctly', () => {
|
||||
@ -189,3 +191,20 @@ describe('normalizeValue', () => {
|
||||
expect(normalizeValue('cpu_threads', 0)).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('should handle invalid values correctly by falling back to originParams', () => {
|
||||
const modelParams = { temperature: 'invalid', token_limit: -1 };
|
||||
const originParams = { temperature: 0.5, token_limit: 100 };
|
||||
expect(extractInferenceParams(modelParams, originParams)).toEqual(originParams);
|
||||
});
|
||||
|
||||
|
||||
it('should return an empty object when no modelParams are provided', () => {
|
||||
expect(extractModelLoadParams()).toEqual({});
|
||||
});
|
||||
|
||||
|
||||
it('should return an empty object when no modelParams are provided', () => {
|
||||
expect(extractInferenceParams()).toEqual({});
|
||||
});
|
||||
|
||||
@ -4,6 +4,7 @@ import { ChatCompletionRole, MessageStatus } from '@janhq/core'
|
||||
import { ThreadMessageBuilder } from './threadMessageBuilder'
|
||||
import { MessageRequestBuilder } from './messageRequestBuilder'
|
||||
|
||||
import { ContentType } from '@janhq/core';
|
||||
describe('ThreadMessageBuilder', () => {
|
||||
it('testBuildMethod', () => {
|
||||
const msgRequest = new MessageRequestBuilder(
|
||||
@ -25,3 +26,75 @@ import { ChatCompletionRole, MessageStatus } from '@janhq/core'
|
||||
expect(result.content).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
it('testPushMessageWithPromptOnly', () => {
|
||||
const msgRequest = new MessageRequestBuilder(
|
||||
'type',
|
||||
{ model: 'model' },
|
||||
{ id: 'thread-id' },
|
||||
[]
|
||||
);
|
||||
const builder = new ThreadMessageBuilder(msgRequest);
|
||||
const prompt = 'test prompt';
|
||||
builder.pushMessage(prompt, undefined, []);
|
||||
expect(builder.content).toEqual([
|
||||
{
|
||||
type: ContentType.Text,
|
||||
text: {
|
||||
value: prompt,
|
||||
annotations: [],
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
it('testPushMessageWithPdf', () => {
|
||||
const msgRequest = new MessageRequestBuilder(
|
||||
'type',
|
||||
{ model: 'model' },
|
||||
{ id: 'thread-id' },
|
||||
[]
|
||||
);
|
||||
const builder = new ThreadMessageBuilder(msgRequest);
|
||||
const prompt = 'test prompt';
|
||||
const base64 = 'test base64';
|
||||
const fileUpload = [{ type: 'pdf', file: { name: 'test.pdf', size: 1000 } }];
|
||||
builder.pushMessage(prompt, base64, fileUpload);
|
||||
expect(builder.content).toEqual([
|
||||
{
|
||||
type: ContentType.Pdf,
|
||||
text: {
|
||||
value: prompt,
|
||||
annotations: [base64],
|
||||
name: fileUpload[0].file.name,
|
||||
size: fileUpload[0].file.size,
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
it('testPushMessageWithImage', () => {
|
||||
const msgRequest = new MessageRequestBuilder(
|
||||
'type',
|
||||
{ model: 'model' },
|
||||
{ id: 'thread-id' },
|
||||
[]
|
||||
);
|
||||
const builder = new ThreadMessageBuilder(msgRequest);
|
||||
const prompt = 'test prompt';
|
||||
const base64 = 'test base64';
|
||||
const fileUpload = [{ type: 'image', file: { name: 'test.jpg', size: 1000 } }];
|
||||
builder.pushMessage(prompt, base64, fileUpload);
|
||||
expect(builder.content).toEqual([
|
||||
{
|
||||
type: ContentType.Image,
|
||||
text: {
|
||||
value: prompt,
|
||||
annotations: [base64],
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user