Spaces:
Sleeping
Sleeping
/** | |
* Tests for Factory Functions - equivalent to Python's test_factory_functions.py | |
*/ | |
import { test, expect, describe, beforeEach, afterEach } from "bun:test"; | |
import { robotics } from "../src/index"; | |
import { TEST_SERVER_URL, TestRoomManager, MessageCollector, sleep } from "./setup"; | |
const { RoboticsProducer, RoboticsConsumer, createClient, createProducerClient, createConsumerClient } = robotics; | |
describe("Factory Functions", () => { | |
let roomManager: TestRoomManager; | |
beforeEach(() => { | |
roomManager = new TestRoomManager(); | |
}); | |
afterEach(async () => { | |
// Cleanup will be handled by individual tests | |
}); | |
test("create client producer", () => { | |
const client = createClient("producer", TEST_SERVER_URL); | |
expect(client).toBeInstanceOf(RoboticsProducer); | |
expect(client.isConnected()).toBe(false); | |
expect(client.getConnectionInfo().base_url).toBe("http://localhost:8000"); | |
}); | |
test("create client consumer", () => { | |
const client = createClient("consumer", TEST_SERVER_URL); | |
expect(client).toBeInstanceOf(RoboticsConsumer); | |
expect(client.isConnected()).toBe(false); | |
expect(client.getConnectionInfo().base_url).toBe("http://localhost:8000"); | |
}); | |
test("create client invalid role", () => { | |
expect(() => createClient("invalid_role" as any, TEST_SERVER_URL)).toThrow("Invalid role"); | |
}); | |
test("create client default url", () => { | |
const client = createClient("producer", TEST_SERVER_URL); | |
expect(client.getConnectionInfo().base_url).toBe("http://localhost:8000"); | |
}); | |
test("create producer client auto room", async () => { | |
const producer = await createProducerClient(TEST_SERVER_URL); | |
try { | |
expect(producer).toBeInstanceOf(RoboticsProducer); | |
expect(producer.isConnected()).toBe(true); | |
const info = producer.getConnectionInfo(); | |
expect(info.room_id).toBeTruthy(); | |
expect(info.workspace_id).toBeTruthy(); | |
expect(info.role).toBe("producer"); | |
// Should be able to send commands immediately | |
await producer.sendStateSync({ test: 123.0 }); | |
// Track for cleanup | |
roomManager.addRoom(info.workspace_id!, info.room_id!); | |
} finally { | |
await producer.disconnect(); | |
await roomManager.cleanup(producer); | |
} | |
}); | |
test("create producer client specific room", async () => { | |
// First create a room | |
const tempProducer = new RoboticsProducer(TEST_SERVER_URL); | |
const { workspaceId, roomId } = await tempProducer.createRoom(); | |
roomManager.addRoom(workspaceId, roomId); | |
try { | |
const producer = await createProducerClient(TEST_SERVER_URL, workspaceId, roomId); | |
expect(producer).toBeInstanceOf(RoboticsProducer); | |
expect(producer.isConnected()).toBe(true); | |
const info = producer.getConnectionInfo(); | |
expect(info.room_id).toBe(roomId); | |
expect(info.workspace_id).toBe(workspaceId); | |
expect(info.role).toBe("producer"); | |
await producer.disconnect(); | |
} finally { | |
await roomManager.cleanup(tempProducer); | |
} | |
}); | |
test("create consumer client", async () => { | |
// First create a room | |
const tempProducer = new RoboticsProducer(TEST_SERVER_URL); | |
const { workspaceId, roomId } = await tempProducer.createRoom(); | |
roomManager.addRoom(workspaceId, roomId); | |
try { | |
const consumer = await createConsumerClient(workspaceId, roomId, TEST_SERVER_URL); | |
expect(consumer).toBeInstanceOf(RoboticsConsumer); | |
expect(consumer.isConnected()).toBe(true); | |
const info = consumer.getConnectionInfo(); | |
expect(info.room_id).toBe(roomId); | |
expect(info.workspace_id).toBe(workspaceId); | |
expect(info.role).toBe("consumer"); | |
// Should be able to get state immediately | |
const state = await consumer.getStateSyncAsync(); | |
expect(typeof state).toBe("object"); | |
await consumer.disconnect(); | |
} finally { | |
await roomManager.cleanup(tempProducer); | |
} | |
}); | |
test("create producer consumer pair", async () => { | |
const producer = await createProducerClient(TEST_SERVER_URL); | |
const producerInfo = producer.getConnectionInfo(); | |
const workspaceId = producerInfo.workspace_id!; | |
const roomId = producerInfo.room_id!; | |
roomManager.addRoom(workspaceId, roomId); | |
try { | |
const consumer = await createConsumerClient(workspaceId, roomId, TEST_SERVER_URL); | |
// Both should be connected to same room | |
const consumerInfo = consumer.getConnectionInfo(); | |
expect(producerInfo.room_id).toBe(consumerInfo.room_id); | |
expect(producerInfo.workspace_id).toBe(consumerInfo.workspace_id); | |
expect(producer.isConnected()).toBe(true); | |
expect(consumer.isConnected()).toBe(true); | |
// Test communication | |
const updateCollector = new MessageCollector(1); | |
consumer.onJointUpdate(updateCollector.collect); | |
// Give some time for connection to stabilize | |
await sleep(100); | |
// Send update from producer | |
await producer.sendStateSync({ test_joint: 42.0 }); | |
// Wait for message | |
const receivedUpdates = await updateCollector.waitForMessages(2000); | |
// Consumer should have received update | |
expect(receivedUpdates.length).toBeGreaterThanOrEqual(1); | |
await consumer.disconnect(); | |
} finally { | |
await producer.disconnect(); | |
await roomManager.cleanup(producer); | |
} | |
}); | |
test("convenience functions with default url", async () => { | |
const producer = await createProducerClient(TEST_SERVER_URL); | |
const producerInfo = producer.getConnectionInfo(); | |
const workspaceId = producerInfo.workspace_id!; | |
const roomId = producerInfo.room_id!; | |
roomManager.addRoom(workspaceId, roomId); | |
try { | |
expect(producerInfo.base_url).toBe("http://localhost:8000"); | |
expect(producer.isConnected()).toBe(true); | |
const consumer = await createConsumerClient(workspaceId, roomId, TEST_SERVER_URL); | |
try { | |
const consumerInfo = consumer.getConnectionInfo(); | |
expect(consumerInfo.base_url).toBe("http://localhost:8000"); | |
expect(consumer.isConnected()).toBe(true); | |
} finally { | |
await consumer.disconnect(); | |
} | |
} finally { | |
await producer.disconnect(); | |
await roomManager.cleanup(producer); | |
} | |
}); | |
test("multiple convenience producers", async () => { | |
const producer1 = await createProducerClient(TEST_SERVER_URL); | |
const producer2 = await createProducerClient(TEST_SERVER_URL); | |
try { | |
const info1 = producer1.getConnectionInfo(); | |
const info2 = producer2.getConnectionInfo(); | |
// Both should be connected to different rooms | |
expect(info1.room_id).not.toBe(info2.room_id); | |
expect(producer1.isConnected()).toBe(true); | |
expect(producer2.isConnected()).toBe(true); | |
// Track for cleanup | |
roomManager.addRoom(info1.workspace_id!, info1.room_id!); | |
roomManager.addRoom(info2.workspace_id!, info2.room_id!); | |
// Both should work independently | |
await producer1.sendStateSync({ joint1: 10.0 }); | |
await producer2.sendStateSync({ joint2: 20.0 }); | |
} finally { | |
await producer1.disconnect(); | |
await producer2.disconnect(); | |
await roomManager.cleanup(producer1); | |
} | |
}); | |
test("create consumer nonexistent room", async () => { | |
const fakeWorkspaceId = "00000000-0000-0000-0000-000000000000"; | |
const fakeRoomId = "00000000-0000-0000-0000-000000000000"; | |
const consumer = new RoboticsConsumer(TEST_SERVER_URL); | |
const success = await consumer.connect(fakeWorkspaceId, fakeRoomId); | |
// Should fail to connect to non-existent room | |
expect(success).toBe(false); | |
expect(consumer.isConnected()).toBe(false); | |
}); | |
}); |