reform 2.2.4 → 2.6.2

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 (76) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +17 -0
  3. data/.gitignore +5 -1
  4. data/CHANGES.md +80 -4
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +2 -16
  7. data/ISSUE_TEMPLATE.md +25 -0
  8. data/LICENSE.txt +1 -1
  9. data/README.md +10 -12
  10. data/Rakefile +6 -10
  11. data/lib/reform/contract/custom_error.rb +41 -0
  12. data/lib/reform/contract/validate.rb +53 -23
  13. data/lib/reform/contract.rb +7 -17
  14. data/lib/reform/errors.rb +61 -0
  15. data/lib/reform/form/call.rb +1 -1
  16. data/lib/reform/form/composition.rb +2 -2
  17. data/lib/reform/form/dry/input_hash.rb +37 -0
  18. data/lib/reform/form/dry.rb +25 -35
  19. data/lib/reform/form/populator.rb +20 -26
  20. data/lib/reform/form/prepopulate.rb +5 -4
  21. data/lib/reform/form/validate.rb +29 -14
  22. data/lib/reform/form.rb +36 -10
  23. data/lib/reform/result.rb +90 -0
  24. data/lib/reform/validation/groups.rb +12 -28
  25. data/lib/reform/validation.rb +19 -11
  26. data/lib/reform/version.rb +1 -1
  27. data/lib/reform.rb +1 -0
  28. data/reform.gemspec +13 -13
  29. data/test/benchmarking.rb +39 -6
  30. data/test/call_test.rb +9 -9
  31. data/test/changed_test.rb +14 -14
  32. data/test/coercion_test.rb +57 -25
  33. data/test/composition_test.rb +85 -49
  34. data/test/contract/custom_error_test.rb +55 -0
  35. data/test/contract_test.rb +20 -20
  36. data/test/default_test.rb +4 -4
  37. data/test/deserialize_test.rb +17 -20
  38. data/test/docs/validation_test.rb +134 -0
  39. data/test/errors_test.rb +142 -82
  40. data/test/feature_test.rb +10 -12
  41. data/test/fixtures/dry_error_messages.yml +83 -23
  42. data/test/form_option_test.rb +5 -5
  43. data/test/form_test.rb +8 -8
  44. data/test/from_test.rb +18 -22
  45. data/test/inherit_test.rb +54 -68
  46. data/test/module_test.rb +27 -32
  47. data/test/parse_option_test.rb +40 -0
  48. data/test/parse_pipeline_test.rb +4 -4
  49. data/test/populate_test.rb +217 -100
  50. data/test/populator_skip_test.rb +11 -11
  51. data/test/prepopulator_test.rb +24 -25
  52. data/test/read_only_test.rb +12 -1
  53. data/test/readable_test.rb +9 -9
  54. data/test/reform_test.rb +47 -66
  55. data/test/save_test.rb +35 -23
  56. data/test/setup_test.rb +17 -17
  57. data/test/skip_if_test.rb +33 -22
  58. data/test/skip_setter_and_getter_test.rb +9 -10
  59. data/test/test_helper.rb +23 -14
  60. data/test/validate_test.rb +165 -145
  61. data/test/validation/dry_validation_test.rb +630 -146
  62. data/test/validation/result_test.rb +77 -0
  63. data/test/validation_library_provided_test.rb +16 -0
  64. data/test/virtual_test.rb +47 -7
  65. data/test/writeable_test.rb +38 -9
  66. metadata +46 -38
  67. data/.travis.yml +0 -11
  68. data/gemfiles/Gemfile.disposable-0.3 +0 -6
  69. data/lib/reform/contract/errors.rb +0 -43
  70. data/lib/reform/form/mongoid.rb +0 -37
  71. data/lib/reform/form/orm.rb +0 -26
  72. data/lib/reform/mongoid.rb +0 -4
  73. data/test/deprecation_test.rb +0 -27
  74. data/test/readonly_test.rb +0 -14
  75. data/test/validation/dry_test.rb +0 -60
  76. data/test/validation/errors.yml +0 -4
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
  require "representable/json"
3
3
 
