reform 2.3.0.rc1 → 2.3.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +30 -0
  4. data/.rubocop_todo.yml +460 -0
  5. data/.travis.yml +26 -11
  6. data/CHANGES.md +25 -2
  7. data/Gemfile +6 -3
  8. data/ISSUE_TEMPLATE.md +1 -1
  9. data/README.md +2 -4
  10. data/Rakefile +18 -9
  11. data/lib/reform/contract.rb +7 -7
  12. data/lib/reform/contract/custom_error.rb +41 -0
  13. data/lib/reform/contract/validate.rb +9 -5
  14. data/lib/reform/errors.rb +27 -15
  15. data/lib/reform/form.rb +22 -11
  16. data/lib/reform/form/call.rb +1 -1
  17. data/lib/reform/form/composition.rb +2 -2
  18. data/lib/reform/form/dry.rb +10 -86
  19. data/lib/reform/form/dry/input_hash.rb +37 -0
  20. data/lib/reform/form/dry/new_api.rb +58 -0
  21. data/lib/reform/form/dry/old_api.rb +61 -0
  22. data/lib/reform/form/populator.rb +9 -11
  23. data/lib/reform/form/prepopulate.rb +3 -2
  24. data/lib/reform/form/validate.rb +19 -12
  25. data/lib/reform/result.rb +36 -9
  26. data/lib/reform/validation.rb +10 -8
  27. data/lib/reform/validation/groups.rb +2 -3
  28. data/lib/reform/version.rb +1 -1
  29. data/reform.gemspec +10 -9
  30. data/test/benchmarking.rb +10 -11
  31. data/test/call_new_api.rb +23 -0
  32. data/test/{call_test.rb → call_old_api.rb} +3 -3
  33. data/test/changed_test.rb +7 -7
  34. data/test/coercion_test.rb +50 -18
  35. data/test/composition_new_api.rb +186 -0
  36. data/test/{composition_test.rb → composition_old_api.rb} +23 -26
  37. data/test/contract/custom_error_test.rb +55 -0
  38. data/test/contract_new_api.rb +77 -0
  39. data/test/{contract_test.rb → contract_old_api.rb} +8 -8
  40. data/test/default_test.rb +1 -1
  41. data/test/deserialize_test.rb +8 -11
  42. data/test/errors_new_api.rb +225 -0
  43. data/test/errors_old_api.rb +230 -0
  44. data/test/feature_test.rb +7 -9
  45. data/test/fixtures/dry_error_messages.yml +5 -2
  46. data/test/fixtures/dry_new_api_error_messages.yml +104 -0
  47. data/test/form_new_api.rb +57 -0
  48. data/test/{form_test.rb → form_old_api.rb} +2 -2
  49. data/test/form_option_new_api.rb +24 -0
  50. data/test/{form_option_test.rb → form_option_old_api.rb} +1 -1
  51. data/test/from_test.rb +8 -12
  52. data/test/inherit_new_api.rb +105 -0
  53. data/test/{inherit_test.rb → inherit_old_api.rb} +10 -17
  54. data/test/module_new_api.rb +137 -0
  55. data/test/{module_test.rb → module_old_api.rb} +19 -15
  56. data/test/parse_option_test.rb +5 -5
  57. data/test/parse_pipeline_test.rb +2 -2
  58. data/test/populate_new_api.rb +304 -0
  59. data/test/{populate_test.rb → populate_old_api.rb} +28 -34
  60. data/test/populator_skip_test.rb +1 -2
  61. data/test/prepopulator_test.rb +5 -6
  62. data/test/read_only_test.rb +12 -1
  63. data/test/readable_test.rb +5 -5
  64. data/test/reform_new_api.rb +204 -0
  65. data/test/{reform_test.rb → reform_old_api.rb} +17 -23
  66. data/test/save_new_api.rb +101 -0
  67. data/test/{save_test.rb → save_old_api.rb} +10 -13
  68. data/test/setup_test.rb +6 -6
  69. data/test/{skip_if_test.rb → skip_if_new_api.rb} +20 -9
  70. data/test/skip_if_old_api.rb +92 -0
  71. data/test/skip_setter_and_getter_test.rb +2 -3
  72. data/test/test_helper.rb +13 -5
  73. data/test/validate_new_api.rb +408 -0
  74. data/test/{validate_test.rb → validate_old_api.rb} +43 -53
  75. data/test/validation/dry_validation_new_api.rb +826 -0
  76. data/test/validation/{dry_validation_test.rb → dry_validation_old_api.rb} +223 -116
  77. data/test/validation/result_test.rb +20 -22
  78. data/test/validation_library_provided_test.rb +3 -3
  79. data/test/virtual_test.rb +46 -6
  80. data/test/writeable_test.rb +7 -7
  81. metadata +101 -51
  82. data/test/errors_test.rb +0 -180
  83. data/test/readonly_test.rb +0 -14
