gourami 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9aeeb89759c11dd7f9559824ccfd42bc6ab7755aa2d60f11b8a38e5b0db08902
4
- data.tar.gz: 80c1968c495c2cff9277b4bd51c0340bd8381874dc864d53dab711091f61443a
3
+ metadata.gz: f4786ed7265bcf16aca2b9fb9e4a695e84b6d7e31ebe5264870e8674f71a1115
4
+ data.tar.gz: dcd57424cf0af46cda99949e77051c70beb4204c4b85f82c8d4300ed229fb09b
5
5
  SHA512:
6
- metadata.gz: 97af9a59317e79d499c95b7b05f31a5089e9f56c7b7970818c22b36482de075f646f212b12e41ad4b53d9be1e967c34b08b34e55c46a90e033151f46416208dc
7
- data.tar.gz: 48979f3194878e519431c3a46deb3da5eea9dc624731483f89e8006370d84c30027445b4ac6b31f0ca91b1d669539ad79edf988c51a2d8b2f56f7877b1659cdd
6
+ metadata.gz: 6a1811ded432ac060c4461dc790e2cb08f9b7779157f6533cb8d32c9e189f1a716c0824dcc6ca8764d8bf21a2c8bbd67d1822860d11fb5f3d37979a75a03451a
7
+ data.tar.gz: 7158387f0e394fe67f165df9a8e63aa2b8889d13e26e867d74048a68c9655cded3a181e731bddc4d73d6d087e60a5b83deea899ce7a5a5cbbee5311344a35a33
@@ -0,0 +1,17 @@
1
+ name: ci
2
+ on: [push]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v2
8
+ - name: Set up Ruby
9
+ uses: ruby/setup-ruby@v1
10
+ with:
11
+ ruby-version: 2.6
12
+ - name: Install dependencies
13
+ run: bundle install
14
+ - name: Build Gem
15
+ run: gem build gourami.gemspec
16
+ - name: Run tests
17
+ run: bundle exec rake test
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.0.0
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Gourami
2
2
 
