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