4
4
  class DeserializeTest < MiniTest::Spec
@@ -6,11 +6,11 @@ class DeserializeTest < MiniTest::Spec
6
6
  Album = Struct.new(:title, :artist)
7
7
  Artist = Struct.new(:name, :callname)
8
8
 
9
- class JsonAlbumForm < Reform::Form
9
+ class JsonAlbumForm < TestForm
10
10
  module Json
11
11
  def deserialize(params)
12
12
  deserializer.new(self).
13
- # extend(Representable::Debug).
13
+ # extend(Representable::Debug).
14
14
  from_json(params)
15
15
  end
16
16
 
@@ -18,7 +18,7 @@ class DeserializeTest < MiniTest::Spec
18
18
  Disposable::Rescheme.from(self.class,
19
19
  include: [Representable::JSON],
20
20
  superclass: Representable::Decorator,
21
- definitions_from: lambda { |inline| inline.definitions },
21
+ definitions_from: ->(inline) { inline.definitions },
22
22
  options_from: :deserializer,
23
23
  exclude_options: [:populator]
24
24
  )
@@ -26,15 +26,13 @@ class DeserializeTest < MiniTest::Spec
26
26
  end
27
27
  include Json
28
28
 
29
-
30
29
  property :title
31
30
  property :artist, populate_if_empty: Artist do
32
31
  property :name
33
32
  end
34
33
  end
35
34
 
36
-
37
- let (:artist) { Artist.new("A-ha") }
35
+ let(:artist) { Artist.new("A-ha") }
38
36
  it do
39
37
  artist_id = artist.object_id
40
38
 
@@ -43,13 +41,13 @@ class DeserializeTest < MiniTest::Spec
43
41
 
44
42
  form.validate(json)
45
43
 
46
- form.title.must_equal "Apocalypse Soon"
47
- form.artist.name.must_equal "Mute"
48
- form.artist.model.object_id.must_equal artist_id
44
+ assert_equal form.title, "Apocalypse Soon"
45
+ assert_equal form.artist.name, "Mute"
46
+ assert_equal form.artist.model.object_id, artist_id
49
47
  end
50
48
 
51
49
  describe "infering the deserializer from another form should NOT copy its populators" do
52
- class CompilationForm < Reform::Form
50
+ class CompilationForm < TestForm
53
51
  property :artist, populator: ->(options) { self.artist = Artist.new(nil, options[:fragment].to_s) } do
54
52
  property :name
55
53
  end
@@ -62,20 +60,19 @@ class DeserializeTest < MiniTest::Spec
62
60
  # also tests the Form#deserializer API. # FIXME.
63
61
  it "uses deserializer inferred from JsonAlbumForm but deserializes/populates to CompilationForm" do
64
62
  form = CompilationForm.new(Album.new)
65
- form.validate("artist"=> {"name" => "Horowitz"}) # the deserializer doesn't know symbols.
63
+ form.validate("artist" => {"name" => "Horowitz"}) # the deserializer doesn't know symbols.
66
64
  form.sync
67
- form.artist.model.must_equal Artist.new("Horowitz", %{{"name"=>"Horowitz"}})
65
+ assert_equal form.artist.model, Artist.new("Horowitz", %{{"name"=>"Horowitz"}})
68
66
  end
69
67
  end
70
68
  end
71
69
 
72
-
73
70
  class ValidateWithBlockTest < MiniTest::Spec
74
71
  Song = Struct.new(:title, :album, :composer)
75
72
  Album = Struct.new(:title, :artist)
76
73
  Artist = Struct.new(:name)
77
74
 
78
- class AlbumForm < Reform::Form
75
+ class AlbumForm < TestForm
79
76
  property :title
80
77
  property :artist, populate_if_empty: Artist do
81
78
  property :name
@@ -90,15 +87,15 @@ class ValidateWithBlockTest < MiniTest::Spec
90
87
  deserializer = Disposable::Rescheme.from(AlbumForm,
91
88
  include: [Representable::JSON],
92
89
  superclass: Representable::Decorator,
93
- definitions_from: lambda { |inline| inline.definitions },
90
+ definitions_from: ->(inline) { inline.definitions },
94
91
  options_from: :deserializer
95
92
  )