3
+ ![Github Actions CI](https://github.com/Vydia/gourami/workflows/ci/badge.svg)
4
+
3
5
  Keep your Routes, Controllers and Models thin with Plain Old Ruby Objects (PORO).
4
6
 
5
7
  ## Installation
@@ -12,7 +14,7 @@ gem 'gourami'
12
14
 
13
15
  And then execute:
14
16
 
15
- $ bundle
17
+ $ bundle install
16
18
 
17
19
  Or install it yourself as:
18
20
 
@@ -20,10 +22,10 @@ Or install it yourself as:
20
22
 
21
23
  ## Usage
22
24
 
23
- ### A Typical Gourami::Form will
25
+ ### A Typical `Gourami::Form` will
24
26
 
25
- - Define some attributes
26
- - Validate user input
27
+ - Define attributes (inputs & outputs)
28
+ - Validate input
27
29
  - Perform an action
28
30
 
29
31
  ```ruby
@@ -173,6 +175,56 @@ class UpdateFishBowl < CreateFishBowl
173
175
  end
174
176
  ```
175
177
 
178
+ #### Configure default attribute options
179
+
180
+ The following examples will result in all `:string` attributes getting the options `:strip` and `:upcase` set to `true`.
181
+
182
+ Set global defaults:
183
+
184
+ ```ruby
185
+ Gourami::Form.set_default_attribute_options(:string, upcase: true)
186
+
187
+ # Make sure to define CreateFishBowl and other forms AFTER setting default options.
188
+ class CreateFishBowl < Gourami::Form
189
+ attribute(:name, type: :string)
190
+ end
191
+
192
+ form = CreateFishBowl.new(name: "Snake Gyllenhaal")
193
+ form.name # => "SNAKE GYLLENHAAL"
194
+ ```
195
+
196
+ Instead of global defaults, you can also apply defaults to certain form classes.
197
+
198
+ Just as `attributes` are inherited by subclasses, so are `default_attribute_options`.
199
+
200
+ Set local defaults:
201
+
202
+ ```ruby
203
+ class ScreamingForm < Gourami::Form
204
+ set_default_attribute_options(:string, upcase: true)
205
+ end
206
+
207
+ class CreateScreamingFish < ScreamingForm
208
+ attribute(:name, type: :string)
209
+ end
210
+
211
+ class UpdateScreamingFish < CreateScreamingFish; end
212
+
213
+ create_form = CreateScreamingFish.new(name: "Snake Gyllenhaal")
214
+ create_form.name # => "SNAKE GYLLENHAAL"
215
+
216
+ update_form = UpdateScreamingFish.new(name: "Snake Gyllenhaal")
217
+ update_form.name # => "SNAKE GYLLENHAAL"
218
+
219
+ # Other Gourami::Forms are unaffected
220
+ class RegularForm < Gourami::Form
221
+ attribute(:name, type: :string)
222
+ end
223
+
224
+ regular_form = RegularForm.new(name: "Snake Gyllenhaal")
225
+ regular_form.name # => "Snake Gyllenhaal"
226
+ ```
227
+
176
228
  #### Extensions / Plugins
177
229
 
178
230
  ##### Gourami::Extensions::Changes
@@ -250,7 +302,7 @@ end
250
302
 
251
303
  ## Development
252
304
 
253
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
305
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests, or `rake test:watch` to automatically rerun the tests when you make code changes. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
254
306
 
255
307
  To install this gem onto your local machine, run `bundle exec rake install`.
256
308
 
@@ -9,6 +9,7 @@ module Gourami
9
9
  def inherited(klass)
10
10
  super(klass)
11
11
  klass.instance_variable_set(:@attributes, attributes.dup)
12
+ klass.instance_variable_set(:@default_attribute_options, default_attribute_options.dup)
12
13
  end
13
14
 
14
15
  # Define an attribute for the form.
@@ -25,15 +26,17 @@ module Gourami
25
26
  options = options.dup
26
27
  options[:default] = default_block if block_given?
27
28
 
29
+ options_with_defaults = merge_default_attribute_options(options)
30
+
28
31
  mixin = Module.new do |mixin|
29
- unless options[:skip_reader]
30
- if !base.attributes.key?(name) && base.instance_methods.include?(name) && !options[:override_reader]
32
+ unless options_with_defaults[:skip_reader]
33
+ if !base.attributes.key?(name) && base.instance_methods.include?(name) && !options_with_defaults[:override_reader]
31
34
  raise AttributeNameConflictError, "#{name} is already a method. To use the existing method, use `:skip_reader => true` option. To override the existing method, use `:override_reader => true` option."
32
35
  end
33
36
 
34
37
  mixin.send(:define_method, :"#{name}") do
35
38
  value = instance_variable_get(:"@#{name}")
36
- default = options[:default]
39
+ default = options_with_defaults[:default]
37
40
 
38
41
  if value.nil? && default
39
42
  default.respond_to?(:call) ? instance_exec(&default) : default
@@ -51,7 +54,7 @@ module Gourami
51
54
 
52
55
  # Define internal setter.
53
56
  mixin.send(:define_method, :"_#{name}=") do |value|
54
- instance_variable_set(:"@#{name}", setter_filter(name, value, options))
57
+ instance_variable_set(:"@#{name}", setter_filter(name, value, self.class.merge_default_attribute_options(options)))
55
58
  end
56
59
  mixin.send(:private, :"_#{name}=")
57
60
 
@@ -76,11 +79,11 @@ module Gourami
76
79
  # @option options [Class]
77
80
  # The Class of the type of this attribute. Can be any of String, Integer,
78
81
  # Float, Array, Hash or :boolean.
79
- def record(name, options = {})
82
+ def record(name, options = {}, &block)
80
83
  define_method(:record) do
81
84
  send(name)
82
85
  end
83
- attribute(name, options.merge(:skip => true, :record => true))
86
+ attribute(name, options.merge(:skip => true, :record => true), &block)
84
87
  end
85
88
 
86
89
  # Retrieve the list of attributes of the form.
@@ -90,6 +93,24 @@ module Gourami
90
93
  def attributes
91
94
  @attributes ||= {}
92
95
  end
96
+
97
+ # Useful if you want, for example, all type: :string attributes to use
98
+ # strip: true to remove whitespace padding.
99
+ def set_default_attribute_options(attr_type, options)
100
+ default_attribute_options[attr_type] = options
101
+ end
102
+
103
+ def default_attribute_options
104
+ @default_attribute_options ||= {}
105
+ end
106
+
107
+ def merge_default_attribute_options(options)
108
+ if options[:type]
109
+ default_attribute_options.fetch(options[:type], {}).merge(options)
110
+ else
111
+ options
112
+ end
113
+ end
93
114
  end
94
115
 
95
116
  # Extend ClassMethods into including class.
@@ -33,6 +33,9 @@ module Gourami
33
33
  end
34
34
 
35
35
  value = value.to_s.dup.force_encoding(Encoding::UTF_8)
36
+
37
+ # TODO: Instead of providing unconfigurable defaults like this, use
38
+ # set_default_attribute_options at the gem level or consumer level.
36
39
  value.strip! if options.fetch(:strip, true)
37
40
  value.upcase! if options.fetch(:upcase, false)
38
41
 
@@ -84,6 +87,9 @@ module Gourami
84
87
  element_type_options = {}
85
88
  end
86
89
 
90
+ element_type_options[:type] = element_type
91
+ element_type_options = self.class.merge_default_attribute_options(element_type_options) if self.class.respond_to?(:merge_default_attribute_options)
92
+
87
93
  coercer_method_name = :"coerce_#{element_type}"
88
94
 
89
95
  value.map do |array_element|
@@ -149,6 +155,9 @@ module Gourami
149
155
  value_type_options = {}
150
156
  end
151
157
 
158
+ value_type_options[:type] = value_type
159
+ value_type_options = self.class.merge_default_attribute_options(value_type_options) if self.class.respond_to?(:merge_default_attribute_options)
160
+
152
161
  value = send(:"coerce_#{value_type}", value, value_type_options) if value_type
153
162
 
154
163
  coerced_hash[key] = value
@@ -1,3 +1,3 @@
1
1
  module Gourami
2
- VERSION = "1.3.0".freeze
2
+ VERSION = "1.4.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gourami
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TSMMark
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-09 00:00:00.000000000 Z
11
+ date: 2023-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -88,8 +88,9 @@ executables: []
88
88
  extensions: []
89
89
  extra_rdoc_files: []
90
90
  files:
91
+ - ".github/workflows/ci.yml"
91
92
  - ".gitignore"
92
- - ".travis.yml"
93
+ - ".ruby-version"
93
94
  - CODE_OF_CONDUCT.md
94
95
  - Gemfile
95
96
  - LICENSE.txt
@@ -118,7 +119,7 @@ homepage: http://github.com/Vydia/gourami
118
119
  licenses:
119
120
  - MIT
120
121
  metadata: {}
121
- post_install_message:
122
+ post_install_message:
122
123
  rdoc_options: []
123
124
  require_paths:
124
125
  - lib
@@ -133,8 +134,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
134
  - !ruby/object:Gem::Version
134
135
  version: '0'
135
136
  requirements: []
136
- rubygems_version: 3.0.4
137
- signing_key:
137
+ rubygems_version: 3.4.12
138
+ signing_key:
138
139
  specification_version: 4
139
140
  summary: Keep your Routes, Controllers and Models thin.
140
141
  test_files: []
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.1.8
5
- before_install: gem install bundler -v 1.13.5