test_bench 1.0.0.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/lib/test_bench.rb +37 -0
- data/lib/test_bench/cli.rb +43 -0
- data/lib/test_bench/cli/parse_arguments.rb +168 -0
- data/lib/test_bench/controls.rb +22 -0
- data/lib/test_bench/controls/caller_location.rb +5 -0
- data/lib/test_bench/controls/depth.rb +21 -0
- data/lib/test_bench/controls/device.rb +27 -0
- data/lib/test_bench/controls/directory.rb +15 -0
- data/lib/test_bench/controls/error.rb +35 -0
- data/lib/test_bench/controls/fixture.rb +29 -0
- data/lib/test_bench/controls/output/escape_code.rb +23 -0
- data/lib/test_bench/controls/output/newline_character.rb +11 -0
- data/lib/test_bench/controls/output/print_error.rb +19 -0
- data/lib/test_bench/controls/output/styling.rb +29 -0
- data/lib/test_bench/controls/output/summary/error.rb +44 -0
- data/lib/test_bench/controls/output/summary/run.rb +59 -0
- data/lib/test_bench/controls/path.rb +15 -0
- data/lib/test_bench/controls/pattern.rb +29 -0
- data/lib/test_bench/controls/result.rb +5 -0
- data/lib/test_bench/controls/test_file.rb +5 -0
- data/lib/test_bench/controls/time.rb +61 -0
- data/lib/test_bench/deactivation_variants.rb +21 -0
- data/lib/test_bench/environment/boolean.rb +40 -0
- data/lib/test_bench/fixtures.rb +3 -0
- data/lib/test_bench/fixtures/configure_receiver.rb +80 -0
- data/lib/test_bench/output.rb +9 -0
- data/lib/test_bench/output/build.rb +57 -0
- data/lib/test_bench/output/levels/debug.rb +229 -0
- data/lib/test_bench/output/levels/failure.rb +31 -0
- data/lib/test_bench/output/levels/none.rb +13 -0
- data/lib/test_bench/output/levels/pass.rb +274 -0
- data/lib/test_bench/output/levels/summary.rb +21 -0
- data/lib/test_bench/output/print_error.rb +163 -0
- data/lib/test_bench/output/summary/error.rb +77 -0
- data/lib/test_bench/output/summary/run.rb +102 -0
- data/lib/test_bench/output/summary/run/print.rb +98 -0
- data/lib/test_bench/output/timer.rb +75 -0
- data/lib/test_bench/output/timer/substitute.rb +45 -0
- data/lib/test_bench/output/writer.rb +192 -0
- data/lib/test_bench/output/writer/dependency.rb +12 -0
- data/lib/test_bench/output/writer/sgr.rb +54 -0
- data/lib/test_bench/output/writer/substitute.rb +38 -0
- data/lib/test_bench/run.rb +103 -0
- data/lib/test_bench/run/substitute.rb +36 -0
- data/lib/test_bench/test_bench.rb +76 -0
- data/script/bench +19 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '0359bdc17397c6a467d757d2c50851ebe475625536e04ebbb2e65b1bb804d3fd'
|
4
|
+
data.tar.gz: 4db8e6a9084c79383349d9eaafd9b88911316174654ce0c26a91e68fff2e6868
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2fb8769efb25591f4eb2bbc1c3b1c0a5b185bb5a3853c224ca8998467564023196a0142413f4380d19d9dd26ecd6e5fd93d91f74034a3852dd567b527277266c
|
7
|
+
data.tar.gz: 48252b7032528645d743e4a1f52faaf95f61763c17c6ad4078d1f208610f529a2acff4318f5446efb140df63a9323df3d08b0fdd7c5e56f0824db7af8bcc46cd
|
data/lib/test_bench.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'optionparser'
|
2
|
+
|
3
|
+
require 'test_bench/fixture'
|
4
|
+
|
5
|
+
require 'test_bench/environment/boolean'
|
6
|
+
|
7
|
+
require 'test_bench/output/writer'
|
8
|
+
require 'test_bench/output/writer/sgr'
|
9
|
+
require 'test_bench/output/writer/substitute'
|
10
|
+
require 'test_bench/output/writer/dependency'
|
11
|
+
|
12
|
+
require 'test_bench/output/timer'
|
13
|
+
require 'test_bench/output/timer/substitute'
|
14
|
+
|
15
|
+
require 'test_bench/output/print_error'
|
16
|
+
|
17
|
+
require 'test_bench/output/summary/run/print'
|
18
|
+
require 'test_bench/output/summary/run'
|
19
|
+
require 'test_bench/output/summary/error'
|
20
|
+
|
21
|
+
require 'test_bench/output/levels/none'
|
22
|
+
require 'test_bench/output/levels/summary'
|
23
|
+
require 'test_bench/output/levels/failure'
|
24
|
+
require 'test_bench/output/levels/debug'
|
25
|
+
require 'test_bench/output/levels/pass'
|
26
|
+
|
27
|
+
require 'test_bench/output/build'
|
28
|
+
require 'test_bench/output'
|
29
|
+
|
30
|
+
require 'test_bench/test_bench'
|
31
|
+
require 'test_bench/deactivation_variants'
|
32
|
+
|
33
|
+
require 'test_bench/run'
|
34
|
+
require 'test_bench/run/substitute'
|
35
|
+
|
36
|
+
require 'test_bench/cli/parse_arguments'
|
37
|
+
require 'test_bench/cli'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module TestBench
|
2
|
+
module CLI
|
3
|
+
def self.call(tests_directory=nil, **runner_args)
|
4
|
+
tests_directory ||= Defaults.tests_directory
|
5
|
+
|
6
|
+
path_arguments = ParseArguments.()
|
7
|
+
|
8
|
+
read_stdin = $stdin.stat.pipe?
|
9
|
+
|
10
|
+
if read_stdin && $stdin.eof?
|
11
|
+
warn "$stdin is a pipe, but no data was written to it; no test files will be run"
|
12
|
+
end
|
13
|
+
|
14
|
+
Run.(**runner_args) do |run|
|
15
|
+
if read_stdin
|
16
|
+
until $stdin.eof?
|
17
|
+
path = $stdin.gets.chomp
|
18
|
+
|
19
|
+
next if path.empty?
|
20
|
+
|
21
|
+
run.path(path)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
if path_arguments.empty?
|
26
|
+
unless read_stdin
|
27
|
+
run.path(tests_directory)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
path_arguments.each do |path|
|
31
|
+
run.path(path)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Defaults
|
38
|
+
def self.tests_directory
|
39
|
+
ENV.fetch('TEST_BENCH_TESTS_DIRECTORY', 'test/automated')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module TestBench
|
2
|
+
module CLI
|
3
|
+
class ParseArguments
|
4
|
+
Error = Class.new(RuntimeError)
|
5
|
+
|
6
|
+
attr_reader :argv
|
7
|
+
|
8
|
+
def env
|
9
|
+
@env ||= {}
|
10
|
+
end
|
11
|
+
attr_writer :env
|
12
|
+
|
13
|
+
def output_device
|
14
|
+
@output_device ||= StringIO.new
|
15
|
+
end
|
16
|
+
attr_writer :output_device
|
17
|
+
|
18
|
+
def initialize(argv)
|
19
|
+
@argv = argv
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.build(argv=nil, env: nil)
|
23
|
+
argv ||= ::ARGV
|
24
|
+
env ||= ::ENV
|
25
|
+
|
26
|
+
instance = new(argv)
|
27
|
+
instance.output_device = Output::Writer::Defaults.device
|
28
|
+
instance.env = env
|
29
|
+
instance
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.call(argv=nil, env: nil)
|
33
|
+
instance = build(argv, env: env)
|
34
|
+
instance.()
|
35
|
+
end
|
36
|
+
|
37
|
+
def call
|
38
|
+
option_parser.parse(argv)
|
39
|
+
end
|
40
|
+
|
41
|
+
def option_parser
|
42
|
+
@option_parser ||= OptionParser.new do |parser|
|
43
|
+
parser.banner = "Usage: #{self.class.program_name} [options] [paths]"
|
44
|
+
|
45
|
+
parser.separator('')
|
46
|
+
parser.separator("Informational Options")
|
47
|
+
|
48
|
+
parser.on('-h', '--help', "Print this help message and exit successfully") do
|
49
|
+
output_device.puts(parser.help)
|
50
|
+
|
51
|
+
exit(true)
|
52
|
+
end
|
53
|
+
|
54
|
+
parser.on('-V', '--version', "Print version and exit successfully") do
|
55
|
+
output_device.puts <<~TEXT
|
56
|
+
test-bench (#{self.class.program_name}) version #{self.class.version}
|
57
|
+
TEXT
|
58
|
+
|
59
|
+
exit(true)
|
60
|
+
end
|
61
|
+
|
62
|
+
parser.separator('')
|
63
|
+
parser.separator("Configuration Options")
|
64
|
+
|
65
|
+
parser.on('-a', '--[no-]abort-on-error', %{Exit immediately after any test failure or error (Default: #{Session::Defaults.abort_on_error ? 'on' : 'off'})}) do |abort_on_error|
|
66
|
+
env['TEST_BENCH_ABORT_ON_ERROR'] = abort_on_error ? 'on' : 'off'
|
67
|
+
end
|
68
|
+
|
69
|
+
parser.on('-x', '--[no-]exclude PATTERN', %{Do not execute test files matching PATTERN (Default: #{Run::Defaults.exclude_file_pattern.inspect})}) do |pattern_text|
|
70
|
+
if pattern_text == false
|
71
|
+
pattern_text = self.none_pattern
|
72
|
+
end
|
73
|
+
|
74
|
+
assure_pattern(pattern_text)
|
75
|
+
|
76
|
+
env['TEST_BENCH_EXCLUDE_FILE_PATTERN'] = pattern_text
|
77
|
+
end
|
78
|
+
|
79
|
+
parser.on('-o', '--[no-]omit-backtrace PATTERN', %{Omit backtrace frames matching PATTERN (Default: #{Output::PrintError::Defaults.omit_backtrace_pattern.inspect})}) do |pattern_text|
|
80
|
+
if pattern_text == false
|
81
|
+
pattern_text = self.none_pattern
|
82
|
+
end
|
83
|
+
|
84
|
+
assure_pattern(pattern_text)
|
85
|
+
|
86
|
+
env['TEST_BENCH_OMIT_BACKTRACE_PATTERN'] = pattern_text
|
87
|
+
end
|
88
|
+
|
89
|
+
parser.on('-l', '--output-level [none|summary|failure|pass|debug]', %{Sets output level (Default: #{Output::Build::Defaults.level})}) do |level_text|
|
90
|
+
level = level_text.to_sym
|
91
|
+
|
92
|
+
Output::Build.assure_level(level)
|
93
|
+
|
94
|
+
env['TEST_BENCH_OUTPUT_LEVEL'] = level_text
|
95
|
+
end
|
96
|
+
|
97
|
+
parser.on('-s', '--output-styling [on|off|detect]', %{Render output coloring and font styling escape codes (Default: #{Output::Writer::Defaults.styling_setting})}) do |styling_text|
|
98
|
+
styling_text ||= 'on'
|
99
|
+
|
100
|
+
styling_setting = styling_text.to_sym
|
101
|
+
|
102
|
+
Output::Writer.assure_styling_setting(styling_setting)
|
103
|
+
|
104
|
+
env['TEST_BENCH_OUTPUT_STYLING'] = styling_text
|
105
|
+
end
|
106
|
+
|
107
|
+
parser.on('-p', '--[no-]permit-deactivated-tests', %{Do not fail the test run if there are deactivated tests or contexts, e.g. _test or _context (Default: #{!DeactivationVariants::Defaults.fail_session ? 'on' : 'off'})}) do |permit_deactivated_tests|
|
108
|
+
env['TEST_BENCH_FAIL_DEACTIVATED_TESTS'] = !permit_deactivated_tests ? 'on' : 'off'
|
109
|
+
end
|
110
|
+
|
111
|
+
parser.on('-r', '--[no-]reverse-backtraces', %{Reverse order of backtraces when printing errors (Default: #{Output::PrintError::Defaults.reverse_backtraces ? 'on' : 'off'})}) do |reverse_backtraces|
|
112
|
+
env['TEST_BENCH_REVERSE_BACKTRACES'] = reverse_backtraces ? 'on' : 'off'
|
113
|
+
end
|
114
|
+
|
115
|
+
parser.separator(<<~TEXT)
|
116
|
+
|
117
|
+
Paths to test files (and directories containing test files) can be given after any command line arguments or via STDIN (or both).
|
118
|
+
If no paths are given, a default path (#{Defaults.tests_directory}) is scanned for test files.
|
119
|
+
|
120
|
+
The following environment variables can also control execution:
|
121
|
+
|
122
|
+
#{parser.summary_indent}TEST_BENCH_ABORT_ON_ERROR Same as -a or --abort-on-error
|
123
|
+
#{parser.summary_indent}TEST_BENCH_EXCLUDE_FILE_PATTERN Same as -x or --exclude-file-pattern
|
124
|
+
#{parser.summary_indent}TEST_BENCH_OMIT_BACKTRACE_PATTERN Same as -o or --omit-backtrace-pattern
|
125
|
+
#{parser.summary_indent}TEST_BENCH_OUTPUT_LEVEL Same as -l or --output-level
|
126
|
+
#{parser.summary_indent}TEST_BENCH_OUTPUT_STYLING Same as -s or --output-styling
|
127
|
+
#{parser.summary_indent}TEST_BENCH_FAIL_DEACTIVATED_TESTS Opposite of -p or --permit-deactivated-tests
|
128
|
+
#{parser.summary_indent}TEST_BENCH_REVERSE_BACKTRACES Same as -r or --reverse-backtraces
|
129
|
+
|
130
|
+
TEXT
|
131
|
+
|
132
|
+
parser.separator(<<~TEXT)
|
133
|
+
Finally, the VERBOSE environment variable can set the output level to debug. If given, VERBOSE will take precedence over TEST_BENCH_OUTPUT_STYLING.
|
134
|
+
|
135
|
+
TEXT
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def assure_pattern(pattern_text)
|
140
|
+
Regexp.new(pattern_text)
|
141
|
+
rescue RegexpError
|
142
|
+
raise Error, "Invalid regular expression pattern (Pattern: #{pattern_text.inspect})"
|
143
|
+
end
|
144
|
+
|
145
|
+
def none_pattern
|
146
|
+
/\z./
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.program_name
|
150
|
+
$PROGRAM_NAME
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.version
|
154
|
+
if defined?(Gem)
|
155
|
+
spec = Gem.loaded_specs['test_bench']
|
156
|
+
end
|
157
|
+
|
158
|
+
spec&.version || '(unknown)'
|
159
|
+
end
|
160
|
+
|
161
|
+
module Defaults
|
162
|
+
def self.tests_directory
|
163
|
+
ENV.fetch('TEST_BENCH_TESTS_DIRECTORY', 'test/automated')
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
require 'test_bench/fixture/controls'
|
4
|
+
|
5
|
+
require 'test_bench/controls/caller_location'
|
6
|
+
require 'test_bench/controls/depth'
|
7
|
+
require 'test_bench/controls/device'
|
8
|
+
require 'test_bench/controls/directory'
|
9
|
+
require 'test_bench/controls/error'
|
10
|
+
require 'test_bench/controls/fixture'
|
11
|
+
require 'test_bench/controls/path'
|
12
|
+
require 'test_bench/controls/pattern'
|
13
|
+
require 'test_bench/controls/result'
|
14
|
+
require 'test_bench/controls/test_file'
|
15
|
+
require 'test_bench/controls/time'
|
16
|
+
|
17
|
+
require 'test_bench/controls/output/escape_code'
|
18
|
+
require 'test_bench/controls/output/newline_character'
|
19
|
+
require 'test_bench/controls/output/styling'
|
20
|
+
require 'test_bench/controls/output/print_error'
|
21
|
+
require 'test_bench/controls/output/summary/run'
|
22
|
+
require 'test_bench/controls/output/summary/error'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module TestBench
|
2
|
+
module Controls
|
3
|
+
module Device
|
4
|
+
def self.example
|
5
|
+
Interactive.example
|
6
|
+
end
|
7
|
+
|
8
|
+
module Interactive
|
9
|
+
def self.example
|
10
|
+
device = Non.example
|
11
|
+
|
12
|
+
def device.tty?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
device
|
17
|
+
end
|
18
|
+
|
19
|
+
module Non
|
20
|
+
def self.example
|
21
|
+
StringIO.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module TestBench
|
2
|
+
module Controls
|
3
|
+
Error = TestBench::Fixture::Controls::Error
|
4
|
+
|
5
|
+
module Error
|
6
|
+
module Text
|
7
|
+
def self.example(message=nil, indentation_depth: nil)
|
8
|
+
indentation_depth ||= 0
|
9
|
+
|
10
|
+
indent = ' ' * indentation_depth
|
11
|
+
|
12
|
+
error = Error.example(message)
|
13
|
+
|
14
|
+
<<~TEXT
|
15
|
+
#{indent}#{error.backtrace[0]}: #{error.message} (#{error.class.name})
|
16
|
+
\t#{indent}from #{error.backtrace[1]}
|
17
|
+
\t#{indent}from #{error.backtrace[2]}
|
18
|
+
TEXT
|
19
|
+
end
|
20
|
+
|
21
|
+
module Assertion
|
22
|
+
def self.example(caller_location: nil)
|
23
|
+
caller_location ||= CallerLocation.example
|
24
|
+
|
25
|
+
assertion_failure = TestBench::Fixture::AssertionFailure.build(caller_location)
|
26
|
+
|
27
|
+
<<~TEXT
|
28
|
+
#{assertion_failure.backtrace[0]}: #{assertion_failure.message} (#{assertion_failure.class.name})
|
29
|
+
TEXT
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module TestBench
|
2
|
+
module Controls
|
3
|
+
module Fixture
|
4
|
+
def self.example(output=nil, error_policy: nil)
|
5
|
+
error_policy ||= self.error_policy
|
6
|
+
|
7
|
+
fixture = Example.new
|
8
|
+
|
9
|
+
TestBench::Fixture::ErrorPolicy.configure(fixture.test_session, policy: error_policy)
|
10
|
+
|
11
|
+
unless output.nil?
|
12
|
+
fixture.test_session.output = output
|
13
|
+
end
|
14
|
+
|
15
|
+
fixture
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.example_class(&block)
|
19
|
+
TestBench::Fixture::Controls::Fixture.example_class(&block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.error_policy
|
23
|
+
:rescue
|
24
|
+
end
|
25
|
+
|
26
|
+
Example = example_class
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TestBench
|
2
|
+
module Controls
|
3
|
+
module Output
|
4
|
+
module EscapeCode
|
5
|
+
def self.example
|
6
|
+
'1'
|
7
|
+
end
|
8
|
+
|
9
|
+
module ID
|
10
|
+
def self.example
|
11
|
+
:bold
|
12
|
+
end
|
13
|
+
|
14
|
+
module Unknown
|
15
|
+
def self.example
|
16
|
+
:unknown
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|