strict 0.0.0 → 1.1.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/.rubocop.yml +14 -2
- data/Gemfile.lock +19 -2
- data/README.md +165 -6
- data/lib/strict/accessor/attributes.rb +15 -0
- data/lib/strict/accessor/module.rb +45 -0
- data/lib/strict/assignment_error.rb +25 -0
- data/lib/strict/attribute.rb +71 -0
- data/lib/strict/attributes/class.rb +17 -0
- data/lib/strict/attributes/coercer.rb +32 -0
- data/lib/strict/attributes/configuration.rb +46 -0
- data/lib/strict/attributes/dsl.rb +43 -0
- data/lib/strict/attributes/instance.rb +68 -0
- data/lib/strict/coercers/array.rb +22 -0
- data/lib/strict/coercers/hash.rb +34 -0
- data/lib/strict/dsl/coercible.rb +14 -0
- data/lib/strict/dsl/validatable.rb +28 -0
- data/lib/strict/implementation_does_not_conform_error.rb +88 -0
- data/lib/strict/initialization_error.rb +57 -0
- data/lib/strict/interface.rb +21 -0
- data/lib/strict/interfaces/instance.rb +54 -0
- data/lib/strict/method.rb +72 -0
- data/lib/strict/method_call_error.rb +72 -0
- data/lib/strict/method_definition_error.rb +46 -0
- data/lib/strict/method_return_error.rb +25 -0
- data/lib/strict/methods/configuration.rb +14 -0
- data/lib/strict/methods/dsl.rb +56 -0
- data/lib/strict/methods/module.rb +26 -0
- data/lib/strict/methods/verifiable_method.rb +158 -0
- data/lib/strict/object.rb +9 -0
- data/lib/strict/parameter.rb +63 -0
- data/lib/strict/reader/attributes.rb +15 -0
- data/lib/strict/reader/module.rb +27 -0
- data/lib/strict/return.rb +28 -0
- data/lib/strict/validators/all_of.rb +24 -0
- data/lib/strict/validators/any_of.rb +24 -0
- data/lib/strict/validators/anything.rb +20 -0
- data/lib/strict/validators/array_of.rb +24 -0
- data/lib/strict/validators/boolean.rb +20 -0
- data/lib/strict/validators/hash_of.rb +25 -0
- data/lib/strict/validators/range_of.rb +24 -0
- data/lib/strict/value.rb +22 -0
- data/lib/strict/version.rb +1 -1
- data/lib/strict.rb +1 -0
- data/strict.gemspec +41 -0
- metadata +97 -2
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module Strict
|
6
|
+
module Methods
|
7
|
+
class VerifiableMethod # rubocop:disable Metrics/ClassLength
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
class UnknownParameterError < Error
|
11
|
+
attr_reader :parameter_name
|
12
|
+
|
13
|
+
def initialize(parameter_name:)
|
14
|
+
super(message_from(parameter_name:))
|
15
|
+
|
16
|
+
@parameter_name = parameter_name
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def message_from(parameter_name:)
|
22
|
+
"Strict tried to find a parameter named #{parameter_name} but was unable. " \
|
23
|
+
"It's likely this in an internal bug, feel free to open an issue at #{Strict::ISSUE_TRACKER} for help."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def_delegator :method, :name
|
28
|
+
|
29
|
+
attr_reader :parameters, :returns
|
30
|
+
|
31
|
+
def initialize(method:, parameters:, returns:, instance:)
|
32
|
+
@method = method
|
33
|
+
@parameters = parameters
|
34
|
+
@parameters_index = parameters.to_h { |p| [p.name, p] }
|
35
|
+
@returns = returns
|
36
|
+
@instance = instance
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
"#{method.owner}#{separator}#{name}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify_definition!
|
44
|
+
expected_parameters = Set.new(parameters.map(&:name))
|
45
|
+
defined_parameters = Set.new(method.parameters.filter_map { |kind, name| name unless kind == :block })
|
46
|
+
return if expected_parameters == defined_parameters
|
47
|
+
|
48
|
+
missing_parameters = expected_parameters - defined_parameters
|
49
|
+
additional_parameters = defined_parameters - expected_parameters
|
50
|
+
raise Strict::MethodDefinitionError.new(verifiable_method: self, missing_parameters:, additional_parameters:)
|
51
|
+
end
|
52
|
+
|
53
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/BlockLength
|
54
|
+
# TODO(kkt): clean this up- it's late, though, and the tests are passing
|
55
|
+
def verify_parameters!(*args, **kwargs)
|
56
|
+
invalid_parameters = nil
|
57
|
+
missing_parameters = nil
|
58
|
+
|
59
|
+
positional_arguments = []
|
60
|
+
keyword_arguments = {}
|
61
|
+
|
62
|
+
# TODO(kkt): doesn't handle oddly sorted optional positional parameters like def foo(opt = nil, req)
|
63
|
+
method.parameters.each do |kind, name|
|
64
|
+
case kind
|
65
|
+
when POSITIONAL
|
66
|
+
parameter_kind = :positional
|
67
|
+
value = args.any? ? args.shift : NOT_PROVIDED
|
68
|
+
when REST
|
69
|
+
parameter_kind = :rest
|
70
|
+
value = [*args]
|
71
|
+
args.clear
|
72
|
+
when KEYWORD
|
73
|
+
parameter_kind = :keyword
|
74
|
+
value = kwargs.key?(name) ? kwargs.delete(name) : NOT_PROVIDED
|
75
|
+
when KEYREST
|
76
|
+
parameter_kind = :keyrest
|
77
|
+
value = { **kwargs }
|
78
|
+
kwargs.clear
|
79
|
+
end
|
80
|
+
next unless parameter_kind
|
81
|
+
|
82
|
+
parameter = parameter_named!(name)
|
83
|
+
if value.equal?(NOT_PROVIDED) && parameter.optional?
|
84
|
+
value = parameter.default_generator.call
|
85
|
+
elsif value.equal?(NOT_PROVIDED)
|
86
|
+
missing_parameters ||= []
|
87
|
+
missing_parameters << parameter.name
|
88
|
+
next
|
89
|
+
end
|
90
|
+
|
91
|
+
value = parameter.coerce(value)
|
92
|
+
if parameter.valid?(value)
|
93
|
+
case parameter_kind
|
94
|
+
when :positional
|
95
|
+
positional_arguments << value
|
96
|
+
when :rest
|
97
|
+
positional_arguments.concat(value)
|
98
|
+
when :keyword
|
99
|
+
keyword_arguments[name] = value
|
100
|
+
when :keyrest
|
101
|
+
keyword_arguments.merge!(value)
|
102
|
+
end
|
103
|
+
else
|
104
|
+
invalid_parameters ||= {}
|
105
|
+
invalid_parameters[parameter] = value
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
if args.empty? && kwargs.empty? && invalid_parameters.nil? && missing_parameters.nil?
|
110
|
+
[positional_arguments, keyword_arguments]
|
111
|
+
else
|
112
|
+
raise Strict::MethodCallError.new(
|
113
|
+
verifiable_method: self,
|
114
|
+
remaining_args: args,
|
115
|
+
remaining_kwargs: kwargs,
|
116
|
+
invalid_parameters:,
|
117
|
+
missing_parameters:
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/BlockLength
|
122
|
+
|
123
|
+
def verify_returns!(value)
|
124
|
+
value = returns.coerce(value)
|
125
|
+
return if returns.valid?(value)
|
126
|
+
|
127
|
+
raise Strict::MethodReturnError.new(verifiable_method: self, value:)
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
POSITIONAL = Set.new(%i[req opt])
|
133
|
+
private_constant :POSITIONAL
|
134
|
+
REST = :rest
|
135
|
+
private_constant :REST
|
136
|
+
KEYWORD = Set.new(%i[keyreq key])
|
137
|
+
private_constant :KEYWORD
|
138
|
+
KEYREST = :keyrest
|
139
|
+
private_constant :KEYREST
|
140
|
+
NOT_PROVIDED = ::Object.new.freeze
|
141
|
+
private_constant :NOT_PROVIDED
|
142
|
+
|
143
|
+
attr_reader :method, :parameters_index
|
144
|
+
|
145
|
+
def instance?
|
146
|
+
@instance
|
147
|
+
end
|
148
|
+
|
149
|
+
def separator
|
150
|
+
instance? ? "#" : "."
|
151
|
+
end
|
152
|
+
|
153
|
+
def parameter_named!(name)
|
154
|
+
parameters_index.fetch(name) { raise UnknownParameterError.new(parameter_name: name) }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
class Parameter
|
5
|
+
NOT_PROVIDED = ::Object.new.freeze
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def make(name, validator = Validators::Anything.instance, coerce: false, **defaults)
|
9
|
+
unless valid_defaults?(**defaults)
|
10
|
+
raise ArgumentError, "Only one of 'default', 'default_value', or 'default_generator' can be provided"
|
11
|
+
end
|
12
|
+
|
13
|
+
new(name: name.to_sym, validator:, default_generator: make_default_generator(**defaults), coercer: coerce)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def valid_defaults?(default: NOT_PROVIDED, default_value: NOT_PROVIDED, default_generator: NOT_PROVIDED)
|
19
|
+
defaults_provided = [default, default_value, default_generator].count do |default_option|
|
20
|
+
!default_option.equal?(NOT_PROVIDED)
|
21
|
+
end
|
22
|
+
|
23
|
+
defaults_provided <= 1
|
24
|
+
end
|
25
|
+
|
26
|
+
def make_default_generator(default: NOT_PROVIDED, default_value: NOT_PROVIDED, default_generator: NOT_PROVIDED)
|
27
|
+
if !default.equal?(NOT_PROVIDED)
|
28
|
+
default.respond_to?(:call) ? default : -> { default }
|
29
|
+
elsif !default_value.equal?(NOT_PROVIDED)
|
30
|
+
-> { default_value }
|
31
|
+
elsif !default_generator.equal?(NOT_PROVIDED)
|
32
|
+
default_generator
|
33
|
+
else
|
34
|
+
NOT_PROVIDED
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :name, :validator, :default_generator, :coercer
|
40
|
+
|
41
|
+
def initialize(name:, validator:, default_generator:, coercer:)
|
42
|
+
@name = name.to_sym
|
43
|
+
@validator = validator
|
44
|
+
@default_generator = default_generator
|
45
|
+
@coercer = coercer
|
46
|
+
@optional = !default_generator.equal?(NOT_PROVIDED)
|
47
|
+
end
|
48
|
+
|
49
|
+
def optional?
|
50
|
+
@optional
|
51
|
+
end
|
52
|
+
|
53
|
+
def valid?(value)
|
54
|
+
validator === value
|
55
|
+
end
|
56
|
+
|
57
|
+
def coerce(value)
|
58
|
+
return value unless coercer
|
59
|
+
|
60
|
+
coercer.call(value)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
module Reader
|
5
|
+
module Attributes
|
6
|
+
def attributes(&block)
|
7
|
+
block ||= -> {}
|
8
|
+
configuration = Strict::Attributes::Dsl.run(&block)
|
9
|
+
include Module.new(configuration)
|
10
|
+
include Strict::Attributes::Instance
|
11
|
+
extend Strict::Attributes::Class
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
module Reader
|
5
|
+
class Module < ::Module
|
6
|
+
attr_reader :configuration
|
7
|
+
|
8
|
+
def initialize(configuration)
|
9
|
+
super()
|
10
|
+
|
11
|
+
@configuration = configuration
|
12
|
+
const_set(Strict::Attributes::Class::CONSTANT, configuration)
|
13
|
+
configuration.attributes.each do |attribute|
|
14
|
+
module_eval(
|
15
|
+
"def #{attribute.name} = #{attribute.instance_variable}", # def name = @instance_variable
|
16
|
+
__FILE__,
|
17
|
+
__LINE__ - 2
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#<#{self.class} (#{configuration.attributes.map(&:name).join(', ')})>"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
class Return
|
5
|
+
class << self
|
6
|
+
def make(validator = Validators::Anything.instance, coerce: false)
|
7
|
+
new(validator:, coercer: coerce)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :validator, :coercer
|
12
|
+
|
13
|
+
def initialize(validator:, coercer:)
|
14
|
+
@validator = validator
|
15
|
+
@coercer = coercer
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid?(value)
|
19
|
+
validator === value
|
20
|
+
end
|
21
|
+
|
22
|
+
def coerce(value)
|
23
|
+
return value unless coercer
|
24
|
+
|
25
|
+
coercer.call(value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
module Validators
|
5
|
+
class AllOf
|
6
|
+
attr_reader :subvalidators
|
7
|
+
|
8
|
+
def initialize(*subvalidators)
|
9
|
+
@subvalidators = subvalidators
|
10
|
+
end
|
11
|
+
|
12
|
+
def ===(value)
|
13
|
+
subvalidators.all? do |subvalidator|
|
14
|
+
subvalidator === value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"AllOf(#{subvalidators.map(&:inspect).join(', ')})"
|
20
|
+
end
|
21
|
+
alias to_s inspect
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
module Validators
|
5
|
+
class AnyOf
|
6
|
+
attr_reader :subvalidators
|
7
|
+
|
8
|
+
def initialize(*subvalidators)
|
9
|
+
@subvalidators = subvalidators
|
10
|
+
end
|
11
|
+
|
12
|
+
def ===(value)
|
13
|
+
subvalidators.any? do |subvalidator|
|
14
|
+
subvalidator === value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"AnyOf(#{subvalidators.map(&:inspect).join(', ')})"
|
20
|
+
end
|
21
|
+
alias to_s inspect
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "singleton"
|
4
|
+
|
5
|
+
module Strict
|
6
|
+
module Validators
|
7
|
+
class Anything
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
def ===(_value)
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
"Anything()"
|
16
|
+
end
|
17
|
+
alias to_s inspect
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
module Validators
|
5
|
+
class ArrayOf
|
6
|
+
attr_reader :element_validator
|
7
|
+
|
8
|
+
def initialize(element_validator)
|
9
|
+
@element_validator = element_validator
|
10
|
+
end
|
11
|
+
|
12
|
+
def ===(value)
|
13
|
+
Array === value && value.all? do |v|
|
14
|
+
element_validator === v
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"ArrayOf(#{element_validator.inspect})"
|
20
|
+
end
|
21
|
+
alias to_s inspect
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "singleton"
|
4
|
+
|
5
|
+
module Strict
|
6
|
+
module Validators
|
7
|
+
class Boolean
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
def ===(value)
|
11
|
+
value.equal?(true) || value.equal?(false)
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
"Boolean()"
|
16
|
+
end
|
17
|
+
alias to_s inspect
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
module Validators
|
5
|
+
class HashOf
|
6
|
+
attr_reader :key_validator, :value_validator
|
7
|
+
|
8
|
+
def initialize(key_validator, value_validator)
|
9
|
+
@key_validator = key_validator
|
10
|
+
@value_validator = value_validator
|
11
|
+
end
|
12
|
+
|
13
|
+
def ===(value)
|
14
|
+
Hash === value && value.all? do |k, v|
|
15
|
+
key_validator === k && value_validator === v
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
"HashOf(#{key_validator.inspect} => #{value_validator.inspect})"
|
21
|
+
end
|
22
|
+
alias to_s inspect
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
module Validators
|
5
|
+
class RangeOf
|
6
|
+
attr_reader :element_validator
|
7
|
+
|
8
|
+
def initialize(element_validator)
|
9
|
+
@element_validator = element_validator
|
10
|
+
end
|
11
|
+
|
12
|
+
def ===(value)
|
13
|
+
Range === value && [value.begin, value.end].compact.all? do |v|
|
14
|
+
element_validator === v
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"RangeOf(#{element_validator.inspect})"
|
20
|
+
end
|
21
|
+
alias to_s inspect
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/strict/value.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Strict
|
4
|
+
module Value
|
5
|
+
def self.included(mod)
|
6
|
+
mod.extend(Reader::Attributes)
|
7
|
+
end
|
8
|
+
|
9
|
+
def with(**attributes)
|
10
|
+
self.class.new(**to_h.merge(attributes))
|
11
|
+
end
|
12
|
+
|
13
|
+
def eql?(other)
|
14
|
+
self.class.equal?(other.class) && to_h.eql?(other.to_h)
|
15
|
+
end
|
16
|
+
alias == eql?
|
17
|
+
|
18
|
+
def hash
|
19
|
+
[self.class, to_h].hash
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/strict/version.rb
CHANGED
data/lib/strict.rb
CHANGED
data/strict.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/strict/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "strict"
|
7
|
+
spec.version = Strict::VERSION
|
8
|
+
spec.authors = ["Kyle Thompson"]
|
9
|
+
spec.email = ["me@kkt.dev"]
|
10
|
+
|
11
|
+
spec.summary = "Strictly define a contract for your objects and methods"
|
12
|
+
spec.homepage = "https://github.com/kylekthompson/strict"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = ">= 3.1.2"
|
15
|
+
|
16
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
+
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
20
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
21
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
22
|
+
|
23
|
+
spec.files = Dir.chdir(__dir__) do
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_dependency "zeitwerk", "~> 2.6"
|
33
|
+
spec.add_development_dependency "debug", ">= 1.0.0"
|
34
|
+
spec.add_development_dependency "gem-release", "~> 2.2"
|
35
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
36
|
+
spec.add_development_dependency "minitest-spec-context", "~> 0.0.4"
|
37
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
38
|
+
spec.add_development_dependency "rubocop", "~> 1.21"
|
39
|
+
spec.add_development_dependency "rubocop-minitest", "~> 0.22"
|
40
|
+
spec.add_development_dependency "rubocop-rake", "~> 0.6"
|
41
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strict
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Thompson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zeitwerk
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: debug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.0.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: gem-release
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '5.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest-spec-context
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.0.4
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.0.4
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rake
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +108,34 @@ dependencies:
|
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '1.21'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-minitest
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.22'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.22'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-rake
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.6'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.6'
|
83
139
|
description:
|
84
140
|
email:
|
85
141
|
- me@kkt.dev
|
@@ -96,9 +152,48 @@ files:
|
|
96
152
|
- README.md
|
97
153
|
- Rakefile
|
98
154
|
- lib/strict.rb
|
155
|
+
- lib/strict/accessor/attributes.rb
|
156
|
+
- lib/strict/accessor/module.rb
|
157
|
+
- lib/strict/assignment_error.rb
|
158
|
+
- lib/strict/attribute.rb
|
159
|
+
- lib/strict/attributes/class.rb
|
160
|
+
- lib/strict/attributes/coercer.rb
|
161
|
+
- lib/strict/attributes/configuration.rb
|
162
|
+
- lib/strict/attributes/dsl.rb
|
163
|
+
- lib/strict/attributes/instance.rb
|
164
|
+
- lib/strict/coercers/array.rb
|
165
|
+
- lib/strict/coercers/hash.rb
|
166
|
+
- lib/strict/dsl/coercible.rb
|
167
|
+
- lib/strict/dsl/validatable.rb
|
99
168
|
- lib/strict/error.rb
|
169
|
+
- lib/strict/implementation_does_not_conform_error.rb
|
170
|
+
- lib/strict/initialization_error.rb
|
171
|
+
- lib/strict/interface.rb
|
172
|
+
- lib/strict/interfaces/instance.rb
|
173
|
+
- lib/strict/method.rb
|
174
|
+
- lib/strict/method_call_error.rb
|
175
|
+
- lib/strict/method_definition_error.rb
|
176
|
+
- lib/strict/method_return_error.rb
|
177
|
+
- lib/strict/methods/configuration.rb
|
178
|
+
- lib/strict/methods/dsl.rb
|
179
|
+
- lib/strict/methods/module.rb
|
180
|
+
- lib/strict/methods/verifiable_method.rb
|
181
|
+
- lib/strict/object.rb
|
182
|
+
- lib/strict/parameter.rb
|
183
|
+
- lib/strict/reader/attributes.rb
|
184
|
+
- lib/strict/reader/module.rb
|
185
|
+
- lib/strict/return.rb
|
186
|
+
- lib/strict/validators/all_of.rb
|
187
|
+
- lib/strict/validators/any_of.rb
|
188
|
+
- lib/strict/validators/anything.rb
|
189
|
+
- lib/strict/validators/array_of.rb
|
190
|
+
- lib/strict/validators/boolean.rb
|
191
|
+
- lib/strict/validators/hash_of.rb
|
192
|
+
- lib/strict/validators/range_of.rb
|
193
|
+
- lib/strict/value.rb
|
100
194
|
- lib/strict/version.rb
|
101
195
|
- sig/strict.rbs
|
196
|
+
- strict.gemspec
|
102
197
|
homepage: https://github.com/kylekthompson/strict
|
103
198
|
licenses:
|
104
199
|
- MIT
|