96
93
 
97
- form.validate(json) do |params|
94
+ assert form.validate(json) { |params|
98
95
  deserializer.new(form).from_json(params)
99
- end.must_equal true # with block must return result, too.
96
+ } # with block must return result, too.
100
97
 
101
- form.title.must_equal "Apocalypse Soon"
102
- form.artist.name.must_equal "Mute"
98
+ assert_equal form.title, "Apocalypse Soon"
99
+ assert_equal form.artist.name, "Mute"
103
100
  end
104
101
  end
@@ -0,0 +1,134 @@
1
+ require 'test_helper'
2
+ require 'reform/form/dry'
3
+
4
+ class DocsDryVTest < Minitest::Spec
5
+ #:basic
6
+ class AlbumForm < Reform::Form
7
+ feature Reform::Form::Dry
8
+
9
+ property :name
10
+
11
+ validation do
12
+ params do
13
+ required(:name).filled
14
+ end
15
+ end
16
+ end
17
+ #:basic end
18
+
19
+ it 'validates correctly' do
20
+ form = DocsDryVTest::AlbumForm.new(Album.new(nil, nil, nil))
21
+ result = form.call(name: nil)
22
+
23
+ refute result.success?
24
+ assert_equal({ name: ['must be filled'] }, form.errors.messages)
25
+ end
26
+ end
27
+
28
+ class DocsDryVWithRulesTest < Minitest::Spec
29
+ #:basic_with_rules
30
+ class AlbumForm < Reform::Form
31
+ feature Reform::Form::Dry
32
+
33
+ property :name
34
+
35
+ validation name: :default do
36
+ option :form
37
+
38
+ params do
39
+ required(:name).filled
40
+ end
41
+
42
+ rule(:name) do
43
+ key.failure('must be unique') if Album.where.not(id: form.model.id).where(name: value).exists?
44
+ end
45
+ end
46
+ end
47
+ #:basic_with_rules end
48
+
49
+ it 'validates correctly' do
50
+ Album = Struct.new(:name, :songs, :artist, :user)
51
+ form = DocsDryVWithRulesTest::AlbumForm.new(Album.new(nil, nil, nil, nil))
52
+ result = form.call(name: nil)
53
+
54
+ refute result.success?
55
+ assert_equal({ name: ['must be filled'] }, form.errors.messages)
56
+ end
57
+ end
58
+
59
+ class DryVWithNestedTest < Minitest::Spec
60
+ #:nested
61
+ class AlbumForm < Reform::Form
62
+ feature Reform::Form::Dry
63
+
64
+ property :name
65
+
66
+ validation do
67
+ params { required(:name).filled }
68
+ end
69
+
70
+ property :artist do
71
+ property :name
72
+
73
+ validation do
74
+ params { required(:name).filled }
75
+ end
76
+ end
77
+ end
78
+ #:nested end
79
+
80
+ it 'validates correctly' do
81
+ form = DryVWithNestedTest::AlbumForm.new(Album.new(nil, nil, Artist.new(nil)))
82
+ result = form.call(name: nil, artist: { name: '' })
83
+
84
+ refute result.success?
85
+ assert_equal({ name: ['must be filled'], 'artist.name': ['must be filled'] }, form.errors.messages)
86
+ end
87
+ end
88
+
89
+ class DryVValGroupTest < Minitest::Spec
90
+ class AlbumForm < Reform::Form
91
+ feature Reform::Form::Dry
92
+
93
+ property :name
94
+ property :artist
95
+ #:validation_groups
96
+ validation name: :default do
97
+ params { required(:name).filled }
98
+ end
99
+
100
+ validation name: :artist, if: :default do
101
+ params { required(:artist).filled }
102
+ end
103
+
104
+ validation name: :famous, after: :default do
105
+ params { optional(:artist) }
106
+
107
+ rule(:artist) do
108
+ if value
109
+ key.failure('only famous artist') unless value =~ /famous/
110
+ end
111
+ end
112
+ end
113
+ #:validation_groups end
114
+ end
115
+
116
+ it 'validates correctly' do
117
+ form = DryVValGroupTest::AlbumForm.new(Album.new(nil, nil, nil))
118
+ result = form.call(name: nil)
119
+
120
+ refute result.success?
121
+ assert_equal({ name: ['must be filled'] }, result.errors.messages)
122
+
123
+ result = form.call(name: 'Title')
124
+ refute result.success?
125
+ assert_equal({ artist: ['must be filled'] }, result.errors.messages)
126
+
127
+ result = form.call(name: 'Title', artist: 'Artist')
128
+ refute result.success?
129
+ assert_equal({ artist: ['only famous artist'] }, result.errors.messages)
130
+
131
+ result = form.call(name: 'Title', artist: 'Artist famous')
132
+ assert result.success?
133
+ end
134
+ end
data/test/errors_test.rb CHANGED
@@ -1,20 +1,28 @@
1
1
  require "test_helper"