@@ -2,16 +2,31 @@ language: ruby
2
2
  cache: bundler
3
3
  bundler_args: --without benchmarks tools
4
4
  rvm:
5
- - 2.1.10
6
- - 2.2.5
7
- - 2.3.1
8
- - 2.4.0
5
+ - ruby-head
6
+ - 2.5
7
+ - 2.4
8
+ env:
9
+ - "DRY_VALIDATION='~> 1.3.0'"
10
+ - "DRY_VALIDATION='~> 1.2.0'"
11
+ - "DRY_VALIDATION='~> 1.1.0'"
12
+ - "DRY_VALIDATION='~> 1.0.0'"
13
+ - "DRY_VALIDATION='~> 0.13.0'"
14
+ - "DRY_VALIDATION='~> 0.12.0'"
9
15
  matrix:
10
16
  fast_finish: true
11
- notifications:
12
- webhooks:
13
- urls:
14
- - https://webhooks.gitter.im/e/680e86d98056f2ae2fd7
15
- on_success: change # options: [always|never|change] default: always
16
- on_failure: always # options: [always|never|change] default: always
17
- on_start: never # options: [always|never|change] default: always
17
+ allow_failures:
18
+ - rvm: ruby-head
19
+ include:
20
+ - { rvm: 2.2, env: "DRY_VALIDATION='~> 0.11.0'" }
21
+ - { rvm: 2.3, env: "DRY_VALIDATION='~> 0.12.0'" }
22
+ - { rvm: 2.3, env: "DRY_VALIDATION='~> 0.13.0'" }
23
+
24
+
25
+ # maybe move this to slack in a private channel
26
+ # notifications:
27
+ # webhooks:
28
+ # urls:
29
+ # - https://webhooks.gitter.im/e/680e86d98056f2ae2fd7
30
+ # on_success: change # options: [always|never|change] default: always
31
+ # on_failure: always # options: [always|never|change] default: always
32
+ # on_start: never # options: [always|never|change] default: always
data/CHANGES.md CHANGED
@@ -17,10 +17,33 @@ You can upgrade from 2.2.0 without worries.
17
17
  * Reform now maintains a generic `Dry::Schema` class for global schema configuration. Can be overridden via `::validation`.
18
18
  * When validating with dry-validation, we now pass a symbolized hash. We also replaced `Dry::Validation::Form` with `Schema` which won't coerce values where it shouldn't.
19
19
  * [private] `Group#call` API now is: `call(form, errors)`.
20
- * Removed `Form#valid?`.
21
-
20
+ * Modify `Form#valid?` - simply calls `validate({})`.
22
21
  * In `:if` for validation groups, you now get a hash of result objects, not just true/false.
22
+ * Allow adding a custom error AFTER validate has been already called
23
+
24
+ Compatibility with `dry-validation` with 1.x:
25
+ * [CHANGE] seems like "custom" predicate are not supported by `dry-schema` anymore or better the same result is reached using the `rule` method:
26
+ Something like this:
27
+ ```ruby
28
+ validation do
29
+ def a_song?(value)
30
+ value == :really_cool_song
31
+ end
23
32
 
33
+ required(:songs).filled(:a_song?)
34
+ end
35
+ ```
36
+ will be something like:
37
+ ```ruby
38
+ validation do
39
+ required(:songs).filled
40
+
41
+ rule(:songs) do
42
+ key.failure(:a_song?) unless value == :really_cool_song
43
+ end
44
+ end
45
+ ```
46
+ * [BREAKING] inheriting/merging/overriding schema/rules is not supported by `dry-v` so the `inherit:` option is **NOT SUPPORTED** for now. Also extend a `schema:` option using a block is **NOT SUPPORTED** for now. Possible workaround is to use reform module to compose different validations but this won't override existing validations but just merge them
24
47
 
