duckface-interfaces 0.0.2 → 0.0.3

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: 30396b46a38049271ab9ed210b927668e994da99
4
- data.tar.gz: 56d6a155fde25658a4e7cb1a735b0d74a6efbce2
3
+ metadata.gz: 00d6fb73ecee350b171fbcee1cc119d9dd9323cb
4
+ data.tar.gz: a17598b3ebbc212ca731e8d30f57e4caa9a10ebc
5
5
  SHA512:
6
- metadata.gz: 296f5f84390d8f29802e599678e7cd094e68dd0dd405deb91e0e081d526082ce0fa1be9b250530bdfb21d581056ab6455d1206d1686200f30982d7064a2102cd
7
- data.tar.gz: 87bcbc634568b6dd6d4764be504f55752541fb6432d29d0aa6886a1540eac79fa30973954d10b979d7a6a71e2029122a89fafb519c68040c2acb8cdaeab99946
6
+ metadata.gz: 1e9b94fe6673a539bfa4d487133e67b9c2bfe7eaaf2382f300b9a2d2791f7b10716503f785662cb79b6986495b1acfa2b6cdf62adbd601c0a55dce8df7b0c1fe
7
+ data.tar.gz: c554f1d3674e99bee366f1dd476d6434eb7801f6ac3a1a5fb3f51ed2ed03fff488605382f3115527ae012ecef9cc59cae036305b89b34b195a83f824052deebe
@@ -1,3 +1,8 @@
1
+ 0.0.3
2
+
3
+ * `Class.check_it_implements` now returns a `CheckSession`.
4
+ * RSpec shared example takes advantage of `CheckSession` to be able to present a list of reasons why your implementation sucks.
5
+
1
6
  0.0.2
2
7
 
3
8
  * Add `Class.says_it_implements?` for quickly checking whether a class says it is implementing a given interface. This doesn't perform the full method/params checking that happens on `.check_it_implements`.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckface-interfaces (0.0.1)
