Added basic tests for testing a real websocket
This commit is contained in:
Vendored
+6
-6
@@ -1,8 +1,8 @@
|
|||||||
declare module 'app-env' {
|
declare module "app-env" {
|
||||||
interface ENV {
|
interface ENV {
|
||||||
VITE_USE_HOST_NAME: boolean
|
VITE_USE_HOST_NAME: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const appEnv: ENV
|
const appEnv: ENV;
|
||||||
export default appEnv
|
export default appEnv;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -25,6 +25,7 @@
|
|||||||
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
||||||
"@types/eslint": "^9.6.1",
|
"@types/eslint": "^9.6.1",
|
||||||
"@types/three": "^0.180.0",
|
"@types/three": "^0.180.0",
|
||||||
|
"@types/ws": "^8.18.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
||||||
"@typescript-eslint/parser": "^8.46.0",
|
"@typescript-eslint/parser": "^8.46.0",
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
@@ -44,7 +45,8 @@
|
|||||||
"typescript-eslint": "^8.51.0",
|
"typescript-eslint": "^8.51.0",
|
||||||
"unplugin-icons": "^22.4.2",
|
"unplugin-icons": "^22.4.2",
|
||||||
"vite": "^7.1.9",
|
"vite": "^7.1.9",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^3.2.4",
|
||||||
|
"ws": "^8.18.3"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
Generated
+14
-3
@@ -87,6 +87,9 @@ importers:
|
|||||||
'@types/three':
|
'@types/three':
|
||||||
specifier: ^0.180.0
|
specifier: ^0.180.0
|
||||||
version: 0.180.0
|
version: 0.180.0
|
||||||
|
'@types/ws':
|
||||||
|
specifier: ^8.18.1
|
||||||
|
version: 8.18.1
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ^8.46.0
|
specifier: ^8.46.0
|
||||||
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||||
@@ -147,6 +150,9 @@ importers:
|
|||||||
vitest:
|
vitest:
|
||||||
specifier: ^3.2.4
|
specifier: ^3.2.4
|
||||||
version: 3.2.4(@types/node@24.7.1)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(yaml@2.8.1)
|
version: 3.2.4(@types/node@24.7.1)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(yaml@2.8.1)
|
||||||
|
ws:
|
||||||
|
specifier: ^8.18.3
|
||||||
|
version: 8.18.3
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@@ -763,6 +769,9 @@ packages:
|
|||||||
'@types/webxr@0.5.24':
|
'@types/webxr@0.5.24':
|
||||||
resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==}
|
resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==}
|
||||||
|
|
||||||
|
'@types/ws@8.18.1':
|
||||||
|
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.46.0':
|
'@typescript-eslint/eslint-plugin@8.46.0':
|
||||||
resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==}
|
resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -2720,7 +2729,6 @@ snapshots:
|
|||||||
'@types/node@24.7.1':
|
'@types/node@24.7.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 7.14.0
|
undici-types: 7.14.0
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@types/stats.js@0.17.4': {}
|
'@types/stats.js@0.17.4': {}
|
||||||
|
|
||||||
@@ -2736,6 +2744,10 @@ snapshots:
|
|||||||
|
|
||||||
'@types/webxr@0.5.24': {}
|
'@types/webxr@0.5.24': {}
|
||||||
|
|
||||||
|
'@types/ws@8.18.1':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 24.7.1
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
'@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.12.1
|
'@eslint-community/regexpp': 4.12.1
|
||||||
@@ -3999,8 +4011,7 @@ snapshots:
|
|||||||
|
|
||||||
ufo@1.6.1: {}
|
ufo@1.6.1: {}
|
||||||
|
|
||||||
undici-types@7.14.0:
|
undici-types@7.14.0: {}
|
||||||
optional: true
|
|
||||||
|
|
||||||
unplugin-icons@22.4.2(svelte@5.39.11):
|
unplugin-icons@22.4.2(svelte@5.39.11):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
||||||
|
import { WebSocketServer } from 'ws'
|
||||||
|
import { socket } from '../../src/lib/stores/socket'
|
||||||
|
import { IMUData, RSSIData, WebsocketMessage } from '../../src/lib/platform_shared/websocket_message'
|
||||||
|
|
||||||
|
// Helper function to create encoded WebSocket messages
|
||||||
|
function createEncodedMessage(messageType: 'imu' | 'rssi' | 'mode', data: any): Uint8Array {
|
||||||
|
const message: any = {}
|
||||||
|
message[messageType] = data
|
||||||
|
const wsMessage = WebsocketMessage.create(message)
|
||||||
|
return WebsocketMessage.encode(wsMessage).finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
describe.sequential('WebSocket Integration Tests', () => {
|
||||||
|
let wss: WebSocketServer
|
||||||
|
let TEST_PORT = 8765
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
// Use a different port for each test to avoid conflicts
|
||||||
|
TEST_PORT++
|
||||||
|
|
||||||
|
// Create real WebSocket server
|
||||||
|
wss = new WebSocketServer({ port: TEST_PORT })
|
||||||
|
|
||||||
|
// Wait for server to start
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
wss.on('listening', () => resolve())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
// Close all connections and server
|
||||||
|
wss.clients.forEach((client) => client.close())
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
wss.close(() => resolve())
|
||||||
|
})
|
||||||
|
// Wait a bit for cleanup
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should connect to WebSocket server', async () => {
|
||||||
|
socket.init(`ws://localhost:${TEST_PORT}`)
|
||||||
|
|
||||||
|
// Wait for connection
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100))
|
||||||
|
|
||||||
|
let isConnected = false
|
||||||
|
socket.subscribe(value => {
|
||||||
|
isConnected = value
|
||||||
|
})()
|
||||||
|
|
||||||
|
expect(isConnected).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should receive and decode IMU data from server', async () => {
|
||||||
|
let receivedIMUData: any = null
|
||||||
|
|
||||||
|
// Subscribe to IMU messages before connecting
|
||||||
|
const unsubscribe = socket.on(IMUData, (data) => {
|
||||||
|
receivedIMUData = data
|
||||||
|
})
|
||||||
|
|
||||||
|
// Connect socket
|
||||||
|
socket.init(`ws://localhost:${TEST_PORT}`)
|
||||||
|
|
||||||
|
// Wait for client to connect
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
wss.on('connection', (ws) => {
|
||||||
|
// Server sends IMU data to client
|
||||||
|
const imuPayload = {
|
||||||
|
x: 1.5,
|
||||||
|
y: 2.5,
|
||||||
|
z: 3.5,
|
||||||
|
temp: 25.0
|
||||||
|
}
|
||||||
|
|
||||||
|
const encodedMessage = createEncodedMessage('imu', imuPayload)
|
||||||
|
ws.send(encodedMessage)
|
||||||
|
|
||||||
|
setTimeout(resolve, 50)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(receivedIMUData).toBeDefined()
|
||||||
|
expect(receivedIMUData.imu?.x).toBe(1.5)
|
||||||
|
expect(receivedIMUData.imu?.y).toBe(2.5)
|
||||||
|
expect(receivedIMUData.imu?.z).toBe(3.5)
|
||||||
|
expect(receivedIMUData.imu?.temp).toBe(25.0)
|
||||||
|
|
||||||
|
unsubscribe()
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('WebsocketMessage Protobuf Encoding/Decoding', () => {
|
||||||
|
it('should encode and decode IMU data correctly', () => {
|
||||||
|
const imuData = {
|
||||||
|
x: 1.5,
|
||||||
|
y: 2.5,
|
||||||
|
z: 3.5,
|
||||||
|
temp: 25.0
|
||||||
|
}
|
||||||
|
|
||||||
|
const encoded = IMUData.encode(imuData).finish()
|
||||||
|
const decoded = IMUData.decode(encoded)
|
||||||
|
|
||||||
|
expect(decoded.x).toBe(imuData.x)
|
||||||
|
expect(decoded.y).toBe(imuData.y)
|
||||||
|
expect(decoded.z).toBe(imuData.z)
|
||||||
|
expect(decoded.temp).toBe(imuData.temp)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
it('should encode and decode complete WebsocketMessage', () => {
|
||||||
|
const original = WebsocketMessage.create({
|
||||||
|
imu: {
|
||||||
|
x: 1.5,
|
||||||
|
y: 2.5,
|
||||||
|
z: 3.5,
|
||||||
|
temp: 25.0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const encoded = WebsocketMessage.encode(original).finish()
|
||||||
|
const decoded = WebsocketMessage.decode(encoded)
|
||||||
|
|
||||||
|
expect(decoded.imu).toBeDefined()
|
||||||
|
expect(decoded.imu?.x).toBe(1.5)
|
||||||
|
expect(decoded.imu?.y).toBe(2.5)
|
||||||
|
expect(decoded.imu?.z).toBe(3.5)
|
||||||
|
expect(decoded.imu?.temp).toBe(25.0)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
+11
-5
@@ -1,11 +1,17 @@
|
|||||||
import { defineConfig, UserConfigExport } from 'vitest/config'
|
import { defineConfig, UserConfigExport } from 'vitest/config'
|
||||||
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
const config: UserConfigExport = {
|
const config: UserConfigExport = {
|
||||||
plugins: [svelte()],
|
plugins: [svelte()],
|
||||||
test: {
|
resolve: {
|
||||||
globals: true,
|
alias: {
|
||||||
environment: 'jsdom'
|
$lib: path.resolve(__dirname, './src/lib')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: 'jsdom'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export default defineConfig(config)
|
export default defineConfig(config)
|
||||||
|
|||||||
Reference in New Issue
Block a user