You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
3.0 KiB
73 lines
3.0 KiB
import CoreVideo
|
|
import Foundation
|
|
import Testing
|
|
@testable import Intercom
|
|
|
|
@Suite struct MediaTests {
|
|
@Test func opusEncodesTwentyMillisecondPackets() throws {
|
|
let encoder = try #require(TalkbackEncoder())
|
|
let tone = (0..<4800).map { Float(sin(Double($0) * 2 * .pi * 440 / 48_000) * 0.3) }
|
|
let packets = tone.withUnsafeBufferPointer { encoder.append($0) }
|
|
#expect(packets.count == 5)
|
|
#expect(packets.allSatisfy { !$0.0.isEmpty && $0.0.count < 400 })
|
|
let steps = zip(packets.dropFirst(), packets).map { $0.1 &- $1.1 }
|
|
#expect(steps.allSatisfy { $0 == 960 })
|
|
}
|
|
|
|
@Test(.timeLimit(.minutes(1))) func previewStartsWithParameterSetsAndKeyFrame() async throws {
|
|
let encoder = PreviewEncoder(width: 320, height: 180)
|
|
let received = Received()
|
|
encoder.onAccessUnit = { nalUnits, _ in received.add(nalUnits) }
|
|
|
|
var buffer: CVPixelBuffer?
|
|
CVPixelBufferCreate(nil, 1280, 720, kCVPixelFormatType_32BGRA,
|
|
[kCVPixelBufferIOSurfacePropertiesKey: [:]] as CFDictionary, &buffer)
|
|
let frame = try #require(buffer)
|
|
for _ in 0..<20 where received.first == nil {
|
|
encoder.encode(frame)
|
|
try await Task.sleep(for: .milliseconds(50))
|
|
}
|
|
let nalUnits = try #require(received.first)
|
|
let types = nalUnits.map { $0[0] & 0x1F }
|
|
#expect(types.prefix(2) == [7, 8]) // SPS, PPS
|
|
#expect(types.contains(5)) // IDR
|
|
// Constrained baseline: profile_idc 66, constraint_set1 flag.
|
|
#expect(nalUnits[0][1] == 66)
|
|
#expect(nalUnits[0][2] & 0x40 != 0)
|
|
}
|
|
|
|
private final class Received: @unchecked Sendable {
|
|
private let lock = NSLock()
|
|
private var units: [[[UInt8]]] = []
|
|
func add(_ nalUnits: [[UInt8]]) { lock.withLock { units.append(nalUnits) } }
|
|
var first: [[UInt8]]? { lock.withLock { units.first } }
|
|
}
|
|
}
|
|
|
|
@Suite struct HTTPTests {
|
|
@Test func parsesRequestAcrossChunks() throws {
|
|
var parser = HTTPRequestParser()
|
|
let raw = Array("POST /api/offer?x=1 HTTP/1.1\r\nHost: musubi\r\nContent-Length: 11\r\n\r\n{\"a\":\"bcd\"}".utf8)
|
|
#expect(try parser.append(Array(raw[0..<30])) == nil)
|
|
let request = try #require(try parser.append(Array(raw[30...])))
|
|
#expect(request.method == "POST")
|
|
#expect(request.path == "/api/offer")
|
|
#expect(request.headers["host"] == "musubi")
|
|
#expect(request.body == Array("{\"a\":\"bcd\"}".utf8))
|
|
}
|
|
|
|
@Test func rejectsOversizedBody() {
|
|
var parser = HTTPRequestParser()
|
|
#expect(throws: HTTPRequestParser.ParseError.self) {
|
|
try parser.append(Array("POST / HTTP/1.1\r\nContent-Length: 999999\r\n\r\n".utf8))
|
|
}
|
|
}
|
|
|
|
@Test func serializesResponse() {
|
|
let text = String(decoding: HTTPResponse.text(404, "Nicht gefunden.").serialized, as: UTF8.self)
|
|
#expect(text.hasPrefix("HTTP/1.1 404 Not Found\r\n"))
|
|
#expect(text.contains("Content-Length: 15\r\n"))
|
|
#expect(text.hasSuffix("\r\n\r\nNicht gefunden."))
|
|
}
|
|
}
|