handshake 0.3.0 → 0.3.1
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/{README.txt → README.rdoc} +32 -11
- data/Rakefile +9 -49
- data/lib/handshake.rb +24 -45
- data/lib/handshake/block_contract.rb +1 -1
- data/lib/handshake/clause_methods.rb +1 -1
- data/lib/handshake/version.rb +1 -1
- data/test/handshake_test.rb +598 -0
- metadata +67 -42
- data/test/tc_disable_handshake.rb +0 -29
- data/test/tc_handshake.rb +0 -528
metadata
CHANGED
@@ -1,58 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.0
|
3
|
-
specification_version: 1
|
4
2
|
name: handshake
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
-
|
11
|
-
|
12
|
-
homepage: http://handshake.rubyforge.org
|
13
|
-
rubyforge_project: handshake
|
14
|
-
description: Handshake is a simple design-by-contract system for Ruby.
|
15
|
-
autorequire:
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 3
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
25
10
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
11
|
authors:
|
30
12
|
- Brian Guthrie
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-25 00:00:00 +05:30
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: shoulda
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
32
|
+
description: " Handshake is an informal AOP and design-by-contract system written in pure Ruby.\n It's intended to allow Ruby developers to apply simple, clear constraints\n to their methods and classes.\n"
|
33
|
+
email: btguthrie@gmail.com
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files: []
|
39
|
+
|
31
40
|
files:
|
32
|
-
- Manifest.txt
|
33
|
-
- README.txt
|
34
|
-
- MIT-LICENSE
|
35
|
-
- Rakefile
|
36
|
-
- lib/handshake.rb
|
37
41
|
- lib/handshake/block_contract.rb
|
38
42
|
- lib/handshake/clause_methods.rb
|
39
43
|
- lib/handshake/inheritable_attributes.rb
|
40
44
|
- lib/handshake/proxy_self.rb
|
41
45
|
- lib/handshake/version.rb
|
42
|
-
-
|
43
|
-
-
|
44
|
-
|
45
|
-
-
|
46
|
-
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
executables: []
|
46
|
+
- lib/handshake.rb
|
47
|
+
- Manifest.txt
|
48
|
+
- MIT-LICENSE
|
49
|
+
- Rakefile
|
50
|
+
- README.rdoc
|
51
|
+
- test/handshake_test.rb
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: http://github.com/bguthrie/handshake
|
54
|
+
licenses: []
|
52
55
|
|
53
|
-
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
54
58
|
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
55
75
|
requirements: []
|
56
76
|
|
57
|
-
|
58
|
-
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.3.6
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: An informal design-by-contract framework for Ruby.
|
82
|
+
test_files:
|
83
|
+
- test/handshake_test.rb
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'handshake'
|
3
|
-
|
4
|
-
# The purpose of this test case is to ensure that when the $DEBUG flag is not
|
5
|
-
# set contracts may still be declared without raising a syntax error, although
|
6
|
-
# they are not enforced.
|
7
|
-
class TestDisableHandshake < Test::Unit::TestCase
|
8
|
-
|
9
|
-
class ComprehensiveContracts
|
10
|
-
include Handshake
|
11
|
-
|
12
|
-
invariant("foo must always be true") { @foo == true }
|
13
|
-
|
14
|
-
contract /foo/ => /bar/
|
15
|
-
before do |arg|
|
16
|
-
assert_equal "foo", arg
|
17
|
-
end
|
18
|
-
after do |arg, returned|
|
19
|
-
assert_equal "bar", returned
|
20
|
-
end
|
21
|
-
def call(str); "baz"; end
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_contracts_not_enforced
|
25
|
-
assert_nothing_raised { ComprehensiveContracts.new }
|
26
|
-
assert_nothing_raised { ComprehensiveContracts.new.call 3 }
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
data/test/tc_handshake.rb
DELETED
@@ -1,528 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'handshake'
|
3
|
-
|
4
|
-
$DEBUG = true
|
5
|
-
|
6
|
-
class TestContract < Test::Unit::TestCase
|
7
|
-
|
8
|
-
class InvariantDeclarations
|
9
|
-
include Handshake
|
10
|
-
invariant { true }
|
11
|
-
end
|
12
|
-
|
13
|
-
class ExtendsInvariantDeclarations < InvariantDeclarations
|
14
|
-
invariant { true }
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_invariant_declarations
|
18
|
-
assert_equal 1, InvariantDeclarations.invariants.length
|
19
|
-
assert_equal 2, ExtendsInvariantDeclarations.invariants.length
|
20
|
-
end
|
21
|
-
|
22
|
-
class NonFunctionalArray < Array
|
23
|
-
include Handshake
|
24
|
-
invariant { false }
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_basic_invariant
|
28
|
-
assert_violation { NonFunctionalArray.new }
|
29
|
-
end
|
30
|
-
|
31
|
-
class NonEmptyArray < Array
|
32
|
-
include Handshake
|
33
|
-
invariant { not empty? }
|
34
|
-
end
|
35
|
-
class ExtendsNonEmptyArray < NonEmptyArray; end
|
36
|
-
|
37
|
-
class PositiveBalance
|
38
|
-
include Handshake
|
39
|
-
invariant { @balance > 0 }
|
40
|
-
attr_accessor :balance
|
41
|
-
def initialize(balance); @balance = balance; end
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_invariants
|
45
|
-
assert_violation { NonEmptyArray.new }
|
46
|
-
assert_passes { NonEmptyArray.new [1] }
|
47
|
-
assert_violation { ExtendsNonEmptyArray.new }
|
48
|
-
assert_passes { ExtendsNonEmptyArray.new [1] }
|
49
|
-
|
50
|
-
assert_violation { NonEmptyArray.new([1]).pop }
|
51
|
-
|
52
|
-
assert_violation { PositiveBalance.new -10 }
|
53
|
-
assert_violation { PositiveBalance.new 0 }
|
54
|
-
assert_passes { PositiveBalance.new 10 }
|
55
|
-
assert_violation {
|
56
|
-
pb = PositiveBalance.new(10); pb.balance = -10
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
class MethodDeclarations
|
61
|
-
include Handshake
|
62
|
-
contract :accepts_str, String => anything
|
63
|
-
contract :accepts_int, Integer => anything
|
64
|
-
def accepts_str(str); str; end
|
65
|
-
def accepts_int(int); int; end
|
66
|
-
end
|
67
|
-
class ExtendsMethodDeclarations < MethodDeclarations; end
|
68
|
-
|
69
|
-
def test_method_declarations
|
70
|
-
assert MethodDeclarations.method_contracts.has_key?(:accepts_str)
|
71
|
-
assert MethodDeclarations.method_contracts.has_key?(:accepts_int)
|
72
|
-
assert ExtendsMethodDeclarations.method_contracts.has_key?(:accepts_str)
|
73
|
-
assert ExtendsMethodDeclarations.method_contracts.has_key?(:accepts_int)
|
74
|
-
end
|
75
|
-
|
76
|
-
class AcceptsString
|
77
|
-
include Handshake
|
78
|
-
contract :initialize, String => anything
|
79
|
-
def initialize(str); @str = str; end
|
80
|
-
contract String => anything
|
81
|
-
def str=(str); @str = str; end
|
82
|
-
end
|
83
|
-
class ExtendsAcceptsString < AcceptsString; end
|
84
|
-
class AcceptsIntegerInstead < AcceptsString
|
85
|
-
contract :initialize, Integer => anything
|
86
|
-
end
|
87
|
-
class AcceptsSymbolInstead < AcceptsString
|
88
|
-
contract :initialize, Symbol => anything
|
89
|
-
end
|
90
|
-
|
91
|
-
def test_method_accepts
|
92
|
-
assert_violation { AcceptsString.new 3 }
|
93
|
-
assert_violation { AcceptsString.new :foo }
|
94
|
-
assert_passes { AcceptsString.new "string" }
|
95
|
-
assert_violation { AcceptsString.new("foo").str = 3 }
|
96
|
-
assert_violation { ExtendsAcceptsString.new 3 }
|
97
|
-
assert_violation { ExtendsAcceptsString.new :foo }
|
98
|
-
assert_passes { ExtendsAcceptsString.new "string" }
|
99
|
-
assert_violation { ExtendsAcceptsString.new("foo").str = 3 }
|
100
|
-
assert_violation { AcceptsIntegerInstead.new("foo") }
|
101
|
-
assert_passes { AcceptsIntegerInstead.new 3 }
|
102
|
-
assert_violation { AcceptsSymbolInstead.new "foo" }
|
103
|
-
assert_violation { AcceptsSymbolInstead.new 3 }
|
104
|
-
assert_passes { AcceptsSymbolInstead.new :foo }
|
105
|
-
end
|
106
|
-
|
107
|
-
class ReturnsString
|
108
|
-
include Handshake
|
109
|
-
contract String => anything
|
110
|
-
def call(val); val; end
|
111
|
-
end
|
112
|
-
class ExtendsReturnsString < ReturnsString; end
|
113
|
-
|
114
|
-
def test_method_returns
|
115
|
-
assert_violation { ReturnsString.new.call(1) }
|
116
|
-
assert_violation { ReturnsString.new.call(true) }
|
117
|
-
assert_passes { ReturnsString.new.call("foo") }
|
118
|
-
assert_violation { ExtendsReturnsString.new.call(1) }
|
119
|
-
assert_violation { ExtendsReturnsString.new.call(true) }
|
120
|
-
assert_passes { ExtendsReturnsString.new.call("foo") }
|
121
|
-
end
|
122
|
-
|
123
|
-
class ReturnsMultiple
|
124
|
-
include Handshake
|
125
|
-
contract [ String, Integer ] => anything
|
126
|
-
def call(arg1, arg2); return arg1, arg2; end
|
127
|
-
end
|
128
|
-
|
129
|
-
def test_method_returns_multiple
|
130
|
-
assert_violation { ReturnsMultiple.new.call("foo", "foo") }
|
131
|
-
assert_violation { ReturnsMultiple.new.call(3, 3) }
|
132
|
-
assert_passes { ReturnsMultiple.new.call("foo", 3) }
|
133
|
-
end
|
134
|
-
|
135
|
-
class AcceptsVarargs
|
136
|
-
include Handshake
|
137
|
-
contract [[ String ]] => anything
|
138
|
-
def initialize(*strs); @strs = strs; end
|
139
|
-
end
|
140
|
-
|
141
|
-
def test_method_accepts_varargs
|
142
|
-
assert_passes { AcceptsVarargs.new }
|
143
|
-
assert_violation { AcceptsVarargs.new(1, 2, 3) }
|
144
|
-
assert_violation { AcceptsVarargs.new("foo", 1, 2) }
|
145
|
-
assert_violation { AcceptsVarargs.new(:foo, "foo") }
|
146
|
-
assert_passes { AcceptsVarargs.new("foo") }
|
147
|
-
assert_passes { AcceptsVarargs.new("foo1", "foo2") }
|
148
|
-
end
|
149
|
-
|
150
|
-
class AcceptsBlock
|
151
|
-
include Handshake
|
152
|
-
contract Block => anything
|
153
|
-
def call1; end
|
154
|
-
contract Block => anything
|
155
|
-
def call2(&block); end
|
156
|
-
end
|
157
|
-
|
158
|
-
def test_method_accepts_block
|
159
|
-
assert_violation { AcceptsBlock.new.call1 }
|
160
|
-
assert_violation { AcceptsBlock.new.call2 }
|
161
|
-
assert_passes { AcceptsBlock.new.call1 { true } }
|
162
|
-
assert_passes { AcceptsBlock.new.call2 { true } }
|
163
|
-
assert_passes { AcceptsBlock.new.call1 { "foo" } }
|
164
|
-
assert_violation { AcceptsBlock.new.call1("foo") }
|
165
|
-
assert_violation { AcceptsBlock.new.call2("foo") }
|
166
|
-
end
|
167
|
-
|
168
|
-
class AcceptsWriter
|
169
|
-
include Handshake
|
170
|
-
contract String => anything
|
171
|
-
def val=(str); @str = str; end
|
172
|
-
end
|
173
|
-
|
174
|
-
def test_writer_method_accepts_str
|
175
|
-
assert_violation { AcceptsWriter.new.val = 3 }
|
176
|
-
assert_violation { AcceptsWriter.new.val = :foo }
|
177
|
-
assert_passes { AcceptsWriter.new.val = "foo" }
|
178
|
-
end
|
179
|
-
|
180
|
-
# EXCELSIOR!
|
181
|
-
class AcceptsMixed
|
182
|
-
include Handshake
|
183
|
-
contract [ String, String, [ Integer ], Block ] => String
|
184
|
-
def call(str1, str2, *ints, &block); "foo"; end
|
185
|
-
end
|
186
|
-
|
187
|
-
def test_method_mixed
|
188
|
-
assert_violation { AcceptsMixed.new.call }
|
189
|
-
assert_violation { AcceptsMixed.new.call 3 }
|
190
|
-
assert_violation { AcceptsMixed.new.call "foo" }
|
191
|
-
assert_violation { AcceptsMixed.new.call "foo", 3 }
|
192
|
-
assert_violation { AcceptsMixed.new.call "foo", "bar" }
|
193
|
-
assert_passes { AcceptsMixed.new.call("foo", "bar") { true } }
|
194
|
-
assert_passes { AcceptsMixed.new.call("foo", "bar", 3) { true } }
|
195
|
-
assert_passes { AcceptsMixed.new.call("foo", "bar", 3, 4, 5) { true } }
|
196
|
-
end
|
197
|
-
|
198
|
-
class AcceptsSimpleAssertion
|
199
|
-
include Handshake
|
200
|
-
equals_foo = clause {|o| o == "foo"}
|
201
|
-
contract [ equals_foo ] => anything
|
202
|
-
def call(foo)
|
203
|
-
return foo
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
def test_method_simple_assertion
|
208
|
-
assert_violation { AcceptsSimpleAssertion.new.call }
|
209
|
-
assert_violation { AcceptsSimpleAssertion.new.call 3 }
|
210
|
-
assert_violation { AcceptsSimpleAssertion.new.call "bar", "bar" }
|
211
|
-
assert_passes { AcceptsSimpleAssertion.new.call "foo" }
|
212
|
-
end
|
213
|
-
|
214
|
-
class AcceptsAll
|
215
|
-
include Handshake
|
216
|
-
equals_five = clause {|o| o == 5}
|
217
|
-
contract all?(Integer, equals_five) => anything
|
218
|
-
def initialize(n); end
|
219
|
-
end
|
220
|
-
|
221
|
-
def test_accepts_all_of
|
222
|
-
assert_violation { AcceptsAll.new "foo" }
|
223
|
-
assert_violation { AcceptsAll.new 3 }
|
224
|
-
assert_violation { AcceptsAll.new 5.0 }
|
225
|
-
assert_passes { AcceptsAll.new 5 }
|
226
|
-
end
|
227
|
-
|
228
|
-
class AcceptsAny
|
229
|
-
include Handshake
|
230
|
-
equals_five = clause {|o| o == 5}
|
231
|
-
equals_three = clause {|o| o == 3}
|
232
|
-
contract any?(equals_five, equals_three) => anything
|
233
|
-
def three_or_five(n); end
|
234
|
-
contract any?(String, Integer, Symbol) => anything
|
235
|
-
def str_int_sym(o); end
|
236
|
-
end
|
237
|
-
|
238
|
-
def test_accepts_any_of
|
239
|
-
assert_violation { AcceptsAny.new.three_or_five "foo" }
|
240
|
-
assert_violation { AcceptsAny.new.three_or_five 7 }
|
241
|
-
assert_violation { AcceptsAny.new.three_or_five 8, 9 }
|
242
|
-
assert_passes { AcceptsAny.new.three_or_five 3 }
|
243
|
-
assert_passes { AcceptsAny.new.three_or_five 5 }
|
244
|
-
|
245
|
-
assert_violation { AcceptsAny.new.str_int_sym 5.3 }
|
246
|
-
assert_raises(ArgumentError) { AcceptsAny.new.str_int_sym "str", 3, :sym }
|
247
|
-
assert_passes { AcceptsAny.new.str_int_sym "str" }
|
248
|
-
assert_passes { AcceptsAny.new.str_int_sym 3 }
|
249
|
-
assert_passes { AcceptsAny.new.str_int_sym :foo }
|
250
|
-
end
|
251
|
-
|
252
|
-
class AcceptsNot
|
253
|
-
include Handshake
|
254
|
-
contract not?(String) => anything
|
255
|
-
def initialize(not_str); end
|
256
|
-
end
|
257
|
-
|
258
|
-
def test_accepts_not_string
|
259
|
-
assert_violation { AcceptsNot.new "string" }
|
260
|
-
assert_passes { AcceptsNot.new 3 }
|
261
|
-
assert_passes { AcceptsNot.new :symbol }
|
262
|
-
end
|
263
|
-
|
264
|
-
class AcceptsBoolean
|
265
|
-
include Handshake
|
266
|
-
contract boolean? => anything
|
267
|
-
def initialize(bool); end
|
268
|
-
end
|
269
|
-
|
270
|
-
def test_accepts_boolean
|
271
|
-
assert_violation { AcceptsBoolean.new "foo" }
|
272
|
-
assert_violation { AcceptsBoolean.new :foo }
|
273
|
-
assert_passes { AcceptsBoolean.new true }
|
274
|
-
assert_passes { AcceptsBoolean.new false }
|
275
|
-
end
|
276
|
-
|
277
|
-
class AcceptsNonzero
|
278
|
-
include Handshake
|
279
|
-
contract nonzero? => anything
|
280
|
-
def initialize(nonzero); end
|
281
|
-
end
|
282
|
-
|
283
|
-
def test_accepts_nonzero
|
284
|
-
assert_violation { AcceptsNonzero.new :foo }
|
285
|
-
assert_violation { AcceptsNonzero.new 0 }
|
286
|
-
assert_passes { AcceptsNonzero.new 3 }
|
287
|
-
end
|
288
|
-
|
289
|
-
class AcceptsHashOf
|
290
|
-
include Handshake
|
291
|
-
contract hash_of?(Symbol, String) => anything
|
292
|
-
def initialize(arg={}); end
|
293
|
-
end
|
294
|
-
|
295
|
-
def test_hash_of_sym_string
|
296
|
-
assert_passes { AcceptsHashOf.new({}) }
|
297
|
-
assert_passes { AcceptsHashOf.new({ :symbol => "String" }) }
|
298
|
-
assert_violation { AcceptsHashOf.new({ :another => :symbol }) }
|
299
|
-
assert_violation { AcceptsHashOf.new({ "two" => "strings" }) }
|
300
|
-
assert_violation { AcceptsHashOf.new({ false => true }) }
|
301
|
-
end
|
302
|
-
|
303
|
-
class AcceptsHashWithKeys
|
304
|
-
include Handshake
|
305
|
-
contract hash_with_keys(:foo, :bar) => anything
|
306
|
-
def initialize(options={}); end
|
307
|
-
end
|
308
|
-
|
309
|
-
def test_hash_with_keys_foo_bar
|
310
|
-
assert_passes { AcceptsHashWithKeys.new({}) }
|
311
|
-
assert_passes { AcceptsHashWithKeys.new({ :foo => "anything" }) }
|
312
|
-
assert_passes { AcceptsHashWithKeys.new({ :bar => "anything" }) }
|
313
|
-
assert_passes { AcceptsHashWithKeys.new({ :foo => "anything", :bar => "goes" }) }
|
314
|
-
assert_violation { AcceptsHashWithKeys.new({ :arbitrary => "key" }) }
|
315
|
-
end
|
316
|
-
|
317
|
-
class AcceptsHashContract
|
318
|
-
include Handshake
|
319
|
-
contract hash_contract({ :foo => String, :bar => Integer, :baz => Symbol }) => anything
|
320
|
-
def initialize(options={}); end
|
321
|
-
end
|
322
|
-
|
323
|
-
def test_hash_contract
|
324
|
-
assert_passes { AcceptsHashContract.new({}) }
|
325
|
-
assert_passes { AcceptsHashContract.new({ :foo => "bar"}) }
|
326
|
-
assert_violation { AcceptsHashContract.new({ :foo => :bar}) }
|
327
|
-
assert_passes { AcceptsHashContract.new({ :bar => 3 }) }
|
328
|
-
assert_violation { AcceptsHashContract.new({ :bar => "foo" }) }
|
329
|
-
assert_passes { AcceptsHashContract.new({ :baz => :foo }) }
|
330
|
-
assert_violation { AcceptsHashContract.new({ :baz => "baz" }) }
|
331
|
-
assert_passes { AcceptsHashContract.new({ :foo => "bar", :bar => 3, :baz => :qux }) }
|
332
|
-
end
|
333
|
-
|
334
|
-
class AcceptsRespondsTo
|
335
|
-
include Handshake
|
336
|
-
contract responds_to?(:each, :first) => anything
|
337
|
-
def initialize(duck_array); end
|
338
|
-
end
|
339
|
-
|
340
|
-
def test_responds_to_each_first
|
341
|
-
assert_violation { AcceptsRespondsTo.new({}) }
|
342
|
-
assert_violation { AcceptsRespondsTo.new "foo" }
|
343
|
-
assert_violation { AcceptsRespondsTo.new 3 }
|
344
|
-
assert_passes { AcceptsRespondsTo.new([]) }
|
345
|
-
end
|
346
|
-
|
347
|
-
class AcceptsIsA
|
348
|
-
include Handshake
|
349
|
-
contract is?(:String) => is?(:Symbol)
|
350
|
-
def call_is_a(str); return str.intern; end
|
351
|
-
end
|
352
|
-
|
353
|
-
def test_accepts_is_string_symbol
|
354
|
-
assert_violation { AcceptsIsA.new.call_is_a(3) }
|
355
|
-
assert_violation { AcceptsIsA.new.call_is_a(:foo) }
|
356
|
-
assert_passes { AcceptsIsA.new.call_is_a("foo") }
|
357
|
-
end
|
358
|
-
|
359
|
-
class SimpleBeforeCondition
|
360
|
-
include Handshake
|
361
|
-
before { assert false }
|
362
|
-
def call_fails; end
|
363
|
-
def call_passes; end
|
364
|
-
end
|
365
|
-
class ExtendsSimpleBeforeCondition < SimpleBeforeCondition; end
|
366
|
-
|
367
|
-
def test_simple_before_condition
|
368
|
-
assert_equal(1, SimpleBeforeCondition.method_contracts.length)
|
369
|
-
assert_not_nil(SimpleBeforeCondition.method_contracts[:call_fails])
|
370
|
-
assert_violation { SimpleBeforeCondition.new.call_fails }
|
371
|
-
assert_passes { SimpleBeforeCondition.new.call_passes }
|
372
|
-
assert_equal(1, ExtendsSimpleBeforeCondition.method_contracts.length)
|
373
|
-
assert_not_nil(ExtendsSimpleBeforeCondition.method_contracts[:call_fails])
|
374
|
-
assert_violation { ExtendsSimpleBeforeCondition.new.call_fails }
|
375
|
-
assert_passes { ExtendsSimpleBeforeCondition.new.call_passes }
|
376
|
-
end
|
377
|
-
|
378
|
-
class SimpleAfterCondition
|
379
|
-
include Handshake
|
380
|
-
after { |accepted, returned| assert returned }
|
381
|
-
def call(bool); bool; end
|
382
|
-
end
|
383
|
-
|
384
|
-
def test_simple_after_condition
|
385
|
-
assert_equal(1, SimpleAfterCondition.method_contracts.length)
|
386
|
-
assert_not_nil(SimpleAfterCondition.method_contracts[:call])
|
387
|
-
assert_violation { SimpleAfterCondition.new.call(false) }
|
388
|
-
assert_violation { SimpleAfterCondition.new.call(nil) }
|
389
|
-
assert_passes { SimpleAfterCondition.new.call(true) }
|
390
|
-
assert_passes { SimpleAfterCondition.new.call("foo") }
|
391
|
-
end
|
392
|
-
|
393
|
-
class SimpleAroundCondition
|
394
|
-
include Handshake
|
395
|
-
around {|arg| assert(!arg) }
|
396
|
-
def call(bool); bool; end
|
397
|
-
end
|
398
|
-
|
399
|
-
def test_simple_around_condition
|
400
|
-
[ 1, :foo, true, false, "bar", 8.3, nil ].each do |val|
|
401
|
-
assert_violation { SimpleAroundCondition.new.call(val) }
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
class ScopedBeforeCondition
|
406
|
-
include Handshake
|
407
|
-
def initialize(bool); @bool = bool; end
|
408
|
-
before { assert @bool }
|
409
|
-
def call; end
|
410
|
-
end
|
411
|
-
|
412
|
-
def test_scoped_before_condition
|
413
|
-
assert_violation { ScopedBeforeCondition.new(false).call }
|
414
|
-
assert_passes { ScopedBeforeCondition.new(true).call }
|
415
|
-
end
|
416
|
-
|
417
|
-
class ContractAccessor
|
418
|
-
include Handshake
|
419
|
-
contract_reader :foo => String
|
420
|
-
contract_writer :bar => Integer
|
421
|
-
contract_accessor :baz => Symbol, :qux => Float
|
422
|
-
def initialize(foo=nil); @foo = foo; end
|
423
|
-
end
|
424
|
-
|
425
|
-
def test_contract_accessor
|
426
|
-
assert_equal(6, ContractAccessor.method_contracts.length)
|
427
|
-
assert_violation { ContractAccessor.new.foo }
|
428
|
-
assert_violation { ContractAccessor.new(3).foo }
|
429
|
-
assert_passes { ContractAccessor.new("foo").foo }
|
430
|
-
assert_violation { ContractAccessor.new.bar = "bar" }
|
431
|
-
assert_passes { ContractAccessor.new.bar = 3 }
|
432
|
-
assert_violation { ContractAccessor.new.baz = "3" }
|
433
|
-
assert_violation { ContractAccessor.new.qux = 3 }
|
434
|
-
assert_passes { ContractAccessor.new.baz = :baz }
|
435
|
-
assert_passes { ContractAccessor.new.qux = 3.3 }
|
436
|
-
end
|
437
|
-
|
438
|
-
class BeforeClauseAssert
|
439
|
-
include Handshake
|
440
|
-
|
441
|
-
before do |arg|
|
442
|
-
assert_equal("foo", arg, "arg must equal foo")
|
443
|
-
end; def call(arg)
|
444
|
-
arg
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
def test_before_clause_assert
|
449
|
-
assert_violation { BeforeClauseAssert.new.call 3 }
|
450
|
-
assert_violation { BeforeClauseAssert.new.call "bar" }
|
451
|
-
assert_passes { BeforeClauseAssert.new.call "foo" }
|
452
|
-
end
|
453
|
-
|
454
|
-
class Superclass
|
455
|
-
include Handshake
|
456
|
-
contract Superclass => boolean?
|
457
|
-
def ==(other); self.class === other; end
|
458
|
-
end
|
459
|
-
|
460
|
-
class Subclass < Superclass; end
|
461
|
-
|
462
|
-
class AcceptsSuperAndSub
|
463
|
-
include Handshake
|
464
|
-
contract Superclass => anything
|
465
|
-
def call(cls); cls; end
|
466
|
-
end
|
467
|
-
|
468
|
-
def test_accepts_super_and_sub
|
469
|
-
assert_violation { AcceptsSuperAndSub.new.call 3 }
|
470
|
-
assert_passes { AcceptsSuperAndSub.new.call Superclass.new }
|
471
|
-
assert_passes { AcceptsSuperAndSub.new.call Subclass.new }
|
472
|
-
assert_passes { Superclass.new == Subclass.new }
|
473
|
-
end
|
474
|
-
|
475
|
-
class CheckedSelf
|
476
|
-
include Handshake
|
477
|
-
def call_checked(obj)
|
478
|
-
checked_self.call(obj)
|
479
|
-
end
|
480
|
-
def call_unchecked(obj)
|
481
|
-
call(obj)
|
482
|
-
end
|
483
|
-
contract String => anything
|
484
|
-
def call(str); str; end
|
485
|
-
end
|
486
|
-
|
487
|
-
class ExtendsCheckedSelf < CheckedSelf
|
488
|
-
private
|
489
|
-
contract Numeric => anything
|
490
|
-
def call(n); n; end
|
491
|
-
end
|
492
|
-
|
493
|
-
def test_checked_self
|
494
|
-
assert_violation { CheckedSelf.new.call(5) }
|
495
|
-
assert_violation { CheckedSelf.new.call_checked(5) }
|
496
|
-
assert_passes { CheckedSelf.new.call_unchecked(5) }
|
497
|
-
assert_passes { CheckedSelf.new.call_checked("foo") }
|
498
|
-
assert_violation { ExtendsCheckedSelf.new.call_checked("foo") }
|
499
|
-
assert_passes { ExtendsCheckedSelf.new.call_checked(5) }
|
500
|
-
assert_passes { ExtendsCheckedSelf.new.call_unchecked("foo") }
|
501
|
-
end
|
502
|
-
|
503
|
-
class CheckedBlockContract
|
504
|
-
include Handshake
|
505
|
-
|
506
|
-
contract [ anything, Block(String => Integer) ] => Integer
|
507
|
-
def yields(value); yield(value); end
|
508
|
-
|
509
|
-
contract [ anything, Block(String => Integer) ] => Integer
|
510
|
-
def calls(value, &block); block.call(value); end
|
511
|
-
end
|
512
|
-
|
513
|
-
def test_checked_block_contract_yields
|
514
|
-
assert_violation { CheckedBlockContract.new.yields("3") {|s| s.to_s } }
|
515
|
-
assert_violation { CheckedBlockContract.new.yields("3") {|s| "foo" } }
|
516
|
-
assert_violation { CheckedBlockContract.new.yields(3) {|s| s.to_i} }
|
517
|
-
assert_passes { CheckedBlockContract.new.yields("3") {|s| 3 } }
|
518
|
-
assert_passes { CheckedBlockContract.new.yields("3") {|s| s.to_i } }
|
519
|
-
end
|
520
|
-
|
521
|
-
def test_checked_block_contract_calls
|
522
|
-
assert_violation { CheckedBlockContract.new.calls("3") {|s| s.to_s } }
|
523
|
-
assert_violation { CheckedBlockContract.new.calls("3") {|s| "foo" } }
|
524
|
-
assert_violation { CheckedBlockContract.new.calls(3) {|s| s.to_i} }
|
525
|
-
assert_passes { CheckedBlockContract.new.calls("3") {|s| 3 } }
|
526
|
-
assert_passes { CheckedBlockContract.new.calls("3") {|s| s.to_i } }
|
527
|
-
end
|
528
|
-
end
|