reform 2.1.0 → 2.2.0.rc1

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +4 -12
  4. data/CHANGES.md +8 -0
  5. data/README.md +36 -743
  6. data/Rakefile +1 -31
  7. data/gemfiles/{Gemfile.rails-3.1 → Gemfile.disposable-0.3} +1 -2
  8. data/lib/reform.rb +0 -9
  9. data/lib/reform/contract.rb +5 -1
  10. data/lib/reform/form.rb +1 -4
  11. data/lib/reform/form/composition.rb +1 -2
  12. data/lib/reform/form/dry.rb +29 -16
  13. data/lib/reform/form/module.rb +15 -3
  14. data/lib/reform/form/validate.rb +1 -1
  15. data/lib/reform/validation.rb +3 -3
  16. data/lib/reform/version.rb +1 -1
  17. data/reform.gemspec +3 -10
  18. data/test/coercion_test.rb +7 -7
  19. data/test/composition_test.rb +5 -1
  20. data/test/contract_test.rb +10 -4
  21. data/test/deserialize_test.rb +3 -3
  22. data/test/errors_test.rb +48 -28
  23. data/test/form_option_test.rb +3 -1
  24. data/test/form_test.rb +19 -14
  25. data/test/module_test.rb +51 -11
  26. data/test/populate_test.rb +21 -7
  27. data/test/reform_test.rb +24 -20
  28. data/test/save_test.rb +10 -4
  29. data/test/skip_if_test.rb +5 -3
  30. data/test/test_helper.rb +3 -43
  31. data/test/validate_test.rb +34 -14
  32. data/test/validation/dry_test.rb +60 -0
  33. data/test/validation/dry_validation_test.rb +65 -43
  34. data/test/validation/errors.yml +4 -0
  35. metadata +16 -192
  36. data/database.sqlite3 +0 -0
  37. data/gemfiles/Gemfile.rails-3.2 +0 -7
  38. data/gemfiles/Gemfile.rails-4.0 +0 -8
  39. data/gemfiles/Gemfile.rails-4.1 +0 -8
  40. data/gemfiles/Gemfile.rails-4.2 +0 -8
  41. data/lib/reform/active_record.rb +0 -4
  42. data/lib/reform/form/active_model.rb +0 -87
  43. data/lib/reform/form/active_model/form_builder_methods.rb +0 -48
  44. data/lib/reform/form/active_model/model_reflections.rb +0 -46
  45. data/lib/reform/form/active_model/model_validations.rb +0 -110
  46. data/lib/reform/form/active_model/validations.rb +0 -107
  47. data/lib/reform/form/active_record.rb +0 -30
  48. data/lib/reform/form/lotus.rb +0 -59
  49. data/lib/reform/form/multi_parameter_attributes.rb +0 -48
  50. data/lib/reform/form/validation/unique_validator.rb +0 -54
  51. data/lib/reform/rails.rb +0 -13
  52. data/test/active_model_custom_validation_translations_test.rb +0 -75
  53. data/test/active_model_test.rb +0 -207
  54. data/test/active_model_validation_for_property_named_format_test.rb +0 -18
  55. data/test/active_record_test.rb +0 -273
  56. data/test/builder_test.rb +0 -32
  57. data/test/custom_validation_test.rb +0 -47
  58. data/test/dummy/Rakefile +0 -7
  59. data/test/dummy/app/controllers/albums_controller.rb +0 -18
  60. data/test/dummy/app/controllers/application_controller.rb +0 -4
  61. data/test/dummy/app/controllers/musician_controller.rb +0 -5
  62. data/test/dummy/app/forms/album_form.rb +0 -18
  63. data/test/dummy/app/helpers/application_helper.rb +0 -2
  64. data/test/dummy/app/models/album.rb +0 -4
  65. data/test/dummy/app/models/song.rb +0 -3
  66. data/test/dummy/app/views/albums/new.html.erb +0 -28
  67. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  68. data/test/dummy/config.ru +0 -4
  69. data/test/dummy/config/application.rb +0 -20
  70. data/test/dummy/config/boot.rb +0 -10
  71. data/test/dummy/config/database.yml +0 -22
  72. data/test/dummy/config/environment.rb +0 -5
  73. data/test/dummy/config/environments/development.rb +0 -16
  74. data/test/dummy/config/environments/production.rb +0 -46
  75. data/test/dummy/config/environments/test.rb +0 -33
  76. data/test/dummy/config/locales/en.yml +0 -14
  77. data/test/dummy/config/routes.rb +0 -4
  78. data/test/dummy/db/test.sqlite3 +0 -0
  79. data/test/form_builder_test.rb +0 -138
  80. data/test/lotus/Gemfile +0 -5
  81. data/test/lotus/lotus_test.rb +0 -31
  82. data/test/lotus_test.rb +0 -150
  83. data/test/model_reflections_test.rb +0 -138
  84. data/test/model_validations_test.rb +0 -82
  85. data/test/mongoid_test.rb +0 -313
  86. data/test/multi_parameter_attributes_test.rb +0 -50
  87. data/test/rails/integration_test.rb +0 -54
  88. data/test/unique_test.rb +0 -135
  89. data/test/validation/activemodel_validation_test.rb +0 -252
