rspec 0.7.3 → 0.7.4
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/CHANGES +23 -1
- data/Rakefile +11 -9
- data/bin/spec +0 -1
- data/lib/spec.rb +1 -0
- data/lib/spec/callback.rb +3 -0
- data/lib/spec/callback/callback_container.rb +60 -0
- data/lib/spec/callback/extensions/module.rb +24 -0
- data/lib/spec/callback/extensions/object.rb +33 -0
- data/lib/spec/expectations/diff.rb +10 -14
- data/lib/spec/expectations/extensions.rb +1 -3
- data/lib/spec/expectations/extensions/numeric.rb +6 -1
- data/lib/spec/expectations/extensions/object.rb +72 -18
- data/lib/spec/expectations/should/base.rb +27 -5
- data/lib/spec/expectations/should/have.rb +2 -2
- data/lib/spec/expectations/should/should.rb +5 -4
- data/lib/spec/mocks/error_generator.rb +23 -12
- data/lib/spec/mocks/message_expectation.rb +4 -0
- data/lib/spec/mocks/mock_handler.rb +9 -8
- data/lib/spec/rake/spectask.rb +2 -1
- data/lib/spec/runner.rb +0 -1
- data/lib/spec/runner/backtrace_tweaker.rb +1 -0
- data/lib/spec/runner/context_eval.rb +1 -1
- data/lib/spec/runner/formatter/base_text_formatter.rb +1 -1
- data/lib/spec/runner/formatter/html_formatter.rb +94 -74
- data/lib/spec/runner/option_parser.rb +5 -1
- data/lib/spec/runner/specification.rb +64 -37
- data/lib/spec/version.rb +3 -3
- data/vendor/{selenium → web_spec/selenium}/README.txt +0 -0
- data/vendor/{selenium → web_spec/selenium}/find_rspecs_home_page.rb +0 -0
- data/vendor/{selenium → web_spec/selenium}/rspec_selenium.rb +0 -0
- data/vendor/{selenium → web_spec/selenium}/start_browser_once.patch +0 -0
- data/vendor/{watir → web_spec/watir}/README.txt +2 -2
- data/vendor/web_spec/watir/find_rspecs_home_page.rb +27 -0
- data/vendor/{watir → web_spec/watir}/find_rspecs_home_page.txt +0 -0
- data/vendor/{watir → web_spec/watir}/rspec_watir.rb +13 -12
- data/vendor/web_spec/web_test_html_formatter.rb +8 -0
- data/vendor/web_spec/web_test_html_formatter_helper.rb +26 -0
- data/vendor/web_spec/web_test_html_formatter_osx_helper.rb +19 -0
- data/vendor/web_spec/web_test_html_formatter_win_helper.rb +14 -0
- metadata +19 -14
- data/lib/spec/expectations/extensions/inspect_for_expectation_not_met_error.rb +0 -15
- data/lib/spec/expectations/extensions/symbol.rb +0 -5
- data/lib/spec/runner/extensions/object.rb +0 -21
- data/vendor/watir/find_rspecs_home_page.rb +0 -21
@@ -40,7 +40,7 @@ module Spec
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def msg(sym, args, text)
|
43
|
-
"#{@target.
|
43
|
+
"#{@target.inspect} #{text} #{sym}: #{args.collect{|arg| arg.inspect}.join(', ')}"
|
44
44
|
end
|
45
45
|
|
46
46
|
def actual_size(collection)
|
@@ -49,7 +49,7 @@ module Spec
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def build_message(sym, args)
|
52
|
-
message = "#{@target.
|
52
|
+
message = "#{@target.inspect} should have"
|
53
53
|
message += " at least" if @at_least
|
54
54
|
message += " at most" if @at_most
|
55
55
|
message += " #{@expected} #{sym} (has #{actual_size(collection(sym, args))})"
|
@@ -7,7 +7,7 @@ module Spec
|
|
7
7
|
@target = target
|
8
8
|
@be_seen = false
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def have(expected_number=nil)
|
12
12
|
Have.new(@target, :exactly, expected_number)
|
13
13
|
end
|
@@ -45,7 +45,8 @@ module Spec
|
|
45
45
|
|
46
46
|
def __delegate_method_missing_to_target(original_sym, actual_sym, *args)
|
47
47
|
return if @target.send(actual_sym, *args)
|
48
|
-
|
48
|
+
message = default_message("should#{@be_seen ? ' be' : ''} #{original_sym}", args[0])
|
49
|
+
fail_with_message(message)
|
49
50
|
end
|
50
51
|
|
51
52
|
def match(expected)
|
@@ -58,9 +59,9 @@ module Spec
|
|
58
59
|
rescue exception => e
|
59
60
|
unless message.nil?
|
60
61
|
if message.is_a?(Regexp)
|
61
|
-
e.message.
|
62
|
+
e.message.should =~ message
|
62
63
|
else
|
63
|
-
e.message.
|
64
|
+
e.message.should == message
|
64
65
|
end
|
65
66
|
end
|
66
67
|
return
|
@@ -3,7 +3,7 @@ module Spec
|
|
3
3
|
class ErrorGenerator
|
4
4
|
attr_writer :opts
|
5
5
|
|
6
|
-
def initialize
|
6
|
+
def initialize(target, name)
|
7
7
|
@target = target
|
8
8
|
@name = name
|
9
9
|
end
|
@@ -12,27 +12,34 @@ module Spec
|
|
12
12
|
@opts ||= {}
|
13
13
|
end
|
14
14
|
|
15
|
-
def raise_unexpected_message_error
|
15
|
+
def raise_unexpected_message_error(sym, *args)
|
16
16
|
__raise "#{intro} received unexpected message :#{sym}#{arg_message(*args)}"
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def raise_unexpected_message_args_error(expectation, *args)
|
20
|
+
#this is either :no_args or an Array
|
21
|
+
expected_args = (expectation.expected_args == :no_args ? "(no args)" : format_args(*expectation.expected_args))
|
22
|
+
actual_args = args.empty? ? "(no args)" : format_args(*args)
|
23
|
+
__raise "#{intro} expected #{expectation.sym.inspect} with #{expected_args} but received it with #{actual_args}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def raise_expectation_error(sym, expected_received_count, actual_received_count, *args)
|
20
27
|
__raise "#{intro} expected :#{sym}#{arg_message(*args)} #{count_message(expected_received_count)}, but received it #{count_message(actual_received_count)}"
|
21
28
|
end
|
22
29
|
|
23
|
-
def raise_out_of_order_error
|
30
|
+
def raise_out_of_order_error(sym)
|
24
31
|
__raise "#{intro} received :#{sym} out of order"
|
25
32
|
end
|
26
33
|
|
27
|
-
def raise_block_failed_error
|
34
|
+
def raise_block_failed_error(sym, detail)
|
28
35
|
__raise "#{intro} received :#{sym} but passed block failed with: #{detail}"
|
29
36
|
end
|
30
37
|
|
31
|
-
def raise_missing_block_error
|
38
|
+
def raise_missing_block_error(args_to_yield)
|
32
39
|
__raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed"
|
33
40
|
end
|
34
41
|
|
35
|
-
def raise_wrong_arity_error
|
42
|
+
def raise_wrong_arity_error(args_to_yield, arity)
|
36
43
|
__raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}"
|
37
44
|
end
|
38
45
|
|
@@ -41,15 +48,19 @@ module Spec
|
|
41
48
|
@name ? "Mock '#{@name}'" : @target.to_s
|
42
49
|
end
|
43
50
|
|
44
|
-
def __raise
|
51
|
+
def __raise(message)
|
45
52
|
message = opts[:message] unless opts[:message].nil?
|
46
53
|
Kernel::raise(Spec::Mocks::MockExpectationError, message)
|
47
54
|
end
|
48
55
|
|
49
|
-
def arg_message
|
50
|
-
|
51
|
-
|
52
|
-
|
56
|
+
def arg_message(*args)
|
57
|
+
" with " + format_args(*args)
|
58
|
+
end
|
59
|
+
|
60
|
+
def format_args(*args)
|
61
|
+
return "(no args)" if args.empty? || args == :no_args || args == [:no_args]
|
62
|
+
return "(any args)" if [:any_args] == args
|
63
|
+
"(" + arg_list(*args) + ")"
|
53
64
|
end
|
54
65
|
|
55
66
|
def arg_list(*args)
|
@@ -41,14 +41,11 @@ module Spec
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def __add expected_from, sym, block
|
44
|
-
Runner::Specification.
|
44
|
+
current_spec = Runner::Specification.current
|
45
|
+
current_spec.after_teardown {verify} if current_spec && @options[:auto_verify]
|
45
46
|
define_expected_method(sym)
|
46
47
|
end
|
47
48
|
|
48
|
-
def spec_finished spec
|
49
|
-
verify
|
50
|
-
end
|
51
|
-
|
52
49
|
def define_expected_method(sym)
|
53
50
|
if @target.respond_to?(sym) && !@proxied_methods[sym]
|
54
51
|
@proxied_methods[sym] = @target.method(sym)
|
@@ -106,7 +103,7 @@ module Spec
|
|
106
103
|
@proxied_methods.clear
|
107
104
|
end
|
108
105
|
|
109
|
-
def metaclass_eval
|
106
|
+
def metaclass_eval(str)
|
110
107
|
(class << @target; self; end).class_eval str
|
111
108
|
end
|
112
109
|
|
@@ -137,13 +134,17 @@ module Spec
|
|
137
134
|
elsif stub = find_matching_method_stub(sym)
|
138
135
|
stub.invoke([], nil)
|
139
136
|
elsif expectation = find_almost_matching_expectation(sym, *args)
|
140
|
-
|
137
|
+
raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object?
|
141
138
|
else
|
142
139
|
@target.send :method_missing, sym, *args, &block
|
143
140
|
end
|
144
141
|
end
|
145
142
|
|
146
|
-
def
|
143
|
+
def raise_unexpected_message_args_error(expectation, *args)
|
144
|
+
@error_generator.raise_unexpected_message_args_error expectation, *args
|
145
|
+
end
|
146
|
+
|
147
|
+
def raise_unexpected_message_error(sym, *args)
|
147
148
|
@error_generator.raise_unexpected_message_error sym, *args
|
148
149
|
end
|
149
150
|
|
data/lib/spec/rake/spectask.rb
CHANGED
data/lib/spec/runner.rb
CHANGED
@@ -11,6 +11,5 @@ require 'spec/runner/backtrace_tweaker'
|
|
11
11
|
require 'spec/runner/reporter'
|
12
12
|
require 'spec/runner/spec_matcher'
|
13
13
|
require 'spec/runner/extensions/kernel'
|
14
|
-
require 'spec/runner/extensions/object'
|
15
14
|
require 'spec/runner/spec_should_raise_handler'
|
16
15
|
require 'spec/runner/spec_parser'
|
@@ -29,6 +29,7 @@ module Spec
|
|
29
29
|
line = nil if line =~ /\/lib\/spec\/mocks\//
|
30
30
|
line = nil if line =~ /\/lib\/spec\/rake\//
|
31
31
|
line = nil if line =~ /\/lib\/spec\/runner\//
|
32
|
+
line = nil if line =~ /\/lib\/spec\/callback\//
|
32
33
|
line = nil if line =~ /bin\/spec:/
|
33
34
|
line = nil if line =~ /bin\/rcov:/
|
34
35
|
line = nil if line =~ /lib\/rspec_on_rails/
|
@@ -4,83 +4,98 @@ module Spec
|
|
4
4
|
class HtmlFormatter < BaseTextFormatter
|
5
5
|
def initialize(output, dry_run=false, colour=false)
|
6
6
|
super
|
7
|
-
@
|
8
|
-
@
|
7
|
+
@current_spec_number = 0
|
8
|
+
@current_context_number = 0
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def start(spec_count)
|
12
12
|
@spec_count = spec_count
|
13
|
-
|
14
|
-
@output.puts
|
13
|
+
|
14
|
+
@output.puts @@header
|
15
15
|
STDOUT.flush
|
16
16
|
end
|
17
17
|
|
18
18
|
def add_context(name, first)
|
19
|
+
@current_context_number += 1
|
19
20
|
unless first
|
20
|
-
@output.puts " </
|
21
|
+
@output.puts " </dl>"
|
21
22
|
@output.puts "</div>"
|
22
23
|
end
|
23
24
|
@output.puts "<div class=\"context\">"
|
24
|
-
@output.puts " <
|
25
|
-
@output.puts " <
|
25
|
+
@output.puts " <dl>"
|
26
|
+
@output.puts " <dt id=\"context_#{@current_context_number}\">#{name}</dt>"
|
26
27
|
STDOUT.flush
|
27
28
|
end
|
28
29
|
|
29
30
|
def start_dump
|
30
|
-
@output.puts " </
|
31
|
+
@output.puts " </dl>"
|
31
32
|
@output.puts "</div>"
|
32
33
|
STDOUT.flush
|
33
34
|
end
|
34
35
|
|
35
36
|
def spec_started(name)
|
36
37
|
@current_spec = name
|
37
|
-
@
|
38
|
+
@current_spec_number += 1
|
38
39
|
STDOUT.flush
|
39
40
|
end
|
40
41
|
|
41
42
|
def spec_passed(name)
|
42
43
|
move_progress
|
43
|
-
@output.puts " <
|
44
|
+
@output.puts " <dd class=\"spec passed\"><span class=\"passed_spec_name\">#{escape(@current_spec)}</span></dd>"
|
44
45
|
STDOUT.flush
|
45
46
|
end
|
46
47
|
|
47
48
|
def spec_failed(name, counter, failure)
|
48
|
-
@output.puts " <script type=\"text/javascript\">
|
49
|
+
@output.puts " <script type=\"text/javascript\">makeRed('header');</script>"
|
50
|
+
@output.puts " <script type=\"text/javascript\">makeRed('context_#{@current_context_number}');</script>"
|
49
51
|
move_progress
|
50
|
-
@output.puts " <
|
51
|
-
@output.puts " <
|
52
|
+
@output.puts " <dd class=\"spec failed\">"
|
53
|
+
@output.puts " <span class=\"failed_spec_name\">#{escape(@current_spec)}</span>"
|
52
54
|
@output.puts " <div class=\"failure\" id=\"failure_#{counter}\">"
|
53
55
|
@output.puts " <div class=\"message\"><pre>#{escape(failure.exception.message)}</pre></div>" unless failure.exception.nil?
|
54
56
|
@output.puts " <div class=\"backtrace\"><pre>#{format_backtrace(failure.exception.backtrace)}</pre></div>" unless failure.exception.nil?
|
57
|
+
extra_failure_content
|
55
58
|
@output.puts " </div>"
|
56
|
-
@output.puts " </
|
59
|
+
@output.puts " </dd>"
|
57
60
|
STDOUT.flush
|
58
61
|
end
|
59
62
|
|
63
|
+
# Override this method if you wish to output extra HTML for a failed spec. For example, you
|
64
|
+
# could output links to images or other files produced during the specs. Example:
|
65
|
+
#
|
66
|
+
#
|
67
|
+
def extra_failure_content
|
68
|
+
end
|
69
|
+
|
60
70
|
def move_progress
|
61
|
-
percent_done = @spec_count == 0 ? 100.0 : (@
|
71
|
+
percent_done = @spec_count == 0 ? 100.0 : (@current_spec_number.to_f / @spec_count.to_f * 1000).to_i / 10.0
|
62
72
|
@output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
|
63
73
|
end
|
64
74
|
|
65
75
|
def escape(string)
|
66
76
|
string.gsub(/&/n, '&').gsub(/\"/n, '"').gsub(/>/n, '>').gsub(/</n, '<')
|
67
77
|
end
|
68
|
-
|
78
|
+
|
69
79
|
def dump_failure(counter, failure)
|
70
80
|
end
|
71
81
|
|
72
82
|
def dump_summary(duration, spec_count, failure_count)
|
83
|
+
if @dry_run
|
84
|
+
totals = "This was a dry-run"
|
85
|
+
else
|
86
|
+
totals = "#{spec_count} specification#{'s' unless spec_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}"
|
87
|
+
end
|
88
|
+
@output.puts "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{duration} seconds</strong>\";</script>"
|
89
|
+
@output.puts "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{totals}\";</script>"
|
90
|
+
@output.puts "</div>"
|
73
91
|
@output.puts "</body>"
|
74
92
|
@output.puts "</html>"
|
75
93
|
STDOUT.flush
|
76
94
|
end
|
77
|
-
|
78
|
-
|
79
|
-
GREEN_BACKGROUND = '#659D32'
|
80
|
-
|
81
|
-
HEADER = <<-HEADER
|
95
|
+
|
96
|
+
@@header = <<-HEADER
|
82
97
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
83
|
-
<!DOCTYPE html
|
98
|
+
<!DOCTYPE html
|
84
99
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
85
100
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
86
101
|
|
@@ -91,98 +106,103 @@ module Spec
|
|
91
106
|
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
92
107
|
<script type="text/javascript">
|
93
108
|
function moveProgressBar(percentDone) {
|
94
|
-
document.getElementById("
|
109
|
+
document.getElementById("header").style.width = percentDone +"%";
|
95
110
|
}
|
96
|
-
function
|
97
|
-
document.getElementById(
|
111
|
+
function makeRed(element_id) {
|
112
|
+
document.getElementById(element_id).style.background = '#C40D0D';
|
98
113
|
}
|
99
114
|
</script>
|
100
115
|
<style type="text/css">
|
101
116
|
body {
|
102
|
-
|
103
|
-
|
104
|
-
width: 85%;
|
117
|
+
margin: 0; padding: 0;
|
118
|
+
background: #fff;
|
105
119
|
}
|
106
120
|
|
107
|
-
#
|
108
|
-
background
|
109
|
-
border-bottom: 1px solid gray;
|
110
|
-
border-right: 1px solid gray;
|
121
|
+
#header {
|
122
|
+
background: #65C400; color: #fff;
|
111
123
|
}
|
112
124
|
|
113
|
-
|
114
|
-
|
115
|
-
|
125
|
+
h1 {
|
126
|
+
margin: 0 0 10px;
|
127
|
+
padding: 10px;
|
128
|
+
font: bold 18px "Lucida Grande", Helvetica, sans-serif;
|
116
129
|
}
|
117
130
|
|
118
|
-
|
119
|
-
padding:
|
120
|
-
|
121
|
-
|
131
|
+
#summary {
|
132
|
+
margin: 0; padding: 5px 10px;
|
133
|
+
font: bold 10px "Lucida Grande", Helvetica, sans-serif;
|
134
|
+
text-align: right;
|
135
|
+
position: absolute;
|
136
|
+
top: 0px;
|
137
|
+
right: 0px;
|
122
138
|
}
|
123
139
|
|
124
|
-
|
125
|
-
|
140
|
+
#summary p {
|
141
|
+
margin: 0 0 2px;
|
126
142
|
}
|
127
143
|
|
128
|
-
|
129
|
-
|
130
|
-
margin: 0;
|
131
|
-
border: 1px solid #fff;
|
144
|
+
#summary #totals {
|
145
|
+
font-size: 14px;
|
132
146
|
}
|
133
147
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
color: #589CCF;
|
148
|
+
.context {
|
149
|
+
margin: 0 10px 5px;
|
150
|
+
background: #fff;
|
138
151
|
}
|
139
152
|
|
140
|
-
|
141
|
-
|
142
|
-
|
153
|
+
dl {
|
154
|
+
margin: 0; padding: 0 0 5px;
|
155
|
+
font: normal 11px "Lucida Grande", Helvetica, sans-serif;
|
143
156
|
}
|
144
157
|
|
145
|
-
|
158
|
+
dt {
|
159
|
+
padding: 3px;
|
160
|
+
background: #65C400;
|
161
|
+
color: #fff;
|
146
162
|
font-weight: bold;
|
147
|
-
color: #EEB4B4;
|
148
163
|
}
|
149
164
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
padding: 1px 4px;
|
165
|
+
dd {
|
166
|
+
margin: 5px 0 5px 5px;
|
167
|
+
padding: 3px 3px 3px 18px;
|
154
168
|
}
|
155
169
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
color: #
|
160
|
-
padding: 2px 4px;
|
170
|
+
dd.spec.passed {
|
171
|
+
border-left: 5px solid #65C400;
|
172
|
+
border-bottom: 1px solid #65C400;
|
173
|
+
background: #DBFFB4; color: #3D7700;
|
161
174
|
}
|
162
175
|
|
163
|
-
|
164
|
-
|
165
|
-
|
176
|
+
dd.spec.failed {
|
177
|
+
border-left: 5px solid #C20000;
|
178
|
+
border-bottom: 1px solid #C20000;
|
179
|
+
color: #C20000; background: #FFFBD3;
|
166
180
|
}
|
167
181
|
|
168
182
|
div.backtrace {
|
169
|
-
color: #
|
183
|
+
color: #000;
|
184
|
+
font-size: 12px;
|
170
185
|
}
|
171
186
|
|
172
|
-
|
173
|
-
color: #
|
187
|
+
a {
|
188
|
+
color: #BE5C00;
|
174
189
|
}
|
175
|
-
|
176
190
|
</style>
|
177
191
|
</head>
|
178
192
|
<body>
|
179
193
|
|
180
|
-
<div id="
|
181
|
-
<
|
194
|
+
<div id="header">
|
195
|
+
<h1>RSpec Results</h1>
|
196
|
+
|
197
|
+
<div id="summary">
|
198
|
+
<p id="duration"> </p>
|
199
|
+
<p id="totals"> </p>
|
200
|
+
</div>
|
182
201
|
</div>
|
183
202
|
|
203
|
+
<div id="results">
|
184
204
|
HEADER
|
185
205
|
end
|
186
206
|
end
|
187
207
|
end
|
188
|
-
end
|
208
|
+
end
|