probatio 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2ad9b151150b2a112358c58b0a480d72eaba65a400ae8a6a21e54d74e61136e
4
- data.tar.gz: d2d008237d2133169b56dedd842e72c27efc760caa2ddf13d95d232e6c5b6197
3
+ metadata.gz: cf6d07083021c42a5695d160c5de95cb18cef70ed2cf58fb958498cbc33a3c9c
4
+ data.tar.gz: 9c9a5c712f92568e05e1986be11e505b3fd3863023cc2d797b0a964a7e5da2e5
5
5
  SHA512:
6
- metadata.gz: ceb178be47b755d00d0bedb8f16087d983b3e5ab61afa1c7b22d366ecd8f3646edb231f70f840cf2a3ce65b744991802b087b9806e9f385d009d6fbf60ca76fe
7
- data.tar.gz: b1845474c38066483e226dfbd87ef75697ab0d39a2deaf9b550229ab9000744b3906f1e133b453804e5d02148b5252a5f79e691ad09c27d44ca804d496fc72c4
6
+ metadata.gz: a4521e7b2c50ddcdc08fe1a064e8aea1580a01a623fe666933892ee8f099b8bf9f6f90bfc18231e00b669f9b6b0be630ada8f413084bd93d7f0daf25c92cde1d
7
+ data.tar.gz: 0e9f61a0222ceb65692a17ce532bb8e2684f7b31c49cb918894a02923a23aab51954001d186905423ba30e6e2ce2c7225a335d42c7f6bfd061f988dc033c382b
data/CHANGELOG.md CHANGED
@@ -2,7 +2,12 @@
2
2
  # CHANGELOG.md
3
3
 
4
4
 
5
- ## djan 0.9.0 released 2024-12-19
5
+ ## proba 1.0.0 released 2025-02-08
6
+
7
+ * Initial release
8
+
9
+
10
+ ## proba 0.9.0 released 2024-12-19
6
11
 
7
12
  * Initial bogus release ;-)
8
13
 
data/README.md CHANGED
@@ -7,6 +7,307 @@
7
7
  Test tools for floraison and flor. Somewhere between Minitest and Rspec, but not as excellent.
8
8
 
9
9
 
