granite-form 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -2
- data/.github/workflows/{ci.yml → ruby.yml} +22 -4
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +3 -3
- data/Appraisals +1 -2
- data/CHANGELOG.md +15 -0
- data/README.md +6 -15
- data/docker-compose.yml +14 -0
- data/gemfiles/rails.5.0.gemfile +0 -1
- data/gemfiles/rails.5.1.gemfile +0 -1
- data/gemfiles/rails.5.2.gemfile +0 -1
- data/granite-form.gemspec +15 -15
- data/lib/granite/form/active_record/associations.rb +1 -1
- data/lib/granite/form/base.rb +1 -2
- data/lib/granite/form/errors.rb +0 -15
- data/lib/granite/form/model/associations/base.rb +0 -4
- data/lib/granite/form/model/associations/collection/embedded.rb +2 -1
- data/lib/granite/form/model/associations/collection/proxy.rb +1 -1
- data/lib/granite/form/model/associations/embeds_any.rb +7 -0
- data/lib/granite/form/model/associations/embeds_many.rb +9 -58
- data/lib/granite/form/model/associations/embeds_one.rb +7 -36
- data/lib/granite/form/model/associations/nested_attributes.rb +7 -7
- data/lib/granite/form/model/associations/persistence_adapters/active_record.rb +0 -4
- data/lib/granite/form/model/associations/persistence_adapters/base.rb +0 -4
- data/lib/granite/form/model/associations/references_many.rb +0 -32
- data/lib/granite/form/model/associations/references_one.rb +0 -28
- data/lib/granite/form/model/associations/reflections/embeds_any.rb +1 -1
- data/lib/granite/form/model/associations/reflections/embeds_many.rb +1 -1
- data/lib/granite/form/model/associations/reflections/embeds_one.rb +11 -1
- data/lib/granite/form/model/associations/reflections/references_any.rb +0 -4
- data/lib/granite/form/model/associations/reflections/singular.rb +0 -22
- data/lib/granite/form/model/associations.rb +0 -6
- data/lib/granite/form/model/attributes/attribute.rb +3 -21
- data/lib/granite/form/model/attributes/base.rb +5 -23
- data/lib/granite/form/model/attributes/reference_many.rb +1 -1
- data/lib/granite/form/model/attributes/reference_one.rb +1 -1
- data/lib/granite/form/model/attributes/reflections/attribute.rb +2 -8
- data/lib/granite/form/model/attributes/reflections/base/build_type_definition.rb +38 -0
- data/lib/granite/form/model/attributes/reflections/base.rb +20 -17
- data/lib/granite/form/model/attributes/reflections/collection/build_type_definition.rb +19 -0
- data/lib/granite/form/model/attributes/reflections/dictionary/build_type_definition.rb +19 -0
- data/lib/granite/form/model/attributes/reflections/dictionary.rb +0 -3
- data/lib/granite/form/model/attributes/reflections/reference_one.rb +0 -6
- data/lib/granite/form/model/attributes/reflections/represents/build_type_definition.rb +73 -0
- data/lib/granite/form/model/attributes/reflections/represents.rb +10 -2
- data/lib/granite/form/model/attributes/represents.rb +22 -37
- data/lib/granite/form/model/attributes.rb +10 -2
- data/lib/granite/form/model/persistence.rb +1 -19
- data/lib/granite/form/model/representation.rb +1 -0
- data/lib/granite/form/model/validations.rb +6 -0
- data/lib/granite/form/model.rb +1 -3
- data/lib/granite/form/types/active_support/time_zone.rb +2 -0
- data/lib/granite/form/types/array.rb +2 -0
- data/lib/granite/form/types/big_decimal.rb +2 -0
- data/lib/granite/form/types/boolean.rb +2 -0
- data/lib/granite/form/types/collection.rb +11 -0
- data/lib/granite/form/types/date.rb +2 -0
- data/lib/granite/form/types/date_time.rb +2 -0
- data/lib/granite/form/types/dictionary.rb +23 -0
- data/lib/granite/form/types/float.rb +2 -0
- data/lib/granite/form/types/has_subtype.rb +18 -0
- data/lib/granite/form/types/hash_with_action_controller_parameters.rb +2 -0
- data/lib/granite/form/types/integer.rb +2 -0
- data/lib/granite/form/types/object.rb +28 -0
- data/lib/granite/form/types/string.rb +2 -0
- data/lib/granite/form/types/time.rb +2 -0
- data/lib/granite/form/types/uuid.rb +2 -0
- data/lib/granite/form/types.rb +3 -0
- data/lib/granite/form/util.rb +55 -0
- data/lib/granite/form/version.rb +1 -1
- data/lib/granite/form.rb +1 -0
- data/spec/granite/form/active_record/associations_spec.rb +16 -18
- data/spec/granite/form/model/associations/embeds_many_spec.rb +29 -305
- data/spec/granite/form/model/associations/embeds_one_spec.rb +27 -212
- data/spec/granite/form/model/associations/nested_attributes_spec.rb +0 -95
- data/spec/granite/form/model/associations/references_many_spec.rb +5 -326
- data/spec/granite/form/model/associations/references_one_spec.rb +7 -279
- data/spec/granite/form/model/associations/reflections/embeds_any_spec.rb +1 -2
- data/spec/granite/form/model/associations/reflections/embeds_many_spec.rb +18 -26
- data/spec/granite/form/model/associations/reflections/embeds_one_spec.rb +16 -23
- data/spec/granite/form/model/associations/reflections/references_many_spec.rb +1 -1
- data/spec/granite/form/model/associations/reflections/references_one_spec.rb +1 -22
- data/spec/granite/form/model/associations/validations_spec.rb +0 -3
- data/spec/granite/form/model/associations_spec.rb +3 -24
- data/spec/granite/form/model/attributes/attribute_spec.rb +0 -29
- data/spec/granite/form/model/attributes/reflections/attribute_spec.rb +0 -9
- data/spec/granite/form/model/attributes/reflections/base/build_type_definition_spec.rb +27 -0
- data/spec/granite/form/model/attributes/reflections/base_spec.rb +16 -10
- data/spec/granite/form/model/attributes/reflections/collection/build_type_definition_spec.rb +24 -0
- data/spec/granite/form/model/attributes/reflections/dictionary/build_type_definition_spec.rb +24 -0
- data/spec/granite/form/model/attributes/reflections/dictionary_spec.rb +0 -6
- data/spec/granite/form/model/attributes/reflections/represents/build_type_definition_spec.rb +129 -0
- data/spec/granite/form/model/attributes/reflections/represents_spec.rb +43 -20
- data/spec/granite/form/model/attributes/represents_spec.rb +78 -55
- data/spec/granite/form/model/attributes_spec.rb +84 -23
- data/spec/granite/form/model/dirty_spec.rb +1 -7
- data/spec/granite/form/model/persistence_spec.rb +0 -2
- data/spec/granite/form/model/representation_spec.rb +4 -7
- data/spec/granite/form/model/validations/associated_spec.rb +2 -4
- data/spec/granite/form/model/validations/nested_spec.rb +2 -4
- data/spec/granite/form/model/validations_spec.rb +28 -1
- data/spec/granite/form/types/collection_spec.rb +22 -0
- data/spec/granite/form/types/dictionary_spec.rb +32 -0
- data/spec/granite/form/types/has_subtype_spec.rb +20 -0
- data/spec/granite/form/types/object_spec.rb +50 -4
- data/spec/granite/form/util_spec.rb +108 -0
- data/spec/spec_helper.rb +0 -15
- data/spec/support/active_record.rb +23 -0
- data/spec/support/shared/nested_attribute_examples.rb +3 -21
- metadata +56 -51
- data/.github/workflows/main.yml +0 -29
- data/gemfiles/rails.4.2.gemfile +0 -15
- data/lib/granite/form/model/attributes/collection.rb +0 -19
- data/lib/granite/form/model/attributes/dictionary.rb +0 -28
- data/lib/granite/form/model/attributes/localized.rb +0 -44
- data/lib/granite/form/model/attributes/reflections/localized.rb +0 -45
- data/lib/granite/form/model/callbacks.rb +0 -72
- data/lib/granite/form/model/lifecycle.rb +0 -309
- data/lib/granite/form/model/localization.rb +0 -26
- data/spec/granite/form/model/attributes/collection_spec.rb +0 -72
- data/spec/granite/form/model/attributes/dictionary_spec.rb +0 -100
- data/spec/granite/form/model/attributes/localized_spec.rb +0 -103
- data/spec/granite/form/model/attributes/reflections/localized_spec.rb +0 -37
- data/spec/granite/form/model/callbacks_spec.rb +0 -337
- data/spec/granite/form/model/lifecycle_spec.rb +0 -356
@@ -3,7 +3,8 @@ require 'spec_helper'
|
|
3
3
|
describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
|
4
4
|
before do
|
5
5
|
stub_model(:project) do
|
6
|
-
include Granite::Form::Model::
|
6
|
+
include Granite::Form::Model::Persistence
|
7
|
+
include Granite::Form::Model::Associations
|
7
8
|
attribute :title, String
|
8
9
|
end
|
9
10
|
stub_model(:user) do
|
@@ -24,24 +25,28 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
|
|
24
25
|
attribute :name
|
25
26
|
embeds_many :projects,
|
26
27
|
read: lambda { |reflection, object|
|
27
|
-
value = object.
|
28
|
+
value = object.instance_variable_get("@_value_#{reflection.name}")
|
28
29
|
JSON.parse(value) if value.present?
|
29
30
|
},
|
30
31
|
write: lambda { |reflection, object, value|
|
31
|
-
|
32
|
+
value = value.to_json if value
|
33
|
+
object.instance_variable_set("@_value_#{reflection.name}", value)
|
32
34
|
}
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
|
-
let(:user) { User.
|
38
|
+
let(:user) { User.new }
|
37
39
|
let(:new_project1) { Project.new(title: 'Project 1') }
|
38
40
|
let(:new_project2) { Project.new(title: 'Project 2') }
|
39
41
|
|
40
42
|
specify do
|
41
|
-
expect
|
42
|
-
.
|
43
|
-
.
|
44
|
-
|
43
|
+
expect do
|
44
|
+
user.projects = [new_project1, new_project2]
|
45
|
+
user.association(:projects).sync
|
46
|
+
end
|
47
|
+
.to change { user.projects(true) }
|
48
|
+
.from([])
|
49
|
+
.to([have_attributes(title: 'Project 1'), have_attributes(title: 'Project 2')])
|
45
50
|
end
|
46
51
|
end
|
47
52
|
|
@@ -54,23 +59,10 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
|
|
54
59
|
specify { expect { user.projects.build(title: 'Project') }.to change { user.projects }.from([]).to([project]) }
|
55
60
|
end
|
56
61
|
|
57
|
-
describe '#create' do
|
58
|
-
let(:project) { Project.new title: 'Project' }
|
59
|
-
specify { expect(user.projects.create(title: 'Project')).to eq(project) }
|
60
|
-
specify { expect { user.projects.create(title: 'Project') }.to change { user.projects }.from([]).to([project]) }
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#create!' do
|
64
|
-
let(:project) { Project.new title: 'Project' }
|
65
|
-
specify { expect(user.projects.create!(title: 'Project')).to eq(project) }
|
66
|
-
specify { expect { user.projects.create!(title: 'Project') }.to change { user.projects }.from([]).to([project]) }
|
67
|
-
end
|
68
|
-
|
69
62
|
describe '#reload' do
|
70
63
|
let(:project) { Project.new title: 'Project' }
|
71
64
|
before do
|
72
|
-
user.
|
73
|
-
user.apply_association_changes!
|
65
|
+
user.write_attribute(:projects, [{title: 'Project'}])
|
74
66
|
end
|
75
67
|
before { user.projects.build }
|
76
68
|
|
@@ -120,8 +112,8 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
|
|
120
112
|
|
121
113
|
specify { expect(User.reflect_on_association(:projects).klass).to eq(User::Project) }
|
122
114
|
specify { expect(User.new.projects).to eq([]) }
|
123
|
-
specify { expect(User.new.tap { |u| u.projects.
|
124
|
-
specify { expect(User.new.tap { |u| u.projects.
|
115
|
+
specify { expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects).to be_a(Granite::Form::Model::Associations::Collection::Embedded) }
|
116
|
+
specify { expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects).to match([have_attributes(title: 'Project')]) }
|
125
117
|
end
|
126
118
|
|
127
119
|
context do
|
@@ -138,8 +130,8 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
|
|
138
130
|
|
139
131
|
specify { expect(User.reflect_on_association(:projects).klass).to eq(User::Project) }
|
140
132
|
specify { expect(User.new.projects).to eq([]) }
|
141
|
-
specify { expect(User.new.tap { |u| u.projects.
|
142
|
-
specify { expect(User.new.tap { |u| u.projects.
|
133
|
+
specify { expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects).to be_a(Granite::Form::Model::Associations::Collection::Embedded) }
|
134
|
+
specify { expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects).to match([have_attributes(title: 'Project', value: nil)]) }
|
143
135
|
end
|
144
136
|
end
|
145
137
|
end
|
@@ -3,7 +3,8 @@ require 'spec_helper'
|
|
3
3
|
describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
|
4
4
|
before do
|
5
5
|
stub_model(:author) do
|
6
|
-
include Granite::Form::Model::
|
6
|
+
include Granite::Form::Model::Persistence
|
7
|
+
include Granite::Form::Model::Associations
|
7
8
|
attribute :name, String
|
8
9
|
end
|
9
10
|
|
@@ -27,22 +28,26 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
|
|
27
28
|
attribute :title
|
28
29
|
embeds_one :author,
|
29
30
|
read: lambda { |reflection, object|
|
30
|
-
value = object.
|
31
|
+
value = object.instance_variable_get("@_value_#{reflection.name}")
|
31
32
|
JSON.parse(value) if value.present?
|
32
33
|
},
|
33
34
|
write: lambda { |reflection, object, value|
|
34
|
-
|
35
|
+
value = value.to_json if value
|
36
|
+
object.instance_variable_set("@_value_#{reflection.name}", value)
|
35
37
|
}
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
|
-
let(:book) { Book.
|
41
|
+
let(:book) { Book.new }
|
40
42
|
let(:author) { Author.new(name: 'Rick') }
|
41
43
|
|
42
44
|
specify do
|
43
|
-
expect
|
44
|
-
.
|
45
|
-
.
|
45
|
+
expect do
|
46
|
+
book.author = author
|
47
|
+
book.association(:author).sync
|
48
|
+
end
|
49
|
+
.to change { book.author(true) }
|
50
|
+
.from(nil).to(have_attributes(name: 'Rick'))
|
46
51
|
end
|
47
52
|
end
|
48
53
|
|
@@ -65,18 +70,6 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
|
|
65
70
|
specify { expect { book.build_author(name: 'Author') }.to change { book.author }.from(nil).to(author) }
|
66
71
|
end
|
67
72
|
|
68
|
-
describe '#create_author' do
|
69
|
-
let(:author) { Author.new name: 'Author' }
|
70
|
-
specify { expect(book.create_author(name: 'Author')).to eq(author) }
|
71
|
-
specify { expect { book.create_author(name: 'Author') }.to change { book.author }.from(nil).to(author) }
|
72
|
-
end
|
73
|
-
|
74
|
-
describe '#create_author!' do
|
75
|
-
let(:author) { Author.new name: 'Author' }
|
76
|
-
specify { expect(book.create_author!(name: 'Author')).to eq(author) }
|
77
|
-
specify { expect { book.create_author!(name: 'Author') }.to change { book.author }.from(nil).to(author) }
|
78
|
-
end
|
79
|
-
|
80
73
|
context 'on the fly' do
|
81
74
|
context do
|
82
75
|
before do
|
@@ -92,8 +85,8 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
|
|
92
85
|
|
93
86
|
specify { expect(Book.reflect_on_association(:author).klass).to eq(Book::Author) }
|
94
87
|
specify { expect(Book.new.author).to be_nil }
|
95
|
-
specify { expect(Book.new.tap { |b| b.
|
96
|
-
specify { expect(Book.new.tap { |b| b.
|
88
|
+
specify { expect(Book.new.tap { |b| b.build_author(name: 'Author') }.author).to be_a(Book::Author) }
|
89
|
+
specify { expect(Book.new.tap { |b| b.build_author(name: 'Author') }.author).to have_attributes(name: 'Author') }
|
97
90
|
end
|
98
91
|
|
99
92
|
context do
|
@@ -110,8 +103,8 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
|
|
110
103
|
|
111
104
|
specify { expect(Book.reflect_on_association(:author).klass).to eq(Book::Author) }
|
112
105
|
specify { expect(Book.new.author).to be_nil }
|
113
|
-
specify { expect(Book.new.tap { |b| b.
|
114
|
-
specify { expect(Book.new.tap { |b| b.
|
106
|
+
specify { expect(Book.new.tap { |b| b.build_author(name: 'Author') }.author).to be_a(Book::Author) }
|
107
|
+
specify { expect(Book.new.tap { |b| b.build_author(name: 'Author') }.author).to have_attributes(name: 'Author', age: nil) }
|
115
108
|
end
|
116
109
|
end
|
117
110
|
end
|
@@ -4,7 +4,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
|
|
4
4
|
before do
|
5
5
|
stub_class(:author, ActiveRecord::Base) do
|
6
6
|
scope :name_starts_with_a, -> { name_starts_with('a') }
|
7
|
-
scope :name_starts_with, ->(letter) { where("name
|
7
|
+
scope :name_starts_with, ->(letter) { where("name ILIKE '#{letter}%'") }
|
8
8
|
end
|
9
9
|
|
10
10
|
stub_model(:book) do
|
@@ -4,7 +4,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
4
4
|
before do
|
5
5
|
stub_class(:author, ActiveRecord::Base) do
|
6
6
|
scope :name_starts_with_a, -> { name_starts_with('a') }
|
7
|
-
scope :name_starts_with, ->(letter) { where("name
|
7
|
+
scope :name_starts_with, ->(letter) { where("name ILIKE '#{letter}%'") }
|
8
8
|
end
|
9
9
|
|
10
10
|
stub_model(:book) do
|
@@ -263,25 +263,4 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
|
|
263
263
|
specify { expect { book.author_id = nil }.to change { book.author }.from(other).to(nil) }
|
264
264
|
end
|
265
265
|
end
|
266
|
-
|
267
|
-
describe '#build_author' do
|
268
|
-
specify { expect(book.build_author(name: 'Author')).to be_a(Author) }
|
269
|
-
specify { expect(book.build_author(name: 'Author')).not_to be_persisted }
|
270
|
-
specify { expect { book.build_author(name: 'Author') }.to change { book.author }.from(nil).to(an_instance_of(Author)) }
|
271
|
-
specify { expect { book.build_author(name: 'Author') }.not_to change { book.author_id }.from(nil) }
|
272
|
-
end
|
273
|
-
|
274
|
-
describe '#create_author' do
|
275
|
-
specify { expect(book.create_author(name: 'Author')).to be_a(Author) }
|
276
|
-
specify { expect(book.create_author(name: 'Author')).to be_persisted }
|
277
|
-
specify { expect { book.create_author(name: 'Author') }.to change { book.author }.from(nil).to(an_instance_of(Author)) }
|
278
|
-
specify { expect { book.create_author(name: 'Author') }.to change { book.author_id }.from(nil).to(be_a(Integer)) }
|
279
|
-
end
|
280
|
-
|
281
|
-
describe '#create_author!' do
|
282
|
-
specify { expect(book.create_author!(name: 'Author')).to be_a(Author) }
|
283
|
-
specify { expect(book.create_author!(name: 'Author')).to be_persisted }
|
284
|
-
specify { expect { book.create_author!(name: 'Author') }.to change { book.author }.from(nil).to(an_instance_of(Author)) }
|
285
|
-
specify { expect { book.create_author!(name: 'Author') }.to change { book.author_id }.from(nil).to(be_a(Integer)) }
|
286
|
-
end
|
287
266
|
end
|
@@ -3,7 +3,6 @@ require 'spec_helper'
|
|
3
3
|
describe Granite::Form::Model::Associations::Validations do
|
4
4
|
before do
|
5
5
|
stub_model(:project) do
|
6
|
-
include Granite::Form::Model::Lifecycle
|
7
6
|
include Granite::Form::Model::Associations
|
8
7
|
include Granite::Form::Model::Associations::Validations
|
9
8
|
|
@@ -17,8 +16,6 @@ describe Granite::Form::Model::Associations::Validations do
|
|
17
16
|
end
|
18
17
|
|
19
18
|
stub_model(:profile) do
|
20
|
-
include Granite::Form::Model::Lifecycle
|
21
|
-
|
22
19
|
attribute :first_name, String
|
23
20
|
attribute :last_name, String
|
24
21
|
validates :first_name, presence: true
|
@@ -7,7 +7,7 @@ describe Granite::Form::Model::Associations do
|
|
7
7
|
include Granite::Form::Model::Associations
|
8
8
|
end
|
9
9
|
stub_model(:project) do
|
10
|
-
include Granite::Form::Model::
|
10
|
+
include Granite::Form::Model::Persistence
|
11
11
|
end
|
12
12
|
stub_model(:user, Nobody) do
|
13
13
|
include Granite::Form::Model::Associations
|
@@ -65,7 +65,7 @@ describe Granite::Form::Model::Associations do
|
|
65
65
|
context do
|
66
66
|
before do
|
67
67
|
stub_model(:project) do
|
68
|
-
include Granite::Form::Model::
|
68
|
+
include Granite::Form::Model::Persistence
|
69
69
|
include Granite::Form::Model::Associations
|
70
70
|
|
71
71
|
attribute :title, String
|
@@ -80,7 +80,7 @@ describe Granite::Form::Model::Associations do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
stub_model(:profile) do
|
83
|
-
include Granite::Form::Model::
|
83
|
+
include Granite::Form::Model::Persistence
|
84
84
|
|
85
85
|
attribute :first_name, String
|
86
86
|
attribute :last_name, String
|
@@ -160,27 +160,6 @@ describe Granite::Form::Model::Associations do
|
|
160
160
|
specify { expect(user.association_names).to eq(%i[profile projects]) }
|
161
161
|
end
|
162
162
|
|
163
|
-
describe '#apply_association_changes!' do
|
164
|
-
let(:profile) { Profile.new first_name: 'Name' }
|
165
|
-
let(:project) { Project.new title: 'Project' }
|
166
|
-
let(:user) { User.new(profile: profile, projects: [project]) }
|
167
|
-
before { project.build_author(name: 'Author') }
|
168
|
-
|
169
|
-
specify do
|
170
|
-
expect { user.apply_association_changes! }.to change { user.attributes['profile'] }
|
171
|
-
.from(nil).to('first_name' => 'Name', 'last_name' => nil)
|
172
|
-
end
|
173
|
-
specify do
|
174
|
-
expect { user.apply_association_changes! }.to change { user.attributes['projects'] }
|
175
|
-
.from(nil).to([{'title' => 'Project', 'author' => {'name' => 'Author'}}])
|
176
|
-
end
|
177
|
-
|
178
|
-
context do
|
179
|
-
let(:project) { Project.new }
|
180
|
-
specify { expect { user.apply_association_changes! }.to raise_error Granite::Form::AssociationChangesNotApplied }
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
163
|
describe '#instantiate' do
|
185
164
|
before { User.send(:include, Granite::Form::Model::Persistence) }
|
186
165
|
let(:profile) { Profile.new first_name: 'Name' }
|
@@ -46,8 +46,6 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
46
46
|
specify { expect(attribute.default).to eq(nil) }
|
47
47
|
specify { expect(attribute(default: 'hello').default).to eq('hello') }
|
48
48
|
specify { expect(attribute(default: -> { value }).default).to eq(42) }
|
49
|
-
specify { expect(attribute(default: ->(object) { object.value }).default).to eq(42) }
|
50
|
-
specify { expect(attribute(default: ->(*args) { args.first.value }).default).to eq(42) }
|
51
49
|
end
|
52
50
|
|
53
51
|
describe '#defaultize' do
|
@@ -57,31 +55,6 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
57
55
|
specify { expect(attribute(default: false, type: Boolean).defaultize(nil)).to eq(false) }
|
58
56
|
end
|
59
57
|
|
60
|
-
describe '#enum' do
|
61
|
-
before { allow_any_instance_of(Dummy).to receive_messages(value: 1..5) }
|
62
|
-
|
63
|
-
specify { expect(attribute.enum).to eq([].to_set) }
|
64
|
-
specify { expect(attribute(enum: []).enum).to eq([].to_set) }
|
65
|
-
specify { expect(attribute(enum: 'hello').enum).to eq(['hello'].to_set) }
|
66
|
-
specify { expect(attribute(enum: %w[hello world]).enum).to eq(%w[hello world].to_set) }
|
67
|
-
specify { expect(attribute(enum: [1..5]).enum).to eq([1..5].to_set) }
|
68
|
-
specify { expect(attribute(enum: 1..5).enum).to eq((1..5).to_a.to_set) }
|
69
|
-
specify { expect(attribute(enum: -> { 1..5 }).enum).to eq((1..5).to_a.to_set) }
|
70
|
-
specify { expect(attribute(enum: -> { 'hello' }).enum).to eq(['hello'].to_set) }
|
71
|
-
specify { expect(attribute(enum: -> { ['hello', 42] }).enum).to eq(['hello', 42].to_set) }
|
72
|
-
specify { expect(attribute(enum: -> { value }).enum).to eq((1..5).to_a.to_set) }
|
73
|
-
specify { expect(attribute(enum: ->(object) { object.value }).enum).to eq((1..5).to_a.to_set) }
|
74
|
-
end
|
75
|
-
|
76
|
-
describe '#enumerize' do
|
77
|
-
specify { expect(attribute.enumerize('anything')).to eq('anything') }
|
78
|
-
specify { expect(attribute(enum: ['hello', 42]).enumerize('hello')).to eq('hello') }
|
79
|
-
specify { expect(attribute(enum: ['hello', 42]).enumerize('world')).to eq(nil) }
|
80
|
-
specify { expect(attribute(enum: -> { 'hello' }).enumerize('hello')).to eq('hello') }
|
81
|
-
specify { expect(attribute(enum: -> { 1..5 }).enumerize(2)).to eq(2) }
|
82
|
-
specify { expect(attribute(enum: -> { 1..5 }).enumerize(42)).to eq(nil) }
|
83
|
-
end
|
84
|
-
|
85
58
|
describe '#normalize' do
|
86
59
|
specify { expect(attribute.normalize(' hello ')).to eq(' hello ') }
|
87
60
|
specify { expect(attribute(normalizer: ->(v) { v.strip }).normalize(' hello ')).to eq('hello') }
|
@@ -93,8 +66,6 @@ describe Granite::Form::Model::Attributes::Attribute do
|
|
93
66
|
let(:other) { 'other' }
|
94
67
|
|
95
68
|
specify { expect(attribute(normalizer: ->(_v) { value }).normalize(' hello ')).to eq('value') }
|
96
|
-
specify { expect(attribute(normalizer: ->(_v, object) { object.value }).normalize(' hello ')).to eq('value') }
|
97
|
-
specify { expect(attribute(normalizer: ->(_v, _object) { other }).normalize(' hello ')).to eq('other') }
|
98
69
|
end
|
99
70
|
|
100
71
|
context 'integration' do
|
@@ -43,15 +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 '#enumerizer' do
|
47
|
-
specify { expect(reflection.enumerizer).to be_nil }
|
48
|
-
specify { expect(reflection(enum: 42).enumerizer).to eq(42) }
|
49
|
-
specify { expect(reflection(enum: -> {}).enumerizer).to be_a Proc }
|
50
|
-
specify { expect(reflection(in: 42).enumerizer).to eq(42) }
|
51
|
-
specify { expect(reflection(in: -> {}).enumerizer).to be_a Proc }
|
52
|
-
specify { expect(reflection(enum: 42, in: -> {}).enumerizer).to eq(42) }
|
53
|
-
end
|
54
|
-
|
55
46
|
describe '#normalizers' do
|
56
47
|
specify { expect(reflection.normalizers).to eq([]) }
|
57
48
|
specify { expect(reflection(normalizer: -> {}).normalizers).to be_a Array }
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Granite::Form::Model::Attributes::Reflections::Base::BuildTypeDefinition do
|
6
|
+
def build_type_definition(**options)
|
7
|
+
@reflection = Granite::Form::Model::Attributes::Reflections::Base.new(:field, options)
|
8
|
+
described_class.new(owner, @reflection).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def have_type(type)
|
12
|
+
have_attributes(type: type, reflection: @reflection, owner: owner)
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
stub_class :owner
|
17
|
+
stub_class(:dummy, String)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:owner) { Owner.new }
|
21
|
+
|
22
|
+
specify { expect { build_type_definition }.to raise_error('Type is not specified for `field`') }
|
23
|
+
specify { expect(build_type_definition(type: String)).to have_type(String) }
|
24
|
+
specify { expect(build_type_definition(type: :string)).to have_type(String) }
|
25
|
+
specify { expect(build_type_definition(type: Dummy)).to have_type(Dummy) }
|
26
|
+
specify { expect { build_type_definition(type: :blabla) }.to raise_error NameError }
|
27
|
+
end
|
@@ -30,6 +30,8 @@ describe Granite::Form::Model::Attributes::Reflections::Base do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
describe '#build_attribute' do
|
33
|
+
subject { reflection.build_attribute(owner, nil) }
|
34
|
+
|
33
35
|
before do
|
34
36
|
stub_class('SomeScope::Borogoves', described_class)
|
35
37
|
stub_class('Granite::Form::Model::Attributes::Borogoves', Granite::Form::Model::Attributes::Base)
|
@@ -39,18 +41,22 @@ describe Granite::Form::Model::Attributes::Reflections::Base do
|
|
39
41
|
let(:reflection) { SomeScope::Borogoves.new(:field, type: Object) }
|
40
42
|
let(:owner) { Owner.new }
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
specify { expect(reflection.build_attribute(owner, nil).owner).to eq(owner) }
|
44
|
+
it { is_expected.to be_a(Granite::Form::Model::Attributes::Borogoves) }
|
45
|
+
it { is_expected.to have_attributes(reflection: reflection, owner: owner, type: Object) }
|
45
46
|
end
|
46
47
|
|
47
|
-
describe '#
|
48
|
-
|
48
|
+
describe '#enum' do
|
49
|
+
specify { expect(reflection.enum).to be_nil }
|
50
|
+
specify { expect(reflection(enum: 42).enum).to eq(42) }
|
51
|
+
specify { expect(reflection(enum: -> {}).enum).to be_a Proc }
|
52
|
+
specify { expect(reflection(in: 42).enum).to eq(42) }
|
53
|
+
specify { expect(reflection(in: -> {}).enum).to be_a Proc }
|
54
|
+
specify { expect(reflection(enum: 42, in: -> {}).enum).to eq(42) }
|
55
|
+
end
|
49
56
|
|
50
|
-
|
51
|
-
specify { expect(reflection
|
52
|
-
specify { expect(reflection(
|
53
|
-
specify { expect(reflection(
|
54
|
-
specify { expect { reflection(type: :blabla).type }.to raise_error NameError }
|
57
|
+
describe '#keys' do
|
58
|
+
specify { expect(reflection.keys).to eq([]) }
|
59
|
+
specify { expect(reflection(keys: ['a', :b]).keys).to eq(%w[a b]) }
|
60
|
+
specify { expect(reflection(keys: :c).keys).to eq(%w[c]) }
|
55
61
|
end
|
56
62
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Granite::Form::Model::Attributes::Reflections::Collection::BuildTypeDefinition do
|
6
|
+
def build_type_definition(name = :name, **options)
|
7
|
+
@reflection = Granite::Form::Model::Attributes::Reflections::Collection.new(name, options)
|
8
|
+
described_class.new(owner, @reflection).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def have_collection_type(type)
|
12
|
+
subtype_definition = have_attributes(type: type, reflection: @reflection, owner: owner)
|
13
|
+
have_attributes(subtype_definition: subtype_definition)
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
stub_class :owner
|
18
|
+
stub_class(:dummy, String)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:owner) { Owner.new }
|
22
|
+
|
23
|
+
it { expect(build_type_definition(type: String)).to have_collection_type(String) }
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Granite::Form::Model::Attributes::Reflections::Dictionary::BuildTypeDefinition do
|
6
|
+
def build_type_definition(name = :name, **options)
|
7
|
+
@reflection = Granite::Form::Model::Attributes::Reflections::Dictionary.new(name, options)
|
8
|
+
described_class.new(owner, @reflection).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def have_dictionary_type(type)
|
12
|
+
subtype_definition = have_attributes(type: type, reflection: @reflection, owner: owner)
|
13
|
+
have_attributes(subtype_definition: subtype_definition)
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
stub_class :owner
|
18
|
+
stub_class(:dummy, String)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:owner) { Owner.new }
|
22
|
+
|
23
|
+
it { expect(build_type_definition(type: String)).to have_dictionary_type(String) }
|
24
|
+
end
|
@@ -34,10 +34,4 @@ describe Granite::Form::Model::Attributes::Reflections::Dictionary do
|
|
34
34
|
expect(Target).to be_method_defined(:field_alias_values)
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
38
|
-
describe '#keys' do
|
39
|
-
specify { expect(reflection.keys).to eq([]) }
|
40
|
-
specify { expect(reflection(keys: ['a', :b]).keys).to eq(%w[a b]) }
|
41
|
-
specify { expect(reflection(keys: :c).keys).to eq(%w[c]) }
|
42
|
-
end
|
43
37
|
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Granite::Form::Model::Attributes::Reflections::Represents::BuildTypeDefinition do
|
6
|
+
def build_type_definition(name = :name, **options)
|
7
|
+
@reflection = Granite::Form::Model::Attributes::Reflections::Represents.new(name, options.reverse_merge(of: :author))
|
8
|
+
described_class.new(owner, @reflection).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def have_type(type)
|
12
|
+
have_attributes(type: type, reflection: @reflection, owner: owner)
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:owner) { Owner.new }
|
16
|
+
|
17
|
+
before do
|
18
|
+
stub_model :author
|
19
|
+
stub_model(:owner) do
|
20
|
+
def author
|
21
|
+
@author ||= Author.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it { expect(build_type_definition).to have_type(Object) }
|
27
|
+
it { expect(build_type_definition(type: String)).to have_type(String) }
|
28
|
+
|
29
|
+
context 'when defined in attribute' do
|
30
|
+
before { Author.attribute :name, String }
|
31
|
+
|
32
|
+
it { expect(build_type_definition).to have_type(String) }
|
33
|
+
it { expect(build_type_definition(type: Integer)).to have_type(Integer) }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when defined in represented attribute' do
|
37
|
+
before do
|
38
|
+
stub_model(:real_author) do
|
39
|
+
attribute :name, Boolean
|
40
|
+
end
|
41
|
+
Author.class_eval do
|
42
|
+
include Granite::Form::Model::Representation
|
43
|
+
represents :name, of: :subject
|
44
|
+
|
45
|
+
def subject
|
46
|
+
@subject ||= RealAuthor.new
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it { expect(build_type_definition).to have_type(Boolean) }
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when defined in references_many' do
|
55
|
+
before do
|
56
|
+
stub_class(:user, ActiveRecord::Base)
|
57
|
+
Author.class_eval do
|
58
|
+
include Granite::Form::Model::Associations
|
59
|
+
references_many :users
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it do
|
64
|
+
attribute = build_type_definition(:user_ids)
|
65
|
+
expect(attribute).to be_a(Granite::Form::Types::Collection)
|
66
|
+
expect(attribute.subtype_definition).to have_type(Integer)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when defined in collection' do
|
71
|
+
before do
|
72
|
+
Author.collection :users, String
|
73
|
+
end
|
74
|
+
|
75
|
+
it do
|
76
|
+
attribute = build_type_definition(:users)
|
77
|
+
expect(attribute).to be_a(Granite::Form::Types::Collection)
|
78
|
+
expect(attribute.subtype_definition).to have_type(String)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when defined in dictionary' do
|
83
|
+
before do
|
84
|
+
Author.dictionary :numbers, Float
|
85
|
+
end
|
86
|
+
|
87
|
+
it do
|
88
|
+
attribute = build_type_definition(:numbers)
|
89
|
+
expect(attribute).to be_a(Granite::Form::Types::Dictionary)
|
90
|
+
expect(attribute.subtype_definition).to have_type(Float)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when defined in ActiveRecord::Base' do
|
95
|
+
before do
|
96
|
+
stub_class(:author, ActiveRecord::Base) do
|
97
|
+
alias_attribute :full_name, :name
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it { expect(build_type_definition).to have_type(String) }
|
102
|
+
it { expect(build_type_definition(:status)).to have_type(Integer) }
|
103
|
+
it { expect(build_type_definition(:full_name)).to have_type(String) }
|
104
|
+
it { expect(build_type_definition(:unknown_attribute)).to have_type(Object) }
|
105
|
+
it do
|
106
|
+
attribute = build_type_definition(:related_ids)
|
107
|
+
expect(attribute).to be_a(Granite::Form::Types::Collection)
|
108
|
+
expect(attribute.subtype_definition).to have_type(Integer)
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'with enum' do
|
112
|
+
before do
|
113
|
+
if ActiveRecord.gem_version >= Gem::Version.new('7.0')
|
114
|
+
Author.enum :status, once: 1, many: 2
|
115
|
+
else
|
116
|
+
Author.enum status: %i[once many]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it { expect(build_type_definition(:status)).to have_type(String) }
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'with serialized attribute' do
|
124
|
+
before { Author.serialize :data }
|
125
|
+
|
126
|
+
it { expect(build_type_definition(:data)).to have_type(Object) }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|