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,44 +1,104 @@
1
- array?: "%{name} must be an array"
1
+ en:
2
+ dry_validation:
3
+ errors:
4
+ array?: "must be an array"
2
5
 
3
- empty?: "%{name} cannot be empty"
6
+ empty?: "must be empty"
4
7
 
5
- exclusion?: "%{name} must not be one of: %{list}"
8
+ excludes?: "must not include %{value}"
6
9
 
7
- eql?: "%{name} must be equal to %{eql_value}"
10
+ excluded_from?:
11
+ arg:
12
+ default: "must not be one of: %{list}"
13
+ range: "must not be one of: %{list_left} - %{list_right}"
8
14
 
9
- filled?: "%{name} must be filled"
15
+ eql?: "must be equal to %{left}"
10
16
 
11
- format?: "%{name} is in invalid format"
17
+ not_eql?: "must not be equal to %{left}"
12
18
 
13
- gt?: "%{name} must be greater than %{num} (%{value} was given)"
19
+ filled?: "must be filled"
14
20
 
15
- gteq?: "%{name} must be greater than or equal to %{num}"
21
+ format?: "is in invalid format"
16
22
 
17
- hash?: "%{name} must be a hash"
23
+ number?: "must be a number"
18
24
 
19
- inclusion?: "%{name} must be one of: %{list}"
25
+ odd?: "must be odd"
20
26
 
21
- int?: "%{name} must be an integer"
27
+ even?: "must be even"
22
28
 
23
- key?: "%{name} is missing"
29
+ gt?: "must be greater than %{num}"
24
30
 
25
- lt?: "%{name} must be less than %{num} (%{value} was given)"
31
+ gteq?: "must be greater than or equal to %{num}"
26
32
 
27
- lteq?: "%{name} must be less than or equal to %{num}"
33
+ hash?: "must be a hash"
28
34
 
29
- max_size?: "%{name} size cannot be greater than %{num}"
35
+ included_in?:
36
+ arg:
37
+ default: "must be one of: %{list}"
38
+ range: "must be one of: %{list_left} - %{list_right}"
30
39
 
31
- min_size?: "%{name} size cannot be less than %{num}"
40
+ includes?: "must include %{value}"
32
41
 
33
- nil?: "%{name} cannot be nil"
42
+ bool?: "must be boolean"
34
43
 
35
- size?:
36
- range: "%{name} size must be within %{left} - %{right}"
37
- default: "%{name} size must be %{num}"
44
+ true?: "must be true"
38
45
 
39
- str?: "%{name} must be a string"
46
+ false?: "must be false"
40
47
 
41
- good_musical_taste?: "you're a bad person"
48
+ int?: "must be an integer"
42
49
 
43
- form_access_validation?: "this doesn't look like a Reform form dude!!"
50
+ float?: "must be a float"
44
51
 