4
+ duckface-interfaces (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -166,4 +166,4 @@ DEPENDENCIES
166
166
  spring-watcher-listen
167
167
 
168
168
  BUNDLED WITH
169
- 1.16.1
169
+ 1.16.4
data/README.md CHANGED
@@ -75,3 +75,14 @@ describe MyImplementation
75
75
  it_behaves_like 'it implements', MyInterface
76
76
  end
77
77
  ```
78
+
79
+ If it fails you'll get messages pointing out where you've gone wrong:
80
+ ```ruby
81
+ Failures:
82
+
83
+ 1) MyImplementation behaves like it implements MyInterface correctly
84
+ Failure/Error: expect(check_session.successful?).to be(true), formatted_message(check_session)
85
+
86
+ expected to correctly implement MyInterface:
87
+ - say_my_name is not present
88
+ ```
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Duckface
4
+ class CheckSession
5
+ def initialize
6
+ @methods_not_implemented = []
7
+ @methods_with_incorrect_signatures = []
8
+ end
9
+
10
+ attr_reader :methods_not_implemented,
11
+ :methods_with_incorrect_signatures
12
+
13
+ def notice_not_implemented_method(method_name)
14
+ @methods_not_implemented << method_name
15
+ end
16
+
17
+ def notice_method_with_incorrect_signature(method_name)
18
+ @methods_with_incorrect_signatures << method_name
19
+ end
20
+
21
+ def successful?
22
+ @methods_not_implemented.empty? && @methods_with_incorrect_signatures.empty?
23
+ end
24
+
25
+ def null?
26
+ false
27
+ end
28
+
29
+ alias correctly successful?
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Duckface
4
+ class NullCheckSession
5
+ def methods_not_implemented
6
+ []
7
+ end
8
+
9
+ def methods_with_incorrect_signatures
10
+ []
11
+ end
12
+
13
+ def successful?
14
+ false
15
+ end
16
+
17
+ def null?
18
+ true
19
+ end
20
+
21
+ alias correctly successful?
22
+ end
23
+ end
@@ -2,12 +2,13 @@
2
2
 
3
3
  require 'duckface/services/check_class_implements_interface'
4
4
  require 'duckface/implementation_methods'
5
+ require 'duckface/null_check_session'
5
6
 
6
7
  module Duckface
7
8
  # Provides methods on any class to indicate usage of interfaces
8
9
  module ObjectSugar
9
10
  def check_it_implements(_interface_class)
10
- false
11
+ NullCheckSession.new
11
12
  end
12
13
 
13
14
  def says_it_implements?(_interface_class)
@@ -1,9 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ module Duckface
4
+ module RSpec
5
+ class CheckSessionFailureFormatter
6
+ def initialize(check_session)
7
+ @check_session = check_session
8
+ end
9
+
10
+ def message
11
+ return ' but it does not implement any interfaces' if @check_session.null?
12
+
13
+ ":\n#{formatted_lines}"
14
+ end
15
+
16
+ private
17
+
18
+ def formatted_lines
19
+ lines.map do |line|
20
+ " - #{line}"
21
+ end.join("\n")
22
+ end
23
+
24
+ def lines
25
+ [not_implemented_lines, incorrect_signature_lines].flatten
26
+ end
27
+
28
+ def not_implemented_lines
29
+ @check_session.methods_not_implemented.map do |method_name|
30
+ "#{method_name} is not present"
31
+ end
32
+ end
33
+
34
+ def incorrect_signature_lines
35
+ @check_session.methods_with_incorrect_signatures.map do |method_name|
36
+ "#{method_name} has an incorrect method signature"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
3
43
  RSpec.shared_examples 'it implements' do |interface_class|
4
- describe "implements interface #{interface_class.name}" do
5
- subject(:check_it_implements) { described_class.check_it_implements(interface_class) }
44
+ subject(:check_session) { described_class.check_it_implements(interface_class) }
45
+
46
+ def formatted_message(check_session)
47
+ formatted_check_session = Duckface::RSpec::CheckSessionFailureFormatter.new(check_session)
48
+ "expected to correctly implement #{described_class.name}#{formatted_check_session.message}"
49
+ end
6
50
 
7
- it { is_expected.to be true }
51
+ describe "#{interface_class} correctly" do
52
+ specify ' ' do
53
+ expect(check_session.successful?).to be(true), formatted_message(check_session)
54
+ end
8
55
  end
9
56
  end
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'duckface/errors'
4
3
  require 'duckface/method_implementation'
4
+ require 'duckface/check_session'
5
5
 
6
6
  module Duckface
7
7
  module Services
8
8
  class CheckClassImplementsInterface
9
+ extend Forwardable
10
+
9
11
  def initialize(implementation_class, interface_class)
10
12
  @implementation_class = implementation_class
11
13
  @interface_class = interface_class
14
+ @check_session = CheckSession.new
12
15
  end
13
16
 
14
17
  def perform
@@ -16,20 +19,25 @@ module Duckface
16
19
  check_method_is_implemented(method_name)
17
20
  check_method_has_correct_signature(method_name)
18
21
  end
19
- true
22
+ @check_session
20
23
  end
21
24
 
22
25
  private
23
26
 
24
27
  def check_method_is_implemented(method_name)
25
28
  return if method_implemented?(method_name)
26
- raise Errors::InterfaceMethodNotImplementedError, "##{method_name} is not implemented"
29
+
30
+ notice_not_implemented_method(method_name)
27
31
  end
28
32
 
33
+ def_delegators :@check_session,
34
+ :notice_not_implemented_method,
35
+ :notice_method_with_incorrect_signature
36
+
29
37
  def check_method_has_correct_signature(method_name)
30
38
  return if method_has_correct_signature?(method_name)
31
- raise Errors::ImplementationSignatureIncorrectError,
32
- "##{method_name} does not have the correct signature"
39
+
40
+ notice_method_with_incorrect_signature(method_name)
33
41
  end
34
42
 
35
43
  def methods_that_should_be_implemented
File without changes
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Duckface
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duckface-interfaces
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bellroy Tech Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-27 00:00:00.000000000 Z
11
+ date: 2018-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -76,16 +76,18 @@ files:
76
76
  - duckface-interfaces.gemspec
77
77
  - lib/duckface.rb
78
78
  - lib/duckface/acts_as_interface.rb
79
+ - lib/duckface/check_session.rb
79
80
  - lib/duckface/constants.rb
80
- - lib/duckface/errors.rb
81
81
  - lib/duckface/implementation_methods.rb
82
82
  - lib/duckface/method_implementation.rb
83
+ - lib/duckface/null_check_session.rb
83
84
  - lib/duckface/object_sugar.rb
84
85
  - lib/duckface/parameter_pair.rb
85
86
  - lib/duckface/parameter_pairs.rb
86
87
  - lib/duckface/rspec.rb
87
88
  - lib/duckface/services.rb
88
89
  - lib/duckface/services/check_class_implements_interface.rb
90
+ - lib/duckface/types.rb
89
91
  - lib/duckface/version.rb
90
92
  homepage: https://github.com/samuelgiles/duckface
91
93
  licenses: []
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Duckface
4
- module Errors
5
- # Raised when a class does not implement a method
6
- class InterfaceMethodNotImplementedError < NotImplementedError; end
7
- # Raised when an implementation method does not have the same signature
8
- # as the interface
9
- class ImplementationSignatureIncorrectError < NotImplementedError; end
10
- end
11
- end