gloo-test 1.1
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 +30 -0
- data/lib/assert.rb +88 -0
- data/lib/gloo-test.rb +29 -0
- data/lib/refute.rb +89 -0
- data/lib/result.rb +44 -0
- data/lib/results.rb +114 -0
- data/lib/test.rb +126 -0
- data/lib/test_file.rb +59 -0
- data/lib/test_files.rb +102 -0
- data/lib/test_runner.rb +74 -0
- metadata +52 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 4a73cec30908a847f9a57eff2a51260510ce2c6dae9c7ce3a5c899cb2b687385
|
|
4
|
+
data.tar.gz: 3e39c1eeac6b251ed68f81047759a7a505d5eccff6c62b3c156994a8c42b5a8c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a78397cbeb4554166ec1d210149969121f1ebe133f3d6b7c45811fba1da0c1f3f2c2627a0a12dfa2257b3a6e9b4a85294fd61f42c53b8731cf201e33a29b6e5a
|
|
7
|
+
data.tar.gz: b11b5be346c5de429676e3095c675b4ef651fc4ea4688890473fba113bcd1345777175ee95011ef4f930fe5d6054bbe8c751f3987df1e3ce5d347f28d9a83c29
|
data/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# gloo-test
|
|
2
|
+
|
|
3
|
+
A core gloo library for unit testing gloo code.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Loaded automatically when running gloo in test mode:
|
|
8
|
+
|
|
9
|
+
```gloo
|
|
10
|
+
> gloo --test ./path/to/tests/
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
It can also be loaded explicitly in a script, like any other core library:
|
|
14
|
+
|
|
15
|
+
```gloo
|
|
16
|
+
> load lib test
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Objects
|
|
20
|
+
|
|
21
|
+
- `test` — a single gloo test
|
|
22
|
+
|
|
23
|
+
## Verbs
|
|
24
|
+
|
|
25
|
+
- `assert` — assert an expectation about the state or result of a prior command
|
|
26
|
+
- `refute` — refute an expectation about the state or result of a prior command
|
|
27
|
+
|
|
28
|
+
## Full Reference
|
|
29
|
+
|
|
30
|
+
Every object/verb's full syntax is documented in-app once the library is loaded — e.g. `help> verb assert`.
|
data/lib/assert.rb
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Assert that [it] is true.
|
|
3
|
+
#
|
|
4
|
+
class Assert < Gloo::Core::Verb
|
|
5
|
+
|
|
6
|
+
KEYWORD = 'assert'.freeze
|
|
7
|
+
KEYWORD_SHORT = 'expect'.freeze
|
|
8
|
+
DEFAULT_MESSAGE = 'Assertion failed'.freeze
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Get the Verb's keyword.
|
|
12
|
+
#
|
|
13
|
+
def self.keyword
|
|
14
|
+
return KEYWORD
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# Get the Verb's keyword shortcut.
|
|
19
|
+
#
|
|
20
|
+
def self.keyword_shortcut
|
|
21
|
+
return KEYWORD_SHORT
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Run the verb.
|
|
26
|
+
#
|
|
27
|
+
def run
|
|
28
|
+
begin
|
|
29
|
+
@engine.context_object.assert_count += 1
|
|
30
|
+
if @engine.heap.it.is_true?
|
|
31
|
+
# Assertion passes
|
|
32
|
+
@engine.context_object.passed = true
|
|
33
|
+
return true
|
|
34
|
+
else
|
|
35
|
+
# Assertion fails
|
|
36
|
+
@engine.context_object.passed = false
|
|
37
|
+
@engine.context_object.add_message get_message
|
|
38
|
+
return false
|
|
39
|
+
end
|
|
40
|
+
rescue => ex
|
|
41
|
+
@engine.log_exception ex
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# Get the assertion message.
|
|
47
|
+
#
|
|
48
|
+
def get_message
|
|
49
|
+
if @tokens.token_count > 1
|
|
50
|
+
expr = Gloo::Expr::Expression.new( @engine, @tokens.params )
|
|
51
|
+
result = expr.evaluate
|
|
52
|
+
return result
|
|
53
|
+
end
|
|
54
|
+
return DEFAULT_MESSAGE
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# ---------------------------------------------------------------------
|
|
58
|
+
# Verb Documentation
|
|
59
|
+
# ---------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Get the verb's documentation data.
|
|
63
|
+
#
|
|
64
|
+
def self.doc_data
|
|
65
|
+
{
|
|
66
|
+
:name => KEYWORD,
|
|
67
|
+
:shortcut => KEYWORD_SHORT,
|
|
68
|
+
:description => 'Assert an expectation about the state or ' \
|
|
69
|
+
'results. The verb looks at the value of it. If it is true, ' \
|
|
70
|
+
'then the assertion passes, otherwise it fails.',
|
|
71
|
+
:syntax => [ 'assert {optional expectation message}' ],
|
|
72
|
+
:parameters => [
|
|
73
|
+
"optional expectation message — A textual statement about " \
|
|
74
|
+
"what was expected. Optional. If none provided the default " \
|
|
75
|
+
"\"#{DEFAULT_MESSAGE}\" will be shown."
|
|
76
|
+
],
|
|
77
|
+
:result => 'Validates an assumption and reports failures (or success).',
|
|
78
|
+
:examples => <<~EXAMPLES.strip
|
|
79
|
+
assert_noop [test] :
|
|
80
|
+
description [string] : Assert no operation
|
|
81
|
+
on_test [script] :
|
|
82
|
+
noop
|
|
83
|
+
assert 'noop should be true'
|
|
84
|
+
EXAMPLES
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
data/lib/gloo-test.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Shim to allow `require 'gloo-test'`
|
|
3
|
+
#
|
|
4
|
+
# This file is loaded when someone does `require 'gloo-test'`
|
|
5
|
+
#
|
|
6
|
+
require 'assert'
|
|
7
|
+
require 'refute'
|
|
8
|
+
require 'result'
|
|
9
|
+
require 'results'
|
|
10
|
+
require 'test_file'
|
|
11
|
+
require 'test_files'
|
|
12
|
+
require 'test_runner'
|
|
13
|
+
require 'test'
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Registers the extension.
|
|
17
|
+
#
|
|
18
|
+
class TestInit < Gloo::Plugin::Base
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Register verbs and objects.
|
|
22
|
+
#
|
|
23
|
+
def register( callback )
|
|
24
|
+
callback.register_obj( Test )
|
|
25
|
+
callback.register_verb( Assert )
|
|
26
|
+
callback.register_verb( Refute )
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
data/lib/refute.rb
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Refute that [it] is true.
|
|
3
|
+
# (Assert that [it] is false.)
|
|
4
|
+
#
|
|
5
|
+
class Refute < Gloo::Core::Verb
|
|
6
|
+
|
|
7
|
+
KEYWORD = 'refute'.freeze
|
|
8
|
+
KEYWORD_SHORT = 'expect_not'.freeze
|
|
9
|
+
DEFAULT_MESSAGE = 'Refutation failed'.freeze
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Get the Verb's keyword.
|
|
13
|
+
#
|
|
14
|
+
def self.keyword
|
|
15
|
+
return KEYWORD
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Get the Verb's keyword shortcut.
|
|
20
|
+
#
|
|
21
|
+
def self.keyword_shortcut
|
|
22
|
+
return KEYWORD_SHORT
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Run the verb.
|
|
27
|
+
#
|
|
28
|
+
def run
|
|
29
|
+
begin
|
|
30
|
+
@engine.context_object.refute_count += 1
|
|
31
|
+
if @engine.heap.it.is_false?
|
|
32
|
+
# Refutation passes
|
|
33
|
+
@engine.context_object.passed = true
|
|
34
|
+
return true
|
|
35
|
+
else
|
|
36
|
+
# Refutation fails
|
|
37
|
+
@engine.context_object.passed = false
|
|
38
|
+
@engine.context_object.add_message(get_message)
|
|
39
|
+
return false
|
|
40
|
+
end
|
|
41
|
+
rescue => ex
|
|
42
|
+
@engine.log_exception ex
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# Get the refutation message.
|
|
48
|
+
#
|
|
49
|
+
def get_message
|
|
50
|
+
if @tokens.token_count > 1
|
|
51
|
+
expr = Gloo::Expr::Expression.new( @engine, @tokens.params )
|
|
52
|
+
result = expr.evaluate
|
|
53
|
+
return result
|
|
54
|
+
end
|
|
55
|
+
return DEFAULT_MESSAGE
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# ---------------------------------------------------------------------
|
|
59
|
+
# Verb Documentation
|
|
60
|
+
# ---------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# Get the verb's documentation data.
|
|
64
|
+
#
|
|
65
|
+
def self.doc_data
|
|
66
|
+
{
|
|
67
|
+
:name => KEYWORD,
|
|
68
|
+
:shortcut => KEYWORD_SHORT,
|
|
69
|
+
:description => 'Refute an expectation about the state or ' \
|
|
70
|
+
'results. The verb looks at the value of it. If it is false, ' \
|
|
71
|
+
'then the assertion passes, otherwise it fails.',
|
|
72
|
+
:syntax => [ 'refute {optional expectation message}' ],
|
|
73
|
+
:parameters => [
|
|
74
|
+
"optional expectation message — A textual statement about " \
|
|
75
|
+
"what was NOT expected. Optional. If none provided the " \
|
|
76
|
+
"default \"#{DEFAULT_MESSAGE}\" will be shown."
|
|
77
|
+
],
|
|
78
|
+
:result => 'Validates a negative assumption and reports failures (or success).',
|
|
79
|
+
:examples => <<~EXAMPLES.strip
|
|
80
|
+
refute [test] :
|
|
81
|
+
description [string] : Refute an operation
|
|
82
|
+
on_test [script] :
|
|
83
|
+
eval false
|
|
84
|
+
refute 'false should be false'
|
|
85
|
+
EXAMPLES
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
data/lib/result.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#
|
|
2
|
+
# A gloo unit test result object.
|
|
3
|
+
# The result of a single test.
|
|
4
|
+
#
|
|
5
|
+
class Result
|
|
6
|
+
|
|
7
|
+
attr_accessor :passed, :assert_count, :refute_count
|
|
8
|
+
|
|
9
|
+
def initialize( engine, test )
|
|
10
|
+
@engine = engine
|
|
11
|
+
@test = test
|
|
12
|
+
@test_desc = test.test_desc
|
|
13
|
+
@pn = test.pn
|
|
14
|
+
|
|
15
|
+
@assert_count = 0
|
|
16
|
+
@refute_count = 0
|
|
17
|
+
|
|
18
|
+
@passed = true
|
|
19
|
+
@failure_msg = ''
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# Show the test result symbol.
|
|
24
|
+
#
|
|
25
|
+
def show_result_symbol
|
|
26
|
+
print @passed ? '.' : 'x'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# Add a failure message to the result.
|
|
31
|
+
#
|
|
32
|
+
def add_message(message)
|
|
33
|
+
@failure_msg += " " + message + "\n"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# Show the failure message.
|
|
38
|
+
#
|
|
39
|
+
def show_failure
|
|
40
|
+
puts "#{@pn} -> #{@test_desc}"
|
|
41
|
+
puts @failure_msg
|
|
42
|
+
puts
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/results.rb
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#
|
|
2
|
+
# A gloo unit test results collection.
|
|
3
|
+
# The results of a the set of tests run.
|
|
4
|
+
#
|
|
5
|
+
class Results
|
|
6
|
+
|
|
7
|
+
attr_accessor :file_count, :test_count,
|
|
8
|
+
:pass_count, :fail_count, :assert_count
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Set up the results collection.
|
|
12
|
+
#
|
|
13
|
+
def initialize( engine )
|
|
14
|
+
@engine = engine
|
|
15
|
+
|
|
16
|
+
@all_results = []
|
|
17
|
+
@failures = []
|
|
18
|
+
|
|
19
|
+
@file_count = 0
|
|
20
|
+
@pass_count = 0
|
|
21
|
+
@fail_count = 0
|
|
22
|
+
@assert_count = 0
|
|
23
|
+
|
|
24
|
+
@engine.log.debug "Results initialized"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# ---------------------------------------------------------------------
|
|
28
|
+
# Timer
|
|
29
|
+
# ---------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Set a timer to track test duration.
|
|
33
|
+
#
|
|
34
|
+
def start_timer
|
|
35
|
+
@start_time = Time.now
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# End the timer.
|
|
40
|
+
#
|
|
41
|
+
def end_timer
|
|
42
|
+
@end_time = Time.now
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# Get the duration of the test.
|
|
47
|
+
#
|
|
48
|
+
def duration
|
|
49
|
+
return @end_time - @start_time
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# ---------------------------------------------------------------------
|
|
54
|
+
# Results
|
|
55
|
+
# ---------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Add a result to the collection.
|
|
59
|
+
#
|
|
60
|
+
def add_result( result )
|
|
61
|
+
@all_results << result
|
|
62
|
+
@failures << result unless result.passed
|
|
63
|
+
|
|
64
|
+
@pass_count += 1 if result.passed
|
|
65
|
+
@fail_count += 1 unless result.passed
|
|
66
|
+
@assert_count += result.assert_count
|
|
67
|
+
@assert_count += result.refute_count
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# ---------------------------------------------------------------------
|
|
72
|
+
# Show Results
|
|
73
|
+
# ---------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
#
|
|
76
|
+
# Show the results.
|
|
77
|
+
#
|
|
78
|
+
def show_results
|
|
79
|
+
delta = duration.round( 2 )
|
|
80
|
+
puts
|
|
81
|
+
puts get_result_summary
|
|
82
|
+
puts "Tests finished in #{delta} seconds".white
|
|
83
|
+
puts
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
# Show the failures.
|
|
88
|
+
#
|
|
89
|
+
def show_failures
|
|
90
|
+
if @fail_count > 0
|
|
91
|
+
puts
|
|
92
|
+
puts "*** Failures (#{@fail_count}) ***".red
|
|
93
|
+
puts
|
|
94
|
+
@failures.each do |failure|
|
|
95
|
+
failure.show_failure
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
# Get a textual summary of the results.
|
|
102
|
+
#
|
|
103
|
+
def get_result_summary
|
|
104
|
+
str = "Tests: #{@all_results.length} • Passed: #{@pass_count} • ".white
|
|
105
|
+
if @fail_count > 0
|
|
106
|
+
str += " Failed: #{@fail_count} ".red
|
|
107
|
+
else
|
|
108
|
+
str += " Failed: #{@fail_count} ".white
|
|
109
|
+
end
|
|
110
|
+
str += "\n Assertions: #{@assert_count} • Files: #{@file_count}".yellow
|
|
111
|
+
return str
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
data/lib/test.rb
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#
|
|
2
|
+
# A gloo unit test object
|
|
3
|
+
#
|
|
4
|
+
class Test < Gloo::Core::Obj
|
|
5
|
+
|
|
6
|
+
KEYWORD = 'test'.freeze
|
|
7
|
+
TEST_DESC = 'description'.freeze
|
|
8
|
+
ON_TEST_EVENT = 'on_test'.freeze
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# The name of the object type.
|
|
13
|
+
#
|
|
14
|
+
def self.typename
|
|
15
|
+
return KEYWORD
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# The short name of the object type.
|
|
20
|
+
# Same as the typename.
|
|
21
|
+
#
|
|
22
|
+
def self.short_typename
|
|
23
|
+
return KEYWORD
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Get the test description.
|
|
28
|
+
#
|
|
29
|
+
def test_desc
|
|
30
|
+
o = find_child TEST_DESC
|
|
31
|
+
return o ? o.value : 'Unknown'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# ---------------------------------------------------------------------
|
|
36
|
+
# Children
|
|
37
|
+
# ---------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
# Does this object have children to add when an object
|
|
40
|
+
# is created in interactive mode?
|
|
41
|
+
# This does not apply during obj load, etc.
|
|
42
|
+
def add_children_on_create?
|
|
43
|
+
return true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Add children to this object.
|
|
47
|
+
# This is used by containers to add children needed
|
|
48
|
+
# for default configurations.
|
|
49
|
+
def add_default_children
|
|
50
|
+
fac = @engine.factory
|
|
51
|
+
fac.create_string TEST_DESC, '', self
|
|
52
|
+
fac.create_script ON_TEST_EVENT, '', self
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# ---------------------------------------------------------------------
|
|
57
|
+
# Messages
|
|
58
|
+
# ---------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# Get a list of message names that this object receives.
|
|
62
|
+
#
|
|
63
|
+
def self.messages
|
|
64
|
+
return super # + [ 'run' ]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Run the test.
|
|
69
|
+
#
|
|
70
|
+
def run_test
|
|
71
|
+
result = Result.new( @engine, self )
|
|
72
|
+
@engine.context_object = result
|
|
73
|
+
run_on_test
|
|
74
|
+
@engine.context_object = nil
|
|
75
|
+
|
|
76
|
+
result.show_result_symbol
|
|
77
|
+
|
|
78
|
+
return result
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# Run the on_test script.
|
|
83
|
+
#
|
|
84
|
+
def run_on_test
|
|
85
|
+
o = find_child ON_TEST_EVENT
|
|
86
|
+
return unless o
|
|
87
|
+
|
|
88
|
+
Gloo::Exec::Dispatch.message( @engine, 'run', o )
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# ---------------------------------------------------------------------
|
|
92
|
+
# Object Documentation
|
|
93
|
+
# ---------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
# Get the object's documentation data.
|
|
97
|
+
#
|
|
98
|
+
def self.doc_data
|
|
99
|
+
{
|
|
100
|
+
:name => KEYWORD,
|
|
101
|
+
:shortcut => KEYWORD,
|
|
102
|
+
:description => 'A single gloo test.',
|
|
103
|
+
:children => [
|
|
104
|
+
'description (string) — A textual description of the test and desired outcome, used in output if there is an error.',
|
|
105
|
+
'on_test (script) — The script to run when the test is executed. Note that the normal way to run tests is with gloo --test.'
|
|
106
|
+
],
|
|
107
|
+
:examples => <<~EXAMPLES.strip
|
|
108
|
+
#
|
|
109
|
+
# Basic tests
|
|
110
|
+
#
|
|
111
|
+
tests [can] :
|
|
112
|
+
basic [can] :
|
|
113
|
+
|
|
114
|
+
on_load [script] :
|
|
115
|
+
log 'Include functionality for all test in on_load' (debug)
|
|
116
|
+
|
|
117
|
+
assert_noop [test] :
|
|
118
|
+
description [string] : Assert no operation
|
|
119
|
+
on_test [script] :
|
|
120
|
+
noop
|
|
121
|
+
assert 'noop should be true'
|
|
122
|
+
EXAMPLES
|
|
123
|
+
}
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
data/lib/test_file.rb
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#
|
|
2
|
+
# A single Test File, might have multiple tests.
|
|
3
|
+
#
|
|
4
|
+
class TestFile
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# Set up the test file.
|
|
8
|
+
#
|
|
9
|
+
def initialize( engine, path_name )
|
|
10
|
+
@engine = engine
|
|
11
|
+
@path_name = path_name
|
|
12
|
+
|
|
13
|
+
@tests = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Execute all tests in this file and add results
|
|
18
|
+
# to the overall test results.
|
|
19
|
+
#
|
|
20
|
+
def run_tests( results )
|
|
21
|
+
# Load the test file
|
|
22
|
+
@engine.persist_man.load( @path_name )
|
|
23
|
+
# @engine.parser.run '.'
|
|
24
|
+
|
|
25
|
+
# Find all Test objects in the loaded file(s)
|
|
26
|
+
# The loaded file might have loaded other files
|
|
27
|
+
@tests = Gloo::Core::ObjFinder.by_type( @engine, 'test' )
|
|
28
|
+
|
|
29
|
+
# randomize the tests
|
|
30
|
+
@tests.shuffle!
|
|
31
|
+
|
|
32
|
+
# For each Test object, run its on_test script
|
|
33
|
+
@tests.each do |o|
|
|
34
|
+
result = o.run_test
|
|
35
|
+
results.add_result result
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Collect results from each test
|
|
39
|
+
|
|
40
|
+
# Aggregate result from test into overall results
|
|
41
|
+
|
|
42
|
+
# file.show_info
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# Get the number of tests run.
|
|
47
|
+
#
|
|
48
|
+
def tests_run_count
|
|
49
|
+
return @tests.length
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def show_info
|
|
53
|
+
puts "Test file: #{@path_name}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
data/lib/test_files.rb
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#
|
|
2
|
+
# The collection of Test Files.
|
|
3
|
+
#
|
|
4
|
+
class TestFiles
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
TEST_FILE_PATTERN = '**/*.test.gloo'
|
|
8
|
+
|
|
9
|
+
#
|
|
10
|
+
# Set up the test file.
|
|
11
|
+
#
|
|
12
|
+
def initialize( engine, input_files = nil )
|
|
13
|
+
@engine = engine
|
|
14
|
+
@input_files = input_files
|
|
15
|
+
@files = []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Detect test files.
|
|
20
|
+
#
|
|
21
|
+
def detect_files
|
|
22
|
+
@engine.log.debug "Detecting test files…"
|
|
23
|
+
|
|
24
|
+
if @input_files.length > 0
|
|
25
|
+
use_input_files
|
|
26
|
+
else
|
|
27
|
+
# Use the current directory
|
|
28
|
+
look_for_files_in Dir.pwd
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
@engine.log.debug "Found #{count} test files"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Use the files and or directories specified by the user.
|
|
36
|
+
#
|
|
37
|
+
def use_input_files
|
|
38
|
+
@engine.log.debug "Input files specified: #{@input_files}"
|
|
39
|
+
@input_files.each do |f|
|
|
40
|
+
@engine.log.debug "Test file specified: #{f}"
|
|
41
|
+
if Dir.exist?( f )
|
|
42
|
+
# Expand path for file
|
|
43
|
+
f = File.expand_path( f )
|
|
44
|
+
look_for_files_in f
|
|
45
|
+
elsif File.exist?( f )
|
|
46
|
+
add( f )
|
|
47
|
+
else
|
|
48
|
+
# TODO: Show error
|
|
49
|
+
puts "Test file does not exist: #{f}"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Look for test files in a directory.
|
|
56
|
+
# The directory might be provided as a parameter to the test runner,
|
|
57
|
+
# or if no parameter is provided, it is the current directory.
|
|
58
|
+
#
|
|
59
|
+
def look_for_files_in dir
|
|
60
|
+
@engine.log.debug "Looking for test files in: #{dir}"
|
|
61
|
+
root = File.join( dir, TEST_FILE_PATTERN )
|
|
62
|
+
files = Dir.glob( root )
|
|
63
|
+
@engine.log.debug "Found files: #{@files}"
|
|
64
|
+
files.each do |f|
|
|
65
|
+
@engine.log.debug "Found: #{f}"
|
|
66
|
+
add f
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Add a test file to the collection.
|
|
72
|
+
#
|
|
73
|
+
def add( file )
|
|
74
|
+
@files << TestFile.new( @engine, file )
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Randomize the order of the test files.
|
|
79
|
+
#
|
|
80
|
+
def randomize
|
|
81
|
+
@engine.log.debug "Randomizing test files…"
|
|
82
|
+
@files.shuffle!
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
#
|
|
86
|
+
# Get the number of test files.
|
|
87
|
+
#
|
|
88
|
+
def count
|
|
89
|
+
return @files.length
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# Iterator method for Enumerable interface.
|
|
94
|
+
#
|
|
95
|
+
def each(&block)
|
|
96
|
+
@files.each(&block)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
data/lib/test_runner.rb
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Test Runner.
|
|
3
|
+
#
|
|
4
|
+
class TestRunner
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Set up the test runner.
|
|
9
|
+
#
|
|
10
|
+
def initialize( engine, input_files = nil )
|
|
11
|
+
@engine = engine
|
|
12
|
+
|
|
13
|
+
@files = TestFiles.new( @engine, input_files )
|
|
14
|
+
@results = Results.new( @engine )
|
|
15
|
+
|
|
16
|
+
@engine.log.debug "TestRunner initialized"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Execute all tests and display results.
|
|
21
|
+
#
|
|
22
|
+
def run
|
|
23
|
+
setup
|
|
24
|
+
|
|
25
|
+
@results.start_timer
|
|
26
|
+
run_for_files
|
|
27
|
+
@results.end_timer
|
|
28
|
+
|
|
29
|
+
@results.show_failures
|
|
30
|
+
@results.show_results
|
|
31
|
+
@engine.log.debug "TestRunner is finished"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Set up the test runner.
|
|
36
|
+
#
|
|
37
|
+
def setup
|
|
38
|
+
@engine.log.debug "TestRunner is running…"
|
|
39
|
+
puts
|
|
40
|
+
puts "Gloo Test Runner".white
|
|
41
|
+
puts
|
|
42
|
+
|
|
43
|
+
# Get a list of test files and randomize
|
|
44
|
+
@files.detect_files
|
|
45
|
+
@results.file_count = @files.count
|
|
46
|
+
@files.randomize
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Run tests for each file.
|
|
51
|
+
#
|
|
52
|
+
def run_for_files
|
|
53
|
+
@files.each do |file|
|
|
54
|
+
run_one_file( file )
|
|
55
|
+
end
|
|
56
|
+
puts
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
#
|
|
60
|
+
# Run tests for a single file.
|
|
61
|
+
# Once done, reset the engine's state.
|
|
62
|
+
#
|
|
63
|
+
def run_one_file( file )
|
|
64
|
+
# Run all tests in the file
|
|
65
|
+
# Add the results to the overall results
|
|
66
|
+
file.run_tests( @results )
|
|
67
|
+
|
|
68
|
+
# Reset the engine's state
|
|
69
|
+
@engine.reset_state
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
metadata
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: gloo-test
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: '1.1'
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Eric Crane
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Adds Gloo Unit Test support to Gloo.
|
|
13
|
+
email:
|
|
14
|
+
- eric.crane@mac.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- README.md
|
|
20
|
+
- lib/assert.rb
|
|
21
|
+
- lib/gloo-test.rb
|
|
22
|
+
- lib/refute.rb
|
|
23
|
+
- lib/result.rb
|
|
24
|
+
- lib/results.rb
|
|
25
|
+
- lib/test.rb
|
|
26
|
+
- lib/test_file.rb
|
|
27
|
+
- lib/test_files.rb
|
|
28
|
+
- lib/test_runner.rb
|
|
29
|
+
homepage: https://github.com/ecrane/gloo
|
|
30
|
+
licenses:
|
|
31
|
+
- MIT
|
|
32
|
+
metadata:
|
|
33
|
+
gloo.type: core-library
|
|
34
|
+
documentation_uri: https://github.com/ecrane/gloo
|
|
35
|
+
rdoc_options: []
|
|
36
|
+
require_paths:
|
|
37
|
+
- lib
|
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0'
|
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
requirements: []
|
|
49
|
+
rubygems_version: 4.0.17
|
|
50
|
+
specification_version: 4
|
|
51
|
+
summary: Gloo core library. Gloo Unit Test support.
|
|
52
|
+
test_files: []
|