Browse Source

feat: add unit tests for prompt templates

Jun Siang Cheah 11 months ago
parent
commit
a789b785b4
5 changed files with 1080 additions and 10 deletions
  1. 18 0
      .github/workflows/format-build-frontend.yaml
  2. 990 6
      package-lock.json
  3. 4 2
      package.json
  4. 2 2
      src/lib/constants.ts
  5. 66 0
      src/lib/utils/index.test.ts

+ 18 - 0
.github/workflows/format-build-frontend.yaml

@@ -37,3 +37,21 @@ jobs:
 
 
       - name: Build Frontend
       - name: Build Frontend
         run: npm run build
         run: npm run build
+
+  test-frontend:
+    name: 'Frontend Unit Tests'
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout Repository
+        uses: actions/checkout@v4
+
+      - name: Setup Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: '20'
+
+      - name: Install Dependencies
+        run: npm ci
+
+      - name: Run vitest
+        run: npm run test:frontend

File diff suppressed because it is too large
+ 990 - 6
package-lock.json


+ 4 - 2
package.json

@@ -15,7 +15,8 @@
 		"format": "prettier --plugin-search-dir --write '**/*.{js,ts,svelte,css,md,html,json}'",
 		"format": "prettier --plugin-search-dir --write '**/*.{js,ts,svelte,css,md,html,json}'",
 		"format:backend": "black . --exclude \"/venv/\"",
 		"format:backend": "black . --exclude \"/venv/\"",
 		"i18n:parse": "i18next --config i18next-parser.config.ts && prettier --write 'src/lib/i18n/**/*.{js,json}'",
 		"i18n:parse": "i18next --config i18next-parser.config.ts && prettier --write 'src/lib/i18n/**/*.{js,json}'",
-		"cy:open": "cypress open"
+		"cy:open": "cypress open",
+		"test:frontend": "vitest"
 	},
 	},
 	"devDependencies": {
 	"devDependencies": {
 		"@sveltejs/adapter-auto": "^2.0.0",
 		"@sveltejs/adapter-auto": "^2.0.0",
@@ -41,7 +42,8 @@
 		"tailwindcss": "^3.3.3",
 		"tailwindcss": "^3.3.3",
 		"tslib": "^2.4.1",
 		"tslib": "^2.4.1",
 		"typescript": "^5.0.0",
 		"typescript": "^5.0.0",
-		"vite": "^4.4.2"
+		"vite": "^4.4.2",
+		"vitest": "^1.6.0"
 	},
 	},
 	"type": "module",
 	"type": "module",
 	"dependencies": {
 	"dependencies": {

+ 2 - 2
src/lib/constants.ts

@@ -1,8 +1,8 @@
-import { dev } from '$app/environment';
+import { browser, dev } from '$app/environment';
 // import { version } from '../../package.json';
 // import { version } from '../../package.json';
 
 
 export const APP_NAME = 'Open WebUI';
 export const APP_NAME = 'Open WebUI';
-export const WEBUI_BASE_URL = dev ? `http://${location.hostname}:8080` : ``;
+export const WEBUI_BASE_URL = browser ? (dev ? `http://${location.hostname}:8080` : ``) : ``;
 
 
 export const WEBUI_API_BASE_URL = `${WEBUI_BASE_URL}/api/v1`;
 export const WEBUI_API_BASE_URL = `${WEBUI_BASE_URL}/api/v1`;
 
 

+ 66 - 0
src/lib/utils/index.test.ts

@@ -0,0 +1,66 @@
+import { promptTemplate } from '$lib/utils/index';
+import { expect, test } from 'vitest';
+
+test('promptTemplate correctly replaces {{prompt}} placeholder', () => {
+	const template = 'Hello {{prompt}}!';
+	const prompt = 'world';
+	const expected = 'Hello world!';
+	const actual = promptTemplate(template, prompt);
+	expect(actual).toBe(expected);
+});
+
+test('promptTemplate correctly replaces {{prompt:start:<length>}} placeholder', () => {
+	const template = 'Hello {{prompt:start:3}}!';
+	const prompt = 'world';
+	const expected = 'Hello wor!';
+	const actual = promptTemplate(template, prompt);
+	expect(actual).toBe(expected);
+});
+
+test('promptTemplate correctly replaces {{prompt:end:<length>}} placeholder', () => {
+	const template = 'Hello {{prompt:end:3}}!';
+	const prompt = 'world';
+	const expected = 'Hello rld!';
+	const actual = promptTemplate(template, prompt);
+	expect(actual).toBe(expected);
+});
+
+test('promptTemplate correctly replaces {{prompt:middletruncate:<length>}} placeholder when prompt length is greater than length', () => {
+	const template = 'Hello {{prompt:middletruncate:4}}!';
+	const prompt = 'world';
+	const expected = 'Hello wo...ld!';
+	const actual = promptTemplate(template, prompt);
+	expect(actual).toBe(expected);
+});
+
+test('promptTemplate correctly replaces {{prompt:middletruncate:<length>}} placeholder when prompt length is less than or equal to length', () => {
+	const template = 'Hello {{prompt:middletruncate:5}}!';
+	const prompt = 'world';
+	const expected = 'Hello world!';
+	const actual = promptTemplate(template, prompt);
+	expect(actual).toBe(expected);
+});
+
+test('promptTemplate returns original template when no placeholders are present', () => {
+	const template = 'Hello world!';
+	const prompt = 'world';
+	const expected = 'Hello world!';
+	const actual = promptTemplate(template, prompt);
+	expect(actual).toBe(expected);
+});
+
+test('promptTemplate does not replace placeholders inside of replaced placeholders', () => {
+	const template = 'Hello {{prompt}}!';
+	const prompt = 'World, {{prompt}} injection';
+	const expected = 'Hello World, {{prompt}} injection!';
+	const actual = promptTemplate(template, prompt);
+	expect(actual).toBe(expected);
+});
+
+test('promptTemplate correctly replaces multiple placeholders', () => {
+	const template = 'Hello {{prompt}}! This is {{prompt:start:3}}!';
+	const prompt = 'world';
+	const expected = 'Hello world! This is wor!';
+	const actual = promptTemplate(template, prompt);
+	expect(actual).toBe(expected);
+});

Some files were not shown because too many files changed in this diff