rspec-ontap 0.1.0 → 0.2.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.
data/.ruby CHANGED
@@ -30,9 +30,9 @@ load_path:
30
30
  revision: 0
31
31
  created: '2011-12-13'
32
32
  summary: RSpec On Tap-Y/J
33
- title: RSpecOnTap
34
- version: 0.1.0
33
+ title: RSpec-On-Tap
34
+ version: 0.2.0
35
35
  name: rspec-ontap
36
- description: RSpecOnTap is a TAP-Y/J formatter for RSpec.
36
+ description: RSpec-On-Tap is a TAP-Y/J formatter for RSpec.
37
37
  organization: Rubyworks
38
- date: '2011-12-12'
38
+ date: '2012-02-01'
data/HISTORY.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # Release History
2
2
 
3
3
 
4
+ ## 0.2.0 / 2012-02-01
5
+
6
+ This release adds support for $stdout and $stderr capturing.
7
+
8
+ Changes:
9
+
10
+ * Handle captured stdout and stderr.
11
+
12
+
4
13
  ## 0.1.0 / 2011-12-13
5
14
 
6
15
  This is the first release of `RSpec On Tap`, a formatter for RSpec
@@ -8,21 +8,27 @@ module RSpec
8
8
  class TapBaseFormatter < Core::Formatters::BaseFormatter
9
9
 
10
10
  # TAP-Y/J Revision
11
- REVISION = 3
11
+ REVISION = 4
12
12
 
13
+ #
13
14
  attr_accessor :example_group_stack
14
15
 
16
+ #
17
+ #
18
+ #
15
19
  def initialize(output)
16
20
  super(output)
17
21
  @example_group_stack = []
18
22
  end
19
23
 
24
+ #
20
25
  # This method is invoked before any examples are run, right after
21
26
  # they have all been collected. This can be useful for special
22
27
  # formatters that need to provide progress on feedback (graphical ones)
23
28
  #
24
29
  # This will only be invoked once, and the next one to be invoked
25
30
  # is #example_group_started
31
+ #
26
32
  def start(example_count)
27
33
  super(example_count)
28
34
 
@@ -38,11 +44,13 @@ module RSpec
38
44
  return doc
39
45
  end
40
46
 
47
+ #
41
48
  # This method is invoked at the beginning of the execution of each example group.
42
49
  # +example_group+ is the example_group.
43
50
  #
44
51
  # The next method to be invoked after this is +example_passed+,
45
52
  # +example_pending+, or +example_finished+
53
+ #
46
54
  def example_group_started(example_group)
47
55
  super(example_group) #@example_group = example_group
48
56
  doc = {
@@ -64,6 +72,8 @@ module RSpec
64
72
  #
65
73
  def example_started(example)
66
74
  examples << example
75
+ # set up stdout and stderr to be captured
76
+ reset_output
67
77
  end
68
78
 
69
79
  #
@@ -93,6 +103,9 @@ module RSpec
93
103
  #}
94
104
  'time' => Time.now - @start_time
95
105
  }
106
+
107
+ doc.update(captured_output)
108
+
96
109
  return doc
97
110
  end
98
111
 
@@ -121,6 +134,9 @@ module RSpec
121
134
  #}
122
135
  'time' => Time.now - @start_time
123
136
  }
137
+
138
+ doc.update(captured_output)
139
+
124
140
  return doc
125
141
  end
126
142
 
@@ -185,6 +201,8 @@ module RSpec
185
201
  'time' => Time.now - @start_time
186
202
  )
187
203
 
204
+ doc.update(captured_output)
205
+
188
206
  return doc
189
207
  end
190
208
 
@@ -276,6 +294,47 @@ module RSpec
276
294
  return source_file, source_line
277
295
  end
278
296
 
