arrest 0.0.19 → 0.0.20

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.
@@ -7,10 +7,10 @@ require "arrest/attributes/belongs_to"
7
7
  require "arrest/attributes/has_attributes"
8
8
  require "arrest/attributes/attribute"
9
9
  require "arrest/attributes/nested_attribute"
10
- require "arrest/attributes/polymorphic_attribute"
11
10
  require "arrest/attributes/belongs_to_attribute"
12
11
  require "arrest/attributes/has_many_attribute"
13
12
  require "arrest/attributes/has_many_sub_resource_attribute"
13
+ require "arrest/attributes/polymorphic_attribute"
14
14
  require "arrest/attributes/converter"
15
15
  require "arrest/class_utils.rb"
16
16
  require "arrest/string_utils.rb"
@@ -20,11 +20,11 @@ module Arrest
20
20
  Arrest::Source::source
21
21
  end
22
22
 
23
- def body_root response
23
+ def body_root(response)
24
24
  if response == nil
25
25
  raise Errors::DocumentNotFoundError
26
26
  end
27
- all = JSON.parse response
27
+ all = JSON.parse(response)
28
28
  body = all["result"]
29
29
  if body == nil
30
30
  raise Errors::DocumentNotFoundError
@@ -32,11 +32,18 @@ module Arrest
32
32
  body
33
33
  end
34
34
 
35
- def build hash
36
- self.new hash, true
35
+ def build(hash)
36
+ resource = self.new(hash, true)
37
+
38
+ # traverse fields for subresources and fill them in
39
+ self.all_fields.find_all{|f| f.is_a?(HasManySubResourceAttribute)}.each do |attr|
40
+ ids = AbstractResource::source.get_one("#{resource.resource_location}/#{attr.sub_resource_field_name}")
41
+ resource.send("#{attr.name}=", body_root(ids))
42
+ end
43
+ resource
37
44
  end
38
45
 
39
- def custom_resource_name new_name
46
+ def custom_resource_name(new_name)
40
47
  @custom_resource_name = new_name
41
48
  end
42
49
 
@@ -64,7 +71,7 @@ module Arrest
64
71
 
65
72
  url_part = method_name.to_s
66
73
 
