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 CHANGED
@@ -31,37 +31,36 @@ Or install it yourself as:
31
31
 
32
32
  Consider a canonical superclass.
33
33
 
34
- class Vehicle
35
- def drive(passengers, destination)
36
- load passengers
37
- follow Route.new(@current_location, destination)
38
- unload passengers
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
- See all the methods have to be implemented for this to work? Let's specify these as part of the interface:
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
- class Vehicle
44
+ class Vehicle
45
+ include Contractual::Interface
45
46
 
46
- must_implement :load, :passengers
47
- must_implement :follow, :route
48
- must_implement :unload, :passengers
47
+ must :load, :passengers
48
+ must :follow, :route
49
+ must :unload, :passengers
49
50
 
50
- def move(passengers, destination)
51
- load passengers
52
- follow Route.new(@current_location, destination)
53
- unload passengers
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
- class Zeppelin
60
-
61
- def load(passengers); @passengers << passengers; end
62
- def unload(passengers); @current_location << passengers; @passengers = []; end
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
 
@@ -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} needs to implement '#{method_name}' for interface #{self.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
 
@@ -1,3 +1,3 @@
1
1
  module Contractual
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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.1
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