Skip to content

Commit 9ff3fed

Browse files
committed
Transcription tests
1 parent bb5c0b9 commit 9ff3fed

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/*
2+
* Copyright 2025 LiveKit
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
@testable import LiveKit
18+
import OrderedCollections
19+
import XCTest
20+
21+
actor MessageCollector {
22+
private var updates: [ReceivedMessage] = []
23+
private var messages: OrderedDictionary<ReceivedMessage.ID, ReceivedMessage> = [:]
24+
25+
func add(_ message: ReceivedMessage) {
26+
updates.append(message)
27+
messages[message.id] = message
28+
}
29+
30+
func getUpdates() -> [ReceivedMessage] {
31+
updates
32+
}
33+
34+
func getMessages() -> OrderedDictionary<ReceivedMessage.ID, ReceivedMessage> {
35+
messages
36+
}
37+
}
38+
39+
class TranscriptionTests: LKTestCase, @unchecked Sendable {
40+
// Same segment, same stream
41+
func testUpdates() async throws {
42+
let messageExpectation = expectation(description: "Receives all message updates")
43+
messageExpectation.expectedFulfillmentCount = 3
44+
45+
let segmentID = "test-segment"
46+
let topic = "lk.transcription"
47+
48+
let testChunks = ["Hey", " there!", " What's up?"]
49+
50+
try await withRooms([
51+
RoomTestingOptions(canSubscribe: true),
52+
RoomTestingOptions(canPublishData: true),
53+
]) { rooms in
54+
let receiverRoom = rooms[0]
55+
let senderRoom = rooms[1]
56+
57+
let receiver = TranscriptionStreamReceiver(room: receiverRoom)
58+
let messageStream = try await receiver.messages()
59+
let streamID = UUID().uuidString
60+
61+
let messageCollector = MessageCollector()
62+
63+
let collectionTask = Task { @Sendable in
64+
var iterator = messageStream.makeAsyncIterator()
65+
while let message = await iterator.next() {
66+
await messageCollector.add(message)
67+
messageExpectation.fulfill()
68+
}
69+
}
70+
71+
for (index, chunk) in testChunks.enumerated() {
72+
let isLast = index == testChunks.count - 1
73+
74+
var attributes: [String: String] = [
75+
"lk.segment_id": segmentID,
76+
"lk.transcription_final": "false",
77+
]
78+
79+
if isLast {
80+
attributes["lk.transcription_final"] = "true"
81+
}
82+
83+
let options = StreamTextOptions(
84+
topic: topic,
85+
attributes: attributes,
86+
id: streamID
87+
)
88+
89+
try await senderRoom.localParticipant.sendText(chunk, options: options)
90+
try await Task.sleep(nanoseconds: 10_000_000)
91+
}
92+
93+
await self.fulfillment(of: [messageExpectation], timeout: 5)
94+
collectionTask.cancel()
95+
96+
let updates = await messageCollector.getUpdates()
97+
XCTAssertEqual(updates.count, 3)
98+
XCTAssertEqual(updates[0].content, .agentTranscript("Hey"))
99+
XCTAssertEqual(updates[1].content, .agentTranscript("Hey there!"))
100+
XCTAssertEqual(updates[2].content, .agentTranscript("Hey there! What's up?"))
101+
102+
XCTAssertEqual(updates[0].id, segmentID)
103+
XCTAssertEqual(updates[1].id, segmentID)
104+
XCTAssertEqual(updates[2].id, segmentID)
105+
106+
let firstTimestamp = updates[0].timestamp
107+
XCTAssertEqual(updates[1].timestamp, firstTimestamp)
108+
XCTAssertEqual(updates[2].timestamp, firstTimestamp)
109+
110+
let messages = await messageCollector.getMessages()
111+
XCTAssertEqual(messages.count, 1)
112+
XCTAssertEqual(messages.keys[0], segmentID)
113+
XCTAssertEqual(messages.values[0].content, .agentTranscript("Hey there! What's up?"))
114+
XCTAssertEqual(messages.values[0].id, segmentID)
115+
XCTAssertEqual(messages.values[0].timestamp, firstTimestamp)
116+
}
117+
}
118+
119+
// Same segment, different stream
120+
func testReplace() async throws {
121+
let messageExpectation = expectation(description: "Receives all message updates")
122+
messageExpectation.expectedFulfillmentCount = 3
123+
124+
let segmentID = "test-segment"
125+
let topic = "lk.transcription"
126+
127+
let testChunks = ["Hey", "Hey there!", "Hey there! What's up?"]
128+
129+
try await withRooms([
130+
RoomTestingOptions(canSubscribe: true),
131+
RoomTestingOptions(canPublishData: true),
132+
]) { rooms in
133+
let receiverRoom = rooms[0]
134+
let senderRoom = rooms[1]
135+
136+
let receiver = TranscriptionStreamReceiver(room: receiverRoom)
137+
let messageStream = try await receiver.messages()
138+
139+
let messageCollector = MessageCollector()
140+
141+
let collectionTask = Task { @Sendable in
142+
var iterator = messageStream.makeAsyncIterator()
143+
while let message = await iterator.next() {
144+
await messageCollector.add(message)
145+
messageExpectation.fulfill()
146+
}
147+
}
148+
149+
for (index, chunk) in testChunks.enumerated() {
150+
let isLast = index == testChunks.count - 1
151+
152+
var attributes: [String: String] = [
153+
"lk.segment_id": segmentID,
154+
"lk.transcription_final": "false",
155+
]
156+
157+
if isLast {
158+
attributes["lk.transcription_final"] = "true"
159+
}
160+
161+
let options = StreamTextOptions(
162+
topic: topic,
163+
attributes: attributes,
164+
id: UUID().uuidString
165+
)
166+
167+
try await senderRoom.localParticipant.sendText(chunk, options: options)
168+
try await Task.sleep(nanoseconds: 10_000_000)
169+
}
170+
171+
await self.fulfillment(of: [messageExpectation], timeout: 5)
172+
collectionTask.cancel()
173+
174+
let updates = await messageCollector.getUpdates()
175+
XCTAssertEqual(updates.count, 3)
176+
XCTAssertEqual(updates[0].content, .agentTranscript("Hey"))
177+
XCTAssertEqual(updates[1].content, .agentTranscript("Hey there!"))
178+
XCTAssertEqual(updates[2].content, .agentTranscript("Hey there! What's up?"))
179+
180+
XCTAssertEqual(updates[0].id, segmentID)
181+
XCTAssertEqual(updates[1].id, segmentID)
182+
XCTAssertEqual(updates[2].id, segmentID)
183+
184+
let firstTimestamp = updates[0].timestamp
185+
XCTAssertEqual(updates[1].timestamp, firstTimestamp)
186+
XCTAssertEqual(updates[2].timestamp, firstTimestamp)
187+
188+
let messages = await messageCollector.getMessages()
189+
XCTAssertEqual(messages.count, 1)
190+
XCTAssertEqual(messages.keys[0], segmentID)
191+
XCTAssertEqual(messages.values[0].content, .agentTranscript("Hey there! What's up?"))
192+
XCTAssertEqual(messages.values[0].id, segmentID)
193+
XCTAssertEqual(messages.values[0].timestamp, firstTimestamp)
194+
}
195+
}
196+
}

0 commit comments

Comments
 (0)