probatio 0.9.0 → 1.1.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.
@@ -0,0 +1,72 @@
1
+
2
+ #
3
+ # probatio/plug.rb
4
+
5
+
6
+ module Probatio; class << self
7
+
8
+ def plugins; @plugins; end
9
+
10
+ def plug(x, position=:last)
11
+
12
+ @plugins.insert(determine_plugin_pos(position), x)
13
+ @plugouts = nil
14
+ end
15
+
16
+ def unplug(old)
17
+
18
+ i =
19
+ plug_index(old) ||
20
+ fail(ArgumentError.new("Cannot locate plugin to remove"))
21
+
22
+ @plugins.delete_at(i)
23
+ @plugouts = nil
24
+ end
25
+
26
+ def replug(old, new)
27
+
28
+ i =
29
+ plug_index(old) ||
30
+ fail(ArgumentError.new("Cannot locate plugin to replace"))
31
+
32
+ @plugins[i] = new
33
+ @plugouts = nil
34
+ end
35
+
36
+ protected
37
+
38
+ def plugin_index(x)
39
+
40
+ return x \
41
+ if x.is_a?(Integer)
42
+ return @plugins.index { |pl| pl.respond_to?(x) } \
43
+ if x.is_a?(Symbol) || x.is_a?(String)
44
+
45
+ i = @plugins.index(x); return i if i
46
+
47
+ return @plugins.index { |pl| pl.is_a?(x) } if x.is_a?(Module)
48
+
49
+ nil
50
+ end
51
+
52
+ def determine_plugin_pos(pos)
53
+
54
+ return pos if pos.is_a?(Integer)
55
+
56
+ return 0 if pos == :first
57
+ #return @plugins.length if pos == :last
58
+
59
+ h = pos.is_a?(Hash) ? pos : {}
60
+
61
+ l = @plugins.length
62
+
63
+ if af = h[:after]
64
+ (@plugins.index { |pl| pl == af || (pl.is_a?(af) rescue nil) } || l) + 1
65
+ elsif bf = h[:before]
66
+ (@plugins.index { |pl| pl == bf || (pl.is_a?(bf) rescue nil) } || l)
67
+ else
68
+ l # last resort, put at the end...
69
+ end
70
+ end
71
+ end; end
72
+
@@ -0,0 +1,253 @@
1
+
2
+ #
3
+ # probatio/plugins.rb
4
+
5
+ module Probatio::Colours
6
+
7
+ protected
8
+
9
+ def c; Probatio.c; end # colours or not...
10
+ end
11
+
12
+ class Probatio::Recorder
13
+
14
+ attr_reader :events
15
+
16
+ def record(ev)
17
+
18
+ (@events ||= []) << ev
19
+ end
20
+
21
+ def failures; @events.select { |ev| ev.name == 'test_fail' }; end
22
+ def successes; @events.select { |ev| ev.name == 'test_succeed' }; end
23
+
24
+ def test_leave_event(test_node)
25
+
26
+ @events.find { |e|
27
+ e.name == 'test_leave' &&
28
+ e.node_full_name == test_node.full_name }
29
+ end
30
+
31
+ def total_duration
32
+
33
+ @events.last.tstamp - @events.first.tstamp
34
+ end
35
+
36
+ def failed_tests; @events.select { |e| e.name == 'test_fail' }; end
37
+
38
+ def test_count; @events.count { |e| e.name == 'test_leave' }; end
39
+ def assertion_count; @events.count { |e| e.name == 'assertion_leave' }; end
40
+ def failure_count; @events.count { |e| e.name == 'test_fail' }; end
41
+ def pending_count; @events.count { |e| e.name == 'test_pending' }; end
42
+
43
+ def file_count
44
+
45
+ @events.map(&:path).compact.uniq.count
46
+ end
47
+ end
48
+
49
+ module Probatio
50
+
51
+ class << self
52
+
53
+ def recorder_plugin
54
+
55
+ @plugins.find { |pl| pl.respond_to?(:events) }
56
+ end
57
+ end
58
+ end
59
+
60
+ class Probatio::Chronometer
61
+
62
+ def record(ev)
63
+
64
+ # compute ev.leave_delta if ev is a "leave"
65
+
66
+ if ev.enter?
67
+
68
+ (@enters ||= []) << ev
69
+
70
+ elsif ev.leave?
71
+
72
+ e = @enters.pop
73
+
74
+ fail "ev mismatch #{ev.name} vs #{e.name}" \
75
+ if ( ! e) || (ev.type != e.type)
76
+
77
+ ev.leave_delta = ev.tstamp - e.tstamp
78
+ end
79
+ end
80
+ end
81
+
82
+ module Probatio::SeedReporter
83
+
84
+ def on_start(ev)
85
+
86
+ puts
87
+ puts "Run options: --seed #{Probatio.seed}"
88
+ puts
89
+ end
90
+ end
91
+
92
+ class Probatio::DotReporter
93
+
94
+ include Probatio::Colours
95
+ include Probatio::SeedReporter
96
+
97
+ def on_test_succeed(ev)
98
+
99
+ print c.dark_grey + '·' + c.reset
100
+ end
101
+
102
+ def on_test_fail(ev)
103
+
104
+ print c.red + 'x' + c.reset
105
+ end
106
+
107
+ def on_test_pending(ev)
108
+
109
+ print c.yellow + '.' + c.reset
110
+ end
111
+ end
112
+
113
+ class Probatio::VanillaSummarizer
114
+
115
+ def on_over(ev)
116
+
117
+ c = Probatio.c # colours or not
118
+
119
+ recorder = Probatio.plugins.find { |pl| pl.respond_to?(:failures) }
120
+ return unless recorder
121
+
122
+ if recorder.test_count == 0
123
+ puts c.dark_grey(" ¯\\_(ツ)_/¯")
124
+ else
125
+ puts
126
+ end
127
+
128
+ recorder.failures.each do |ev|
129
+
130
+ #puts
131
+ puts '-' * [ Probatio.term_width, 80 ].min
132
+ #puts ev.leaf.parent.to_s
133
+ #puts ev.leaf.head
134
+ #puts ev.leaf.trail
135
+ puts ev.error.trail
136
+ puts
137
+ #puts "%4d %s" % [ ev.error.line, c.dark_grey(ev.error.source_line) ]
138
+ #puts c.dark_grey(ev.error.path)
139
+ ev.error.source_lines.each do |i, l|
140
+ puts "%4s %s" % [
141
+ i == ev.error.line ? c.underlined(i.to_s) :
142
+ i % 5 == 0 ? c.dark_grey(i.to_s) :
143
+ c.white(i.to_s),
144
+ i == ev.error.line ? c.yellow(l) : c.dark_grey(l) ]
145
+ end
146
+ puts; puts c.dark_grey(ev.error.summary(' '))
147
+ #puts ev.error.inspect
148
+ #puts '.'
149
+ #puts ev.to_s
150
+ #puts
151
+ end
152
+ #puts '-' * 80 if recorder.failures.any?
153
+
154
+ r = Probatio.recorder_plugin
155
+
156
+ d = r.total_duration
157
+
158
+ tc = r.test_count
159
+ ac = r.assertion_count
160
+
161
+ fc = r.failure_count; fc = Probatio.c.red(fc.to_s) if fc > 0
162
+ pc = r.pending_count; pc = Probatio.c.yellow(pc.to_s) if pc > 0
163
+
164
+ tpc = tc / d
165
+ apc = ac / d
166
+
167
+ fic = r.file_count
168
+
169
+ puts
170
+ puts
171
+ print "Finished in #{Probatio.to_time_s(d)}, "
172
+ print "%0.3f tests/s, %0.3f assertions/s." % [ tpc, apc ]
173
+ puts
174
+ puts
175
+ print "#{tc} test#{s(tc)}, #{ac} assertion#{s(ac)}, "
176
+ print "#{fc} failure#{s(fc)}, #{pc} pending, "
177
+ print "#{fic} file#{s(fic)}."
178
+ puts
179
+ puts
180
+ end
181
+
182
+ protected
183
+
184
+ def s(count); count == 1 ? '' : 's'; end
185
+ end
186
+
187
+ class Probatio::ProbaOutputter
188
+
189
+ require 'rbconfig'
190
+
191
+ def on_over(ev)
192
+
193
+ # TODO unplug if --mute or some switch like that...
194
+ r = Probatio.recorder_plugin
195
+
196
+ flh = r.failed_tests.collect(&:to_h).each { |h| h.delete(:n) }
197
+ fls = Cerata.table_to_s(flh, ' ')
198
+
199
+ rb = {}
200
+ #
201
+ rv =
202
+ File.exist?('.ruby-version') &&
203
+ File.readlines('.ruby-version').find { |l| ! l.strip.start_with?('#') }
204
+ #
205
+ rb[:v] = ".ruby-version:#{rv.strip}" if rv
206
+ rb[:p] = File.join(
207
+ RbConfig::CONFIG['bindir'],
208
+ RbConfig::CONFIG['ruby_install_name'])
209
+ rb[:d] = RUBY_DESCRIPTION
210
+ rb[:l] = RUBY_PATCHLEVEL
211
+ #
212
+ #rb = Cerata.horizontal_h_to_s(rb)
213
+ rb = Cerata.vertical_h_to_s(rb, ' ')
214
+
215
+ env = Cerata.vertical_h_to_s(
216
+ ENV.filter { |k, _|
217
+ k.match?(/^(RUBY_|GEM_|(HOME|PATH|USER|SHELL|PWD)$)/) },
218
+ ' ')
219
+
220
+ File.open(Probatio.opath, 'wb') do |o|
221
+ o << '# ' << Probatio.opath << "\n"
222
+ o << "{\n"
223
+ o << "argv: " << Cerata.horizontal_a_to_s(ARGV) << ",\n"
224
+ o << "failures:\n"
225
+ #o << " [\n"
226
+ #fls.each { |fl| o << ' ' << fl << ",\n" }
227
+ #o << " ],\n"
228
+ o << fls << ",\n"
229
+ o << "duration: #{Probatio.to_time_s(r.total_duration).inspect},\n"
230
+ o << "probatio: { v: #{Probatio::VERSION.inspect} },\n"
231
+ o << "ruby:\n#{rb},\n"
232
+ o << "some_env:\n#{env},\n"
233
+ o << "}\n"
234
+ end
235
+ end
236
+ end
237
+
238
+ class Probatio::Exitter
239
+
240
+ def on_exit(ev)
241
+
242
+ exit 1 if Probatio.recorder_plugin.failure_count > 0
243
+ exit 0
244
+ end
245
+ end
246
+
247
+ Probatio.plug(Probatio::Recorder.new)
248
+ Probatio.plug(Probatio::Chronometer.new)
249
+ Probatio.plug(Probatio::DotReporter.new)
250
+ Probatio.plug(Probatio::VanillaSummarizer.new)
251
+ Probatio.plug(Probatio::ProbaOutputter.new)
252
+ Probatio.plug(Probatio::Exitter.new)
253
+
@@ -0,0 +1,44 @@
1
+
2
+ #
3
+ # probatio/waiters.rb
4
+
5
+ module Probatio::Waiters
6
+
7
+ def wait_until(opts={}, &block)
8
+
9
+ timeout = opts[:timeout] || 14
10
+ frequency = opts[:frequency] || 0.1
11
+
12
+ start = Probatio.monow
13
+
14
+ loop do
15
+
16
+ sleep(frequency)
17
+
18
+ #return if block.call == true
19
+ r = block.call
20
+ return r if r
21
+
22
+ break if Probatio.monow - start > timeout
23
+ end
24
+
25
+ fail "timeout after #{timeout}s"
26
+ end
27
+ alias wait_for wait_until
28
+
29
+ def monow
30
+
31
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
32
+ end
33
+ end
34
+
35
+ class Probatio::Section
36
+
37
+ include Probatio::Waiters
38
+ end
39
+
40
+ class Probatio::Context
41
+
42
+ include Probatio::Waiters
43
+ end
44
+