reform 2.2.4 → 2.3.1

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 (99) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +5 -1
  3. data/.rubocop.yml +30 -0
  4. data/.rubocop_todo.yml +460 -0
  5. data/.travis.yml +11 -6
  6. data/Appraisals +8 -0
  7. data/CHANGES.md +54 -4
  8. data/CONTRIBUTING.md +31 -0
  9. data/Gemfile +2 -16
  10. data/ISSUE_TEMPLATE.md +25 -0
  11. data/LICENSE.txt +1 -1
  12. data/README.md +5 -7
  13. data/Rakefile +18 -9
  14. data/gemfiles/0.13.0.gemfile +8 -0
  15. data/gemfiles/1.5.0.gemfile +9 -0
  16. data/lib/reform.rb +1 -0
  17. data/lib/reform/contract.rb +7 -17
  18. data/lib/reform/contract/custom_error.rb +41 -0
  19. data/lib/reform/contract/validate.rb +53 -23
  20. data/lib/reform/errors.rb +61 -0
  21. data/lib/reform/form.rb +36 -10
  22. data/lib/reform/form/call.rb +1 -1
  23. data/lib/reform/form/composition.rb +2 -2
  24. data/lib/reform/form/dry.rb +10 -58
  25. data/lib/reform/form/dry/input_hash.rb +37 -0
  26. data/lib/reform/form/dry/new_api.rb +46 -0
  27. data/lib/reform/form/dry/old_api.rb +61 -0
  28. data/lib/reform/form/populator.rb +11 -27
  29. data/lib/reform/form/prepopulate.rb +4 -3
  30. data/lib/reform/form/validate.rb +28 -13
  31. data/lib/reform/result.rb +90 -0
  32. data/lib/reform/validation.rb +19 -11
  33. data/lib/reform/validation/groups.rb +12 -27
  34. data/lib/reform/version.rb +1 -1
  35. data/reform.gemspec +15 -13
  36. data/test/benchmarking.rb +39 -6
  37. data/test/call_new_api.rb +23 -0
  38. data/test/{call_test.rb → call_old_api.rb} +4 -4
  39. data/test/changed_test.rb +8 -8
  40. data/test/coercion_test.rb +51 -19
  41. data/test/composition_new_api.rb +186 -0
  42. data/test/{composition_test.rb → composition_old_api.rb} +66 -31
  43. data/test/contract/custom_error_test.rb +55 -0
  44. data/test/contract_new_api.rb +77 -0
  45. data/test/{contract_test.rb → contract_old_api.rb} +13 -13
  46. data/test/default_test.rb +2 -2
  47. data/test/deserialize_test.rb +11 -14
  48. data/test/errors_new_api.rb +225 -0
  49. data/test/errors_old_api.rb +230 -0
  50. data/test/feature_test.rb +8 -10
  51. data/test/fixtures/dry_error_messages.yml +73 -23
  52. data/test/fixtures/dry_new_api_error_messages.yml +104 -0
  53. data/test/form_new_api.rb +57 -0
  54. data/test/{form_test.rb → form_old_api.rb} +5 -5
  55. data/test/form_option_new_api.rb +24 -0
  56. data/test/{form_option_test.rb → form_option_old_api.rb} +4 -4
  57. data/test/from_test.rb +9 -13
  58. data/test/inherit_new_api.rb +105 -0
  59. data/test/inherit_old_api.rb +105 -0
  60. data/test/{module_test.rb → module_new_api.rb} +20 -25
  61. data/test/module_old_api.rb +146 -0
  62. data/test/parse_option_test.rb +40 -0
  63. data/test/parse_pipeline_test.rb +3 -3
  64. data/test/populate_new_api.rb +304 -0
  65. data/test/{populate_test.rb → populate_old_api.rb} +83 -49
  66. data/test/populator_skip_test.rb +9 -9
  67. data/test/prepopulator_test.rb +8 -9
  68. data/test/read_only_test.rb +12 -1
  69. data/test/readable_test.rb +7 -7
  70. data/test/reform_new_api.rb +204 -0
  71. data/test/{reform_test.rb → reform_old_api.rb} +30 -51
  72. data/test/save_new_api.rb +101 -0
  73. data/test/{save_test.rb → save_old_api.rb} +32 -20
  74. data/test/setup_test.rb +8 -8
  75. data/test/{skip_if_test.rb → skip_if_new_api.rb} +23 -12
  76. data/test/skip_if_old_api.rb +92 -0
  77. data/test/skip_setter_and_getter_test.rb +3 -4
  78. data/test/test_helper.rb +25 -14
  79. data/test/validate_new_api.rb +408 -0
  80. data/test/{validate_test.rb → validate_old_api.rb} +59 -69
  81. data/test/validation/dry_validation_new_api.rb +836 -0
  82. data/test/validation/dry_validation_old_api.rb +772 -0
  83. data/test/validation/result_test.rb +77 -0
  84. data/test/validation_library_provided_test.rb +16 -0
  85. data/test/virtual_test.rb +47 -7
  86. data/test/writeable_test.rb +35 -6
  87. metadata +127 -56
  88. data/gemfiles/Gemfile.disposable-0.3 +0 -6
  89. data/lib/reform/contract/errors.rb +0 -43
  90. data/lib/reform/form/mongoid.rb +0 -37
  91. data/lib/reform/form/orm.rb +0 -26
  92. data/lib/reform/mongoid.rb +0 -4
  93. data/test/deprecation_test.rb +0 -27
  94. data/test/errors_test.rb +0 -165
  95. data/test/inherit_test.rb +0 -119
  96. data/test/readonly_test.rb +0 -14
  97. data/test/validation/dry_test.rb +0 -60
  98. data/test/validation/dry_validation_test.rb +0 -352
  99. data/test/validation/errors.yml +0 -4
