duckpond 1.2 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e412869c6899468637cccaf6debbf31ffef6fd7a
4
- data.tar.gz: aaf49e52a9f2c35987260541a3c888d7cf89e7c6
3
+ metadata.gz: 6c635271dca4ed930b071dc968a417b806c7cfb1
4
+ data.tar.gz: 4a8da65e653dadfac684a2204199d9f9acd3d9c4
5
5
  SHA512:
6
- metadata.gz: f14ccc6e1268198efc50b0116e0fa4a4c0d4ec52ffeee97e4bf92f2fbf2396bf4a682614f08204310112a52fb24ec8b2c99ff7bb87e302b5bf8eb10d42c738b1
7
- data.tar.gz: 42995441b44f631d907cec3d3e5d8849b2f0266cb84f16a01a627e2e202c042459b139ae9f2ad82dcb440630db0f267e08d8c1ac92aa55817049067da936a440
6
+ metadata.gz: 52973252980ae5be14a152965de3f0faffc8cc0de46489ee3002a07f4f457b30cf92298e453c37d79d4e80911a42f90ccd37aecfc58cc460966f87a6e337f822
7
+ data.tar.gz: d426f2173a3cc9baae657ddb8782d1f9749870a1f2ddfbd1350fba3af971e1ba043bedc53341e7f53506f28208249fd078e76425da321191c1dbacb59e944677
data/.travis.yml CHANGED
@@ -1,9 +1,9 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 1.9.3
5
- - 2.0.0
6
- - 2.1.1
4
+ - 2.3.0
5
+ - 2.2.4
6
+ - 2.1.8
7
7
  - jruby-19mode
8
8
 
9
9
  script: bundle exec rspec spec
data/Gemfile.lock CHANGED
@@ -1,52 +1,53 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckpond (1.1.4)
4
+ duckpond (1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- coveralls (0.7.0)
10
- multi_json (~> 1.3)
11
- rest-client
12
- simplecov (>= 0.7)
13
- term-ansicolor
14
- thor
9
+ coveralls (0.8.13)
10
+ json (~> 1.8)
11
+ simplecov (~> 0.11.0)
12
+ term-ansicolor (~> 1.3)
13
+ thor (~> 0.19.1)
14
+ tins (~> 1.6.0)
15
15
  diff-lcs (1.2.5)
16
16
  docile (1.1.5)
17
- mime-types (2.3)
18
- multi_json (1.10.1)
17
+ json (1.8.3)
19
18
  rake (0.9.6)
20
- rest-client (1.6.7)
21
- mime-types (>= 1.16)
22
- rspec (3.0.0)
23
- rspec-core (~> 3.0.0)
24
- rspec-expectations (~> 3.0.0)
25
- rspec-mocks (~> 3.0.0)
26
- rspec-core (3.0.1)
27
- rspec-support (~> 3.0.0)
28
- rspec-expectations (3.0.1)
19
+ rspec (3.4.0)
20
+ rspec-core (~> 3.4.0)
21
+ rspec-expectations (~> 3.4.0)
22
+ rspec-mocks (~> 3.4.0)
23
+ rspec-core (3.4.3)
24
+ rspec-support (~> 3.4.0)
25
+ rspec-expectations (3.4.0)
29
26
  diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.0.0)
31
- rspec-mocks (3.0.1)
32
- rspec-support (~> 3.0.0)
33
- rspec-support (3.0.0)
34
- simplecov (0.8.2)
27
+ rspec-support (~> 3.4.0)
28
+ rspec-mocks (3.4.1)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.4.0)
31
+ rspec-support (3.4.1)
32
+ simplecov (0.11.2)
35
33
  docile (~> 1.1.0)
36
- multi_json
37
- simplecov-html (~> 0.8.0)
38
- simplecov-html (0.8.0)
39
- term-ansicolor (1.3.0)
34
+ json (~> 1.8)
35
+ simplecov-html (~> 0.10.0)
36
+ simplecov-html (0.10.0)
37
+ term-ansicolor (1.3.2)
40
38
  tins (~> 1.0)
41
39
  thor (0.19.1)
42
- tins (1.3.0)
40
+ tins (1.6.0)
43
41
 
44
42
  PLATFORMS
