reform 2.1.0 → 2.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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,28 +0,0 @@
1
- New Album
2
-
3
- <%= form_for @form do |f| %>
4
- <% if @form.errors.any? %>
5
- <div>
6
- <h3><%= pluralize(@form.errors.count, "error") %> prohibited this form from being saved:</h3>
7
-
8
- <ul>
9
- <% @form.errors.full_messages.each do |msg| %>
10
- <li><%= msg %></li>
11
- <% end %>
12
- </ul>
13
- </div>
14
- <% end %>
15
-
16
- <%= f.label :title, "Album Title" %>
17
- <%= f.text_field :title %>
18
-
19
- <%= f.fields_for :songs do |song| %>
20
- <div>
21
- <%= song.label :title %>
22
- <%= song.text_field :title %>
23
- </div>
24
- <% end %>
25
-
26
- <%= f.submit %>
27
- <% end %>
28
-
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Dummy</title>
5
- <%= stylesheet_link_tag :all %>
6
- <%= javascript_include_tag :defaults %>
7
- <%= csrf_meta_tag %>
8
- </head>
9
- <body>
10
-
11
- <%= yield %>
12
-
13
- </body>
14
- </html>
@@ -1,4 +0,0 @@
1
- # This file is used by Rack-based servers to start the application.
2
-
3
- require ::File.expand_path('../config/environment', __FILE__)
4
- run Dummy::Application
@@ -1,20 +0,0 @@
1
- require File.expand_path('../boot', __FILE__)
2
-
3
- require "active_model/railtie"
4
- require "action_controller/railtie"
5
- require "action_view/railtie"
6
-
7
- Bundler.require
8
-
9
- module Dummy
10
- class Application < Rails::Application
11
- config.encoding = "utf-8"
12
-
13
- # Configure sensitive parameters which will be filtered from the log file.
14
- config.filter_parameters += [:password]
15
-
16
- config.cache_store = :memory_store
17
- end
18
- end
19
-
20
- #require "reform/rails" # FIXME: this has to happen automatically in the rake test_rails run.
@@ -1,10 +0,0 @@
1
- require 'rubygems'
2
- gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3
-
4
- if File.exist?(gemfile)
5
- ENV['BUNDLE_GEMFILE'] = gemfile
6
- require 'bundler'
7
- Bundler.setup
8
- end
9
-
10
- $:.unshift File.expand_path('../../../../lib', __FILE__)
@@ -1,22 +0,0 @@
1
- # SQLite version 3.x
2
- # gem install sqlite3-ruby (not necessary on OS X Leopard)
3
- development:
4
- adapter: sqlite3
5
- database: db/development.sqlite3
6
- pool: 5
7
- timeout: 5000
8
-
9
- # Warning: The database defined as "test" will be erased and
10
- # re-generated from your development database when you run "rake".
11
- # Do not set this db to the same as development or production.
12
- test:
13
- adapter: sqlite3
14
- database: db/test.sqlite3
15
- pool: 5
16
- timeout: 5000
17
-
18
- production:
19
- adapter: sqlite3
20
- database: db/production.sqlite3
21
- pool: 5
22
- timeout: 5000
@@ -1,5 +0,0 @@
1
- # Load the rails application
2
- require File.expand_path('../application', __FILE__)
3
-
4
- # Initialize the rails application
5
- Dummy::Application.initialize!
@@ -1,16 +0,0 @@
1
- Dummy::Application.configure do
2
- # Settings specified here will take precedence over those in config/environment.rb
3
-
4
- # In the development environment your application's code is reloaded on
5
- # every request. This slows down response time but is perfect for development
6
- # since you don't have to restart the webserver when you make code changes.
7
- config.cache_classes = false
8
-
9
- # Log error messages when you accidentally call methods on nil.
10
- config.whiny_nils = true
11
-
12
- # Show full error reports and disable caching
13
- config.consider_all_requests_local = true
14
- config.action_controller.perform_caching = false
15
- config.secret_key_base = 123
16
- end
@@ -1,46 +0,0 @@
1
- Dummy::Application.configure do
2
- # Settings specified here will take precedence over those in config/environment.rb
3
-
4
- # The production environment is meant for finished, "live" apps.
5
- # Code is not reloaded between requests
6
- config.cache_classes = true
7
-
8
- # Full error reports are disabled and caching is turned on
9
- config.consider_all_requests_local = false
10
- config.action_controller.perform_caching = true
11
-
12
- # Specifies the header that your server uses for sending files
13
- config.action_dispatch.x_sendfile_header = "X-Sendfile"
14
-
15
- # For nginx:
16
- # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
17
-
18
- # If you have no front-end server that supports something like X-Sendfile,
19
- # just comment this out and Rails will serve the files
20
-
21
- # See everything in the log (default is :info)
22
- # config.log_level = :debug
23
-
24
- # Use a different logger for distributed setups
25
- # config.logger = SyslogLogger.new
26
-
27
- # Use a different cache store in production
28
- # config.cache_store = :mem_cache_store
29
-
30
- # Disable Rails's static asset server
31
- # In production, Apache or nginx will already do this
32
- config.serve_static_assets = false
33
-
34
- # Enable serving of images, stylesheets, and javascripts from an asset server
35
- # config.action_controller.asset_host = "http://assets.example.com"
36
-
37
- # Disable delivery errors, bad email addresses will be ignored
38
- # config.action_mailer.raise_delivery_errors = false
39
-
40
- # Enable threaded mode
41
- # config.threadsafe!
42
-
43
- # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
44
- # the I18n.default_locale when a translation can not be found)
45
- config.i18n.fallbacks = true
46
- end
@@ -1,33 +0,0 @@
1
- Dummy::Application.configure do
2
- # Settings specified here will take precedence over those in config/environment.rb
3
-
4
- # The test environment is used exclusively to run your application's
5
- # test suite. You never need to work with it otherwise. Remember that
6
- # your test database is "scratch space" for the test suite and is wiped
7
- # and recreated between test runs. Don't rely on the data there!
8
- config.cache_classes = true
9
-
10
- # Log error messages when you accidentally call methods on nil.
11
- config.whiny_nils = true
12
-
13
- # Show full error reports and disable caching
14
- config.consider_all_requests_local = true
15
- config.action_controller.perform_caching = false
16
-
17
- # Raise exceptions instead of rendering exception templates
18
- config.action_dispatch.show_exceptions = false
19
-
20
- # Disable request forgery protection in test environment
21
- config.action_controller.allow_forgery_protection = false
22
- config.secret_key_base = "yo"
23
-
24
- # Tell Action Mailer not to deliver emails to the real world.
25
- # The :test delivery method accumulates sent emails in the
26
- # ActionMailer::Base.deliveries array.
27
- #config.action_mailer.delivery_method = :test
28
-
29
- # Use SQL instead of Active Record's schema dumper when creating the test database.
30
- # This is necessary if your schema can't be completely dumped by the schema dumper,
31
- # like if you have constraints or database-specific column types
32
- # config.active_record.schema_format = :sql
33
- end
@@ -1,14 +0,0 @@
1
- ---
2
- en:
3
- # custom validation error messages
4
- errors:
5
- messages:
6
- taken: has already been taken
7
- activemodel:
8
- errors:
9
- models:
10
- song:
11
- attributes:
12
- title:
13
- custom_error_message: Custom Error Message
14
- taken: has already been taken
@@ -1,4 +0,0 @@
1
- Dummy::Application.routes.draw do
2
- get ':controller(/:action(/:id(.:format)))'
3
- resources :albums
4
- end
File without changes
@@ -1,138 +0,0 @@
1
- require 'test_helper'
2
-
3
- class FormBuilderCompatTest < BaseTest
4
- class AlbumForm < Reform::Form
5
- feature Reform::Form::ActiveModel::FormBuilderMethods
6
-
7
- feature Reform::Form::MultiParameterAttributes
8
-
9
- property :artist do
10
- property :name
11
- validates :name, :presence => true
12
- end
13
-
14
- collection :songs do
15
- # feature Reform::Form::ActiveModel::FormBuilderMethods
16
- property :title
17
- property :release_date, :multi_params => true
18
- validates :title, :presence => true
19
- end
20
-
21
- class LabelForm < Reform::Form
22
- property :name
23
- end
24
-
25
- property :label, form: LabelForm
26
-
27
- property :band do
28
- property :label do
29
- property :name
30
-
31
- property :location do
32
- property :postcode
33
- end
34
- end
35
- end
36
- end
37
-
38
-
39
- let (:song) { OpenStruct.new }
40
- let (:form) {
41
- AlbumForm.new(OpenStruct.new(
42
- :artist => Artist.new(:name => "Propagandhi"),
43
- :songs => [song],
44
- :label => Label.new,
45
-
46
- :band => Band.new(OpenStruct.new(location: OpenStruct.new))
47
- ))
48
- }
49
-
50
- it "respects _attributes params hash" do
51
- form.validate(
52
- "artist_attributes" => {"name" => "Blink 182"},
53
- "songs_attributes" => {"0" => {"title" => "Damnit"}},
54
- "band_attributes" => {"label_attributes" => {"name" => "Epitaph", "location_attributes" => {"postcode" => 2481}}})
55
-
56
- form.artist.name.must_equal "Blink 182"
57
- form.songs.first.title.must_equal "Damnit"
58
- form.band.label.name.must_equal "Epitaph"
59
- form.band.label.location.postcode.must_equal 2481
60
- end
61
-
62
- it "allows nested collection and property to be missing" do
63
- form.validate({})
64
-
65
- form.artist.name.must_equal "Propagandhi"
66
-
67
- form.songs.size.must_equal 1
68
- form.songs[0].model.must_equal song # this is a weird test.
69
- end
70
-
71
- it "defines _attributes= setter so Rails' FB works properly" do
72
- form.must_respond_to("artist_attributes=")
73
- form.must_respond_to("songs_attributes=")
74
- form.must_respond_to("label_attributes=")
75
- end
76
-
77
- describe "deconstructed datetime parameters" do
78
- let(:form_attributes) do
79
- {
80
- "artist_attributes" => {"name" => "Blink 182"},
81
- "songs_attributes" => {"0" => {"title" => "Damnit", "release_date(1i)" => release_year,
82
- "release_date(2i)" => release_month, "release_date(3i)" => release_day,
83
- "release_date(4i)" => release_hour, "release_date(5i)" => release_minute}}
84
- }
85
- end
86
- let(:release_year) { "1997" }
87
- let(:release_month) { "9" }
88
- let(:release_day) { "27" }
89
- let(:release_hour) { nil }
90
- let(:release_minute) { nil }
91
-
92
- describe "with valid date parameters" do
93
- it "creates a date" do
94
- form.validate(form_attributes)
95
-
96
- form.songs.first.release_date.must_equal Date.new(1997, 9, 27)
97
- end
98
- end
99
-
100
- describe "with valid datetime parameters" do
101
- let(:release_hour) { "10" }
102
- let(:release_minute) { "11" }
103
-
104
- it "creates a datetime" do
105
- form.validate(form_attributes)
106
-
107
- form.songs.first.release_date.must_equal Time.new(1997, 9, 27, 10, 11)
108
- end
109
- end
110
-
111
- %w(year month day).each do |date_attr|
112
- describe "when the #{date_attr} is missing" do
113
- let(:"release_#{date_attr}") { "" }
114
-
115
- it "rejects the date" do
116
- form.validate(form_attributes)
117
-
118
- form.songs.first.release_date.must_be_nil
119
- end
120
- end
121
- end
122
-
123
-
124
- # doesn't modify original params.
125
- it do
126
- original = form_attributes.inspect
127
-
128
- form.validate(form_attributes)
129
- form_attributes.inspect.must_equal original
130
- end
131
- end
132
-
133
- it "returns flat errors hash" do
134
- form.validate("artist_attributes" => {"name" => ""},
135
- "songs_attributes" => {"0" => {"title" => ""}})
136
- form.errors.messages.must_equal(:"artist.name" => ["can't be blank"], :"songs.title" => ["can't be blank"])
137
- end
138
- end
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem "reform", path: "../../"
4
- gem "lotus-validations"
5
- gem "minitest"
@@ -1,31 +0,0 @@
1
- require "reform"
2
- require "reform/form/lotus"
3
- require "minitest/autorun"
4
-
5
- Reform::Contract.class_eval do
6
- include Reform::Contract::Validate
7
- include Reform::Form::Lotus
8
- end
9
-
10
- class LotusTest < Minitest::Spec
11
- Album = Struct.new(:title, :songs, :artist)
12
-
13
- class AlbumForm < Reform::Form
14
-
15
-
16
- property :title
17
- validates :title, presence: true
18
-
19
- property :songs do
20
- property :name
21
- end
22
- end
23
-
24
- it do
25
- form = AlbumForm.new(Album.new("Show Completo"))
26
-
27
- form.validate(title: "").must_equal false
28
-
29
- form.errors.to_s.must_equal ""
30
- end
31
- end
@@ -1,150 +0,0 @@
1
- require "test_helper"
2
-
3
- require "reform/form/lotus"
4
-
5
- class LotusValidationsTest < MiniTest::Spec
6
- class AlbumForm < Reform::Form
7
- feature Lotus
8
-
9
- property :title
10
-
11
- property :hit do
12
- property :title
13
- validates :title, :presence => true
14
- end
15
-
16
- collection :songs do
17
- property :title
18
- validates :title, :presence => true
19
- end
20
-
21
- property :band do # yepp, people do crazy stuff like that.
22
- property :name
23
- property :label do
24
- property :name
25
- validates :name, :presence => true
26
- end
27
- # TODO: make band a required object.
28
-
29
- validate :validate_musical_taste
30
-
31
- def validate_musical_taste
32
- errors.add(:base, "You are a bad person") if name == 'Nickelback'
33
- end
34
- end
35
-
36
- validates :title, :presence => true
37
- end
38
-
39
- let (:album) do
40
- OpenStruct.new(
41
- :title => "Blackhawks Over Los Angeles",
42
- :hit => song,
43
- :songs => songs, # TODO: document this requirement,
44
-
45
- :band => Struct.new(:name, :label).new("Epitaph", OpenStruct.new),
46
- )
47
- end
48
- let (:song) { OpenStruct.new(:title => "Downtown") }
49
- let (:songs) { [song=OpenStruct.new(:title => "Calling"), song] }
50
- let (:form) { AlbumForm.new(album) }
51
-
52
-
53
- # correct #validate.
54
- it do
55
- result = form.validate(
56
- "name" => "Best Of",
57
- "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne", "composer" => {"name" => "Sting"}}],
58
- "artist" => {"name" => "The Police"},
59
- "band" => {"label" => {"name" => "Epitaph"}},
60
- )
61
-
62
- result.must_equal true
63
- form.errors.inspect.must_equal "{}"
64
- end
65
-
66
-
67
- describe "incorrect #validate" do
68
- it("xxx") do
69
- result = form.validate(
70
- "hit" =>{"title" => ""},
71
- "title" => "",
72
- "songs" => [{"title" => ""}, {"title" => ""}])
73
-
74
- result.must_equal false
75
-
76
- form.errors.messages.inspect.must_match "title"
77
- form.errors.messages.inspect.must_match "hit.title"
78
- form.errors.messages.inspect.must_match "songs.title"
79
- form.errors.messages.inspect.must_match "band.label.name"
80
-
81
-
82
- form.hit.errors.messages.inspect.must_match "title"
83
- form.songs[0].errors.messages.inspect.must_match "title"
84
- # FIXME
85
-
86
- # form.errors.messages.must_equal({
87
- # :title => ["can't be blank"],
88
- # :"hit.title"=>["can't be blank"],
89
- # :"songs.title"=>["can't be blank"],
90
- # :"band.label.name"=>["can't be blank"]
91
- # })
92
-
93
- # # nested forms keep their own Errors:
94
- # form.hit.errors.messages.must_equal({:title=>["can't be blank"]})
95
- # form.songs[0].errors.messages.must_equal({:title=>["can't be blank"]})
96
-
97
- # form.errors.messages.must_equal({
98
- # :title => ["can't be blank"],
99
- # :"hit.title" => ["can't be blank"],
100
- # :"songs.title"=> ["can't be blank"],
101
- # :"band.label.name"=>["can't be blank"]
102
- # })
103
- end
104
- end
105
-
106
-
107
- describe "#validate with collection form invalid" do
108
- it do
109
- result = form.validate("songs"=>[{"title" => ""}], "band"=>{"label"=>{:name => "Fat Wreck"}})
110
- result.must_equal false
111
- # FIXME
112
- # form.errors.messages.must_equal({:"songs.title"=>["can't be blank"]})
113
- form.errors.messages.inspect.must_match "songs.title"
114
- end
115
- end
116
-
117
-
118
- describe "#validate with collection and 2-level-nested invalid" do
119
- it do
120
- result = form.validate("songs"=>[{"title" => ""}], "band" => {"label" => {}})
121
- result.must_equal false
122
- # FIXME
123
- # form.errors.messages.must_equal({:"songs.title"=>["can't be blank"], :"band.label.name"=>["can't be blank"]})
124
- form.errors.messages.inspect.must_match "songs.title"
125
- form.errors.messages.inspect.must_match "band.label.name"
126
- end
127
- end
128
-
129
- # TODO: implement.
130
- # describe "#validate with nested form using :base invalid" do
131
- # before { @result = form.validate("songs"=>[{"title" => "Someday"}], "band" => {"name" => "Nickelback", "label" => {"name" => "Roadrunner Records"}}) }
132
-
133
- # it { @result.must_equal false }
134
- # it { form.errors.messages.must_equal({:base=>["You are a bad person"]}) }
135
- # end
136
-
137
- describe "correct #validate" do
138
- before { @result = form.validate(
139
- "hit" => {"title" => "Sacrifice"},
140
- "title" => "Second Heat",
141
- "songs" => [{"title"=>"Heart Of A Lion"}],
142
- "band" => {"label"=>{:name => "Fat Wreck"}}
143
- ) }
144
-
145
- it { @result.must_equal true }
146
- it { form.hit.title.must_equal "Sacrifice" }
147
- it { form.title.must_equal "Second Heat" }
148
- it { form.songs.first.title.must_equal "Heart Of A Lion" }
149
- end
150
- end