297
+ #
298
+ def reset_output
299
+ @_oldout = $stdout
300
+ @_olderr = $stderr
301
+
302
+ @_newout = StringIO.new
303
+ @_newerr = StringIO.new
304
+
305
+ $stdout = @_newout
306
+ $stderr = @_newerr
307
+ end
308
+
309
+ #
310
+ def captured_output
311
+ stdout = @_newout.string.chomp("\n")
312
+ stderr = @_newerr.string.chomp("\n")
313
+
314
+ doc = {}
315
+ doc['stdout'] = stdout unless stdout.empty?
316
+ doc['stderr'] = stderr unless stderr.empty?
317
+
318
+ $stdout = @_oldout
319
+ $stderr = @_olderr
320
+
321
+ return doc
322
+ end
323
+
324
+ #
325
+ def capture_io
326
+ ostdout, ostderr = $stdout, $stderr
327
+ cstdout, cstderr = StringIO.new, StringIO.new
328
+ $stdout, $stderr = cstdout, cstderr
329
+
330
+ yield
331
+
332
+ return cstdout.string.chomp("\n"), cstderr.string.chomp("\n")
333
+ ensure
334
+ $stdout = ostdout
335
+ $stderr = ostderr
336
+ end
337
+
279
338
  end
280
339
 
281
340
  #
@@ -305,7 +364,7 @@ module RSpec
305
364
  end
306
365
  end
307
366
 
308
- #
367
+ #rspec -f RSpec::TapY spec/*.rb | tapout progress
309
368
  class TapJ < TapBaseFormatter
310
369
  def initialize(*whatever)
311
370
  require 'json'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-ontap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-14 00:00:00.000000000 Z
12
+ date: 2012-02-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &16983840 !ruby/object:Gem::Requirement
16
+ requirement: &11523640 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *16983840
24
+ version_requirements: *11523640
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: tapout
27
- requirement: &16982400 !ruby/object:Gem::Requirement
27
+ requirement: &11522360 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *16982400
35
+ version_requirements: *11522360
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: detroit
38
- requirement: &16980480 !ruby/object:Gem::Requirement
38
+ requirement: &11521320 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,8 +43,8 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *16980480
47
- description: RSpecOnTap is a TAP-Y/J formatter for RSpec.
46
+ version_requirements: *11521320
47
+ description: RSpec-On-Tap is a TAP-Y/J formatter for RSpec.
48
48
  email:
49
49
  - transfire@gmail.com
50
50
  executables: []
@@ -57,10 +57,8 @@ files:
57
57
  - .ruby
58
58
  - .yardopts
59
59
  - lib/rspec/ontap.rb
60
- - lib/rspec/tap.rb
61
60
  - lib/rspec/tap_j.rb
62
61
  - lib/rspec/tap_y.rb
63
- - spec/demonstrate.rb
64
62
  - HISTORY.md
65
63
  - README.md
66
64
  - COPYING.rdoc
@@ -85,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
83
  version: '0'
86
84
  requirements: []
87
85
  rubyforge_project:
88
- rubygems_version: 1.8.10
86
+ rubygems_version: 1.8.11
89
87
  signing_key:
90
88
  specification_version: 3
91
89
  summary: RSpec On Tap-Y/J