10
+ ## Goals
11
+
12
+ * versatile `bundle exec proba`, run this or these tests, at the line
13
+ * `bundle exec proba first` for first failing tests
14
+ * `bundle exec proba last` for last failing tests
15
+ * `bundle exec proba .` for the test currently edited `.test-point`
16
+ * `bundle exec proba f` for the test file currently edited `.test-point`
17
+ * `bundle exec proba list.txt` to run a list of tests
18
+ * `bundle exec proba list.rb` to run a list of tests (Ruby array)
19
+
20
+
21
+ ## Usage
22
+
23
+ ```
24
+ Usage: bundle exec proba [OPTIONS] [DIRS] [FILES] [OTHERS] [ENVS]
25
+
26
+ A test runner for Ruby.
27
+
28
+ Options:
29
+ -h, --help Show this help message and quit
30
+ --version Show proba's version and exit
31
+ -c, --color Enable colour output anyway
32
+ -C, --no-color Disable colour output
33
+ -y, --dry Don't run the tests, just flag them as successes
34
+ -n, --name PATTERN include tests matching /regexp/ or string in run
35
+ -e, --exclude PATTERN Exclude /regexp/ or string from run
36
+ -p, --print Dumps the test tree
37
+ -m, --map Dumps the test file map
38
+ -s, --seed Sets random seed
39
+ -d, --debug smr 's' for start opts, 'm' for messages, 'r' for $DEBUG
40
+ -x, --example Outputs an example test file
41
+ -X, --plugin-example Outputs an example plugin file
42
+ --mangle Turns the given _spec.rb files into proba _test.rb
43
+
44
+ Dirs:
45
+ Defaults to test/ if no files nor dir are given.
46
+ Probatio will look at all the *_helper[s].rb, *_test[s].rb files
47
+ under the given dirs and also at the setup.rb, *_setup.rb files
48
+
49
+ Files:
50
+ List of test files to scan for tests.
51
+ A file may end with `:123` to indicate that the test at line 123 should
52
+ be run. Multiple "colon-lnumber" suffixes may be specified, as in
53
+ `test/fun/that_test.rb:123:456`
54
+
55
+ Others:
56
+ Short codes like
57
+ * `bundle exec proba -1`
58
+ * `bundle exec proba last` run the last failing test of the last run
59
+ * `bundle exec proba first`
60
+ * `bundle exec proba 1st`
61
+ * `bundle exec proba 0` run the first failing test of the last run
62
+ Lists:
63
+ * `bundle exec proba list.txt` will run all the tests in list.txt
64
+ * `bundle exec proba a_list.rb` will eval and lists the arrayed tests
65
+
66
+
67
+ Envs:
68
+ Short FULLCAPS environment variable setters driven by a
69
+ `.probatio-environments.rb` file in the current work directory.
70
+
71
+ ```
72
+ # .probatio-environments.rb
73
+ {
74
+ D: { 'FLOR_DEBUG' => 'dbg,stdout' },
75
+ DD: { 'FLOR_DEBUG' => 'dbg,sto,stdout' },
76
+ }
77
+ ```
78
+
79
+ Examples:
80
+ # Run all tests in a dir
81
+ bundle exec proba test/
82
+
83
+ # Run all the tests in a file
84
+ bundle exec proba test/this_test.rb
85
+ ```
86
+
87
+ ## Test files
88
+
89
+ By default probatio looks into `test/` for test files ending in `_test.rb` or `_tests.rb` but first look at helpers ending in `_helper.rb` or `_helpers.rb`.
90
+
91
+ A typical test hierarchy:
92
+ ```
93
+ test/
94
+ |-- helpers/
95
+ | |-- some_helpers.rb
96
+ | `-- some_other_helpers.rb
97
+ |-- this_test.rb
98
+ |-- that_test.rb
99
+ `-- more_tests.rb
100
+ ```
101
+
102
+ ```ruby
103
+ group 'core' do
104
+
105
+ setup do
106
+ # occurs once before tests and sub-groups in group 'core'
107
+ end
108
+ teadowm do
109
+ # occurs once after tests and sub-groups in group 'core'
110
+ end
111
+
112
+ group 'alpha' do
113
+
114
+ before do
115
+ # is run in the separate test context before _each_ test
116
+ end
117
+ after do
118
+ # is run in the separate test context after _each_ test
119
+ end
120
+
121
+ test 'one' do
122
+
123
+ MyLib.do_this_or_that()
124
+
125
+ assert_nil nil
126
+ assert_not_nil [], 1
127
+
128
+ assert_true true
129
+ assert_false 1 > 2
130
+
131
+ assert_truthy "yes", "no"
132
+ assert_trueish "yes", "no"
133
+ assert_falsy nil, false
134
+ assert_falsey nil, false
135
+ assert_falseish nil, false
136
+
137
+ assert_any %w[ an array ], 'a string'
138
+ assert_empty [], ''
139
+
140
+ assert_size [], 0
141
+ assert_size 'foo', 3
142
+ assert_size { a: 1 }, 1
143
+ assert_count %w[ a b c ], 3
144
+
145
+ assert_equal 'one', 'o' + 'ne'
146
+ # checks that all its arguments are equal
147
+
148
+ assert_match 'one', /^one$/
149
+ # checks that it receives a regex and one or more strings
150
+ # and that all those strings match the regex
151
+
152
+ assert_start_with 'one', 'one two or three'
153
+ # checks that the shortest string is the start of the remaining string
154
+ # arguments
155
+ assert_end_with 'three', 'one two or three'
156
+ # checks that the shortest string is the end of the remaining string
157
+ # arguments
158
+
159
+ assert_include 1, [ 1, 'two' ]
160
+ # checks that the first array argument includes all other arguments
161
+
162
+ assert_error(ArgumentError) { do_this_or_that() }
163
+ # checks that the given block raises an ArgumentError
164
+ assert_error(ArgumentError, /bad/) { do_this_or_that() }
165
+ # checks that the given block raises an ArgumentError and
166
+ # the error message matches the /bad/ regexp
167
+ assert_error lambda { do_this_or_that() }, ArgumentError
168
+ # checks that the given Proc raises an ArgumentError
169
+ assert_error lambda { do_this_or_that() }, ArgumentError, 'bad'
170
+ # checks that the given Proc raises an ArgumentError and
171
+ # the error message == "bad"
172
+
173
+ assert_hashy(
174
+ this_thing => 1,
175
+ that_thing => 'two')
176
+ # combines two assert_equals in one
177
+
178
+ assert_instance_of 1, Integer
179
+ assert_is_a Integer, 123
180
+ # checks that value or set of values are of a given of class
181
+
182
+ assert 1, 1
183
+ # behaves like assert_equal
184
+ assert 'one', /one/i
185
+ # behaves like assert_match
186
+ assert 11 => '10'.to_i + 1
187
+ # assert equality between key and value
188
+ assert 'one' => 'on' + 'e', 'two' => :two.to_s
189
+ # assert equality between keys and values
190
+ end
191
+ end
192
+
193
+ group 'bravo' do
194
+ end
195
+ end
196
+
197
+ group 'core' do
198
+ #
199
+ # it's OK to re-open a group to add sub-groups, tests,
200
+ # and setups, teardowns, befores, or afters
201
+ #
202
+ # it's OK to re-open a group in another file, as long
203
+ # as it's the same name at the same point in the name hierarchy
204
+
205
+ _test 'not yet' do
206
+ #
207
+ # prefix a test, a group, or other element with _
208
+ # marks it as _pending
209
+ end
210
+ end
211
+
212
+ group 'core', 'sub-core', 'sub-sub-core' do
213
+ #
214
+ # it's OK to specifiy a path of group names
215
+
216
+ test 'this' do
217
+ end
218
+ end
219
+
220
+ group 'core < sub-core < sub-sub-core' do
221
+ #
222
+ # this is also ok...
223
+
224
+ test 'that' do
225
+ end
226
+ end
227
+ ```
228
+
229
+
230
+ ## .test-point
231
+
232
+ By running `bx proba .`, one tells probatio to run the test pointed at in the file `.test-point`.
233
+
234
+ Here is an example of `.test-point` content:
235
+ ```
236
+ test/wma/dwm/onboarding_benchmark_non_star_test.rb:189
237
+ ```
238
+
239
+ For Vim users, here is a snippet that saves the current path and line number to `.test-point` every 700ms:
240
+ ```vim
241
+ au BufEnter test/*_test.rb,test/**/*_test.rb :set updatetime=700
242
+
243
+ au BufEnter,CursorHold,BufWrite test/*_test.rb,test/**/*_test.rb :call writefile([ expand('%') . ':' . line('.') ], '.test-point', 'b')
244
+ ```
245
+
246
+
247
+ ## .probatio-output.rb
248
+
249
+ By default, probatio summarizes a run in a `.probatio-output.rb` file.
250
+
251
+ Here is an example of such a file:
252
+ ```ruby
253
+ # .probatio-output.rb
254
+ {
255
+ argv: [ "test/alpha_test.rb:23" ],
256
+ failures:
257
+ [
258
+ { n: "test_fail", p: "test/alpha_test.rb", l: 24, t: "0s000_077" },
259
+ { n: "test_fail", p: "test/alpha_test.rb", l: 29, t: "0s000_033" },
260
+ ],
261
+ duration: "0s001_297",
262
+ probatio: { v: "1.0.0" },
263
+ ruby:
264
+ {
265
+ p: "/usr/local/bin/ruby33",
266
+ d: "ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [x86_64-openbsd]",
267
+ l: 100,
268
+ },
269
+ some_env:
270
+ {
271
+ USER: "jmettraux",
272
+ HOME: "/home/jmettraux",
273
+ PATH: "/home/jmettraux/.gem/ruby/3.3/bin:/home/jmettraux/.pkg_rubies/ruby33:/usr/local/jdk-21/bin:/home/jmettraux/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin",
274
+ SHELL: "/usr/local/bin/fish",
275
+ GEM_HOME: "/home/jmettraux/.gem/ruby/3.3",
276
+ PWD: "/home/jmettraux/w/probatio/test",
277
+ },
278
+ }
279
+ ```
280
+
281
+ Probatio uses it when servicing `bundle exec proba 0` or `bundle exe proba -1`.
282
+
283
+ It can also be useful to other tools around probatio.
284
+
285
+
286
+ ## Warnings
287
+
288
+ ```
289
+ $ RUBYOPT="-w $RUBYOPT" bundle exec proba
290
+ ```
291
+
292
+
293
+ ## Plugins
294
+
295
+ ```ruby
296
+ #
297
+ # examples of probatio plugins
298
+
299
+ class MyProbatioPlugin
300
+
301
+ def on_test_succeed(ev)
302
+
303
+ puts "GREAT SUCCESS! " + ev.to_s
304
+ end
305
+ end
306
+
307
+ Probatio.plug(MyProbatioPlugin.new)
308
+ ```
309
+
310
+
10
311
  ## LICENSE