2
2
 
3
3
  class ErrorsTest < MiniTest::Spec
4
- class AlbumForm < Reform::Form
4
+ class AlbumForm < TestForm
5
5
  property :title
6
+ validation do
7
+ params { required(:title).filled }
8
+ end
9
+
10
+ property :artists, default: []
11
+ property :producer do
12
+ property :name
13
+ end
6
14
 
7
15
  property :hit do
8
16
  property :title
9
17
  validation do
10
- required(:title).filled
18
+ params { required(:title).filled }
11
19
  end
12
20
  end
13
21
 
14
22
  collection :songs do
15
23
  property :title
16
24
  validation do
17
- required(:title).filled
25
+ params { required(:title).filled }
18
26
  end
19
27
  end
20
28
 
@@ -23,143 +31,195 @@ class ErrorsTest < MiniTest::Spec
23
31
  property :label do
24
32
  property :name
25
33
  validation do
26
- required(:name).filled
34
+ params { required(:name).filled }
27
35
  end
28
36
  end
29
37
  # TODO: make band a required object.
30
38
 
31
39
  validation do
32
- # required(:name).filled(:music_taste_ok?)
40
+ config.messages.load_paths << "test/fixtures/dry_error_messages.yml"
33
41
 
34
- configure do
35
- config.messages_file = "test/validation/errors.yml"
42
+ params { required(:name).filled }
36
43
 
37
- def music_taste_ok?(value)
38
- value != "Nickelback"
39
- # errors.add(:base, "You are a bad person") if name == "Nickelback"
40
- end
41
- end
44
+ rule(:name) { key.failure(:good_musical_taste?) if value == "Nickelback" }
42
45
  end
43
- # validate :music_taste_ok?
44
-
45
- # private
46
- # def music_taste_ok?
47
- # errors.add(:base, "You are a bad person") if name == "Nickelback"
48
- # end
49
46
  end
50
47
 
51
48
  validation do
52
- required(:title).filled
49
+ params do
50
+ required(:title).filled
51
+ required(:artists).each(:str?)
52
+ required(:producer).hash do
53
+ required(:name).filled
54
+ end
55
+ end
53
56
  end
54
57
  end
55
58
 
56
- let (:album) do
59
+ let(:album_title) { "Blackhawks Over Los Angeles" }
60
+ let(:album) do
57
61
  OpenStruct.new(
58
- :title => "Blackhawks Over Los Angeles",
59
- :hit => song,
60
- :songs => songs, # TODO: document this requirement,
61
-
62
- :band => Struct.new(:name, :label).new("Epitaph", OpenStruct.new),
62
+ title: album_title,
63
+ hit: song,
64
+ songs: songs, # TODO: document this requirement,
65
+ band: Struct.new(:name, :label).new("Epitaph", OpenStruct.new),
66
+ producer: Struct.new(:name).new("Sun Records")
63
67
  )
64
68
  end
65
- let (:song) { OpenStruct.new(:title => "Downtown") }
66
- let (:songs) { [song=OpenStruct.new(:title => "Calling"), song] }
67
- let (:form) { AlbumForm.new(album) }
68
-
69
+ let(:song) { OpenStruct.new(title: "Downtown") }
70
+ let(:songs) { [song = OpenStruct.new(title: "Calling"), song] }
71
+ let(:form) { AlbumForm.new(album) }
69
72
 
70
- describe "incorrect #validate" do
71
- before { form.validate(
72
- "hit" =>{"title" => ""},
73
- "title" => "",
74
- "songs" => [{"title" => ""}, {"title" => ""}]) } # FIXME: what happens if item is missing?
73
+ describe "#validate with invalid array property" do
74
+ it do
75
+ refute form.validate(
76
+ title: "Swimming Pool - EP",
77
+ band: {
78
+ name: "Marie Madeleine",
79
+ label: {name: "Ekler'o'shocK"}
80
+ },
81
+ artists: [42, "Good Charlotte", 43]
82
+ )
83
+ assert_equal form.errors.messages, artists: {0 => ["must be a string"], 2 => ["must be a string"]}
84
+ assert_equal form.errors.size, 1
85
+ end
86
+ end
75
87
 
88
+ describe "#errors without #validate" do
76
89
  it do
77
- form.errors.messages.must_equal({
78
- :title => ["must be filled"],
79
- :"hit.title"=>["must be filled"],
80
- :"songs.title"=>["must be filled"],
81
- :"band.label.name"=>["is missing"]
82
- })
90
+ assert_equal form.errors.size, 0
91
+ end
92
+ end
93
+
94
+ describe "blank everywhere" do
95
+ before do
96
+ form.validate(
97
+ "hit" => {"title" => ""},
98
+ "title" => "",
99
+ "songs" => [{"title" => ""}, {"title" => ""}],
100
+ "producer" => {"name" => ""}
101
+ )
83
102
  end
84
103
 
85
104
  it do
86
- #form.errors.must_equal({:title => ["must be filled"]})
87
- # TODO: this should only contain local errors?
105
+ assert_equal form.errors.messages,{
106
+ title: ["must be filled"],
107
+ "hit.title": ["must be filled"],
108
+ "songs.title": ["must be filled"],
109
+ "band.label.name": ["must be filled"],
110
+ "producer.name": ["must be filled"]
111
+ }
88
112
  end
89
113
 
114
+ # it do
115
+ # form.errors.must_equal({:title => ["must be filled"]})
116
+ # TODO: this should only contain local errors?
117
+ # end
118
+
90
119
  # nested forms keep their own Errors:
91
- it { form.hit.errors.messages.must_equal({:title=>["must be filled"]}) }
92
- it { form.songs[0].errors.messages.must_equal({:title=>["must be filled"]}) }
120
+ it { assert_equal form.producer.errors.messages, name: ["must be filled"] }
121
+ it { assert_equal form.hit.errors.messages, title: ["must be filled"] }
122
+ it { assert_equal form.songs[0].errors.messages, title: ["must be filled"] }
93
123
 
94
124
  it do
95
- form.errors.messages.must_equal({
96
- :title => ["must be filled"],
97
- :"hit.title" => ["must be filled"],
98
- :"songs.title"=> ["must be filled"],
99
- :"band.label.name"=>["is missing"]
100
- })
125
+ assert_equal form.errors.messages, {
126
+ title: ["must be filled"],
127
+ "hit.title": ["must be filled"],
128
+ "songs.title": ["must be filled"],
129
+ "band.label.name": ["must be filled"],
130
+ "producer.name": ["must be filled"]
131
+ }
132
+ assert_equal form.errors.size, 5
101
133
  end
102
134
  end
103
135
 
104
-
105
136
  describe "#validate with main form invalid" do
106
137
  it do
107
- form.validate("title"=>"", "band"=>{"label"=>{:name => "Fat Wreck"}}).must_equal false
108
- form.errors.messages.must_equal({:title=>["must be filled"]})
138
+ refute form.validate("title" => "", "band" => {"label" => {name: "Fat Wreck"}}, "producer" => nil)
139
+ assert_equal form.errors.messages, title: ["must be filled"], producer: ["must be a hash"]
140
+ assert_equal form.errors.size, 2
109
141
  end
110
142
  end
111
143
 