@@ -1,336 +0,0 @@
1
- require 'rspec/core/formatters/base_formatter'
2
-
3
- module RSpec
4
- #module Core
5
- #module Formatters
6
-
7
- #
8
- class TapBaseFormatter < Core::Formatters::BaseFormatter
9
-
10
- # TAP-Y/J Revision
11
- REVISION = 3
12
-
13
- attr_accessor :example_group_stack
14
-
15
- def initialize(output)
16
- super(output)
17
- @example_group_stack = []
18
- end
19
-
20
- # This method is invoked before any examples are run, right after
21
- # they have all been collected. This can be useful for special
22
- # formatters that need to provide progress on feedback (graphical ones)
23
- #
24
- # This will only be invoked once, and the next one to be invoked
25
- # is #example_group_started
26
- def start(example_count)
27
- super(example_count)
28
-
29
- @start_time = Time.now
30
-
31
- doc = {
32
- 'type' => 'suite',
33
- 'start' => @start_time.strftime('%Y-%m-%d %H:%M:%S'),
34
- 'count' => example_count,
35
- 'seed' => @seed,
36
- 'rev' => REVISION
37
- }
38
- return doc
39
- end
40
-
41
- # This method is invoked at the beginning of the execution of each example group.
42
- # +example_group+ is the example_group.
43
- #
44
- # The next method to be invoked after this is +example_passed+,
45
- # +example_pending+, or +example_finished+
46
- def example_group_started(example_group)
47
- super(example_group) #@example_group = example_group
48
- doc = {
49
- 'type' => 'case',
50
- 'subtype' => 'describe',
51
- 'label' => "#{example_group.description}",
52
- 'level' => @example_group_stack.size
53
- }
54
- @example_group_stack << example_group
55
- return doc
56
- end
57
-
58
- # This method is invoked at the end of the execution of each example group.
59
- # +example_group+ is the example_group.
60
- def example_group_finished(example_group)
61
- @example_group_stack.pop
62
- end
63
-
64
- #
65
- def example_started(example)
66
- examples << example
67
- end
68
-
69
- #
70
- def example_passed(example)
71
- super(example)
72
-
73
- file, line = example.location.split(':')
74
- file = self.class.relative_path(file)
75
- line = line.to_i
76
-
77
- doc = {
78
- 'type' => 'test',
79
- 'subtype' => 'it',
80
- 'status' => 'pass',
81
- #'setup': foo instance
82
- 'label' => "#{example.description}",
83
- #'expected' => 2
84
- #'returned' => 2
85
- 'file' => file,
86
- 'line' => line,
87
- 'source' => source(file)[line-1].strip,
88
- 'snippet' => code_snippet(file, line),
89
- #'coverage' => {
90
- # file: lib/foo.rb
91
- # line: 11..13
92
- # code: Foo#*
93
- #}
94
- 'time' => Time.now - @start_time
95
- }
96
- return doc
97
- end
98
-
99
- #
100
- def example_pending(example)
101
- super(example)
102
-
103
- file, line = example.location.split(':')
104
- file = self.class.relative_path(file)
105
- line = line.to_i
106
-
107
- doc = {
108
- 'type' => 'test',
109
- 'subtype' => 'it',
110
- 'status' => 'todo',
111
- #'setup': foo instance
112
- 'label' => "#{example.description}",
113
- 'file' => file,
114
- 'line' => line,
115
- 'source' => source(file)[line-1].strip,
116
- 'snippet' => code_snippet(file, line),
117
- #'coverage' => {
118
- # file: lib/foo.rb
119
- # line: 11..13
120
- # code: Foo#*
121
- #}
122
- 'time' => Time.now - @start_time
123
- }
124
- return doc
125
- end
126
-
127
- def example_failed(example)
128
- super(example)
129
-
130
- file, line = example.location.split(':')
131
-
132
- file = self.class.relative_path(file)
133
- line = line.to_i
134
-
135
- if RSpec::Expectations::ExpectationNotMetError === example.exception
136
- status = 'fail'
137
- if md = /expected:\s*(.*?)\n\s*got:\s*(.*?)\s+/.match(example.exception.to_s)
138
- expected, returned = md[1], md[2]
139
- else
140
- expected, returned = nil, nil
141
- end
142
- else
143
- status = 'error'
144
- end
145
-
146
- backtrace = format_backtrace(example.exception.backtrace, example)
147
-
148
- efile, eline = parse_source_location(backtrace)
149
-
150
- doc = {
151
- 'type' => 'test',
152
- 'subtype' => 'it',
153
- 'status' => status,
154
- 'label' => "#{example.description}",
155
- #'setup' => "foo instance",
156
- 'file' => file,
157
- 'line' => line,
158
- 'source' => source(file)[line-1].strip,
159
- 'snippet' => code_snippet(file, line),
160
- #'coverage' =>
161
- #{
162
- # 'file' => lib/foo.rb
163
- # 'line' => 11..13
164
- # 'code' => Foo#*
165
- #}
166
- }
167
-
168
- if expected or returned
169
- doc.update(
170
- 'expected' => expected,
171
- 'returned' => returned,
172
- )
173
- end
174
-
175
- doc.update(
176
- 'exception' => {
177
- 'message' => example.exception.to_s.strip,
178
- 'class' => example.exception.class.name,
179
- 'file' => efile,
180
- 'line' => eline,
181
- 'source' => source(efile)[eline-1].strip,
182
- 'snippet' => code_snippet(efile, eline),
183
- 'backtrace' => backtrace
184
- },
185
- 'time' => Time.now - @start_time
186
- )
187
-
188
- return doc
189
- end
190
-
191
- # @todo Is this a note?
192
- def message(message)
193
- end
194
-
195
- #def stop
196
- #end
197
-
198
- # This method is invoked after the dumping of examples and failures.
199
- def dump_summary(duration, example_count, failure_count, pending_count)
200
- super(duration, example_count, failure_count, pending_count)
201
-
202
- error_count = 0
203
-
204
- @failed_examples.each do |e|
205
- if RSpec::Expectations::ExpectationNotMetError === e.exception
206
- #failure_count += 1
207
- else
208
- failure_count -= 1
209
- error_count += 1
210
- end
211
- end
212
-
213
- passing_count = example_count - failure_count - error_count - pending_count
214
-
215
- doc = {
216
- 'type' => 'final',
217
- 'time' => duration,
218
- 'counts' => {
219
- 'total' => example_count,
220
- 'pass' => passing_count,
221
- 'fail' => failure_count,
222
- 'error' => error_count,
223
- 'omit' => 0,
224
- 'todo' => pending_count
225
- }
226
- }
227
- return doc
228
- end
229
-
230
- # This gets invoked after the summary if option is set to do so.
231
- #def dump_pending
232
- #end
233
-
234
- def seed(number)
235
- @seed = number
236
- end
237
-
238
- private
239
-
240
- # Returns a String of source code.
241
- def code_snippet(file, line)
242
- s = []
243
- if File.file?(file)
244
- source = source(file)
245
- radius = 2 # TODO: make customizable (number of surrounding lines to show)
246
- region = [line - radius, 1].max ..
247
- [line + radius, source.length].min
248
-
249
- s = region.map do |n|
250
- {n => source[n-1].chomp}
251
- end
252
- end
253
- return s
254
- end
255
-
256
- # Cache source file text. This is only used if the TAP-Y stream
257
- # doesn not provide a snippet and the test file is locatable.
258
- def source(file)
259
- @_source_cache ||= {}
260
- @_source_cache[file] ||= (
261
- File.readlines(file)
262
- )
263
- end
264
-
265
- # Parse source location from caller, caller[0] or an Exception object.
266
- def parse_source_location(caller)
267
- case caller
268
- when Exception
269
- trace = caller.backtrace #.reject{ |bt| bt =~ INTERNALS }
270
- caller = trace.first
271
- when Array
272
- caller = caller.first
273
- end
274
- caller =~ /(.+?):(\d+(?=:|\z))/ or return ""
275
- source_file, source_line = $1, $2.to_i
276
- return source_file, source_line
277
- end
278
-
279
- end
280
-
281
- #
282
- class TapY < TapBaseFormatter
283
- def initialize(*whatever)
284
- require 'yaml'
285
- super(*whatever)
286
- end
287
- def start(example_count)
288
- output.puts super(example_count).to_yaml
289
- end
290
- def example_group_started(example_group)
291
- output.puts super(example_group).to_yaml
292
- end
293
- def example_passed(example)
294
- output.puts super(example).to_yaml
295
- end
296
- def example_pending(example)
297
- output.puts super(example).to_yaml
298
- end
299
- def example_failed(example)
300
- output.puts super(example).to_yaml
301
- end
302
- def dump_summary(duration, example_count, failure_count, pending_count)
303
- output.puts super(duration, example_count, failure_count, pending_count).to_yaml
304
- output.puts "..."
305
- end
306
- end
307
-
308
- #
309
- class TapJ < TapBaseFormatter
310
- def initialize(*whatever)
311
- require 'json'
312
- super(*whatever)
313
- end
314
- def start(example_count)
315
- output.puts super(example_count).to_json
316
- end
317
- def example_group_started(example_group)
318
- output.puts super(example_group).to_json
319
- end
320
- def example_passed(example)
321
- output.puts super(example).to_json
322
- end
323
- def example_pending(example)
324
- output.puts super(example).to_json
325
- end
326
- def example_failed(example)
327
- output.puts super(example).to_json
328
- end
329
- def dump_summary(duration, example_count, failure_count, pending_count)
330
- output.puts super(duration, example_count, failure_count, pending_count).to_json
331
- end
332
- end
333
-
334
- #end
335
- #end
336
- end
@@ -1,16 +0,0 @@
1
- describe "demonstration" do
2
-
3
- it "should show this passing" do
4
- 1.should == 1
5
- end
6
-
7
- it "should show this failing" do
8
- 1.should == 2
9
- end
10
-
11
- it "should show this raising an error" do
12
- raise NameError
13
- end
14
-
15
- end
16
-