Class: TUITD::Snapshot

Inherits:
Object
  • Object
show all
Defined in:
lib/tui_td/snapshot.rb

Overview

Named, persisted snapshot for terminal state comparison.

First run: saves the snapshot to disk (golden master). Subsequent runs: compares current state against the saved snapshot.

Types:

:text  - chars_only comparison (ignores colors/styles), saved as JSON
:full  - full cell comparison (includes colors/styles), saved as JSON
:png   - screenshot PNG, compared byte-by-byte
:html  - HTML render, compared byte-by-byte
:all   - saves/compares all three formats

Environment:

UPDATE_SNAPSHOTS=1 — auto-update all snapshots instead of comparing

Defined Under Namespace

Classes: ComparisonResult

Constant Summary collapse

EXTENSIONS =
{
  text: ".json",
  full: ".json",
  png: ".png",
  html: ".html",
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, type: :text, snapshot_dir: nil) ⇒ Snapshot

Returns a new instance of Snapshot.



44
45
46
47
48
49
# File 'lib/tui_td/snapshot.rb', line 44

def initialize(name, type: :text, snapshot_dir: nil)
  @name = name.to_s
  @type = type.to_sym
  @snapshot_dir = snapshot_dir || TUITD.configuration.snapshot_dir || "spec/snapshots"
  FileUtils.mkdir_p(@snapshot_dir)
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



42
43
44
# File 'lib/tui_td/snapshot.rb', line 42

def name
  @name
end

#snapshot_dirObject (readonly)

Returns the value of attribute snapshot_dir.



42
43
44
# File 'lib/tui_td/snapshot.rb', line 42

def snapshot_dir
  @snapshot_dir
end

#typeObject (readonly)

Returns the value of attribute type.



42
43
44
# File 'lib/tui_td/snapshot.rb', line 42

def type
  @type
end

Instance Method Details

#compare(state_data, ignore_rows: nil, region: nil) ⇒ Object

Compare current terminal state against the saved snapshot. Returns ComparisonResult.



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/tui_td/snapshot.rb', line 80

def compare(state_data, ignore_rows: nil, region: nil)
  if @type == :all
    compare_all(state_data, ignore_rows: ignore_rows, region: region)
  elsif png?
    compare_png(state_data)
  elsif html?
    compare_html(state_data)
  else
    compare_json(state_data, chars_only: @type == :text, ignore_rows: ignore_rows, region: region)
  end
end

#exists?Boolean

Check if the primary snapshot file exists on disk.

Returns:

  • (Boolean)


57
58
59
60
61
62
63
# File 'lib/tui_td/snapshot.rb', line 57

def exists?
  if @type == :all
    %i[text png html].all? { |t| File.exist?(path(EXTENSIONS[t])) }
  else
    File.exist?(path)
  end
end

#path(ext = EXTENSIONS.fetch(@type, ".json")) ⇒ Object

Return the full filesystem path for the given extension.



52
53
54
# File 'lib/tui_td/snapshot.rb', line 52

def path(ext = EXTENSIONS.fetch(@type, ".json"))
  File.join(@snapshot_dir, "#{@name}#{ext}")
end

#save(state_data) ⇒ Object

Save terminal state as a named snapshot.



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/tui_td/snapshot.rb', line 66

def save(state_data)
  data = normalize(state_data)

  File.write(path(".json"), JSON.pretty_generate(data)) if save_json?

  Screenshot.new(data).render(path(".png")) if save_png?

  return unless save_html?

  HtmlRenderer.new(data).render(path(".html"))
end