reform 2.1.0 → 2.2.0.rc1

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 (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