contractual 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +21 -22
- data/lib/contractual.rb +1 -1
- data/lib/contractual/version.rb +1 -1
- data/spec/contractual_spec.rb +24 -0
- metadata +4 -2
data/README.md
CHANGED
@@ -31,37 +31,36 @@ Or install it yourself as:
|
|
31
31
|
|
32
32
|
Consider a canonical superclass.
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
class Vehicle
|
35
|
+
def drive(passengers, destination)
|
36
|
+
load passengers
|
37
|
+
follow Route.new(@current_location, destination)
|
38
|
+
unload passengers
|
39
|
+
end
|
39
40
|
end
|
40
|
-
end
|
41
41
|
|
42
|
-
|
42
|
+
Note all the methods have to be implemented for this to work (load, follow, unload). Let's go ahead and specify these as part of the interface:
|
43
43
|
|
44
|
-
|
44
|
+
class Vehicle
|
45
|
+
include Contractual::Interface
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
must :load, :passengers
|
48
|
+
must :follow, :route
|
49
|
+
must :unload, :passengers
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
def move(passengers, destination)
|
52
|
+
load passengers
|
53
|
+
follow Route.new(@current_location, destination)
|
54
|
+
unload passengers
|
55
|
+
end
|
54
56
|
end
|
55
|
-
end
|
56
57
|
|
57
58
|
Let's suppose we've been handed this interface from another developer. How do we make a custom subclass? Our first attempt at implementing might look something like this:
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
60
|
+
class Zeppelin
|
61
|
+
def load(passengers); @passengers << passengers; end
|
62
|
+
def unload(passengers); @current_location << passengers; @passengers = []; end
|
63
|
+
end
|
65
64
|
|
66
65
|
So now when we try to invoke Zeppelin.move, we'll get an exception warning us that Zeppelin is obligated to implement a method 'follow' from the interface Vehicle. This is the 'hint' that the implementing developer has a bit more work to do before they can use this custom class smoothly with the rest of the system.
|
67
66
|
|
data/lib/contractual.rb
CHANGED
@@ -20,7 +20,7 @@ module Contractual
|
|
20
20
|
klass_name = klass.class.name
|
21
21
|
interface_name = self.name
|
22
22
|
|
23
|
-
raise MethodNotImplementedError.new("#{klass.class.name}
|
23
|
+
raise MethodNotImplementedError.new("#{klass.class.name} is obligated to implement '#{method_name}' for interface #{self.name}!")
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
data/lib/contractual/version.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'contractual'
|
2
|
+
|
3
|
+
describe Contractual::Interface, "an interface should support a contract" do
|
4
|
+
|
5
|
+
class MockInterface
|
6
|
+
include Contractual::Interface
|
7
|
+
|
8
|
+
must_implement :mock_operation
|
9
|
+
must :perform_another_mock_operation
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
class MockInterfaceImpl < MockInterface; end
|
14
|
+
|
15
|
+
|
16
|
+
it "should warn about unimplemented methods" do
|
17
|
+
mock_object = MockInterfaceImpl.new
|
18
|
+
|
19
|
+
lambda { mock_object.mock_operation }.should raise_error(Contractual::Interface::MethodNotImplementedError, "MockInterfaceImpl is obligated to implement 'mock_operation' for interface MockInterface!")
|
20
|
+
|
21
|
+
lambda { mock_object.perform_another_mock_operation }.should raise_error(Contractual::Interface::MethodNotImplementedError, "MockInterfaceImpl is obligated to implement 'perform_another_mock_operation' for interface MockInterface!")
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contractual
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -30,6 +30,7 @@ files:
|
|
30
30
|
- contractual.gemspec
|
31
31
|
- lib/contractual.rb
|
32
32
|
- lib/contractual/version.rb
|
33
|
+
- spec/contractual_spec.rb
|
33
34
|
homepage: ''
|
34
35
|
licenses: []
|
35
36
|
post_install_message:
|
@@ -54,4 +55,5 @@ rubygems_version: 1.8.22
|
|
54
55
|
signing_key:
|
55
56
|
specification_version: 3
|
56
57
|
summary: Specify interface contracts for your Ruby classes.
|
57
|
-
test_files:
|
58
|
+
test_files:
|
59
|
+
- spec/contractual_spec.rb
|