bryton-lite 1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|