@@ -0,0 +1,57 @@
1
+ require "test_helper"
2
+
3
+ class FormTest < MiniTest::Spec
4
+ Artist = Struct.new(:name)
5
+
6
+ class AlbumForm < TestForm
7
+ property :title
8
+
9
+ property :hit do
10
+ property :title
11
+ end
12
+
13
+ collection :songs do
14
+ property :title
15
+ end
16
+
17
+ property :band do # yepp, people do crazy stuff like that.
18
+ property :label do
19
+ property :name
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "::dup" do
25
+ let(:cloned) { AlbumForm.clone }
26
+
27
+ # #dup is called in Op.inheritable_attr(:contract_class), it must be subclass of the original one.
28
+ it { cloned.wont_equal AlbumForm }
29
+ it { AlbumForm.definitions.wont_equal cloned.definitions }
30
+
31
+ it do
32
+ # currently, forms need a name for validation, even without AM.
33
+ cloned.singleton_class.class_eval do
34
+ def name
35
+ "Album"
36
+ end
37
+ end
38
+
39
+ cloned.validation do
40
+ params { required(:title).filled }
41
+ end
42
+
43
+ cloned.new(OpenStruct.new).validate({})
44
+ end
45
+ end
46
+
47
+ describe "#initialize" do
48
+ class ArtistForm < TestForm
49
+ property :name
50
+ property :current_user, virtual: true
51
+ end
52
+
53
+ it "allows injecting :virtual options" do
54
+ ArtistForm.new(Artist.new, current_user: Object).current_user.must_equal Object
55
+ end
56
+ end
57
+ end
@@ -1,9 +1,9 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class FormTest < MiniTest::Spec
4
4
  Artist = Struct.new(:name)
5
5
 
6
- class AlbumForm < Reform::Form
6
+ class AlbumForm < TestForm
7
7
  property :title
8
8
 
9
9
  property :hit do
@@ -22,7 +22,7 @@ class FormTest < MiniTest::Spec
22
22
  end
23
23
 
24
24
  describe "::dup" do
25
- let (:cloned) { AlbumForm.clone }
25
+ let(:cloned) { AlbumForm.clone }
26
26
 
27
27
  # #dup is called in Op.inheritable_attr(:contract_class), it must be subclass of the original one.
28
28
  it { cloned.wont_equal AlbumForm }
@@ -37,7 +37,7 @@ class FormTest < MiniTest::Spec
37
37
  end
38
38
 
39
39
  cloned.validation do
40
- key(:title).required
40
+ required(:title).filled
41
41
  end
42
42
 
43
43
  cloned.new(OpenStruct.new).validate({})
@@ -45,7 +45,7 @@ class FormTest < MiniTest::Spec
45
45
  end
46
46
 
47
47
  describe "#initialize" do
48
- class ArtistForm < Reform::Form
48
+ class ArtistForm < TestForm
49
49
  property :name
50
50
  property :current_user, virtual: true
51
51
  end
