reform 1.2.6 → 2.0.0.beta1

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -1
  3. data/CHANGES.md +14 -0
  4. data/Gemfile +3 -2
  5. data/README.md +225 -283
  6. data/Rakefile +27 -0
  7. data/TODO.md +12 -0
  8. data/database.sqlite3 +0 -0
  9. data/gemfiles/Gemfile.rails-3.0 +1 -0
  10. data/gemfiles/Gemfile.rails-3.1 +1 -0
  11. data/gemfiles/Gemfile.rails-3.2 +1 -0
  12. data/gemfiles/Gemfile.rails-4.0 +1 -0
  13. data/lib/reform.rb +0 -1
  14. data/lib/reform/contract.rb +64 -170
  15. data/lib/reform/contract/validate.rb +10 -13
  16. data/lib/reform/form.rb +74 -19
  17. data/lib/reform/form/active_model.rb +19 -14
  18. data/lib/reform/form/coercion.rb +1 -13
  19. data/lib/reform/form/composition.rb +2 -24
  20. data/lib/reform/form/multi_parameter_attributes.rb +43 -62
  21. data/lib/reform/form/populator.rb +85 -0
  22. data/lib/reform/form/prepopulate.rb +13 -43
  23. data/lib/reform/form/validate.rb +29 -90
  24. data/lib/reform/form/validation/unique_validator.rb +13 -0
  25. data/lib/reform/version.rb +1 -1
  26. data/reform.gemspec +7 -7
  27. data/test/active_model_test.rb +43 -0
  28. data/test/changed_test.rb +23 -51
  29. data/test/coercion_test.rb +1 -7
  30. data/test/composition_test.rb +128 -34
  31. data/test/contract_test.rb +27 -86
  32. data/test/feature_test.rb +43 -6
  33. data/test/fields_test.rb +2 -12
  34. data/test/form_builder_test.rb +28 -25
  35. data/test/form_option_test.rb +19 -0
  36. data/test/from_test.rb +0 -75
  37. data/test/inherit_test.rb +178 -117
  38. data/test/model_reflections_test.rb +1 -1
  39. data/test/populate_test.rb +226 -0
  40. data/test/prepopulator_test.rb +112 -0
  41. data/test/readable_test.rb +2 -4
  42. data/test/save_test.rb +56 -112
  43. data/test/setup_test.rb +48 -0
  44. data/test/skip_if_test.rb +5 -2
  45. data/test/skip_setter_and_getter_test.rb +54 -0
  46. data/test/test_helper.rb +3 -1
  47. data/test/uniqueness_test.rb +41 -0
  48. data/test/validate_test.rb +325 -289
  49. data/test/virtual_test.rb +1 -3
  50. data/test/writeable_test.rb +3 -4
  51. metadata +35 -39
  52. data/lib/reform/composition.rb +0 -63
  53. data/lib/reform/contract/setup.rb +0 -50
  54. data/lib/reform/form/changed.rb +0 -9
  55. data/lib/reform/form/sync.rb +0 -116
  56. data/lib/reform/representer.rb +0 -84
  57. data/test/empty_test.rb +0 -58
  58. data/test/form_composition_test.rb +0 -145
  59. data/test/nested_form_test.rb +0 -197
  60. data/test/prepopulate_test.rb +0 -85
  61. data/test/sync_option_test.rb +0 -83
  62. data/test/sync_test.rb +0 -56