45
43
  ruby
46
44
 
47
45
  DEPENDENCIES
48
- bundler (~> 1.3)
46
+ bundler (~> 1.10)
49
47
  coveralls
50
48
  duckpond!
51
49
  rake (~> 0)
52
50
  rspec
51
+
52
+ BUNDLED WITH
53
+ 1.10.6
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  Explicit duck typing for ruby.
8
8
 
9
9
 
10
- ## Inspiration
10
+ ## Introduction
11
11
 
12
12
  Duck Typing can make code confusing and unreadable, particularly
13
13
  when multiple developers are working on the same project or when
@@ -35,6 +35,8 @@ Or install it yourself as:
35
35
 
36
36
  ## Usage
37
37
 
38
+ There is now a [screencast](https://www.youtube.com/watch?v=XTFigHzAfsk&feature=youtu.be) demonstrating the duckpond gem!
39
+
38
40
  Usage is demonstrated in '[the_solution](docs/the_solution.txt)', but in a nutshell you
39
41
  create "contract" classes by inheriting from DuckPond::Contract. These classes should
40
42
  be commented extensively.
@@ -56,10 +58,13 @@ fulfilled by the object:
56
58
  => false
57
59
 
58
60
  There is also a "bang" version of the #fulfills method, that raises an error instead
59
- of returning false.
61
+ of returning false. The error message details why it got raised.
62
+
63
+ MyContract.fulfills! :foo
64
+ => DuckPond::Contract::ContractInfringementError:
65
+ One or more clauses from MyContract were not fulfilled by :foo (Symbol)
66
+ Expected subject to respond to method 'length'
60
67
 
61
- MyContract.fulfills! 12
62
- => RAISES ERROR!!
63
68
 
64
69
  Contracts can be combined into composite "super contracts" - contracts which are made up of
65
70
  various other contracts. This ties in with the reccomendation of preferring composition over inheritance:
@@ -127,11 +132,11 @@ And then be implemented in a method like this:
127
132
 
128
133
  ## Compatibility
129
134
 
130
- CI tests exist for the following rubies, so they definately work and there's no reason all 1.9.x rubies wouldnt' work either:
135
+ CI tests exist for the following rubies, other versions are not supported but should still work;
131
136
 
132
- - 1.9.3
133
- - 2.0.0
134
- - 2.1.1
137
+ - 2.3.0
138
+ - 2.2.4
139
+ - 2.1.8
135
140
  - jruby-19mode
136
141
 
137
142
 
data/duckpond.gemspec CHANGED
@@ -18,6 +18,6 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(spec)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "bundler", "~> 1.10"
22
22
  spec.add_development_dependency "rake", "~> 0"
23
23
  end
@@ -4,43 +4,58 @@
4
4
  # Satisfied if the subject responds to the method represented
5
5
  # by this clause.
6
6
  #
7
+ # Available Options:
8
+ #
9
+ # :method_name => The name of the method to check for / call
10
+ # :given_args => Arguments to pass into the method
11
+ # :responds_with => What you would expect the method to respond with
12
+ #
13
+ #
7
14
  module DuckPond
8
15
  class MethodClause < Clause
9
16
 
10
- def method_name
11
- @options[:method_name]
12
- end
13
-
14
- #
15
- # satisfied_by?
16
17
  #
17
- # A subject satisfies a method clause if it responds to that method.
18
+ # legal_assesment
18
19
  #
19
- def satisfied_by?(subject)
20
-
21
- # Check the method actually exists.
22
- return false unless subject.respond_to? method_name
23
-
24
- # Unless a block was given, or a response is required, we're done!
25
- return true unless @options[:block] || @options[:responds_with]
26
-
27
- # If we get this far, we need to tap into the result of the method
28
- # call, as the user is interrogating it somehow.
29
- response_when_called(subject, method_name, @options[:given_args])
30
- .tap do |response_when_called|
31
- if @options[:block]
32
- return false unless @options[:block].call(response_when_called)
20
+ def legal_assesment(subject)
21
+ Lawyer.new do |lawyer|
22
+ unless subject.respond_to? method
23
+ lawyer.unsatisfied! "Expected subject to respond to method '#{method}'"
33
24
  end
34
- if @options[:responds_with]
35
- return false unless response_when_called == @options[:responds_with]
25
+
26
+ if @block || expected_response
27
+ response_when_called(subject, method, args).tap do |response_when_called|
28
+ if @block
29
+ unless @block.call(response_when_called)
30
+ lawyer.unsatisfied! "Block did not respond with 'true' for method #{method}"
31
+ end
32
+ end
33
+
34
+ if expected_response
35
+ unless response_when_called == expected_response
36
+ lawyer.unsatisfied! "Expected method #{method} to return #{expected_response} but got #{response_when_called}"
37
+ end
38
+ end
39
+ end
36
40
  end
37
41
  end
38
- true
39
42
  end
40
43
 
41
44
  private
42
45
  def response_when_called(subject, method, args = [])
43
- subject.send(method_name, *args)
46
+ subject.send(method, *args)
47
+ end
48
+
49
+ def method
50
+ @options[:method_name]
51
+ end
52
+
53
+ def expected_response
54
+ @options[:responds_with]
55
+ end
56
+
57
+ def args
58
+ @options[:given_args]
44
59
  end
45
60
 
46
61
  end
@@ -6,14 +6,26 @@
6
6
  module DuckPond
7
7
  class Clause
8
8
 
9
- attr_reader :options
9
+ attr_reader :options, :block
10
10
 
11
11
  #
12
12
  # initialize
13
13
  #
14
14
  def initialize(opts={}, block)
15
15
  @options = opts
16
- @options[:block] = block
16
+ @block = block
17
17
  end
18
+
19
+ def satisfied_by?(subject)
20
+ self.legal_assesment(subject).satisfied?
21
+ end
22
+
23
+ def legal_assesment
24
+ # it is the responsibility of clauses to provide a #legal_assesment
25
+ # method - this should return a lawyer who is either satisfied or
26
+ # not satisfied that the subject fulfills the clause.
27
+ raise NotImplementedError
28
+ end
29
+
18
30
  end
19
31
  end
@@ -0,0 +1,19 @@
1
+ module DuckPond
2
+ class Contract
3
+ class ContractInfringementError < TypeError
4
+ def initialize(contract, subject, inspection = nil)
5
+ @contract = contract
6
+ @subject = subject
7
+ @messages = inspection.messages
8
+ end
9
+
10
+ def message
11
+ %Q{
12
+ One or more clauses from #{@contract} were not fulfilled by #{@subject} (#{@subject.class})
13
+ #{@messages.join(', ') if @messages.any?}
14
+ }
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ #
2
+ # Contract::ConvinienceMethods
3
+ #
4
+ # A set of methods used to make adding clauses easier for the user.
5
+ #
6
+ module DuckPond
7
+ class Contract
8
+ module ConvinienceMethods
9
+ #
10
+ # has_method
11
+ #
12
+ # Adds a method clause to the contract
13
+ #
14
+ def has_method(method_name, opts = {})
15
+ if block_given?
16
+ has_clause(MethodClause, opts.merge(:method_name => method_name), &Proc.new)
17
+ else
18
+ has_clause(MethodClause, opts.merge(:method_name => method_name))
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,6 @@
1
+ require 'duckpond/contract/convinience_methods'
2
+ require 'duckpond/contract/contract_infringement_error'
3
+
1
4
  #
2
5
  # DuckPond::Contract
3
6
  #
@@ -7,7 +10,7 @@
7
10
  #
8
11
  module DuckPond
9
12
  class Contract
10
- class ContractInfringementError < TypeError;end
13
+ extend DuckPond::Contract::ConvinienceMethods
11
14
 
12
15
  class << self
13
16
 
@@ -41,20 +44,6 @@ module DuckPond
41
44
  clauses << clause_klass.new(opts, block)
42
45
  end
43
46
 
44
-
45
- #
46
- # has_method
47
- #
48
- # Adds a method clause to the contract
49
- #
50
- def has_method(method_name, opts = {})
51
- if block_given?
52
- has_clause(MethodClause, opts.merge(:method_name => method_name), &Proc.new)
53
- else
54
- has_clause(MethodClause, opts.merge(:method_name => method_name))
55
- end
56
- end
57
-
58
47
  #
59
48
  # include_clauses_from
60
49
  #
@@ -62,7 +51,7 @@ module DuckPond
62
51
  #
63
52
  def include_clauses_from(other_contract)
64
53
  other_contract.each_clause do |other_clause|
65
- has_method other_clause.method_name
54
+ has_clause other_clause.class, other_clause.options, &other_clause.block
66
55
  end
67
56
  end
68
57
 
@@ -73,11 +62,13 @@ module DuckPond
73
62
  # otherwise false.
74
63
  #
75
64
  def fulfills?(obj)
76
- inspection = DuckPond::Inspection.new(obj)
77
- return false unless inspection.fulfilled_by? self
78
- true
65
+ DuckPond::Inspection.new(obj).tap do |inspection|
66
+ return inspection.fulfilled_by? self
67
+ end
79
68
  end
80
69
 
70
+ alias_method :fulfilled_by?, :fulfills?
71
+
81
72
  #
82
73
  # fulfills!
83
74
  #
@@ -85,9 +76,17 @@ module DuckPond
85
76
  # the passed in object, otherwise returns true.
86
77
  #
87
78
  def fulfills!(obj)
88
- raise ContractInfringementError unless fulfills?(obj)
89
- true
79
+ DuckPond::Inspection.new(obj).tap do |inspection|
80
+ unless inspection.fulfilled_by? self
81
+ raise ContractInfringementError.new(self, obj, inspection)
82
+ else
83
+ return true
84
+ end
85
+ end
90
86
  end
87
+
88
+ alias_method :fulfilled_by!, :fulfills!
89
+
91
90
  end
92
91
  end
93
92
  end
@@ -16,7 +16,13 @@ module DuckPond
16
16
  # Construct with any ruby object.
17
17
  #
18
18
  def initialize(subject)
19
- @subject = subject
19
+ @subject = subject
20
+ @satisfied = true
21
+ @messages = []
22
+ end
23
+
24
+ def messages
25
+ @messages.flatten.uniq
20
26
  end
21
27
 
22
28
  #
@@ -28,9 +34,18 @@ module DuckPond
28
34
  #
29
35
  def fulfilled_by?(contract)
30
36
  contract.each_clause do |clause|
31
- return false unless clause.satisfied_by?(@subject)
37
+ clause.legal_assesment(@subject).tap do |lawyer|
38
+ unless lawyer.satisfied?
39
+ @satisfied = false
40
+ @messages << lawyer.messages
41
+ end
42
+ end
32
43
  end
33
- true
44
+ @satisfied
45
+ end
46
+
47
+ def satisfied?
48
+ @satisfied
34
49
  end
35
50
  end
36
51
  end
@@ -0,0 +1,30 @@
1
+ #
2
+ # DuckPond::Lawyer
3
+ #
4
+ # The lawyer class is responsible for maintaining the sate of satisfaction
5
+ # between a subject and its contract. Typically these are used in clauses.
6
+ #
7
+ module DuckPond
8
+ class Lawyer
9
+
10
+ def initialize
11
+ @satisfied = true
12
+ @messages = []
13
+ yield self if block_given?
14
+ end
15
+
16
+ def satisfied?
17
+ @satisfied
18
+ end
19
+
20
+ def messages
21
+ @messages
22
+ end
23
+
24
+ def unsatisfied!(msg = nil)
25
+ @satisfied = false
26
+ @messages << msg unless msg.nil?
27
+ end
28
+ end
29
+
30
+ end
@@ -1,3 +1,3 @@
1
1
  module DuckPond
2
- VERSION = "1.2"
2
+ VERSION = "1.2.1"
3
3
  end
data/lib/duckpond.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'duckpond/version'
2
+ require 'duckpond/lawyer'
2
3
  require 'duckpond/contract'
3
4
  require 'duckpond/inspection'
4
5
 
@@ -12,7 +12,7 @@ module DuckPond
12
12
  context 'when constructed with a method name option' do
13
13
  it 'adds that method name as an attribute' do
14
14
  clause = MethodClause.new({:method_name => :foo}, nil)
15
- expect(clause.method_name).to eq :foo
15
+ expect(clause.options[:method_name]).to eq :foo
16
16
  end
17
17
  end
18
18
  end
@@ -24,12 +24,12 @@ module DuckPond
24
24
 
25
25
  context 'when the subject responds to the clauses method' do
26
26
  it 'returns true' do
27
- expect(clause.satisfied_by? 'Hello').to eq true
27
+ expect(clause.satisfied_by?('Hello')).to eq true
28
28
  end
29
29
  end
30
30
  context 'when the subject responds to the clauses method' do
31
31
  it 'returns false' do
32
- expect(clause.satisfied_by? 42).to eq false
32
+ expect(clause.satisfied_by?(42)).to eq false
33
33
  end
34
34
  end
35
35
  end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'MethodClause usage' do
4
+
5
+ #
6
+ # see spec/classes/specific_length_contract.rb
7
+ #
8
+ describe SpecificLengthContract do
9
+ it 'checks a methods response is correct' do
10
+ expect(SpecificLengthContract.fulfills?("Hello")).to eq true
11
+ expect(SpecificLengthContract.fulfills?("Yello")).to eq false
12
+ expect(SpecificLengthContract.fulfills?("Goodbye")).to eq false
13
+ end
14
+ end
15
+
16
+ describe SpecificLengthBehaviourContract do
17
+ it 'checks the given block against the subjects method repsonse' do
18
+ expect(SpecificLengthBehaviourContract.fulfills?('Hello')).to eq true
19
+ expect(SpecificLengthBehaviourContract.fulfills?('Goodbye')).to eq false
20
+ end
21
+ end
22
+
23
+ describe SpecificIncludeBehaviourContract do
24
+ it 'checks the given block against the subjects method response' do
25
+ expect(SpecificIncludeBehaviourContract.fulfills?('Hello')).to eq true
26
+ expect(SpecificLengthBehaviourContract.fulfills?('Goodbye')).to eq false
27
+ end
28
+ end
29
+
30
+ end
@@ -36,7 +36,7 @@ module DuckPond
36
36
  end
37
37
  context 'when the object is not fulfilled by the contract' do
38
38
  it 'returns false' do
39
- expect{LengthContract.fulfills!(2)}.to raise_error
39
+ expect{LengthContract.fulfills!(2)}.to raise_error DuckPond::Contract::ContractInfringementError
40
40
  end
41
41
  end
42
42
  end
@@ -45,36 +45,11 @@ module DuckPond
45
45
  it 'returns the clauses for this contract' do
46
46
  clauses = LengthContract.clauses
47
47
  expect(clauses.length).to eq 1
48
- expect(clauses.map(&:method_name)).to include :length
48
+ expect(clauses.first.options[:method_name]).to eq :length
49
49
  end
50
50
  end
51
51
  end
52
52
 
53
- #
54
- # see spec/classes/specific_length_contract.rb
55
- #
56
- describe SpecificLengthContract do
57
- it 'checks a methods response is correct' do
58
- expect(SpecificLengthContract.fulfills?("Hello")).to eq true
59
- expect(SpecificLengthContract.fulfills?("Yello")).to eq false
60
- expect(SpecificLengthContract.fulfills?("Goodbye")).to eq false
61
- end
62
- end
63
-
64
- describe SpecificLengthBehaviourContract do
65
- it 'checks the given block against the subjects method repsonse' do
66
- expect(SpecificLengthBehaviourContract.fulfills?('Hello')).to eq true
67
- expect(SpecificLengthBehaviourContract.fulfills?('Goodbye')).to eq false
68
- end
69
- end
70
-
71
- describe SpecificIncludeBehaviourContract do
72
- it 'checks the given block against the subjects method response' do
73
- expect(SpecificIncludeBehaviourContract.fulfills?('Hello')).to eq true
74
- expect(SpecificLengthBehaviourContract.fulfills?('Goodbye')).to eq false
75
- end
76
- end
77
-
78
53
  #
79
54
  # See spec/classes/composite_contract.rb
80
55
  #
@@ -82,8 +57,11 @@ module DuckPond
82
57
  it 'retains its parents quackings' do
83
58
  clauses = CompositeContract.clauses
84
59
  expect(clauses.length).to eq 2
85
- expect(clauses.map(&:method_name)).to include :length
86
- expect(clauses.map(&:method_name)).to include :chunky_bacon
60
+ clauses.map {|c|c.options[:method_name]}.tap do |method_names|
61
+ expect(method_names).to include :length
62
+ expect(method_names).to include :chunky_bacon
63
+ end
87
64
  end
88
65
  end
66
+
89
67
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ module DuckPond
4
+ describe Lawyer do
5
+ describe 'constructor' do
6
+ it 'yields itself if passed a block' do
7
+ oid_1 = nil
8
+ oid_2 = Lawyer.new do |lawyer|
9
+ oid_1 = lawyer.object_id
10
+ end.object_id
11
+ expect(oid_1).to eq oid_2
12
+ end
13
+ end
14
+ describe 'unsatisified!' do
15
+ it 'sets the lawyers satisfied flag to false' do
16
+ lawyer = Lawyer.new
17
+ expect(lawyer.satisfied?).to be true
18
+
19
+ lawyer.unsatisfied!
20
+ expect(lawyer.satisfied?).to be false
21
+ end
22
+ end
23
+ end
24
+ end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duckpond
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.2'
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikey Hogarth
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-26 00:00:00.000000000 Z
11
+ date: 2016-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '1.10'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '1.10'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  description: Explicit duck-typing for ruby
@@ -45,9 +45,9 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - .gitignore
49
- - .rspec
50
- - .travis.yml
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - ".travis.yml"
51
51
  - Gemfile
52
52
  - Gemfile.lock
53
53
  - LICENSE
@@ -60,16 +60,21 @@ files:
60
60
  - lib/duckpond/clause.rb
61
61
  - lib/duckpond/clause/method_clause.rb
62
62
  - lib/duckpond/contract.rb
63
+ - lib/duckpond/contract/contract_infringement_error.rb
64
+ - lib/duckpond/contract/convinience_methods.rb
63
65
  - lib/duckpond/inspection.rb
66
+ - lib/duckpond/lawyer.rb
64
67
  - lib/duckpond/version.rb
65
68
  - spec/classes/contracts/composite_contract.rb
66
69
  - spec/classes/contracts/length_contract.rb
67
70
  - spec/classes/contracts/specific_include_behaviour_contract.rb
68
71
  - spec/classes/contracts/specific_length_behaviour_contract.rb
69
72
  - spec/classes/contracts/specific_length_contract.rb
70
- - spec/clauses/method_clause_spec.rb
73
+ - spec/clauses/method_clause/method_clause_spec.rb
74
+ - spec/clauses/method_clause/method_clause_usage_spec.rb
71
75
  - spec/contract_spec.rb
72
76
  - spec/inspection_spec.rb
77
+ - spec/lawyer_spec.rb
73
78
  - spec/spec_helper.rb
74
79
  homepage: https://github.com/mikeyhogarth/duckpond
75
80
  licenses:
@@ -81,17 +86,17 @@ require_paths:
81
86
  - lib
82
87
  required_ruby_version: !ruby/object:Gem::Requirement
83
88
  requirements:
84
- - - '>='
89
+ - - ">="
85
90
  - !ruby/object:Gem::Version
86
91
  version: '0'
87
92
  required_rubygems_version: !ruby/object:Gem::Requirement
88
93
  requirements:
89
- - - '>='
94
+ - - ">="
90
95
  - !ruby/object:Gem::Version
91
96
  version: '0'
92
97
  requirements: []
93
98
  rubyforge_project:
94
- rubygems_version: 2.2.2
99
+ rubygems_version: 2.4.5.1
95
100
  signing_key:
96
101
  specification_version: 4
97
102
  summary: Explicit duck-typing for ruby
@@ -101,7 +106,10 @@ test_files:
101
106
  - spec/classes/contracts/specific_include_behaviour_contract.rb
102
107
  - spec/classes/contracts/specific_length_behaviour_contract.rb
103
108
  - spec/classes/contracts/specific_length_contract.rb
104
- - spec/clauses/method_clause_spec.rb
109
+ - spec/clauses/method_clause/method_clause_spec.rb
110
+ - spec/clauses/method_clause/method_clause_usage_spec.rb
105
111
  - spec/contract_spec.rb
106
112
  - spec/inspection_spec.rb
113
+ - spec/lawyer_spec.rb
107
114
  - spec/spec_helper.rb
115
+ has_rdoc: