rspec-ontap 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
-