@@ -0,0 +1,24 @@
1
+ require "test_helper"
2
+
3
+ class FormOptionTest < MiniTest::Spec
4
+ Song = Struct.new(:title)
5
+ Album = Struct.new(:song)
6
+
7
+ class SongForm < TestForm
8
+ property :title
9
+ validation do
10
+ params { required(:title).filled }
11
+ end
12
+ end
13
+
14
+ class AlbumForm < TestForm
15
+ property :song, form: SongForm
16
+ end
17
+
18
+ it do
19
+ form = AlbumForm.new(Album.new(Song.new("When It Comes To You")))
20
+ form.song.title.must_equal "When It Comes To You"
21
+
22
+ form.validate(song: {title: "Run For Cover"})
23
+ end
24
+ end
@@ -1,17 +1,17 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class FormOptionTest < MiniTest::Spec
4
4
  Song = Struct.new(:title)
5
5
  Album = Struct.new(:song)
6
6
 
7
- class SongForm < Reform::Form
7
+ class SongForm < TestForm
8
8
  property :title
9
9
  validation do
10
- key(:title).required
10
+ required(:title).filled
11
11
  end
12
12
  end
13
13
 
14
- class AlbumForm < Reform::Form
14
+ class AlbumForm < TestForm
15
15
  property :song, form: SongForm
16
16
  end
17
17
 
@@ -1,7 +1,7 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class AsTest < BaseTest
4
- class AlbumForm < Reform::Form
4
+ class AlbumForm < TestForm
5
5
  property :name, from: :title
6
6
 
7
7
  property :single, from: :hit do
@@ -19,15 +19,15 @@ class AsTest < BaseTest
19
19
  end
20
20
  end
21
21
 
22
- let (:song2) { Song.new("Roxanne") }
22
+ let(:song2) { Song.new("Roxanne") }
23
23
 
24
- let (:params) {
24
+ let(:params) do
25
25
  {
26
26
  "name" => "Best Of The Police",
27
- "single" => {"title" => "So Lonely"},
27
+ "single" => {"title" => "So Lonely"},
28
28
  "tracks" => [{"name" => "Message In A Bottle"}, {"name" => "Roxanne"}]
29
29
  }
30
- }
30
+ end
31
31
 
32
32
  subject { AlbumForm.new(Album.new("Best Of", hit, [Song.new("Fallout"), song2])) }
33
33
 
@@ -36,10 +36,8 @@ class AsTest < BaseTest
36
36
  it { subject.tracks[0].name.must_equal "Fallout" }
37
37
  it { subject.tracks[1].name.must_equal "Roxanne" }
38
38
 
39
-
40
39
  describe "#validate" do
41
40
 
42
-
43
41
  before { subject.validate(params) }
44
42
 
45
43
  it { subject.name.must_equal "Best Of The Police" }
@@ -48,17 +46,15 @@ class AsTest < BaseTest
48
46
  it { subject.tracks[1].name.must_equal "Roxanne" }
49
47
  end
50
48
 
51
-
52
49
  describe "#sync" do
53
- before {
50
+ before do
54
51
  subject.tracks[1].name = "Livin' Ain't No Crime"
55
52
  subject.sync
56
- }
53
+ end
57
54
 
58
55
  it { song2.title.must_equal "Livin' Ain't No Crime" }
59
56
  end
60
57
 
61
-
62
58
  describe "#save (nested hash)" do
63
59
  before { subject.validate(params) }
64
60
 
@@ -69,7 +65,7 @@ class AsTest < BaseTest
69
65
  hash = nested_hash
70
66
  end
71
67
 
72
- hash.must_equal({"title"=>"Best Of The Police", "hit"=>{"title"=>"So Lonely"}, "songs"=>[{"title"=>"Message In A Bottle"}, {"title"=>"Roxanne"}]})
68
+ hash.must_equal({"title" => "Best Of The Police", "hit" => {"title" => "So Lonely"}, "songs" => [{"title" => "Message In A Bottle"}, {"title" => "Roxanne"}], "band" => nil})
73
69
  end
74
70
  end
75
71
  end
