Added basic tests for testing a real websocket
This commit is contained in:
Vendored
+6
-6
@@ -1,8 +1,8 @@
|
||||
declare module 'app-env' {
|
||||
interface ENV {
|
||||
VITE_USE_HOST_NAME: boolean
|
||||
}
|
||||
declare module "app-env" {
|
||||
interface ENV {
|
||||
VITE_USE_HOST_NAME: boolean;
|
||||
}
|
||||
|
||||
const appEnv: ENV
|
||||
export default appEnv
|
||||
const appEnv: ENV;
|
||||
export default appEnv;
|
||||
}
|
||||
|
||||
+3
-1
@@ -25,6 +25,7 @@
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/three": "^0.180.0",
|
||||
"@types/ws": "^8.18.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
||||
"@typescript-eslint/parser": "^8.46.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
@@ -44,7 +45,8 @@
|
||||
"typescript-eslint": "^8.51.0",
|
||||
"unplugin-icons": "^22.4.2",
|
||||
"vite": "^7.1.9",
|
||||
"vitest": "^3.2.4"
|
||||
"vitest": "^3.2.4",
|
||||
"ws": "^8.18.3"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
Generated
+14
-3
@@ -87,6 +87,9 @@ importers:
|
||||
'@types/three':
|
||||
specifier: ^0.180.0
|
||||
version: 0.180.0
|
||||
'@types/ws':
|
||||
specifier: ^8.18.1
|
||||
version: 8.18.1
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
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)
|
||||
@@ -147,6 +150,9 @@ importers:
|
||||
vitest:
|
||||
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)
|
||||
ws:
|
||||
specifier: ^8.18.3
|
||||
version: 8.18.3
|
||||
|
||||
packages:
|
||||
|
||||
@@ -763,6 +769,9 @@ packages:
|
||||
'@types/webxr@0.5.24':
|
||||
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':
|
||||
resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
@@ -2720,7 +2729,6 @@ snapshots:
|
||||
'@types/node@24.7.1':
|
||||
dependencies:
|
||||
undici-types: 7.14.0
|
||||
optional: true
|
||||
|
||||
'@types/stats.js@0.17.4': {}
|
||||
|
||||
@@ -2736,6 +2744,10 @@ snapshots:
|
||||
|
||||
'@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)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
@@ -3999,8 +4011,7 @@ snapshots:
|
||||
|
||||
ufo@1.6.1: {}
|
||||
|
||||
undici-types@7.14.0:
|
||||
optional: true
|
||||
undici-types@7.14.0: {}
|
||||
|
||||
unplugin-icons@22.4.2(svelte@5.39.11):
|
||||
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 { svelte } from '@sveltejs/vite-plugin-svelte'
|
||||
import path from 'path'
|
||||
|
||||
const config: UserConfigExport = {
|
||||
plugins: [svelte()],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom'
|
||||
}
|
||||
plugins: [svelte()],
|
||||
resolve: {
|
||||
alias: {
|
||||
$lib: path.resolve(__dirname, './src/lib')
|
||||
}
|
||||
},
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom'
|
||||
}
|
||||
}
|
||||
export default defineConfig(config)
|
||||
|
||||
Reference in New Issue
Block a user