@@ -1,18 +0,0 @@
1
- require "test_helper"
2
-
3
- class AMValidationWithFormatTest < MiniTest::Spec
4
- class SongForm < Reform::Form
5
- property :format
6
- validates :format, presence: true
7
- end
8
-
9
- class Song
10
- def format
11
- 1
12
- end
13
- end
14
-
15
- it do
16
- SongForm.new(Song.new).validate({}).must_equal true
17
- end
18
- end
@@ -1,273 +0,0 @@
1
- require 'test_helper'
2
- require 'reform/active_record'
3
-
4
- # ActiveRecord::Schema.define do
5
- # create_table :artists do |table|
6
- # table.column :name, :string
7
- # table.timestamps
8
- # end
9
- # create_table :songs do |table|
10
- # table.column :title, :string
11
- # table.column :artist_id, :integer
12
- # table.column :album_id, :integer
13
- # table.timestamps
14
- # end
15
- # create_table :albums do |table|
16
- # table.column :title, :string
17
- # table.timestamps
18
- # end
19
- # end
20
- # Artist.new(:name => "Racer X").save
21
-
22
- class ActiveRecordTest < MiniTest::Spec
23
- class SongForm < Reform::Form
24
- feature Reform::Form::ActiveModel::Validations
25
-
26
- include Reform::Form::ActiveRecord
27
- model :song
28
-
29
- property :title
30
- property :created_at
31
-
32
- validates_uniqueness_of :title, scope: [:album_id, :artist_id]
33
- validates :created_at, :presence => true # have another property to test if we mix up.
34
-
35
- property :artist do
36
- property :name
37
- validates_uniqueness_of :name # this currently also tests if Form::AR is included as a feature.
38
- end
39
- end
40
-
41
- let(:album) { Album.create(:title => "Damnation") }
42
- let(:artist) { Artist.create(:name => "Opeth") }
43
- let(:form) { SongForm.new(Song.new(:artist => Artist.new)) }
44
-
45
- it { form.class.i18n_scope.must_equal :activerecord }
46
-
47
- # uniqueness
48
- it "has no errors on title when title is unique for the same artist and album" do
49
- form.validate("title" => "The Gargoyle", "artist_id" => artist.id, "album" => album.id, "created_at" => "November 6, 1966")
50
- assert_empty form.errors[:title]
51
- end
52
-
53
- it "has errors on title when title is taken for the same artist and album" do
54
- skip "replace ActiveModel::Validations with our own, working and reusable gem."
55
- Song.create(title: "Windowpane", artist_id: artist.id, album_id: album.id)
56
- form.validate("title" => "Windowpane", "artist_id" => artist.id, "album" => album)
57
- refute_empty form.errors[:title]
58
- end
59
-
60
- # nested object taken.
61
- it "is valid when artist name is unique" do
62
- form.validate("artist" => {"name" => "Paul Gilbert"}, "title" => "The Gargoyle", "created_at" => "November 6, 1966").must_equal true
63
- end
64
-
65
- it "is invalid and shows error when taken" do
66
- Song.delete_all
67
- Artist.create(:name => "Racer X")
68
-
69
- form.validate("artist" => {"name" => "Racer X"}, "title" => "Ghost Inside My Skin").must_equal false
70
- form.errors.messages.must_equal({:"artist.name"=>["has already been taken"], :created_at => ["can't be blank"]})
71
- end
72
-
73
- it "works with Composition" do
74
- form = Class.new(Reform::Form) do
75
- include Reform::Form::ActiveRecord
76
- include Reform::Form::Composition
77
-
78
- property :name, :on => :artist
79
- validates_uniqueness_of :name
80
- end.new(:artist => Artist.new)
81
-
82
- Artist.create(:name => "Bad Religion")
83
- form.validate("name" => "Bad Religion").must_equal false
84
- end
85
-
86
- describe "#save" do
87
- # TODO: test 1-n?
88
- it "calls model.save" do
89
- Artist.delete_all
90
- form.validate("artist" => {"name" => "Bad Religion"}, "title" => "Ghost Inside My Skin")
91
- form.save
92
- Artist.where(:name => "Bad Religion").size.must_equal 1
93
- end
94
-
95
- it "doesn't call model.save when block is given" do
96
- Artist.delete_all
97
- form.validate("name" => "Bad Religion")
98
- form.save {}
99
- Artist.where(:name => "Bad Religion").size.must_equal 0
100
- end
101
-
102
- it "can access block params using string or hash key" do
103
- Artist.delete_all
104
- form.validate("artist" => {"name" => "Paul Gilbert"}, "title" => "The Gargoyle", "created_at" => "November 6, 1966")
105
- form.save do |params|
106
- params[:title].must_equal 'The Gargoyle'
107
- params['title'].must_equal 'The Gargoyle'
108
- end
109
- end
110
- end
111
- end
112
-
113
-
114
- class PopulateWithActiveRecordTest < MiniTest::Spec
115
- class AlbumForm < Reform::Form
116
-
117
- property :title
118
-
119
- collection :songs, :populate_if_empty => Song do
120
- property :title
121
- end
122
- end
123
-
124
- let (:album) { Album.new(:songs => []) }
125
- it do
126
- form = AlbumForm.new(album)
127
-
128
- form.validate("songs" => [{"title" => "Straight From The Jacket"}])
129
-
130
- # form populated.
131
- form.songs.size.must_equal 1
132
- form.songs[0].model.must_be_kind_of Song
133
-
134
- # model NOT populated.
135
- album.songs.must_equal []
136
-
137
-
138
- form.sync
139
-
140
- # form populated.
141
- form.songs.size.must_equal 1
142
- form.songs[0].model.must_be_kind_of Song
143
-
144
- # model also populated.
145
- song = album.songs[0]
146
- album.songs.must_equal [song]
147
- song.title.must_equal "Straight From The Jacket"
148
-
149
-
150
- if ActiveRecord::VERSION::STRING !~ /^3.0/
151
- # saving saves association.
152
- form.save
153
-
154
- album.reload
155
- song = album.songs[0]
156
- album.songs.must_equal [song]
157
- song.title.must_equal "Straight From The Jacket"
158
- end
159
- end
160
-
161
-
162
- describe "modifying 1., adding 2." do
163
- let (:song) { Song.new(:title => "Part 2") }
164
- let (:album) { Album.create.tap { |a| a.songs << song } }
165
-
166
- it do
167
- form = AlbumForm.new(album)
168
-
169
- id = album.songs[0].id
170
- assert id > 0
171
-
172
- form.validate("songs" => [{"title" => "Part Two"}, {"title" => "Check For A Pulse"}])
173
-
174
- # form populated.
175
- form.songs.size.must_equal 2
176
- form.songs[0].model.must_be_kind_of Song
177
- form.songs[1].model.must_be_kind_of Song
178
-
179
- # model NOT populated.
180
- album.songs.must_equal [song]
181
-
182
-
183
- form.sync
184
-
185
- # form populated.
186
- form.songs.size.must_equal 2
187
-
188
- # model also populated.
189
- album.songs.size.must_equal 2
190
-
191
- # corrected title
192
- album.songs[0].title.must_equal "Part Two"
193
- # ..but same song.
194
- album.songs[0].id.must_equal id
195
-
196
- # and a new song.
197
- album.songs[1].title.must_equal "Check For A Pulse"
198
- album.songs[1].persisted?.must_equal true # TODO: with << strategy, this shouldn't be saved.
199
- end
200
-
201
- describe 'using nested_models_attributes to modify nested collection' do
202
- class ActiveModelAlbumForm < Reform::Form
203
- include Reform::Form::ActiveModel
204
- include Reform::Form::ActiveModel::FormBuilderMethods
205
-
206
- property :title
207
-
208
- collection :songs, :populate_if_empty => Song do
209
- property :title
210
- end
211
- end
212
-
213
- let (:album) { Album.create(:title => 'Greatest Hits') }
214
- let (:form) { ActiveModelAlbumForm.new(album) }
215
-
216
- it "xxx"do
217
- form.validate('songs_attributes' => {'0' => {'title' => 'Tango'}})
218
-
219
- # form populated.
220
- form.songs.size.must_equal 1
221
- form.songs[0].model.must_be_kind_of Song
222
- form.songs[0].title.must_equal 'Tango'
223
-
224
- # model NOT populated.
225
- album.songs.must_equal []
226
-
227
- form.save
228
-
229
- # nested model persisted.
230
- first_song = album.songs[0]
231
- assert first_song.id > 0
232
-
233
- # form populated.
234
- form.songs.size.must_equal 1
235
-
236
- # model also populated.
237
- album.songs.size.must_equal 1
238
- album.songs[0].title.must_equal 'Tango'
239
-
240
- # DISCUSS: IfEmpty uses twin.original[index] for syncing. in our case, this is empty, so it will add Tango again.
241
- form = ActiveModelAlbumForm.new(album)
242
- form.validate('songs_attributes' => {'0' => {'id' => first_song.id, 'title' => 'Tango nuevo'}, '1' => {'title' => 'Waltz'}})
243
-
244
- # form populated.
245
- form.songs.size.must_equal 2
246
- form.songs[0].model.must_be_kind_of Song
247
- form.songs[1].model.must_be_kind_of Song
248
- form.songs[0].title.must_equal 'Tango nuevo'
249
- form.songs[1].title.must_equal 'Waltz'
250
-
251
- # model NOT populated.
252
- album.songs.size.must_equal 1
253
- album.songs[0].title.must_equal 'Tango'
254
-
255
- form.save
256
-
257
- # form populated.
258
- form.songs.size.must_equal 2
259
-
260
- # model also populated.
261
- album.songs.size.must_equal 2
262
- album.songs[0].id.must_equal first_song.id
263
- album.songs[0].persisted?.must_equal true
264
- album.songs[1].persisted?.must_equal true
265
- album.songs[0].title.must_equal 'Tango nuevo'
266
- album.songs[1].title.must_equal 'Waltz'
267
- end
268
- end
269
- end
270
- end
271
-
272
-
273
-
@@ -1,32 +0,0 @@
1
- # require 'test_helper'
2
-
3
- # class BuilderTest < MiniTest::Spec
4
- # it do
5
- # Builder.new.checkboxes(:settings, :hash => {"play" => true, "released" => false}).must_equal %{<input name="yo" type="hidden" value="unchecked_value" /><input id="object_name_method" name="yo" type="checkbox" value="checked_value" />
6
- # <input name="yo" type="hidden" value="unchecked_value" /><input id="object_name_method" name="yo" type="checkbox" value="checked_value" />}
7
- # end
8
- # end
9
-
10
-
11
- # require 'action_view/helpers/capture_helper'
12
- # require 'action_view/helpers/tag_helper'
13
- # require 'action_view/helpers/url_helper'
14
- # require 'action_view/helpers/sanitize_helper'
15
- # require 'action_view/helpers/text_helper'
16
- # require 'action_view/helpers/form_tag_helper'
17
- # require 'action_view/helpers/form_helper'
18
-
19
- # class Builder
20
- # include ActionView::Helpers::CaptureHelper
21
- # include ActionView::Helpers::FormHelper
22
-
23
- # # {name: value}
24
- # def checkboxes(name, options)
25
- # # get property form.to_a ? to_builder_hash or something like that
26
- # options[:hash].collect do |id, value|
27
- # ActionView::Helpers::InstanceTag.new(:object_name, :method, self).to_check_box_tag({:name => "yo"}, :checked_value, :unchecked_value)
28
-
29
- # # check_box_tag(id, value, checked = false, {})
30
- # end.join("\n")
31
- # end
32
- # end
@@ -1,47 +0,0 @@
1
- require 'test_helper'
2
-
3
- unless ActiveModel::VERSION::MAJOR == 3 and ActiveModel::VERSION::MINOR == 0
4
-
5
- class UnexistantTitleValidator < ActiveModel::Validator
6
- def validate record
7
- if record.title == 'unexistant_song'
8
- record.errors.add(:title, 'this title does not exist!')
9
- end
10
- end
11
- end
12
-
13
- class CustomValidationTest < MiniTest::Spec
14
-
15
- class Album
16
- include ActiveModel::Validations
17
- attr_accessor :title, :artist
18
-
19
- validates_with UnexistantTitleValidator
20
- end
21
-
22
- class AlbumForm < Reform::Form
23
- extend ActiveModel::ModelValidations
24
-
25
- property :title
26
- property :artist_name, from: :artist
27
- copy_validations_from Album
28
- end
29
-
30
- let(:album) { Album.new }
31
-
32
- describe 'non-composite form' do
33
-
34
- let(:album_form) { AlbumForm.new(album) }
35
-
36
- it 'is not valid when title is unexistant_song' do
37
- album_form.validate(artist_name: 'test', title: 'unexistant_song').must_equal false
38
- end
39
-
40
- it 'is valid when title is something existant' do
41
- album_form.validate(artist_name: 'test', title: 'test').must_equal true
42
- end
43
-
44
- end
45
-
46
- end
47
- end
@@ -1,7 +0,0 @@
1
- # Add your own tasks in files placed in lib/tasks ending in .rake,
2
- # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
-
4
- require File.expand_path('../config/application', __FILE__)
5
- require 'rake'
6
-
7
- Rails::Application.load_tasks
@@ -1,18 +0,0 @@
1
- class AlbumsController < ActionController::Base
2
- def new
3
- album = Album.new(:songs => [Song.new, Song.new])
4
- @form = AlbumForm.new(album)
5
- end
6
-
7
- def create
8
- album = Album.new(songs: [Song.new, Song.new])
9
- @form = AlbumForm.new(album)
10
-
11
- if @form.validate(params["album"])
12
- @form.save
13
- redirect_to album_path(album)
14
- else
15
- render :new
16
- end
17
- end
18
- end
@@ -1,4 +0,0 @@
1
- class ApplicationController < ActionController::Base
2
- protect_from_forgery
3
- layout 'application'
4
- end
@@ -1,5 +0,0 @@
1
- class MusicianController < ActionController::Base
2
- def index
3
- render :text => Artist.find(:all)
4
- end
5
- end
@@ -1,18 +0,0 @@
1
- class AlbumForm < Reform::Form # FIXME: sub forms don't inherit FBM.
2
-
3
- model :album
4
-
5
- property :title
6
-
7
- collection :songs do
8
- property :title
9
- validates :title, presence: true
10
- end
11
-
12
- validates :title, presence: true
13
-
14
- def save
15
- super
16
- model.save
17
- end
18
- end
@@ -1,2 +0,0 @@
1
- module ApplicationHelper
2
- end
@@ -1,4 +0,0 @@
1
- class Album < ActiveRecord::Base
2
- has_many :songs
3
- has_and_belongs_to_many :artists
4
- end
@@ -1,3 +0,0 @@
1
- class Song < ActiveRecord::Base
2
- belongs_to :album
3
- end