@@ -100,6 +100,93 @@ final class ColorParseTests {
100100 }
101101}
102102
103+ final class BellStyleTests {
104+ @Test func tagNameRoundTrips ( ) {
105+ for style in BellStyle . allCases {
106+ #expect ( BellStyle ( tagName: style. tagName) == style)
107+ }
108+ #expect ( BellStyle ( tagName: " kazoo " ) == nil )
109+ }
110+ }
111+
112+ @MainActor
113+ final class BellDispatchTests {
114+ final class CountingDelegate : TerminalViewDelegate {
115+ var bells = 0
116+ func sizeChanged ( source: TerminalView , newCols: Int , newRows: Int ) { }
117+ func setTerminalTitle ( source: TerminalView , title: String ) { }
118+ func hostCurrentDirectoryUpdate ( source: TerminalView , directory: String ? ) { }
119+ func send ( source: TerminalView , data: ArraySlice < UInt8 > ) { }
120+ func scrolled ( source: TerminalView , position: Double ) { }
121+ func rangeChanged ( source: TerminalView , startY: Int , endY: Int ) { }
122+ func requestOpenLink ( source: TerminalView , link: String , params: [ String : String ] ) { }
123+ func clipboardCopy ( source: TerminalView , content: Data ) { }
124+ func bell ( source: TerminalView ) {
125+ bells += 1
126+ }
127+ }
128+
129+ @Test func bellStyleGatesDelegate ( ) {
130+ let view = TerminalView ( frame: CGRect ( x: 0 , y: 0 , width: 400 , height: 300 ) )
131+ let delegate = CountingDelegate ( )
132+ view. terminalDelegate = delegate
133+
134+ view. bellStyle = . sound
135+ view. bell ( source: view. getTerminal ( ) )
136+ #expect ( delegate. bells == 1 )
137+
138+ view. bellStyle = . none
139+ view. bell ( source: view. getTerminal ( ) )
140+ #expect ( delegate. bells == 1 )
141+
142+ view. bellStyle = . visual
143+ view. bell ( source: view. getTerminal ( ) )
144+ #expect ( delegate. bells == 1 )
145+
146+ view. bellStyle = . soundAndVisual
147+ view. bell ( source: view. getTerminal ( ) )
148+ #expect ( delegate. bells == 2 )
149+ }
150+ }
151+
152+ final class ClearScrollbackTests {
153+ class DummyDelegate : TerminalDelegate {
154+ func send ( source: Terminal , data: ArraySlice < UInt8 > ) { }
155+ }
156+
157+ @Test func clearScrollbackDropsHistoryKeepsScreen ( ) {
158+ let terminal = Terminal ( delegate: DummyDelegate ( ) ,
159+ options: TerminalOptions ( cols: 20 , rows: 5 , scrollback: 100 ) )
160+ for i in 0 ..< 30 {
161+ terminal. feed ( text: " line \( i) \r \n " )
162+ }
163+ let buffer = terminal. buffer
164+ #expect ( buffer. yBase > 0 )
165+ let visibleBefore = terminal. getText (
166+ start: Position ( col: 0 , row: buffer. yBase) ,
167+ end: Position ( col: 19 , row: buffer. yBase) )
168+
169+ terminal. clearScrollback ( )
170+ #expect ( buffer. yBase == 0 )
171+ #expect ( buffer. yDisp == 0 )
172+ let visibleAfter = terminal. getText (
173+ start: Position ( col: 0 , row: 0 ) ,
174+ end: Position ( col: 19 , row: 0 ) )
175+ #expect ( visibleAfter == visibleBefore)
176+ }
177+
178+ @Test func clearScrollbackOnEmptyBufferIsANoop ( ) {
179+ let terminal = Terminal ( delegate: DummyDelegate ( ) ,
180+ options: TerminalOptions ( cols: 20 , rows: 5 , scrollback: 100 ) )
181+ terminal. feed ( text: " hello " )
182+ terminal. clearScrollback ( )
183+ #expect ( terminal. buffer. yBase == 0 )
184+ let text = terminal. getText ( start: Position ( col: 0 , row: 0 ) ,
185+ end: Position ( col: 5 , row: 0 ) )
186+ #expect ( text == " hello " )
187+ }
188+ }
189+
103190@MainActor
104191final class TerminalViewOptionsTests {
105192 @Test func startupOptionsReachTheTerminal ( ) {
0 commit comments