granite-form 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +7 -0
- data/Rakefile +4 -0
- data/granite-form.gemspec +1 -0
- data/lib/granite/form/config.rb +10 -10
- data/lib/granite/form/model/associations/nested_attributes.rb +3 -3
- data/lib/granite/form/model/associations/reflections/references_many.rb +3 -1
- data/lib/granite/form/model/associations/reflections/references_one.rb +3 -1
- data/lib/granite/form/model/attributes/attribute.rb +1 -1
- data/lib/granite/form/model/attributes/base.rb +13 -16
- data/lib/granite/form/model/attributes/collection.rb +1 -1
- data/lib/granite/form/model/attributes/dictionary.rb +1 -1
- data/lib/granite/form/model/attributes/localized.rb +1 -1
- data/lib/granite/form/model/attributes/reference_many.rb +1 -1
- data/lib/granite/form/model/attributes/reference_one.rb +1 -9
- data/lib/granite/form/model/attributes/reflections/base.rb +1 -5
- data/lib/granite/form/model/attributes/reflections/reference_one.rb +0 -4
- data/lib/granite/form/model/validations/nested.rb +1 -1
- data/lib/granite/form/types/active_support/time_zone.rb +22 -0
- data/lib/granite/form/types/array.rb +17 -0
- data/lib/granite/form/types/big_decimal.rb +15 -0
- data/lib/granite/form/types/boolean.rb +38 -0
- data/lib/granite/form/types/date.rb +15 -0
- data/lib/granite/form/types/date_time.rb +15 -0
- data/lib/granite/form/types/float.rb +15 -0
- data/lib/granite/form/types/hash_with_action_controller_parameters.rb +18 -0
- data/lib/granite/form/types/integer.rb +13 -0
- data/lib/granite/form/types/object.rb +30 -0
- data/lib/granite/form/types/string.rb +13 -0
- data/lib/granite/form/types/time.rb +15 -0
- data/lib/granite/form/types/uuid.rb +22 -0
- data/lib/granite/form/types.rb +15 -0
- data/lib/granite/form/version.rb +1 -1
- data/lib/granite/form.rb +19 -118
- data/spec/{lib/granite → granite}/form/active_record/associations_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/active_record/nested_attributes_spec.rb +0 -1
- data/spec/{lib/granite → granite}/form/config_spec.rb +22 -10
- data/spec/granite/form/extensions_spec.rb +12 -0
- data/spec/{lib/granite → granite}/form/model/associations/embeds_many_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/embeds_one_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/nested_attributes_spec.rb +0 -1
- data/spec/{lib/granite → granite}/form/model/associations/persistence_adapters/active_record_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/references_many_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/references_one_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_any_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_many_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_one_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/reflections/references_many_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/reflections/references_one_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations/validations_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/associations_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/attributes/attribute_spec.rb +4 -46
- data/spec/{lib/granite → granite}/form/model/attributes/base_spec.rb +11 -2
- data/spec/{lib/granite → granite}/form/model/attributes/collection_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/attributes/dictionary_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/attributes/localized_spec.rb +1 -1
- data/spec/{lib/granite → granite}/form/model/attributes/reflections/attribute_spec.rb +0 -12
- data/spec/{lib/granite → granite}/form/model/attributes/reflections/base_spec.rb +1 -1
- data/spec/{lib/granite → granite}/form/model/attributes/reflections/collection_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/attributes/reflections/dictionary_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/attributes/reflections/localized_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/attributes/reflections/represents_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/attributes/represents_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/attributes_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/callbacks_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/conventions_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/dirty_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/lifecycle_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/persistence_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/primary_spec.rb +1 -1
- data/spec/{lib/granite → granite}/form/model/representation_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/scopes_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/validations/associated_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model/validations/nested_spec.rb +55 -11
- data/spec/{lib/granite → granite}/form/model/validations_spec.rb +0 -0
- data/spec/{lib/granite → granite}/form/model_spec.rb +0 -0
- data/spec/granite/form/types/active_support/time_zone_spec.rb +24 -0
- data/spec/granite/form/types/array_spec.rb +13 -0
- data/spec/granite/form/types/big_decimal_spec.rb +19 -0
- data/spec/granite/form/types/boolean_spec.rb +21 -0
- data/spec/granite/form/types/date_spec.rb +18 -0
- data/spec/granite/form/types/date_time_spec.rb +20 -0
- data/spec/granite/form/types/float_spec.rb +19 -0
- data/spec/granite/form/types/hash_with_action_controller_parameters_spec.rb +22 -0
- data/spec/granite/form/types/integer_spec.rb +18 -0
- data/spec/granite/form/types/object_spec.rb +40 -0
- data/spec/granite/form/types/string_spec.rb +13 -0
- data/spec/granite/form/types/time_spec.rb +31 -0
- data/spec/granite/form/types/uuid_spec.rb +21 -0
- data/spec/{lib/granite → granite}/form_spec.rb +0 -0
- data/spec/{shared → support/shared}/nested_attribute_examples.rb +0 -0
- data/spec/support/shared/type_examples.rb +7 -0
- metadata +147 -91
- data/spec/lib/granite/form/model/typecasting_spec.rb +0 -193
data/lib/granite/form.rb
CHANGED
@@ -11,6 +11,7 @@ require 'granite/form/version'
|
|
11
11
|
require 'granite/form/errors'
|
12
12
|
require 'granite/form/extensions'
|
13
13
|
require 'granite/form/undefined_class'
|
14
|
+
require 'granite/form/types'
|
14
15
|
require 'granite/form/config'
|
15
16
|
require 'granite/form/railtie' if defined? Rails
|
16
17
|
require 'granite/form/model'
|
@@ -19,130 +20,26 @@ require 'granite/form/model/associations/persistence_adapters/active_record'
|
|
19
20
|
|
20
21
|
module Granite
|
21
22
|
module Form
|
22
|
-
BOOLEAN_MAPPING = {
|
23
|
-
1 => true,
|
24
|
-
0 => false,
|
25
|
-
'1' => true,
|
26
|
-
'0' => false,
|
27
|
-
't' => true,
|
28
|
-
'f' => false,
|
29
|
-
'T' => true,
|
30
|
-
'F' => false,
|
31
|
-
true => true,
|
32
|
-
false => false,
|
33
|
-
'true' => true,
|
34
|
-
'false' => false,
|
35
|
-
'TRUE' => true,
|
36
|
-
'FALSE' => false,
|
37
|
-
'y' => true,
|
38
|
-
'n' => false,
|
39
|
-
'yes' => true,
|
40
|
-
'no' => false
|
41
|
-
}.freeze
|
42
|
-
|
43
23
|
def self.config
|
44
24
|
Granite::Form::Config.instance
|
45
25
|
end
|
46
26
|
|
47
27
|
singleton_class.delegate(*Granite::Form::Config.delegated, to: :config)
|
48
28
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|
65
|
-
ActiveSupport.on_load :action_controller do
|
66
|
-
Granite::Form.typecaster('Hash') do |value|
|
67
|
-
case value
|
68
|
-
when ActionController::Parameters
|
69
|
-
value.to_h if value.permitted?
|
70
|
-
when ::Hash then
|
71
|
-
value
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
typecaster('Date') do |value|
|
76
|
-
begin
|
77
|
-
value.to_date
|
78
|
-
rescue ArgumentError, NoMethodError
|
79
|
-
nil
|
80
|
-
end
|
81
|
-
end
|
82
|
-
typecaster('DateTime') do |value|
|
83
|
-
begin
|
84
|
-
value.to_datetime
|
85
|
-
rescue ArgumentError
|
86
|
-
nil
|
87
|
-
end
|
88
|
-
end
|
89
|
-
typecaster('Time') do |value|
|
90
|
-
begin
|
91
|
-
value.is_a?(String) && ::Time.zone ? ::Time.zone.parse(value) : value.to_time
|
92
|
-
rescue ArgumentError
|
93
|
-
nil
|
94
|
-
end
|
95
|
-
end
|
96
|
-
typecaster('ActiveSupport::TimeZone') do |value|
|
97
|
-
case value
|
98
|
-
when ActiveSupport::TimeZone
|
99
|
-
value
|
100
|
-
when ::TZInfo::Timezone
|
101
|
-
ActiveSupport::TimeZone[value.name]
|
102
|
-
when String, Numeric, ActiveSupport::Duration
|
103
|
-
value = begin
|
104
|
-
Float(value)
|
105
|
-
rescue ArgumentError, TypeError
|
106
|
-
value
|
107
|
-
end
|
108
|
-
ActiveSupport::TimeZone[value]
|
109
|
-
end
|
110
|
-
end
|
111
|
-
typecaster('BigDecimal') do |value|
|
112
|
-
next unless value
|
113
|
-
begin
|
114
|
-
BigDecimal(Float(value).to_s)
|
115
|
-
rescue ArgumentError, TypeError
|
116
|
-
nil
|
117
|
-
end
|
118
|
-
end
|
119
|
-
typecaster('Float') do |value|
|
120
|
-
begin
|
121
|
-
Float(value)
|
122
|
-
rescue ArgumentError, TypeError
|
123
|
-
nil
|
124
|
-
end
|
125
|
-
end
|
126
|
-
typecaster('Integer') do |value|
|
127
|
-
begin
|
128
|
-
Float(value).to_i
|
129
|
-
rescue ArgumentError, TypeError
|
130
|
-
nil
|
131
|
-
end
|
132
|
-
end
|
133
|
-
typecaster('Boolean') { |value| BOOLEAN_MAPPING[value] }
|
134
|
-
typecaster('Granite::Form::UUID') do |value|
|
135
|
-
case value
|
136
|
-
when UUIDTools::UUID
|
137
|
-
Granite::Form::UUID.parse_raw value.raw
|
138
|
-
when Granite::Form::UUID
|
139
|
-
value
|
140
|
-
when String
|
141
|
-
Granite::Form::UUID.parse_string value
|
142
|
-
when Integer
|
143
|
-
Granite::Form::UUID.parse_int value
|
144
|
-
end
|
145
|
-
end
|
29
|
+
config.types = {
|
30
|
+
'Object' => Types::Object,
|
31
|
+
'String' => Types::String,
|
32
|
+
'Array' => Types::Array,
|
33
|
+
'Date' => Types::Date,
|
34
|
+
'DateTime' => Types::DateTime,
|
35
|
+
'Time' => Types::Time,
|
36
|
+
'ActiveSupport::TimeZone' => Types::ActiveSupport::TimeZone,
|
37
|
+
'BigDecimal' => Types::BigDecimal,
|
38
|
+
'Float' => Types::Float,
|
39
|
+
'Integer' => Types::Integer,
|
40
|
+
'Boolean' => Types::Boolean,
|
41
|
+
'Granite::Form::UUID' => Types::UUID
|
42
|
+
}
|
146
43
|
end
|
147
44
|
end
|
148
45
|
|
@@ -150,6 +47,10 @@ require 'granite/form/base'
|
|
150
47
|
|
151
48
|
Granite::Form.base_class = Granite::Form::Base
|
152
49
|
|
50
|
+
ActiveSupport.on_load :action_controller do
|
51
|
+
Granite::Form.config.types['Hash'] = Granite::Form::Types::HashWithActionControllerParameters
|
52
|
+
end
|
53
|
+
|
153
54
|
ActiveSupport.on_load :active_record do
|
154
55
|
require 'granite/form/active_record/associations'
|
155
56
|
require 'granite/form/active_record/nested_attributes'
|
File without changes
|
@@ -47,20 +47,32 @@ describe Granite::Form::Config do
|
|
47
47
|
|
48
48
|
describe '#typecaster' do
|
49
49
|
specify do
|
50
|
-
expect { subject.typecaster('Object')
|
51
|
-
.to change {
|
52
|
-
|
50
|
+
expect { subject.typecaster('Object', &:to_s) }
|
51
|
+
.to change { subject.types['Object'] }.from(nil).to(an_instance_of(Class))
|
52
|
+
|
53
|
+
expect(subject.types['Object'].new(Object, nil, stub_model.new).typecast(1)).to eq('1')
|
53
54
|
end
|
55
|
+
|
56
|
+
specify do
|
57
|
+
expect { subject.typecaster(Object) {} }
|
58
|
+
.to change { subject.types['Object'] }.from(nil).to(an_instance_of(Class))
|
59
|
+
end
|
60
|
+
|
54
61
|
specify do
|
55
|
-
expect { subject.typecaster('
|
56
|
-
.to change {
|
57
|
-
.from(nil).to(an_instance_of(Proc))
|
62
|
+
expect { subject.typecaster('object') {} }
|
63
|
+
.to change { subject.types['Object'] }.from(nil).to(an_instance_of(Class))
|
58
64
|
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#type_for' do
|
68
|
+
let(:definition) { subject.types['Numeric'] }
|
69
|
+
|
70
|
+
before { subject.typecaster('Numeric') {} }
|
71
|
+
|
59
72
|
specify do
|
60
|
-
expect
|
61
|
-
|
62
|
-
|
73
|
+
expect(subject.type_for(Numeric)).to eq(definition)
|
74
|
+
expect(subject.type_for(Integer)).to eq(definition)
|
75
|
+
expect { subject.type_for(String) }.to raise_error(Granite::Form::TypecasterMissing)
|
63
76
|
end
|
64
|
-
specify { expect { subject.typecaster(Object) }.to raise_error Granite::Form::TypecasterMissing }
|
65
77
|
end
|
66
78
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Granite::Form::UUID do
|
6
|
+
subject(:uuid) { Granite::Form::UUID.random_create }
|
7
|
+
|
8
|
+
specify { expect(uuid.as_json).to eq(uuid.to_s) }
|
9
|
+
specify { expect(uuid.to_json).to eq("\"#{uuid}\"") }
|
10
|
+
specify { expect(uuid.to_param).to eq(uuid.to_s) }
|
11
|
+
specify { expect(uuid.to_query(:key)).to eq("key=#{uuid}") }
|
12
|
+
end
|
File without changes
|
File without changes
|
data/spec/{lib/granite → granite}/form/model/associations/persistence_adapters/active_record_spec.rb
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/{lib/granite → granite}/form/model/associations/reflections/references_many_spec.rb
RENAMED
File without changes
|
data/spec/{lib/granite → granite}/form/model/associations/reflections/references_one_spec.rb
RENAMED
File without changes
|
File without changes
|
File without changes
|
@@ -57,51 +57,6 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
57
57
|
specify { expect(attribute(default: false, type: Boolean).defaultize(nil)).to eq(false) }
|
58
58
|
end
|
59
59
|
|
60
|
-
describe '#typecast' do
|
61
|
-
context 'when Object' do
|
62
|
-
specify { expect(attribute.typecast(:hello)).to eq(:hello) }
|
63
|
-
end
|
64
|
-
|
65
|
-
context 'when Integer' do
|
66
|
-
specify { expect(attribute(type: Integer).typecast(42)).to eq(42) }
|
67
|
-
specify { expect(attribute(type: Integer).typecast('42')).to eq(42) }
|
68
|
-
end
|
69
|
-
|
70
|
-
context 'when Hash' do
|
71
|
-
let(:to_h) { {'x' => {'foo' => 'bar'}, 'y' => 2} }
|
72
|
-
let(:parameters) { ActionController::Parameters.new(to_h) }
|
73
|
-
|
74
|
-
before(:all) do
|
75
|
-
@default_hash_typecaster = Granite::Form.typecaster('Hash')
|
76
|
-
require 'action_controller'
|
77
|
-
Class.new(ActionController::Base)
|
78
|
-
@action_controller_hash_typecaster = Granite::Form.typecaster('Hash')
|
79
|
-
end
|
80
|
-
|
81
|
-
context 'when ActionController is loaded' do
|
82
|
-
before { Granite::Form.typecaster('Hash', &@action_controller_hash_typecaster) }
|
83
|
-
after { Granite::Form.typecaster('Hash', &@default_hash_typecaster) }
|
84
|
-
|
85
|
-
specify { expect(attribute(type: Hash).typecast(nil)).to be_nil }
|
86
|
-
specify { expect(attribute(type: Hash).typecast(to_h)).to eq(to_h) }
|
87
|
-
specify { expect(attribute(type: Hash).typecast(parameters)).to be_nil }
|
88
|
-
specify { expect(attribute(type: Hash).typecast(parameters.permit(:y, x: [:foo]))).to eq(to_h) }
|
89
|
-
end
|
90
|
-
|
91
|
-
context 'when ActionController is not loaded' do
|
92
|
-
before { Granite::Form.typecaster('Hash', &@default_hash_typecaster) }
|
93
|
-
|
94
|
-
specify { expect(attribute(type: Hash).typecast(nil)).to be_nil }
|
95
|
-
specify { expect(attribute(type: Hash).typecast(to_h)).to eq(to_h) }
|
96
|
-
if ActiveSupport.version > Gem::Version.new('4.3')
|
97
|
-
specify { expect(attribute(type: Hash).typecast(parameters.permit(:y, x: [:foo]))).to be_nil }
|
98
|
-
else
|
99
|
-
specify { expect(attribute(type: Hash).typecast(parameters.permit(:y, x: [:foo]))).to eq(to_h) }
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
60
|
describe '#enum' do
|
106
61
|
before { allow_any_instance_of(Dummy).to receive_messages(value: 1..5) }
|
107
62
|
|
@@ -144,7 +99,10 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
144
99
|
|
145
100
|
context 'integration' do
|
146
101
|
before do
|
147
|
-
|
102
|
+
config = Granite::Form::Config.send(:new)
|
103
|
+
config.types.merge! Granite::Form.config.types
|
104
|
+
allow(Granite::Form).to receive_messages(config: config)
|
105
|
+
|
148
106
|
Granite::Form.normalizer(:strip) { |value, _, _| value.strip }
|
149
107
|
Granite::Form.normalizer(:trim) do |value, options, _attribute|
|
150
108
|
value.first(length || options[:length] || 2)
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Granite::Form::Model::Attributes::Base do
|
4
|
+
let(:model) { Dummy.new }
|
5
|
+
|
4
6
|
before { stub_model(:dummy) }
|
5
7
|
|
6
8
|
def attribute(*args)
|
7
9
|
options = args.extract_options!
|
8
|
-
Dummy.add_attribute(Granite::Form::Model::Attributes::Reflections::Base, :field, options)
|
9
|
-
|
10
|
+
Dummy.add_attribute(Granite::Form::Model::Attributes::Reflections::Base, :field, options.reverse_merge(type: Object))
|
11
|
+
model.attribute(:field)
|
10
12
|
end
|
11
13
|
|
12
14
|
describe '#read' do
|
@@ -94,4 +96,11 @@ describe Granite::Form::Model::Attributes::Base do
|
|
94
96
|
specify { expect(attribute(readonly: -> { false })).not_to be_readonly }
|
95
97
|
specify { expect(attribute(readonly: -> { true })).to be_readonly }
|
96
98
|
end
|
99
|
+
|
100
|
+
describe '#type_definition' do
|
101
|
+
subject { attr.type_definition }
|
102
|
+
let(:attr) { attribute(type: String) }
|
103
|
+
|
104
|
+
it { is_expected.to have_attributes(type: String, reflection: subject.reflection, owner: model) }
|
105
|
+
end
|
97
106
|
end
|
File without changes
|
File without changes
|
@@ -6,7 +6,7 @@ describe Granite::Form::Model::Attributes::Localized do
|
|
6
6
|
def attribute(*args)
|
7
7
|
options = args.extract_options!
|
8
8
|
Dummy.add_attribute(Granite::Form::Model::Attributes::Reflections::Localized, :field, options)
|
9
|
-
|
9
|
+
Dummy.new.attribute(:field)
|
10
10
|
end
|
11
11
|
|
12
12
|
describe '#read' do
|
@@ -43,18 +43,6 @@ describe Granite::Form::Model::Attributes::Reflections::Attribute do
|
|
43
43
|
specify { expect(reflection(default: -> {}).defaultizer).to be_a Proc }
|
44
44
|
end
|
45
45
|
|
46
|
-
describe '#typecaster' do
|
47
|
-
before do
|
48
|
-
stub_class(:dummy, String)
|
49
|
-
stub_class(:dummy_dummy, Dummy)
|
50
|
-
end
|
51
|
-
|
52
|
-
specify { expect(reflection(type: Object).typecaster).to eq(Granite::Form.typecaster(Object)) }
|
53
|
-
specify { expect(reflection(type: String).typecaster).to eq(Granite::Form.typecaster(String)) }
|
54
|
-
specify { expect(reflection(type: Dummy).typecaster).to eq(Granite::Form.typecaster(String)) }
|
55
|
-
specify { expect(reflection(type: DummyDummy).typecaster).to eq(Granite::Form.typecaster(String)) }
|
56
|
-
end
|
57
|
-
|
58
46
|
describe '#enumerizer' do
|
59
47
|
specify { expect(reflection.enumerizer).to be_nil }
|
60
48
|
specify { expect(reflection(enum: 42).enumerizer).to eq(42) }
|
@@ -36,7 +36,7 @@ describe Granite::Form::Model::Attributes::Reflections::Base do
|
|
36
36
|
stub_class(:owner)
|
37
37
|
end
|
38
38
|
|
39
|
-
let(:reflection) { SomeScope::Borogoves.new(:field) }
|
39
|
+
let(:reflection) { SomeScope::Borogoves.new(:field, type: Object) }
|
40
40
|
let(:owner) { Owner.new }
|
41
41
|
|
42
42
|
specify { expect(reflection.build_attribute(owner, nil)).to be_a(Granite::Form::Model::Attributes::Borogoves) }
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -114,35 +114,79 @@ describe Granite::Form::Model::Validations::NestedValidator do
|
|
114
114
|
|
115
115
|
context 'object field is invalid and referenced object does not include AutosaveAssociation' do
|
116
116
|
before do
|
117
|
-
|
118
|
-
include Granite::Form::Model::Validations
|
119
|
-
include Granite::Form::Model::Attributes
|
120
|
-
include Granite::Form::Model::Primary
|
121
|
-
|
122
|
-
primary :id
|
117
|
+
stub_model(:validated_object) do
|
123
118
|
attribute :title, String
|
124
119
|
validates_presence_of :title
|
125
120
|
end
|
126
121
|
|
127
|
-
|
128
|
-
include Granite::Form::Model::
|
122
|
+
stub_model(:main) do
|
123
|
+
include Granite::Form::Model::Persistence
|
124
|
+
|
129
125
|
attribute :object, Object
|
130
126
|
validates :object, nested: true
|
131
127
|
end
|
132
128
|
end
|
133
129
|
|
134
|
-
subject(:instance) { Main.instantiate name: 'hello', object: object
|
130
|
+
subject(:instance) { Main.instantiate name: 'hello', object: object }
|
135
131
|
|
136
|
-
context do
|
132
|
+
context 'nested object is valid' do
|
137
133
|
let(:object) { ValidatedObject.new(title: 'Mr.') }
|
134
|
+
|
138
135
|
it { is_expected.to be_valid }
|
139
136
|
end
|
140
137
|
|
141
|
-
context do
|
138
|
+
context 'nested object is invalid' do
|
142
139
|
let(:object) { ValidatedObject.new }
|
140
|
+
|
143
141
|
it do
|
144
142
|
expect { subject.valid? }.not_to raise_error
|
145
143
|
expect(subject).not_to be_valid
|
144
|
+
expect(subject.errors.count).to eq(1)
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'nested validation runs twice' do
|
148
|
+
before do
|
149
|
+
stub_model(:main) do
|
150
|
+
include Granite::Form::Model::Persistence
|
151
|
+
|
152
|
+
attribute :object, Object
|
153
|
+
validates :object, nested: true
|
154
|
+
validates :object, nested: true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it do
|
159
|
+
subject.validate
|
160
|
+
expect(subject.errors.count).to eq(1)
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'nested object validation has condition' do
|
164
|
+
before do
|
165
|
+
stub_model(:validated_object) do
|
166
|
+
attribute :title, String
|
167
|
+
validates_presence_of :title, if: -> { true }
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it do
|
172
|
+
subject.validate
|
173
|
+
expect(subject.errors.count).to eq(1)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'nested object validation has message' do
|
178
|
+
before do
|
179
|
+
stub_model(:validated_object) do
|
180
|
+
attribute :title, String
|
181
|
+
validates_presence_of :title, message: 'test'
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
it do
|
186
|
+
subject.validate
|
187
|
+
expect(subject.errors.count).to eq(1)
|
188
|
+
end
|
189
|
+
end
|
146
190
|
end
|
147
191
|
end
|
148
192
|
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Granite::Form::Types::ActiveSupport::TimeZone do
|
6
|
+
describe 'typecasting' do
|
7
|
+
include_context 'type setup', 'ActiveSupport::TimeZone'
|
8
|
+
|
9
|
+
specify { expect(typecast(nil)).to be_nil }
|
10
|
+
specify { expect(typecast(Object.new)).to be_nil }
|
11
|
+
specify { expect(typecast(Time.now)).to be_nil }
|
12
|
+
specify { expect(typecast('blablabla')).to be_nil }
|
13
|
+
specify { expect(typecast(TZInfo::Timezone.all.first)).to be_a ActiveSupport::TimeZone }
|
14
|
+
specify { expect(typecast('Moscow')).to be_a ActiveSupport::TimeZone }
|
15
|
+
specify { expect(typecast('+4')).to be_a ActiveSupport::TimeZone }
|
16
|
+
specify { expect(typecast('-3')).to be_a ActiveSupport::TimeZone }
|
17
|
+
specify { expect(typecast('3600')).to be_a ActiveSupport::TimeZone }
|
18
|
+
specify { expect(typecast('-7200')).to be_a ActiveSupport::TimeZone }
|
19
|
+
specify { expect(typecast(4)).to be_a ActiveSupport::TimeZone }
|
20
|
+
specify { expect(typecast(-3)).to be_a ActiveSupport::TimeZone }
|
21
|
+
specify { expect(typecast(3600)).to be_a ActiveSupport::TimeZone }
|
22
|
+
specify { expect(typecast(-7200)).to be_a ActiveSupport::TimeZone }
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Granite::Form::Types::Array do
|
6
|
+
describe 'typecasting' do
|
7
|
+
include_context 'type setup', 'Array'
|
8
|
+
|
9
|
+
specify { expect(typecast([1, 2, 3])).to eq([1, 2, 3]) }
|
10
|
+
specify { expect(typecast('hello, world')).to eq(%w[hello world]) }
|
11
|
+
specify { expect(typecast(10)).to be_nil }
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Granite::Form::Types::BigDecimal do
|
6
|
+
describe 'typecasting' do
|
7
|
+
include_context 'type setup', 'BigDecimal'
|
8
|
+
|
9
|
+
specify { expect(typecast('hello')).to be_nil }
|
10
|
+
specify { expect(typecast('123hello')).to be_nil }
|
11
|
+
specify { expect(typecast('123')).to eq(BigDecimal('123.0')) }
|
12
|
+
specify { expect(typecast('123.')).to be_nil }
|
13
|
+
specify { expect(typecast('123.5')).to eq(BigDecimal('123.5')) }
|
14
|
+
specify { expect(typecast(123)).to eq(BigDecimal('123.0')) }
|
15
|
+
specify { expect(typecast(123.5)).to eq(BigDecimal('123.5')) }
|
16
|
+
specify { expect(typecast(nil)).to be_nil }
|
17
|
+
specify { expect(typecast([123.5])).to be_nil }
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Granite::Form::Types::Boolean do
|
6
|
+
describe 'typecasting' do
|
7
|
+
include_context 'type setup', 'Boolean'
|
8
|
+
|
9
|
+
specify { expect(typecast('hello')).to be_nil }
|
10
|
+
specify { expect(typecast('true')).to eq(true) }
|
11
|
+
specify { expect(typecast('false')).to eq(false) }
|
12
|
+
specify { expect(typecast('1')).to eq(true) }
|
13
|
+
specify { expect(typecast('0')).to eq(false) }
|
14
|
+
specify { expect(typecast(true)).to eq(true) }
|
15
|
+
specify { expect(typecast(false)).to eq(false) }
|
16
|
+
specify { expect(typecast(1)).to eq(true) }
|
17
|
+
specify { expect(typecast(0)).to eq(false) }
|
18
|
+
specify { expect(typecast(nil)).to be_nil }
|
19
|
+
specify { expect(typecast([123])).to be_nil }
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Granite::Form::Types::Date do
|
6
|
+
describe 'typecasting' do
|
7
|
+
include_context 'type setup', 'Date'
|
8
|
+
let(:date) { Date.new(2013, 6, 13) }
|
9
|
+
|
10
|
+
specify { expect(typecast(nil)).to be_nil }
|
11
|
+
specify { expect(typecast('2013-06-13')).to eq(date) }
|
12
|
+
specify { expect(typecast('2013-55-55')).to be_nil }
|
13
|
+
specify { expect(typecast('blablabla')).to be_nil }
|
14
|
+
specify { expect(typecast(DateTime.new(2013, 6, 13, 23, 13))).to eq(date) } # rubocop:disable Style/DateTime
|
15
|
+
specify { expect(typecast(Time.new(2013, 6, 13, 23, 13))).to eq(date) }
|
16
|
+
specify { expect(typecast(Date.new(2013, 6, 13))).to eq(date) }
|
17
|
+
end
|
18
|
+
end
|