11
312
 
12
313
  MIT, see [LICENSE.txt](LICENSE.txt)
data/exe/proba CHANGED
@@ -2,15 +2,259 @@
2
2
 
3
3
  require 'probatio'
4
4
 
5
+
5
6
  #
6
7
  # gather opts
7
8
 
8
- opts = { dir: 'test' }
9
+ args = ARGV.dup
10
+
11
+ def rework_switch(a)
12
+
13
+ case a
14
+ when '-n', '--name' then '--name'
15
+ when '-e', '--exclude' then '--exclude'
16
+ when '-s', '--seed' then '--seed'
17
+ when '-d', '--debug' then '--debug'
18
+ else nil
19
+ end
20
+ end
21
+
22
+ def is_directory_with_tests?(path)
23
+
24
+ File.directory?(path) &&
25
+ Dir[File.join(path, '**', '*_test.rb')].any?
26
+ end
27
+
28
+ switches = {}
29
+ dirs, files, lists, strings, environments, integers = [], [], [], [], [], []
30
+
31
+ while a = args.shift
32
+
33
+ if a.match?(/^(-[a-z]|--[a-z0-9][-a-z0-9]+)$/i)
34
+ if k = rework_switch(a)
35
+ (switches[k] ||= []) << args.shift
36
+ else
37
+ switches[a] = true
38
+ end
39
+ elsif File.directory?(a) && a != '.'
40
+ dirs << a
41
+ elsif File.file?(a) && (a.match?(/(\.txt|_list\.rb)$/))
42
+ lists << a
43
+ elsif File.file?(a.split(':').first)
44
+ files << a
45
+ elsif a.match?(/\A-?\d+\z/)
46
+ integers << a.to_i
47
+ elsif a.match?(/\A[A-Z][A-Z0-9]*\z/)
48
+ environments << a
49
+ else
50
+ strings << a
51
+ end
52
+ end
53
+
54
+ $_PROBATIO_COLOURS =
55
+ switches['-C'] || switches['--no-color'] ? Colorato.no_colours :
56
+ switches['-c'] || switches['--color'] ? Colorato.colours :
57
+ ( ! $stdout.tty?) ? Colorato.no_colours :
58
+ Colorato.colours
59
+
60
+ $_PROBATIO_DEBUG =
61
+ (switches['--debug'] || []).join.downcase.chars.collect(&:to_sym)
62
+ $DEBUG =
63
+ true if $_PROBATIO_DEBUG.include?(:r)
64
+
65
+ Probatio.dbg_s {
66
+ ' * switches: ' + switches.inspect + "\n" +
67
+ ' * strings: ' + strings.inspect + "\n" +
68
+ ' * integers: ' + integers.inspect + "\n" +
69
+ ' * environments: ' + environments.inspect }
70
+
71
+ if switches['-h'] || switches['--help']
72
+
73
+ puts %{
74
+ Usage: bundle exec proba [OPTIONS] [DIRS] [FILES] [OTHERS] [ENVS]
75
+
76
+ A test runner for Ruby.
77
+
78
+ Options:
79
+ -h, --help Show this help message and quit
80
+ --version Show proba's version and exit
81
+ -c, --color Enable colour output anyway
82
+ -C, --no-color Disable colour output
83
+ -y, --dry Don't run the tests, just flag them as successes
84
+ -n, --name PATTERN include tests matching /regexp/ or string in run
85
+ -e, --exclude PATTERN Exclude /regexp/ or string from run
86
+ -p, --print Dumps the test tree
87
+ -m, --map Dumps the test file map
88
+ -s, --seed Sets random seed
89
+ -d, --debug smr 's' for start opts, 'm' for messages, 'r' for $DEBUG
90
+ -x, --example Outputs an example test file
91
+ -X, --plugin-example Outputs an example plugin file
92
+ --mangle Turns the given _spec.rb files into proba _test.rb
93
+
94
+ Dirs:
95
+ Defaults to test/ if no files nor dir are given.
96
+ Probatio will look at all the *_helper[s].rb, *_test[s].rb files
97
+ under the given dirs and also at the setup.rb, *_setup.rb files
98
+
99
+ Files:
100
+ List of test files to scan for tests.
101
+ A file may end with `:123` to indicate that the test at line 123 should
102
+ be run. Multiple "colon-lnumber" suffixes may be specified, as in
103
+ `test/fun/that_test.rb:123:456`
104
+
105
+ Others:
106
+ Short codes like
107
+ * `bundle exec proba -1`
108
+ * `bundle exec proba last` run the last failing test of the last run
109
+ * `bundle exec proba first`
110
+ * `bundle exec proba 1st`
111
+ * `bundle exec proba 0` run the first failing test of the last run
112
+ Lists:
113
+ * `bundle exec proba list.txt` will run all the tests in list.txt
114
+ * `bundle exec proba a_list.rb` will eval and lists the arrayed tests
115
+
116
+
117
+ Envs:
118
+ Short FULLCAPS environment variable setters driven by a
119
+ `.probatio-environments.rb` file in the current work directory.
120
+
121
+ ```
122
+ # .probatio-environments.rb
123
+ {
124
+ D: { 'FLOR_DEBUG' => 'dbg,stdout' },
125
+ DD: { 'FLOR_DEBUG' => 'dbg,sto,stdout' },
126
+ }
127
+ ```
128
+
129
+ Examples:
130
+ # Run all tests in a dir
131
+ bundle exec proba test/
132
+
133
+ # Run all the tests in a file
134
+ bundle exec proba test/this_test.rb
135
+ }.rstrip + "\n\n"
136
+ exit 0
137
+ end
138
+
139
+ if switches['--version']
140
+
141
+ puts "proba -- probatio test tool -- #{Probatio::VERSION}"
142
+ exit 0
143
+
144
+ elsif switches['-x'] || switches['--example']
145
+
146
+ puts File.read(File.join(__dir__, '../lib/probatio/examples/a_test.rb'))
147
+ exit 0
148
+
149
+ elsif switches['-X'] || switches['--plugin-example']
150
+
151
+ puts File.read(File.join(__dir__, '../lib/probatio/examples/a_plugin.rb'))
152
+ exit 0
153
+
154
+ elsif switches['--mangle']
155
+
156
+ require 'probatio/mangle'
157
+ Probatio.mangle(dirs, files, switches)
158
+ exit 0
159
+ end
160
+
161
+ opts = {}
162
+
163
+ opts[:dry] = true if switches['-y'] || switches['--dry']
164
+
165
+ opts[:map] = true if switches['-m'] || switches['--map']
166
+ opts[:print] = true if switches['-p'] || switches['--print']
167
+
168
+ opts[:dirs] = dirs if dirs.any?
169
+ opts[:files] = files.any? ? files : []
170
+
171
+ def read_list(a, item)
172
+
173
+ case item
174
+ when Array
175
+ item.each { |e| read_list(a, e) }
176
+ when Hash
177
+ if item[:p].is_a?(String)
178
+ a << [ item[:p], item[:l] ].compact.collect(&:to_s).join(':')
179
+ elsif (fs = item[:failures] || item[:files] || item[:paths]).is_a?(Array)
180
+ read_list(a, fs)
181
+ #else
182
+ # no item to add...
183
+ end
184
+ else
185
+ s = item.to_s.strip
186
+ a << s if File.file?(s.split(':').first)
187
+ end
188
+
189
+ a
190
+ end
191
+
192
+ prev = Kernel.eval(File.read(Probatio.opath)) rescue { failures: [] }
193
+ fails = prev[:failures].collect { |f| "#{f[:p]}:#{f[:l]}" }
194
+ #print 'fails:'; pp fails
195
+ #
196
+ tpoint = File.exist?(Probatio.tpath) ? File.read(Probatio.tpath).strip : nil
197
+ #
198
+ strings.each do |s|
199
+ opts[:files] <<
200
+ case s
201
+ when '.' then tpoint
202
+ when 'f' then tpoint && tpoint.split(':').first
203
+ when '1st', 'first' then fails[0]
204
+ when 'last' then fails[-1]
205
+ when /^:\d+$/ then fails.find { |f| f.end_with?(s) }
206
+ else nil; end
207
+ end
208
+ integers.each do |i|
209
+ opts[:files] << fails[i]
210
+ end
211
+ lists.each do |li|
212
+ opts[:files].concat(
213
+ li.end_with?('_list.rb') ? read_list([], Kernel.eval(File.read(li))) :
214
+ read_list([], File.readlines(li)))
215
+ end
216
+ #
217
+ opts[:files] = opts[:files].uniq.compact
218
+ opts[:files] = nil if opts[:files].empty? && strings.empty? && integers.empty?
219
+
220
+ opts[:dirs] = [
221
+ is_directory_with_tests?('test') ? 'test' :
222
+ is_directory_with_tests?('spec') ? 'spec' :
223
+ 'test'
224
+ ] unless opts[:dirs] || opts[:files]
225
+
226
+ opts[:includes] = Probatio.to_rexes_and_strs(switches['--name'])
227
+ opts[:excludes] = Probatio.to_rexes_and_strs(switches['--exclude'])
228
+
229
+ s = switches['--seed'] || []
230
+ s = s.any? ? s.first : (Time.now.to_f * 1000) % 99_999
231
+ opts[:seed] = s.to_i
232
+
233
+ if environments.any?
234
+ envs =
235
+ (File.exist?(Probatio.epath) &&
236
+ Kernel.eval(File.read(Probatio.epath)) rescue nil) ||
237
+ {}
238
+ environments.each do |e|
239
+ (envs[e.to_sym] || {}).each { |k, v|
240
+ Probatio.dbg_s { " . setting ENV[#{k.inspect}] to #{v.inspect}" }
241
+ ENV[k] = v }
242
+ end
243
+ end
244
+
245
+ Probatio.dbg_s { ' * opts: ' + opts.inspect }
246
+
247
+ if strings & %w[ . 1st first last ]
248
+ puts $_PROBATIO_COLOURS.dark_grey
249
+ puts opts[:files]
250
+ print $_PROBATIO_COLOURS.reset
251
+ end
9
252
 
10
253
  #
11
254
  # run
12
255
 
13
256
  Probatio.run(opts)
14
257
 
258
+
15
259
  # vim: set filetype=ruby
16
260