67
- hm_attr = create_has_many_attribute(sub_resource,
74
+ hm_attr = create_has_many_attribute(sub_resource, # e.g. 'team_ids' attribute for 'has_many :teams'
68
75
  ids_field_name,
69
76
  method_name,
70
77
  clazz_name,
@@ -72,7 +79,7 @@ module Arrest
72
79
  foreign_key)
73
80
  add_attribute(hm_attr)
74
81
 
75
- send :define_method, method_name do
82
+ send :define_method, method_name do # e.g. define 'teams' method for notation 'has_many :teams'
76
83
  if @has_many_collections == nil
77
84
  @has_many_collections = {}
78
85
  end
@@ -112,6 +119,7 @@ module Arrest
112
119
  clazz_name = clazz.to_s
113
120
  end
114
121
  end
122
+
115
123
  send :define_method, method_name do
116
124
  if @child_collections == nil
117
125
  @child_collections = {}
@@ -130,7 +138,7 @@ module Arrest
130
138
  end
131
139
 
132
140
 
133
- def scope name, &block
141
+ def scope(name, &block)
134
142
  if @scopes == nil
135
143
  @scopes = []
136
144
  end
@@ -150,8 +158,8 @@ module Arrest
150
158
 
151
159
  attr_accessor :id
152
160
 
153
- def initialize hash={}, from_json = false
154
- initialize_has_attributes hash, from_json
161
+ def initialize(hash={}, from_json = false)
162
+ initialize_has_attributes(hash, from_json)
155
163
  end
156
164
 
157
165
  def save
@@ -160,9 +168,10 @@ module Arrest
160
168
 
161
169
  success = !!AbstractResource::source.send(req_type, self)
162
170
 
163
- if success # check for special sub resources
171
+ if success
172
+ # check for sub resources in case of n:m relationships
164
173
  self.class.all_fields.find_all{|f| f.is_a?(HasManySubResourceAttribute)}.each do |attr|
165
- ids = self.send(attr.name)
174
+ ids = self.send(attr.name) # get ids_field e.g. for team has_many :users get 'self.user_ids'
166
175
  srifn = attr.sub_resource_field_name
167
176
  result = !!AbstractResource::source.put_sub_resource(self, srifn, ids)
168
177
  return false if !result
@@ -181,7 +190,7 @@ module Arrest
181
190
  AbstractResource::source().delete self
182
191
  true
183
192
  end
184
- #
193
+
185
194
  # convenience method printing curl command
186
195
  def curl
187
196
  hs = ""
@@ -27,5 +27,5 @@ module Arrest
27
27
  end
28
28
  converter.mk_json value
29
29
  end
30
- end
30
+ end
31
31
  end
@@ -16,7 +16,7 @@ module Arrest
16
16
  "#{name}_id"
17
17
  end
18
18
  end
19
-
19
+
20
20
  def create_and_add_attribute(field_name, polymorphic, read_only, foreign_key, class_name)
21
21
  if polymorphic
22
22
  add_attribute(PolymorphicAttribute.new(field_name.to_sym, read_only))
@@ -24,14 +24,14 @@ module Arrest
24
24
  add_attribute(BelongsToAttribute.new(field_name.to_sym, read_only, String, foreign_key, class_name))
25
25
  end
26
26
  end
27
-
27
+
28
28
  def belongs_to(*args)
29
29
  arg = args[0]
30
30
  name = arg.to_s.downcase
31
31
  class_name = StringUtils.classify(name)
32
32
  foreign_key = "#{StringUtils.underscore(ClassUtils.simple_name(self))}_id"
33
33
  params = args[1] unless args.length < 2
34
-
34
+
35
35
  if params
36
36
  read_only = params[:read_only] == true
37
37
  polymorphic = params[:polymorphic] unless params[:polymorphic] == nil
@@ -42,13 +42,13 @@ module Arrest
42
42
  field_name = create_field_name(name, params, polymorphic)
43
43
 
44
44
  create_and_add_attribute(field_name, polymorphic, read_only, foreign_key, class_name)
45
-
45
+
46
46
  send :define_method, name do
47
47
  val = self.send(field_name)
48
48
  if val == nil || val == ""
49
49
  return nil
50
- end
51
-
50
+ end
51
+
52
52
  begin
53
53
  if polymorphic
54
54
  Arrest::Source.mod.const_get(polymorphic[val.type.to_sym]).find(val.id)
@@ -58,7 +58,7 @@ module Arrest
58
58
  rescue Errors::DocumentNotFoundError => e
59
59
  raise Errors::DocumentNotFoundError, "Couldnt find a #{class_name} with id #{val}"
60
60
  end
61
-
61
+
62
62
  end
63
63
  end
64
64
  end
@@ -3,22 +3,22 @@ module Arrest
3
3
  module HasAttributes
4
4
  attr_accessor :attribute_values
5
5
 
6
- def initialize_has_attributes hash, from_json = false, &blk
6
+ def initialize_has_attributes(hash, from_json = false, &blk)
7
7
  if block_given?
8
8
  @stubbed = true
9
9
  @load_blk = blk
10
10
  else
11
11
  @stubbed = false
12
12
  end
13
- init_from_hash hash, from_json
13
+ init_from_hash(hash, from_json)
14
14
  end
15
15
 
16
- def initialize hash = {}, from_json = false, &blk
16
+ def initialize(hash = {}, from_json = false, &blk)
17
17
  if block_given?
18
18
  @stubbed = true
19
19
  @load_blk = blk
20
20
  else
21
- init_from_hash hash, from_json
21
+ init_from_hash(hash, from_json)
22
22
  end
23
23
  end
24
24
 
@@ -26,7 +26,7 @@ module Arrest
26
26
  base.extend HasAttributesMethods
27
27
  end
28
28
 
29
- def init_from_hash as_i={}, from_json = false
29
+ def init_from_hash(as_i={}, from_json = false)
30
30
  @attribute_values = {} unless @attribute_values != nil
31
31
  as = {}
32
32
  as_i.each_pair do |k,v|
@@ -38,12 +38,26 @@ module Arrest
38
38
  else
39
39
  key = field.name
40
40
  end
41
- value = as[key]
41
+ value = as[key]
42
42
  converted = field.from_hash(value)
43
43
  self.send(field.name.to_s + '=', converted) unless converted == nil
44
44
  end
45
45
  end
46
46
 
47
+ def update_attributes attribute_hash
48
+ fields = self.class.all_fields
49
+ field_names = fields.map(&:name)
50
+ attribute_hash.each_pair do |k,v|
51
+ matching_fields = fields.find_all{|f| f.name.to_s == k.to_s}
52
+ field = matching_fields.first
53
+ if field
54
+ converted = field.from_hash(v)
55
+ self.send("#{k}=", converted)
56
+ end
57
+ end
58
+ self.save
59
+ end
60
+
47
61
  def load_from_stub
48
62
  @load_blk.call
49
63
  @stubbed = false
@@ -79,7 +93,7 @@ module Arrest
79
93
  @fields = []
80
94
  end
81
95
 
82
- def attribute name, clazz, attribs = {}
96
+ def attribute(name, clazz, attribs = {})
83
97
  read_only = !!attribs[:read_only]
84
98
  add_attribute Attribute.new(name, read_only, clazz)
85
99
  end
@@ -90,16 +104,22 @@ module Arrest
90
104
  end
91
105
  end
92
106
 
93
- def add_attribute attribute
94
- if @fields == nil
95
- @fields = []
96
- end
97
- send :define_method, "#{attribute.name}=" do |v|
98
- Arrest::debug "setter #{self.class.name} #{attribute.name} = #{v}"
99
- self.attribute_values[attribute.name] = v
107
+ def add_attribute(attribute)
108
+ @fields ||= []
109
+ if (attribute.is_a?(HasManySubResourceAttribute))
110
+ send :define_method, "#{attribute.name}=" do |v|
111
+ raise ArgumentError, 'Argument is not of Array type' unless v.is_a?(Array)
112
+ Arrest::debug "setter #{self.class.name} #{attribute.name} = #{v}"
113
+ self.attribute_values[attribute.name] = v
114
+ end
115
+ else
116
+ send :define_method, "#{attribute.name}=" do |v|
117
+ Arrest::debug "setter #{self.class.name} #{attribute.name} = #{v}"
118
+ self.attribute_values[attribute.name] = v
119
+ end
100
120
  end
101
121
  send :define_method, "#{attribute.name}" do
102
- Arrest::debug "getter #{self.class.name} #{attribute.name}"
122
+ Arrest::debug "getter #{self.class.name} #{attribute.name}"
103
123
  self.load_from_stub if @stubbed
104
124
  self.attribute_values[attribute.name]
105
125
  end
@@ -1,5 +1,7 @@
1
1
  module Arrest
2
2
  class HasManySubResourceAttribute < HasManyAttribute
3
+ alias :super_from_hash :from_hash
4
+
3
5
  def initialize(ids_field_name,
4
6
  method_name,
5
7
  clazz_name,
@@ -13,5 +15,10 @@ module Arrest
13
15
  def sub_resource_field_name
14
16
  @name
15
17
  end
18
+
19
+ def from_hash(value)
20
+ return [] if value == nil
21
+ super_from_hash(value)
22
+ end
16
23
  end
17
24
  end
@@ -7,7 +7,7 @@ module Arrest
7
7
  CallLog = Struct.new(:request, :response)
8
8
 
9
9
  # The classes in this module supply default behaviour
10
- # for certain processing steps in the consumttion ot the
10
+ # for certain processing steps in the consumption ot the
11
11
  # rest api
12
12
  module Handlers
13
13
 
@@ -21,7 +21,23 @@ module Arrest
21
21
 
22
22
  # a converter to transform between the name of the field in
23
23
  # the json object and the name of the field in ruby code.
24
- # Default behaviour is that for an underscored name in ruby
24
+ # Default behaviour is the identity, i.e. the very same string in
25
+ # JSON as in RUBY
26
+ class IdentityJSONKeyConverter
27
+ class << self
28
+ def key_from_json name
29
+ name.to_s
30
+ end
31
+
32
+ def key_to_json name
33
+ name.to_s
34
+ end
35
+ end
36
+ end
37
+
38
+ # a converter to transform between the name of the field in
39
+ # the json object and the name of the field in ruby code.
40
+ # Special behaviour is that for an underscored name in ruby
25
41
  # a camel cased version in json expected:
26
42
  # ruby -> json
27
43
  # started_at startedAt
@@ -1,12 +1,13 @@
1
1
  module Arrest
2
2
  class HasManyCollection #< BasicObject
3
- def initialize parent, has_many_attribute
3
+ def initialize(parent, has_many_attribute)
4
4
  @parent = parent
5
5
  @clazz_name = (StringUtils.classify(has_many_attribute.clazz_name.to_s))
6
6
  @url_part = has_many_attribute.url_part
7
7
  @children = nil
8
8
  @foreign_key_name = (StringUtils.underscore(@parent.class.name).gsub(/^.*\//, '') + '_id').to_sym
9
9
  define_filters
10
+ @attribute = has_many_attribute
10
11
  end
11
12
 
12
13
  def build attributes = {}
@@ -70,8 +70,7 @@ module Arrest
70
70
  end
71
71
 
72
72
  def put_sub_resource(rest_resource, sub_url, ids)
73
- location = rest_resource.resource_location + "/#{sub_url}"
74
- #body = {sub_url => ids}.to_json
73
+ location = "#{rest_resource.resource_location}/#{sub_url}"
75
74
  body = ids.to_json
76
75
 
77
76
  internal_put(rest_resource, location, body)
@@ -1,20 +1,20 @@
1
1
  module Arrest
2
-
2
+
3
3
  Edge = Struct.new(:foreign_key, :name, :id, :tail)
4
-
4
+
5
5
  class MemSource
6
6
 
7
7
  attr_accessor :data
8
-
8
+
9
9
 
10
10
  @@all_objects = {} # holds all objects of all types,
11
11
  # each having a unique id
12
12
 
13
13
  @@collections = {} # maps urls to collections of ids of objects
14
-
15
- # For every has_many relation
14
+
15
+ # For every has_many relation
16
16
  @@edge_matrix = {} # matrix of edges based on node ids for has_many and belongs_to relations
17
-
17
+
18
18
  @@data = {}
19
19
 
20
20
  def objects
@@ -32,7 +32,7 @@ module Arrest
32
32
  def edge_matrix
33
33
  @@edge_matrix
34
34
  end
35
-
35
+
36
36
  def edge_count
37
37
  @@edge_matrix.values.inject(0){|sum, edges| sum + edges.length }
38
38
  end
@@ -40,7 +40,7 @@ module Arrest
40
40
  def node_count
41
41
  @@edge_matrix.length
42
42
  end
43
-
43
+
44
44
  def initialize
45
45
  @@all_objects = {} # holds all objects of all types,
46
46
 
@@ -100,7 +100,7 @@ module Arrest
100
100
  def get_many(sub, filters = {})
101
101
  Arrest::debug sub + (hash_to_query filters)
102
102
  # filters are ignored by mem impl so far
103
-
103
+
104
104
  id_list = parse_for_has_many_relations(sub)
105
105
  if id_list.empty?
106
106
  id_list = @@collections[sub] || []
@@ -126,7 +126,7 @@ module Arrest
126
126
  end
127
127
  wrap val.to_jhash.to_json, 1
128
128
  end
129
-
129
+
130
130
  def delete_all resource_path
131
131
  id_list = Array.new(@@collections[resource_path] || [])
132
132
  id_list.each do |base_id|
@@ -137,7 +137,7 @@ module Arrest
137
137
  remove_edges(@@edge_matrix, base_id)
138
138
  end
139
139
  end
140
-
140
+
141
141
  def collection_json values
142
142
  single_jsons = values.map do |v|
143
143
  v.to_jhash.to_json
@@ -173,12 +173,12 @@ module Arrest
173
173
  out_edges = edge_matrix[id].find_all{|edge| edge.tail}
174
174
  in_edges_to_delete = out_edges.map do |out_edge|
175
175
  foreign_edges = edge_matrix[out_edge.id] # the edge set of the foreign node that this node points to
176
- has_many_back_edges = foreign_edges.find_all do |for_edge|
176
+ has_many_back_edges = foreign_edges.find_all do |for_edge|
177
177
  for_edge.id == id && for_edge.foreign_key == out_edge.foreign_key
178
178
  end
179
179
  [has_many_back_edges.first, out_edge.id] # first element may be nil
180
180
  end
181
-
181
+
182
182
  in_edges_to_delete.each do |tupel|
183
183
  if tupel[0]
184
184
  edge_matrix[tupel[1]].delete_if{|e| e.id == tupel[0].id && e.foreign_key == tupel[0].foreign_key}
@@ -200,7 +200,7 @@ module Arrest
200
200
 
201
201
  def identify_and_store_edges(edge_matrix, rest_resource)
202
202
  from_id = rest_resource.id
203
-
203
+
204
204
  rest_resource.class.all_fields.each do |attr|
205
205
  if attr.is_a?(Arrest::HasManyAttribute)
206
206
  to_ids = rest_resource.send(attr.name) # -> foo_ids
@@ -225,7 +225,7 @@ module Arrest
225
225
  return if hm_candidates.empty?
226
226
  has_many_node = hm_candidates.first
227
227
  url_part = has_many_node.url_part
228
-
228
+
229
229
  edge_matrix[from_id] ||= Set.new()
230
230
  edge_matrix[from_id].add(Edge.new(foreign_key, url_part, to_id, true))
231
231
  edge_matrix[to_id] ||= Set.new()
@@ -235,13 +235,18 @@ module Arrest
235
235
  end
236
236
  end
237
237
 
238
+ def put_sub_resource(rest_resource, sub_url, ids)
239
+ location = "#{rest_resource.resource_location}/#{sub_url}"
240
+ body = ids.to_json
241
+ @@collections[location] = body
242
+ end
238
243
 
239
244
  def put(rest_resource)
240
245
  raise "To change an object it must have an id" unless rest_resource.respond_to?(:id) && rest_resource.id != nil
241
246
  old = @@all_objects[rest_resource.id]
242
-
247
+
243
248
  remove_outgoing_edges(@@edge_matrix, old.id)
244
-
249
+
245
250
  rest_resource.class.all_fields.each do |f|
246
251
  old.send("#{f.name}=", rest_resource.send(f.name))
247
252
  end
@@ -252,8 +257,9 @@ module Arrest
252
257
  end
253
258
 
254
259
 
260
+
255
261
  def post(rest_resource)
256
-
262
+
257
263
  Arrest::debug "post -> #{rest_resource.class.name} #{rest_resource.to_hash} #{rest_resource.class.all_fields.map(&:name)}"
258
264
  raise "new object must have setter for id" unless rest_resource.respond_to?(:id=)
259
265
  raise "new object must not have id" if rest_resource.respond_to?(:id) && rest_resource.id != nil
@@ -7,7 +7,7 @@ module Arrest
7
7
  "#{self.resource_name}"
8
8
  end
9
9
 
10
- def by_url url
10
+ def by_url(url)
11
11
  begin
12
12
  body = body_root(source().get_many(url))
13
13
  rescue Arrest::Errors::DocumentNotFoundError
@@ -20,9 +20,9 @@ module Arrest
20
20
  end
21
21
  end
22
22
 
23
- def all filter={}
23
+ def all(filter={})
24
24
  begin
25
- body = body_root(source().get_many self.resource_path, filter)
25
+ body = body_root(source().get_many(self.resource_path, filter))
26
26
  rescue Arrest::Errors::DocumentNotFoundError
27
27
  Arrest::logger.info "DocumentNotFoundError for #{self.resource_path} gracefully returning []"
28
28
  return []
@@ -40,10 +40,10 @@ module Arrest
40
40
  Arrest::logger.info "DocumentNotFoundError for #{self.resource_path}"
41
41
  raise Errors::DocumentNotFoundError.new
42
42
  end
43
- self.build body
43
+ self.build(body)
44
44
  end
45
45
 
46
- def find id
46
+ def find(id)
47
47
  if id == nil || "" == id
48
48
  Arrest::logger.info "DocumentNotFoundError: no id given"
49
49
  raise Errors::DocumentNotFoundError.new
@@ -97,7 +97,7 @@ module Arrest
97
97
  super(name)
98
98
  if block_given?
99
99
  send :define_singleton_method, name do
100
- self.all.select &block
100
+ self.all.select &block
101
101
  end
102
102
  else
103
103
  send :define_singleton_method, name do
@@ -122,8 +122,8 @@ module Arrest
122
122
  end
123
123
  n
124
124
  end
125
-
126
-
125
+
126
+
127
127
  def delete_all
128
128
  source().delete_all(self.resource_path)
129
129
  end
@@ -134,7 +134,7 @@ module Arrest
134
134
  end
135
135
 
136
136
  def resource_location
137
- self.class.resource_path + '/' + self.id.to_s
137
+ self.class.resource_path + '/' + self.id.to_s
138
138
  end
139
139
 
140
140
  end
@@ -53,7 +53,7 @@ module Arrest
53
53
  Source.mod = nil
54
54
  Source.header_decorator = Handlers::HeaderDecorator
55
55
  Source.debug = false
56
- Source.json_key_converter = Handlers::KeyConverter
56
+ Source.json_key_converter = Handlers::IdentityJSONKeyConverter
57
57
  Source.error_handler = Handlers::ErrorHandler
58
58
  Source.call_logger = Handlers::CallLogger
59
59
  Source.skip_validations = false
@@ -1,3 +1,3 @@
1
1
  module Arrest
2
- VERSION = "0.0.19"
2
+ VERSION = "0.0.20"
3
3
  end
@@ -18,7 +18,7 @@ class Animal < Arrest::RestChild
18
18
  attribute :kind, String
19
19
  attribute :age, Integer
20
20
  attribute :male, Boolean
21
-
21
+
22
22
  parent :zoo
23
23
 
24
24
  scope :server_males_only
@@ -34,7 +34,7 @@ end
34
34
  class SpecialZoo < Zoo
35
35
  custom_resource_name :zoo3000
36
36
  read_only_attributes({ :ro2 => String})
37
- attributes({
37
+ attributes({
38
38
  :is_magic => Boolean,
39
39
  :opened_at => Time
40
40
  })
@@ -113,8 +113,8 @@ class Comment < Arrest::RootResource
113
113
  :comb => "CommentableB" }
114
114
  end
115
115
  class ExtendedComment < Comment
116
- belongs_to :other_commentable,
117
- :field_name => "special_commentable_ref",
116
+ belongs_to :other_commentable,
117
+ :field_name => "special_commentable_ref",
118
118
  :polymorphic => { :comc => :CommentableC }
119
119
  end
120
120
 
@@ -122,7 +122,7 @@ class DeleteMeAll < Arrest::RootResource
122
122
  end
123
123
 
124
124
  class Foo < Arrest::RootResource
125
- has_many :bars#, :class_name => :Bar, :foreign_key => defaults to bar_id
125
+ has_many :bars#, :class_name => :Bar, :foreign_key => defaults to bar_id
126
126
  has_many :other_bars, :class_name => :Bar, :foreign_key => :common_key
127
127
  end
128
128
  class Bar < Arrest::RootResource
@@ -130,3 +130,7 @@ class Bar < Arrest::RootResource
130
130
  belongs_to :foo# foreign key defaults to class name, {:foreign_key => bar_id}
131
131
  belongs_to :other_foo, {:class_name => Foo, :foreign_key => :common_key}#, :foreign_key => :other_foo_key
132
132
  end
133
+
134
+ class BarWithHasManySubResource < Arrest::RootResource
135
+ has_many :foos, :sub_resource => true
136
+ end
@@ -18,7 +18,7 @@ class NestedResourcesTest < Test::Unit::TestCase
18
18
  input = {
19
19
  :parent_name => 'parent',
20
20
  :bool => false,
21
- :nested_object => {
21
+ :nested_object => {
22
22
  :name => 'iamnested',
23
23
  :underscore_name => 'foo',
24
24
  :bool => true
@@ -37,7 +37,7 @@ class NestedResourcesTest < Test::Unit::TestCase
37
37
  input = {
38
38
  :parent_name => 'parent',
39
39
  :bool => false,
40
- :nested_object => {
40
+ :nested_object => {
41
41
  :name => 'iamnested',
42
42
  :underscore_name => 'foo',
43
43
  :bool => true
@@ -55,13 +55,13 @@ class NestedResourcesTest < Test::Unit::TestCase
55
55
  :parent_name => 'parent',
56
56
  :bool => false,
57
57
  :nested_objects => [
58
- {
58
+ {
59
59
  :name => 'iamnested_one',
60
60
  :bool => true
61
- },{
61
+ },{
62
62
  :name => 'iamnested_two',
63
63
  :bool => false
64
- }
64
+ }
65
65
  ]
66
66
  }
67
67
 
@@ -71,14 +71,14 @@ class NestedResourcesTest < Test::Unit::TestCase
71
71
 
72
72
  end
73
73
 
74
- def test_belongd_to_to_hash
74
+ def test_belongs_to_to_hash
75
75
  new_zoo = Zoo.new({:name => "Foo"})
76
76
  new_zoo.save
77
77
 
78
78
  input = {
79
79
  :parent_name => 'parent',
80
80
  :bool => false,
81
- :nested_object => {
81
+ :nested_object => {
82
82
  :name => 'iamnested',
83
83
  :bool => true,
84
84
  :zoo_id => new_zoo.id
@@ -105,7 +105,7 @@ class NestedResourcesTest < Test::Unit::TestCase
105
105
  assert_not_nil c.id, "Persisted object should have id"
106
106
  assert_equal "Foo", c.zoo_thing.name
107
107
  assert_equal "Foo", c.zoo.name
108
-
108
+
109
109
 
110
110
  assert_not_nil c.id, "Persisted zoo should have id"
111
111
  c_reloaded = CustomNamedBelongsTo.all.first
@@ -22,7 +22,7 @@ class FirstTest < Test::Unit::TestCase
22
22
  #assert_not_empty Arrest::RootResource.all_fields.select {|f| f.name == :id}, "RootResource should inherit id from AbstractResource"
23
23
  #assert_not_empty Zoo.all_fields.select {|f| f.name == :id}, "Zoo should inherit id field from RootResource"
24
24
  end
25
-
25
+
26
26
  def test_create
27
27
  zoo_count_before = Zoo.all.length
28
28
  new_zoo = Zoo.new({:name => "Foo"})
@@ -85,7 +85,7 @@ class FirstTest < Test::Unit::TestCase
85
85
 
86
86
  zoo_reloaded = Zoo.find(new_zoo.id)
87
87
  assert_equal new_zoo.name, zoo_reloaded.name
88
-
88
+
89
89
  zoo_reloaded.delete
90
90
  assert_equal zoo_count_before, Zoo.all.length
91
91
  end
@@ -115,7 +115,7 @@ class FirstTest < Test::Unit::TestCase
115
115
 
116
116
  assert_equal new_zoo_name, zoo_reloaded.name
117
117
  end
118
-
118
+
119
119
  def test_child
120
120
  new_zoo = Zoo.new({:name => "Foo"})
121
121
  new_zoo.save
@@ -139,7 +139,7 @@ class FirstTest < Test::Unit::TestCase
139
139
  assert_equal 1, zoo_reloaded.animals.length
140
140
  assert_equal Animal, zoo_reloaded.animals.first.class
141
141
  assert_equal 42, zoo_reloaded.animals.first.age
142
-
142
+
143
143
  animal_reloaded = zoo_reloaded.animals.first
144
144
 
145
145
  assert_equal new_zoo.id, animal_reloaded.zoo.id
@@ -203,18 +203,18 @@ class FirstTest < Test::Unit::TestCase
203
203
  def test_read_only_attributes
204
204
  now = Time.now
205
205
  zoo = SpecialZoo.new({
206
- :name => "Zoo",
207
- :ro1 => "one",
208
- :ro2 => "two",
206
+ :name => "Zoo",
207
+ :ro1 => "one",
208
+ :ro2 => "two",
209
209
  :is_magic => true,
210
210
  :opened_at => now
211
211
  })
212
-
212
+
213
213
  assert_equal "Zoo", zoo.name
214
214
  assert_equal "one", zoo.ro1
215
215
  assert_equal "two", zoo.ro2
216
216
  assert_equal true, zoo.is_magic
217
-
217
+
218
218
  hash = zoo.to_jhash
219
219
 
220
220
  assert_nil hash[:ro1]
@@ -227,7 +227,7 @@ class FirstTest < Test::Unit::TestCase
227
227
  def test_stub_delayed_load
228
228
  new_zoo = Zoo.new({:name => "Foo"})
229
229
  new_zoo.save
230
-
230
+
231
231
  assert_not_nil new_zoo.id
232
232
 
233
233
  stubbed = Zoo.stub(new_zoo.id)
@@ -241,14 +241,14 @@ class FirstTest < Test::Unit::TestCase
241
241
  def test_stub_not_load_for_child_access
242
242
  new_zoo = Zoo.new({:name => "Foo"})
243
243
  new_zoo.save
244
-
244
+
245
245
  assert_not_nil new_zoo.id
246
246
  # this is where the magic hapens
247
247
  stubbed = Zoo.stub(new_zoo.id)
248
248
 
249
249
  new_animal = Animal.new new_zoo, {:kind => "foo", :age => 42}
250
250
  new_animal.save
251
-
251
+
252
252
  assert stubbed.stubbed?, "Zoo should be a stub, so not loaded yet"
253
253
 
254
254
  animals = stubbed.animals
@@ -265,11 +265,11 @@ class FirstTest < Test::Unit::TestCase
265
265
  def test_root_scope
266
266
  assert_not_nil Zoo.server_scope
267
267
  end
268
-
268
+
269
269
  def test_child_scope
270
270
  new_zoo = Zoo.new({:name => "Foo"})
271
271
  new_zoo.save
272
-
272
+
273
273
  assert_not_nil new_zoo.id
274
274
 
275
275
  assert_not_nil new_zoo.animals.server_males_only
@@ -319,9 +319,9 @@ class FirstTest < Test::Unit::TestCase
319
319
  p1 = ParentFilter.new({:afield => "ParentFoo"})
320
320
  p1.save
321
321
 
322
- c1 = ChildFilter.new(p1, :bfield => "Foo")
322
+ c1 = ChildFilter.new(p1, :bfield => "Foo")
323
323
  c1.save
324
- c2 = ChildFilter.new(p1, :bfield => "Bar")
324
+ c2 = ChildFilter.new(p1, :bfield => "Bar")
325
325
  c2.save
326
326
 
327
327
  reloaded_parent = ParentFilter.find(p1.id)
@@ -398,55 +398,55 @@ class FirstTest < Test::Unit::TestCase
398
398
  t = TimeClass.new(:time => now)
399
399
  assert_equal expected, t.to_jhash[:time], "This is the expected default format"
400
400
  end
401
-
401
+
402
402
  def test_polymorphic_belongs_to
403
403
  coma = CommentableA.new()
404
404
  coma.save
405
405
  comb = CommentableB.new()
406
406
  comb.save
407
-
407
+
408
408
  c = Comment.new(:commentable_ref => { :id => coma.id, :type => "coma"})
409
409
  result = c.commentable
410
410
  assert_equal coma.id, c.commentable_ref.id
411
411
  assert_equal result.class, CommentableA
412
-
412
+
413
413
  c2 = Comment.new(:commentable_ref => { :id => comb.id, :type => "comb"})
414
414
  result2 = c2.commentable
415
415
  assert_equal comb.id, c2.commentable_ref.id
416
416
  assert_equal result2.class, CommentableB
417
417
  end
418
-
418
+
419
419
  def test_polymorphic_belongs_to_extended
420
420
  coma = CommentableA.new()
421
421
  coma.save
422
422
  comc = CommentableC.new()
423
423
  comc.save
424
-
425
- c = ExtendedComment.new({ :special_commentable_ref => { :id => comc.id, :type => "comc"},
424
+
425
+ c = ExtendedComment.new({ :special_commentable_ref => { :id => comc.id, :type => "comc"},
426
426
  :commentable_ref => { :id => coma.id, :type => "coma" }})
427
427
  assert_equal c.commentable.class, CommentableA
428
428
  assert_equal c.other_commentable.class, CommentableC
429
-
429
+
430
430
  c.save
431
431
  c_reloaded = ExtendedComment.find(c.id)
432
432
  assert_equal comc.id, c_reloaded.special_commentable_ref.id
433
433
  assert_equal CommentableC, c_reloaded.other_commentable.class
434
434
  assert_equal CommentableA, c_reloaded.commentable.class
435
435
  end
436
-
436
+
437
437
  def test_delete_all_root_resources
438
438
  d1 = DeleteMeAll.new()
439
439
  d1.save
440
440
  d2 = DeleteMeAll.new()
441
441
  d2.save
442
-
442
+
443
443
  d1_rel = DeleteMeAll.find(d1.id)
444
444
  assert_not_nil d1_rel
445
445
  d2_rel = DeleteMeAll.find(d2.id)
446
446
  assert_not_nil d2_rel
447
447
  all = DeleteMeAll.all
448
448
  assert_equal 2, all.length
449
-
449
+
450
450
  DeleteMeAll.delete_all
451
451
  all = DeleteMeAll.all
452
452
  assert_equal [], all
@@ -460,7 +460,7 @@ class FirstTest < Test::Unit::TestCase
460
460
  b1.save
461
461
  assert_equal 2, Arrest::Source.source.edge_count
462
462
  assert_equal 2, Arrest::Source.source.node_count
463
-
463
+
464
464
  f2 = Foo.new()
465
465
  f2.save
466
466
  assert_equal 2, Arrest::Source.source.edge_count
@@ -470,7 +470,7 @@ class FirstTest < Test::Unit::TestCase
470
470
  assert_equal 2, Arrest::Source.source.edge_count
471
471
  assert_equal 3, Arrest::Source.source.node_count
472
472
  end
473
-
473
+
474
474
  def test_has_many_matrix_in_mem_source
475
475
  f1 = Foo.new()
476
476
  f1.save
@@ -481,33 +481,33 @@ class FirstTest < Test::Unit::TestCase
481
481
 
482
482
  b1 = Bar.new({:foo_ids => [f1.id, f2.id], :foo_id => f3.id})
483
483
  b1.save
484
-
484
+
485
485
  assert_equal 2, b1.foos.length
486
-
486
+
487
487
  b2 = Bar.new({:foo_ids => [f2.id, f3.id], :foo_id =>f1.id})
488
488
  b2.save
489
-
489
+
490
490
  f1.delete
491
-
491
+
492
492
  b1_rel = Bar.find(b1.id)
493
493
  assert_equal 1, b1_rel.foos.length
494
494
  assert_equal f2.id, b1_rel.foos.first.id
495
-
496
-
495
+
496
+
497
497
  f2.bar_ids=[b1.id]
498
498
  f2.other_bar_ids=[b2.id]
499
499
  f2.save
500
500
  f2_rel = Foo.find(f2.id)
501
501
  assert_equal 1, f2_rel.bars.length
502
502
  assert_equal 1, f2_rel.other_bars.length
503
-
503
+
504
504
  b2.delete
505
-
505
+
506
506
  f2_rel = Foo.find(f2.id)
507
507
  assert_equal 1, f2_rel.bars.length
508
508
  assert_equal 0, f2_rel.other_bars.length
509
509
  assert_equal b1.id, f2_rel.bars.first.id
510
-
510
+
511
511
  end
512
512
 
513
513
  def test_has_many_with_belongs_to
@@ -522,24 +522,23 @@ class FirstTest < Test::Unit::TestCase
522
522
  b1.save
523
523
  b2 = Bar.new({:other_foo_id => f2.id, :foo_id => f1.id})
524
524
  b2.save
525
-
525
+
526
526
  f1_rel = Foo.find(f1.id)
527
527
  f2_rel = Foo.find(f2.id)
528
528
  f3_rel = Foo.find(f3.id)
529
-
529
+
530
530
  assert_equal 1, f1_rel.bars.length
531
531
  assert_equal b1.id, f1_rel.other_bars.first.id
532
532
  assert_equal b1.id, f3_rel.bars.first.id
533
533
 
534
534
  assert_equal b2.id, f1_rel.bars.first.id
535
535
  assert_equal b2.id, f2_rel.other_bars.first.id
536
-
536
+
537
537
  #test update
538
538
  b1.foo_id = f2.id
539
539
  b1.save
540
-
541
-
542
-
540
+
541
+
543
542
  f3_rel = Foo.find(f3.id)
544
543
  assert f3_rel.bars.empty?
545
544
  f2_rel = Foo.find(f2.id)
@@ -574,8 +573,8 @@ class FirstTest < Test::Unit::TestCase
574
573
 
575
574
  assert_not_equal zoo1,zoo2, 'objects with different ids should not be equal'
576
575
 
577
- assert_equal zoo1, zoo1, 'An object should be euqual to itself'
578
-
576
+ assert_equal zoo1, zoo1, 'An object should be equal to itself'
577
+
579
578
  assert_not_equal zoo1, nil, 'Anactual object should not equal nil'
580
579
 
581
580
  zoo1_reloaded = Zoo.find(zoo1.id)
@@ -587,9 +586,30 @@ class FirstTest < Test::Unit::TestCase
587
586
  foo.id = zoo1.id
588
587
 
589
588
  assert_not_equal zoo1, foo, "Objects of different classes should not be euqal, even if they have the same id"
590
-
589
+
591
590
  zoo1_reloaded.name = 'zoooooo'
592
591
  assert_equal zoo1, zoo1_reloaded, "Objects of the same class with the same id should be equal even if they differ in attributes (same as in rails)"
593
592
  end
593
+
594
+ def test_has_many_sub_resource_attr_setter
595
+ b = BarWithHasManySubResource.new()
596
+ b.save
597
+
598
+ assert_raise ArgumentError do
599
+ b.foo_ids = nil
600
+ end
601
+
602
+ assert_raise ArgumentError do
603
+ b.foo_ids = "Tralala"
604
+ end
605
+
606
+ b.foo_ids = []
607
+ end
608
+
609
+ def test_update_attribute
610
+ zoo1 = Zoo.new(:name => 'zoo1')
611
+ zoo1.update_attributes({:name => "updated"})
612
+ assert_equal "updated", zoo1.name
613
+ end
594
614
  end
595
615
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arrest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.20
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-31 00:00:00.000000000Z
12
+ date: 2012-02-03 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &2164553540 !ruby/object:Gem::Requirement
16
+ requirement: &2165537620 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2164553540
24
+ version_requirements: *2165537620
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: faraday
27
- requirement: &2164549080 !ruby/object:Gem::Requirement
27
+ requirement: &2165536020 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - =
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.7.5
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2164549080
35
+ version_requirements: *2165536020
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: activemodel
38
- requirement: &2164547760 !ruby/object:Gem::Requirement
38
+ requirement: &2165535100 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '3'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2164547760
46
+ version_requirements: *2165535100
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &2164546900 !ruby/object:Gem::Requirement
49
+ requirement: &2165534560 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2164546900
57
+ version_requirements: *2165534560
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &2164545840 !ruby/object:Gem::Requirement
60
+ requirement: &2165534160 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2164545840
68
+ version_requirements: *2165534160
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rdoc
71
- requirement: &2164544020 !ruby/object:Gem::Requirement
71
+ requirement: &2165533580 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2164544020
79
+ version_requirements: *2165533580
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &2164543140 !ruby/object:Gem::Requirement
82
+ requirement: &2165532960 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '2'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2164543140
90
+ version_requirements: *2165532960
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rr
93
- requirement: &2164542260 !ruby/object:Gem::Requirement
93
+ requirement: &2165532320 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *2164542260
101
+ version_requirements: *2165532320
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: simplecov
104
- requirement: &2164541340 !ruby/object:Gem::Requirement
104
+ requirement: &2165531160 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *2164541340
112
+ version_requirements: *2165531160
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rack
115
- requirement: &2164522540 !ruby/object:Gem::Requirement
115
+ requirement: &2165530080 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,7 +120,7 @@ dependencies:
120
120
  version: '0'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *2164522540
123
+ version_requirements: *2165530080
124
124
  description: Consume a rest API in a AR like fashion
125
125
  email:
126
126
  - axel.tetzlaff@fortytools.com