52
+ decimal?: "must be a decimal"
53
+
54
+ date?: "must be a date"
55
+
56
+ date_time?: "must be a date time"
57
+
58
+ time?: "must be a time"
59
+
60
+ key?: "is missing"
61
+
62
+ attr?: "is missing"
63
+
64
+ lt?: "must be less than %{num}"
65
+
66
+ lteq?: "must be less than or equal to %{num}"
67
+
68
+ max_size?: "size cannot be greater than %{num}"
69
+
70
+ min_size?: "size cannot be less than %{num}"
71
+
72
+ none?: "cannot be defined"
73
+
74
+ str?: "must be a string"
75
+
76
+ type?: "must be %{type}"
77
+
78
+ size?:
79
+ arg:
80
+ default: "size must be %{size}"
81
+ range: "size must be within %{size_left} - %{size_right}"
82
+
83
+ value:
84
+ string:
85
+ arg:
86
+ default: "length must be %{size}"
87
+ range: "length must be within %{size_left} - %{size_right}"
88
+
89
+
90
+
91
+ rules:
92
+ name:
93
+ good_musical_taste?: "you're a bad person"
94
+ title:
95
+ good_musical_taste?: "you're a bad person"
96
+ songs:
97
+ a_song?: "must have at least one enabled song"
98
+ artist:
99
+ with_last_name?: "must have last name"
100
+
101
+ de:
102
+ dry_validation:
103
+ errors:
104
+ filled?: "muss abgefüllt sein"
@@ -1,23 +1,23 @@
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
+ params { 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
 
18
18
  it do
19
19
  form = AlbumForm.new(Album.new(Song.new("When It Comes To You")))
20
- form.song.title.must_equal "When It Comes To You"
20
+ assert_equal "When It Comes To You", form.song.title
21
21
 
22
22
  form.validate(song: {title: "Run For Cover"})
23
23
  end
data/test/form_test.rb CHANGED
@@ -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,11 +22,11 @@ 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
- it { cloned.wont_equal AlbumForm }
29
- it { AlbumForm.definitions.wont_equal cloned.definitions }
28
+ it { refute_equal cloned, AlbumForm }
29
+ it { refute_equal AlbumForm.definitions, cloned.definitions }
30
30
 
31
31
  it do
32
32
  # currently, forms need a name for validation, even without AM.
@@ -37,7 +37,7 @@ class FormTest < MiniTest::Spec
37
37
  end
38
38
 
39
39
  cloned.validation do
40
- key(:title).required
40
+ params { required(:title).filled }
41
41
  end
42
42
 
43
43
  cloned.new(OpenStruct.new).validate({})
@@ -45,13 +45,13 @@ 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
52
52
 
53
53
  it "allows injecting :virtual options" do
54
- ArtistForm.new(Artist.new, current_user: Object).current_user.must_equal Object
54
+ assert_equal ArtistForm.new(Artist.new, current_user: Object).current_user, Object
55
55
  end
56
56
  end
57
57
  end
data/test/from_test.rb CHANGED
@@ -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,46 +19,42 @@ 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
 
34
- it { subject.name.must_equal "Best Of" }
35
- it { subject.single.title.must_equal "Roxanne" }
36
- it { subject.tracks[0].name.must_equal "Fallout" }
37
- it { subject.tracks[1].name.must_equal "Roxanne" }
38
-
34
+ it { assert_equal subject.name, "Best Of" }
35
+ it { assert_equal subject.single.title, "Roxanne" }
36
+ it { assert_equal subject.tracks[0].name, "Fallout" }
37
+ it { assert_equal subject.tracks[1].name, "Roxanne" }
39
38
 
40
39
  describe "#validate" do
41
40
 
42
-
43
41
  before { subject.validate(params) }
44
42
 
45
- it { subject.name.must_equal "Best Of The Police" }
46
- it { subject.single.title.must_equal "So Lonely" }
47
- it { subject.tracks[0].name.must_equal "Message In A Bottle" }
48
- it { subject.tracks[1].name.must_equal "Roxanne" }
43
+ it { assert_equal subject.name, "Best Of The Police" }
44
+ it { assert_equal subject.single.title, "So Lonely" }
45
+ it { assert_equal subject.tracks[0].name, "Message In A Bottle" }
46
+ it { assert_equal subject.tracks[1].name, "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
- it { song2.title.must_equal "Livin' Ain't No Crime" }
55
+ it { assert_equal song2.title, "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
+ assert_equal hash, "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
data/test/inherit_test.rb CHANGED
@@ -1,119 +1,105 @@
1
- require 'test_helper'
2
- require 'representable/json'
1
+ require "test_helper"
2
+ require "representable/json"
3
3
 
4
4
  class InheritTest < BaseTest
5
5
  Populator = Reform::Form::Populator
6
6
 
7
- class AlbumForm < Reform::Form
7
+ class SkipParse
8
+ include Uber::Callable
9
+ def call(*_args)
10
+ false
11
+ end
12
+ end
13
+
14
+ class AlbumForm < TestForm
8
15
  property :title, deserializer: {instance: "Instance"}, skip_if: "skip_if in AlbumForm" # allow direct configuration of :deserializer.
9
16
 
10
- property :hit, populator: "Populator" do
17
+ property :hit, populate_if_empty: ->(*) { Song.new } do
11
18
  property :title
19
+ validation do
20
+ params { required(:title).filled }
21
+ end
12
22
  end
13
23
 
14
- collection :songs, populate_if_empty: lambda {}, skip_if: :all_blank do
24
+ collection :songs, populate_if_empty: -> {}, skip_if: :all_blank do
15
25
  property :title
16
26
  end
17
27
 
18
- property :artist, populate_if_empty: lambda {} do
19
-
20
- def artist_id
28
+ property :band, populate_if_empty: -> {} do
29
+ def band_id
21
30
  1
22
31
  end
23
32
  end
24
33
  end
25
34
 
26
- puts
27
- puts "inherit"
28
-
29
35
  class CompilationForm < AlbumForm
30
36
  property :title, inherit: true, skip_if: "skip_if from CompilationForm"
31
- puts "[#{options_for(:title)[:deserializer].object_id}] COM@@@@@ #{options_for(:title)[:deserializer].inspect}"
32
- # property :hit, :inherit => true do
33
- # property :rating
34
- # validates :title, :rating, :presence => true
35
- # end
36
-
37
- # puts representer_class.representable_attrs.
38
- # get(:hit)[:extend].evaluate(nil).new(OpenStruct.new).rating
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
39
43
 
40
44
  # NO collection here, this is entirely inherited.
41
- # collection :songs, ..
42
-
43
- property :artist, inherit: true do # inherit everything, but explicitely.
44
- end
45
45
 
46
- # completely override.
47
- property :hit, skip_if: "SkipParse" do
46
+ property :band, inherit: true do # inherit everything, but explicitely.
48
47
  end
49
-
50
- # override partly.
51
48
  end
52
49
 
53
- let (:album) { Album.new(nil, OpenStruct.new(:hit => OpenStruct.new()) ) }
50
+ let(:album) { Album.new(nil, Song.new, [], Band.new) }
54
51
  subject { CompilationForm.new(album) }
55
52
 
53
+ it do
54
+ subject.validate("hit" => {"title" => "LA Drone", "rating" => 10})
55
+ assert_equal subject.hit.title, "LA Drone"
56
+ assert_equal subject.hit.rating, 10
57
+ assert_equal subject.errors.messages, {}
58
+ end
56
59
 
57
- # valid.
58
- # it {
59
- # subject.validate("hit" => {"title" => "LA Drone", "rating" => 10})
60
- # subject.hit.title.must_equal "LA Drone"
61
- # subject.hit.rating.must_equal 10
62
- # subject.errors.messages.must_equal({})
63
- # }
64
-
65
- # it do
66
- # subject.validate({})
67
- # subject.hit.title.must_equal nil
68
- # subject.hit.rating.must_equal nil
69
- # subject.errors.messages.must_equal({:"hit.title"=>["can't be blank"], :"hit.rating"=>["can't be blank"]})
70
- # end
71
-
72
- require "pp"
60
+ it do
61
+ subject.validate({})
62
+ assert_nil subject.model.hit.title
63
+ assert_nil subject.model.hit.rating
64
+ assert_equal subject.errors.messages, "hit.title": ["must be filled"], "hit.rating": ["must be filled"]
65
+ end
73
66
 
74
67
  it "xxx" do
75
68
  # sub hashes like :deserializer must be properly cloned when inheriting.
76
- AlbumForm.options_for(:title)[:deserializer].object_id.wont_equal CompilationForm.options_for(:title)[:deserializer].object_id
69
+ refute_equal AlbumForm.options_for(:title)[:deserializer].object_id, CompilationForm.options_for(:title)[:deserializer].object_id
77
70
 
78
71
  # don't overwrite direct deserializer: {} configuration.
79
- AlbumForm.options_for(:title)[:internal_populator].must_be_instance_of Reform::Form::Populator::Sync
80
- AlbumForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if in AlbumForm"
72
+ assert AlbumForm.options_for(:title)[:internal_populator].is_a? Reform::Form::Populator::Sync
73
+ assert_equal AlbumForm.options_for(:title)[:deserializer][:skip_parse], "skip_if in AlbumForm"
81
74
 
82
- AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
75
+ # AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
83
76
  # AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_be_instance_with Reform::Form::Populator, user_proc: "Populator"
84
77
 
78
+ assert AlbumForm.options_for(:songs)[:internal_populator].is_a? Reform::Form::Populator::IfEmpty
79
+ assert AlbumForm.options_for(:songs)[:deserializer][:skip_parse].is_a? Reform::Form::Validate::Skip::AllBlank
85
80
 
86
- AlbumForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
87
- AlbumForm.options_for(:songs)[:deserializer][:skip_parse].must_be_instance_of Reform::Form::Validate::Skip::AllBlank
88
-
89
- AlbumForm.options_for(:artist)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
81
+ assert AlbumForm.options_for(:band)[:internal_populator].is_a? Reform::Form::Populator::IfEmpty
90
82
 
91
-
92
-
93
- CompilationForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if from CompilationForm"
83
+ assert_equal CompilationForm.options_for(:title)[:deserializer][:skip_parse], "skip_if from CompilationForm"
94
84
  # pp CompilationForm.options_for(:songs)
95
- CompilationForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
96
-
85
+ assert CompilationForm.options_for(:songs)[:internal_populator].is_a? Reform::Form::Populator::IfEmpty
97
86
 
98
- CompilationForm.options_for(:artist)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
87
+ assert CompilationForm.options_for(:band)[:internal_populator].is_a? Reform::Form::Populator::IfEmpty
99
88
 
100
89
  # completely overwrite inherited.
101
- CompilationForm.options_for(:hit)[:internal_populator].must_be_instance_of Reform::Form::Populator::Sync # reset to default.
102
- CompilationForm.options_for(:hit)[:deserializer][:skip_parse].must_equal "SkipParse"
103
-
90
+ assert CompilationForm.options_for(:hit)[:deserializer][:skip_parse].is_a? SkipParse
104
91
 
105
92
  # inherit: true with block will still inherit the original class.
106
- AlbumForm.new(OpenStruct.new(artist: OpenStruct.new)).artist.artist_id.must_equal 1
107
- CompilationForm.new(OpenStruct.new(artist: OpenStruct.new)).artist.artist_id.must_equal 1
93
+ assert_equal AlbumForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id, 1
94
+ assert_equal CompilationForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id, 1
108
95
  end
109
96
 
110
-
111
97
  class CDForm < AlbumForm
112
- # override :artist's original populate_if_empty but with :inherit.
113
- property :artist, inherit: true, populator: "CD Populator" do
98
+ # override :band's original populate_if_empty but with :inherit.
99
+ property :band, inherit: true, populator: "CD Populator" do
114
100
 
115
101
  end
116
102
  end
117
103
 
118
- it { CDForm.options_for(:artist)[:internal_populator].instance_variable_get(:@user_proc).must_equal "CD Populator" }
119
- end
104
+ it { assert_equal CDForm.options_for(:band)[:internal_populator].instance_variable_get(:@user_proc), "CD Populator" }
105
+ end
data/test/module_test.rb CHANGED
@@ -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
- include Dry::Types.module # allows using Types::* in module.
29
- property :cool, type: Form::Bool # test coercion.
28
+ include Dry.Types(default: :nominal) # allows using Types::* in module.
29
+ property :cool, type: Types::Params::Bool # test coercion.
30
30
  end
31
31
 
32
32
  # TODO: test if works, move stuff into inherit_schema!
@@ -36,53 +36,50 @@ 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
- it { SongForm.new(song).band.title.must_equal "Time Again" }
63
+ it { assert_equal SongForm.new(song).band.title, "Time Again" }
66
64
 
67
65
  # methods from module get included.
68
- it { SongForm.new(song).id.must_equal 1 }
69
- it { SongForm.new(song).band.id.must_equal 2 }
66
+ it { assert_equal SongForm.new(song).id, 1 }
67
+ it { assert_equal SongForm.new(song).band.id, 2 }
70
68
 
71
69
  # validators get inherited.
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
+ assert_equal form.errors.messages, 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"})
82
- form.cool.must_equal true
79
+ form.validate(cool: "1")
80
+ assert form.cool
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
+ assert_equal form.errors.messages, "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,16 +123,15 @@ 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
- IncludingSongForm.new(song).id.must_equal 1
138
- IncludingSongForm.new(song).title.must_equal "INSTANT MASH"
133
+ assert_equal IncludingSongForm.new(song).id, 1
134
+ assert_equal IncludingSongForm.new(song).title, "INSTANT MASH"
139
135
  end
140
136
  end
141
137
  end
142
-
@@ -0,0 +1,40 @@
1
+ require "test_helper"
2
+
3
+ class ParseOptionTest < MiniTest::Spec
4
+ Comment = Struct.new(:content, :user)
5
+ User = Struct.new(:name)
6
+
7
+ class CommentForm < TestForm
8
+ property :content
9
+ property :user, parse: false
10
+ end
11
+
12
+ let(:current_user) { User.new("Peter") }
13
+ let(:form) { CommentForm.new(Comment.new, user: current_user) }
14
+
15
+ it do
16
+ assert_equal form.user, current_user
17
+
18
+ lorem = "Lorem ipsum dolor sit amet..."
19
+ form.validate("content" => lorem, "user" => "not the current user")
20
+
21
+ assert_equal form.content, lorem
22
+ assert_equal form.user, current_user
23
+ end
24
+
25
+ describe "using ':parse' option doesn't override other ':deserialize' options" do
26
+ class ArticleCommentForm < TestForm
27
+ property :content
28
+ property :article, deserializer: {instance: "Instance"}
29
+ property :user, parse: false, deserializer: {instance: "Instance"}
30
+ end
31
+
32
+ it do
33
+ assert_equal ArticleCommentForm.definitions.get(:user)[:deserializer][:writeable], false
34
+ assert_equal ArticleCommentForm.definitions.get(:user)[:deserializer][:instance], "Instance"
35
+
36
+ assert ArticleCommentForm.definitions.get(:article)[:deserializer][:writeable]
37
+ assert_equal ArticleCommentForm.definitions.get(:article)[:deserializer][:instance], "Instance"
38
+ end
39
+ end
40
+ end