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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +4 -12
- data/CHANGES.md +8 -0
- data/README.md +36 -743
- data/Rakefile +1 -31
- data/gemfiles/{Gemfile.rails-3.1 → Gemfile.disposable-0.3} +1 -2
- data/lib/reform.rb +0 -9
- data/lib/reform/contract.rb +5 -1
- data/lib/reform/form.rb +1 -4
- data/lib/reform/form/composition.rb +1 -2
- data/lib/reform/form/dry.rb +29 -16
- data/lib/reform/form/module.rb +15 -3
- data/lib/reform/form/validate.rb +1 -1
- data/lib/reform/validation.rb +3 -3
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +3 -10
- data/test/coercion_test.rb +7 -7
- data/test/composition_test.rb +5 -1
- data/test/contract_test.rb +10 -4
- data/test/deserialize_test.rb +3 -3
- data/test/errors_test.rb +48 -28
- data/test/form_option_test.rb +3 -1
- data/test/form_test.rb +19 -14
- data/test/module_test.rb +51 -11
- data/test/populate_test.rb +21 -7
- data/test/reform_test.rb +24 -20
- data/test/save_test.rb +10 -4
- data/test/skip_if_test.rb +5 -3
- data/test/test_helper.rb +3 -43
- data/test/validate_test.rb +34 -14
- data/test/validation/dry_test.rb +60 -0
- data/test/validation/dry_validation_test.rb +65 -43
- data/test/validation/errors.yml +4 -0
- metadata +16 -192
- data/database.sqlite3 +0 -0
- data/gemfiles/Gemfile.rails-3.2 +0 -7
- data/gemfiles/Gemfile.rails-4.0 +0 -8
- data/gemfiles/Gemfile.rails-4.1 +0 -8
- data/gemfiles/Gemfile.rails-4.2 +0 -8
- data/lib/reform/active_record.rb +0 -4
- data/lib/reform/form/active_model.rb +0 -87
- data/lib/reform/form/active_model/form_builder_methods.rb +0 -48
- data/lib/reform/form/active_model/model_reflections.rb +0 -46
- data/lib/reform/form/active_model/model_validations.rb +0 -110
- data/lib/reform/form/active_model/validations.rb +0 -107
- data/lib/reform/form/active_record.rb +0 -30
- data/lib/reform/form/lotus.rb +0 -59
- data/lib/reform/form/multi_parameter_attributes.rb +0 -48
- data/lib/reform/form/validation/unique_validator.rb +0 -54
- data/lib/reform/rails.rb +0 -13
- data/test/active_model_custom_validation_translations_test.rb +0 -75
- data/test/active_model_test.rb +0 -207
- data/test/active_model_validation_for_property_named_format_test.rb +0 -18
- data/test/active_record_test.rb +0 -273
- data/test/builder_test.rb +0 -32
- data/test/custom_validation_test.rb +0 -47
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/controllers/albums_controller.rb +0 -18
- data/test/dummy/app/controllers/application_controller.rb +0 -4
- data/test/dummy/app/controllers/musician_controller.rb +0 -5
- data/test/dummy/app/forms/album_form.rb +0 -18
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/models/album.rb +0 -4
- data/test/dummy/app/models/song.rb +0 -3
- data/test/dummy/app/views/albums/new.html.erb +0 -28
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -20
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.yml +0 -22
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -16
- data/test/dummy/config/environments/production.rb +0 -46
- data/test/dummy/config/environments/test.rb +0 -33
- data/test/dummy/config/locales/en.yml +0 -14
- data/test/dummy/config/routes.rb +0 -4
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/form_builder_test.rb +0 -138
- data/test/lotus/Gemfile +0 -5
- data/test/lotus/lotus_test.rb +0 -31
- data/test/lotus_test.rb +0 -150
- data/test/model_reflections_test.rb +0 -138
- data/test/model_validations_test.rb +0 -82
- data/test/mongoid_test.rb +0 -313
- data/test/multi_parameter_attributes_test.rb +0 -50
- data/test/rails/integration_test.rb +0 -54
- data/test/unique_test.rb +0 -135
- data/test/validation/activemodel_validation_test.rb +0 -252
@@ -1,30 +0,0 @@
|
|
1
|
-
require "reform/form/orm"
|
2
|
-
|
3
|
-
module Reform::Form::ActiveRecord
|
4
|
-
def self.included(base)
|
5
|
-
base.class_eval do
|
6
|
-
register_feature Reform::Form::ActiveRecord
|
7
|
-
include Reform::Form::ActiveModel
|
8
|
-
include Reform::Form::ORM
|
9
|
-
extend ClassMethods
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
module ClassMethods
|
14
|
-
def validates_uniqueness_of(attribute, options={})
|
15
|
-
options = options.merge(:attributes => [attribute])
|
16
|
-
validates_with(UniquenessValidator, options)
|
17
|
-
end
|
18
|
-
def i18n_scope
|
19
|
-
:activerecord
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_nested_hash(*)
|
24
|
-
super.with_indifferent_access
|
25
|
-
end
|
26
|
-
|
27
|
-
class UniquenessValidator < ::ActiveRecord::Validations::UniquenessValidator
|
28
|
-
include Reform::Form::ORM::UniquenessValidator
|
29
|
-
end
|
30
|
-
end
|
data/lib/reform/form/lotus.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
require "lotus/validations"
|
2
|
-
|
3
|
-
# Implements ::validates and friends, and #valid?.
|
4
|
-
module Reform::Form::Lotus
|
5
|
-
class Errors < Lotus::Validations::Errors
|
6
|
-
def merge!(errors, prefix)
|
7
|
-
new_errors = {}
|
8
|
-
errors.instance_variable_get(:@errors).each do |name, err|
|
9
|
-
field = (prefix+[name]).join(".")
|
10
|
-
new_errors[field] = err
|
11
|
-
end
|
12
|
-
# next if messages[field] and messages[field].include?(msg)
|
13
|
-
|
14
|
-
new_errors.each { |field, err| add(field, *err) } # TODO: use namespace feature in Lotus here!
|
15
|
-
end
|
16
|
-
|
17
|
-
def inspect
|
18
|
-
@errors.to_s
|
19
|
-
end
|
20
|
-
|
21
|
-
def messages
|
22
|
-
self
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
def self.included(base)
|
28
|
-
# base.send(:include, Lotus::Validations)
|
29
|
-
base.extend(ClassMethods)
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
module ClassMethods
|
34
|
-
def validates(name, options)
|
35
|
-
validations.add(name, options)
|
36
|
-
end
|
37
|
-
|
38
|
-
def validate(name, *)
|
39
|
-
# DISCUSS: lotus does not support that?
|
40
|
-
# validations.add(name, options)
|
41
|
-
end
|
42
|
-
|
43
|
-
def validations
|
44
|
-
@validations ||= Lotus::Validations::ValidationSet.new
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def build_errors
|
49
|
-
Errors.new
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def valid?
|
55
|
-
# DISCUSS: by using @fields here, we avoid setters being called. win!
|
56
|
-
validator = Lotus::Validations::Validator.new(self.class.validations, @fields, errors)
|
57
|
-
validator.validate
|
58
|
-
end
|
59
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module Reform::Form::MultiParameterAttributes
|
2
|
-
# TODO: implement this with parse_filter, so we don't have to manually walk through the hash, etc.
|
3
|
-
class DateTimeParamsFilter
|
4
|
-
def call(params)
|
5
|
-
params = params.dup # DISCUSS: not sure if that slows down form processing?
|
6
|
-
date_attributes = {}
|
7
|
-
|
8
|
-
params.each do |attribute, value|
|
9
|
-
if value.is_a?(Hash)
|
10
|
-
params[attribute] = call(value) # TODO: #validate should only handle local form params.
|
11
|
-
elsif matches = attribute.match(/^(\w+)\(.i\)$/)
|
12
|
-
date_attribute = matches[1]
|
13
|
-
date_attributes[date_attribute] = params_to_date(
|
14
|
-
params.delete("#{date_attribute}(1i)"),
|
15
|
-
params.delete("#{date_attribute}(2i)"),
|
16
|
-
params.delete("#{date_attribute}(3i)"),
|
17
|
-
params.delete("#{date_attribute}(4i)"),
|
18
|
-
params.delete("#{date_attribute}(5i)")
|
19
|
-
)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
params.merge!(date_attributes)
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
def params_to_date(year, month, day, hour, minute)
|
27
|
-
date_fields = [year, month, day].map!(&:to_i)
|
28
|
-
time_fields = [hour, minute].map!(&:to_i)
|
29
|
-
|
30
|
-
if date_fields.any?(&:zero?) || !Date.valid_date?(*date_fields)
|
31
|
-
return nil
|
32
|
-
end
|
33
|
-
|
34
|
-
if hour.blank? && minute.blank?
|
35
|
-
Date.new(*date_fields)
|
36
|
-
else
|
37
|
-
args = date_fields + time_fields
|
38
|
-
Time.zone ? Time.zone.local(*args) :
|
39
|
-
Time.new(*args)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# this hooks into the format-specific #deserialize! method.
|
45
|
-
def deserialize!(params)
|
46
|
-
super DateTimeParamsFilter.new.call(params) # if params.is_a?(Hash) # this currently works for hash, only.
|
47
|
-
end
|
48
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
# === Unique Validation
|
2
|
-
# Reform's own implementation for uniqueness which does not write to model
|
3
|
-
#
|
4
|
-
# == Usage
|
5
|
-
# Pass a true boolean value to validate a field against all values available in
|
6
|
-
# the database:
|
7
|
-
# validates :title, unique: true
|
8
|
-
#
|
9
|
-
# == Options
|
10
|
-
# = Scope
|
11
|
-
# A scope can be use to filter the records that need to be compare with the
|
12
|
-
# current value to validate. A scope array can have one to many fields define.
|
13
|
-
#
|
14
|
-
# A scope can be define the following ways:
|
15
|
-
# validates :title, unique: { scope: :album_id }
|
16
|
-
# validates :title, unique: { scope: [:album_id] }
|
17
|
-
# validates :title, unique: { scope: [:album_id, ...] }
|
18
|
-
#
|
19
|
-
# All fields included in a scope must be declared as a property like this:
|
20
|
-
# property :album_id
|
21
|
-
# validates :title, unique: { scope: :album_id }
|
22
|
-
#
|
23
|
-
# Just remove write access to the property if the field must not be change:
|
24
|
-
# property :album_id, writeable: false
|
25
|
-
# validates :title, unique: { scope: :album_id }
|
26
|
-
#
|
27
|
-
# This use case is useful if album_id is set to a Song this way:
|
28
|
-
# song = album.songs.new
|
29
|
-
# album_id is automatically set and can't be change by the operation
|
30
|
-
|
31
|
-
class Reform::Form::UniqueValidator < ActiveModel::EachValidator
|
32
|
-
def validate_each(form, attribute, value)
|
33
|
-
model = form.model_for_property(attribute)
|
34
|
-
|
35
|
-
# search for models with attribute equals to form field value
|
36
|
-
query = model.class.where(attribute => value)
|
37
|
-
|
38
|
-
# apply scope if options has been declared
|
39
|
-
Array(options[:scope]).each do |field|
|
40
|
-
# add condition to only check unique value with the same scope
|
41
|
-
query = query.where(field => form.send(field))
|
42
|
-
end
|
43
|
-
|
44
|
-
# if model persisted, query may return 0 or 1 rows, else 0
|
45
|
-
allow_count = model.persisted? ? 1 : 0
|
46
|
-
form.errors.add(attribute, :taken) if query.count > allow_count
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# FIXME: ActiveModel loads validators via const_get(#{name}Validator). This magic forces us to
|
51
|
-
# make the new :unique validator available here.
|
52
|
-
Reform::Form::ActiveModel::Validations::Validator.class_eval do
|
53
|
-
UniqueValidator = Reform::Form::UniqueValidator
|
54
|
-
end
|
data/lib/reform/rails.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require "reform/form/active_model"
|
2
|
-
require "reform/form/active_model/validations"
|
3
|
-
|
4
|
-
require "reform/active_record" if defined?(ActiveRecord)
|
5
|
-
require "reform/mongoid" if defined?(Mongoid)
|
6
|
-
|
7
|
-
Reform::Form.class_eval do # DISCUSS: i'd prefer having a separate Rails module to be mixed into the Form but this is way more convenient for 99% users.
|
8
|
-
include Reform::Form::ActiveModel
|
9
|
-
include Reform::Form::ActiveModel::FormBuilderMethods
|
10
|
-
include Reform::Form::ActiveRecord if defined?(ActiveRecord)
|
11
|
-
include Reform::Form::Mongoid if defined?(Mongoid)
|
12
|
-
include Reform::Form::ActiveModel::Validations
|
13
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class ActiveModelCustomValidationTranslationsTest < MiniTest::Spec
|
4
|
-
module SongForm
|
5
|
-
class WithBlock < Reform::Form
|
6
|
-
model :song
|
7
|
-
property :title
|
8
|
-
|
9
|
-
validate do
|
10
|
-
errors.add :title, :blank
|
11
|
-
errors.add :title, :custom_error_message
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class WithLambda < Reform::Form
|
16
|
-
model :song
|
17
|
-
property :title
|
18
|
-
|
19
|
-
validate ->{ errors.add :title, :blank
|
20
|
-
errors.add :title, :custom_error_message }
|
21
|
-
end
|
22
|
-
|
23
|
-
class WithMethod < Reform::Form
|
24
|
-
model :song
|
25
|
-
property :title
|
26
|
-
|
27
|
-
validate :custom_validation_method
|
28
|
-
def custom_validation_method
|
29
|
-
errors.add :title, :blank
|
30
|
-
errors.add :title, :custom_error_message
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
describe 'when using a default translation' do
|
37
|
-
it 'translates the error message when custom validation is used with block' do
|
38
|
-
form = SongForm::WithBlock.new(Song.new)
|
39
|
-
form.validate({})
|
40
|
-
form.errors[:title].must_include "can't be blank"
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'translates the error message when custom validation is used with lambda' do
|
44
|
-
form = SongForm::WithLambda.new(Song.new)
|
45
|
-
form.validate({})
|
46
|
-
form.errors[:title].must_include "can't be blank"
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'translates the error message when custom validation is used with method' do
|
50
|
-
form = SongForm::WithMethod.new(Song.new)
|
51
|
-
form.validate({})
|
52
|
-
form.errors[:title].must_include "can't be blank"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe 'when using a custom translation' do
|
57
|
-
it 'translates the error message when custom validation is used with block' do
|
58
|
-
form = SongForm::WithBlock.new(Song.new)
|
59
|
-
form.validate({})
|
60
|
-
form.errors[:title].must_include "Custom Error Message"
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'translates the error message when custom validation is used with lambda' do
|
64
|
-
form = SongForm::WithLambda.new(Song.new)
|
65
|
-
form.validate({})
|
66
|
-
form.errors[:title].must_include "Custom Error Message"
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'translates the error message when custom validation is used with method' do
|
70
|
-
form = SongForm::WithMethod.new(Song.new)
|
71
|
-
form.validate({})
|
72
|
-
form.errors[:title].must_include "Custom Error Message"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
data/test/active_model_test.rb
DELETED
@@ -1,207 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module IsolatedRailsEngine
|
4
|
-
def self.use_relative_model_naming?
|
5
|
-
true
|
6
|
-
end
|
7
|
-
|
8
|
-
class Lyric < ActiveRecord::Base
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
module NormalRailsEngine
|
13
|
-
class Lyric < ActiveRecord::Base
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
class NewActiveModelTest < MiniTest::Spec # TODO: move to test/rails/
|
19
|
-
class SongForm < Reform::Form
|
20
|
-
include Reform::Form::ActiveModel
|
21
|
-
|
22
|
-
property :name
|
23
|
-
end
|
24
|
-
|
25
|
-
let (:artist) { Artist.create(:name => "Frank Zappa") }
|
26
|
-
let (:form) { SongForm.new(artist) }
|
27
|
-
|
28
|
-
it do
|
29
|
-
form.persisted?.must_equal true
|
30
|
-
form.to_key.must_equal [artist.id]
|
31
|
-
form.to_param.must_equal "#{artist.id}"
|
32
|
-
form.to_model.must_equal form
|
33
|
-
form.id.must_equal artist.id
|
34
|
-
form.model_name.must_equal form.class.model_name
|
35
|
-
end
|
36
|
-
|
37
|
-
describe "::model_name" do
|
38
|
-
it { form.class.model_name.must_be_kind_of ActiveModel::Name }
|
39
|
-
it { form.class.model_name.to_s.must_equal "NewActiveModelTest::Song" }
|
40
|
-
|
41
|
-
let (:class_with_model) {
|
42
|
-
Class.new(Reform::Form) do
|
43
|
-
include Reform::Form::ActiveModel
|
44
|
-
|
45
|
-
model :album
|
46
|
-
end
|
47
|
-
}
|
48
|
-
|
49
|
-
it { class_with_model.model_name.must_be_kind_of ActiveModel::Name }
|
50
|
-
it { class_with_model.model_name.to_s.must_equal "Album" }
|
51
|
-
|
52
|
-
let (:class_with_isolated_model) {
|
53
|
-
Class.new(Reform::Form) do
|
54
|
-
include Reform::Form::ActiveModel
|
55
|
-
|
56
|
-
model "isolated_rails_engine/lyric", namespace: "isolated_rails_engine"
|
57
|
-
end
|
58
|
-
}
|
59
|
-
|
60
|
-
it { class_with_isolated_model.model_name.must_be_kind_of ActiveModel::Name }
|
61
|
-
it { class_with_isolated_model.model_name.to_s.must_equal "IsolatedRailsEngine::Lyric" }
|
62
|
-
|
63
|
-
let (:class_with_namespace_model) {
|
64
|
-
Class.new(Reform::Form) do
|
65
|
-
include Reform::Form::ActiveModel
|
66
|
-
|
67
|
-
model "normal_rails_engine/lyric"
|
68
|
-
end
|
69
|
-
}
|
70
|
-
|
71
|
-
it { class_with_namespace_model.model_name.must_be_kind_of ActiveModel::Name }
|
72
|
-
it { class_with_namespace_model.model_name.to_s.must_equal "NormalRailsEngine::Lyric" }
|
73
|
-
|
74
|
-
let (:subclass_of_class_with_model) {
|
75
|
-
Class.new(class_with_model)
|
76
|
-
}
|
77
|
-
|
78
|
-
it { subclass_of_class_with_model.model_name.must_be_kind_of ActiveModel::Name }
|
79
|
-
it { subclass_of_class_with_model.model_name.to_s.must_equal 'Album' }
|
80
|
-
|
81
|
-
it { form.class.model_name.route_key.must_equal "new_active_model_test_songs" }
|
82
|
-
it { class_with_model.model_name.route_key.must_equal "albums" }
|
83
|
-
it { class_with_isolated_model.model_name.route_key.must_equal "lyrics" }
|
84
|
-
it { class_with_namespace_model.model_name.route_key.must_equal "normal_rails_engine_lyrics" }
|
85
|
-
it { subclass_of_class_with_model.model_name.route_key.must_equal 'albums' }
|
86
|
-
|
87
|
-
describe "class named Song::Form" do
|
88
|
-
it do
|
89
|
-
class Form < Reform::Form
|
90
|
-
include Reform::Form::ActiveModel
|
91
|
-
self
|
92
|
-
end.model_name.to_s.must_equal "NewActiveModelTest"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
|
-
describe "inline with model" do
|
98
|
-
let (:form_class) {
|
99
|
-
Class.new(Reform::Form) do
|
100
|
-
include Reform::Form::ActiveModel
|
101
|
-
|
102
|
-
property :song do
|
103
|
-
include Reform::Form::ActiveModel
|
104
|
-
model :hit
|
105
|
-
end
|
106
|
-
end
|
107
|
-
}
|
108
|
-
|
109
|
-
let (:inline) { form_class.new(OpenStruct.new(:song => Object.new)).song }
|
110
|
-
|
111
|
-
it { inline.class.model_name.must_be_kind_of ActiveModel::Name }
|
112
|
-
it { inline.class.model_name.to_s.must_equal "Hit" }
|
113
|
-
end
|
114
|
-
|
115
|
-
describe "inline without model" do
|
116
|
-
let (:form_class) {
|
117
|
-
Class.new(Reform::Form) do
|
118
|
-
include Reform::Form::ActiveModel
|
119
|
-
|
120
|
-
property :song do
|
121
|
-
include Reform::Form::ActiveModel
|
122
|
-
end
|
123
|
-
|
124
|
-
collection :hits do
|
125
|
-
include Reform::Form::ActiveModel
|
126
|
-
end
|
127
|
-
end
|
128
|
-
}
|
129
|
-
|
130
|
-
let (:form) { form_class.new(OpenStruct.new(:hits=>[OpenStruct.new], :song => OpenStruct.new)) }
|
131
|
-
|
132
|
-
it { form.song.class.model_name.must_be_kind_of ActiveModel::Name }
|
133
|
-
it { form.song.class.model_name.to_s.must_equal "Song" }
|
134
|
-
it "singularizes collection name" do
|
135
|
-
form.hits.first.class.model_name.to_s.must_equal "Hit"
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
|
142
|
-
class ActiveModelWithCompositionTest < MiniTest::Spec
|
143
|
-
class HitForm < Reform::Form
|
144
|
-
include Composition
|
145
|
-
include Reform::Form::ActiveModel
|
146
|
-
|
147
|
-
property :title, :on => :song
|
148
|
-
properties :name, :genre, :on => :artist # we need to check both ::property and ::properties here!
|
149
|
-
|
150
|
-
model :hit, :on => :song
|
151
|
-
end
|
152
|
-
|
153
|
-
let (:rio) { OpenStruct.new(:title => "Rio") }
|
154
|
-
let (:duran) { OpenStruct.new }
|
155
|
-
let (:form) { HitForm.new(:song => rio, :artist => duran) }
|
156
|
-
|
157
|
-
describe "model accessors a la model#[:hit]" do
|
158
|
-
it { form.model[:song].must_equal rio }
|
159
|
-
it { form.model[:artist].must_equal duran }
|
160
|
-
|
161
|
-
it "doesn't delegate when :on missing" do
|
162
|
-
class SongOnlyForm < Reform::Form
|
163
|
-
include Composition
|
164
|
-
include Reform::Form::ActiveModel
|
165
|
-
|
166
|
-
property :title, :on => :song
|
167
|
-
|
168
|
-
model :song
|
169
|
-
end.new(:song => rio, :artist => duran).model[:song].must_equal rio
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
|
174
|
-
it "provides ::model_name" do
|
175
|
-
form.class.model_name.must_equal "Hit"
|
176
|
-
end
|
177
|
-
|
178
|
-
it "provides #persisted?" do
|
179
|
-
HitForm.new(:song => OpenStruct.new.instance_eval { def persisted?; "yo!"; end; self }, :artist => OpenStruct.new).persisted?.must_equal "yo!"
|
180
|
-
end
|
181
|
-
|
182
|
-
it "provides #to_key" do
|
183
|
-
HitForm.new(:song => OpenStruct.new.instance_eval { def to_key; "yo!"; end; self }, :artist => OpenStruct.new).to_key.must_equal "yo!"
|
184
|
-
end
|
185
|
-
|
186
|
-
it "provides #to_param" do
|
187
|
-
HitForm.new(:song => OpenStruct.new.instance_eval { def to_param; "yo!"; end; self }, :artist => OpenStruct.new).to_param.must_equal "yo!"
|
188
|
-
end
|
189
|
-
|
190
|
-
it "provides #to_model" do
|
191
|
-
form = HitForm.new(:song => OpenStruct.new, :artist => OpenStruct.new)
|
192
|
-
form.to_model.must_equal form
|
193
|
-
end
|
194
|
-
|
195
|
-
it "works with any order of ::model and ::property" do
|
196
|
-
class AnotherForm < Reform::Form
|
197
|
-
include Composition
|
198
|
-
include Reform::Form::ActiveModel
|
199
|
-
|
200
|
-
model :song, :on => :song
|
201
|
-
property :title, :on => :song
|
202
|
-
end
|
203
|
-
|
204
|
-
|
205
|
-
AnotherForm.new(:song => rio).model[:song].must_equal rio
|
206
|
-
end
|
207
|
-
end
|