verifly 0.2.0.0 → 0.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +193 -0
  3. data/lib/verifly/version.rb +1 -1
  4. metadata +7 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bb480769ef6ceb801e8d09f52eb9eab8a31bd356
4
- data.tar.gz: fb911427e5d26cb1f10ae5142af217aae51110fc
3
+ metadata.gz: 7171d204c82a0f84dd0b8780dda21a0c527687e1
4
+ data.tar.gz: cec080bcb1b9e2e38a3dd3434f8f18c498293f64
5
5
  SHA512:
6
- metadata.gz: e22e09f78908ed3e451c3ce90d1e1c7d439cb1c69c8c356c4fd858ea2bbd3a071713c62666d6c74e364bc57faa61207cd3425e897b76fc834a1394f2bbe8bcb5
7
- data.tar.gz: c5f4a1fd4a51b470cc12c5b4f57086a0e526919abbbbb949ef6781d3efb2e2b6645b879a14a4866ebeecb9ffaf4bb504ab2607e6f4258d0f61aa642ef1016c39
6
+ metadata.gz: 3f8f1bcaf78681238fd4935cc831e4b5716aa937fe92caafffb4aa1762837d0091da69a891d4b33ce25126a40d3193cacb930a23e7c9ec1adf33dbfb2b73b850
7
+ data.tar.gz: 2ede721d805ba64742b50743b16952609e6c82529d0a634f82bf32b7152660becd766c687147e9ae369aa8e02211cb12b80a4da7284d950abdd147ad8f6a2fea
@@ -0,0 +1,193 @@
1
+ # Verifly v0.2
2
+ [![Build Status](https://travis-ci.org/umbrellio/verifly.svg?branch=master)](https://travis-ci.org/umbrellio/verifly)
3
+
4
+ This gem provides an api to run sequential checks like
5
+ 'ActiveModel::Validations' do, but with generic messages instead of errors.
6
+
7
+ It also provides additional components to build it which could be used
8
+ to imporve code readability. See [Applicator](#Applicator),
9
+ [ApplicatorWithOptions](#ApplicatorWithOptions) and
10
+ [ClassBuilder](#ClassBuilder) along with [Verifier](#Verifier)
11
+
12
+ ## Instalation
13
+
14
+ ```
15
+ $ gem install verifly
16
+ ```
17
+
18
+ and then in code
19
+
20
+ ```
21
+ require 'verifly'
22
+ ```
23
+
24
+ ## ClassBuilder
25
+
26
+ example:
27
+
28
+ ```lang=ruby
29
+ Abstract = Struct.new(:data)
30
+ extend Verifly::ClassBuilder::Mixin
31
+
32
+ class WithString < self
33
+ def self.build_class(x)
34
+ self if x.is_a?(String)
35
+ end
36
+ end
37
+
38
+ Generic = Class.new(self)
39
+
40
+ self.buildable_classes = [WithString, Generic]
41
+ # or, vice versa
42
+ def self.buildable_classes
43
+ [WithString, Generic]
44
+ end
45
+ end
46
+
47
+ Abstract.build("foo") # => WithString.new("foo")
48
+ Abstract.build(:foo) # => Generic.new("foo")
49
+ ```
50
+
51
+ or see it at rubydoc.info
52
+
53
+ Why don't just use Uber::Builder?
54
+ ([Uber](https://github.com/apotonick/uber) is cool, you should try it)
55
+ There are two reasons: firstly, it is an unnecessary dependency.
56
+ We dont want npm hell, do we? Uber::Builder realy does not do much work,
57
+ it's just a pattern. Secondly, this implementation looks more clear to me,
58
+ because children are deciding whether they will handle arguments, not parents.
59
+
60
+ So to use it, you have to:
61
+
62
+ 1. Write some classes with duck type `.class_builder(*args)`
63
+
64
+ 2. Invoke `Verifly::ClassBuilder.new([<%= array_of_classes %>]).call(*args)`
65
+
66
+ 3. ????
67
+
68
+ 4. PROFIT
69
+
70
+ It's simple and clear, but not very sugary. So, otherwise, you may do
71
+ following:
72
+
73
+ 1. Write an abstract class
74
+
75
+ 2. Extend `Verifly::ClassBuilder::Mixin`
76
+
77
+ 3. Inherit from the abstract class in different implementations
78
+
79
+ 4. If some implementations have common ancestors
80
+ (not including the abstract class), you can implement common ancestor's
81
+ `.build_class` in terms of super (i.e.
82
+ `def self.build_class(x); super if x.is_a?(String); end`)
83
+
84
+ 5. Change `.build_class` of other classes like `self if ...`.
85
+ Don't change default implementation's `.build_class`
86
+
87
+ 6. Setup `.buildable_classes` on the abstract class, mentioning only direct
88
+ children if you done step 4
89
+
90
+ 7. Optionally redefine `.build` in abstract class, if you want
91
+ to separate `build_class` and constructor params
92
+
93
+ 8. Use `.build` instead of `new`
94
+
95
+ ## Applicator
96
+
97
+ Applicator is designed to wrap applications of
98
+ [applicable](https://en.wikipedia.org/wiki/Sepulka) objects
99
+ around some binding in some context
100
+
101
+ example:
102
+
103
+ ```lang=ruby
104
+ object = OpenStruct.new(foo: :bar)
105
+ Applicator.call(:foo, object, {}) # => :bar
106
+ Applicator.call('foo', object, {}) # => :bar
107
+ Applicator.call('context', object, {}) # => {}
108
+ Applicator.call(-> { foo }, object, {}) # => :bar
109
+ Applicator.call(->(context) { context[foo] }, object, bar: :baz) # => :baz
110
+ Applicator.call(true, object, {}) # => true
111
+
112
+ foo = :bar
113
+ Applicator.call(:foo, binding, {}) # => :bar
114
+ Applicator.call('object.foo', binding, {}) # => :bar
115
+ ```
116
+
117
+ Applicator is good, but in most cases
118
+ [ApplicatorWithOptions](#ApplicatorWithOptions) would be a better option.
119
+
120
+ ## ApplicatorWithOptions
121
+
122
+ ApplicatorWithOptions is an applicator with options.
123
+ The options are `if: ` and `unless: `. Same as in ActiveModel::Validations,
124
+ they are applied to the same binding. Main action is executed
125
+ only if `if: ` evaluates to truthy and `unless: ` evaluates to falsey.
126
+
127
+ See examples:
128
+
129
+ ```lang=ruby
130
+ ApplicatorWithOptions.new(:foo, if: -> { true }).call(binding, {}) # => foo
131
+
132
+ ApplicatorWithOptions.new(:foo, if: -> (context) { context[:bar] })
133
+ .call(binding, { bar: true }) # => foo
134
+
135
+ ApplicatorWithOptions.new(:foo, if: { bar: true }).call(binding, :bar) # => foo
136
+
137
+ ApplicatorWithOptions.new(:foo, unless: -> { true })
138
+ .call(binding, {}) # => nil
139
+ ApplicatorWithOptions.new(:foo, unless: -> (context) { context[:bar] })
140
+ .call(binding, { bar: true }) # => foo
141
+ ApplicatorWithOptions.new(:foo, unless: { bar: true })
142
+ .call(binding, :bar) # => nil
143
+ ```
144
+
145
+ ## Verifier
146
+
147
+ The last, but the most interesting component is Verifier.
148
+ Verifiers use ApplciatorWithOptions to execute generic procedures.
149
+ Procedures should call `message!` if they want to yield something.
150
+ Note that you should implement `message!` by yourself (in terms of super)
151
+
152
+ ```lang=ruby
153
+ class MyVerifier < Verifly::Verifier
154
+ Message = Struct.new(:text)
155
+ verify :foo, if: { foo: true }
156
+
157
+ private
158
+
159
+ def message!(text)
160
+ super { Message.new(text) }
161
+ end
162
+
163
+ def foo
164
+ message!('Something is wrong') if Fixnum != Bignum
165
+ end
166
+ end
167
+ ```
168
+
169
+ In addition to Applicator's power, you also can nest your verifiers
170
+ to split the logic
171
+
172
+ ```lang=ruby
173
+ class MyVerifier < Verifly::Verifier
174
+ Message = Struct.new(:text)
175
+ verify_with ChildVerifier, if: -> (context) { cotnext[:foo] }
176
+
177
+ private
178
+
179
+ def message!(text)
180
+ super { Message.new(text) }
181
+ end
182
+ end
183
+
184
+ class ChildVerifier < MyVerifier
185
+ verify %q(message!("it's alive!"))
186
+ end
187
+ ```
188
+
189
+ ## Yard documentation
190
+
191
+ This gem uses yard to generate documentation about its API.
192
+ Visit http://www.rubydoc.info/github/umbrellio/verifly/master to see
193
+ actual documentation for master.
@@ -8,5 +8,5 @@ module Verifly
8
8
  # * a stands for public api changes
9
9
  # * b stands for private api changes
10
10
  # * c stands for patch changes (not touching public or private api)
11
- VERSION = '0.2.0.0'
11
+ VERSION = '0.2.0.1'
12
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: verifly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.0
4
+ version: 0.2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Smirnov
@@ -150,13 +150,15 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '1.1'
153
- description: 'See more info at http://www.rubydoc.info/gems/verifly/0.2.0.0 '
153
+ description: 'An api to run sequential checks like ''ActiveModel::Validations'' do,
154
+ but with generic messages instead of errors. See more info at [http://www.rubydoc.info/gems/verifly/0.2.0.1] '
154
155
  email:
155
156
  - begdory4@gmail.com
156
157
  executables: []
157
158
  extensions: []
158
159
  extra_rdoc_files: []
159
160
  files:
161
+ - README.md
160
162
  - lib/verifly.rb
161
163
  - lib/verifly/applicator.rb
162
164
  - lib/verifly/applicator_with_options.rb
@@ -166,7 +168,8 @@ files:
166
168
  homepage: https://github.com/umbrellio/verifly
167
169
  licenses:
168
170
  - MIT
169
- metadata: {}
171
+ metadata:
172
+ yard.run: yri
170
173
  post_install_message:
171
174
  rdoc_options: []
172
175
  require_paths:
@@ -186,6 +189,5 @@ rubyforge_project:
186
189
  rubygems_version: 2.5.2
187
190
  signing_key:
188
191
  specification_version: 4
189
- summary: An api to run sequential checks like 'ActiveModel::Validations' do, but with
190
- generic messages instead of errors
192
+ summary: See more info at [http://www.rubydoc.info/gems/verifly/0.2.0.1]
191
193
  test_files: []