lucid_works 0.5.3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -20
- data/lib/lucid_works/associations/has_many.rb +70 -0
- data/lib/lucid_works/associations/has_one.rb +38 -0
- data/lib/lucid_works/associations/proxy.rb +51 -0
- data/lib/lucid_works/associations.rb +71 -52
- data/lib/lucid_works/base.rb +53 -7
- data/lib/lucid_works/collection.rb +1 -1
- data/lib/lucid_works/datasource.rb +6 -5
- data/lib/lucid_works/patch_restclient.rb +2 -2
- data/lib/lucid_works/patch_time.rb +1 -1
- data/lib/lucid_works/version.rb +1 -1
- data/lib/lucid_works.rb +3 -0
- data/spec/lib/lucid_works/associations/has_many_spec.rb +167 -0
- data/spec/lib/lucid_works/associations/has_one_spec.rb +177 -0
- data/spec/lib/lucid_works/associations_spec.rb +68 -88
- data/spec/lib/lucid_works/base_spec.rb +32 -13
- data/spec/lib/lucid_works/collection_spec.rb +1 -1
- data/spec/lib/lucid_works/datasource_spec.rb +4 -4
- data/spec/lib/lucid_works/server_spec.rb +6 -3
- metadata +9 -2
data/README.rdoc
CHANGED
@@ -227,23 +227,6 @@ Then
|
|
227
227
|
|
228
228
|
thing.build_whatnot -> an unsaved Whatnot
|
229
229
|
|
230
|
-
==== Has_singleton associations
|
231
|
-
|
232
|
-
The has_singleton association is used to associate a resource with another intransient singleton resource, i.e. one that always exists and calling destroy does not remove it.
|
233
|
-
|
234
|
-
class Thing < LucidWorks::Base
|
235
|
-
has_one :whatnot
|
236
|
-
end
|
237
|
-
|
238
|
-
class Whatnot < LucidWorks::Base
|
239
|
-
self.singleton = true
|
240
|
-
belongs_to :thing
|
241
|
-
end
|
242
|
-
|
243
|
-
Then
|
244
|
-
|
245
|
-
thing.whatnot -> an unsaved Whatnot
|
246
|
-
|
247
230
|
=== Belongs_to associations
|
248
231
|
|
249
232
|
Te belongs to association augments the model with methods to access its parent. Given:
|
@@ -257,6 +240,8 @@ Then:
|
|
257
240
|
|
258
241
|
whatnot.thing -> A Thing
|
259
242
|
|
243
|
+
For more information on association see LucidWorks::Associations::ClassMethods
|
244
|
+
|
260
245
|
=== Schema
|
261
246
|
|
262
247
|
A class may have a schema defined as follows:
|
@@ -267,11 +252,11 @@ A class may have a schema defined as follows:
|
|
267
252
|
attribute :bool1, :boolean
|
268
253
|
attribute :integer1, :integer
|
269
254
|
attributes :string2, :string3, :string4
|
270
|
-
attributes :bool2,
|
271
|
-
attributes :int2,
|
255
|
+
attributes :bool2, :bool3, :type => :boolean
|
256
|
+
attributes :int2, :int3, :type => :integer
|
272
257
|
attribute :string_with_values, :values => ['one', 'two']
|
273
258
|
attribute :dontsendme, :omit_during_update => true
|
274
|
-
attribute :sendnull,
|
259
|
+
attribute :sendnull, :string, :nil_when_blank => true
|
275
260
|
end
|
276
261
|
end
|
277
262
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module LucidWorks
|
2
|
+
module Associations
|
3
|
+
class HasMany < Proxy #:nodoc:
|
4
|
+
|
5
|
+
def build(attributes={})
|
6
|
+
@target_class.new(attributes.merge({:parent => @owner}))
|
7
|
+
# Don't cache it - it's only a single target
|
8
|
+
end
|
9
|
+
|
10
|
+
def create(attributes={})
|
11
|
+
target = build(attributes)
|
12
|
+
target.save
|
13
|
+
target
|
14
|
+
end
|
15
|
+
|
16
|
+
def create!(attributes={})
|
17
|
+
target = build(attributes)
|
18
|
+
if target.save
|
19
|
+
target
|
20
|
+
else
|
21
|
+
raise target.errors.full_messages
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def remember_find_options(options)
|
26
|
+
@find_options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
# Explicit find call does not use the remembered options, or cache the result
|
30
|
+
def find(id_or_find_type, options={})
|
31
|
+
@target_class.send(:find, id_or_find_type, options.merge(:parent => @owner))
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Caching rules
|
37
|
+
# It's easy to cache a has_one resource as we never search for different things.
|
38
|
+
# With a has_many the user can either use .others and get the entire collection
|
39
|
+
# or .others.find(id) and get just one. What do we cache?
|
40
|
+
#
|
41
|
+
# Interestingly for us the cost difference is marginal between the two forms of
|
42
|
+
# the call. Should we just grab all of them and return the one they want?
|
43
|
+
# Probably not. Not every elegant and there is some cost to creating models
|
44
|
+
# on our end.
|
45
|
+
#
|
46
|
+
# Okay for now we will just not cache .find()
|
47
|
+
#
|
48
|
+
# The largest challenge is this sequence:
|
49
|
+
#
|
50
|
+
# a = others.find(1) #
|
51
|
+
# others.find(1).name
|
52
|
+
# b = others.first # requires retrieving all
|
53
|
+
|
54
|
+
|
55
|
+
def load_target(options={})
|
56
|
+
if @target.nil? || options[:force]
|
57
|
+
if @options[:has_content] === false
|
58
|
+
return true # make method_missing happy so it will operate on NilClass
|
59
|
+
else
|
60
|
+
opts = (@find_options || {}).merge(:parent => @owner)
|
61
|
+
@target = @target_class.send(:find, :all, opts)
|
62
|
+
@find_options = {}
|
63
|
+
end
|
64
|
+
else
|
65
|
+
end
|
66
|
+
@target
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module LucidWorks
|
2
|
+
module Associations
|
3
|
+
class HasOne < Proxy #:nodoc:
|
4
|
+
|
5
|
+
def build(attributes={})
|
6
|
+
@target = @target_class.new(attributes.merge({:parent => @owner}))
|
7
|
+
end
|
8
|
+
|
9
|
+
def create(attributes={})
|
10
|
+
build(attributes)
|
11
|
+
@target.save
|
12
|
+
@target
|
13
|
+
end
|
14
|
+
|
15
|
+
def create!(attributes={})
|
16
|
+
build(attributes)
|
17
|
+
if @target.save
|
18
|
+
@target
|
19
|
+
else
|
20
|
+
raise @target.errors.full_messages
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def load_target(options={})
|
27
|
+
if @target.nil? || options[:force]
|
28
|
+
if @options[:has_content] === false
|
29
|
+
return true # make method_missing happy so it will operate on NilClass
|
30
|
+
else
|
31
|
+
@target = @target_class.send(:find, :singleton, :parent => @owner)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
@target
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module LucidWorks
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
# This is the root class of our association proxies:
|
5
|
+
#
|
6
|
+
# Associations
|
7
|
+
# Proxy
|
8
|
+
# HasOne
|
9
|
+
# HasMany
|
10
|
+
|
11
|
+
class Proxy #:nodoc:
|
12
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|caller|^object_id$)/ }
|
13
|
+
|
14
|
+
def initialize(owner, target_class, options={})
|
15
|
+
@owner, @target_class, @options = owner, target_class, options
|
16
|
+
@target = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sets the target of this proxy to <tt>\target</tt>.
|
20
|
+
def target=(target)
|
21
|
+
@target = target
|
22
|
+
end
|
23
|
+
|
24
|
+
def loaded?
|
25
|
+
!!@target
|
26
|
+
end
|
27
|
+
|
28
|
+
# Can targets be retrieved for all owners if this type, in one step using owner/all/target
|
29
|
+
def supports_all?
|
30
|
+
@options[:supports_all]
|
31
|
+
end
|
32
|
+
|
33
|
+
def reload!
|
34
|
+
load_target(:force => true)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Forwards any missing method call to the \target.
|
40
|
+
def method_missing(method, *args, &block)
|
41
|
+
if load_target
|
42
|
+
if @target.respond_to?(method)
|
43
|
+
@target.send(method, *args, &block)
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,37 +1,58 @@
|
|
1
1
|
module LucidWorks
|
2
2
|
|
3
|
+
#
|
4
|
+
# See LucidWorks::Associations::ClassMethods
|
5
|
+
#
|
3
6
|
module Associations
|
4
7
|
extend ActiveSupport::Concern
|
5
8
|
|
6
9
|
module ClassMethods
|
7
10
|
|
11
|
+
def associations #:nodoc:
|
12
|
+
@associations ||= {}
|
13
|
+
end
|
14
|
+
|
8
15
|
# Specifies a singleton child resource.
|
9
16
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
+
# has_one :resource, <options>
|
18
|
+
#
|
19
|
+
# In the parent resource, creates methods:
|
20
|
+
#
|
21
|
+
# .resource
|
22
|
+
# .resource!
|
23
|
+
# .resource.build(attributes={})
|
24
|
+
# .resource.create(attributes={})
|
25
|
+
# .resource.create!(attributes={})
|
26
|
+
# .build_resource(attributes={})
|
27
|
+
# .create_resource(attributes={})
|
28
|
+
#
|
29
|
+
# _.resource_ will not actually load the resource until used i.e. resource._anything_ is called.
|
30
|
+
# After being loaded, the child is cached. Use _.resource!_ or _resource.reload!_ to relaod it.
|
31
|
+
#
|
32
|
+
# _.resource!_ will load the resource immediately, or reload it if it was already loaded.
|
33
|
+
#
|
34
|
+
# _.build_ creates a new model but does not save it. Parent is preset to the calling class.
|
35
|
+
#
|
36
|
+
# _.create_ builds the model, saves it, then returns it.
|
37
|
+
# You need to check persisted? and errors to see if the save succeeded.
|
38
|
+
#
|
39
|
+
# _.build_resource_ and _.create_resource_ are aliases for _.resource.build_ and _.resource.create_ respectively.
|
40
|
+
#
|
17
41
|
# === Options
|
18
42
|
#
|
19
43
|
# The declaration can also include an options hash to specialize the behavior of the association.
|
20
44
|
#
|
21
45
|
# Options are:
|
22
|
-
# [:class_name]
|
23
|
-
# Specify the class name of the association. Use it
|
46
|
+
# [:class_name => "name"]
|
47
|
+
# Specify the class name of the association. Use it if you want to us a child class name different
|
24
48
|
# from the association name, e.g.
|
25
|
-
# has_one :
|
26
|
-
# has_one :foo, :class_name => :'
|
27
|
-
# [:has_content]
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
|
32
|
-
# will instead build and return new, unsaved, model. This is useful for pseudo-resources that only
|
33
|
-
# provide actions, not data.
|
34
|
-
#
|
49
|
+
# has_one :foo # Use class Foo
|
50
|
+
# has_one :foo, :class_name => :'things/foo_bar' # use class Things::FooBar
|
51
|
+
# [:has_content => false]
|
52
|
+
# If set to false, indicated that this resource may not be retrieved using a GET,
|
53
|
+
# and will cause the _.resource_ method to return nil until the resource is built or created.
|
54
|
+
# This is useful for pseudo-resources that only provide actions, not data.
|
55
|
+
|
35
56
|
def has_one(*arguments)
|
36
57
|
options = arguments.last.is_a?(Hash) ? arguments.pop : {}
|
37
58
|
arguments.each do |resource|
|
@@ -39,7 +60,7 @@ module LucidWorks
|
|
39
60
|
end
|
40
61
|
end
|
41
62
|
|
42
|
-
# Specifies a child resource.
|
63
|
+
# Specifies a collection child resource.
|
43
64
|
#
|
44
65
|
# e.g. for Blog has_many posts
|
45
66
|
#
|
@@ -86,57 +107,55 @@ module LucidWorks
|
|
86
107
|
|
87
108
|
private
|
88
109
|
|
89
|
-
def define_has_one(resource, options={})
|
90
|
-
resource_class_name = (options
|
110
|
+
def define_has_one(resource, options={}) #:nodoc:
|
111
|
+
resource_class_name = (options.delete(:class_name) || resource).to_s.camelize
|
112
|
+
associations[resource.to_sym] = {:type => :has_one, :class_name => "#{resource_class_name}"}.merge(options)
|
91
113
|
|
92
114
|
class_eval <<-EOF, __FILE__, __LINE__ + 1
|
93
|
-
def #{resource}
|
94
|
-
@#{resource}
|
95
|
-
end
|
96
|
-
EOF
|
115
|
+
def #{resource}
|
116
|
+
@#{resource}_association ||= HasOne.new(self, #{resource_class_name}, #{options.to_s})
|
117
|
+
end
|
97
118
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
def build_#{resource}(options = {})
|
111
|
-
#{resource_class_name}.new(options.merge :parent => self)
|
112
|
-
end
|
113
|
-
EOF
|
114
|
-
end
|
119
|
+
def #{resource}!
|
120
|
+
#{resource}.reload!
|
121
|
+
end
|
122
|
+
|
123
|
+
def build_#{resource}(options = {})
|
124
|
+
#{resource}.build(options)
|
125
|
+
end
|
126
|
+
|
127
|
+
def create_#{resource}(options = {})
|
128
|
+
#{resource}.create(options)
|
129
|
+
end
|
130
|
+
EOF
|
115
131
|
end
|
116
132
|
|
117
|
-
def define_has_many(resources, options
|
133
|
+
def define_has_many(resources, options={}) #:nodoc:
|
118
134
|
resource = resources.to_s.singularize
|
119
|
-
resource_class_name = (options
|
135
|
+
resource_class_name = (options.delete(:class_name) || resource).to_s.classify
|
136
|
+
associations[resource.to_sym] = {:type => :has_many, :class_name => "#{resource_class_name}"}.merge(options)
|
120
137
|
|
121
138
|
class_eval <<-EOF, __FILE__, __LINE__ + 1
|
122
139
|
def #{resources}(options={})
|
123
|
-
@#{resources}
|
140
|
+
@#{resources}_association ||= HasMany.new(self, #{resource_class_name}, #{options.to_s})
|
141
|
+
@#{resources}_association.remember_find_options(options) unless options.empty?
|
142
|
+
@#{resources}_association
|
124
143
|
end
|
125
144
|
|
126
145
|
def #{resources}!(options={})
|
127
|
-
|
146
|
+
#{resources}(options).reload!
|
128
147
|
end
|
129
148
|
|
130
|
-
def #{resource}(
|
131
|
-
#{
|
149
|
+
def build_#{resource}(options = {})
|
150
|
+
#{resources}.build(options)
|
132
151
|
end
|
133
152
|
|
134
153
|
def create_#{resource}(options = {})
|
135
|
-
#{
|
154
|
+
#{resources}.create(options)
|
136
155
|
end
|
137
156
|
|
138
|
-
def
|
139
|
-
#{
|
157
|
+
def #{resource}(id, options={})
|
158
|
+
#{resources}.find(id, options)
|
140
159
|
end
|
141
160
|
EOF
|
142
161
|
end
|
data/lib/lucid_works/base.rb
CHANGED
@@ -141,8 +141,8 @@ module LucidWorks
|
|
141
141
|
|
142
142
|
results =
|
143
143
|
if kind_of_find == :all
|
144
|
-
data.collect do |
|
145
|
-
new(
|
144
|
+
data.collect do |model_attributes|
|
145
|
+
new(model_attributes.merge(:parent => parent, :persisted => true))
|
146
146
|
end
|
147
147
|
else
|
148
148
|
attributes = data.is_a?(Hash) ? data : {}
|
@@ -154,11 +154,56 @@ module LucidWorks
|
|
154
154
|
end
|
155
155
|
|
156
156
|
# Process :include options
|
157
|
-
#
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
157
|
+
#
|
158
|
+
# In the section, to reduce confusion we will use the terms owner/target instead of
|
159
|
+
# parent/child to describe the association.
|
160
|
+
#
|
161
|
+
# If we are doing a find(:all) and this owner resource supports retrieval of all targets
|
162
|
+
# in one request with owners/all/targets, get them and attach them to the original models'
|
163
|
+
# association proxys.
|
164
|
+
#
|
165
|
+
results_array = [results].flatten # allow us to process a single result or array with the same code
|
166
|
+
if includes && !results_array.empty?
|
167
|
+
includes = [includes].flatten
|
168
|
+
includes.each do |association_name|
|
169
|
+
association_info = associations[association_name.to_s.singularize.to_sym]
|
170
|
+
target_class = class_eval(association_info[:class_name]) # get scoping right
|
171
|
+
target_name = association_info[:class_name].underscore
|
172
|
+
|
173
|
+
if kind_of_find == :all && association_info[:supports_all]
|
174
|
+
all_targets_path = "#{collection_url(parent)}/all/#{target_name}"
|
175
|
+
raw_response = ActiveSupport::Notifications.instrument("lucid_works.request") do |payload|
|
176
|
+
payload[:method] = :get
|
177
|
+
payload[:uri] = all_targets_path
|
178
|
+
payload[:response] = RestClient.get(all_targets_path)
|
179
|
+
end
|
180
|
+
if association_info[:type] == :has_one
|
181
|
+
all_targets_attributes = JSON.parse raw_response
|
182
|
+
all_targets_attributes.each do |target_attributes|
|
183
|
+
owner_id = target_attributes['id']
|
184
|
+
owner = results_array.detect { |result| result.id == owner_id }
|
185
|
+
if owner
|
186
|
+
target = target_class.new(target_attributes.merge(:parent => owner, :persisted => true))
|
187
|
+
association_proxy = owner.send(association_name)
|
188
|
+
association_proxy.target = target
|
189
|
+
end
|
190
|
+
end
|
191
|
+
elsif association_info[:type] == :has_many
|
192
|
+
# [{"history":[...history_models...],"id":372},{"history":[...history_models...],"id":371}]
|
193
|
+
JSON.parse(raw_response).each do |group_of_targets|
|
194
|
+
owner_id = group_of_targets['id']
|
195
|
+
owner = results_array.detect { |result| result.id == owner_id }
|
196
|
+
targets = group_of_targets[target_name].collect do |target_attrs|
|
197
|
+
target_class.new(target_attrs.merge(:parent => owner, :persisted => true))
|
198
|
+
end
|
199
|
+
association_proxy = owner.send(association_name)
|
200
|
+
association_proxy.target = targets
|
201
|
+
end
|
202
|
+
end
|
203
|
+
else # kind_of_find != :all || !supports_all
|
204
|
+
results_array.each do |result|
|
205
|
+
result.send("#{association_name}!")
|
206
|
+
end
|
162
207
|
end
|
163
208
|
end
|
164
209
|
end
|
@@ -249,6 +294,7 @@ module LucidWorks
|
|
249
294
|
def initialize(options)
|
250
295
|
raise ArgumentError.new("new requires a Hash") unless options.is_a?(Hash)
|
251
296
|
@parent = self.class.extract_parent_from_options(options)
|
297
|
+
@associations = {}
|
252
298
|
@persisted = options.delete(:persisted) || singleton? || false
|
253
299
|
@attributes = {}.with_indifferent_access
|
254
300
|
load_attributes(options)
|
@@ -2,8 +2,9 @@ module LucidWorks
|
|
2
2
|
|
3
3
|
class Datasource < Base
|
4
4
|
belongs_to :collection
|
5
|
-
has_many :histories, :class_name => :history
|
6
|
-
has_one :status, :
|
5
|
+
has_many :histories, :class_name => :history, :supports_all => true
|
6
|
+
has_one :status, :supports_all => true
|
7
|
+
has_one :schedule, :crawldata
|
7
8
|
has_one :index, :job, :has_content => false
|
8
9
|
|
9
10
|
schema do
|
@@ -62,7 +63,7 @@ module LucidWorks
|
|
62
63
|
|
63
64
|
|
64
65
|
def empty!
|
65
|
-
|
66
|
+
build_index.destroy
|
66
67
|
end
|
67
68
|
|
68
69
|
def editable?
|
@@ -81,11 +82,11 @@ module LucidWorks
|
|
81
82
|
end
|
82
83
|
|
83
84
|
def start_crawl!
|
84
|
-
|
85
|
+
build_job.save
|
85
86
|
end
|
86
87
|
|
87
88
|
def stop_crawl!
|
88
|
-
|
89
|
+
build_job.destroy
|
89
90
|
end
|
90
91
|
|
91
92
|
def t_type
|
data/lib/lucid_works/version.rb
CHANGED
data/lib/lucid_works.rb
CHANGED
@@ -23,6 +23,9 @@ require 'lucid_works/patch_time'
|
|
23
23
|
|
24
24
|
require 'lucid_works/exceptions'
|
25
25
|
require 'lucid_works/associations'
|
26
|
+
require 'lucid_works/associations/proxy'
|
27
|
+
require 'lucid_works/associations/has_one'
|
28
|
+
require 'lucid_works/associations/has_many'
|
26
29
|
require 'lucid_works/server'
|
27
30
|
require 'lucid_works/base'
|
28
31
|
require 'lucid_works/schema'
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LucidWorks::Associations::HasMany do
|
4
|
+
before :all do
|
5
|
+
@fake_server_uri = "http://12.0.0.1:99999"
|
6
|
+
@server = LucidWorks::Server.new(@fake_server_uri)
|
7
|
+
|
8
|
+
class ::Target < LucidWorks::Base
|
9
|
+
attr_accessor :foo
|
10
|
+
end
|
11
|
+
class ::Owner < LucidWorks::Base
|
12
|
+
has_many :targets
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before :each do
|
17
|
+
@owner = Owner.new(:parent => @server)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not load the targets if just referenced" do
|
21
|
+
Target.should_not_receive(:find)
|
22
|
+
@owner.targets
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should load the target with find(:parent => Owner) when target is accessed" do
|
26
|
+
Target.should_receive(:find).with(:all, :parent => @owner)
|
27
|
+
@owner.targets.first
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should load the target with find(:parent => Owner) and remembered options when target is accessed" do
|
31
|
+
Target.should_receive(:find).with(:all, :parent => @owner, :include => :foo)
|
32
|
+
@owner.targets(:include => :foo)
|
33
|
+
@owner.targets.first
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should cache the targets and not reload them on every access" do
|
37
|
+
mock_targets = [double('target1'), double('target2')]
|
38
|
+
Target.should_receive(:find).with(:all, :parent => @owner).once.and_return(mock_targets)
|
39
|
+
@owner.targets.first
|
40
|
+
@owner.targets.first
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should delegate methods to the target" do
|
44
|
+
mock_targets = [double('target1'), double('target2')]
|
45
|
+
Target.stub(:find) { mock_targets }
|
46
|
+
mock_targets.should_receive(:first)
|
47
|
+
@owner.targets.first
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#loaded?" do
|
51
|
+
it "should return true if the target has been loaded, false otherwise" do
|
52
|
+
mock_targets = [double('target1'), double('target2')]
|
53
|
+
Target.stub(:find) { mock_targets }
|
54
|
+
|
55
|
+
@owner.targets.loaded?.should be_false
|
56
|
+
@owner.targets.first
|
57
|
+
@owner.targets.loaded?.should be_true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#reload!" do
|
62
|
+
it "should force a reload of the target" do
|
63
|
+
mock_targets = [double('target1'), double('target2')]
|
64
|
+
Target.should_receive(:find).with(:all, :parent => @owner).twice.and_return(mock_targets)
|
65
|
+
@owner.targets.first
|
66
|
+
@owner.targets.reload!
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#find" do
|
71
|
+
it "should call Target.find with the provided options (not remembered options)" do
|
72
|
+
@owner.targets(:include => :foo)
|
73
|
+
Target.should_receive(:find).with(123, :parent => @owner)
|
74
|
+
@owner.targets.find(123)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should pass the find options to Target.find() when actually accessed" do
|
78
|
+
mock_target = double('target')
|
79
|
+
Target.should_receive(:find).with(123, :parent => @owner).and_return(mock_target)
|
80
|
+
@owner.targets.find(123).class
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#build" do
|
85
|
+
it "should new up a target and initialize it with the supplied attributes" do
|
86
|
+
target = @owner.targets.build(:foo => 'bar')
|
87
|
+
target.should_not be_persisted
|
88
|
+
target.foo.should == 'bar'
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should initialize the new target's parent" do
|
92
|
+
target = @owner.targets.build
|
93
|
+
target.parent.should == @owner
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#create" do
|
98
|
+
it "should new up a target and initialize it with the supplied attributes, then attempt to save it" do
|
99
|
+
mock_target = double('target')
|
100
|
+
Target.should_receive(:new).with(:foo => :bar, :parent => @owner).and_return(mock_target)
|
101
|
+
mock_target.should_receive(:save).and_return(:save_result)
|
102
|
+
target = @owner.targets.create(:foo => :bar)
|
103
|
+
target.should == mock_target
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should initialize the new target's parent" do
|
107
|
+
target = @owner.targets.build
|
108
|
+
target.parent.should == @owner
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#create!" do
|
113
|
+
before do
|
114
|
+
@mock_target = double('target')
|
115
|
+
Target.should_receive(:new).with(:foo => :bar, :parent => @owner).and_return(@mock_target)
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when save succeeds" do
|
119
|
+
before do
|
120
|
+
@mock_target.should_receive(:save).and_return(true)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should return the target" do
|
124
|
+
target = @owner.targets.create!(:foo => :bar)
|
125
|
+
target.should == @mock_target
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "when save fails" do
|
130
|
+
before do
|
131
|
+
@mock_target.should_receive(:save).and_return(false)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should raise an error" do
|
135
|
+
lambda {
|
136
|
+
@owner.targets.create!(:foo => :bar)
|
137
|
+
}.should raise_error
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "with options :supports_all => true" do
|
143
|
+
before :all do
|
144
|
+
class ::AllableTarget < LucidWorks::Base
|
145
|
+
end
|
146
|
+
class ::Owner
|
147
|
+
has_many :allable_targets, :supports_all => true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "Owner.find(:all, :include => :targets)" do
|
152
|
+
it "should use owwner/all/targets to retrieve the targets" do
|
153
|
+
owners_json = '[{"id":1},{"id":2}]'
|
154
|
+
target_json = '[{"id":1,"allable_target":[{"id":1,"fruit":"apple"},{"id":1,"fruit":"pear"}]},' +
|
155
|
+
'{"id":2,"allable_target":[{"id":2,"fruit":"orange"}]}]'
|
156
|
+
RestClient.should_receive(:get).with("#{@fake_server_uri}/api/owners").
|
157
|
+
once.ordered.and_return(owners_json)
|
158
|
+
RestClient.should_receive(:get).with("#{@fake_server_uri}/api/owners/all/allable_target").
|
159
|
+
once.ordered.and_return(target_json)
|
160
|
+
owners = Owner.find(:all, :parent => @server, :include => :allable_targets)
|
161
|
+
owners.first.allable_targets.first.fruit.should == 'apple'
|
162
|
+
owners.first.allable_targets.last.fruit.should == 'pear'
|
163
|
+
owners.last.allable_targets.first.fruit.should == 'orange'
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LucidWorks::Associations::HasOne do
|
4
|
+
before :all do
|
5
|
+
@fake_server_uri = "http://12.0.0.1:99999"
|
6
|
+
@server = LucidWorks::Server.new(@fake_server_uri)
|
7
|
+
|
8
|
+
class ::Target < LucidWorks::Base
|
9
|
+
attr_accessor :foo
|
10
|
+
end
|
11
|
+
class ::Owner < LucidWorks::Base
|
12
|
+
has_one :target
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before :each do
|
17
|
+
@owner = Owner.new(:parent => @server)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not load the target if just referenced" do
|
21
|
+
Target.should_not_receive(:find)
|
22
|
+
@owner.target
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should load the target with find(:parent => Owner) when target is accessed" do
|
26
|
+
Target.should_receive(:find).with(:singleton, :parent => @owner)
|
27
|
+
@owner.target.class
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should cache the target and not reload it on every access" do
|
31
|
+
mock_target = double('target')
|
32
|
+
Target.should_receive(:find).with(:singleton, :parent => @owner).once.and_return(mock_target)
|
33
|
+
@owner.target.class
|
34
|
+
@owner.target.class
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should delegate methods to the target" do
|
38
|
+
mock_target = double('target')
|
39
|
+
Target.stub(:find) { mock_target }
|
40
|
+
mock_target.should_receive(:foo)
|
41
|
+
@owner.target.foo
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#loaded?" do
|
45
|
+
it "should return true if the target has been loaded, false otherwise" do
|
46
|
+
mock_target = double('target')
|
47
|
+
Target.stub(:find) { mock_target }
|
48
|
+
|
49
|
+
@owner.target.loaded?.should be_false
|
50
|
+
@owner.target.class
|
51
|
+
@owner.target.loaded?.should be_true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#reload!" do
|
56
|
+
it "should force a reload of the target" do
|
57
|
+
mock_target = double('target')
|
58
|
+
Target.should_receive(:find).with(:singleton, :parent => @owner).twice.and_return(mock_target)
|
59
|
+
@owner.target.class
|
60
|
+
@owner.target.reload!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#build" do
|
65
|
+
it "should new up a target and initialize it with the supplied attributes" do
|
66
|
+
target = @owner.target.build(:foo => 'bar')
|
67
|
+
target.should_not be_persisted
|
68
|
+
target.foo.should == 'bar'
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should initialize the new target's parent" do
|
72
|
+
target = @owner.target.build
|
73
|
+
target.parent.should == @owner
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#create" do
|
78
|
+
it "should new up a target and initialize it with the supplied attributes, then attempt to save it" do
|
79
|
+
mock_target = double('target')
|
80
|
+
Target.should_receive(:new).with(:foo => :bar, :parent => @owner).and_return(mock_target)
|
81
|
+
mock_target.should_receive(:save).and_return(:save_result)
|
82
|
+
target = @owner.target.create(:foo => :bar)
|
83
|
+
target.should == mock_target
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should initialize the new target's parent" do
|
87
|
+
target = @owner.target.build
|
88
|
+
target.parent.should == @owner
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#create!" do
|
93
|
+
before do
|
94
|
+
@mock_target = double('target')
|
95
|
+
Target.should_receive(:new).with(:foo => :bar, :parent => @owner).and_return(@mock_target)
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when save succeeds" do
|
99
|
+
before do
|
100
|
+
@mock_target.should_receive(:save).and_return(true)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should return the target" do
|
104
|
+
target = @owner.target.create!(:foo => :bar)
|
105
|
+
target.should == @mock_target
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when save fails" do
|
110
|
+
before do
|
111
|
+
@mock_target.should_receive(:save).and_return(false)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should raise an error" do
|
115
|
+
lambda {
|
116
|
+
@owner.target.create!(:foo => :bar)
|
117
|
+
}.should raise_error
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "with option has_content => false" do
|
123
|
+
before :all do
|
124
|
+
class ::TargetWithoutContent < LucidWorks::Base
|
125
|
+
attr_accessor :foo
|
126
|
+
end
|
127
|
+
class ::Owner
|
128
|
+
has_one :target_without_content, :has_content => false
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
before :each do
|
133
|
+
@owner = Owner.new(:parent => @server)
|
134
|
+
end
|
135
|
+
|
136
|
+
context "before any build or create" do
|
137
|
+
describe "attribute accesses" do
|
138
|
+
it "should not attempt to retrieve the target, and let the caller interact with NilClass" do
|
139
|
+
TargetWithoutContent.should_not_receive(:find)
|
140
|
+
@owner.target_without_content.should be_a(NilClass)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "after build" do
|
146
|
+
it "should return the target" do
|
147
|
+
target = @owner.target_without_content.build(:foo => 'bar')
|
148
|
+
target.should be_a(TargetWithoutContent)
|
149
|
+
target.foo.should == 'bar'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "with options :supports_all => true" do
|
155
|
+
before :all do
|
156
|
+
class ::TargetWithAll < LucidWorks::Base
|
157
|
+
end
|
158
|
+
class ::Owner
|
159
|
+
has_one :target_with_all, :supports_all => true
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "Owner.find(:all, :include => :target)" do
|
164
|
+
it "should use owwner/all/target to retrieve the targets" do
|
165
|
+
owners_json = '[{"id":1},{"id":2}]'
|
166
|
+
target_json = '[{"id":1,"fruit":"apple"},{"id":2,"fruit":"orange"}]'
|
167
|
+
RestClient.should_receive(:get).with("#{@fake_server_uri}/api/owners").
|
168
|
+
once.ordered.and_return(owners_json)
|
169
|
+
RestClient.should_receive(:get).with("#{@fake_server_uri}/api/owners/all/target_with_all").
|
170
|
+
once.ordered.and_return(target_json)
|
171
|
+
owners = Owner.find(:all, :parent => @server, :include => :target_with_all)
|
172
|
+
owners.first.target_with_all.fruit.should == 'apple'
|
173
|
+
owners.last.target_with_all.fruit.should == 'orange'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -4,128 +4,108 @@ describe LucidWorks::Associations do
|
|
4
4
|
before :all do
|
5
5
|
@fake_server_uri = "http://fakehost.com:8888"
|
6
6
|
@server = LucidWorks::Server.new(@fake_server_uri)
|
7
|
-
|
8
|
-
class ::Blog < LucidWorks::Base
|
9
|
-
has_many :posts
|
10
|
-
has_one :homepage
|
11
|
-
has_one :launch_party, :has_content => false
|
12
|
-
end
|
13
|
-
@blog = ::Blog.new(:parent => @server)
|
14
|
-
|
15
|
-
class ::Post < LucidWorks::Base
|
16
|
-
belongs_to :blog
|
17
|
-
end
|
18
|
-
|
19
|
-
class ::Homepage < LucidWorks::Base
|
20
|
-
self.singleton = true
|
21
|
-
belongs_to :blog
|
22
|
-
end
|
23
|
-
|
24
|
-
class ::LaunchParty < LucidWorks::Base
|
25
|
-
self.singleton = true
|
26
|
-
belongs_to :blog
|
27
|
-
end
|
28
7
|
end
|
29
8
|
|
30
9
|
describe ".has_one" do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
@blog.launch_party.should == mock_launch_party
|
38
|
-
@blog.launch_party.should == mock_launch_party
|
39
|
-
end
|
10
|
+
before :all do
|
11
|
+
class ::Blog < LucidWorks::Base
|
12
|
+
has_one :homepage
|
13
|
+
has_one :calendar, :bogus_option => :bogus_value
|
14
|
+
has_one :sitemap, :class_name => 'blog_site_map', :bogus_option => :bogus_value
|
40
15
|
end
|
16
|
+
class ::Homepage < LucidWorks::Base ; end
|
17
|
+
class ::Calendar < LucidWorks::Base ; end
|
18
|
+
class ::BlogSiteMap < LucidWorks::Base ; end
|
41
19
|
|
42
|
-
|
43
|
-
|
44
|
-
LaunchParty.should_not_receive(:find)
|
45
|
-
|
46
|
-
launch_party = @blog.launch_party!
|
20
|
+
@blog = ::Blog.new(:parent => @server)
|
21
|
+
end
|
47
22
|
|
48
|
-
|
49
|
-
|
50
|
-
|
23
|
+
describe "#resource" do
|
24
|
+
it "should create a HasOne association proxy for the specified class" do
|
25
|
+
LucidWorks::Associations::HasOne.should_receive(:new).
|
26
|
+
with(@blog, Homepage, {})
|
27
|
+
@blog.homepage
|
51
28
|
end
|
52
29
|
end
|
53
30
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
31
|
+
describe "#build_resource" do
|
32
|
+
it "should call .resource.build" do
|
33
|
+
mock_association = double("has_one association")
|
34
|
+
@blog.should_receive(:homepage).and_return(mock_association)
|
35
|
+
mock_association.should_receive(:build).with(:foo => :bar)
|
36
|
+
@blog.build_homepage(:foo => :bar)
|
60
37
|
end
|
38
|
+
end
|
61
39
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
40
|
+
describe "#create_resource" do
|
41
|
+
it "should call .resource.create" do
|
42
|
+
mock_association = double("has_one association")
|
43
|
+
@blog.should_receive(:homepage).and_return(mock_association)
|
44
|
+
mock_association.should_receive(:create).with(:foo => :bar)
|
45
|
+
@blog.create_homepage(:foo => :bar)
|
69
46
|
end
|
47
|
+
end
|
70
48
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
homepage.should be_persisted
|
76
|
-
end
|
77
|
-
end
|
49
|
+
it "should pass thru options to the proxy" do
|
50
|
+
LucidWorks::Associations::HasOne.should_receive(:new).
|
51
|
+
with(@blog, Calendar, :bogus_option => :bogus_value)
|
52
|
+
@blog.calendar
|
78
53
|
end
|
79
|
-
end
|
80
54
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
55
|
+
it "should respect the :class_name option" do
|
56
|
+
LucidWorks::Associations::HasOne.should_receive(:new).
|
57
|
+
with(@blog, BlogSiteMap, :bogus_option => :bogus_value)
|
58
|
+
@blog.sitemap
|
85
59
|
end
|
86
60
|
end
|
87
61
|
|
88
62
|
describe ".has_many" do
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
@blog.posts!
|
63
|
+
before :all do
|
64
|
+
class ::Blog < LucidWorks::Base
|
65
|
+
has_many :posts
|
93
66
|
end
|
94
|
-
end
|
95
67
|
|
96
|
-
|
97
|
-
|
98
|
-
mock_posts = double('some posts')
|
99
|
-
Post.should_receive(:find).once.and_return(mock_posts)
|
100
|
-
@blog.posts.should == mock_posts
|
101
|
-
@blog.posts.should == mock_posts
|
68
|
+
class ::Post < LucidWorks::Base
|
69
|
+
belongs_to :blog
|
102
70
|
end
|
103
71
|
end
|
104
72
|
|
105
|
-
|
106
|
-
|
107
|
-
Post.should_receive(:find).with('child_id', :parent => @blog)
|
108
|
-
@blog.post('child_id')
|
109
|
-
end
|
73
|
+
before :each do
|
74
|
+
@blog = ::Blog.new(:parent => @server)
|
110
75
|
end
|
111
76
|
|
112
|
-
describe "
|
113
|
-
it "should
|
114
|
-
|
115
|
-
|
77
|
+
describe "#resources" do
|
78
|
+
it "should create a HasMany association proxy for the specified class" do
|
79
|
+
mock_proxy = double('hasmany proxy', :find => nil)
|
80
|
+
LucidWorks::Associations::HasMany.should_receive(:new).
|
81
|
+
with(@blog, Post, {}).
|
82
|
+
and_return(mock_proxy)
|
83
|
+
@blog.posts
|
116
84
|
end
|
117
85
|
end
|
118
86
|
|
119
|
-
describe "#
|
120
|
-
it "should
|
121
|
-
|
122
|
-
|
123
|
-
post.
|
87
|
+
describe "#resource" do
|
88
|
+
it "should call Resource.find" do
|
89
|
+
mock_proxy = double('hasmany proxy', :first => nil)
|
90
|
+
Post.should_receive(:find).with('child_id', :parent => @blog).and_return(mock_proxy)
|
91
|
+
@blog.post('child_id').first
|
124
92
|
end
|
125
93
|
end
|
126
94
|
end
|
127
95
|
|
128
96
|
describe ".belongs_to" do
|
97
|
+
before :all do
|
98
|
+
class ::Blog < LucidWorks::Base
|
99
|
+
has_many :posts # Same as above - keep
|
100
|
+
end
|
101
|
+
class ::Post < LucidWorks::Base
|
102
|
+
belongs_to :blog
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
before :each do
|
107
|
+
@blog = ::Blog.new(:parent => @server)
|
108
|
+
end
|
129
109
|
|
130
110
|
describe ".belongs_to_association_name (private)" do
|
131
111
|
it "should return the name of the association" do
|
@@ -16,6 +16,7 @@ describe LucidWorks::Base do
|
|
16
16
|
|
17
17
|
class Widget < LucidWorks::Base
|
18
18
|
has_one :singleton_widget
|
19
|
+
has_one :singleton_widget_that_supports_all, :supports_all => true
|
19
20
|
end
|
20
21
|
|
21
22
|
class SingletonWidget < LucidWorks::Base
|
@@ -226,18 +227,36 @@ describe LucidWorks::Base do
|
|
226
227
|
|
227
228
|
describe ":include option" do
|
228
229
|
context "with a single argument" do
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
230
|
+
context "for a subresource that does not support /all" do
|
231
|
+
it "should retrieve the :included submodel by retrieving them individually" do
|
232
|
+
RestClient.should_receive(:get).with("#{@fake_server_uri}/widgets").and_return(WIDGETS_JSON)
|
233
|
+
mock_singleton1 = double('singleton widget1')
|
234
|
+
mock_singleton2 = double('singleton widget2')
|
235
|
+
mock_singleton3 = double('singleton widget3')
|
236
|
+
SingletonWidget.should_receive(:find).and_return(mock_singleton1, mock_singleton2, mock_singleton3)
|
237
|
+
|
238
|
+
widgets = Widget.find(:all, :include => :singleton_widget, :parent => @server)
|
239
|
+
|
240
|
+
widgets[0].singleton_widget.should == mock_singleton1
|
241
|
+
widgets[1].singleton_widget.should == mock_singleton2
|
242
|
+
widgets[2].singleton_widget.should == mock_singleton3
|
243
|
+
end
|
244
|
+
end
|
235
245
|
|
236
|
-
|
246
|
+
context "for a subresource that supports /all" do
|
247
|
+
it "should retrieve the :included submodel by using /submodel/all" do
|
248
|
+
RestClient.should_receive(:get).with("#{@fake_server_uri}/widgets").and_return(WIDGETS_JSON)
|
249
|
+
mock_singleton1 = double('singleton widget1')
|
250
|
+
mock_singleton2 = double('singleton widget2')
|
251
|
+
mock_singleton3 = double('singleton widget3')
|
252
|
+
SingletonWidget.should_receive(:find).and_return(mock_singleton1, mock_singleton2, mock_singleton3)
|
237
253
|
|
238
|
-
|
239
|
-
|
240
|
-
|
254
|
+
widgets = Widget.find(:all, :include => :singleton_widget, :parent => @server)
|
255
|
+
|
256
|
+
widgets[0].singleton_widget.should == mock_singleton1
|
257
|
+
widgets[1].singleton_widget.should == mock_singleton2
|
258
|
+
widgets[2].singleton_widget.should == mock_singleton3
|
259
|
+
end
|
241
260
|
end
|
242
261
|
end
|
243
262
|
|
@@ -253,9 +272,9 @@ describe LucidWorks::Base do
|
|
253
272
|
mock_singleton1 = double('singleton widget1')
|
254
273
|
mock_singleton2 = double('singleton widget2')
|
255
274
|
mock_singleton3 = double('singleton widget3')
|
256
|
-
mock_other_widgets_1 = double('other widgets 1')
|
257
|
-
mock_other_widgets_2 = double('other widgets 2')
|
258
|
-
mock_other_widgets_3 = double('other widgets 3')
|
275
|
+
mock_other_widgets_1 = double('other widgets 1', :supports_all? => false)
|
276
|
+
mock_other_widgets_2 = double('other widgets 2', :supports_all? => false)
|
277
|
+
mock_other_widgets_3 = double('other widgets 3', :supports_all? => false)
|
259
278
|
SingletonWidget.should_receive(:find).and_return(mock_singleton1, mock_singleton2, mock_singleton3)
|
260
279
|
OtherWidget.should_receive(:find).and_return(mock_other_widgets_1, mock_other_widgets_2, mock_other_widgets_3)
|
261
280
|
|
@@ -222,7 +222,7 @@ describe LucidWorks::Datasource do
|
|
222
222
|
end
|
223
223
|
end
|
224
224
|
|
225
|
-
describe "#
|
225
|
+
describe "#build_index" do
|
226
226
|
it "should return a new LucidWorks::Datasource::Index for this datasource" do
|
227
227
|
@datasource = LucidWorks::Datasource.create(
|
228
228
|
:collection => @collection,
|
@@ -234,7 +234,7 @@ describe LucidWorks::Datasource do
|
|
234
234
|
)
|
235
235
|
@datasource.should be_valid
|
236
236
|
|
237
|
-
index = @datasource.
|
237
|
+
index = @datasource.build_index
|
238
238
|
index.should be_a(LucidWorks::Datasource::Index)
|
239
239
|
index.should be_persisted # special case - singletons are always considered persisted
|
240
240
|
end
|
@@ -253,9 +253,9 @@ describe LucidWorks::Datasource do
|
|
253
253
|
@datasource.should be_valid
|
254
254
|
end
|
255
255
|
|
256
|
-
describe "#
|
256
|
+
describe "#build_job" do
|
257
257
|
it "should return a new LucidWorks::Datasource::Job for this datasource" do
|
258
|
-
job = @datasource.
|
258
|
+
job = @datasource.build_job
|
259
259
|
job.should be_a(LucidWorks::Datasource::Job)
|
260
260
|
job.should be_persisted # special case - singletons are always considered persisted
|
261
261
|
end
|
@@ -29,9 +29,12 @@ describe LucidWorks::Server do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "#collections" do
|
32
|
-
|
33
|
-
|
34
|
-
LucidWorks::
|
32
|
+
it "should create a HasMany association proxy for the specified class" do
|
33
|
+
mock_proxy = double('has_many proxy', :find => nil)
|
34
|
+
LucidWorks::Associations::HasMany.should_receive(:new).
|
35
|
+
with(@server, LucidWorks::Collection, {}).
|
36
|
+
and_return(mock_proxy)
|
37
|
+
|
35
38
|
@server.collections
|
36
39
|
end
|
37
40
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: lucid_works
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.6.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Sam Pierson
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-25 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -101,6 +101,9 @@ files:
|
|
101
101
|
- config/locales/en.yml
|
102
102
|
- lib/lucid_works.rb
|
103
103
|
- lib/lucid_works/associations.rb
|
104
|
+
- lib/lucid_works/associations/has_many.rb
|
105
|
+
- lib/lucid_works/associations/has_one.rb
|
106
|
+
- lib/lucid_works/associations/proxy.rb
|
104
107
|
- lib/lucid_works/base.rb
|
105
108
|
- lib/lucid_works/collection.rb
|
106
109
|
- lib/lucid_works/collection/activity.rb
|
@@ -131,6 +134,8 @@ files:
|
|
131
134
|
- lib/lucid_works/utils.rb
|
132
135
|
- lib/lucid_works/version.rb
|
133
136
|
- lucid_works.gemspec
|
137
|
+
- spec/lib/lucid_works/associations/has_many_spec.rb
|
138
|
+
- spec/lib/lucid_works/associations/has_one_spec.rb
|
134
139
|
- spec/lib/lucid_works/associations_spec.rb
|
135
140
|
- spec/lib/lucid_works/base_spec.rb
|
136
141
|
- spec/lib/lucid_works/collection/activity/history_spec.rb
|
@@ -176,6 +181,8 @@ signing_key:
|
|
176
181
|
specification_version: 3
|
177
182
|
summary: Ruby wrapper for the LucidWorks REST API
|
178
183
|
test_files:
|
184
|
+
- spec/lib/lucid_works/associations/has_many_spec.rb
|
185
|
+
- spec/lib/lucid_works/associations/has_one_spec.rb
|
179
186
|
- spec/lib/lucid_works/associations_spec.rb
|
180
187
|
- spec/lib/lucid_works/base_spec.rb
|
181
188
|
- spec/lib/lucid_works/collection/activity/history_spec.rb
|