verifly 0.2.0.0 → 0.2.0.1

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.
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: []