oficina / meet Public

Clone
git clone https://amadan.net/oficina/meet

Plain git — no account needed to clone.

Download

Download this file

1import CoreGraphics
2import Foundation
3import XCTest
4
5@testable import CallsKit
6
7/// 2026-10-05: a tile's placeholder centred in the whole tile, the stage
8/// filling the window under the filmstrip, a camera cropped with headroom,
9/// and the screen's backdrop.
10final class TileLayoutTests: XCTestCase {
11 // MARK: Placeholder
12
13 func testCentredInTheWholeTileWhenThereIsRoom() {
14 // A stage 600 tall, a 34 pt label block: centred, not above the label.
15 let top = PlaceholderPlacement.top(tile: 600, content: 80, reserve: 34)
16 XCTAssertEqual(top, 260)
17 XCTAssertEqual(top + 40, 300, "its middle is the tile's middle")
18 }
19
20 func testRisesOnlyAsFarAsTheLabelNeedsOnAShortTile() {
21 // The mini window at its smallest, 200 × 112.5, label block 44: a
22 // 34 pt symbol centred would end at 73.25, past the label's top less
23 // the gap (112.5 - 48 = 64.5), so it rises by 8.75 and no more.
24 let top = PlaceholderPlacement.top(tile: 112.5, content: 34, reserve: 44)
25 XCTAssertEqual(top + 34, 112.5 - 44 - PlaceholderPlacement.gap, accuracy: 0.001)
26 XCTAssertLessThan(top, (112.5 - 34) / 2)
27 XCTAssertEqual((112.5 - 34) / 2 - top, 8.75, accuracy: 0.001)
28 }
29
30 func testNeverAboveTheTop() {
31 XCTAssertEqual(PlaceholderPlacement.top(tile: 60, content: 50, reserve: 40), 0)
32 }
33
34 func testNoLabelIsPlainCentring() {
35 XCTAssertEqual(PlaceholderPlacement.top(tile: 100, content: 20, reserve: 0), 40)
36 XCTAssertEqual(PlaceholderPlacement.room(tile: 100, reserve: 0), 100)
37 }
38
39 func testRoomIsWhatChoosesTheWords() {
40 // At 200 wide the words and symbol (about 66 pt) do not fit above a
41 // 44 pt label in 112.5: the symbol stands alone.
42 XCTAssertLessThan(PlaceholderPlacement.room(tile: 112.5, reserve: 44), 66)
43 // At 320 (180 tall) they do.
44 XCTAssertGreaterThan(PlaceholderPlacement.room(tile: 180, reserve: 44), 66)
45 }
46
47 func testEveryMiniSizeKeepsTheSymbolClearOfTheLabelAndCentredWhereItCan() {
48 for width in [200.0, 320, 480] {
49 let tile = width * 9 / 16
50 let reserve: CGFloat = 44
51 let content: CGFloat = PlaceholderPlacement.room(tile: tile, reserve: reserve) >= 66 ? 66 : 34
52 let top = PlaceholderPlacement.top(tile: tile, content: content, reserve: reserve)
53 XCTAssertLessThanOrEqual(top + content, tile - reserve - PlaceholderPlacement.gap + 0.001, "\(width)")
54 let centred = (tile - content) / 2
55 if centred + content <= tile - reserve - PlaceholderPlacement.gap {
56 XCTAssertEqual(top, centred, accuracy: 0.001, "\(width): centred when it clears")
57 }
58 }
59 }
60
61 // MARK: The stage
62
63 func testStageLabelRidesAboveTheFilmstrip() {
64 // Controls showing: the filmstrip rises 72 for the bar; band 102.
65 XCTAssertEqual(StageLabel.lift(bar: 72, band: 102), 174)
66 // Hidden: just the band.
67 XCTAssertEqual(StageLabel.lift(bar: 0, band: 102), 102)
68 // A call of two: no filmstrip, the bar alone.
69 XCTAssertEqual(StageLabel.lift(bar: 72, band: 0), 72)
70 }
71
72 func testACameraFillsWithMoreCropFromTheBottom() {
73 // 16:9 into a 4:3 window: fills, crops sides evenly.
74 let wide = VideoFrame.place(video: CGSize(width: 1280, height: 720), in: CGSize(width: 800, height: 600), fit: false)
75 XCTAssertEqual(wide.height, 600, accuracy: 0.001)
76 XCTAssertEqual(wide.minX, -(wide.width - 800) / 2, accuracy: 0.001)
77 XCTAssertEqual(wide.minY, 0, accuracy: 0.001)
78 // 16:9 into a tall window: crops top and bottom, 35% from the top.
79 let tall = VideoFrame.place(video: CGSize(width: 1280, height: 720), in: CGSize(width: 1600, height: 600), fit: false)
80 let overflow = tall.height - 600
81 XCTAssertGreaterThan(overflow, 0)
82 XCTAssertEqual(-tall.minY, overflow * VideoFrame.headroom, accuracy: 0.001)
83 XCTAssertEqual(tall.maxY - 600, overflow * (1 - VideoFrame.headroom), accuracy: 0.001)
84 }
85
86 func testAScreenIsFittedWholeAndCentred() {
87 let r = VideoFrame.place(video: CGSize(width: 1920, height: 1200), in: CGSize(width: 1000, height: 1000), fit: true)
88 XCTAssertEqual(r.width, 1000, accuracy: 0.001)
89 XCTAssertEqual(r.minY, (1000 - r.height) / 2, accuracy: 0.001)
90 XCTAssertGreaterThanOrEqual(r.minY, 0)
91 }
92
93 // MARK: The screen's backdrop
94
95 func testBackdropPictureIsTheFramesColoursBlurred() throws {
96 // A 64 × 36 I420 frame: left half pure red, right half pure blue.
97 let (w, h) = (BackdropSampler.width, BackdropSampler.height)
98 var y = [UInt8](repeating: 0, count: w * h)
99 var u = [UInt8](repeating: 0, count: (w / 2) * (h / 2))
100 var v = [UInt8](repeating: 0, count: (w / 2) * (h / 2))
101 for row in 0..<h {
102 for col in 0..<w { y[row * w + col] = col < w / 2 ? 81 : 41 }
103 }
104 for row in 0..<(h / 2) {
105 for col in 0..<(w / 2) {
106 u[row * (w / 2) + col] = col < w / 4 ? 90 : 240
107 v[row * (w / 2) + col] = col < w / 4 ? 240 : 110
108 }
109 }
110 var rgba = y.withUnsafeBufferPointer { yp in
111 u.withUnsafeBufferPointer { up in
112 v.withUnsafeBufferPointer { vp in
113 BackdropSampler.rgbaFromI420(
114 width: w, height: h, y: yp.baseAddress!, strideY: w, u: up.baseAddress!, strideU: w / 2,
115 v: vp.baseAddress!, strideV: w / 2, outWidth: w, outHeight: h)
116 }
117 }
118 }
119 XCTAssertGreaterThan(rgba[0], 200, "red on the left")
120 XCTAssertGreaterThan(rgba[(w - 1) * 4 + 2], 200, "blue on the right")
121 let edge = (w / 2) * 4
122 let before = rgba[edge]
123 BackdropSampler.boxBlur(&rgba, width: w, height: h, radius: 3, passes: 2)
124 XCTAssertLessThan(rgba[edge], before == 0 ? 255 : 255, "blurred")
125 XCTAssertGreaterThan(rgba[edge + 2], 40, "blue has bled across the edge")
126 XCTAssertGreaterThan(rgba[edge], 40, "and red")
127 XCTAssertNotNil(BackdropSampler.image(rgba, width: w, height: h))
128 _ = try XCTUnwrap(rgba.last)
129 }
130
131 func testBackdropWorkIsCheap() {
132 // What happens twice a second for a screen on the stage, after
133 // WebRTC's own scale to 64 × 36: conversion, blur and the CGImage.
134 let (w, h) = (BackdropSampler.width, BackdropSampler.height)
135 let y = [UInt8](repeating: 120, count: w * h)
136 let c = [UInt8](repeating: 128, count: (w / 2) * (h / 2))
137 let runs = 50
138 let start = Date()
139 for _ in 0..<runs {
140 var rgba = y.withUnsafeBufferPointer { yp in
141 c.withUnsafeBufferPointer { cp in
142 BackdropSampler.rgbaFromI420(
143 width: w, height: h, y: yp.baseAddress!, strideY: w, u: cp.baseAddress!, strideU: w / 2,
144 v: cp.baseAddress!, strideV: w / 2, outWidth: w, outHeight: h)
145 }
146 }
147 BackdropSampler.boxBlur(&rgba, width: w, height: h, radius: 3, passes: 2)
148 _ = BackdropSampler.image(rgba, width: w, height: h)
149 }
150 let each = Date().timeIntervalSince(start) / Double(runs) * 1000
151 print("backdrop: \(String(format: "%.3f", each)) ms a picture, twice a second")
152 // A debug build; release is several times quicker. Well under a frame.
153 XCTAssertLessThan(each, 8)
154 }
155}
156