loupe 0.1.5

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.
data/lib/loupe/test.rb ADDED
@@ -0,0 +1,270 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Loupe's expectations are heavily inspired by or adapted from Minitest and rspec-expectations implementations. The
4
+ # originals licenses can be found below.
5
+ #
6
+ # Minitest https://github.com/seattlerb/minitest
7
+ #
8
+ # (The MIT License)
9
+ #
10
+ # Copyright © Ryan Davis, seattle.rb
11
+ #
12
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13
+ # documentation files (the 'Software'), to deal in the Software without restriction, including without limitation
14
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15
+ # to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of
18
+ # the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
21
+ # THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23
+ # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
+ # IN THE SOFTWARE.
25
+
26
+ # Rspec-expectations
27
+ #
28
+ # https://github.com/rspec/rspec-expectations
29
+ #
30
+ # The MIT License (MIT)
31
+ #
32
+ # Copyright © 2012 David Chelimsky, Myron Marston Copyright © 2006 David Chelimsky, The RSpec Development Team
33
+ # Copyright © 2005 Steven Baker
34
+ #
35
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
36
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation
37
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
38
+ # to permit persons to whom the Software is furnished to do so, subject to the following conditions:
39
+ #
40
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of
41
+ # the Software.
42
+ #
43
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
44
+ # THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
46
+ # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47
+ # DEALINGS IN THE SOFTWARE.
48
+
49
+ module Loupe
50
+ # Test
51
+ #
52
+ # The parent class for tests. Tests should
53
+ # inherit from this class in order to be run.
54
+ class Test
55
+ # @return [Loupe::Reporter]
56
+ attr_reader :reporter
57
+
58
+ # @return [Integer]
59
+ attr_reader :line_number
60
+
61
+ # @return [String]
62
+ attr_reader :file
63
+
64
+ # @return [Loupe::Color]
65
+ attr_reader :color
66
+
67
+ # @return [String]
68
+ attr_reader :name
69
+
70
+ # @return [Hash<Class, Array<Integer>>]
71
+ def self.classes
72
+ @classes ||= {}
73
+ end
74
+
75
+ # @param number [Integer]
76
+ # @return [void]
77
+ def self.add_line_number(number)
78
+ classes[@current_class] << number
79
+ end
80
+
81
+ # @param test_class [Class]
82
+ # @return [void]
83
+ def self.inherited(test_class)
84
+ @current_class = test_class
85
+ classes[test_class] = []
86
+ super
87
+ end
88
+
89
+ # @return [Array<Symbol>]
90
+ def self.test_list
91
+ instance_methods(false).grep(/^test.*/)
92
+ end
93
+
94
+ # Run a single test with designated by `method_name`
95
+ #
96
+ # @param method_name [Symbol]
97
+ # @param options [Hash<Symbol, BasicObject>]
98
+ # @return [Loupe::Reporter]
99
+ def self.run(method_name, options = {})
100
+ reporter = options[:interactive] ? PagedReporter.new(options) : PlainReporter.new(options)
101
+ new(reporter, method_name, options).run
102
+ reporter
103
+ rescue Expectation::ExpectationFailed
104
+ reporter
105
+ end
106
+
107
+ # @param reporter [Loupe::Reporter]
108
+ # @param method_name [Symbol]
109
+ # @param options [Hash<Symbol, BasicObject>]
110
+ # @return [Loupe::Test]
111
+ def initialize(reporter, method_name, options = {})
112
+ @reporter = reporter
113
+ @color = Color.new(options[:color])
114
+ @name = method_name
115
+ @method = method(method_name)
116
+ @file, @line_number = @method.source_location
117
+ end
118
+
119
+ # Run the instantiated test, which corresponds to a single
120
+ # method.
121
+ # @return [void]
122
+ def run
123
+ @reporter.increment_test_count
124
+ before
125
+ @method.call
126
+ after
127
+ @reporter.increment_success_count
128
+ end
129
+
130
+ # @return [void]
131
+ def before; end
132
+
133
+ # @return [void]
134
+ def after; end
135
+
136
+ protected
137
+
138
+ # expect(target)
139
+ #
140
+ # Initial construct for any expectation. Instantiates an Expectation object
141
+ # on which verifications can be performed. Any expectation can be chained to reuse
142
+ # the object if the `target` is the same.
143
+ #
144
+ # Example:
145
+ # expect(collection)
146
+ # .to_not_be_empty
147
+ # .to_include(object)
148
+ # .be_an_instance_of(Array)
149
+ #
150
+ # @return [Loupe::Expectation]
151
+ def expect(target)
152
+ Expectation.new(target, self)
153
+ end
154
+
155
+ # expect_output_to_match(stdout, stderr) { block }
156
+ #
157
+ # Expects the output generated by the execution of `block` to match the matchers used
158
+ # for `stdout` and `stderr`. If the `block` only prints to one of the two, simply pass
159
+ # `nil` for the one that is not of interest.
160
+ #
161
+ # Example:
162
+ # expect_output_to_match("foo") do
163
+ # puts "foo"
164
+ # end
165
+ #
166
+ # expect_output_to_match(nil, /error: .*/) do
167
+ # $stderr.puts "error: operation failed"
168
+ # end
169
+ #
170
+ # @return [void]
171
+ def expect_output_to_match(stdout = nil, stderr = nil, &block)
172
+ raise ArgumentError, "expect_output_to_match requires a block to capture output." unless block
173
+
174
+ out, err = capture_io(&block)
175
+
176
+ match_or_equal(stdout, out) if stdout
177
+ match_or_equal(stderr, err) if stderr
178
+ end
179
+
180
+ # expect_output_to_not_match(stdout, stderr) { block }
181
+ #
182
+ # Expects the output generated by the execution of `block` to not match the matchers used
183
+ # for `stdout` and `stderr`. If the `block` only prints to one of the two, simply pass
184
+ # `nil` for the one that is not of interest.
185
+ #
186
+ # Example:
187
+ # expect_output_to_not_match("foo") do
188
+ # puts "bar"
189
+ # end
190
+ #
191
+ # expect_output_to_not_match(nil, /error: network failed.*/) do
192
+ # $stderr.puts "error: record not unique"
193
+ # end
194
+ #
195
+ # @return [void]
196
+ def expect_output_to_not_match(stdout = nil, stderr = nil, &block)
197
+ raise ArgumentError, "expect_output_to_not_match requires a block to capture output." unless block
198
+
199
+ out, err = capture_io(&block)
200
+
201
+ refute_match_or_equal(stdout, out) if stdout
202
+ refute_match_or_equal(stderr, err) if stderr
203
+ end
204
+
205
+ # expect_output_to_be_empty { block }
206
+ #
207
+ # Expects the output generated by `block` to be empty for both `$stdout` and `$stderr`.
208
+ # That is, expects the `block` to not print anything to either `$stdout` or `$stderr`.
209
+ # For matching to the output of the `block`, see {#expect_output_to_match}.
210
+ #
211
+ # Example:
212
+ # expect_output_to_be_empty do
213
+ # puts "bar" if false
214
+ # end
215
+ #
216
+ # @return [void]
217
+ def expect_output_to_be_empty(&block)
218
+ expect_output_to_match("", "", &block)
219
+ end
220
+
221
+ # expect_output_to_not_be_empty { block }
222
+ #
223
+ # Expects the output generated by `block` to not be empty for both `$stdout` and `$stderr`.
224
+ # That is, expects the `block` to print something to either `$stdout` or `$stderr`.
225
+ # For matching to the output of the `block`, see {#expect_output_to_not_match}.
226
+ #
227
+ # Example:
228
+ # expect_output_to_not_be_empty do
229
+ # puts "foo"
230
+ # end
231
+ #
232
+ # @return [void]
233
+ def expect_output_to_not_be_empty(&block)
234
+ expect_output_to_not_match("", "", &block)
235
+ end
236
+
237
+ private
238
+
239
+ # @param matcher [Regexp, String]
240
+ # @param output [String]
241
+ # @return [void]
242
+ def match_or_equal(matcher, output)
243
+ matcher.is_a?(Regexp) ? expect(matcher).to_match(output) : expect(matcher).to_be_equal_to(output)
244
+ end
245
+
246
+ # @param matcher [Regexp, String]
247
+ # @param output [String]
248
+ # @return [void]
249
+ def refute_match_or_equal(matcher, output)
250
+ matcher.is_a?(Regexp) ? expect(matcher).to_not_match(output) : expect(matcher).to_not_be_equal_to(output)
251
+ end
252
+
253
+ # @return [Array<String>]
254
+ def capture_io
255
+ new_stdout = StringIO.new
256
+ new_stderr = StringIO.new
257
+ stdout = $stdout
258
+ stderr = $stderr
259
+ $stdout = new_stdout
260
+ $stderr = new_stderr
261
+
262
+ yield
263
+
264
+ [new_stdout.string, new_stderr.string]
265
+ ensure
266
+ $stdout = stdout
267
+ $stderr = stderr
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Loupe
4
+ # @return [String]
5
+ VERSION = "0.1.5"
6
+ end
data/lib/loupe.rb ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "loupe/version"
4
+ require "loupe/color"
5
+ require "loupe/expectation"
6
+ require "loupe/test"
7
+ require "loupe/failure"
8
+ require "loupe/reporter"
9
+ require "loupe/executor"
10
+ require "loupe/cli"
11
+
12
+ module Loupe # :nodoc:
13
+ autoload :PlainReporter, "loupe/plain_reporter"
14
+ autoload :PagedReporter, "loupe/paged_reporter"
15
+ autoload :QueueServer, "loupe/queue_server"
16
+ autoload :ProcessExecutor, "loupe/process_executor"
17
+ autoload :RactorExecutor, "loupe/ractor_executor"
18
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: loupe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Vinicius Stock
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-09-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: drb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: io-console
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.5'
41
+ description: Loupe is a Ruby test framework that can run tests in parallel in Ractor
42
+ or forked process mode
43
+ email:
44
+ - stock@hey.com
45
+ executables:
46
+ - loupe
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - exe/loupe
54
+ - lib/loupe.rb
55
+ - lib/loupe/cli.rb
56
+ - lib/loupe/color.rb
57
+ - lib/loupe/executor.rb
58
+ - lib/loupe/expectation.rb
59
+ - lib/loupe/failure.rb
60
+ - lib/loupe/paged_reporter.rb
61
+ - lib/loupe/plain_reporter.rb
62
+ - lib/loupe/process_executor.rb
63
+ - lib/loupe/queue_server.rb
64
+ - lib/loupe/ractor_executor.rb
65
+ - lib/loupe/rake_task.rb
66
+ - lib/loupe/reporter.rb
67
+ - lib/loupe/test.rb
68
+ - lib/loupe/version.rb
69
+ homepage: https://github.com/vinistock/loupe
70
+ licenses:
71
+ - MIT
72
+ metadata:
73
+ homepage_uri: https://github.com/vinistock/loupe
74
+ source_code_uri: https://github.com/vinistock/loupe
75
+ changelog_uri: https://github.com/vinistock/loupe/blob/master/CHANGELOG.md
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 2.7.0
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubygems_version: 3.2.27
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Loupe is a Rubyy test framework with built in parallelism
95
+ test_files: []