backspin 0.4.5 → 0.6.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/CHANGELOG.md +4 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +7 -9
- data/MATCHERS.md +234 -0
- data/README.md +43 -25
- data/backspin.gemspec +2 -4
- data/fixtures/backspin/all_for_logging.yml +1 -1
- data/lib/backspin/command.rb +7 -0
- data/lib/backspin/command_diff.rb +8 -80
- data/lib/backspin/configuration.rb +57 -0
- data/lib/backspin/matcher.rb +110 -0
- data/lib/backspin/recorder.rb +152 -7
- data/lib/backspin/version.rb +1 -1
- data/lib/backspin.rb +53 -65
- data/release.rake +6 -5
- metadata +11 -23
- data/MATCH_ON_USAGE.md +0 -110
data/MATCH_ON_USAGE.md
DELETED
@@ -1,110 +0,0 @@
|
|
1
|
-
# Using match_on for Field-Specific Verification
|
2
|
-
|
3
|
-
The `match_on` option allows you to use custom matchers for specific fields while maintaining exact equality checks for all other fields. This is useful when dealing with dynamic content like timestamps, process IDs, or version numbers.
|
4
|
-
|
5
|
-
## Basic Usage
|
6
|
-
|
7
|
-
### Single Field Matcher
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
# Record a command with a timestamp
|
11
|
-
Backspin.run("timestamp_test") do
|
12
|
-
Open3.capture3("date")
|
13
|
-
end
|
14
|
-
|
15
|
-
# Verify with a custom matcher for stdout
|
16
|
-
result = Backspin.run("timestamp_test",
|
17
|
-
match_on: [:stdout, ->(recorded, actual) {
|
18
|
-
# Both should contain a day of the week
|
19
|
-
recorded.match?(/Mon|Tue|Wed|Thu|Fri|Sat|Sun/) &&
|
20
|
-
actual.match?(/Mon|Tue|Wed|Thu|Fri|Sat|Sun/)
|
21
|
-
}]) do
|
22
|
-
Open3.capture3("date")
|
23
|
-
end
|
24
|
-
```
|
25
|
-
|
26
|
-
### Multiple Field Matchers
|
27
|
-
|
28
|
-
```ruby
|
29
|
-
# Match different fields with different rules
|
30
|
-
result = Backspin.run("multi_field_test",
|
31
|
-
match_on: [
|
32
|
-
[:stdout, ->(recorded, actual) {
|
33
|
-
# Match process ID format
|
34
|
-
recorded.match?(/PID: \d+/) && actual.match?(/PID: \d+/)
|
35
|
-
}],
|
36
|
-
[:stderr, ->(recorded, actual) {
|
37
|
-
# Match error type, ignore details
|
38
|
-
recorded.include?("Error:") && actual.include?("Error:")
|
39
|
-
}]
|
40
|
-
]) do
|
41
|
-
Open3.capture3("./my_script.sh")
|
42
|
-
end
|
43
|
-
```
|
44
|
-
|
45
|
-
## Matcher Format
|
46
|
-
|
47
|
-
The `match_on` option accepts two formats:
|
48
|
-
|
49
|
-
1. **Single field**: `[:field_name, matcher_proc]`
|
50
|
-
2. **Multiple fields**: `[[:field1, matcher1], [:field2, matcher2], ...]`
|
51
|
-
|
52
|
-
Valid field names are:
|
53
|
-
- `:stdout` - Standard output
|
54
|
-
- `:stderr` - Standard error
|
55
|
-
- `:status` - Exit status code
|
56
|
-
|
57
|
-
## Matcher Proc
|
58
|
-
|
59
|
-
The matcher proc receives two arguments:
|
60
|
-
- `recorded_value` - The value from the saved recording
|
61
|
-
- `actual_value` - The value from the current execution
|
62
|
-
|
63
|
-
It should return `true` if the values match according to your criteria, `false` otherwise.
|
64
|
-
|
65
|
-
## Examples
|
66
|
-
|
67
|
-
### Matching Version Numbers
|
68
|
-
|
69
|
-
```ruby
|
70
|
-
# Match major version only
|
71
|
-
match_on: [:stdout, ->(recorded, actual) {
|
72
|
-
recorded.match(/Version: (\d+)\./) &&
|
73
|
-
actual.match(/Version: (\d+)\./) &&
|
74
|
-
$1 == $1 # Major versions match
|
75
|
-
}]
|
76
|
-
```
|
77
|
-
|
78
|
-
### Ignoring Timestamps
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
# Match log format but ignore timestamp
|
82
|
-
match_on: [:stdout, ->(recorded, actual) {
|
83
|
-
# Remove timestamps before comparing
|
84
|
-
recorded.gsub(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, '') ==
|
85
|
-
actual.gsub(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, '')
|
86
|
-
}]
|
87
|
-
```
|
88
|
-
|
89
|
-
### Handling Dynamic IDs
|
90
|
-
|
91
|
-
```ruby
|
92
|
-
# Match API response structure, ignore dynamic IDs
|
93
|
-
match_on: [:stdout, ->(recorded, actual) {
|
94
|
-
recorded_json = JSON.parse(recorded)
|
95
|
-
actual_json = JSON.parse(actual)
|
96
|
-
|
97
|
-
# Compare structure, not values
|
98
|
-
recorded_json.keys.sort == actual_json.keys.sort
|
99
|
-
}]
|
100
|
-
```
|
101
|
-
|
102
|
-
## Important Notes
|
103
|
-
|
104
|
-
1. **Other fields must match exactly**: When using `match_on`, all fields not specified in the matcher list must match exactly. If stdout has a custom matcher but stderr doesn't, stderr must be identical to pass verification.
|
105
|
-
|
106
|
-
2. **Precedence**: If both `matcher` and `match_on` options are provided, `matcher` takes precedence (for backward compatibility).
|
107
|
-
|
108
|
-
3. **Error messages**: When verification fails with `match_on`, the error will indicate which fields failed and whether they failed exact matching or custom matching.
|
109
|
-
|
110
|
-
4. **Works with run!**: The `match_on` option works with both `run` and `run!` methods.
|