backspin 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +18 -6
- data/.ruby-version +1 -0
- data/CHANGELOG.md +16 -1
- data/CLAUDE.md +20 -16
- data/CONTRIBUTING.md +16 -19
- data/Gemfile.lock +3 -6
- data/MATCHERS.md +28 -136
- data/README.md +61 -124
- data/backspin.gemspec +0 -3
- data/docs/backspin-result-api-sketch.md +203 -0
- data/examples/match_on_example.rb +42 -71
- data/lib/backspin/backspin_result.rb +66 -0
- data/lib/backspin/command_diff.rb +28 -23
- data/lib/backspin/configuration.rb +1 -1
- data/lib/backspin/matcher.rb +21 -27
- data/lib/backspin/record.rb +23 -36
- data/lib/backspin/recorder.rb +54 -305
- data/lib/backspin/snapshot.rb +96 -0
- data/lib/backspin/version.rb +1 -1
- data/lib/backspin.rb +127 -94
- metadata +7 -34
- data/lib/backspin/command.rb +0 -106
- data/lib/backspin/command_result.rb +0 -58
- data/lib/backspin/record_result.rb +0 -159
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Backspin
|
|
4
|
-
# Result object for all Backspin record operations
|
|
5
|
-
# Provides a consistent interface whether recording, verifying, or playing back
|
|
6
|
-
class RecordResult
|
|
7
|
-
attr_reader :output, :commands, :mode, :command_diffs
|
|
8
|
-
attr_reader :record
|
|
9
|
-
|
|
10
|
-
def initialize(output:, mode:, record:, verified: nil, command_diffs: nil)
|
|
11
|
-
@output = output
|
|
12
|
-
@mode = mode
|
|
13
|
-
@record = record
|
|
14
|
-
@commands = record.commands
|
|
15
|
-
@verified = verified
|
|
16
|
-
@command_diffs = command_diffs || []
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# @return [Boolean] true if this result is from recording
|
|
20
|
-
def recorded?
|
|
21
|
-
mode == :record
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def record_path
|
|
25
|
-
record.path
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# @return [Boolean, nil] true/false for verification results, nil for recording
|
|
29
|
-
def verified?
|
|
30
|
-
return @verified unless mode == :verify
|
|
31
|
-
|
|
32
|
-
return false if command_diffs.size < commands.size
|
|
33
|
-
|
|
34
|
-
@verified
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# @return [Boolean] true if this result is from playback mode
|
|
38
|
-
def playback?
|
|
39
|
-
mode == :playback
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# @return [String, nil] Human-readable error message if verification failed
|
|
43
|
-
def error_message
|
|
44
|
-
return nil unless verified? == false
|
|
45
|
-
|
|
46
|
-
# Check for command count mismatch first
|
|
47
|
-
if command_diffs.size < commands.size
|
|
48
|
-
return "Expected #{commands.size} commands but only #{command_diffs.size} were executed"
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
return "No commands to verify" if command_diffs.empty?
|
|
52
|
-
|
|
53
|
-
failed_diffs = command_diffs.reject(&:verified?)
|
|
54
|
-
return "All commands verified" if failed_diffs.empty?
|
|
55
|
-
|
|
56
|
-
msg = "Output verification failed for #{failed_diffs.size} command(s):\n\n"
|
|
57
|
-
|
|
58
|
-
command_diffs.each_with_index do |diff, idx|
|
|
59
|
-
next if diff.verified?
|
|
60
|
-
|
|
61
|
-
msg += "Command #{idx + 1}: #{diff.summary}\n"
|
|
62
|
-
msg += diff.diff
|
|
63
|
-
msg += "\n\n" if idx < command_diffs.size - 1
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
msg
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# @return [String, nil] Combined diff from all failed commands
|
|
70
|
-
def diff
|
|
71
|
-
return nil if command_diffs.empty?
|
|
72
|
-
|
|
73
|
-
failed_diffs = command_diffs.reject(&:verified?)
|
|
74
|
-
return nil if failed_diffs.empty?
|
|
75
|
-
|
|
76
|
-
diff_parts = []
|
|
77
|
-
command_diffs.each_with_index do |cmd_diff, idx|
|
|
78
|
-
diff_parts << "Command #{idx + 1}:\n#{cmd_diff.diff}" unless cmd_diff.verified?
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
diff_parts.join("\n\n")
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Convenience accessors for command output
|
|
85
|
-
# For single command (common case), these provide direct access
|
|
86
|
-
# For multiple commands, use all_stdout, all_stderr, etc.
|
|
87
|
-
|
|
88
|
-
# @return [String, nil] stdout from the first command
|
|
89
|
-
def stdout
|
|
90
|
-
commands.first&.result&.stdout
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# @return [String, nil] stderr from the first command
|
|
94
|
-
def stderr
|
|
95
|
-
commands.first&.result&.stderr
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# @return [Integer, nil] exit status from the first command
|
|
99
|
-
def status
|
|
100
|
-
commands.first&.result&.status
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Multiple command accessors
|
|
104
|
-
|
|
105
|
-
# @return [Array<String>] stdout from all commands
|
|
106
|
-
def all_stdout
|
|
107
|
-
commands.map { |cmd| cmd.result.stdout }
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# @return [Array<String>] stderr from all commands
|
|
111
|
-
def all_stderr
|
|
112
|
-
commands.map { |cmd| cmd.result.stderr }
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# @return [Array<Integer>] exit status from all commands
|
|
116
|
-
def all_status
|
|
117
|
-
commands.map { |cmd| cmd.result.status }
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# @return [Boolean] true if this result contains multiple commands
|
|
121
|
-
def multiple_commands?
|
|
122
|
-
commands.size > 1
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# @return [Boolean] true if all commands succeeded (exit status 0)
|
|
126
|
-
def success?
|
|
127
|
-
if multiple_commands?
|
|
128
|
-
# Check all commands - if any command has non-zero status, we're not successful
|
|
129
|
-
commands.all? { |cmd| cmd.result.status.zero? }
|
|
130
|
-
else
|
|
131
|
-
status&.zero? || false
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# @return [Boolean] true if any command failed (non-zero exit status)
|
|
136
|
-
def failure?
|
|
137
|
-
!success?
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
# @return [Hash] Summary of the result for debugging
|
|
141
|
-
def to_h
|
|
142
|
-
hash = {
|
|
143
|
-
mode: mode,
|
|
144
|
-
recorded: recorded?,
|
|
145
|
-
playback: playback?,
|
|
146
|
-
stdout: stdout,
|
|
147
|
-
stderr: stderr,
|
|
148
|
-
status: status
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
hash[:verified] = verified? unless verified?.nil?
|
|
152
|
-
hash[:diff] = diff if diff
|
|
153
|
-
# Include number of failed commands if in verify mode
|
|
154
|
-
hash[:failed_commands] = command_diffs.count { |d| !d.verified? } if mode == :verify && command_diffs.any?
|
|
155
|
-
|
|
156
|
-
hash
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
end
|