@@ -0,0 +1,105 @@
1
+ require "test_helper"
2
+ require "representable/json"
3
+
4
+ class InheritTest < BaseTest
5
+ Populator = Reform::Form::Populator
6
+
7
+ class SkipParse
8
+ include Uber::Callable
9
+ def call(*_args)
10
+ false
11
+ end
12
+ end
13
+
14
+ class AlbumForm < TestForm
15
+ property :title, deserializer: {instance: "Instance"}, skip_if: "skip_if in AlbumForm" # allow direct configuration of :deserializer.
16
+
17
+ property :hit, populate_if_empty: ->(*) { Song.new } do
18
+ property :title
19
+ validation do
20
+ params { required(:title).filled }
21
+ end
22
+ end
23
+
24
+ collection :songs, populate_if_empty: -> {}, skip_if: :all_blank do
25
+ property :title
26
+ end
27
+
28
+ property :band, populate_if_empty: -> {} do
29
+ def band_id
30
+ 1
31
+ end
32
+ end
33
+ end
34
+
35
+ class CompilationForm < AlbumForm
36
+ property :title, inherit: true, skip_if: "skip_if from CompilationForm"
37
+ property :hit, inherit: true, populate_if_empty: ->(*) { Song.new }, skip_if: SkipParse.new do
38
+ property :rating
39
+ validation do
40
+ params { required(:rating).filled }
41
+ end
42
+ end
43
+
44
+ # NO collection here, this is entirely inherited.
45
+
46
+ property :band, inherit: true do # inherit everything, but explicitely.
47
+ end
48
+ end
49
+
50
+ let(:album) { Album.new(nil, Song.new, [], Band.new) }
51
+ subject { CompilationForm.new(album) }
52
+
53
+ it do
54
+ subject.validate("hit" => {"title" => "LA Drone", "rating" => 10})
55
+ subject.hit.title.must_equal "LA Drone"
56
+ subject.hit.rating.must_equal 10
57
+ subject.errors.messages.must_equal({})
58
+ end
59
+
60
+ it do
61
+ subject.validate({})
62
+ assert_nil subject.model.hit.title
63
+ assert_nil subject.model.hit.rating
64
+ subject.errors.messages.must_equal("hit.title": ["must be filled"], "hit.rating": ["must be filled"])
65
+ end
66
+
67
+ it "xxx" do
68
+ # sub hashes like :deserializer must be properly cloned when inheriting.
69
+ AlbumForm.options_for(:title)[:deserializer].object_id.wont_equal CompilationForm.options_for(:title)[:deserializer].object_id
70
+
71
+ # don't overwrite direct deserializer: {} configuration.
72
+ AlbumForm.options_for(:title)[:internal_populator].must_be_instance_of Reform::Form::Populator::Sync
73
+ AlbumForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if in AlbumForm"
74
+
75
+ # AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
76
+ # AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_be_instance_with Reform::Form::Populator, user_proc: "Populator"
77
+
78
+ AlbumForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
79
+ AlbumForm.options_for(:songs)[:deserializer][:skip_parse].must_be_instance_of Reform::Form::Validate::Skip::AllBlank
80
+
81
+ AlbumForm.options_for(:band)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
82
+
83
+ CompilationForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if from CompilationForm"
84
+ # pp CompilationForm.options_for(:songs)
85
+ CompilationForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
86
+
87
+ CompilationForm.options_for(:band)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
88
+
89
+ # completely overwrite inherited.
90
+ CompilationForm.options_for(:hit)[:deserializer][:skip_parse].must_be_instance_of SkipParse
91
+
92
+ # inherit: true with block will still inherit the original class.
93
+ AlbumForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id.must_equal 1
94
+ CompilationForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id.must_equal 1
95
+ end
96
+
97
+ class CDForm < AlbumForm
98
+ # override :band's original populate_if_empty but with :inherit.
99
+ property :band, inherit: true, populator: "CD Populator" do
100
+
101
+ end
102
+ end
103
+
104
+ it { CDForm.options_for(:band)[:internal_populator].instance_variable_get(:@user_proc).must_equal "CD Populator" }
105
+ end
@@ -0,0 +1,105 @@
1
+ require "test_helper"
2
+ require "representable/json"
3
+
4
+ class InheritTest < BaseTest
5
+ Populator = Reform::Form::Populator
6
+
7
+ class SkipParse
8
+ include Uber::Callable
9
+ def call(*_args)
10
+ false
11
+ end
12
+ end
13
+
14
+ class AlbumForm < TestForm
15
+ property :title, deserializer: {instance: "Instance"}, skip_if: "skip_if in AlbumForm" # allow direct configuration of :deserializer.
16
+
17
+ property :hit, populate_if_empty: ->(*) { Song.new } do
18
+ property :title
19
+ validation do
20
+ required(:title).filled
21
+ end
22
+ end
23
+
24
+ collection :songs, populate_if_empty: -> {}, skip_if: :all_blank do
25
+ property :title
26
+ end
27
+
28
+ property :band, populate_if_empty: -> {} do
29
+ def band_id
30
+ 1
31
+ end
32
+ end
33
+ end
34
+
35
+ class CompilationForm < AlbumForm
36
+ property :title, inherit: true, skip_if: "skip_if from CompilationForm"
37
+ property :hit, inherit: true, populate_if_empty: ->(*) { Song.new }, skip_if: SkipParse.new do
38
+ property :rating
39
+ validation do
40
+ required(:rating).filled
41
+ end
42
+ end
43
+
44
+ # NO collection here, this is entirely inherited.
45
+
46
+ property :band, inherit: true do # inherit everything, but explicitely.
47
+ end
48
+ end
49
+
50
+ let(:album) { Album.new(nil, Song.new, [], Band.new) }
51
+ subject { CompilationForm.new(album) }
52
+
53
+ it do
54
+ subject.validate("hit" => {"title" => "LA Drone", "rating" => 10})
55
+ subject.hit.title.must_equal "LA Drone"
56
+ subject.hit.rating.must_equal 10
57
+ subject.errors.messages.must_equal({})
58
+ end
59
+
60
+ it do
61
+ subject.validate({})
62
+ assert_nil subject.model.hit.title
63
+ assert_nil subject.model.hit.rating
64
+ subject.errors.messages.must_equal("hit.title": ["must be filled"], "hit.rating": ["must be filled"])
65
+ end
66
+
67
+ it "xxx" do
68
+ # sub hashes like :deserializer must be properly cloned when inheriting.
69
+ AlbumForm.options_for(:title)[:deserializer].object_id.wont_equal CompilationForm.options_for(:title)[:deserializer].object_id
70
+
71
+ # don't overwrite direct deserializer: {} configuration.
72
+ AlbumForm.options_for(:title)[:internal_populator].must_be_instance_of Reform::Form::Populator::Sync
73
+ AlbumForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if in AlbumForm"
74
+
75
+ # AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
76
+ # AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_be_instance_with Reform::Form::Populator, user_proc: "Populator"
77
+
78
+ AlbumForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
79
+ AlbumForm.options_for(:songs)[:deserializer][:skip_parse].must_be_instance_of Reform::Form::Validate::Skip::AllBlank
80
+
81
+ AlbumForm.options_for(:band)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
82
+
83
+ CompilationForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if from CompilationForm"
84
+ # pp CompilationForm.options_for(:songs)
85
+ CompilationForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
86
+
87
+ CompilationForm.options_for(:band)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
88
+
89
+ # completely overwrite inherited.
90
+ CompilationForm.options_for(:hit)[:deserializer][:skip_parse].must_be_instance_of SkipParse
91
+
92
+ # inherit: true with block will still inherit the original class.
93
+ AlbumForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id.must_equal 1
94
+ CompilationForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id.must_equal 1
95
+ end
96
+
97
+ class CDForm < AlbumForm
98
+ # override :band's original populate_if_empty but with :inherit.
99
+ property :band, inherit: true, populator: "CD Populator" do
100
+
101
+ end
102
+ end
103
+
104
+ it { CDForm.options_for(:band)[:internal_populator].instance_variable_get(:@user_proc).must_equal "CD Populator" }
105
+ end
@@ -1,5 +1,5 @@
1
1
  require "test_helper"
2
- require 'reform/form/coercion'
2
+ require "reform/form/coercion"
3
3
 
4
4
  class ModuleInclusionTest < MiniTest::Spec
5
5
  module BandPropertyForm
@@ -9,7 +9,7 @@ class ModuleInclusionTest < MiniTest::Spec
9
9
  property :title
10
10
 
11
11
  validation do
12
- key(:title).required
12
+ params { required(:title).filled }
13
13
  end
14
14
 
15
15
  def id # gets mixed into Form, too.
@@ -22,11 +22,11 @@ class ModuleInclusionTest < MiniTest::Spec
22
22
  end
23
23
 
24
24
  validation do
25
- key(:band).required
25
+ params { required(:band).filled }
26
26
  end
27
27
 
28
28
  include Dry::Types.module # allows using Types::* in module.
29
- property :cool, type: Form::Bool # test coercion.
29
+ property :cool, type: DRY_TYPES_CONSTANT::Bool # test coercion.
30
30
  end
31
31
 
32
32
  # TODO: test if works, move stuff into inherit_schema!
@@ -36,30 +36,28 @@ class ModuleInclusionTest < MiniTest::Spec
36
36
  collection :airplays do
37
37
  property :station
38
38
  validation do
39
- key(:station).required
39
+ params { required(:station).filled }
40
40
  end
41
41
  end
42
42
  validation do
43
- key(:airplays).required
43
+ params { required(:airplays).filled }
44
44
  end
45
45
  end
46
46
 
47
-
48
47
  # test:
49
48
  # by including BandPropertyForm into multiple classes we assure that options hashes don't get messed up by AM:V.
50
- class HitForm < Reform::Form
49
+ class HitForm < TestForm
51
50
  include BandPropertyForm
52
51
  end
53
52
 
54
- class SongForm < Reform::Form
53
+ class SongForm < TestForm
55
54
  include Coercion
56
55
  property :title
57
56
 
58
57
  include BandPropertyForm
59
58
  end
60
59
 
61
-
62
- let (:song) { OpenStruct.new(:band => OpenStruct.new(:title => "Time Again")) }
60
+ let(:song) { OpenStruct.new(band: OpenStruct.new(title: "Time Again")) }
63
61
 
64
62
  # nested form from module is present and creates accessor.
65
63
  it { SongForm.new(song).band.title.must_equal "Time Again" }
@@ -72,17 +70,16 @@ class ModuleInclusionTest < MiniTest::Spec
72
70
  it do
73
71
  form = SongForm.new(OpenStruct.new)
74
72
  form.validate({})
75
- form.errors.messages.must_equal({:band=>["is missing"]})
73
+ form.errors.messages.must_equal(band: ["must be filled"])
76
74
  end
77
75
 
78
76
  # coercion works
79
77
  it do
80
78
  form = SongForm.new(OpenStruct.new)
81
- form.validate({cool: "1"})
79
+ form.validate(cool: "1")
82
80
  form.cool.must_equal true
83
81
  end
84
82
 
85
-
86
83
  # include a module into a module into a class :)
87
84
  module AlbumFormModule
88
85
  include Reform::Form::Module
@@ -90,29 +87,28 @@ class ModuleInclusionTest < MiniTest::Spec
90
87
 
91
88
  property :name
92
89
  validation do
93
- key(:name).required
90
+ params { required(:name).filled }
94
91
  end
95
92
  end
96
93
 
97
- class AlbumForm < Reform::Form
94
+ class AlbumForm < TestForm
98
95
  include AlbumFormModule
99
96
 
100
97
  # pp heritage
101
- property :band, :inherit => true do
98
+ property :band, inherit: true do
102
99
  property :label
103
100
  validation do
104
- key(:label).required
101
+ params { required(:label).filled }
105
102
  end
106
103
  end
107
104
  end
108
105
 
109
106
  it do
110
- form = AlbumForm.new(OpenStruct.new(:band => OpenStruct.new))
111
- form.validate({"band" => {}})
112
- form.errors.messages.must_equal({:band=>["must be filled"], :"band.title"=>["is missing"], :"band.label"=>["is missing"], :name=>["is missing"]})
107
+ form = AlbumForm.new(OpenStruct.new(band: OpenStruct.new))
108
+ form.validate("band" => {})
109
+ form.errors.messages.must_equal("band.title": ["must be filled"], "band.label": ["must be filled"], name: ["must be filled"])
113
110
  end
114
111
 
115
-
116
112
  describe "module with custom accessors" do
117
113
  module SongModule
118
114
  include Reform::Form::Module
@@ -127,11 +123,11 @@ class ModuleInclusionTest < MiniTest::Spec
127
123
  end
128
124
  end
129
125
 
130
- class IncludingSongForm < Reform::Form
126
+ class IncludingSongForm < TestForm
131
127
  include SongModule
132
128
  end
133
129
 
134
- let (:song) { OpenStruct.new(id: 1, title: "Instant Mash") }
130
+ let(:song) { OpenStruct.new(id: 1, title: "Instant Mash") }
135
131
 
136
132
  it do
137
133
  IncludingSongForm.new(song).id.must_equal 1
@@ -139,4 +135,3 @@ class ModuleInclusionTest < MiniTest::Spec
139
135
  end
140
136
  end
141
137
  end
142
-