Class: Tuile::FakeScreen
- Defined in:
- lib/tuile/fake_screen.rb,
sig/tuile.rbs
Overview
Testing only — a screen which doesn't paint anything, so the TTY running the tests is not painted over. It runs no event loop, so Screen#check_locked admits the thread that called Screen.fake: a spec mutating the UI from a spawned thread raises, exactly as an app would.
Intended for unit-testing individual components: instantiate a component,
mutate it, and assert against #prints or #invalidated?. It does not
run an event loop, so it is not suitable for system-testing whole apps
— for that, drive the real script through a PTY (see spec/examples/).
Call Screen.fake to initialize the fake screen easily. Typical usage:
before { Screen.fake }
after { Screen.close }
it "paints its content" do
label = Component::Label.new.tap { |l| l.text = "hi" }
Screen.instance.content = Component::Window.new("Greeting").tap { |w| w.content = label }
Screen.instance.repaint
assert_includes Screen.instance.prints.join, "hi"
end
Constant Summary collapse
- EDITING_KEYS =
Instance Attribute Summary collapse
- #prints ⇒ ::Array[String] readonly
Attributes inherited from Screen
#background_color, #buffer, #color_depth, #color_scheme, #event_queue, #focused, #on_error, #on_focus_changed, #pane, #size, #theme, #theme_def
Instance Method Summary collapse
-
#background_color=(color) ⇒ void
Plays the terminal answering the OSC 11 re-probe, so a spec can exercise app code that derives colors from Screen#background_color:.
- #clear ⇒ void
-
#detect_background ⇒ TerminalBackground::Result
No terminal probing in tests: skip TerminalBackground.detect (which would write an OSC 11 query to the test runner's TTY and steal its input) and pin the deterministic default.
-
#detect_color_depth ⇒ Symbol
Pins the depth rather than reading the test runner's environment, so a spec asserting flushed bytes gets the same answer on a truecolor terminal, under
TERM=dumbin CI, and inside tmux. -
#emit(str) ⇒ void
Captures the assembled repaint frame instead of writing to the test runner's TTY.
-
#initialize ⇒ FakeScreen
constructor
A new instance of FakeScreen.
-
#invalidated?(component) ⇒ Boolean
@param
component— the component to check. - #invalidated_clear ⇒ void
-
#paste(text) ⇒ Boolean
Pastes
textinto the focused component, as a real terminal would with bracketed paste on:. -
#print(*args) ⇒ void
Doesn't print anything: collects all strings in #prints.
Methods inherited from Screen
#add_popup, #beep, #check_locked, #close, close, #content, #content=, #cursor_position, #cursor_sequence, #cycle_focus, #event_loop, fake, #focus_next, #focus_previous, #handle_key, #handle_mouse, #handle_paste, #has_popup?, instance, #invalidate, #layout, #needs_full_repaint, #on_background_color, #on_color_scheme, #popups, #register_global_shortcut, #remove_popup, #repaint, #run_event_loop, #state, #unregister_global_shortcut
Constructor Details
#initialize ⇒ FakeScreen
Returns a new instance of FakeScreen.
26 27 28 29 30 31 32 |
# File 'lib/tuile/fake_screen.rb', line 26 def initialize super @event_queue = FakeEventQueue.new @size = Size.new(160, 50) @buffer.resize(@size) # super sized it to the test runner's TTY @prints = [] end |
Instance Attribute Details
#prints ⇒ ::Array[String] (readonly)
@return — whatever #print / #emit produced so far.
Component painting lands in Screen#buffer, not here — assert on
Buffer#row_text / Buffer#row_ansi / Buffer#cell for content, and
on prints for cursor and housekeeping escapes.
38 39 40 |
# File 'lib/tuile/fake_screen.rb', line 38 def prints @prints end |
Instance Method Details
#background_color=(color) ⇒ void
This method returns an undefined value.
Plays the terminal answering the OSC 11 re-probe, so a spec can exercise app code that derives colors from Screen#background_color:
Screen.instance.background_color = Color.rgb(30, 30, 46)
Takes the same path a real reply does — a changed color fires Component#on_theme_changed across the tree and invalidates it. There is no such writer on Screen: the value is a report from the terminal, not a setting.
@param color
95 96 97 |
# File 'lib/tuile/fake_screen.rb', line 95 def background_color=(color) on_background_color(color) end |
#clear ⇒ void
This method returns an undefined value.
41 42 43 |
# File 'lib/tuile/fake_screen.rb', line 41 def clear @prints.clear end |
#detect_background ⇒ TerminalBackground::Result
No terminal probing in tests: skip TerminalBackground.detect (which would write an OSC 11 query to the test runner's TTY and steal its input) and pin the deterministic default. The color is nil — the case every app must handle anyway — until a spec assigns one through #background_color=.
107 |
# File 'lib/tuile/fake_screen.rb', line 107 def detect_background = TerminalBackground::Result.new(scheme: :dark, color: nil) |
#detect_color_depth ⇒ Symbol
Pins the depth rather than reading the test runner's environment, so a
spec asserting flushed bytes gets the same answer on a truecolor
terminal, under TERM=dumb in CI, and inside tmux. A spec exercising
degradation builds its own Buffer with the depth it wants.
114 |
# File 'lib/tuile/fake_screen.rb', line 114 def detect_color_depth = :truecolor |
#emit(str) ⇒ void
This method returns an undefined value.
Captures the assembled repaint frame instead of writing to the test runner's TTY. Lands in #prints so cursor/sync escapes can be asserted; painted content is read from Screen#buffer.
@param str
57 58 59 |
# File 'lib/tuile/fake_screen.rb', line 57 def emit(str) @prints << str end |
#invalidated?(component) ⇒ Boolean
@param component — the component to check.
77 |
# File 'lib/tuile/fake_screen.rb', line 77 def invalidated?(component) = @invalidated.include?(component) |
#invalidated_clear ⇒ void
This method returns an undefined value.
80 81 82 |
# File 'lib/tuile/fake_screen.rb', line 80 def invalidated_clear @invalidated.clear end |
#paste(text) ⇒ Boolean
Pastes text into the focused component, as a real terminal would with
bracketed paste on:
area.focus
Screen.instance.paste("one\r\ntwo")
area.text # => "one\ntwo" — one mutation, no ENTER anywhere
Goes through Keys.normalize_paste first, so a spec can hand it the
CR-flavored line endings terminals actually deliver and still assert
against \n.
@param text
@return — true if some component consumed it.
73 |
# File 'lib/tuile/fake_screen.rb', line 73 def paste(text) = handle_paste(Keys.normalize_paste(text)) |
#print(*args) ⇒ void
This method returns an undefined value.
Doesn't print anything: collects all strings in #prints.
@param args
48 49 50 |
# File 'lib/tuile/fake_screen.rb', line 48 def print(*args) @prints += args end |