duckpond 1.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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: