verifly 0.1.0.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 +7 -0
- data/lib/verifly.rb +13 -0
- data/lib/verifly/applicator.rb +205 -0
- data/lib/verifly/applicator_with_options.rb +43 -0
- data/lib/verifly/class_builder.rb +55 -0
- data/lib/verifly/verifier.rb +91 -0
- data/lib/verifly/verifier/applicator_with_options_builder.rb +74 -0
- data/lib/verifly/version.rb +12 -0
- metadata +190 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4f523cb22087d0d7c74367fd62024dcdfb54304e
|
4
|
+
data.tar.gz: 3d6c1a22923b9e3c2878cbed2dd6df65295a0405
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: eb92359f062778ff644ccd41576b4023fcfcfe0af935b0c6edcf549ec4f9e5ea439bb24f617a0003935431313762925620f2e10366bffcad860d48873862ebf7
|
7
|
+
data.tar.gz: 033ac456b04c5cfec227311a83ba3f16f32790632ee9966e103c8ea2d2d09fb36ce83642ec7ccefd9316e32ce65166188014cd613c7997b230d900b924be1ab6
|
data/lib/verifly.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Verifly provides several usefull classes, but most important
|
4
|
+
# is Verifier. Other provided classes are it's dependency.
|
5
|
+
# See README.md or their own documentation for more info about usage
|
6
|
+
module Verifly
|
7
|
+
autoload :VERSION, 'verifly/version'
|
8
|
+
|
9
|
+
autoload :Applicator, 'verifly/applicator'
|
10
|
+
autoload :ApplicatorWithOptions, 'verifly/applicator_with_options'
|
11
|
+
autoload :ClassBuilder, 'verifly/class_builder'
|
12
|
+
autoload :Verifier, 'verifly/verifier'
|
13
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verifly
|
4
|
+
# @abstract implement `#call`
|
5
|
+
# Applies "applicable" objects to given bindings
|
6
|
+
# (applicable objects are named based on their use,
|
7
|
+
# currently any object is applicable).
|
8
|
+
#
|
9
|
+
# This class uses ClassBuilder system.
|
10
|
+
# When reading the code, we suggest starting from '.call' method
|
11
|
+
# @see ClassBuilder
|
12
|
+
# @attr applicable [applicable] wrapped applicable object
|
13
|
+
class Applicator
|
14
|
+
# Proxy is used when applicable itself is an instance of Applicator.
|
15
|
+
# It just delegates #call method to applicable
|
16
|
+
# @example
|
17
|
+
# Applicator.call(Applicator.build(:foo), binding_, context)
|
18
|
+
# # => Applicator.call(:foo, binding_, context)
|
19
|
+
class Proxy < self
|
20
|
+
# @param applicable [Applicator]
|
21
|
+
# @return Proxy if applicable is an instance of Applicator
|
22
|
+
# @return [nil] otherwise
|
23
|
+
def self.build_class(applicable)
|
24
|
+
self if applicable.is_a?(Applicator)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param binding_ [#instance_exec] target to apply applicable
|
28
|
+
# @param context additional info to send it to applicable
|
29
|
+
# @return application result
|
30
|
+
def call(binding_, context)
|
31
|
+
applicable.call(binding_, context)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# MethodExtractor is used when applicable is a symbol.
|
36
|
+
# It extracts extracts method from binding_ and executes it on binding_
|
37
|
+
# (so it works just like send except it sends nothing
|
38
|
+
# when method arity is zero).
|
39
|
+
# @example
|
40
|
+
# Applicator.call(Applicator.build(:foo), User.new, context)
|
41
|
+
# # => User.new.foo(context)
|
42
|
+
# # or => User.new.foo, if it does not accept context
|
43
|
+
class MethodExtractor < self
|
44
|
+
# @param applicable [Symbol]
|
45
|
+
# @return MethodExtractor if applicable is Symbol
|
46
|
+
# @return [nil] otherwise
|
47
|
+
def self.build_class(applicable)
|
48
|
+
self if applicable.is_a?(Symbol)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @param binding_ [#instance_exec] target to apply applicable
|
52
|
+
# @param context additional info to send it to applicable
|
53
|
+
# @return application result
|
54
|
+
def call(binding_, context)
|
55
|
+
if binding_.is_a?(Binding)
|
56
|
+
call_on_binding(binding_, context)
|
57
|
+
else
|
58
|
+
invoke_lambda(binding_.method(applicable), binding_, context)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# When Binding is target, we have to respect both methods and variables
|
65
|
+
# @param binding_ [Binding] target to apply applicable
|
66
|
+
# @param context additional info to send it to applicable
|
67
|
+
# @return application result
|
68
|
+
def call_on_binding(binding_, context)
|
69
|
+
if binding_.receiver.respond_to?(applicable)
|
70
|
+
invoke_lambda(binding_.receiver.method(applicable), binding_, context)
|
71
|
+
else
|
72
|
+
binding_.local_variable_get(applicable)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# InstanceEvaluator is used for string. It works like instance_eval or
|
78
|
+
# Binding#eval depending on binding_ class
|
79
|
+
# @example
|
80
|
+
# Applicator.call('foo if context[:foo]', binding_, context)
|
81
|
+
# # => foo if context[:foo]
|
82
|
+
class InstanceEvaluator < self
|
83
|
+
# @param applicable [String]
|
84
|
+
# @return InstanceEvaluator if applicable is String
|
85
|
+
# @return [nil] otherwise
|
86
|
+
def self.build_class(applicable)
|
87
|
+
self if applicable.is_a?(String)
|
88
|
+
end
|
89
|
+
|
90
|
+
# @param binding_ [#instance_exec] target to apply applicable
|
91
|
+
# @param context additional info to send it to applicable
|
92
|
+
# @return application result
|
93
|
+
def call(binding_, context)
|
94
|
+
if binding_.is_a?(Binding)
|
95
|
+
binding_ = binding_.dup
|
96
|
+
binding_.local_variable_set(:context, context)
|
97
|
+
binding_.eval(applicable, *caller_line)
|
98
|
+
else
|
99
|
+
binding_.instance_eval(applicable, *caller_line)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [String, Integer]
|
104
|
+
# file and line where `Applicator.call` was called
|
105
|
+
def caller_line
|
106
|
+
offset = 2
|
107
|
+
backtace_line = caller(offset..offset)[0]
|
108
|
+
_, file, line = backtace_line.match(/\A(.+):(\d+):[^:]+\z/).to_a
|
109
|
+
[file, Integer(line)]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# ProcApplicatior is used when #to_proc is available.
|
114
|
+
# It works not just with procs, but also with hashes etc
|
115
|
+
# @example with proc
|
116
|
+
# Applicator.call(-> { foo }, binding_, context) # => foo
|
117
|
+
# @example with hash
|
118
|
+
# Applicator.call(Hash[foo: true], binding_, :foo) # => true
|
119
|
+
# Applicator.call(Hash[foo: true], binding_, :bar) # => nil
|
120
|
+
class ProcApplicatior < self
|
121
|
+
# @param applicable [#to_proc]
|
122
|
+
# @return ProcApplicatior if applicable accepts #to_proc
|
123
|
+
# @return [nil] otherwise
|
124
|
+
def self.build_class(applicable)
|
125
|
+
self if applicable.respond_to?(:to_proc)
|
126
|
+
end
|
127
|
+
|
128
|
+
# @param binding_ [#instance_exec] target to apply applicable
|
129
|
+
# @param context additional info to send it to applicable
|
130
|
+
# @return application result
|
131
|
+
def call(binding_, context)
|
132
|
+
invoke_lambda(applicable.to_proc, binding_, context)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Quoter is used when there is no other way to apply applicatable.
|
137
|
+
# @example
|
138
|
+
# Applicator.call(true, binding_, context) # => true
|
139
|
+
class Quoter < self
|
140
|
+
# @return applicable without changes
|
141
|
+
def call(*)
|
142
|
+
applicable
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
extend ClassBuilder::Mixin
|
147
|
+
|
148
|
+
self.buildable_classes =
|
149
|
+
[Proxy, MethodExtractor, InstanceEvaluator, ProcApplicatior, Quoter]
|
150
|
+
|
151
|
+
attr_accessor :applicable
|
152
|
+
|
153
|
+
# Applies applicable on binding_ with context
|
154
|
+
# @todo add @see #initialize when it's todo done
|
155
|
+
# @param applicable [applicable]
|
156
|
+
# see examples in defenitions of sublcasses
|
157
|
+
# @param binding_ [#instance_exec]
|
158
|
+
# where should applicable be applied. It could be either a generic object,
|
159
|
+
# where it would be `instance_exec`uted, or a binding_
|
160
|
+
# @param context
|
161
|
+
# geneneric data you want to pass to applicable function.
|
162
|
+
# If applicable cannot accept params, context will not be sent
|
163
|
+
# @return application result
|
164
|
+
def self.call(applicable, binding_, context)
|
165
|
+
build(applicable).call(binding_, context)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Always use build instead of new
|
169
|
+
# @todo add more examples right here
|
170
|
+
# @param applicable [applicable]
|
171
|
+
# see examples in sublcasses defenitions
|
172
|
+
# @api private
|
173
|
+
def initialize(applicable)
|
174
|
+
self.applicable = applicable
|
175
|
+
end
|
176
|
+
|
177
|
+
# @param [Applicator] other
|
178
|
+
# @return [Boolean] true if applicable matches, false otherwise
|
179
|
+
def ==(other)
|
180
|
+
applicable == other.applicable
|
181
|
+
end
|
182
|
+
|
183
|
+
# @!method call(binding_, context)
|
184
|
+
# @abstract
|
185
|
+
# Applies applicable on binding_ with context
|
186
|
+
# @param binding_ [#instance_exec] binding to be used for applying
|
187
|
+
# @param context param that will be passed if requested
|
188
|
+
# @return application result
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
# invokes lambda respecting it's arity
|
193
|
+
# @param [Proc] lambda
|
194
|
+
# @param binding_ [#instance_exec] binding_ would be used in application
|
195
|
+
# @param context param would be passed if lambda arity > 0
|
196
|
+
# @return invocation result
|
197
|
+
def invoke_lambda(lambda, binding_, context)
|
198
|
+
if lambda.arity.zero?
|
199
|
+
binding_.instance_exec(&lambda)
|
200
|
+
else
|
201
|
+
binding_.instance_exec(context, &lambda)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verifly
|
4
|
+
# An applicator with useful options
|
5
|
+
# @example if
|
6
|
+
# ApplicatorWithOptions.new(action, if: true)
|
7
|
+
# @example unless
|
8
|
+
# ApplicatorWithOptions.new(action, unless: false)
|
9
|
+
# @attr action [Applicator]
|
10
|
+
# main action to apply on call
|
11
|
+
# @attr if_condition [Applicator]
|
12
|
+
# main action only apply if this applies to truthy value
|
13
|
+
# @attr unless_condition [Applicator]
|
14
|
+
# main action only apply if this applies to falsey value
|
15
|
+
class ApplicatorWithOptions
|
16
|
+
attr_accessor :action, :if_condition, :unless_condition
|
17
|
+
|
18
|
+
# @param action [applicable] main action
|
19
|
+
# @option options [applicable] :if
|
20
|
+
# main action only apply if this applies to truthy value
|
21
|
+
# @option options [applicable] :unless
|
22
|
+
# main action only apply if this applies to falsey value
|
23
|
+
def initialize(action, **options)
|
24
|
+
self.action = Applicator.build(action)
|
25
|
+
self.if_condition = Applicator.build(options.fetch(:if, true))
|
26
|
+
self.unless_condition = Applicator.build(options.fetch(:unless, false))
|
27
|
+
end
|
28
|
+
|
29
|
+
# Applies main action if if_condition applyd to truthy value
|
30
|
+
# and unless_condition applyd to falsey value
|
31
|
+
# @param binding_ [#instance_exec]
|
32
|
+
# binding to apply (see Applicator)
|
33
|
+
# @param context
|
34
|
+
# generic context to apply (see Applicator)
|
35
|
+
# @return main action application result
|
36
|
+
# @return [nil] if condition checks failed
|
37
|
+
def call(binding_, context)
|
38
|
+
return unless if_condition.call(binding_, context)
|
39
|
+
return if unless_condition.call(binding_, context)
|
40
|
+
action.call(binding_, context)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verifly
|
4
|
+
# ClassBuilder is something like Uber::Builder, but it
|
5
|
+
# allows the child classes to decide whether they will be used.
|
6
|
+
# I find it much more OOPish
|
7
|
+
# @attr klasses [Array(Class)]
|
8
|
+
# classes to iterate during search of most suitable
|
9
|
+
class ClassBuilder
|
10
|
+
# Mixin provides useful methods to integrate builder subsystem.
|
11
|
+
# Feel free to override or just never include it.
|
12
|
+
# @attr_writer [Array(Class)] buildable_classes
|
13
|
+
# Array of classes which will be checked if they
|
14
|
+
# suite constructor arguments. Order matters
|
15
|
+
module Mixin
|
16
|
+
# Array of classes which would be checked if they
|
17
|
+
# suite constructor arguments. Order matters
|
18
|
+
# @param klasses [Array(Class)]
|
19
|
+
def buildable_classes=(klasses)
|
20
|
+
@class_builder = ClassBuilder.new(klasses).freeze
|
21
|
+
end
|
22
|
+
|
23
|
+
# Default implementation of build_class. Feel free to change
|
24
|
+
# You also have to override it in buildable_classes
|
25
|
+
def build_class(*args, &block)
|
26
|
+
if @class_builder
|
27
|
+
@class_builder.call(*args, &block)
|
28
|
+
else
|
29
|
+
self
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Default implementation.
|
34
|
+
# This method should be used instead of new in all cases
|
35
|
+
def build(*arguments, &block)
|
36
|
+
build_class(*arguments, &block).new(*arguments, &block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_accessor :klasses
|
41
|
+
|
42
|
+
# @param klasses [Array(Classes)]
|
43
|
+
def initialize(klasses)
|
44
|
+
self.klasses = klasses
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Class] first nonzero class returned by .build_class
|
48
|
+
def call(*arguments, &block)
|
49
|
+
klasses.each do |klass|
|
50
|
+
result = klass.build_class(*arguments, &block)
|
51
|
+
return result if result
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verifly
|
4
|
+
# Verifier is a proto-validator class, which allows to
|
5
|
+
# use generic messages formats (instead of errors, which are raw text)
|
6
|
+
# @abstract
|
7
|
+
# implement `#message!` method in terms of super
|
8
|
+
# @attr model
|
9
|
+
# Generic object to be verified
|
10
|
+
# @attr messages [Array]
|
11
|
+
# Array with all messages yielded by the verifier
|
12
|
+
class Verifier
|
13
|
+
autoload :ApplicatorWithOptionsBuilder,
|
14
|
+
'verifly/verifier/applicator_with_options_builder'
|
15
|
+
|
16
|
+
attr_accessor :model, :messages
|
17
|
+
|
18
|
+
# @example with block
|
19
|
+
# verify { |context| message!() if context[:foo] }
|
20
|
+
# @example with proc
|
21
|
+
# verify -> (context) { message!() if context[:foo] }
|
22
|
+
# @example with hash
|
23
|
+
# verify -> { message!() } if: { foo: true }
|
24
|
+
# @example cotnext could be ommited from lambda params
|
25
|
+
# verify -> { message!() }, if: -> (context) { context[:foo] }
|
26
|
+
# @example with symbol
|
27
|
+
# verify :foo, if: :bar
|
28
|
+
# # calls #foo if #bar is true
|
29
|
+
# # bar could either accept context or not
|
30
|
+
# @example with string
|
31
|
+
# verify 'message!() if context[:foo]'
|
32
|
+
# verify 'message!()', if: 'context[:foo]'
|
33
|
+
# @example with descedant
|
34
|
+
# verify DescendantClass
|
35
|
+
# # calls DescendantClass.call(model, context) and merges it's messages
|
36
|
+
# @param verifier [#to_proc|Symbol|String|Class|nil]
|
37
|
+
# verifier defenition, see examples
|
38
|
+
# @option options [#to_proc|Symbol|String|nil] if (true)
|
39
|
+
# call verifier if only block invocation result is truthy
|
40
|
+
# @option options [#to_proc|Symbol|String|nil] unless (false)
|
41
|
+
# call verifier if only block invocation result is falsey
|
42
|
+
# @yield context on `#verfify!` calls
|
43
|
+
# @return [Array] list of all verifiers already defined
|
44
|
+
def self.verify(*args, &block)
|
45
|
+
bound_applicators <<
|
46
|
+
ApplicatorWithOptionsBuilder.call(self, *args, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Array(ApplicatorWithOptions)]
|
50
|
+
# List of applicators, bound by .verify
|
51
|
+
def self.bound_applicators
|
52
|
+
@bound_applicators ||= []
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param model generic model to validate
|
56
|
+
# @param context context in which it would be valdiated
|
57
|
+
# @return [Array] list of messages yielded by verifier
|
58
|
+
def self.call(model, context = {})
|
59
|
+
new(model).verify!(context)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param model generic model to validate
|
63
|
+
def initialize(model)
|
64
|
+
self.model = model
|
65
|
+
self.messages = []
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param context context in which model would be valdiated
|
69
|
+
# @return [Array] list of messages yielded by verifier
|
70
|
+
def verify!(context = {})
|
71
|
+
self.messages = []
|
72
|
+
|
73
|
+
self.class.bound_applicators.each do |bound_applicator|
|
74
|
+
bound_applicator.call(self, context)
|
75
|
+
end
|
76
|
+
|
77
|
+
messages
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# @abstract
|
83
|
+
# implement it like `super { Message.new(status, text, description) }`
|
84
|
+
# @return new message (yield result)
|
85
|
+
def message!(*)
|
86
|
+
new_message = yield
|
87
|
+
@messages << new_message
|
88
|
+
new_message
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verifly
|
4
|
+
class Verifier
|
5
|
+
# Builds ApplicatorWithOptions from different invocation styles.
|
6
|
+
# @api private
|
7
|
+
# @attr base [Class]
|
8
|
+
# class for which applicator_with_options should be built
|
9
|
+
# @attr args [Array]
|
10
|
+
# array of arguments Verifier.verify invoked with
|
11
|
+
# @attr block [Proc]
|
12
|
+
# block Verifier.verify invoked with
|
13
|
+
ApplicatorWithOptionsBuilder = Struct.new(:base, :args, :block)
|
14
|
+
class ApplicatorWithOptionsBuilder
|
15
|
+
# @!method self.call(base)
|
16
|
+
# transforms `verify` arguments to class attributes
|
17
|
+
# and invokes calculation
|
18
|
+
# @raise [ArgumentError]
|
19
|
+
# @return [ApplicatorWithOptions] resulting applicator_with_options
|
20
|
+
def self.call(base, *args, &block)
|
21
|
+
new(base, args, block).call
|
22
|
+
end
|
23
|
+
|
24
|
+
# Tries different invocation styles until one matches
|
25
|
+
# @see #try_block
|
26
|
+
# @see #try_nesting
|
27
|
+
# @see #default
|
28
|
+
# @raise [ArgumentError]
|
29
|
+
# @return [ApplicatorWithOptions] resulting applicator_with_options
|
30
|
+
def call
|
31
|
+
try_block || try_nesting || default
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# @example with options
|
37
|
+
# verify(if: true) { ... }
|
38
|
+
# @example without options
|
39
|
+
# verify { ... }
|
40
|
+
# @return [ApplicatorWithOptions]
|
41
|
+
def try_block
|
42
|
+
ApplicatorWithOptions.new(block, *args) if block
|
43
|
+
end
|
44
|
+
|
45
|
+
# @example correct
|
46
|
+
# verify SubVerifier
|
47
|
+
# @example incorrect
|
48
|
+
# verify Class
|
49
|
+
# @raise [ArgumentError]
|
50
|
+
# @return [ApplicatorWithOptions]
|
51
|
+
def try_nesting
|
52
|
+
verifier, *rest = args
|
53
|
+
return unless verifier.is_a?(Class)
|
54
|
+
raise ArgumentError, <<~ERROR unless verifier < base
|
55
|
+
Nested verifiers should be inherited from verifier they nested are in
|
56
|
+
ERROR
|
57
|
+
|
58
|
+
applicable = lambda do |context|
|
59
|
+
messages.concat(verifier.call(model, context))
|
60
|
+
end
|
61
|
+
|
62
|
+
ApplicatorWithOptions.new(applicable, *rest)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Simply passes args to ApplicatorWithOptions
|
66
|
+
# @example
|
67
|
+
# verify(:foo, unless: false)
|
68
|
+
# @return [ApplicatorWithOptions]
|
69
|
+
def default
|
70
|
+
ApplicatorWithOptions.new(*args)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Verifly
|
4
|
+
# Specifies Verifly version
|
5
|
+
#
|
6
|
+
# Semantical naming: 0.a.b.c where
|
7
|
+
# * 0 is for unreleased
|
8
|
+
# * a is for public api changes
|
9
|
+
# * b is for private api changes
|
10
|
+
# * c is for changes, not changing private api
|
11
|
+
VERSION = '0.1.0.0'
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: verifly
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Smirnov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.14'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.5'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.48'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.48'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.9.8
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.9.8
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: launchy
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.4'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.4'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: coveralls
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.8.19
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.8.19
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.15'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.15'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rspec-its
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1.1'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '1.1'
|
153
|
+
description: ''
|
154
|
+
email:
|
155
|
+
- begdory4@gmail.com
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- lib/verifly.rb
|
161
|
+
- lib/verifly/applicator.rb
|
162
|
+
- lib/verifly/applicator_with_options.rb
|
163
|
+
- lib/verifly/class_builder.rb
|
164
|
+
- lib/verifly/verifier.rb
|
165
|
+
- lib/verifly/verifier/applicator_with_options_builder.rb
|
166
|
+
- lib/verifly/version.rb
|
167
|
+
homepage: http://example.com
|
168
|
+
licenses: []
|
169
|
+
metadata: {}
|
170
|
+
post_install_message:
|
171
|
+
rdoc_options: []
|
172
|
+
require_paths:
|
173
|
+
- lib
|
174
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - ">="
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
requirements: []
|
185
|
+
rubyforge_project:
|
186
|
+
rubygems_version: 2.5.2
|
187
|
+
signing_key:
|
188
|
+
specification_version: 4
|
189
|
+
summary: ''
|
190
|
+
test_files: []
|