112
-
113
144
  describe "#validate with middle nested form invalid" do
114
- before { @result = form.validate("hit"=>{"title" => ""}, "band"=>{"label"=>{:name => "Fat Wreck"}}) }
145
+ before { @result = form.validate("hit" => {"title" => ""}, "band" => {"label" => {name: "Fat Wreck"}}) }
115
146
 
116
- it { @result.must_equal false }
117
- it { form.errors.messages.must_equal({:"hit.title"=>["must be filled"]}) }
147
+ it { refute @result }
148
+ it { assert_equal form.errors.messages, "hit.title": ["must be filled"] }
149
+ it { assert_equal form.errors.size, 1 }
118
150
  end
119
151
 
120
-
121
152
  describe "#validate with collection form invalid" do
122
- before { @result = form.validate("songs"=>[{"title" => ""}], "band"=>{"label"=>{:name => "Fat Wreck"}}) }
153
+ before { @result = form.validate("songs" => [{"title" => ""}], "band" => {"label" => {name: "Fat Wreck"}}) }
123
154
 
124
- it { @result.must_equal false }
125
- it { form.errors.messages.must_equal({:"songs.title"=>["must be filled"]}) }
155
+ it { refute @result }
156
+ it { assert_equal form.errors.messages, "songs.title": ["must be filled"] }
157
+ it { assert_equal form.errors.size, 1 }
126
158
  end
127
159
 
128
-
129
160
  describe "#validate with collection and 2-level-nested invalid" do
130
- before { @result = form.validate("songs"=>[{"title" => ""}], "band" => {"label" => {}}) }
161
+ before { @result = form.validate("songs" => [{"title" => ""}], "band" => {"label" => {}}) }
131
162
 
132
- it { @result.must_equal false }
133
- it { form.errors.messages.must_equal({:"songs.title"=>["must be filled"], :"band.label.name"=>["is missing"]}) }
163
+ it { refute @result }
164
+ it { assert_equal form.errors.messages, "songs.title": ["must be filled"], "band.label.name": ["must be filled"] }
165
+ it { assert_equal form.errors.size, 2 }
134
166
  end
135
167
 
136
168
  describe "#validate with nested form using :base invalid" do
137
169
  it do
138
- result = form.validate("songs"=>[{"title" => "Someday"}], "band" => {"name" => "Nickelback", "label" => {"name" => "Roadrunner Records"}})
139
- result.must_equal false
140
- form.errors.messages.must_equal({:"band.name"=>["You are a bad person"]})
170
+ result = form.validate("songs" => [{"title" => "Someday"}], "band" => {"name" => "Nickelback", "label" => {"name" => "Roadrunner Records"}})
171
+ refute result
172
+ assert_equal form.errors.messages, "band.name": ["you're a bad person"]
173
+ assert_equal form.errors.size, 1
141
174
  end
142
175
  end
143
176
 
144
- describe "correct #validate" do
145
- before { @result = form.validate(
146
- "hit" => {"title" => "Sacrifice"},
147
- "title" => "Second Heat",
148
- "songs" => [{"title"=>"Heart Of A Lion"}],
149
- "band" => {"label"=>{:name => "Fat Wreck"}}
150
- ) }
151
-
152
- it { @result.must_equal true }
153
- it { form.hit.title.must_equal "Sacrifice" }
154
- it { form.title.must_equal "Second Heat" }
155
- it { form.songs.first.title.must_equal "Heart Of A Lion" }
177
+ describe "#add" do
178
+ let(:album_title) { nil }
179
+ it do
180
+ result = form.validate("songs" => [{"title" => "Someday"}], "band" => {"name" => "Nickelback", "label" => {"name" => "Roadrunner Records"}})
181
+ refute result
182
+ assert_equal form.errors.messages, title: ["must be filled"], "band.name": ["you're a bad person"]
183
+ # add a new custom error
184
+ form.errors.add(:policy, "error_text")
185
+ assert_equal form.errors.messages, title: ["must be filled"], "band.name": ["you're a bad person"], policy: ["error_text"]
186
+ # does not duplicate errors
187
+ form.errors.add(:title, "must be filled")
188
+ assert_equal form.errors.messages, title: ["must be filled"], "band.name": ["you're a bad person"], policy: ["error_text"]
189
+ # merge existing errors
190
+ form.errors.add(:policy, "another error")
191
+ assert_equal form.errors.messages, title: ["must be filled"], "band.name": ["you're a bad person"], policy: ["error_text", "another error"]
192
+ end
156
193
  end