@@ -1,85 +0,0 @@
1
- require 'test_helper'
2
-
3
- class PrepopulateTest < MiniTest::Spec
4
- Song = Struct.new(:title, :band, :length)
5
- Band = Struct.new(:name)
6
-
7
- class AlbumForm < Reform::Form
8
- property :title, prepopulate: ->(options){ "Another Day At Work" }
9
- property :length
10
-
11
- property :hit, prepopulate: ->(options){ Song.new } do
12
- property :title
13
-
14
- property :band, prepopulate: ->(options){ Band.new } do
15
- property :name
16
- end
17
- end
18
-
19
- collection :songs, prepopulate: ->(options){ [Song.new, Song.new] } do
20
- property :title
21
- end
22
- end
23
-
24
- subject { AlbumForm.new(OpenStruct.new(length: 1)).prepopulate! }
25
-
26
- it { subject.length.must_equal 1 }
27
- it { subject.title.must_equal "Another Day At Work" }
28
- it { subject.hit.model.must_equal Song.new }
29
- it { subject.songs.size.must_equal 2 }
30
- it { subject.songs[0].model.must_equal Song.new }
31
- it { subject.songs[1].model.must_equal Song.new }
32
- it { subject.hit.band.model.must_equal Band.new }
33
- end
34
-
35
-
36
- class PrepopulateInFormContextTest < MiniTest::Spec
37
- Song = Struct.new(:title, :band, :length)
38
- Band = Struct.new(:name)
39
-
40
- class AlbumForm < Reform::Form
41
- property :title, prepopulate: ->(options){ "#{my_title} #{options.class}" }
42
-
43
- property :hit, prepopulate: ->(options){ my_hit } do
44
- property :title
45
-
46
- property :band, prepopulate: ->(options){ my_band } do
47
- property :name
48
- end
49
-
50
- def my_band
51
- Band.new
52
- end
53
- end
54
-
55
- def my_title
56
- "Rhode Island Shred"
57
- end
58
-
59
- def my_hit
60
- Song.new
61
- end
62
- end
63
-
64
- subject { AlbumForm.new(OpenStruct.new).prepopulate! }
65
-
66
- it { subject.title.must_equal "Rhode Island Shred Hash" }
67
- it { subject.hit.model.must_equal Song.new }
68
- it { subject.hit.band.model.must_equal Band.new }
69
- end
70
-
71
- class PrepopulateWithExistingCollectionTest < MiniTest::Spec
72
- Song = Struct.new(:title)
73
-
74
- class AlbumForm < Reform::Form
75
- collection :songs, prepopulate: ->(*){ songs.map(&:model) + [Song.new] } do
76
- property :title
77
- end
78
- end
79
-
80
- subject { AlbumForm.new(OpenStruct.new(songs: [Song.new])).prepopulate! }
81
-
82
- it { subject.songs.size.must_equal 2 }
83
- it { subject.songs[0].model.must_equal Song.new }
84
- it { subject.songs[1].model.must_equal Song.new }
85
- end
@@ -1,83 +0,0 @@
1
- require 'test_helper'
2
-
3
- class SyncOptionTest < MiniTest::Spec
4
- Band = Struct.new(:name)
5
- let (:band) { Band.new("Metallica") }
6
- let (:form) { BandForm.new(band) }
7
-
8
- # access to :form!
9
- describe ":sync allows you conditionals" do
10
- class BandForm < Reform::Form
11
- property :name, sync: lambda { |value, options| options.user_options[:form].changed?(:name) ? model.name = value : nil } # change if it hasn't changed
12
- end
13
-
14
- # don't set name, didn't change.
15
- it do
16
- band.instance_exec { def name=(*); raise; end }
17
- form.validate("name" => "Metallica").must_equal true
18
- form.sync
19
- band.name.must_equal "Metallica"
20
- end
21
-
22
- # update name.
23
- it do
24
- form.validate("name" => "Iron Maiden").must_equal true
25
- form.sync
26
- form.name.must_equal "Iron Maiden"
27
- end
28
- end
29
- end
30
-
31
-
32
- class SyncWithDynamicOptionsTest < MiniTest::Spec
33
- Song = Struct.new(:id, :title, :length)
34
-
35
- class SongForm < Reform::Form
36
- property :id
37
- property :title, sync: true
38
- property :length
39
- end
40
-
41
- let (:song) { Song.new }
42
- let (:form) { SongForm.new(song) }
43
-
44
- # we have access to original input value and outside parameters.
45
- it do
46
- form.validate("title" => "A Poor Man's Memory", "length" => 10)
47
- length_seconds = 120
48
- form.sync(title: lambda { |value, options| form.model.title = "#{value}: #{length_seconds}" })
49
-
50
- song.title.must_equal "A Poor Man's Memory: 120"
51
- song.length.must_equal 10
52
- song.id.must_equal nil
53
- end
54
- end
55
-
56
-
57
- # :virtual wins over :sync
58
- # class SyncWithVirtualTest < MiniTest::Spec
59
- # Song = Struct.new(:title, :image, :band)
60
- # Band = Struct.new(:name)
61
-
62
- # let (:form) { HitForm.new(song) }
63
- # let (:song) { Song.new("Injection", Object, Band.new("Rise Against")) }
64
-
65
- # class HitForm < Reform::Form
66
- # include Sync::SkipUnchanged
67
- # register_feature Sync::SkipUnchanged
68
-
69
- # property :image, sync: lambda { |value, *| model.image = "processed via :sync: #{value}" }
70
- # property :band do
71
- # property :name, sync: lambda { |value, *| model.name = "band, processed: #{value}" }, virtual: true
72
- # end
73
- # end
74
-
75
- # it "abc" do
76
- # form.validate("image" => "Funny photo of Steve Harris", "band" => {"name" => "Iron Maiden"}).must_equal true
77
-
78
- # form.sync
79
- # song.image.must_equal "processed via :sync: Funny photo of Steve Harris"
80
- # song.band.name.must_equal "Rise Against"
81
- # end
82
- # end
83
-
data/test/sync_test.rb DELETED
@@ -1,56 +0,0 @@
1
- require 'test_helper'
2
-
3
- class SyncTest < BaseTest
4
-
5
- Band = Struct.new(:name, :label)
6
-
7
- describe "populated" do
8
- let (:params) {
9
- {
10
- "title" => "Best Of",
11
- "hit" => {"title" => "Roxanne"},
12
- "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}],
13
- :band => {:label => {:name => "Polydor"}}
14
- }
15
- }
16
-
17
- let (:album) { Album.new(nil, hit, [song1, song2], band) }
18
- let (:hit) { Song.new }
19
- let (:song1) { Song.new }
20
- let (:song2) { Song.new }
21
- let (:band) { Band.new("The Police", label) }
22
- let (:label) { Label.new }
23
-
24
- subject { ErrorsTest::AlbumForm.new(album) }
25
-
26
- before do
27
- subject.validate(params)
28
- subject.sync
29
- end
30
-
31
- it { album.title.must_equal "Best Of" }
32
- it { album.hit.must_be_kind_of Struct }
33
- it { album.songs[0].must_be_kind_of Struct }
34
- it { album.songs[1].must_be_kind_of Struct }
35
-
36
- # it { hit.must_be_kind_of Struct }
37
- it { hit.title.must_equal "Roxanne" }
38
- it { song1.title.must_equal "Fallout" }
39
- it { song2.title.must_equal "Roxanne" }
40
- it { label.name.must_equal "Polydor" }
41
- end
42
-
43
- describe "with incoming nil value" do
44
- it do
45
- album = Album.new("GI")
46
- form = ErrorsTest::AlbumForm.new(album)
47
-
48
- form.title.must_equal "GI"
49
-
50
- form.validate("title" => nil)
51
- form.title.must_equal nil
52
- form.sync
53
- album.title.must_equal nil
54
- end
55
- end
56
- end