praxis 2.0.pre.2 → 2.0.pre.3
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 +5 -5
- data/CHANGELOG.md +6 -0
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +27 -31
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +35 -39
- data/lib/praxis/mapper/active_model_compat.rb +38 -3
- data/lib/praxis/mapper/resource.rb +3 -3
- data/lib/praxis/mapper/selector_generator.rb +98 -75
- data/lib/praxis/mapper/sequel_compat.rb +42 -3
- data/lib/praxis/plugins/mapper_plugin.rb +16 -2
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +3 -0
- data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +106 -0
- data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +147 -0
- data/spec/praxis/extensions/field_selection/support/spec_resources_active_model.rb +130 -0
- data/spec/praxis/extensions/field_selection/support/spec_resources_sequel.rb +106 -0
- data/spec/praxis/mapper/selector_generator_spec.rb +275 -283
- data/spec/spec_helper.rb +11 -0
- data/spec/support/be_deep_equal_matcher.rb +39 -0
- data/spec/support/spec_resources.rb +42 -49
- metadata +37 -4
- data/spec/spec_app/app/models/person.rb +0 -3
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
|
3
|
+
require 'praxis/mapper/sequel_compat'
|
4
|
+
|
5
|
+
|
6
|
+
# Creates a new in-memory DB, and the necessary tables (and mini-seeds) for the sequel models in this file
|
7
|
+
def create_and_seed_tables
|
8
|
+
sequeldb = Sequel.sqlite
|
9
|
+
# sequeldb.loggers = [Logger.new($stdout)] # Uncomment to see sequel logs
|
10
|
+
|
11
|
+
sequeldb.create_table! :sequel_simple_models do
|
12
|
+
primary_key :id
|
13
|
+
String :simple_name
|
14
|
+
Integer :parent_id
|
15
|
+
String :parent_uuid
|
16
|
+
Integer :other_model_id
|
17
|
+
String :added_column
|
18
|
+
end
|
19
|
+
sequeldb.create_table! :sequel_other_models do
|
20
|
+
primary_key :id
|
21
|
+
end
|
22
|
+
sequeldb.create_table! :sequel_parent_models do
|
23
|
+
primary_key :id
|
24
|
+
String :uuid
|
25
|
+
end
|
26
|
+
sequeldb.create_table! :sequel_tag_models do
|
27
|
+
primary_key :id
|
28
|
+
String :tag_name
|
29
|
+
end
|
30
|
+
sequeldb.create_table! :sequel_simple_models_sequel_tag_models do
|
31
|
+
Integer :sequel_simple_model_id
|
32
|
+
Integer :tag_id
|
33
|
+
end
|
34
|
+
|
35
|
+
sequeldb[:sequel_parent_models] << { id: 1 , uuid: 'deadbeef1'}
|
36
|
+
sequeldb[:sequel_parent_models] << { id: 2 , uuid: 'deadbeef2'}
|
37
|
+
|
38
|
+
sequeldb[:sequel_other_models] << { id: 11 }
|
39
|
+
sequeldb[:sequel_other_models] << { id: 22 }
|
40
|
+
|
41
|
+
sequeldb[:sequel_tag_models] << { id: 1 , tag_name: 'blue' }
|
42
|
+
sequeldb[:sequel_tag_models] << { id: 2 , tag_name: 'red' }
|
43
|
+
|
44
|
+
# Simple model 1 is tagged as blue and red
|
45
|
+
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 1, tag_id: 1 }
|
46
|
+
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 1, tag_id: 2 }
|
47
|
+
# Simple model 2 is tagged as red
|
48
|
+
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 2, tag_id: 2 }
|
49
|
+
|
50
|
+
# It's weird to have a parent id and parent uuid (which points to different actual parents)
|
51
|
+
# But it allows us to check pointing to both PKs and not PK columns
|
52
|
+
sequeldb[:sequel_simple_models] << { id: 1 , simple_name: 'Simple1', parent_id: 1, other_model_id: 11, parent_uuid: 'deadbeef1'}
|
53
|
+
sequeldb[:sequel_simple_models] << { id: 2 , simple_name: 'Simple2', parent_id: 2, other_model_id: 22, parent_uuid: 'deadbeef1'}
|
54
|
+
end
|
55
|
+
|
56
|
+
create_and_seed_tables
|
57
|
+
|
58
|
+
class SequelSimpleModel < Sequel::Model
|
59
|
+
include Praxis::Mapper::SequelCompat
|
60
|
+
|
61
|
+
many_to_one :parent, class: 'SequelParentModel'
|
62
|
+
many_to_one :other_model, class: 'SequelOtherModel'
|
63
|
+
many_to_many :tags, class: 'SequelTagModel'
|
64
|
+
end
|
65
|
+
|
66
|
+
class SequelOtherModel < Sequel::Model
|
67
|
+
include Praxis::Mapper::SequelCompat
|
68
|
+
end
|
69
|
+
|
70
|
+
class SequelParentModel < Sequel::Model
|
71
|
+
include Praxis::Mapper::SequelCompat
|
72
|
+
one_to_many :children, class: 'SequelSimpleModel', primary_key: :uuid, key: :parent_uuid
|
73
|
+
end
|
74
|
+
|
75
|
+
class SequelTagModel < Sequel::Model
|
76
|
+
include Praxis::Mapper::SequelCompat
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# A set of resource classes for use in specs
|
81
|
+
class SequelBaseResource < Praxis::Mapper::Resource
|
82
|
+
end
|
83
|
+
|
84
|
+
class SequelOtherResource < SequelBaseResource
|
85
|
+
model SequelOtherModel
|
86
|
+
|
87
|
+
property :display_name, dependencies: [:name]
|
88
|
+
end
|
89
|
+
|
90
|
+
class SequelParentResource < SequelBaseResource
|
91
|
+
model SequelParentModel
|
92
|
+
end
|
93
|
+
|
94
|
+
class SequelTagResource < SequelBaseResource
|
95
|
+
model SequelTagModel
|
96
|
+
end
|
97
|
+
|
98
|
+
class SequelSimpleResource < SequelBaseResource
|
99
|
+
model SequelSimpleModel
|
100
|
+
|
101
|
+
# Forces to add an extra column (added_column)...and yet another (parent_id) that will serve
|
102
|
+
# to check that if that's already automatically added due to an association, it won't interfere or duplicate
|
103
|
+
property :parent, dependencies: [:parent, :added_column, :parent_id]
|
104
|
+
|
105
|
+
property :name, dependencies: [:simple_name]
|
106
|
+
end
|
@@ -1,301 +1,293 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
# describe Praxis::Mapper::SelectorGenerator do
|
4
|
-
# let(:properties) { {} }
|
5
|
-
# let(:resource) { BlogResource }
|
6
|
-
# subject(:generator) {Praxis::Mapper::SelectorGenerator.new }
|
7
3
|
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
describe Praxis::Mapper::SelectorGenerator do
|
5
|
+
let(:resource) { SimpleResource }
|
6
|
+
subject(:generator) {described_class.new }
|
11
7
|
|
12
|
-
#
|
8
|
+
context '#add' do
|
9
|
+
let(:resource) { SimpleResource }
|
10
|
+
shared_examples 'a proper selector' do
|
11
|
+
it { expect(generator.add(resource, fields).dump).to be_deep_equal selectors }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'basic combos' do
|
15
|
+
context 'direct column fields' do
|
16
|
+
let(:fields) { {id: true, foobar: true} }
|
17
|
+
let(:selectors) do
|
18
|
+
{
|
19
|
+
model: SimpleModel,
|
20
|
+
columns: [:id, :foobar]
|
21
|
+
}
|
22
|
+
end
|
23
|
+
it_behaves_like 'a proper selector'
|
24
|
+
end
|
13
25
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
26
|
+
context 'aliased column fields' do
|
27
|
+
let(:fields) { {id: true, name: true} }
|
28
|
+
let(:selectors) do
|
29
|
+
{
|
30
|
+
model: SimpleModel,
|
31
|
+
columns: [:id, :simple_name]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
it_behaves_like 'a proper selector'
|
35
|
+
end
|
24
36
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
37
|
+
context 'pure associations without recursion' do
|
38
|
+
let(:fields) { {other_model: true} }
|
39
|
+
let(:selectors) do
|
40
|
+
{
|
41
|
+
model: SimpleModel,
|
42
|
+
columns: [:other_model_id], # FK of the other_model association
|
43
|
+
tracks: {
|
44
|
+
other_model: {
|
45
|
+
columns: [:id], # joining key for the association
|
46
|
+
model: OtherModel
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
it_behaves_like 'a proper selector'
|
52
|
+
end
|
29
53
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
54
|
+
context 'aliased associations without recursion' do
|
55
|
+
let(:fields) { {other_resource: true} }
|
56
|
+
let(:selectors) do
|
57
|
+
{
|
58
|
+
model: SimpleModel,
|
59
|
+
columns: [:other_model_id], # FK of the other_model association
|
60
|
+
tracks: {
|
61
|
+
other_model: {
|
62
|
+
columns: [:id], # joining key for the association
|
63
|
+
model: OtherModel
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
end
|
68
|
+
it_behaves_like 'a proper selector'
|
69
|
+
end
|
70
|
+
context 'aliased associations without recursion (that map to columns and other associations)' do
|
71
|
+
let(:fields) { {aliased_method: true} }
|
72
|
+
let(:selectors) do
|
73
|
+
{
|
74
|
+
model: SimpleModel,
|
75
|
+
columns: [:column1, :other_model_id], # other_model_id => because of the association
|
76
|
+
tracks: {
|
77
|
+
other_model: {
|
78
|
+
columns: [:id], # joining key for the association
|
79
|
+
model: OtherModel
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
it_behaves_like 'a proper selector'
|
85
|
+
end
|
44
86
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
87
|
+
context 'redefined associations that add some extra columns (would need both the underlying association AND the columns in place)' do
|
88
|
+
let(:fields) { {parent: true} }
|
89
|
+
let(:selectors) do
|
90
|
+
{
|
91
|
+
model: SimpleModel,
|
92
|
+
columns: [:parent_id, :added_column],
|
93
|
+
tracks: {
|
94
|
+
parent: {
|
95
|
+
columns: [:id],
|
96
|
+
model: ParentModel
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
end
|
101
|
+
it_behaves_like 'a proper selector'
|
102
|
+
end
|
58
103
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# select: Set.new([]),
|
70
|
-
# track: Set.new([:comments])
|
71
|
-
# }
|
72
|
-
# }
|
73
|
-
# end
|
74
|
-
# it 'generates the correct set of selectors' do
|
75
|
-
# generator.selectors.should eq expected_selectors
|
76
|
-
# end
|
77
|
-
# end
|
104
|
+
context 'a simple property that requires all fields' do
|
105
|
+
let(:fields) { {everything: true} }
|
106
|
+
let(:selectors) do
|
107
|
+
{
|
108
|
+
model: SimpleModel,
|
109
|
+
columns: [:*],
|
110
|
+
}
|
111
|
+
end
|
112
|
+
it_behaves_like 'a proper selector'
|
113
|
+
end
|
78
114
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
#
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
# select: Set.new([]),
|
90
|
-
# track: Set.new([:other_commented_posts])
|
91
|
-
# }
|
92
|
-
# }
|
93
|
-
# end
|
94
|
-
# it 'generates the correct set of selectors' do
|
95
|
-
# generator.selectors.should eq expected_selectors
|
96
|
-
# end
|
97
|
-
# end
|
115
|
+
context 'a simple property that requires itself' do
|
116
|
+
let(:fields) { {circular_dep: true} }
|
117
|
+
let(:selectors) do
|
118
|
+
{
|
119
|
+
model: SimpleModel,
|
120
|
+
columns: [:circular_dep, :column1], #allows to "expand" the dependency into itself + others
|
121
|
+
}
|
122
|
+
end
|
123
|
+
it_behaves_like 'a proper selector'
|
124
|
+
end
|
98
125
|
|
126
|
+
context 'a simple property without dependencies' do
|
127
|
+
let(:fields) { {no_deps: true} }
|
128
|
+
let(:selectors) do
|
129
|
+
{
|
130
|
+
model: SimpleModel
|
131
|
+
}
|
132
|
+
end
|
133
|
+
it_behaves_like 'a proper selector'
|
134
|
+
end
|
99
135
|
|
100
|
-
|
101
|
-
# let(:properties) { {composite_model: {id: true, type: true} } }
|
102
|
-
# let(:resource) { OtherResource }
|
103
|
-
# let(:expected_selectors) do
|
104
|
-
# {
|
105
|
-
# OtherModel => {
|
106
|
-
# select: Set.new([:composite_id,:composite_type]),
|
107
|
-
# track: Set.new([:composite_model])
|
108
|
-
# },
|
109
|
-
# CompositeIdModel => {
|
110
|
-
# select: Set.new([:id,:type]),
|
111
|
-
# track: Set.new
|
112
|
-
# }
|
113
|
-
# }
|
114
|
-
# end
|
115
|
-
# it 'generates the correct set of selectors' do
|
116
|
-
# generator.selectors.should eq expected_selectors
|
117
|
-
# end
|
118
|
-
# end
|
119
|
-
# end
|
136
|
+
end
|
120
137
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
138
|
+
context 'nested tracking' do
|
139
|
+
context 'pure associations follow the nested fields' do
|
140
|
+
let(:fields) do
|
141
|
+
{
|
142
|
+
other_model: {
|
143
|
+
id: true
|
144
|
+
}
|
145
|
+
}
|
146
|
+
end
|
147
|
+
let(:selectors) do
|
148
|
+
{
|
149
|
+
model: SimpleModel,
|
150
|
+
columns: [:other_model_id],
|
151
|
+
tracks: {
|
152
|
+
other_model: {
|
153
|
+
model: OtherModel,
|
154
|
+
columns: [:id]
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
end
|
159
|
+
it_behaves_like 'a proper selector'
|
160
|
+
end
|
135
161
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
162
|
+
context 'Aliased resources disregard any nested fields...' do
|
163
|
+
let(:fields) do
|
164
|
+
{
|
165
|
+
other_resource: {
|
166
|
+
id: true
|
167
|
+
}
|
168
|
+
}
|
169
|
+
end
|
170
|
+
let(:selectors) do
|
171
|
+
{
|
172
|
+
model: SimpleModel,
|
173
|
+
columns: [:other_model_id],
|
174
|
+
tracks: {
|
175
|
+
other_model: {
|
176
|
+
model: OtherModel,
|
177
|
+
columns: [:id]
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
end
|
182
|
+
it_behaves_like 'a proper selector'
|
183
|
+
end
|
184
|
+
end
|
140
185
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
186
|
+
context 'string associations' do
|
187
|
+
context 'that specify a direct existing colum in the target dependency' do
|
188
|
+
let(:fields) { { direct_other_name: true } }
|
189
|
+
let(:selectors) do
|
190
|
+
{
|
191
|
+
model: SimpleModel,
|
192
|
+
columns: [:other_model_id],
|
193
|
+
tracks: {
|
194
|
+
other_model: {
|
195
|
+
model: OtherModel,
|
196
|
+
columns: [:id, :name]
|
197
|
+
}
|
198
|
+
}
|
199
|
+
}
|
200
|
+
end
|
201
|
+
it_behaves_like 'a proper selector'
|
202
|
+
end
|
155
203
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
# end
|
173
|
-
# end
|
204
|
+
context 'that specify an aliased property in the target dependency' do
|
205
|
+
let(:fields) { { aliased_other_name: true } }
|
206
|
+
let(:selectors) do
|
207
|
+
{
|
208
|
+
model: SimpleModel,
|
209
|
+
columns: [:other_model_id],
|
210
|
+
tracks: {
|
211
|
+
other_model: {
|
212
|
+
model: OtherModel,
|
213
|
+
columns: [:id, :name]
|
214
|
+
}
|
215
|
+
}
|
216
|
+
}
|
217
|
+
end
|
218
|
+
it_behaves_like 'a proper selector'
|
219
|
+
end
|
174
220
|
|
221
|
+
context 'for a property that requires all fields from an association' do
|
222
|
+
let(:fields) { {everything_from_parent: true} }
|
223
|
+
let(:selectors) do
|
224
|
+
{
|
225
|
+
model: SimpleModel,
|
226
|
+
columns: [:parent_id],
|
227
|
+
tracks: {
|
228
|
+
parent: {
|
229
|
+
model: ParentModel,
|
230
|
+
columns: [:*]
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
end
|
235
|
+
it_behaves_like 'a proper selector'
|
236
|
+
end
|
237
|
+
end
|
175
238
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
239
|
+
context 'required extra select fields due to associations' do
|
240
|
+
context 'many_to_one' do
|
241
|
+
let(:fields) { {other_model: true} }
|
242
|
+
let(:selectors) do
|
243
|
+
{
|
244
|
+
model: SimpleModel,
|
245
|
+
columns: [:other_model_id], # FK of the other_model association
|
246
|
+
tracks: {
|
247
|
+
other_model: {
|
248
|
+
columns: [:id],
|
249
|
+
model: OtherModel
|
250
|
+
}
|
251
|
+
}
|
252
|
+
}
|
253
|
+
end
|
254
|
+
it_behaves_like 'a proper selector'
|
255
|
+
end
|
256
|
+
context 'one_to_many' do
|
257
|
+
let(:resource) { ParentResource }
|
258
|
+
let(:fields) { {simple_children: true} }
|
259
|
+
let(:selectors) do
|
260
|
+
{
|
261
|
+
model: ParentModel,
|
262
|
+
columns: [:id], # No FKs in the source model for one_to_many
|
263
|
+
tracks: {
|
264
|
+
simple_children: {
|
265
|
+
columns: [:parent_id],
|
266
|
+
model: SimpleModel
|
267
|
+
}
|
268
|
+
}
|
269
|
+
}
|
270
|
+
end
|
271
|
+
it_behaves_like 'a proper selector'
|
272
|
+
end
|
273
|
+
context 'many_to_many' do
|
274
|
+
let(:resource) { OtherResource }
|
275
|
+
let(:fields) { {simple_models: true} }
|
276
|
+
let(:selectors) do
|
277
|
+
{
|
278
|
+
model: OtherModel,
|
279
|
+
columns: [:id], #join key in the source model for many_to_many (where the middle table points to)
|
280
|
+
tracks: {
|
281
|
+
simple_models: {
|
282
|
+
columns: [:id], #join key in the target model for many_to_many (where the middle table points to)
|
283
|
+
model: SimpleModel
|
284
|
+
}
|
285
|
+
}
|
286
|
+
}
|
287
|
+
end
|
288
|
+
it_behaves_like 'a proper selector'
|
289
|
+
end
|
194
290
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
# let(:expected_selectors) do
|
199
|
-
# {
|
200
|
-
# PostModel => {
|
201
|
-
# select: Set.new([:author_id, :created_at]),
|
202
|
-
# track: Set.new([:author])
|
203
|
-
# },
|
204
|
-
# UserModel => {
|
205
|
-
# select: Set.new([:first_name, :last_name]),
|
206
|
-
# track: Set.new([:posts])
|
207
|
-
# }
|
208
|
-
# }
|
209
|
-
# end
|
210
|
-
# it 'generates the correct set of selectors' do
|
211
|
-
# generator.selectors.should eq expected_selectors
|
212
|
-
# end
|
213
|
-
# end
|
214
|
-
|
215
|
-
# context 'with a property with a circular definition (ie, includes its own field)' do
|
216
|
-
# let(:resource) { PostResource }
|
217
|
-
|
218
|
-
# let(:properties) { {id: true, slug: true} }
|
219
|
-
# let(:expected_selectors) do
|
220
|
-
# {
|
221
|
-
# PostModel => {
|
222
|
-
# select: Set.new([:id, :slug, :title]),
|
223
|
-
# track: Set.new
|
224
|
-
# }
|
225
|
-
# }
|
226
|
-
# end
|
227
|
-
# it 'generates the correct set of selectors' do
|
228
|
-
# generator.selectors.should eq expected_selectors
|
229
|
-
# end
|
230
|
-
# end
|
231
|
-
|
232
|
-
# context 'with a property without the :through option' do
|
233
|
-
# let(:resource) { UserResource }
|
234
|
-
# let(:properties) { {blogs_summary: {size: true}} }
|
235
|
-
# let(:expected_selectors) do
|
236
|
-
# {
|
237
|
-
# BlogModel => {
|
238
|
-
# select: Set.new([:owner_id]),
|
239
|
-
# track: Set.new()
|
240
|
-
# },
|
241
|
-
# UserModel => {
|
242
|
-
# select: Set.new([:id]),
|
243
|
-
# track: Set.new([:blogs])
|
244
|
-
# }
|
245
|
-
# }
|
246
|
-
# end
|
247
|
-
# it 'ignores any subsequent fields when generating selectors' do
|
248
|
-
# generator.selectors.should eq expected_selectors
|
249
|
-
# end
|
250
|
-
# end
|
251
|
-
|
252
|
-
# context 'for a property with no dependencies' do
|
253
|
-
# let(:properties) { {id: true, kind: true} }
|
254
|
-
# let(:expected_selectors) do
|
255
|
-
# {
|
256
|
-
# BlogModel => {
|
257
|
-
# select: Set.new([:id]),
|
258
|
-
# track: Set.new()
|
259
|
-
# }
|
260
|
-
# }
|
261
|
-
# end
|
262
|
-
# it 'generates the correct set of selectors' do
|
263
|
-
# generator.selectors.should eq expected_selectors
|
264
|
-
# end
|
265
|
-
# end
|
266
|
-
|
267
|
-
# context 'with large set of properties' do
|
268
|
-
|
269
|
-
# let(:properties) do
|
270
|
-
# {
|
271
|
-
# display_name: true,
|
272
|
-
# owner: {
|
273
|
-
# id: true,
|
274
|
-
# full_name: true,
|
275
|
-
# blogs_summary: {href: true, size: true},
|
276
|
-
# main_blog: {id: true},
|
277
|
-
# },
|
278
|
-
# administrator: {id: true, full_name: true}
|
279
|
-
# }
|
280
|
-
# end
|
281
|
-
|
282
|
-
# let(:expected_selectors) do
|
283
|
-
# {
|
284
|
-
# BlogModel=> {
|
285
|
-
# select: Set.new([:id, :name, :owner_id, :administrator_id]),
|
286
|
-
# track: Set.new([:owner, :administrator])
|
287
|
-
# },
|
288
|
-
# UserModel=> {
|
289
|
-
# select: Set.new([:id, :first_name, :last_name, :main_blog_id]),
|
290
|
-
# track: Set.new([:blogs, :main_blog])
|
291
|
-
# }
|
292
|
-
# }
|
293
|
-
# end
|
294
|
-
|
295
|
-
# it 'generates the correct set of selectors' do
|
296
|
-
# generator.selectors.should eq(expected_selectors)
|
297
|
-
# end
|
298
|
-
|
299
|
-
# end
|
300
|
-
|
301
|
-
# end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|