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
@@ -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