157
194
 
195
+ describe "correct #validate" do
196
+ before do
197
+ @result = form.validate(
198
+ "hit" => {"title" => "Sacrifice"},
199
+ "title" => "Second Heat",
200
+ "songs" => [{"title" => "Heart Of A Lion"}],
201
+ "band" => {"label" => {name: "Fat Wreck"}}
202
+ )
203
+ end
204
+
205
+ it { assert @result }
206
+ it { assert_equal form.hit.title, "Sacrifice" }
207
+ it { assert_equal form.title, "Second Heat" }
208
+ it { assert_equal form.songs.first.title, "Heart Of A Lion" }
209
+ it do
210
+ skip "WE DON'T NEED COUNT AND EMPTY? ON THE CORE ERRORS OBJECT"
211
+ assert_equal form.errors.size, 0
212
+ assert form.errors.empty
213
+ end
214
+ end
158
215
 
159
216
  describe "Errors#to_s" do
160
- before { form.validate("songs"=>[{"title" => ""}], "band" => {"label" => {}}) }
217
+ before { form.validate("songs" => [{"title" => ""}], "band" => {"label" => {}}) }
161
218
 
162
219
  # to_s is aliased to messages
163
- it { form.errors.to_s.must_equal "{:\"songs.title\"=>[\"must be filled\"], :\"band.label.name\"=>[\"is missing\"]}" }
220
+ it {
221
+ skip "why do we need Errors#to_s ?"
222
+ assert_equal form.errors.to_s, "{:\"songs.title\"=>[\"must be filled\"], :\"band.label.name\"=>[\"must be filled\"]}"
223
+ }
164
224
  end
165
225
  end
data/test/feature_test.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'test_helper'
2
-
3
1
  class FeatureInheritanceTest < BaseTest
4
2
  Song = Struct.new(:title, :album, :composer)
5
3
  Album = Struct.new(:name, :songs, :artist)
@@ -21,7 +19,7 @@ class FeatureInheritanceTest < BaseTest
21
19
  # end
22
20
  # end
23
21
 
24
- class AlbumForm < Reform::Form
22
+ class AlbumForm < TestForm
25
23
  feature Date # feature.
26
24
  property :name
27
25
 
@@ -38,17 +36,17 @@ class FeatureInheritanceTest < BaseTest
38
36
  end
39
37
  end
40
38
 
41
- let (:song) { Song.new("Broken") }
42
- let (:song_with_composer) { Song.new("Resist Stance", nil, composer) }
43
- let (:composer) { Artist.new("Greg Graffin") }
44
- let (:artist) { Artist.new("Bad Religion") }
45
- let (:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
39
+ let(:song) { Song.new("Broken") }
40
+ let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
41
+ let(:composer) { Artist.new("Greg Graffin") }
42
+ let(:artist) { Artist.new("Bad Religion") }
43
+ let(:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
46
44
 
47
- let (:form) { AlbumForm.new(album) }
45
+ let(:form) { AlbumForm.new(album) }
48
46
 
49
47
  it do
50
- form.date.must_equal "May 16"
51
- form.songs[0].date.must_equal "May 16"
48
+ assert_equal form.date, "May 16"
49
+ assert_equal form.songs[0].date, "May 16"
52
50
  end
53
51
 
54
52
  # it { subject.class.include?(Reform::Form::ActiveModel) }
@@ -62,4 +60,4 @@ class FeatureInheritanceTest < BaseTest
62
60
  # it { subject.band.label.is_a?(Reform::Form::ActiveModel) }
63
61
  # it { subject.band.label.is_a?(Reform::Form::Coercion) }
64
62
  # it { subject.band.label.is_a?(Reform::Form::MultiParameterAttributes) }
65
- end
63
+ end