Spaces:
Running
Running
feat(web): added testing structure
Browse files
packages/web/package.json
CHANGED
@@ -36,7 +36,17 @@
|
|
36 |
],
|
37 |
"scripts": {
|
38 |
"build": "tsc --project tsconfig.build.json",
|
39 |
-
"prepublishOnly": "npm run build"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
},
|
41 |
"peerDependencies": {
|
42 |
"typescript": ">=4.5.0"
|
|
|
36 |
],
|
37 |
"scripts": {
|
38 |
"build": "tsc --project tsconfig.build.json",
|
39 |
+
"prepublishOnly": "npm run build",
|
40 |
+
"dev": "vitest --watch",
|
41 |
+
"test": "vitest run",
|
42 |
+
"test:ui": "vitest --ui",
|
43 |
+
"test:coverage": "vitest run --coverage"
|
44 |
+
},
|
45 |
+
"devDependencies": {
|
46 |
+
"vitest": "^2.0.0",
|
47 |
+
"@vitest/ui": "^2.0.0",
|
48 |
+
"jsdom": "^24.0.0",
|
49 |
+
"vite": "^6.3.5"
|
50 |
},
|
51 |
"peerDependencies": {
|
52 |
"typescript": ">=4.5.0"
|
packages/web/tests/setup.ts
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { vi } from "vitest";
|
2 |
+
|
3 |
+
// Mock Web Serial API
|
4 |
+
const mockSerialPort = {
|
5 |
+
readable: new ReadableStream(),
|
6 |
+
writable: new WritableStream(),
|
7 |
+
close: vi.fn(),
|
8 |
+
forget: vi.fn(),
|
9 |
+
getInfo: vi.fn(() => ({ usbVendorId: 0x1234, usbProductId: 0x5678 })),
|
10 |
+
};
|
11 |
+
|
12 |
+
const mockSerial = {
|
13 |
+
requestPort: vi.fn(() => Promise.resolve(mockSerialPort)),
|
14 |
+
getPorts: vi.fn(() => Promise.resolve([mockSerialPort])),
|
15 |
+
};
|
16 |
+
|
17 |
+
// Mock WebUSB API
|
18 |
+
const mockUSB = {
|
19 |
+
requestDevice: vi.fn(),
|
20 |
+
getDevices: vi.fn(() => Promise.resolve([])),
|
21 |
+
};
|
22 |
+
|
23 |
+
// Attach to global navigator
|
24 |
+
Object.defineProperty(globalThis, "navigator", {
|
25 |
+
value: {
|
26 |
+
...globalThis.navigator,
|
27 |
+
serial: mockSerial,
|
28 |
+
usb: mockUSB,
|
29 |
+
},
|
30 |
+
});
|
packages/web/tests/utils/browser-support.test.ts
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { describe, it, expect } from "vitest";
|
2 |
+
import {
|
3 |
+
isWebSerialSupported,
|
4 |
+
isWebUSBSupported,
|
5 |
+
} from "../../src/utils/browser-support.js";
|
6 |
+
|
7 |
+
describe("browser-support", () => {
|
8 |
+
it("should detect Web Serial API support", () => {
|
9 |
+
expect(isWebSerialSupported()).toBe(true);
|
10 |
+
});
|
11 |
+
|
12 |
+
it("should detect WebUSB API support", () => {
|
13 |
+
expect(isWebUSBSupported()).toBe(true);
|
14 |
+
});
|
15 |
+
|
16 |
+
it("should handle missing Web Serial API gracefully", () => {
|
17 |
+
const originalSerial = globalThis.navigator.serial;
|
18 |
+
delete (globalThis.navigator as any).serial;
|
19 |
+
|
20 |
+
expect(isWebSerialSupported()).toBe(false);
|
21 |
+
|
22 |
+
// Restore
|
23 |
+
globalThis.navigator.serial = originalSerial;
|
24 |
+
});
|
25 |
+
|
26 |
+
it("should handle missing WebUSB API gracefully", () => {
|
27 |
+
const originalUSB = globalThis.navigator.usb;
|
28 |
+
delete (globalThis.navigator as any).usb;
|
29 |
+
|
30 |
+
expect(isWebUSBSupported()).toBe(false);
|
31 |
+
|
32 |
+
// Restore
|
33 |
+
globalThis.navigator.usb = originalUSB;
|
34 |
+
});
|
35 |
+
});
|
packages/web/tests/utils/sign-magnitude.test.ts
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { describe, it, expect } from "vitest";
|
2 |
+
import {
|
3 |
+
encodeSignMagnitude,
|
4 |
+
decodeSignMagnitude,
|
5 |
+
} from "../../src/utils/sign-magnitude.js";
|
6 |
+
|
7 |
+
describe("sign-magnitude encoding", () => {
|
8 |
+
it("should encode positive values correctly", () => {
|
9 |
+
expect(encodeSignMagnitude(100)).toBe(100);
|
10 |
+
expect(encodeSignMagnitude(2047)).toBe(2047);
|
11 |
+
expect(encodeSignMagnitude(0)).toBe(0);
|
12 |
+
});
|
13 |
+
|
14 |
+
it("should encode negative values correctly", () => {
|
15 |
+
expect(encodeSignMagnitude(-100)).toBe(0x800 | 100); // Set sign bit (bit 11)
|
16 |
+
expect(encodeSignMagnitude(-2047)).toBe(0x800 | 2047);
|
17 |
+
expect(encodeSignMagnitude(-1)).toBe(0x800 | 1);
|
18 |
+
});
|
19 |
+
|
20 |
+
it("should decode back to original values", () => {
|
21 |
+
const testValues = [0, 1, 100, -100, 2047, -2047, -1];
|
22 |
+
|
23 |
+
testValues.forEach((value) => {
|
24 |
+
const encoded = encodeSignMagnitude(value);
|
25 |
+
const decoded = decodeSignMagnitude(encoded);
|
26 |
+
expect(decoded).toBe(value);
|
27 |
+
});
|
28 |
+
});
|
29 |
+
|
30 |
+
it("should throw on magnitude overflow", () => {
|
31 |
+
expect(() => encodeSignMagnitude(2048)).toThrow();
|
32 |
+
expect(() => encodeSignMagnitude(-2048)).toThrow();
|
33 |
+
});
|
34 |
+
|
35 |
+
it("should handle edge cases", () => {
|
36 |
+
// Test maximum positive value
|
37 |
+
expect(encodeSignMagnitude(2047)).toBe(2047);
|
38 |
+
expect(decodeSignMagnitude(2047)).toBe(2047);
|
39 |
+
|
40 |
+
// Test maximum negative value
|
41 |
+
expect(encodeSignMagnitude(-2047)).toBe(0x800 | 2047);
|
42 |
+
expect(decodeSignMagnitude(0x800 | 2047)).toBe(-2047);
|
43 |
+
});
|
44 |
+
});
|
packages/web/vite.config.ts
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { defineConfig } from "vitest/config";
|
2 |
+
|
3 |
+
export default defineConfig({
|
4 |
+
test: {
|
5 |
+
environment: "jsdom",
|
6 |
+
globals: true,
|
7 |
+
setupFiles: ["./tests/setup.ts"],
|
8 |
+
},
|
9 |
+
build: {
|
10 |
+
lib: {
|
11 |
+
entry: "./src/index.ts",
|
12 |
+
formats: ["es"],
|
13 |
+
},
|
14 |
+
rollupOptions: {
|
15 |
+
external: ["typescript"],
|
16 |
+
},
|
17 |
+
},
|
18 |
+
});
|