test_bench-fixture 1.0.0.0 → 1.2.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 +4 -4
- data/lib/test_bench/fixture.rb +2 -1
- data/lib/test_bench/fixture/controls.rb +1 -0
- data/lib/test_bench/fixture/controls/output.rb +4 -4
- data/lib/test_bench/fixture/controls/output/log.rb +45 -0
- data/lib/test_bench/fixture/fixture.rb +46 -32
- data/lib/test_bench/fixture/output.rb +6 -5
- data/lib/test_bench/fixture/output/capture.rb +113 -0
- data/lib/test_bench/fixture/output/log.rb +44 -11
- data/lib/test_bench/fixture/output/substitute.rb +66 -93
- data/lib/test_bench/fixture/output/substitute/scope.rb +26 -0
- data/lib/test_bench/fixture/session.rb +26 -30
- data/lib/test_bench/fixture/session/substitute.rb +70 -69
- metadata +10 -8
- data/lib/test_bench/fixture/session/substitute/match_tests.rb +0 -131
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c2788177e5994201a774ce4374a65458fe9e6e5c5d2d2066000c5034f56b087
|
4
|
+
data.tar.gz: 53b44687d4060b69a9b3a4504a6b1c79f954179d29560df78dde4916b73ae4c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d44875275551502895a4ffa113712e477bdfe7e4e2348f1f28619a7112b7389d8f3b2d8d908aa1ae6af54d67c564a5221b7c880d4d9122b9e9f6d944ac83de5b
|
7
|
+
data.tar.gz: 1250a8026381d3c393f407e2799cc33fcc79b523fa070ffe54ee88661296a98150dc98a4a6ff9f1e74000788cd71ccf922763b9a80c6876a7159924973b775ef
|
data/lib/test_bench/fixture.rb
CHANGED
@@ -6,13 +6,14 @@ require 'test_bench/fixture/assertion_failure'
|
|
6
6
|
require 'test_bench/fixture/output'
|
7
7
|
require 'test_bench/fixture/output/null'
|
8
8
|
require 'test_bench/fixture/output/log'
|
9
|
+
require 'test_bench/fixture/output/capture'
|
9
10
|
require 'test_bench/fixture/output/substitute'
|
11
|
+
require 'test_bench/fixture/output/substitute/scope'
|
10
12
|
require 'test_bench/fixture/output/multiple'
|
11
13
|
|
12
14
|
require 'test_bench/fixture/error_policy'
|
13
15
|
|
14
16
|
require 'test_bench/fixture/session'
|
15
17
|
require 'test_bench/fixture/session/substitute'
|
16
|
-
require 'test_bench/fixture/session/substitute/match_tests'
|
17
18
|
|
18
19
|
require 'test_bench/fixture/fixture'
|
@@ -34,27 +34,27 @@ module TestBench
|
|
34
34
|
caller_location = Controls::CallerLocation.example
|
35
35
|
error = Controls::Error.example
|
36
36
|
comment_text = 'Some comment'
|
37
|
+
detail_text = 'Some detail'
|
37
38
|
test_title = 'Some test'
|
38
39
|
context_title = 'Some Context'
|
39
40
|
|
40
41
|
{
|
41
42
|
:start => [],
|
42
|
-
:finish => [result],
|
43
43
|
:enter_file => [path],
|
44
44
|
:exit_file => [path, result],
|
45
45
|
:start_fixture => [fixture],
|
46
46
|
:finish_fixture => [fixture, result],
|
47
47
|
:assert => [result, caller_location],
|
48
|
-
:enter_assert_block => [caller_location],
|
49
|
-
:exit_assert_block => [caller_location, result],
|
50
48
|
:comment => [comment_text],
|
49
|
+
:detail => [detail_text],
|
51
50
|
:error => [error],
|
52
51
|
:start_test => [test_title],
|
53
52
|
:finish_test => [test_title, result],
|
54
53
|
:skip_test => [test_title],
|
55
54
|
:enter_context => [context_title],
|
56
55
|
:exit_context => [context_title, result],
|
57
|
-
:skip_context => [context_title]
|
56
|
+
:skip_context => [context_title],
|
57
|
+
:finish => [result]
|
58
58
|
}.each(&block)
|
59
59
|
end
|
60
60
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module TestBench
|
2
|
+
module Fixture
|
3
|
+
module Controls
|
4
|
+
module Output
|
5
|
+
module Log
|
6
|
+
module Level
|
7
|
+
def self.example
|
8
|
+
fatal
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.unknown
|
12
|
+
:unknown
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.fatal
|
16
|
+
:fatal
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.error
|
20
|
+
:error
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.warning
|
24
|
+
:warning
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.info
|
28
|
+
:info
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.debug
|
32
|
+
:debug
|
33
|
+
end
|
34
|
+
|
35
|
+
module Invalid
|
36
|
+
def self.example
|
37
|
+
:not_a_log_level
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -3,6 +3,8 @@ module TestBench
|
|
3
3
|
Error = Class.new(RuntimeError)
|
4
4
|
|
5
5
|
def self.build(cls, *args, session: nil, output: nil, error_policy: nil, factory_method: nil, **kwargs, &block)
|
6
|
+
assure_fixture(cls)
|
7
|
+
|
6
8
|
factory_method = factory_method(cls)
|
7
9
|
|
8
10
|
if kwargs.empty?
|
@@ -16,6 +18,12 @@ module TestBench
|
|
16
18
|
instance
|
17
19
|
end
|
18
20
|
|
21
|
+
def self.assure_fixture(cls)
|
22
|
+
unless cls.included_modules.include?(self)
|
23
|
+
raise Error, "Not a fixture class (Class: #{cls.inspect})"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
19
27
|
def self.factory_method(cls)
|
20
28
|
if cls.respond_to?(:build)
|
21
29
|
cls.method(:build)
|
@@ -54,19 +62,14 @@ module TestBench
|
|
54
62
|
test_session.comment(text)
|
55
63
|
end
|
56
64
|
|
57
|
-
|
58
|
-
|
59
|
-
|
65
|
+
def detail(text)
|
66
|
+
test_session.detail(text)
|
67
|
+
end
|
60
68
|
|
61
|
-
|
62
|
-
|
63
|
-
raise ArgumentError, "Must supply a boolean value or a block (but not both)"
|
64
|
-
end
|
69
|
+
def assert(value, caller_location: nil)
|
70
|
+
caller_location ||= caller_locations.first
|
65
71
|
|
66
|
-
|
67
|
-
else
|
68
|
-
test_session.assert_block(caller_location: caller_location, &block)
|
69
|
-
end
|
72
|
+
test_session.assert(value, caller_location: caller_location)
|
70
73
|
end
|
71
74
|
|
72
75
|
def refute(value, caller_location: nil)
|
@@ -85,24 +88,30 @@ module TestBench
|
|
85
88
|
|
86
89
|
caller_location ||= caller_locations.first
|
87
90
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
+
detail "Expected Error: #{error_class}#{' (strict)' if strict}"
|
92
|
+
detail "Expected Message: #{message.inspect}" unless message.nil?
|
93
|
+
|
94
|
+
block.()
|
91
95
|
|
92
|
-
|
96
|
+
detail "(No error was raised)"
|
93
97
|
|
94
|
-
|
98
|
+
assert(false, caller_location: caller_location)
|
95
99
|
|
96
|
-
|
100
|
+
rescue error_class => error
|
97
101
|
|
98
|
-
|
102
|
+
detail "Raised error: #{error.inspect}#{" (subclass of #{error_class})" if error.class < error_class}"
|
99
103
|
|
100
|
-
|
101
|
-
|
102
|
-
|
104
|
+
if strict && !error.instance_of?(error_class)
|
105
|
+
raise error
|
106
|
+
end
|
103
107
|
|
104
|
-
|
108
|
+
if message.nil?
|
109
|
+
result = true
|
110
|
+
else
|
111
|
+
result = error.message == message
|
105
112
|
end
|
113
|
+
|
114
|
+
assert(result, caller_location: caller_location)
|
106
115
|
end
|
107
116
|
|
108
117
|
def refute_raises(error_class=nil, strict: nil, caller_location: nil, &block)
|
@@ -115,22 +124,27 @@ module TestBench
|
|
115
124
|
|
116
125
|
caller_location ||= caller_locations.first
|
117
126
|
|
118
|
-
|
119
|
-
|
127
|
+
detail "Prohibited Error: #{error_class}#{' (strict)' if strict}"
|
128
|
+
|
129
|
+
block.()
|
120
130
|
|
121
|
-
|
131
|
+
detail "(No error was raised)"
|
122
132
|
|
123
|
-
|
133
|
+
result = true
|
124
134
|
|
125
|
-
|
135
|
+
rescue error_class => error
|
126
136
|
|
127
|
-
|
137
|
+
detail "Raised Error: #{error.inspect}"
|
138
|
+
|
139
|
+
if strict && !error.instance_of?(error_class)
|
140
|
+
raise error
|
141
|
+
end
|
128
142
|
|
129
|
-
|
143
|
+
result = false
|
130
144
|
|
131
|
-
|
132
|
-
|
133
|
-
|
145
|
+
ensure
|
146
|
+
unless result.nil?
|
147
|
+
assert(result, caller_location: caller_location)
|
134
148
|
end
|
135
149
|
end
|
136
150
|
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module TestBench
|
2
2
|
module Fixture
|
3
3
|
module Output
|
4
|
+
def self.signals
|
5
|
+
instance_methods(false)
|
6
|
+
end
|
7
|
+
|
4
8
|
def start
|
5
9
|
end
|
6
10
|
|
@@ -22,13 +26,10 @@ module TestBench
|
|
22
26
|
def assert(result, caller_location)
|
23
27
|
end
|
24
28
|
|
25
|
-
def
|
26
|
-
end
|
27
|
-
|
28
|
-
def exit_assert_block(result, caller_location)
|
29
|
+
def comment(text)
|
29
30
|
end
|
30
31
|
|
31
|
-
def
|
32
|
+
def detail(text)
|
32
33
|
end
|
33
34
|
|
34
35
|
def error(error)
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module TestBench
|
2
|
+
module Fixture
|
3
|
+
module Output
|
4
|
+
class Capture
|
5
|
+
include Fixture::Output
|
6
|
+
|
7
|
+
def records
|
8
|
+
@records ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def current_context
|
12
|
+
@current_context ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
record(:start)
|
17
|
+
end
|
18
|
+
|
19
|
+
def finish(result)
|
20
|
+
record(:finish, result)
|
21
|
+
end
|
22
|
+
|
23
|
+
def enter_file(path)
|
24
|
+
record(:enter_file, path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def exit_file(path, result)
|
28
|
+
record(:exit_file, path, result)
|
29
|
+
end
|
30
|
+
|
31
|
+
def start_fixture(fixture)
|
32
|
+
record(:start_fixture, fixture)
|
33
|
+
end
|
34
|
+
|
35
|
+
def finish_fixture(fixture, result)
|
36
|
+
record(:finish_fixture, fixture, result)
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert(result, caller_location)
|
40
|
+
record(:assert, result, caller_location)
|
41
|
+
end
|
42
|
+
|
43
|
+
def comment(text)
|
44
|
+
record(:comment, text)
|
45
|
+
end
|
46
|
+
|
47
|
+
def detail(text)
|
48
|
+
record(:detail, text)
|
49
|
+
end
|
50
|
+
|
51
|
+
def error(error)
|
52
|
+
record(:error, error)
|
53
|
+
end
|
54
|
+
|
55
|
+
def start_test(title)
|
56
|
+
record(:start_test, title)
|
57
|
+
end
|
58
|
+
|
59
|
+
def finish_test(title, result)
|
60
|
+
record(:finish_test, title, result)
|
61
|
+
end
|
62
|
+
|
63
|
+
def skip_test(title)
|
64
|
+
record(:skip_test, title)
|
65
|
+
end
|
66
|
+
|
67
|
+
def enter_context(title)
|
68
|
+
record = record(:enter_context, title)
|
69
|
+
|
70
|
+
unless title.nil?
|
71
|
+
current_context.push(title)
|
72
|
+
end
|
73
|
+
|
74
|
+
record
|
75
|
+
end
|
76
|
+
|
77
|
+
def exit_context(title, result)
|
78
|
+
unless title.nil?
|
79
|
+
current_context.pop
|
80
|
+
end
|
81
|
+
|
82
|
+
record(:exit_context, title, result)
|
83
|
+
end
|
84
|
+
|
85
|
+
def skip_context(title)
|
86
|
+
record(:skip_context, title)
|
87
|
+
end
|
88
|
+
|
89
|
+
def each_record(&block)
|
90
|
+
records.each(&block)
|
91
|
+
end
|
92
|
+
|
93
|
+
def record(signal, *data)
|
94
|
+
record = new_record(signal, data)
|
95
|
+
records << record
|
96
|
+
record
|
97
|
+
end
|
98
|
+
|
99
|
+
def new_record(signal, data)
|
100
|
+
context = current_context.dup
|
101
|
+
|
102
|
+
record = Record.new(signal, data, context)
|
103
|
+
end
|
104
|
+
|
105
|
+
Record = Struct.new(:signal, :data, :context) do
|
106
|
+
def forward(receiver)
|
107
|
+
receiver.public_send(signal, *data)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -4,28 +4,65 @@ module TestBench
|
|
4
4
|
class Log
|
5
5
|
include Output
|
6
6
|
|
7
|
+
Error = Class.new(RuntimeError)
|
8
|
+
|
7
9
|
attr_reader :logger
|
8
10
|
|
9
11
|
def initialize(logger)
|
10
12
|
@logger = logger
|
11
13
|
end
|
12
14
|
|
13
|
-
def self.build(device=nil)
|
15
|
+
def self.build(device=nil, level: nil)
|
14
16
|
device ||= $stderr
|
17
|
+
level ||= self.default_level
|
18
|
+
|
19
|
+
level_ordinal = level_ordinal(level)
|
15
20
|
|
16
21
|
logger = Logger.new(device)
|
22
|
+
logger.level = level_ordinal
|
17
23
|
|
18
24
|
new(logger)
|
19
25
|
end
|
20
26
|
|
21
|
-
def self.configure(receiver, device=nil, attr_name: nil)
|
27
|
+
def self.configure(receiver, device=nil, level: nil, attr_name: nil)
|
22
28
|
attr_name ||= :output
|
23
29
|
|
24
|
-
instance = build(device)
|
30
|
+
instance = build(device, level: level)
|
25
31
|
receiver.public_send(:"#{attr_name}=", instance)
|
26
32
|
instance
|
27
33
|
end
|
28
34
|
|
35
|
+
def self.default_level
|
36
|
+
:debug
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.levels
|
40
|
+
level_ordinals.keys
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.level_ordinal(level)
|
44
|
+
assure_level(level)
|
45
|
+
|
46
|
+
level_ordinals.fetch(level)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.level_ordinals
|
50
|
+
{
|
51
|
+
:unknown => Logger::Severity::UNKNOWN,
|
52
|
+
:fatal => Logger::Severity::FATAL,
|
53
|
+
:error => Logger::Severity::ERROR,
|
54
|
+
:warning => Logger::Severity::WARN,
|
55
|
+
:info => Logger::Severity::INFO,
|
56
|
+
:debug => Logger::Severity::DEBUG
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.assure_level(level)
|
61
|
+
unless level_ordinals.key?(level)
|
62
|
+
raise Error, "Unknown log level #{level.inspect} (Valid levels: #{levels.map(&:inspect) * ', '})"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
29
66
|
def start
|
30
67
|
logger.debug { "Start" }
|
31
68
|
end
|
@@ -54,18 +91,14 @@ module TestBench
|
|
54
91
|
logger.info { "Assertion (Result: #{result}, Caller Location: #{caller_location})" }
|
55
92
|
end
|
56
93
|
|
57
|
-
def enter_assert_block(caller_location)
|
58
|
-
logger.debug { "Entering assert block (Caller Location: #{caller_location})" }
|
59
|
-
end
|
60
|
-
|
61
|
-
def exit_assert_block(caller_location, result)
|
62
|
-
logger.info { "Exited assert block (Caller Location: #{caller_location}, Result: #{result})" }
|
63
|
-
end
|
64
|
-
|
65
94
|
def comment(text)
|
66
95
|
logger.info { "Comment (Text: #{text})" }
|
67
96
|
end
|
68
97
|
|
98
|
+
def detail(text)
|
99
|
+
logger.debug { "Detail (Text: #{text})" }
|
100
|
+
end
|
101
|
+
|
69
102
|
def error(error)
|
70
103
|
logger.error { "Error (Error: #{error})" }
|
71
104
|
end
|
@@ -8,132 +8,105 @@ module TestBench
|
|
8
8
|
|
9
9
|
MatchError = Class.new(RuntimeError)
|
10
10
|
|
11
|
-
class Output
|
12
|
-
|
11
|
+
class Output < Capture
|
12
|
+
alias_method :raw_records, :records
|
13
13
|
|
14
|
-
def
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def start
|
19
|
-
record(:start)
|
20
|
-
end
|
14
|
+
def scope(*contexts, &block)
|
15
|
+
records = records(*contexts, &block)
|
21
16
|
|
22
|
-
|
23
|
-
record(:finish, result)
|
17
|
+
Scope.build(records)
|
24
18
|
end
|
25
19
|
|
26
|
-
def
|
27
|
-
record(
|
28
|
-
end
|
20
|
+
def recorded_once?(*contexts, &block)
|
21
|
+
record = one_record(*contexts, &block)
|
29
22
|
|
30
|
-
|
31
|
-
record(:exit_file, path, result)
|
23
|
+
record ? true : false
|
32
24
|
end
|
33
25
|
|
34
|
-
def
|
35
|
-
|
36
|
-
end
|
26
|
+
def recorded?(*contexts, &block)
|
27
|
+
records = match_records(*contexts, &block)
|
37
28
|
|
38
|
-
|
39
|
-
record(:finish_fixture, fixture, result)
|
29
|
+
records.any?
|
40
30
|
end
|
41
31
|
|
42
|
-
def
|
43
|
-
|
44
|
-
end
|
32
|
+
def one_record(*contexts, &block)
|
33
|
+
matching_records = match_records(*contexts, &block)
|
45
34
|
|
46
|
-
|
47
|
-
record(:enter_assert_block, caller_location)
|
48
|
-
end
|
49
|
-
|
50
|
-
def exit_assert_block(caller_location, result)
|
51
|
-
record(:exit_assert_block, caller_location, result)
|
52
|
-
end
|
53
|
-
|
54
|
-
def comment(text)
|
55
|
-
record(:comment, text)
|
56
|
-
end
|
35
|
+
return if matching_records.empty?
|
57
36
|
|
58
|
-
|
59
|
-
|
60
|
-
|
37
|
+
unless matching_records.one?
|
38
|
+
raise MatchError, "More than one records match"
|
39
|
+
end
|
61
40
|
|
62
|
-
|
63
|
-
record(:start_test, title)
|
41
|
+
matching_records.shift
|
64
42
|
end
|
65
43
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
44
|
+
def records(*contexts, &block)
|
45
|
+
if contexts.empty? && block.nil?
|
46
|
+
return raw_records
|
47
|
+
end
|
69
48
|
|
70
|
-
|
71
|
-
record(:skip_test, title)
|
49
|
+
match_records(*contexts, &block)
|
72
50
|
end
|
73
51
|
|
74
|
-
def
|
75
|
-
|
76
|
-
end
|
52
|
+
def match_records(*contexts, &block)
|
53
|
+
block ||= proc { true }
|
77
54
|
|
78
|
-
|
79
|
-
|
80
|
-
end
|
55
|
+
raw_records.select do |record|
|
56
|
+
context_iterator = record.context.to_enum
|
81
57
|
|
82
|
-
|
83
|
-
|
84
|
-
|
58
|
+
contexts_match = contexts.all? do |context|
|
59
|
+
until context_iterator.peek == context
|
60
|
+
context_iterator.next
|
61
|
+
end
|
62
|
+
true
|
85
63
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
record
|
90
|
-
end
|
64
|
+
rescue StopIteration
|
65
|
+
false
|
66
|
+
end
|
91
67
|
|
92
|
-
|
93
|
-
|
94
|
-
output.public_send(record.signal, *record.data)
|
68
|
+
contexts_match &&
|
69
|
+
block.(record.signal, *record.data, record.context)
|
95
70
|
end
|
96
71
|
end
|
97
72
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
def one_record(signal=nil, &block)
|
107
|
-
matching_records = matching_records(signal, &block)
|
108
|
-
|
109
|
-
return if matching_records.empty?
|
110
|
-
|
111
|
-
unless matching_records.one?
|
112
|
-
raise MatchError, "More than one records match"
|
73
|
+
Fixture::Output.signals.each do |signal|
|
74
|
+
signal_records_method = :"#{signal}_records" # e.g. comment_records
|
75
|
+
define_method(signal_records_method) do |*contexts, &block|
|
76
|
+
match_records(*contexts) do |recorded_signal, *data|
|
77
|
+
if recorded_signal == signal
|
78
|
+
block.nil? || block.(*data)
|
79
|
+
end
|
80
|
+
end
|
113
81
|
end
|
114
82
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
83
|
+
one_signal_method = :"one_#{signal}_record" # e.g. one_comment_record
|
84
|
+
define_method(one_signal_method) do |*contexts, &block|
|
85
|
+
one_record(*contexts) do |recorded_signal, *data|
|
86
|
+
if recorded_signal == signal
|
87
|
+
block.nil? || block.(*data)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
121
91
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
92
|
+
signal_recorded_method = :"#{signal}_recorded?" # e.g. comment_recorded?
|
93
|
+
define_method(signal_recorded_method) do |*contexts, &block|
|
94
|
+
recorded?(*contexts) do |recorded_signal, *data|
|
95
|
+
if recorded_signal == signal
|
96
|
+
block.nil? || block.(*data)
|
127
97
|
end
|
128
|
-
|
98
|
+
end
|
129
99
|
end
|
130
100
|
|
131
|
-
|
132
|
-
|
101
|
+
signal_recorded_once_method = :"#{signal}_recorded_once?" # e.g. comment_recorded_once?
|
102
|
+
define_method(signal_recorded_once_method) do |*contexts, &block|
|
103
|
+
recorded_once?(*contexts) do |recorded_signal, *data|
|
104
|
+
if recorded_signal == signal
|
105
|
+
block.nil? || block.(*data)
|
106
|
+
end
|
107
|
+
end
|
133
108
|
end
|
134
109
|
end
|
135
|
-
|
136
|
-
Record = Struct.new(:signal, :data)
|
137
110
|
end
|
138
111
|
end
|
139
112
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module TestBench
|
2
|
+
module Fixture
|
3
|
+
module Output
|
4
|
+
module Substitute
|
5
|
+
class Output
|
6
|
+
class Scope < Output
|
7
|
+
attr_writer :records
|
8
|
+
|
9
|
+
def self.build(records)
|
10
|
+
instance = new
|
11
|
+
instance.records = records
|
12
|
+
instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def combine(scope)
|
16
|
+
combined_records = self.records + scope.records
|
17
|
+
|
18
|
+
Scope.build(combined_records)
|
19
|
+
end
|
20
|
+
alias_method :+, :combine
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -13,6 +13,12 @@ module TestBench
|
|
13
13
|
end
|
14
14
|
attr_writer :error_counter
|
15
15
|
|
16
|
+
def skip
|
17
|
+
@skip ||= false
|
18
|
+
end
|
19
|
+
attr_writer :skip
|
20
|
+
alias_method :skip?, :skip
|
21
|
+
|
16
22
|
def started
|
17
23
|
instance_variable_defined?(:@started) ?
|
18
24
|
@started :
|
@@ -95,6 +101,10 @@ module TestBench
|
|
95
101
|
output.comment(text)
|
96
102
|
end
|
97
103
|
|
104
|
+
def detail(text)
|
105
|
+
output.detail(text)
|
106
|
+
end
|
107
|
+
|
98
108
|
def error(error)
|
99
109
|
fail!
|
100
110
|
|
@@ -122,35 +132,6 @@ module TestBench
|
|
122
132
|
result
|
123
133
|
end
|
124
134
|
|
125
|
-
def assert_block(caller_location: nil, &block)
|
126
|
-
caller_location ||= caller_locations.first
|
127
|
-
|
128
|
-
previous_error_counter = self.error_counter
|
129
|
-
previous_assertion_counter = self.assertion_counter
|
130
|
-
|
131
|
-
output.enter_assert_block(caller_location)
|
132
|
-
|
133
|
-
begin
|
134
|
-
block.()
|
135
|
-
|
136
|
-
ensure
|
137
|
-
if self.error_counter > previous_error_counter
|
138
|
-
result = false
|
139
|
-
elsif self.assertion_counter == previous_assertion_counter
|
140
|
-
result = false
|
141
|
-
else
|
142
|
-
result = true
|
143
|
-
end
|
144
|
-
|
145
|
-
output.exit_assert_block(caller_location, result)
|
146
|
-
|
147
|
-
current_exception = $!
|
148
|
-
if current_exception.nil? || current_exception.instance_of?(AssertionFailure)
|
149
|
-
assert(result, caller_location: caller_location)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
135
|
def load(path)
|
155
136
|
output.enter_file(path)
|
156
137
|
|
@@ -171,7 +152,17 @@ module TestBench
|
|
171
152
|
|
172
153
|
output.start_test(title)
|
173
154
|
|
174
|
-
|
155
|
+
previous_assertion_counter = self.assertion_counter
|
156
|
+
|
157
|
+
action = proc {
|
158
|
+
block.()
|
159
|
+
|
160
|
+
unless assertion_counter > previous_assertion_counter
|
161
|
+
raise Error, "Test did not perform an assertion"
|
162
|
+
end
|
163
|
+
}
|
164
|
+
|
165
|
+
evaluate(action) do |result|
|
175
166
|
output.finish_test(title, result)
|
176
167
|
end
|
177
168
|
end
|
@@ -235,12 +226,17 @@ module TestBench
|
|
235
226
|
end
|
236
227
|
|
237
228
|
def fail!
|
229
|
+
self.assertion_counter += 1
|
238
230
|
self.error_counter += 1
|
239
231
|
end
|
240
232
|
|
241
233
|
def failed?
|
242
234
|
error_counter.nonzero? ? true : false
|
243
235
|
end
|
236
|
+
|
237
|
+
def skip!
|
238
|
+
self.skip = true
|
239
|
+
end
|
244
240
|
end
|
245
241
|
end
|
246
242
|
end
|
@@ -7,117 +7,118 @@ module TestBench
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class Session < Session
|
10
|
-
|
10
|
+
def scope(*contexts)
|
11
|
+
scoped_output = output.scope(*contexts)
|
11
12
|
|
12
|
-
|
13
|
+
return nil if scoped_output.records.empty?
|
13
14
|
|
14
|
-
|
15
|
-
output
|
16
|
-
|
17
|
-
end
|
15
|
+
scoped_session = self.class.new
|
16
|
+
scoped_session.output = scoped_output
|
17
|
+
scoped_session
|
18
18
|
end
|
19
|
+
alias_method :[], :scope
|
19
20
|
|
20
|
-
def
|
21
|
-
output.
|
22
|
-
|
23
|
-
(caller_location.nil? || cl == caller_location)
|
21
|
+
def context?(*outer_contexts, title)
|
22
|
+
output.exit_context_recorded_once?(*outer_contexts) do |t|
|
23
|
+
t == title
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
27
|
+
def one_test_passed?(*contexts, title)
|
28
|
+
one_test?(*contexts, title) do |_, result|
|
29
|
+
result == true
|
30
|
+
end
|
29
31
|
end
|
30
32
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
def one_test_failed?(*contexts, title)
|
34
|
+
one_test?(*contexts, title) do |_, result|
|
35
|
+
result == false
|
36
|
+
end
|
37
|
+
end
|
35
38
|
|
36
|
-
|
39
|
+
def one_test?(*contexts, title, &block)
|
40
|
+
test_scope = test_scope(*contexts, title)
|
37
41
|
|
38
|
-
|
42
|
+
test_scope.finish_test_recorded_once?(&block)
|
39
43
|
end
|
40
44
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
45
|
+
def any_test_passed?(*contexts, title)
|
46
|
+
any_test?(*contexts, title) do |_, result|
|
47
|
+
result == true
|
44
48
|
end
|
45
49
|
end
|
50
|
+
alias_method :test_passed?, :any_test_passed?
|
46
51
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
52
|
+
def any_test_failed?(*contexts, title)
|
53
|
+
any_test?(*contexts, title) do |_, result|
|
54
|
+
result == false
|
50
55
|
end
|
51
56
|
end
|
57
|
+
alias_method :test_failed?, :any_test_failed?
|
52
58
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
def any_test?(*contexts, title, &block)
|
60
|
+
test_scope = test_scope(*contexts, title)
|
61
|
+
|
62
|
+
test_scope.finish_test_recorded?(&block)
|
57
63
|
end
|
64
|
+
alias_method :test?, :any_test?
|
58
65
|
|
59
|
-
def
|
60
|
-
output.
|
61
|
-
|
66
|
+
def commented?(*contexts, text)
|
67
|
+
output.comment_recorded?(*contexts) do |t|
|
68
|
+
t == text
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
65
|
-
def
|
66
|
-
|
72
|
+
def detail?(*contexts, text)
|
73
|
+
output.detail_recorded?(*contexts) do |t|
|
74
|
+
t == text
|
75
|
+
end
|
67
76
|
end
|
68
77
|
|
69
|
-
def
|
70
|
-
|
78
|
+
def asserted?(*contexts, result: nil, caller_location: nil)
|
79
|
+
output.assert_recorded?(*contexts) do |r, cl|
|
80
|
+
result_match = result.nil? || r == result
|
81
|
+
caller_location_match = caller_location.nil? || cl == caller_location
|
71
82
|
|
72
|
-
|
83
|
+
result_match && caller_location_match
|
84
|
+
end
|
73
85
|
end
|
74
86
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
if passes.count > 1
|
79
|
-
raise Error, "Multiple passing tests match (Titles: #{titles.inspect})"
|
80
|
-
end
|
87
|
+
def load(path)
|
88
|
+
output.enter_file(path)
|
81
89
|
|
82
|
-
|
83
|
-
|
90
|
+
inert_action = proc { }
|
91
|
+
result = evaluate(inert_action)
|
84
92
|
|
85
|
-
|
86
|
-
one_pass(*titles) ? true : false
|
87
|
-
end
|
93
|
+
output.exit_file(path, result)
|
88
94
|
|
89
|
-
|
90
|
-
passes(*titles).first
|
95
|
+
result
|
91
96
|
end
|
92
97
|
|
93
|
-
def
|
94
|
-
|
98
|
+
def loaded?(path=nil)
|
99
|
+
output.enter_file_recorded? do |p|
|
100
|
+
path.nil? || p == path
|
101
|
+
end
|
95
102
|
end
|
96
103
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
if failures.count > 1
|
101
|
-
raise Error, "Multiple failing tests match (Titles: #{titles.inspect})"
|
104
|
+
def fixture?(fixture)
|
105
|
+
output.finish_fixture_recorded? do |f|
|
106
|
+
f == fixture
|
102
107
|
end
|
103
|
-
|
104
|
-
failures.first
|
105
108
|
end
|
106
109
|
|
107
|
-
def
|
108
|
-
|
109
|
-
end
|
110
|
+
def test_scope(*contexts, title)
|
111
|
+
context_scope = output.scope(*contexts)
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
-
|
113
|
+
titled_test_scope = context_scope.scope do |signal, t|
|
114
|
+
signal == :finish_test && t == title
|
115
|
+
end
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
-
|
117
|
+
untitled_test_scope = context_scope.scope(title) do |signal, t|
|
118
|
+
signal == :finish_test && t.nil?
|
119
|
+
end
|
118
120
|
|
119
|
-
|
120
|
-
MatchTests.(self, *titles, result: result)
|
121
|
+
titled_test_scope + untitled_test_scope
|
121
122
|
end
|
122
123
|
end
|
123
124
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test_bench-fixture
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Ladd
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test_bench-bootstrap
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
description:
|
27
|
+
description:
|
28
28
|
email: nathanladd+github@gmail.com
|
29
29
|
executables: []
|
30
30
|
extensions: []
|
@@ -38,23 +38,25 @@ files:
|
|
38
38
|
- lib/test_bench/fixture/controls/error/backtrace.rb
|
39
39
|
- lib/test_bench/fixture/controls/fixture.rb
|
40
40
|
- lib/test_bench/fixture/controls/output.rb
|
41
|
+
- lib/test_bench/fixture/controls/output/log.rb
|
41
42
|
- lib/test_bench/fixture/controls/result.rb
|
42
43
|
- lib/test_bench/fixture/controls/test_file.rb
|
43
44
|
- lib/test_bench/fixture/error_policy.rb
|
44
45
|
- lib/test_bench/fixture/fixture.rb
|
45
46
|
- lib/test_bench/fixture/output.rb
|
47
|
+
- lib/test_bench/fixture/output/capture.rb
|
46
48
|
- lib/test_bench/fixture/output/log.rb
|
47
49
|
- lib/test_bench/fixture/output/multiple.rb
|
48
50
|
- lib/test_bench/fixture/output/null.rb
|
49
51
|
- lib/test_bench/fixture/output/substitute.rb
|
52
|
+
- lib/test_bench/fixture/output/substitute/scope.rb
|
50
53
|
- lib/test_bench/fixture/session.rb
|
51
54
|
- lib/test_bench/fixture/session/substitute.rb
|
52
|
-
- lib/test_bench/fixture/session/substitute/match_tests.rb
|
53
55
|
homepage: https://github.com/test-bench/test-bench-fixture
|
54
56
|
licenses:
|
55
57
|
- MIT
|
56
58
|
metadata: {}
|
57
|
-
post_install_message:
|
59
|
+
post_install_message:
|
58
60
|
rdoc_options: []
|
59
61
|
require_paths:
|
60
62
|
- lib
|
@@ -69,8 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
71
|
- !ruby/object:Gem::Version
|
70
72
|
version: '0'
|
71
73
|
requirements: []
|
72
|
-
rubygems_version: 3.1.
|
73
|
-
signing_key:
|
74
|
+
rubygems_version: 3.1.4
|
75
|
+
signing_key:
|
74
76
|
specification_version: 4
|
75
77
|
summary: Test object framework
|
76
78
|
test_files: []
|
@@ -1,131 +0,0 @@
|
|
1
|
-
module TestBench
|
2
|
-
module Fixture
|
3
|
-
class Session
|
4
|
-
module Substitute
|
5
|
-
class MatchTests
|
6
|
-
include Output
|
7
|
-
|
8
|
-
attr_reader :output_substitute
|
9
|
-
attr_reader :patterns
|
10
|
-
attr_reader :result
|
11
|
-
|
12
|
-
def matches
|
13
|
-
@matches ||= []
|
14
|
-
end
|
15
|
-
|
16
|
-
def stack
|
17
|
-
@stack ||= []
|
18
|
-
end
|
19
|
-
|
20
|
-
def pattern_index
|
21
|
-
@pattern_index ||= 0
|
22
|
-
end
|
23
|
-
attr_writer :pattern_index
|
24
|
-
|
25
|
-
def initialize(output_substitute, result, *patterns)
|
26
|
-
@output_substitute = output_substitute
|
27
|
-
@result = result
|
28
|
-
@patterns = patterns
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.build(run, *patterns, result: nil)
|
32
|
-
output_substitute = run.output
|
33
|
-
|
34
|
-
patterns.map! do |pattern|
|
35
|
-
if pattern.is_a?(String)
|
36
|
-
Regexp.new("\\A#{Regexp.escape(pattern)}\\z")
|
37
|
-
else
|
38
|
-
pattern
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
new(output_substitute, result, *patterns)
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.call(run, *patterns, result: nil)
|
46
|
-
instance = build(run, *patterns, result: result)
|
47
|
-
instance.()
|
48
|
-
end
|
49
|
-
|
50
|
-
def call
|
51
|
-
output_substitute.replay_records(self)
|
52
|
-
|
53
|
-
matches
|
54
|
-
end
|
55
|
-
|
56
|
-
def enter_context(title)
|
57
|
-
push(title)
|
58
|
-
end
|
59
|
-
|
60
|
-
def exit_context(_, _)
|
61
|
-
pop
|
62
|
-
end
|
63
|
-
|
64
|
-
def finish_test(title, result)
|
65
|
-
push(title)
|
66
|
-
|
67
|
-
if match?(result)
|
68
|
-
text = stack.join("\t")
|
69
|
-
|
70
|
-
matches << text
|
71
|
-
end
|
72
|
-
|
73
|
-
pop unless title.nil?
|
74
|
-
end
|
75
|
-
|
76
|
-
def skip_test(title)
|
77
|
-
push(title)
|
78
|
-
|
79
|
-
pop
|
80
|
-
end
|
81
|
-
|
82
|
-
def push(title)
|
83
|
-
return if title.nil?
|
84
|
-
|
85
|
-
if next_pattern.match?(title)
|
86
|
-
self.pattern_index += 1
|
87
|
-
end
|
88
|
-
|
89
|
-
stack.push(title)
|
90
|
-
end
|
91
|
-
|
92
|
-
def pop
|
93
|
-
title = stack.pop
|
94
|
-
|
95
|
-
if previous_pattern.match?(title)
|
96
|
-
self.pattern_index -= 1
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def match?(result)
|
101
|
-
return false unless pattern_index == patterns.count
|
102
|
-
|
103
|
-
if self.result.nil?
|
104
|
-
true
|
105
|
-
else
|
106
|
-
result == self.result
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def next_pattern
|
111
|
-
return Pattern.none if pattern_index == patterns.count
|
112
|
-
|
113
|
-
patterns.fetch(pattern_index)
|
114
|
-
end
|
115
|
-
|
116
|
-
def previous_pattern
|
117
|
-
return Pattern.none if pattern_index.zero?
|
118
|
-
|
119
|
-
patterns[pattern_index - 1]
|
120
|
-
end
|
121
|
-
|
122
|
-
module Pattern
|
123
|
-
def self.none
|
124
|
-
%r{\z\A}
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|