strong_interface 0.2.0 → 0.3.0
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 +4 -4
- data/CHANGELOG.md +3 -1
- data/Gemfile.lock +1 -1
- data/README.md +9 -3
- data/lib/strong_interface/parameters_validator.rb +8 -7
- data/lib/strong_interface/version.rb +1 -1
- data/lib/strong_interface.rb +14 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7010fd03e0c054d2386425b2ab26c18388ccec88c44dd3cf6ade1c74917141af
|
4
|
+
data.tar.gz: 1ea5cdba16e454fd6dc5386637d4406171db07cd03f5c1ee2850103bf2396200
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdf24793ad076bd234001d1d8f943f3d8e60d159a99cdfbb27924185d0a1305c2c02ccddd635cdb28784baf506f1d7b9c84b189cd09fe15f531cfaff4acfca76
|
7
|
+
data.tar.gz: dd20b7d35a6cbad36f92d613771b8bb14e55e7bbb5a6bbd690c7f70a441aeca7e232ad6f758f132f943abc325c2b60cdbbacdeeed20e9ac583c44529b6905323
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -32,6 +32,7 @@ Or install it yourself as:
|
|
32
32
|
|
33
33
|
```ruby
|
34
34
|
module IDog
|
35
|
+
WORD = String
|
35
36
|
def self.create(*); end
|
36
37
|
def eat(food); end
|
37
38
|
def voice; end
|
@@ -45,6 +46,8 @@ class Lessy
|
|
45
46
|
extend StrongInterface
|
46
47
|
implements IDog
|
47
48
|
|
49
|
+
WORD = 'gav'
|
50
|
+
|
48
51
|
def self.create(name)
|
49
52
|
# Creating...
|
50
53
|
end
|
@@ -54,7 +57,7 @@ class Lessy
|
|
54
57
|
end
|
55
58
|
|
56
59
|
def voice
|
57
|
-
|
60
|
+
WORD
|
58
61
|
end
|
59
62
|
end
|
60
63
|
```
|
@@ -79,7 +82,8 @@ end
|
|
79
82
|
#### Exception will be raised
|
80
83
|
|
81
84
|
```shell
|
82
|
-
StrongInterface::
|
85
|
+
StrongInterface::ImplementationError (Constant `WORD` is absent at `Lessy`)
|
86
|
+
Class method `create` is not implemented at `Lessy`
|
83
87
|
Invalid parameters at method `eat`, expected: `def eat(food)`, got: `def eat(food, water)`
|
84
88
|
```
|
85
89
|
|
@@ -92,7 +96,7 @@ If the variable is not set, the `raise` strategy will be applied.
|
|
92
96
|
|
93
97
|
#### raise (default)
|
94
98
|
|
95
|
-
This is a default strategy. When validator finds incorrect implementation, it raises the `StrongInterface::
|
99
|
+
This is a default strategy. When validator finds incorrect implementation, it raises the `StrongInterface::ImplementationError` exception,
|
96
100
|
and provides a list of methods which aren't implemented
|
97
101
|
|
98
102
|
#### log
|
@@ -105,6 +109,8 @@ even if it has this kind of a problem in code.
|
|
105
109
|
|
106
110
|
- [x] Check if methods of interfaces all exists in a class or module
|
107
111
|
- [x] Check the arguments of methods
|
112
|
+
- [x] Check constants
|
113
|
+
- [ ] Checking the privacy of methods???
|
108
114
|
- [ ] Allow optional arguments at interface methods???
|
109
115
|
|
110
116
|
## Development
|
@@ -24,16 +24,17 @@ module StrongInterface
|
|
24
24
|
return false if @interface_method_parameters.size != @klass_method_parameters.size
|
25
25
|
|
26
26
|
@interface_method_parameters.each.with_index.all? do |key, index|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
case key
|
28
|
+
when :req
|
29
|
+
%i[req opt].include? @klass_method_parameters[index]
|
30
|
+
when :keyreq
|
31
|
+
%i[keyreq key].include? @klass_method_parameters[index]
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
|
-
def description(
|
36
|
-
|
36
|
+
def description(metod)
|
37
|
+
metod.inspect.scan(/[.|#](\S+?\(.*?\))/).last.first
|
37
38
|
end
|
38
39
|
end
|
39
|
-
end
|
40
|
+
end
|
data/lib/strong_interface.rb
CHANGED
@@ -4,17 +4,18 @@ require 'strong_interface/version'
|
|
4
4
|
require 'strong_interface/parameters_validator'
|
5
5
|
|
6
6
|
module StrongInterface
|
7
|
-
|
7
|
+
ImplementationError = Class.new(StandardError)
|
8
8
|
UnknownStrategy = Class.new(StandardError)
|
9
9
|
|
10
10
|
RAISING_STRATEGIES = {
|
11
|
-
'raise' => ->(error) { raise
|
11
|
+
'raise' => ->(error) { raise ImplementationError, error },
|
12
12
|
'log' => ->(error) { Logger.new($stdout).warn { error } }
|
13
13
|
}.freeze
|
14
14
|
|
15
15
|
# @param interfaces [Module|Class|Array<Module|Class>] the list of interfaces that class or module should implements
|
16
|
-
# @raise [UnknownStrategy] if
|
17
|
-
# @raise [ImplementationError] if describing some methods of an interface has been forgotten and
|
16
|
+
# @raise [UnknownStrategy] if SI_VALIDATION_STRATEGY environment variable has wrong value
|
17
|
+
# @raise [ImplementationError] if describing some methods of an interface has been forgotten and
|
18
|
+
# SI_VALIDATION_STRATEGY environment variable is set to `raise`
|
18
19
|
def implements(interfaces)
|
19
20
|
TracePoint.trace(:end) do |t|
|
20
21
|
next if self != t.self
|
@@ -34,13 +35,19 @@ module StrongInterface
|
|
34
35
|
|
35
36
|
def validate(interfaces)
|
36
37
|
Array(interfaces).flat_map do |interface|
|
37
|
-
validate_class_methods(interface) + validate_instance_methods(interface)
|
38
|
+
validate_constants(interface) + validate_class_methods(interface) + validate_instance_methods(interface)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def validate_constants(interface)
|
43
|
+
(interface.constants - constants).map do |missing_constant|
|
44
|
+
"Constant `#{missing_constant}` is absent at `#{self}`"
|
38
45
|
end
|
39
46
|
end
|
40
47
|
|
41
48
|
def validate_class_methods(interface)
|
42
49
|
interface.methods(false).filter_map do |klass_method|
|
43
|
-
|
50
|
+
if !methods(false).include?(klass_method)
|
44
51
|
"Class method `#{klass_method}` is not implemented at `#{self}`"
|
45
52
|
else
|
46
53
|
ParametersValidator.new(interface.method(klass_method), method(klass_method)).validate
|
@@ -50,7 +57,7 @@ module StrongInterface
|
|
50
57
|
|
51
58
|
def validate_instance_methods(interface)
|
52
59
|
interface.instance_methods.filter_map do |instance_method|
|
53
|
-
|
60
|
+
if !instance_methods.include?(instance_method)
|
54
61
|
"Instance method `#{instance_method}` is not implemented at `#{self}`"
|
55
62
|
else
|
56
63
|
ParametersValidator.new(interface.instance_method(instance_method), instance_method(instance_method)).validate
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strong_interface
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Ageev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06-
|
11
|
+
date: 2022-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Simple implementation of an interface pattern for Ruby
|
14
14
|
email:
|