reform 2.3.0.rc1 → 2.3.0.rc2

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 (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
@@ -1,180 +0,0 @@
1
- require "test_helper"
2
-
3
- # TODO:
4
- # This test should, at some point soon, only test the `Errors` object and its
5
- # Rails-ish API. No validation specifics, etc. to be tested here.
6
-
7
- class ErrorsTest < MiniTest::Spec
8
- class AlbumForm < TestForm
9
- property :title
10
-
11
- property :hit do
12
- property :title
13
- validation do
14
- required(:title).filled
15
- end
16
- end
17
-
18
- collection :songs do
19
- property :title
20
- validation do
21
- required(:title).filled
22
- end
23
- end
24
-
25
- property :band do # yepp, people do crazy stuff like that.
26
- property :name
27
- property :label do
28
- property :name
29
- validation do
30
- required(:name).filled
31
- end
32
- end
33
- # TODO: make band a required object.
34
-
35
- validation do
36
- configure do
37
- config.messages_file = "test/fixtures/dry_error_messages.yml"
38
-
39
- def good_musical_taste?(value)
40
- value != "Nickelback"
41
- end
42
- end
43
-
44
- required(:name).filled(:good_musical_taste?)
45
- end
46
- end
47
-
48
- validation do
49
- required(:title).filled
50
- end
51
- end
52
-
53
- let (:album) do
54
- OpenStruct.new(
55
- :title => "Blackhawks Over Los Angeles",
56
- :hit => song,
57
- :songs => songs, # TODO: document this requirement,
58
- :band => Struct.new(:name, :label).new("Epitaph", OpenStruct.new),
59
- )
60
- end
61
- let (:song) { OpenStruct.new(:title => "Downtown") }
62
- let (:songs) { [song=OpenStruct.new(:title => "Calling"), song] }
63
- let (:form) { AlbumForm.new(album) }
64
-
65
-
66
- describe "#errors without #validate" do
67
- it do
68
- form.errors.size.must_equal 0
69
- end
70
- end
71
-
72
- describe "blank everywhere" do
73
- before { form.validate(
74
- "hit" =>{"title" => ""},
75
- "title" => "",
76
- "songs" => [{"title" => ""}, {"title" => ""}]) } # FIXME: what happens if item must be filled?
77
-
78
- it do
79
- form.errors.messages.must_equal({
80
- :title => ["must be filled"],
81
- :"hit.title"=>["must be filled"],
82
- :"songs.title"=>["must be filled"],
83
- :"band.label.name"=>["must be filled"]
84
- })
85
- end
86
-
87
- it do
88
- #form.errors.must_equal({:title => ["must be filled"]})
89
- # TODO: this should only contain local errors?
90
- end
91
-
92
- # nested forms keep their own Errors:
93
- it { form.hit.errors.messages.must_equal({:title=>["must be filled"]}) }
94
- it { form.songs[0].errors.messages.must_equal({:title=>["must be filled"]}) }
95
-
96
- it do
97
- form.errors.messages.must_equal({
98
- :title => ["must be filled"],
99
- :"hit.title" => ["must be filled"],
100
- :"songs.title"=> ["must be filled"],
101
- :"band.label.name"=>["must be filled"]
102
- })
103
- form.errors.size.must_equal(4)
104
- end
105
- end
106
-
107
-
108
- describe "#validate with main form invalid" do
109
- it do
110
- form.validate("title"=>"", "band"=>{"label"=>{:name => "Fat Wreck"}}).must_equal false
111
- form.errors.messages.must_equal({:title=>["must be filled"]})
112
- form.errors.size.must_equal(1)
113
- end
114
- end
115
-
116
-
117
- describe "#validate with middle nested form invalid" do
118
- before { @result = form.validate("hit"=>{"title" => ""}, "band"=>{"label"=>{:name => "Fat Wreck"}}) }
119
-
120
- it { @result.must_equal false }
121
- it { form.errors.messages.must_equal({:"hit.title"=>["must be filled"]}) }
122
- it { form.errors.size.must_equal(1) }
123
- end
124
-
125
-
126
- describe "#validate with collection form invalid" do
127
- before { @result = form.validate("songs"=>[{"title" => ""}], "band"=>{"label"=>{:name => "Fat Wreck"}}) }
128
-
129
- it { @result.must_equal false }
130
- it { form.errors.messages.must_equal({:"songs.title"=>["must be filled"]}) }
131
- it { form.errors.size.must_equal(1) }
132
- end
133
-
134
-
135
- describe "#validate with collection and 2-level-nested invalid" do
136
- before { @result = form.validate("songs"=>[{"title" => ""}], "band" => {"label" => {}}) }
137
-
138
- it { @result.must_equal false }
139
- it { form.errors.messages.must_equal({:"songs.title"=>["must be filled"], :"band.label.name"=>["must be filled"]}) }
140
- it { form.errors.size.must_equal(2) }
141
- end
142
-
143
- describe "#validate with nested form using :base invalid" do
144
- it do
145
- result = form.validate("songs"=>[{"title" => "Someday"}], "band" => {"name" => "Nickelback", "label" => {"name" => "Roadrunner Records"}})
146
- result.must_equal false
147
- form.errors.messages.must_equal({:"band.name"=>["you're a bad person"]})
148
- form.errors.size.must_equal(1)
149
- end
150
- end
151
-
152
- describe "correct #validate" do
153
- before { @result = form.validate(
154
- "hit" => {"title" => "Sacrifice"},
155
- "title" => "Second Heat",
156
- "songs" => [{"title"=>"Heart Of A Lion"}],
157
- "band" => {"label"=>{:name => "Fat Wreck"}}
158
- ) }
159
-
160
- it { @result.must_equal true }
161
- it { form.hit.title.must_equal "Sacrifice" }
162
- it { form.title.must_equal "Second Heat" }
163
- it { form.songs.first.title.must_equal "Heart Of A Lion" }
164
- it do
165
- skip "WE DON'T NEED COUNT AND EMPTY? ON THE CORE ERRORS OBJECT"
166
- form.errors.size.must_equal(0)
167
- form.errors.empty?.must_equal(true)
168
- end
169
- end
170
-
171
-
172
- describe "Errors#to_s" do
173
- before { form.validate("songs"=>[{"title" => ""}], "band" => {"label" => {}}) }
174
-
175
- # to_s is aliased to messages
176
- it {
177
- skip "why do we need Errors#to_s ?"
178
- form.errors.to_s.must_equal "{:\"songs.title\"=>[\"must be filled\"], :\"band.label.name\"=>[\"must be filled\"]}" }
179
- end
180
- end
@@ -1,14 +0,0 @@
1
- require "test_helper"
2
-
3
- class ReadonlyTest < MiniTest::Spec
4
- class SongForm < TestForm
5
- property :artist
6
- property :title, writeable: false
7
- # TODO: what to do with virtual values?
8
- end
9
-
10
- let (:form) { SongForm.new(OpenStruct.new) }
11
-
12
- it { form.readonly?(:artist).must_equal false }
13
- it { form.readonly?(:title).must_equal true }
14
- end