25
48
  ## 2.2.4
26
49
 
data/Gemfile CHANGED
@@ -1,8 +1,11 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem "minitest-line"
6
- gem 'byebug'
7
5
  # gem "disposable", path: "../disposable"
8
6
 
7
+ # just trying to add `dry-monads` correct version in base on dry-validation
8
+ dry_v_version = ENV.fetch('DRY_VALIDATION', '~> 0.13.0')
9
+ dry_m_version = "~> #{dry_v_version.gsub("~>", "").to_f}.0"
10
+ gem 'dry-monads', dry_m_version if dry_v_version.gsub("~>", "").to_f >= 1
11
+ gem 'dry-validation', ENV.fetch('DRY_VALIDATION', '~> 0.13.0')
@@ -1,6 +1,6 @@
1
1
  Note: If you have a question about Reform, would like help using
2
2
  Reform, want to request a feature, or do anything else other than
3
- submit a bug report, please use the Trailblazer gitter channel.
3
+ submit a bug report, please use the [Trailblazer gitter channel](https://gitter.im/trailblazer/chat).
4
4
 
5
5
  Note: Rails/ ActiveRecord/ ActiveModel support.
6
6
  As of Reform 2.2.0 all Rails/ Active-* code was moved to the [reform-rails](https://github.com/trailblazer/reform-rails) gem.
data/README.md CHANGED
@@ -315,16 +315,14 @@ AlbumForm.new(album: album, cd: CD.find(1))
315
315
 
316
316
  Reform comes many more optional features, like hash fields, coercion, virtual fields, and so on. Check the [full documentation here](http://trailblazer.to/gems/reform).
317
317
 
318
- <a href="https://leanpub.com/trailblazer">
319
- ![](http://trailblazer.to/images/3dbuch-freigestellt.png)
320
- </a>
318
+ [![](http://trailblazer.to/images/3dbuch-freigestellt.png)](https://leanpub.com/trailblazer)
321
319
 
322
320
  Reform is part of the [Trailblazer project](http://trailblazer.to). Please [buy my book](https://leanpub.com/trailblazer) to support the development and learn everything about Reform - there's two chapters dedicated to Reform!
323
321
 
324
322
 
325
323
  ## Security And Strong_parameters
326
324
 
327
- By explicitely defining the form layout using `::property` there is no more need for protecting from unwanted input. `strong_parameter` or `attr_accessible` become obsolete. Reform will simply ignore undefined incoming parameters.
325
+ By explicitly defining the form layout using `::property` there is no more need for protecting from unwanted input. `strong_parameter` or `attr_accessible` become obsolete. Reform will simply ignore undefined incoming parameters.
328
326
 
329
327
  ## This is not Reform 1.x!
330
328
 
data/Rakefile CHANGED
@@ -1,15 +1,24 @@
1
1
  require "bundler/gem_tasks"
2
- require 'rake/testtask'
2
+ require "rake/testtask"
3
+ require "rubocop/rake_task"
3
4
 
4
- task :default => [:test]
5
- Rake::TestTask.new(:test) do |test|
6
- test.libs << 'test'
7
- test.test_files = FileList['test/*_test.rb'] + FileList["test/validation/*_test.rb"]
8
- test.verbose = true
5
+ task default: %i[test]
6
+
7
+ TEST_WITH_OLD_AND_NEW_API = %w[
8
+ validation/dry_validation call composition contract errors inherit module reform
9
+ save skip_if populate validate form
10
+ ].freeze
11
+
12
+ def dry_v_test_files
13
+ dry_v_version = ENV.fetch("DRY_VALIDATION", "~> 0.13.0")
14
+ api = dry_v_version.gsub("~>", "").to_f >= 1.0 ? "new" : "old"
15
+ TEST_WITH_OLD_AND_NEW_API.map { |file| "test/#{file}_#{api}_api.rb" }
9
16
  end
10
17
 
11
- Rake::TestTask.new(:test_rails) do |test|
12
- test.libs << 'test'
13
- test.test_files = FileList['test/rails/*_test.rb']
18
+ Rake::TestTask.new(:test) do |test|
19
+ test.libs << "test"
20
+ test.test_files = FileList["test/*_test.rb"] + FileList["test/validation/*_test.rb"] + dry_v_test_files
14
21
  test.verbose = true
15
22
  end
23
+
24
+ RuboCop::RakeTask.new(:rubocop)
@@ -1,9 +1,8 @@
1
- require "uber/inheritable_attr"
2
-
3
1
  module Reform
4
2
  # Define your form structure and its validations. Instantiate it with a model,
5
3
  # and then +validate+ this object graph.
6
4
  class Contract < Disposable::Twin
5
+ require "reform/contract/custom_error"
7
6
  require "disposable/twin/composition" # Expose.
8
7
  include Expose
9
8
 
@@ -15,7 +14,7 @@ module Reform
15
14
  Contract
16
15
  end
17
16
 
18
- def self.property(name, options={}, &block)
17
+ def self.property(name, options = {}, &block)
19
18
  if twin = options.delete(:form)
20
19
  options[:twin] = twin
21
20
  end
@@ -33,7 +32,7 @@ module Reform
33
32
  end
34
33
 
35
34
  require "reform/result"
36
- require 'reform/contract/validate'
35
+ require "reform/contract/validate"
37
36
  include Reform::Contract::Validate
38
37
 
39
38
  require "reform/validation"
@@ -43,14 +42,16 @@ module Reform
43
42
  require "disposable/twin/sync"
44
43
  include Disposable::Twin::Sync
45
44
 
46
- private
45
+ private
46
+
47
47
  # DISCUSS: separate file?
48
48
  module Readonly
49
49
  def readonly?(name)
50
50
  options_for(name)[:writeable] == false
51
51
  end
52
+
52
53
  def options_for(name)
53
- self.class.options_for(name)
54
+ self.class.options_for(name)
54
55
  end
55
56
  end
56
57
 
@@ -59,7 +60,6 @@ module Reform
59
60
  end
60
61
  include Readonly
61
62
 
62
-
63
63
  def self.clone # TODO: test. THIS IS ONLY FOR Trailblazer when contract gets cloned in suboperation.
64
64
  Class.new(self)
65
65
  end
@@ -0,0 +1,41 @@
1
+ module Reform
2
+ class Contract < Disposable::Twin
3
+ # a "fake" Dry schema object to add into the @results array
4
+ # super ugly hack required for 2.3.x version since we are creating
5
+ # a new Reform::Errors instance every time we call form.errors
6
+ class CustomError
7
+ def initialize(key, error_text, results)
8
+ @key = key
9
+ @error_text = error_text
10
+ @errors = {key => Array(error_text)}
11
+ @messages = @errors
12
+ @hint = {}
13
+ @results = results
14
+
15
+ merge!
16
+ end
17
+
18
+ attr_reader :messages, :hint
19
+
20
+ def success?
21
+ false
22
+ end
23
+
24
+ def failure?
25
+ true
26
+ end
27
+
28
+ # dry 1.x errors method has 1 kwargs argument
29
+ def errors(**_args)
30
+ @errors
31
+ end
32
+
33
+ def merge!
34
+ # to_h required for dry_v 1.x since the errors are Dry object instead of an hash
35
+ @results.map(&:errors)
36
+ .detect { |hash| hash.to_h.key?(@key) }
37
+ .tap { |hash| hash.nil? ? @results << self : hash.to_h[@key] |= Array(@error_text) }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -22,7 +22,11 @@ class Reform::Contract < Disposable::Twin
22
22
  @result
23
23
  end
24
24
 
25
- def validate!(name, pointers=[])
25
+ def custom_errors
26
+ @result.to_results.select { |result| result.is_a? Reform::Contract::CustomError }
27
+ end
28
+
29
+ def validate!(name, pointers = [])
26
30
  # run local validations. this could be nested schemas, too.
27
31
  local_errors_by_group = Reform::Validation::Groups::Validate.(self.class.validation_groups, self).compact # TODO: discss compact
28
32
 
@@ -33,10 +37,10 @@ class Reform::Contract < Disposable::Twin
33
37
  nested_errors = validate_nested!(pointers_for_nested)
34
38
 
35
39
  # Result: unified interface #success?, #messages, etc.
36
- @result = Result.new(local_errors_by_group + pointers, nested_errors)
40
+ @result = Result.new(custom_errors + local_errors_by_group + pointers, nested_errors)
37
41
  end
38
42
 
39
- private
43
+ private
40
44
 
41
45
  # Recursively call validate! on nested forms.
42
46
  # A pointer keeps an entire result object (e.g. Dry result) and
@@ -46,11 +50,11 @@ class Reform::Contract < Disposable::Twin
46
50
 
47
51
  schema.each(twin: true) do |dfn|
48
52
  # on collections, this calls validate! on each item form.
49
- Disposable::Twin::PropertyProcessor.new(dfn, self).() { |form, i|
53
+ Disposable::Twin::PropertyProcessor.new(dfn, self).() do |form, i|
50
54
  nested_pointers = pointers.collect { |pointer| pointer.advance(dfn[:name].to_sym, i) }.compact # pointer contains fragment for us, so go deeper
51
55
 
52
56
  arr << form.validate!(dfn[:name], nested_pointers)
53
- }
57
+ end
54
58
  end
55
59
 
56
60
  arr
@@ -12,15 +12,14 @@ class Reform::Contract::Result::Errors
12
12
  # PROTOTYPING. THIS WILL GO TO A SEPARATE GEM IN REFORM 2.4/3.0.
13
13
  DottedErrors = ->(form, prefix, hash) do
14
14
  result = form.to_result
15
- result.messages.collect { |k,v| hash[ [*prefix, k].join(".").to_sym] = v }
15
+ result.messages.collect { |k, v| hash[[*prefix, k].join(".").to_sym] = v }
16
16
 
17
- form.schema.each(twin: true) { |dfn|
17
+ form.schema.each(twin: true) do |dfn|
18
18
  Disposable::Twin::PropertyProcessor.new(dfn, form).() do |frm, i|
19
- # DottedErrors.(form.send(dfn[:name])[i], [*prefix, dfn[:name], i], hash) and next if i
20
- DottedErrors.(form.send(dfn[:name])[i], [*prefix, dfn[:name]], hash) and next if i
21
- DottedErrors.(form.send(dfn[:name]), [*prefix, dfn[:name]], hash)
19
+ form_obj = i ? form.send(dfn[:name])[i] : form.send(dfn[:name])
20
+ DottedErrors.(form_obj, [*prefix, dfn[:name]], hash)
22
21
  end
23
- }
22
+ end
24
23
  end
25
24
 
26
25
  def messages(*args)
@@ -28,22 +27,35 @@ class Reform::Contract::Result::Errors
28
27
  end
29
28
 
30
29
  def full_messages
31
- @dotted_errors.collect do |path, errors|
32
- human_field = path.to_s.gsub(/([\.\_])+/, " ").gsub(/(\b\w)+/) { |s| s.capitalize }
33
- errors.collect { |message| "#{human_field} #{message}" }
34
- end.flatten
30
+ @dotted_errors.collect { |path, errors|
31
+ human_field = path.to_s.gsub(/([\.\_])+/, " ").gsub(/(\b\w)+/) { |s| s.capitalize }
32
+ errors.collect { |message| "#{human_field} #{message}" }
33
+ }.flatten
35
34
  end
36
35
 
37
36
  def [](name)
38
- @dotted_errors[name]
37
+ @dotted_errors[name] || []
39
38
  end
40
39
 
41
40
  def size
42
41
  messages.size
43
42
  end
43
+
44
+ # needed for rails form helpers
45
+ def empty?
46
+ messages.empty?
47
+ end
48
+
49
+ # we need to delegate adding error to result because every time we call form.errors
50
+ # a new instance of this class is created so we need to update the @results array
51
+ # to be able to add custom errors here.
52
+ # This method will actually work only AFTER a validate call has been made
53
+ def add(key, error_test)
54
+ @result.add_error(key, error_test)
55
+ end
44
56
  end
45
57
 
46
- # Ensure that we can return Active Record compliant full messages when using dry
47
- # we only want unique messages in our array
48
- #
49
- # @full_errors.add()
58
+ # Ensure that we can return Active Record compliant full messages when using dry
59
+ # we only want unique messages in our array
60
+ #
61
+ # @full_errors.add()
@@ -1,5 +1,7 @@
1
1
  module Reform
2
2
  class Form < Contract
3
+ class InvalidOptionsCombinationError < StandardError; end
4
+
3
5
  def self.default_nested_class
4
6
  Form
5
7
  end
@@ -15,23 +17,32 @@ module Reform
15
17
 
16
18
  module Property
17
19
  # Add macro logic, e.g. for :populator.
18
- def property(name, options={}, &block)
20
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
21
+ def property(name, options = {}, &block)
22
+ if (options.keys & %i[skip_if populator]).size == 2
23
+ raise InvalidOptionsCombinationError.new(
24
+ "[Reform] #{self}:property:#{name} Do not use skip_if and populator together, use populator with skip! instead"
25
+ )
26
+ end
27
+
19
28
  # if composition and inherited we also need this setting
20
29
  # to correctly inherit modules
21
- if options.key?(:on) && options.key?(:inherit)
22
- options[:_inherited] = options[:inherit]
23
- end
30
+ options[:_inherited] = options[:inherit] if options.key?(:on) && options.key?(:inherit)
24
31
 
25
32
  if options.key?(:parse)
26
33
  options[:deserializer] ||= {}
27
34
  options[:deserializer][:writeable] = options.delete(:parse)
28
35
  end
29
36
 
30
- if options.key?(:writable)
31
- options[:writeable] ||= options.delete(:writable)
37
+ options[:writeable] ||= options.delete(:writable) if options.key?(:writable)
38
+
39
+ # for virtual collection we need at least to have the collection equal to [] to
40
+ # avoid issue when the populator
41
+ if (options.keys & %i[collection virtual]).size == 2
42
+ options = { default: [] }.merge(options)
32
43
  end
33
44
 
34
- definition = super # let disposable and declarative gems sort out inheriting of properties, and so on.
45
+ definition = super # letdisposable and declarative gems sort out inheriting of properties, and so on.
35
46
  definition.merge!(deserializer: {}) unless definition[:deserializer] # always keep :deserializer per property.
36
47
 
37
48
  deserializer_options = definition[:deserializer]
@@ -48,7 +59,7 @@ module Reform
48
59
  external_populator = Populator::External.new
49
60
 
50
61
  # always compute a parse_pipeline for each property of the deserializer and inject it via :parse_pipeline.
51
- # first, let representable compute the pipeline functions by invoking #parse_functions.
62
+ # first, letrepresentable compute the pipeline functions by invoking #parse_functions.
52
63
  if definition[:nested]
53
64
  parse_pipeline = ->(input, opts) do
54
65
  functions = opts[:binding].send(:parse_functions)
@@ -65,7 +76,7 @@ module Reform
65
76
  pipeline = Representable::Pipeline[*functions] # Pipeline[StopOnExcluded, AssignName, ReadFragment, StopOnNotFound, OverwriteOnNil, Collect[#<Representable::Function::CreateObject:0xa6148ec>, #<Representable::Function::Decorate:0xa6148b0>, Deserialize], Set]
66
77
 
67
78
  # FIXME: this won't work with property :name, inherit: true (where there is a populator set already).
68
- pipeline = Representable::Pipeline::Insert.(pipeline, external_populator, replace: Representable::SetValue) if definition[:populator] # FIXME: only diff to options without :populator
79
+ pipeline = Representable::Pipeline::Insert.(pipeline, external_populator, replace: Representable::SetValue) if definition[:populator] # FIXME: only diff to options without :populator
69
80
  pipeline
70
81
  end
71
82
  end
@@ -77,12 +88,12 @@ module Reform
77
88
  deserializer_options.merge!(skip_parse: proc) # TODO: same with skip_parse ==> External
78
89
  end
79
90
 
80
-
81
91
  # per default, everything should be writeable for the deserializer (we're only writing on the form). however, allow turning it off.
82
- deserializer_options.merge!(writeable: true) unless deserializer_options.has_key?(:writeable)
92
+ deserializer_options.merge!(writeable: true) unless deserializer_options.key?(:writeable)
83
93
 
84
94
  definition
85
95
  end
96
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
86
97
  end
87
98
  extend Property
88
99
 
@@ -17,7 +17,7 @@ module Reform::Form::Call
17
17
  end
18
18
 
19
19
  def failure?
20
- ! @success
20
+ !@success
21
21
  end
22
22
  end
23
23
  end