rspec 0.5.2 → 0.5.3
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 +10 -2
- data/Rakefile +22 -30
- data/doc/src/default.css +11 -10
- data/doc/src/documentation/api.page +15 -82
- data/doc/src/documentation/mocks.page +12 -55
- data/doc/src/meta.info +4 -1
- data/examples/airport_spec.rb +0 -1
- data/examples/empty_stack_spec.rb +1 -0
- data/examples/stack_spec.rb +1 -0
- data/examples/team_spec.rb +30 -0
- data/lib/spec/api.rb +1 -0
- data/lib/spec/api/duck_type.rb +16 -0
- data/lib/spec/api/expectations.rb +4 -4
- data/lib/spec/api/mock.rb +1 -0
- data/lib/spec/runner/backtrace_tweaker.rb +1 -2
- data/lib/spec/runner/context.rb +2 -3
- data/lib/spec/runner/context_runner.rb +2 -2
- data/lib/spec/runner/execution_context.rb +4 -0
- data/lib/spec/runner/option_parser.rb +3 -2
- data/lib/spec/runner/simple_text_reporter.rb +11 -25
- data/lib/spec/runner/specification.rb +1 -2
- data/lib/spec/version.rb +1 -1
- data/test/{rake → rcov}/rcov_testtask.rb +4 -4
- data/test/rcov/rcov_verify.rb +28 -0
- data/test/spec/api/duck_type_test.rb +19 -0
- data/test/spec/api/mock_arg_constraints_test.rb +20 -0
- data/test/spec/runner/backtrace_tweaker_test.rb +16 -8
- data/test/spec/runner/context_runner_test.rb +3 -3
- data/test/spec/runner/context_test.rb +2 -2
- data/test/spec/runner/execution_context_test.rb +7 -0
- data/test/spec/runner/option_parser_test.rb +12 -2
- data/test/spec/runner/simple_text_reporter_test.rb +18 -47
- data/test/spec/runner/specification_test.rb +5 -5
- data/test/spec/tool/command_line_test.rb +0 -1
- data/test/test_helper.rb +1 -0
- metadata +9 -7
- data/doc/src/download.page +0 -7
data/CHANGES
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
= RSpec Changelog
|
2
2
|
|
3
|
+
== Version 0.5.3
|
4
|
+
The "hurry up, CoR is in two days" release.
|
5
|
+
|
6
|
+
* Don't run rcov by default [aslak_hellesoy]
|
7
|
+
* Make separate task for running tests with RCov [aslak_hellesoy]
|
8
|
+
* Added Rake task to fail build if coverage drops below a certain threshold [aslak_hellesoy]
|
9
|
+
* Even more failure output cleanup (simplification) [dchelimsky]
|
10
|
+
* Added duck_type constraint for mocks [dchelimsky]
|
11
|
+
|
3
12
|
== Version 0.5.2
|
4
13
|
This release has minor improvements to the commandline and fixes some gem warnings
|
5
14
|
|
@@ -18,8 +27,7 @@ This release is the first release of RSpec with a new website. It will look bett
|
|
18
27
|
* Various improvements to failure reporting [dchelimsky]
|
19
28
|
|
20
29
|
== Version 0.5.0
|
21
|
-
|
22
|
-
This release introduces a new API and obsoletes previous versions.
|
30
|
+
This release introduces a new API and obsolesces previous versions.
|
23
31
|
|
24
32
|
* Moved source code to separate subfolders
|
25
33
|
* Added new DSL runner based on instance_exec
|
data/Rakefile
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
$:.unshift('lib')
|
2
2
|
require 'rubygems'
|
3
|
-
require 'meta_project'
|
4
3
|
require 'rake/gempackagetask'
|
5
4
|
require 'rake/contrib/rubyforgepublisher'
|
6
|
-
require 'rake/contrib/xforge'
|
7
5
|
require 'rake/clean'
|
8
6
|
require 'rake/testtask'
|
9
7
|
require 'rake/rdoctask'
|
10
8
|
require 'lib/spec/version'
|
11
9
|
require 'lib/spec/rake/spectask'
|
12
|
-
require 'test/
|
10
|
+
require 'test/rcov/rcov_testtask'
|
11
|
+
require 'test/rcov/rcov_verify'
|
13
12
|
|
14
13
|
PKG_NAME = "rspec"
|
15
14
|
# Versioning scheme: MAJOR.MINOR.PATCH
|
@@ -36,13 +35,16 @@ Spec::Rake::SpecTask.new do |t|
|
|
36
35
|
end
|
37
36
|
|
38
37
|
Rake::TestTask.new do |t|
|
39
|
-
t.libs << "test"
|
40
38
|
t.test_files = FileList['test/**/*_test.rb']
|
41
39
|
t.verbose = true
|
42
40
|
end
|
43
41
|
|
44
|
-
|
45
|
-
|
42
|
+
RCov::TestTask.new do |t|
|
43
|
+
t.test_files = FileList['test/**/*_test.rb']
|
44
|
+
t.verbose = true
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'Generate HTML documentation'
|
46
48
|
task :doc do
|
47
49
|
sh %{pushd doc; webgen; popd }
|
48
50
|
end
|
@@ -52,19 +54,11 @@ rd = Rake::RDocTask.new("rdoc") do |rdoc|
|
|
52
54
|
rdoc.rdoc_dir = 'doc/output/rdoc'
|
53
55
|
rdoc.title = "RSpec"
|
54
56
|
rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README'
|
55
|
-
rdoc.rdoc_files.include('CHANGES')
|
57
|
+
rdoc.rdoc_files.include('README', 'CHANGES')
|
56
58
|
rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc')
|
57
|
-
rdoc.rdoc_files.exclude('doc/**/*_attrs.rdoc')
|
58
59
|
end
|
59
60
|
|
60
|
-
# ====================================================================
|
61
|
-
# Create a task that will package the Rake software into distributable
|
62
|
-
# tar, zip and gem files.
|
63
|
-
|
64
61
|
spec = Gem::Specification.new do |s|
|
65
|
-
|
66
|
-
#### Basic information.
|
67
|
-
|
68
62
|
s.name = PKG_NAME
|
69
63
|
s.version = PKG_VERSION
|
70
64
|
s.summary = "Behaviour Specification Framework for Ruby"
|
@@ -78,8 +72,6 @@ spec = Gem::Specification.new do |s|
|
|
78
72
|
s.files = PKG_FILES.to_a
|
79
73
|
s.require_path = 'lib'
|
80
74
|
|
81
|
-
#### Documentation and testing.
|
82
|
-
|
83
75
|
s.has_rdoc = true
|
84
76
|
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
|
85
77
|
s.rdoc_options <<
|
@@ -87,18 +79,12 @@ spec = Gem::Specification.new do |s|
|
|
87
79
|
'--main' << 'README' <<
|
88
80
|
'--line-numbers'
|
89
81
|
|
90
|
-
s.test_files = Dir.glob('test
|
91
|
-
|
92
|
-
#### Make executable
|
82
|
+
s.test_files = Dir.glob('test/*_test.rb')
|
93
83
|
s.require_path = 'lib'
|
94
84
|
s.autorequire = 'spec'
|
95
|
-
|
96
85
|
s.bindir = "bin"
|
97
86
|
s.executables = ["spec", "test2rspec"]
|
98
87
|
s.default_executable = "spec"
|
99
|
-
|
100
|
-
#### Author and project details.
|
101
|
-
|
102
88
|
s.author = "Steven Baker"
|
103
89
|
s.email = "srbaker@pobox.com"
|
104
90
|
s.homepage = "http://rspec.rubyforge.org"
|
@@ -110,8 +96,6 @@ Rake::GemPackageTask.new(spec) do |pkg|
|
|
110
96
|
pkg.need_tar = true
|
111
97
|
end
|
112
98
|
|
113
|
-
# Support Tasks ------------------------------------------------------
|
114
|
-
|
115
99
|
def egrep(pattern)
|
116
100
|
Dir['**/*.rb'].each do |fn|
|
117
101
|
count = 0
|
@@ -139,9 +123,14 @@ end
|
|
139
123
|
task :release => [:clobber, :verify_user, :verify_password, :test, :upload_releases, :publish_website, :publish_news]
|
140
124
|
|
141
125
|
desc "Build the website with rdoc and rcov, but do not publish it"
|
142
|
-
task :website => [:clobber, :
|
126
|
+
task :website => [:clobber, :copy_rcov_report, :doc, :rdoc]
|
127
|
+
|
128
|
+
RCov::VerifyTask.new do |t|
|
129
|
+
t.threshold = 99.1 # Don't make it lower unless you have a damn good reason.
|
130
|
+
t.index_html = 'coverage/index.html'
|
131
|
+
end
|
143
132
|
|
144
|
-
task :
|
133
|
+
task :copy_rcov_report => [:test_with_rcov, :rcov_verify] do
|
145
134
|
rm_rf 'doc/output/coverage'
|
146
135
|
mkdir 'doc/output' unless File.exists? 'doc/output'
|
147
136
|
mv 'coverage', 'doc/output'
|
@@ -166,9 +155,10 @@ task :publish_website => [:verify_user, :website] do
|
|
166
155
|
publisher.upload
|
167
156
|
end
|
168
157
|
|
169
|
-
desc "Release gem to RubyForge. You must make sure lib/version.rb is aligned with the CHANGELOG file"
|
158
|
+
desc "Release gem+tgz+zip to RubyForge. You must make sure lib/version.rb is aligned with the CHANGELOG file"
|
170
159
|
task :upload_releases => [:verify_user, :verify_password, :package] do
|
171
|
-
|
160
|
+
require 'meta_project'
|
161
|
+
require 'rake/contrib/xforge'
|
172
162
|
release_files = FileList[
|
173
163
|
"pkg/#{PKG_FILE_NAME}.gem",
|
174
164
|
"pkg/#{PKG_FILE_NAME}.tgz",
|
@@ -186,6 +176,8 @@ end
|
|
186
176
|
|
187
177
|
desc "Publish news on RubyForge"
|
188
178
|
task :publish_news => [:verify_user, :verify_password] do
|
179
|
+
require 'meta_project'
|
180
|
+
require 'rake/contrib/xforge'
|
189
181
|
Rake::XForge::NewsPublisher.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |news|
|
190
182
|
# Never hardcode user name and password in the Rakefile!
|
191
183
|
news.user_name = ENV['RUBYFORGE_USER']
|
data/doc/src/default.css
CHANGED
@@ -41,7 +41,6 @@ acronym {
|
|
41
41
|
#header h1 strong {
|
42
42
|
color:#c00;
|
43
43
|
}
|
44
|
-
|
45
44
|
#header h2 {
|
46
45
|
margin:140px 0 0 0;
|
47
46
|
font-size:1em;
|
@@ -65,7 +64,6 @@ acronym {
|
|
65
64
|
list-style:none;
|
66
65
|
display:inline;
|
67
66
|
}
|
68
|
-
|
69
67
|
#navigation li a {
|
70
68
|
padding:5px 5px 2px 5px;
|
71
69
|
margin:0 1px 0 1px;
|
@@ -74,7 +72,6 @@ acronym {
|
|
74
72
|
font-weight:bold;
|
75
73
|
border-bottom:1px solid #c00;
|
76
74
|
}
|
77
|
-
|
78
75
|
#navigation li a:hover {
|
79
76
|
color:#C00;
|
80
77
|
border-bottom:1px solid #ddd;
|
@@ -86,8 +83,7 @@ acronym {
|
|
86
83
|
#content p {
|
87
84
|
padding:2px 20px;
|
88
85
|
text-align:justify;
|
89
|
-
|
90
|
-
line-height:1.8em;
|
86
|
+
line-height:1.4em;
|
91
87
|
}
|
92
88
|
#content h1 {
|
93
89
|
display:block;
|
@@ -102,7 +98,7 @@ acronym {
|
|
102
98
|
}
|
103
99
|
#content h2 {
|
104
100
|
display:block;
|
105
|
-
margin:20px 0 0
|
101
|
+
margin:20px 0 0 0px;
|
106
102
|
padding:0;
|
107
103
|
font-family:"Trebuchet MS",arial,sans-serif;
|
108
104
|
font-size:1.1em;
|
@@ -140,12 +136,17 @@ acronym {
|
|
140
136
|
padding:0;
|
141
137
|
text-indent:0;
|
142
138
|
}
|
139
|
+
#content code {
|
140
|
+
font-family:"courier new";
|
141
|
+
color:#444;
|
142
|
+
font-weight:bold;
|
143
|
+
}
|
143
144
|
#content pre {
|
144
|
-
|
145
|
-
|
145
|
+
padding:10px;
|
146
|
+
margin:0 18px 0 18px;
|
146
147
|
color:#444;
|
147
|
-
border:1px solid #
|
148
|
-
background-color:#
|
148
|
+
border:1px solid #444;
|
149
|
+
background-color:#ddd;
|
149
150
|
}
|
150
151
|
#content ul {
|
151
152
|
margin-left:70px;
|
@@ -5,200 +5,147 @@ ordering: 5
|
|
5
5
|
---
|
6
6
|
h2. Core API
|
7
7
|
|
8
|
-
When RSpec executes specifications, it defines a method
|
9
|
-
This *should* method is your entry to the magic of RSpec.
|
8
|
+
When RSpec executes specifications, it defines a method <code>should</code> on every object in the system. This <code>should</code> method is your entry to the magic of RSpec.
|
10
9
|
|
11
|
-
Almost all expectation forms have a corresponding negated form. It is listed
|
12
|
-
when it is supported and, in general, is met when ever the non negated form would be
|
13
|
-
violated.
|
10
|
+
Almost all expectation forms have a corresponding negated form. It is listed when it is supported and, in general, is met when ever the non-negated form would be violated.
|
14
11
|
|
15
12
|
h3. General
|
16
13
|
|
17
14
|
h4. Arbitrary Block
|
18
15
|
|
19
16
|
<pre>
|
20
|
-
<code>
|
21
17
|
target.should.satisfy {|arg| ...}
|
22
18
|
target.should.not.satisfy {|arg| ...}
|
23
|
-
</code>
|
24
19
|
</pre>
|
25
20
|
|
26
|
-
The supplied block is evaluated, passing <code>target</code> as the sole argument. If the
|
27
|
-
block evaluates to <code>false</code> in the case of <code>should.satisfy</code>, or <code>true</code> in the case of
|
28
|
-
<code>should.not.satisfy</code>, <code>ExpectationNotMetError</code> is raised.
|
21
|
+
The supplied block is evaluated, passing <code>target</code> as the sole argument. If the block evaluates to <code>false</code> in the case of <code>should.satisfy</code>, or <code>true</code> in the case of <code>should.not.satisfy</code>, <code>ExpectationNotMetError</code> is raised.
|
29
22
|
|
30
23
|
<pre>
|
31
|
-
<code>
|
32
24
|
target.should.satisfy {|arg| arg > 0}
|
33
|
-
</code>
|
34
25
|
</pre>
|
35
26
|
|
36
27
|
h4. Equality
|
37
28
|
|
38
29
|
<pre>
|
39
|
-
<code>
|
40
30
|
target.should.equal <value>
|
41
31
|
target.should.not.equal <value>
|
42
|
-
</code>
|
43
32
|
</pre>
|
44
33
|
|
45
|
-
The target object is compared to <code>value</code> using ==. If the result is <code>false</code> (or
|
46
|
-
<code>true</code> for the negated form) <code>ExpectationNotMetError</code> is raised.
|
34
|
+
The target object is compared to <code>value</code> using ==. If the result is <code>false</code> (or <code>true</code> for the negated form) <code>ExpectationNotMetError</code> is raised.
|
47
35
|
|
48
36
|
h4. Floating Point Comparison
|
49
37
|
|
50
38
|
<pre>
|
51
|
-
<code>
|
52
39
|
target.should.be.close <value>, <tolerance>
|
53
40
|
target.should.not.be.close <value>, <tolerance>
|
54
|
-
</code>
|
55
41
|
</pre>
|
56
42
|
|
57
|
-
The target object is compared to <code>value</code>. In the former case, if they differ
|
58
|
-
by more that <code>tolerance</code> <code>ExpectationNotMetError</code> is raised. In the latter case,
|
59
|
-
it is raised if they differ by less than <code>tolerance</code>.
|
43
|
+
The target object is compared to <code>value</code>. In the former case, if they differ by more that <code>tolerance</code> <code>ExpectationNotMetError</code> is raised. In the latter case, it is raised if they differ by less than <code>tolerance</code>.
|
60
44
|
|
61
45
|
<pre>
|
62
|
-
<code>
|
63
46
|
target.should.be.close 27.35, 0.05
|
64
|
-
</code>
|
65
47
|
</pre>
|
66
48
|
|
67
49
|
h4. Identity
|
68
50
|
|
69
51
|
<pre>
|
70
|
-
<code>
|
71
52
|
target.should.be <value>
|
72
53
|
target.should.not.be <value>
|
73
|
-
</code>
|
74
54
|
</pre>
|
75
55
|
|
76
|
-
The target object is compared to <code>value</code> using <code>equal?</code>. If the result is <code>false</code>
|
77
|
-
(or <code>true</code> for the negated form) <code>ExpectationNotMetError</code> is raised.
|
56
|
+
The target object is compared to <code>value</code> using <code>equal?</code>. If the result is <code>false</code> (or <code>true</code> for the negated form) <code>ExpectationNotMetError</code> is raised.
|
78
57
|
|
79
58
|
h4. Arbitrary Predicate
|
80
59
|
|
81
60
|
|
82
61
|
<pre>
|
83
|
-
<code>
|
84
62
|
target.should.predicate [optional args]
|
85
63
|
target.should.be.predicate [optional args]
|
86
64
|
target.should.not.predicate [optional args]
|
87
65
|
target.should.not.be.predicate [optional args]
|
88
|
-
</code>
|
89
66
|
</pre>
|
90
67
|
|
91
|
-
The message <code>predicate?</code> is sent to <code>target</code> with any supplied arguments. If the
|
92
|
-
result is <code>false</code> (or <code>true</code> for the negated form) <code>ExpectationNotMetError</code> is
|
93
|
-
raised.
|
68
|
+
The message <code>predicate?</code> is sent to <code>target</code> with any supplied arguments. If the result is <code>false</code> (or <code>true</code> for the negated form) <code>ExpectationNotMetError</code> is raised.
|
94
69
|
|
95
70
|
<pre>
|
96
|
-
<code>
|
97
71
|
container.should.include 'a' => container.include? 'a'
|
98
72
|
container.should.be.empty => container.empty?
|
99
|
-
</code>
|
100
73
|
</pre>
|
101
74
|
|
102
75
|
h4. Pattern Matching
|
103
76
|
|
104
77
|
<pre>
|
105
|
-
<code>
|
106
78
|
target.should.match <regex>
|
107
79
|
target.should.not.match <regex>
|
108
|
-
</code>
|
109
80
|
</pre>
|
110
81
|
|
111
|
-
The <code>target</code> is matched against <code>regex</code>. An <code>ExpectationNotMetError</code> is raised if
|
112
|
-
the match fails or succeeds, respectively.
|
82
|
+
The <code>target</code> is matched against <code>regex</code>. An <code>ExpectationNotMetError</code> is raised if the match fails or succeeds, respectively.
|
113
83
|
|
114
84
|
h3. Class/Type
|
115
85
|
|
116
86
|
h4. Direct Instance
|
117
87
|
|
118
88
|
<pre>
|
119
|
-
<code>
|
120
89
|
target.should.be.an.instance.of <class>
|
121
90
|
target.should.not.be.an.instance.of <class>
|
122
|
-
</code>
|
123
91
|
</pre>
|
124
92
|
|
125
|
-
An <code>ExpectationNotMetError</code> is raised if <code>target</code> is not or is, respectively, an
|
126
|
-
direct instance of <code>class</code>. As expected this correlates to <code>target.instance_of?
|
127
|
-
class</code>.
|
93
|
+
An <code>ExpectationNotMetError</code> is raised if <code>target</code> is not or is, respectively, an direct instance of <code>class</code>. As expected this correlates to <code>target.instance_of? class</code>.
|
128
94
|
|
129
95
|
h4. Ancestor Class
|
130
96
|
|
131
97
|
<pre>
|
132
|
-
<code>
|
133
98
|
target.should.be.a.kind.of <class>
|
134
99
|
target.should.not.be.a.kind.of <class>
|
135
|
-
</code>
|
136
100
|
</pre>
|
137
101
|
|
138
|
-
As above, but uses <code>target.kind_of? class</code>: checking whether <code>class</code> is the
|
139
|
-
direct class of <code>target</code>, or an ancestor of <code>target</code>'s class.
|
102
|
+
As above, but uses <code>target.kind_of? class</code>: checking whether <code>class</code> is the direct class of <code>target</code>, or an ancestor of <code>target</code>'s class.
|
140
103
|
|
141
104
|
h4. Type
|
142
105
|
|
143
106
|
<pre>
|
144
|
-
<code>
|
145
107
|
target.should.respond.to <symbol>
|
146
108
|
target.should.not.respond.to <symbol>
|
147
|
-
</code>
|
148
109
|
</pre>
|
149
110
|
|
150
|
-
Uses <code>target.respond_to? symbol?</code> to check whether <code>symbol</code> is the name of a
|
151
|
-
message that <code>target</code> understands.
|
111
|
+
Uses <code>target.respond_to? symbol?</code> to check whether <code>symbol</code> is the name of a message that <code>target</code> understands.
|
152
112
|
|
153
113
|
h3. Procs
|
154
114
|
|
155
115
|
h4. Raising
|
156
116
|
|
157
117
|
<pre>
|
158
|
-
<code>
|
159
118
|
proc.should.raise <exception>
|
160
119
|
proc.should.not.raise <exception>
|
161
|
-
</code>
|
162
120
|
</pre>
|
163
121
|
|
164
|
-
Checks that <code>proc</code> does or doesn't cause the named exception to be raised.
|
165
|
-
Typically the <code>proc</code> is created in place using <code>lambda</code>. For example:
|
122
|
+
Checks that <code>proc</code> does or doesn't cause the named exception to be raised. Typically the <code>proc</code> is created in place using <code>lambda</code>. For example:
|
166
123
|
|
167
124
|
<pre>
|
168
|
-
<code>
|
169
125
|
lambda { 3 / 0 }.should.raise ZeroDivisionError
|
170
|
-
</code>
|
171
126
|
</pre>
|
172
127
|
|
173
128
|
There is a more general form as well.
|
174
129
|
|
175
130
|
<pre>
|
176
|
-
<code>
|
177
131
|
proc.should.raise
|
178
132
|
proc.should.not.raise
|
179
|
-
</code>
|
180
133
|
</pre>
|
181
134
|
|
182
|
-
These forms don't worry about what exception is raised (or not). All they are
|
183
|
-
concern with is that some except was raised, or that no exception was raised.
|
135
|
+
These forms don't worry about what exception is raised (or not). All they are concern with is that some except was raised, or that no exception was raised.
|
184
136
|
|
185
137
|
h4. Throwing
|
186
138
|
|
187
139
|
<pre>
|
188
|
-
<code>
|
189
140
|
proc.should.throw <symbol>
|
190
141
|
proc.should.not.throw <symbol>
|
191
|
-
</code>
|
192
142
|
</pre>
|
193
143
|
|
194
|
-
Similar to the above, but checks that <code>symbol</code> is thrown from within <code>proc</code>, or
|
195
|
-
that it is not. The latter is actually one of two cases: some other symbol is
|
144
|
+
Similar to the above, but checks that <code>symbol</code> is thrown from within <code>proc</code>, or that it is not. The latter is actually one of two cases: some other symbol is
|
196
145
|
thrown, or no symbol is thrown.
|
197
146
|
|
198
147
|
<pre>
|
199
|
-
<code>
|
200
148
|
proc.should.not.throw
|
201
|
-
</code>
|
202
149
|
</pre>
|
203
150
|
|
204
151
|
This form is more specific. It checks that no symbol is thrown from within <code>proc</code>.
|
@@ -208,25 +155,15 @@ h3. Collections
|
|
208
155
|
h4. Containment
|
209
156
|
|
210
157
|
<pre>
|
211
|
-
<code>
|
212
158
|
target.should.include <object>
|
213
|
-
</code>
|
214
159
|
</pre>
|
215
160
|
|
216
|
-
This is simply a specific case of the arbitrary predicate form. It uses
|
217
|
-
<code>target.include? object</code> and raises an <code>ExpectationNotMetError</code> if that returns
|
218
|
-
false. The remaining collection forms are a little more involved. They rely on
|
219
|
-
two things: <code>target</code> responds to the message <code>things</code> by returning an object
|
220
|
-
that responds to either <code>length</code> or <code>size</code>, which return a number that is a
|
221
|
-
measure of size. Currently <code>length</code> is used if is appropriate, otherwise <code>size</code> is
|
222
|
-
attempted.
|
161
|
+
This is simply a specific case of the arbitrary predicate form. It uses <code>target.include? object</code> and raises an <code>ExpectationNotMetError</code> if that returns false. The remaining collection forms are a little more involved. They rely on two things: <code>target</code> responds to the message <code>things</code> by returning an object that responds to either <code>length</code> or <code>size</code>, which return a number that is a measure of size. Currently <code>length</code> is used if is appropriate, otherwise <code>size</code> is attempted.
|
223
162
|
|
224
163
|
h4. Exact Size
|
225
164
|
|
226
165
|
<pre>
|
227
|
-
<code>
|
228
166
|
target.should.have(<number>).<things>
|
229
|
-
</code>
|
230
167
|
</pre>
|
231
168
|
|
232
169
|
The <code>things</code> of <code>target</code> has a length/size of exactly <code>number</code>.
|
@@ -234,9 +171,7 @@ The <code>things</code> of <code>target</code> has a length/size of exactly <cod
|
|
234
171
|
h4. Lower Bound
|
235
172
|
|
236
173
|
<pre>
|
237
|
-
<code>
|
238
174
|
target.should.have.at.least(<number>).<things>
|
239
|
-
</code>
|
240
175
|
</pre>
|
241
176
|
|
242
177
|
The <code>things</code> of <code>target</code> has a length/size of no less than <code>number</code>.
|
@@ -244,9 +179,7 @@ The <code>things</code> of <code>target</code> has a length/size of no less than
|
|
244
179
|
h4. Upper Bound
|
245
180
|
|
246
181
|
<pre>
|
247
|
-
<code>
|
248
182
|
target.should.have.at.most(<number>).<things>
|
249
|
-
</code>
|
250
183
|
</pre>
|
251
184
|
|
252
185
|
The <code>things</code> of <code>target</code> has a length/size of no more than <code>number</code>.
|