bryton-lite 1.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 +7 -0
- data/README.md +296 -0
- data/lib/bryton/lite.rb +427 -0
- metadata +44 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3774eb36e39cd0c1e23784ff1c9b6972aee2cd3228f162183f1b45c7c51ba348
|
4
|
+
data.tar.gz: d12041455299d8b4f19cf83975991168bc6792ff07c227c8c6b5d49e95d34789
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 34cca96d0ce490c263a1e22be5978bb708832940dd0ad7c187f57bfe3195eaa930376957a46c57a61e403284895f8f129786267957c5bc067b45bf0ecc297fc8
|
7
|
+
data.tar.gz: 445ccdbca8dbdba5faf901e2bbcba4eed21214a6e85f8a3fe6376d858b6896752f8dfe2a38cf866678f460243e0075a581770b234fb67623500fa240d7cd50d2
|
data/README.md
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
# bryton-lite
|
2
|
+
Bare bones Ruby implementation of the Bryton testing protocol
|
3
|
+
|
4
|
+
## Install
|
5
|
+
|
6
|
+
The usual:
|
7
|
+
|
8
|
+
```sh
|
9
|
+
gem install bryton-lite
|
10
|
+
```
|
11
|
+
|
12
|
+
## Overview
|
13
|
+
|
14
|
+
Bryton is a file-based testing protocol. The point of Bryton is to allow you to
|
15
|
+
write your tests without constraints on how they need to be organized. All your
|
16
|
+
test scripts have to do is output a JSON object as the last line of STDOUT. At
|
17
|
+
a minimum, the JSON object should have a "success" element set to true or false:
|
18
|
+
|
19
|
+
```json
|
20
|
+
{"success":true}
|
21
|
+
{"success":false}
|
22
|
+
```
|
23
|
+
|
24
|
+
Bryton allows you to start simple, with just a few tests scripts that you can
|
25
|
+
run manually to see the results. As you progress to automated testing you can
|
26
|
+
use a Bryton runner to run all your tests.
|
27
|
+
|
28
|
+
A Bryton runner (i.e. the routine running the tests) calls each executable file
|
29
|
+
in a directory, collecting the results. Those executables can be written in any
|
30
|
+
language, Ruby or otherwise. It also recurses into subdirectories. The runner
|
31
|
+
then reports the results back to you in either a human readable or machine
|
32
|
+
readable format.
|
33
|
+
|
34
|
+
Bryton (which is currently under development) will be a full featured testing
|
35
|
+
system with a large array of options. Bryton::Lite only implements a few of the
|
36
|
+
features. In fact, Bryton::Lite is to be used for testing Bryton.
|
37
|
+
|
38
|
+
|
39
|
+
## Use
|
40
|
+
|
41
|
+
This gem has two modules, one for building tests and one for running tests. The
|
42
|
+
two modules don't depend on each other. You can use one or the other or both.
|
43
|
+
|
44
|
+
### Bryton::Lite::Tests
|
45
|
+
|
46
|
+
#### Basic example
|
47
|
+
|
48
|
+
Bryton is designed to be simple. You don't need any special tools to implement
|
49
|
+
the basic protocol. For example, consider the following script:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
#!/usr/bin/ruby -w
|
53
|
+
require 'json'
|
54
|
+
|
55
|
+
# some test
|
56
|
+
def some_test()
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
|
60
|
+
# results hash
|
61
|
+
results = {}
|
62
|
+
|
63
|
+
# run a test
|
64
|
+
results['success'] = some_test()
|
65
|
+
|
66
|
+
# output results
|
67
|
+
puts JSON.generate(results)
|
68
|
+
```
|
69
|
+
|
70
|
+
Notice that you don't even need this gem to run that script. Bryton is designed
|
71
|
+
to be simple and easy to implement. That test outputs a JSON object as either
|
72
|
+
`{"success":true}` or `{"success":false}`. Now let's take a look at a script
|
73
|
+
in which a test fails.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
#!/usr/bin/ruby -w
|
77
|
+
require 'json'
|
78
|
+
|
79
|
+
# some test
|
80
|
+
def some_test()
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
|
84
|
+
# results hash
|
85
|
+
results = {}
|
86
|
+
|
87
|
+
# run a test
|
88
|
+
if some_test()
|
89
|
+
results['success'] = true
|
90
|
+
else
|
91
|
+
results['errors'] ||= []
|
92
|
+
results['errors'].push({'id'=>'some_test_failure'})
|
93
|
+
end
|
94
|
+
|
95
|
+
# output results
|
96
|
+
puts JSON.generate(results)
|
97
|
+
```
|
98
|
+
|
99
|
+
In this example one of the tests fails. The script could have simply set
|
100
|
+
`success` to false, but instead it gives a little more information by creating
|
101
|
+
the `errors` array and adding a message to it. Notice that `success` is never
|
102
|
+
explicitly set. That's because the presence of an error implies failure.
|
103
|
+
|
104
|
+
#### Bryton::Lite::Tests.assert
|
105
|
+
|
106
|
+
Bryton::Lite::Tests provides several tools for building and outputting test
|
107
|
+
results. Consider this script:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
#!/usr/bin/ruby -w
|
111
|
+
require 'bryton/lite'
|
112
|
+
|
113
|
+
# some test
|
114
|
+
def some_test
|
115
|
+
return false
|
116
|
+
end
|
117
|
+
|
118
|
+
# test a function
|
119
|
+
Bryton::Lite::Tests.assert some_test()
|
120
|
+
|
121
|
+
# done
|
122
|
+
Bryton::Lite::Tests.try_succeed
|
123
|
+
Bryton::Lite::Tests.done
|
124
|
+
```
|
125
|
+
|
126
|
+
In this test, we create a function that, in this case, always returns false.
|
127
|
+
Then we use Bryton::Lite::Tests.assert to check the result of that function.
|
128
|
+
If the test fails, then an error is added to the output hash.
|
129
|
+
|
130
|
+
Next we call Bryton::Lite::Tests.try_succeed. That function marks the test
|
131
|
+
script as successful, but only if there are not errors. Remember that a test run
|
132
|
+
is only considered successful if the output explicitly sets `success` as true.
|
133
|
+
|
134
|
+
|
135
|
+
Finally, we call Bryton::Lite::Tests.done, which outputs the the results and
|
136
|
+
exits. Bryton::Lite::Tests.done should be called as the last line of your
|
137
|
+
script.
|
138
|
+
|
139
|
+
Here's the output for that run.
|
140
|
+
|
141
|
+
```json
|
142
|
+
{"errors":[{"line":12,"file":"./basic.rb"}]}
|
143
|
+
```
|
144
|
+
|
145
|
+
By default, `assert` notes the file name and line number of the error. You can
|
146
|
+
also add an id for the error:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
Bryton::Lite::Tests.assert some_test(), 'running some_test()'
|
150
|
+
```
|
151
|
+
|
152
|
+
which outputs
|
153
|
+
|
154
|
+
```json
|
155
|
+
{"errors":[{"line":11,"file":"./id.rb","id":"running some_test()"}]}
|
156
|
+
```
|
157
|
+
|
158
|
+
If you want to manually add information to the error, use a do block. `assert`
|
159
|
+
yields the error hash:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
Bryton::Lite::Tests.assert(some_test()) do |error|
|
163
|
+
error['notes'] = 'failure of some_test'
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
167
|
+
which outputs a JSON object with whatever you added:
|
168
|
+
|
169
|
+
```json
|
170
|
+
{"errors":[{"line":12,"file":"./block.rb","notes":"failure of some_test"}]}
|
171
|
+
```
|
172
|
+
|
173
|
+
#### Bryton::Lite::Tests.fail
|
174
|
+
|
175
|
+
`fail` works much like `assert`, but it unconditionally adds an error. `fail`
|
176
|
+
has syntax similar to `assert`.
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
Bryton::Lite::Tests.fail() do |error|
|
180
|
+
error['notes'] = 'failed db test'
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
184
|
+
which outputs JSON like this:
|
185
|
+
|
186
|
+
```json
|
187
|
+
{"errors":[{"line":6,"file":"./no-id.rb","notes":"failed db test"}]}
|
188
|
+
```
|
189
|
+
|
190
|
+
### Bryton::Lite::Runner
|
191
|
+
|
192
|
+
Bryton::Lite::Runner runs all the tests in a directory tree. The full Bryton
|
193
|
+
protocol will allow you to pick and choose which tests to run and what to do
|
194
|
+
on success or failure. Bryton::Lite::Runner just implements the basic concept of
|
195
|
+
running all the tests.
|
196
|
+
|
197
|
+
To run tests, your script should go to the root of the directory where you have
|
198
|
+
your test files. Then just run `Bryton::Lite::Runner.run`.
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
#!/usr/bin/ruby -w
|
202
|
+
require 'bryton/lite'
|
203
|
+
|
204
|
+
Dir.chdir '../tests'
|
205
|
+
Bryton::Lite::Runner.run
|
206
|
+
puts Bryton::Lite::Runner.success?
|
207
|
+
```
|
208
|
+
|
209
|
+
If you just want to know the success or failure of the tests, output
|
210
|
+
`Bryton::Lite::Runner.success?`. If you want more information, you can output
|
211
|
+
all the results from the entire test run:
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
puts JSON.pretty_generate(Bryton::Lite::Tests.hsh)
|
215
|
+
```
|
216
|
+
|
217
|
+
Notice that we use `Bryton::Lite::Tests.hsh` to get the results. The runner
|
218
|
+
stores results with Bryton::Lite::Tests because the run itself is a test. There
|
219
|
+
are main three elements to a results hash.
|
220
|
+
|
221
|
+
| key | data type | explanation |
|
222
|
+
|---------|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
223
|
+
| success | true, false, or nil | Indicates success of failure of a test. Nil is considered false. |
|
224
|
+
| file | hash | Hash of information about the fiule being tested. Should at least contain the path to the file relative to the root directory of the test. If `dir` is true then the file is a directory. |
|
225
|
+
| errors | array | Each element of the array give details about an error. If any elements are present in the errors array then `success` should not be true. |
|
226
|
+
| nested | array | Array of nested test results. Every nested result must be successful or the entire test run is considered to have failed. |
|
227
|
+
|
228
|
+
As with any hash, you can add your own custom elements.
|
229
|
+
|
230
|
+
Here is a sample output from a script run. (JSON doesn't allow comments, but
|
231
|
+
I've added some here for clarity.
|
232
|
+
|
233
|
+
```javascript
|
234
|
+
// root directory for tests
|
235
|
+
{
|
236
|
+
// indicates that the test run failed
|
237
|
+
"success": false,
|
238
|
+
|
239
|
+
// file information about this directory
|
240
|
+
"file": {
|
241
|
+
"path": ".",
|
242
|
+
"dir": true
|
243
|
+
},
|
244
|
+
|
245
|
+
// nested list of subtests
|
246
|
+
// directories always have an array of nested tests
|
247
|
+
"nested": [
|
248
|
+
{
|
249
|
+
"file": {
|
250
|
+
"path": "./load-tests",
|
251
|
+
"dir": true
|
252
|
+
},
|
253
|
+
|
254
|
+
"nested": [
|
255
|
+
{
|
256
|
+
// indicates that this file test failed
|
257
|
+
"success": false,
|
258
|
+
|
259
|
+
// file information about ./load-tests/crash.rb
|
260
|
+
"file": {
|
261
|
+
"path": "./load-tests/crash.rb"
|
262
|
+
},
|
263
|
+
|
264
|
+
// array of error messages
|
265
|
+
"errors": [
|
266
|
+
{
|
267
|
+
// indicates that execution of the script failed
|
268
|
+
"id": "execution-failed",
|
269
|
+
|
270
|
+
// STDERR from the execution
|
271
|
+
"stderr": "./crash.rb:5:in `/': divided by 0 (ZeroDivisionError)\n\tfrom ./crash.rb:5:in `<main>'\n"
|
272
|
+
}
|
273
|
+
]
|
274
|
+
},
|
275
|
+
|
276
|
+
{
|
277
|
+
// indicates that the script succeeded
|
278
|
+
"success": true,
|
279
|
+
|
280
|
+
// file information
|
281
|
+
"file": {
|
282
|
+
"path": "./load-tests/success.rb"
|
283
|
+
}
|
284
|
+
}
|
285
|
+
]
|
286
|
+
},
|
287
|
+
|
288
|
+
{
|
289
|
+
"success": true,
|
290
|
+
"file": {
|
291
|
+
"path": "./test-a.rb"
|
292
|
+
}
|
293
|
+
}
|
294
|
+
]
|
295
|
+
}
|
296
|
+
```
|
data/lib/bryton/lite.rb
ADDED
@@ -0,0 +1,427 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
|
5
|
+
#===============================================================================
|
6
|
+
# Bryton, Bryton::Lite
|
7
|
+
#
|
8
|
+
|
9
|
+
# Not much here. Just initializing the Bryton namespace.
|
10
|
+
|
11
|
+
module Bryton
|
12
|
+
end
|
13
|
+
|
14
|
+
# Not much here either. Just initializing the Bryton::Lite namespace.
|
15
|
+
|
16
|
+
module Bryton::Lite
|
17
|
+
end
|
18
|
+
#
|
19
|
+
# Bryton, Bryton::Lite
|
20
|
+
#===============================================================================
|
21
|
+
|
22
|
+
|
23
|
+
#===============================================================================
|
24
|
+
# Bryton::Lite::Runner
|
25
|
+
#
|
26
|
+
|
27
|
+
# Runs tests in the current directory tree.
|
28
|
+
|
29
|
+
module Bryton::Lite::Runner
|
30
|
+
#---------------------------------------------------------------------------
|
31
|
+
# run
|
32
|
+
#
|
33
|
+
|
34
|
+
# Run the tests. If you pass in a block, each test result is yielded with
|
35
|
+
# the path to the file and the results hash.
|
36
|
+
|
37
|
+
def self.run(&block)
|
38
|
+
Bryton::Lite::Tests.reset
|
39
|
+
dir('.', &block)
|
40
|
+
Bryton::Lite::Tests.try_succeed
|
41
|
+
Bryton::Lite::Tests.reorder_results
|
42
|
+
end
|
43
|
+
#
|
44
|
+
# run
|
45
|
+
#---------------------------------------------------------------------------
|
46
|
+
|
47
|
+
|
48
|
+
#---------------------------------------------------------------------------
|
49
|
+
# dir
|
50
|
+
#
|
51
|
+
|
52
|
+
# Runs the tests in a directory. Don't call this method directly.
|
53
|
+
|
54
|
+
def self.dir(path, &block)
|
55
|
+
entries = Dir.entries('./')
|
56
|
+
entries = entries.reject {|entry| entry.match(/\A\.+\z/mu)}
|
57
|
+
|
58
|
+
# note file and path
|
59
|
+
Bryton::Lite::Tests['file'] = {}
|
60
|
+
Bryton::Lite::Tests['file']['path'] = path
|
61
|
+
Bryton::Lite::Tests['file']['dir'] = true
|
62
|
+
|
63
|
+
# loop through entries
|
64
|
+
entries.each do |entry|
|
65
|
+
entry_path = "#{path}/#{entry}"
|
66
|
+
|
67
|
+
# if directory, recurse into it
|
68
|
+
if File.directory?(entry)
|
69
|
+
Dir.chdir(entry) do
|
70
|
+
Bryton::Lite::Tests.nest do
|
71
|
+
self.dir(entry_path, &block)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# elsif the file is executable then execute it
|
76
|
+
elsif File.executable?(entry)
|
77
|
+
results = execute(entry, entry_path)
|
78
|
+
Bryton::Lite::Tests.add_to_nest results
|
79
|
+
|
80
|
+
if block_given?
|
81
|
+
yield entry_path, results
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
#
|
87
|
+
# dir
|
88
|
+
#---------------------------------------------------------------------------
|
89
|
+
|
90
|
+
|
91
|
+
#---------------------------------------------------------------------------
|
92
|
+
# execute
|
93
|
+
#
|
94
|
+
|
95
|
+
# Executes a file, parses the results, and returns the results. Don't call
|
96
|
+
# this method directly.
|
97
|
+
|
98
|
+
def self.execute(name, path)
|
99
|
+
# init
|
100
|
+
rv = {}
|
101
|
+
rv['file'] = {}
|
102
|
+
rv['file']['path'] = path
|
103
|
+
|
104
|
+
# execute script
|
105
|
+
cap = Bryton::Lite::Runner::Capture.new("./#{name}")
|
106
|
+
|
107
|
+
# if script crashed
|
108
|
+
if not cap.success?
|
109
|
+
rv['success'] = false
|
110
|
+
rv['errors'] ||= []
|
111
|
+
|
112
|
+
# build error
|
113
|
+
error = {'id'=>'execution-failed'}
|
114
|
+
error['id'] = 'execution-failed'
|
115
|
+
error['stderr'] = cap.stderr
|
116
|
+
|
117
|
+
# add error and return
|
118
|
+
rv['errors'].push(error)
|
119
|
+
return rv
|
120
|
+
|
121
|
+
# if we get a non-blank line, attempt to parse it as JSON
|
122
|
+
elsif non_blank = self.last_non_blank(cap.stdout)
|
123
|
+
begin
|
124
|
+
# retrieve and parse results
|
125
|
+
results = JSON.parse( non_blank )
|
126
|
+
rv = rv.merge(results)
|
127
|
+
|
128
|
+
# ensure that if there are errors, success is false
|
129
|
+
if rv['errors'] and rv['errors'].any?
|
130
|
+
rv['success'] = false
|
131
|
+
end
|
132
|
+
|
133
|
+
# return
|
134
|
+
return rv
|
135
|
+
rescue
|
136
|
+
rv['success'] = false
|
137
|
+
rv['errors'] = []
|
138
|
+
rv['errors'].push({'id'=>'invalid-json'})
|
139
|
+
return rv
|
140
|
+
end
|
141
|
+
|
142
|
+
# did not get non-blank line
|
143
|
+
else
|
144
|
+
rv['success'] = false
|
145
|
+
rv['errors'] = []
|
146
|
+
rv['errors'].push({'id'=>'no-results'})
|
147
|
+
return rv
|
148
|
+
end
|
149
|
+
end
|
150
|
+
#
|
151
|
+
# execute
|
152
|
+
#---------------------------------------------------------------------------
|
153
|
+
|
154
|
+
|
155
|
+
#---------------------------------------------------------------------------
|
156
|
+
# last_non_blank
|
157
|
+
#
|
158
|
+
|
159
|
+
# Finds the last non-blank line in STDOUT from the file execution. Don't
|
160
|
+
# call this method directly.
|
161
|
+
|
162
|
+
def self.last_non_blank(str)
|
163
|
+
str.lines.reverse.each do |line|
|
164
|
+
if line.match(/\S/mu)
|
165
|
+
return line
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# didn't find non-blank
|
170
|
+
return nil
|
171
|
+
end
|
172
|
+
#
|
173
|
+
# last_non_blank
|
174
|
+
#---------------------------------------------------------------------------
|
175
|
+
|
176
|
+
|
177
|
+
#---------------------------------------------------------------------------
|
178
|
+
# success?
|
179
|
+
#
|
180
|
+
|
181
|
+
# Returns the success or failure of the test run.
|
182
|
+
|
183
|
+
def self.success?
|
184
|
+
return Bryton::Lite::Tests.success?
|
185
|
+
end
|
186
|
+
#
|
187
|
+
# success?
|
188
|
+
#---------------------------------------------------------------------------
|
189
|
+
end
|
190
|
+
#
|
191
|
+
# Bryton::Lite::Runner
|
192
|
+
#===============================================================================
|
193
|
+
|
194
|
+
|
195
|
+
#===============================================================================
|
196
|
+
# Bryton::Lite::Runner::Capture
|
197
|
+
# class for capturing the output of a script
|
198
|
+
#
|
199
|
+
|
200
|
+
# Executes the given command and captures the results.
|
201
|
+
|
202
|
+
class Bryton::Lite::Runner::Capture
|
203
|
+
# Executes the command with Open3.capture3 and holds on to the results.
|
204
|
+
def initialize(*cmd)
|
205
|
+
@results = Open3.capture3(*cmd)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Returns the content of STDOUT from the execution.
|
209
|
+
# @return [String]
|
210
|
+
def stdout
|
211
|
+
return @results[0]
|
212
|
+
end
|
213
|
+
|
214
|
+
# Returns the content of STDERR from the execution.
|
215
|
+
# @return [String]
|
216
|
+
def stderr
|
217
|
+
return @results[1]
|
218
|
+
end
|
219
|
+
|
220
|
+
# Returns the status of execution.
|
221
|
+
# @return [Process::Status]
|
222
|
+
def status
|
223
|
+
return @results[2]
|
224
|
+
end
|
225
|
+
|
226
|
+
# Returns the success or failure of the execution.
|
227
|
+
# @return [Boolean]
|
228
|
+
def success?
|
229
|
+
return status.success?
|
230
|
+
end
|
231
|
+
end
|
232
|
+
#
|
233
|
+
# Bryton::Lite::Runner::Capture
|
234
|
+
#===============================================================================
|
235
|
+
|
236
|
+
|
237
|
+
#===============================================================================
|
238
|
+
# Bryton::Lite::Tests
|
239
|
+
#
|
240
|
+
|
241
|
+
# Utilities for use in the test script.
|
242
|
+
|
243
|
+
module Bryton::Lite::Tests
|
244
|
+
# accessors
|
245
|
+
class << self
|
246
|
+
# @return [Hash]
|
247
|
+
attr_reader :hsh
|
248
|
+
end
|
249
|
+
|
250
|
+
# reset
|
251
|
+
def self.reset()
|
252
|
+
@hsh = {}
|
253
|
+
end
|
254
|
+
|
255
|
+
# call reset
|
256
|
+
reset()
|
257
|
+
|
258
|
+
# Get the element with the given key.
|
259
|
+
def self.[](k)
|
260
|
+
return @hsh[k]
|
261
|
+
end
|
262
|
+
|
263
|
+
# Set the element with the given key and value.
|
264
|
+
def self.[]=(k, v)
|
265
|
+
return @hsh[k] = v
|
266
|
+
end
|
267
|
+
|
268
|
+
# Set to success. Raises an exception if any errors exist. You probably want
|
269
|
+
# to use try_succeed() instead.
|
270
|
+
def self.succeed
|
271
|
+
if not allow_success?
|
272
|
+
raise 'cannot-set-to-success'
|
273
|
+
end
|
274
|
+
|
275
|
+
return @hsh['success'] = true
|
276
|
+
end
|
277
|
+
|
278
|
+
# Returns true if ['success'] is true, false otherwise. Always returns true
|
279
|
+
# or false.
|
280
|
+
# @return [Boolean]
|
281
|
+
def self.success?
|
282
|
+
return @hsh['success'] ? true : false
|
283
|
+
end
|
284
|
+
|
285
|
+
# Try to set to success, but will not do so if there are errors or if the
|
286
|
+
# test is already set as fail. Does not raise an exception if the success
|
287
|
+
# cannot be set to true.
|
288
|
+
# @return [Boolean]
|
289
|
+
def self.try_succeed
|
290
|
+
return @hsh['success'] = allow_success?()
|
291
|
+
end
|
292
|
+
|
293
|
+
# Test if try_succeed can set success. You probably don't need to call this
|
294
|
+
# method directly.
|
295
|
+
# @return [Boolean]
|
296
|
+
def self.allow_success?
|
297
|
+
return allow_success_recurse(@hsh)
|
298
|
+
end
|
299
|
+
|
300
|
+
# Tests each nested result. If any of the nested results are set to failure,
|
301
|
+
# return false. Otherwise returns true.
|
302
|
+
def self.allow_success_recurse(test_hsh)
|
303
|
+
# if any errors
|
304
|
+
if test_hsh['errors'] and test_hsh['errors'].any?
|
305
|
+
return false
|
306
|
+
end
|
307
|
+
|
308
|
+
# recurse into nested elements
|
309
|
+
if test_hsh['nested']
|
310
|
+
test_hsh['nested'].each do |child|
|
311
|
+
if not allow_success_recurse(child)
|
312
|
+
return false
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# at this point it should be successful
|
318
|
+
return true
|
319
|
+
end
|
320
|
+
|
321
|
+
# Returns the errors array, creating it if necessary.
|
322
|
+
def self.errors
|
323
|
+
@hsh['errors'] ||= []
|
324
|
+
return @hsh['errors']
|
325
|
+
end
|
326
|
+
|
327
|
+
# Creates (if necessary) an array with the key "nested". Creates a results
|
328
|
+
# hash that is nested in that array. In the do block,
|
329
|
+
# Bryton::Lite::Tests.hsh is set to that child results hash.
|
330
|
+
def self.nest()
|
331
|
+
@hsh['nested'] ||= []
|
332
|
+
child = {}
|
333
|
+
@hsh['nested'].push child
|
334
|
+
hold_hsh = @hsh
|
335
|
+
@hsh = child
|
336
|
+
|
337
|
+
begin
|
338
|
+
yield
|
339
|
+
ensure
|
340
|
+
@hsh = hold_hsh
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
# Created the "nested" array and adds the given results to that array
|
345
|
+
def self.add_to_nest(child)
|
346
|
+
@hsh['nested'] ||= []
|
347
|
+
@hsh['nested'].push child
|
348
|
+
end
|
349
|
+
|
350
|
+
# done
|
351
|
+
def self.done
|
352
|
+
try_succeed()
|
353
|
+
reorder_results()
|
354
|
+
STDOUT.puts JSON.generate(@hsh)
|
355
|
+
exit
|
356
|
+
end
|
357
|
+
|
358
|
+
# to_json
|
359
|
+
def self.to_json
|
360
|
+
return JSON.generate(@hsh)
|
361
|
+
end
|
362
|
+
|
363
|
+
# assert
|
364
|
+
def self.assert(bool, id=nil, level=0, &block)
|
365
|
+
if not bool
|
366
|
+
fail id, 1, &block
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
# Mark the test as failed.
|
371
|
+
def self.fail(id=nil, level=0, &block)
|
372
|
+
loc = caller_locations[level]
|
373
|
+
|
374
|
+
# create error object
|
375
|
+
error = {}
|
376
|
+
error['line'] = loc.lineno
|
377
|
+
id and error['id'] = id
|
378
|
+
|
379
|
+
# add to errors
|
380
|
+
@hsh['errors'] ||= []
|
381
|
+
@hsh['errors'].push error
|
382
|
+
|
383
|
+
# if block
|
384
|
+
if block_given?
|
385
|
+
yield error
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
# reorder_results
|
390
|
+
# This method is for improving the readability of a result by putting the
|
391
|
+
# "success" element first and "nested" last.
|
392
|
+
def self.reorder_results
|
393
|
+
@hsh = reorder_results_recurse(@hsh)
|
394
|
+
end
|
395
|
+
|
396
|
+
# reorder_results_recurse
|
397
|
+
# This method rcurses through test results, putting "success" first and
|
398
|
+
# "nested" last.
|
399
|
+
def self.reorder_results_recurse(old_hsh)
|
400
|
+
new_hsh = {}
|
401
|
+
nested = old_hsh.delete('nested')
|
402
|
+
|
403
|
+
# add success if it exists
|
404
|
+
if old_hsh.has_key?('success')
|
405
|
+
new_hsh['success'] = old_hsh.delete('success')
|
406
|
+
end
|
407
|
+
|
408
|
+
# add every other element
|
409
|
+
new_hsh = new_hsh.merge(old_hsh)
|
410
|
+
|
411
|
+
# add nested last
|
412
|
+
if nested
|
413
|
+
new_hsh['nested'] = nested
|
414
|
+
|
415
|
+
# recurse through nested results
|
416
|
+
new_hsh['nested'].map! do |child|
|
417
|
+
reorder_results_recurse child
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
# return reformatted hash
|
422
|
+
return new_hsh
|
423
|
+
end
|
424
|
+
end
|
425
|
+
#
|
426
|
+
# Bryton::Lite::Tests
|
427
|
+
#===============================================================================
|
metadata
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bryton-lite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike O'Sullivan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-05-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Bare bones implementation of the Bryton testing protocol
|
14
|
+
email: mike@idocs.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- README.md
|
20
|
+
- lib/bryton/lite.rb
|
21
|
+
homepage: https://github.com/mikosullivan/bryton-lite
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
metadata: {}
|
25
|
+
post_install_message:
|
26
|
+
rdoc_options: []
|
27
|
+
require_paths:
|
28
|
+
- lib
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubygems_version: 3.1.2
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: Bryton::Lite
|
44
|
+
test_files: []
|