hyperion-api 0.1.3 → 0.2.0

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.
@@ -139,22 +139,22 @@ module Hyperion
139
139
  def self.build_query(kind, args)
140
140
  kind = Format.format_kind(kind)
141
141
  filters = build_filters(kind, args[:filters])
142
- sorts = build_sorts(args[:sorts])
142
+ sorts = build_sorts(kind, args[:sorts])
143
143
  Query.new(kind, filters, sorts, args[:limit], args[:offset])
144
144
  end
145
145
 
146
146
  def self.build_filters(kind, filters)
147
147
  (filters || []).map do |(field, operator, value)|
148
148
  operator = Format.format_operator(operator)
149
- field = Format.format_field(field)
149
+ packed_field = pack_field(kind, field)
150
150
  value = pack_value(kind, field, value)
151
- Filter.new(field, operator, value)
151
+ Filter.new(packed_field, operator, value)
152
152
  end
153
153
  end
154
154
 
155
- def self.build_sorts(sorts)
155
+ def self.build_sorts(kind, sorts)
156
156
  (sorts || []).map do |(field, order)|
157
- field = Format.format_field(field)
157
+ field = pack_field(kind, field)
158
158
  order = Format.format_order(order)
159
159
  Sort.new(field, order)
160
160
  end
@@ -168,8 +168,10 @@ module Hyperion
168
168
 
169
169
  def self.unpack_record(record)
170
170
  if record
171
- create_entity(record) do |field_spec, value|
172
- field_spec.unpack(value)
171
+ create_entity(record) do |record, entity, field, field_spec|
172
+ value = record[field_spec.db_name]
173
+ entity[field] = field_spec.unpack(value)
174
+ entity
173
175
  end
174
176
  end
175
177
  end
@@ -182,13 +184,24 @@ module Hyperion
182
184
 
183
185
  def self.pack_record(record)
184
186
  if record
185
- entity = create_entity(record) do |field_spec, value|
186
- field_spec.pack(value || field_spec.default)
187
+ entity = create_entity(record) do |record, entity, field, field_spec|
188
+ value = record[field]
189
+ entity[field_spec.db_name] = field_spec.pack(value || field_spec.default)
190
+ entity
187
191
  end
188
192
  update_timestamps(entity)
189
193
  end
190
194
  end
191
195
 
196
+ def self.pack_field(kind, field)
197
+ field = Format.format_field(field)
198
+ kind_spec = kind_spec_for(kind)
199
+ return field unless kind_spec
200
+ field_spec = kind_spec.fields[field]
201
+ return field unless field_spec
202
+ return field_spec.db_name
203
+ end
204
+
192
205
  def self.pack_value(kind, field, value)
193
206
  kind_spec = kind_spec_for(kind)
194
207
  return value unless kind_spec
@@ -236,8 +249,7 @@ module Hyperion
236
249
  base_record = {:kind => kind}
237
250
  base_record[:key] = key if key
238
251
  spec.fields.reduce(base_record) do |new_record, (name, spec)|
239
- new_record[name] = yield(spec, record[name])
240
- new_record
252
+ yield(record, new_record, name, spec)
241
253
  end
242
254
  end
243
255
  end
@@ -254,7 +266,7 @@ module Hyperion
254
266
 
255
267
  class FieldSpec
256
268
 
257
- attr_reader :name, :default
269
+ attr_reader :name, :default, :db_name
258
270
 
259
271
  def initialize(name, opts={})
260
272
  @name = name
@@ -262,6 +274,7 @@ module Hyperion
262
274
  @type = opts[:type]
263
275
  @packer = opts[:packer]
264
276
  @unpacker = opts[:unpacker]
277
+ @db_name = opts[:db_name] ? Format.format_field(opts[:db_name]) : name
265
278
  end
266
279
 
267
280
  def pack(value)
@@ -26,7 +26,7 @@ shared_examples_for 'Datastore' do
26
26
 
27
27
  it 'saves an existing record' do
28
28
  record1 = api.save({:kind => 'other_testing', :name => 'ann'})
29
- record2 = api.save(record1.merge(:name => 'james'))
29
+ record2 = api.save({:kind => 'other_testing', :key => record1[:key]}, :name => 'james')
30
30
  record1[:key].should == record2[:key]
31
31
  api.find_by_kind('other_testing').length.should == 1
32
32
  end
@@ -81,17 +81,6 @@ shared_examples_for 'Datastore' do
81
81
  end
82
82
 
83
83
  context 'find by kind' do
84
- before :each do
85
- api.save_many([
86
- {:kind => 'testing', :inti => 1, :data => 'one' },
87
- {:kind => 'testing', :inti => 12, :data => 'twelve' },
88
- {:kind => 'testing', :inti => 23, :data => 'twenty3'},
89
- {:kind => 'testing', :inti => 34, :data => 'thirty4'},
90
- {:kind => 'testing', :inti => 45, :data => 'forty5' },
91
- {:kind => 'testing', :inti => 1, :data => 'the one'},
92
- {:kind => 'testing', :inti => 44, :data => 'forty4' }
93
- ])
94
- end
95
84
 
96
85
  it 'filters by the kind' do
97
86
  api.save({:kind => 'other_testing', :inti => 5})
@@ -102,19 +91,33 @@ shared_examples_for 'Datastore' do
102
91
  end
103
92
 
104
93
  it "can't filter on old values" do
105
- record = api.find_by_kind('testing', :filters => [[:inti, '=', 12]]).first
94
+ record = api.save(:kind => 'testing', :inti => 12)
106
95
  api.save(record, :inti => 2)
107
96
  api.find_by_kind('testing', :filters => [[:inti, '=', 12]]).should == []
108
97
  end
109
98
 
110
99
  context 'filters' do
100
+ before :each do
101
+ api.save_many([
102
+ {:kind => 'testing', :inti => 1, :data => 'one' },
103
+ {:kind => 'testing', :inti => 12, :data => 'twelve' },
104
+ {:kind => 'testing', :inti => 23, :data => 'twenty3'},
105
+ {:kind => 'testing', :inti => 34, :data => 'thirty4'},
106
+ {:kind => 'testing', :inti => 45, :data => 'forty5' },
107
+ {:kind => 'testing', :inti => 1, :data => 'the one'},
108
+ {:kind => 'testing', :inti => 44, :data => 'forty4' },
109
+ {:kind => 'testing', :inti => nil, :data => 'forty4' }
110
+ ])
111
+ end
111
112
 
112
113
  [
113
114
  [[[:inti, '<', 25]], [1, 12, 23], :inti],
114
115
  [[[:inti, '<=', 25]], [1, 12, 23], :inti],
115
116
  [[[:inti, '>', 25]], [34, 44, 45], :inti],
116
117
  [[[:inti, '=', 34]], [34], :inti],
117
- [[[:inti, '!=', 34]], [1, 12, 23, 44, 45], :inti],
118
+ [[[:inti, '=', nil]], [nil], :inti],
119
+ [[[:inti, '!=', nil]], [1, 1, 12, 23, 34, 44, 45], :inti],
120
+ [[[:inti, '!=', 34]], [1, 12, 23, 44, 45, nil], :inti],
118
121
  [[[:inti, 'in', [12, 34]]], [12, 34], :inti],
119
122
  [[[:inti, '>', 10], [:inti, '<', 25]], [12, 23], :inti],
120
123
  [[[:inti, '<', 25], [:inti, '>', 10]], [12, 23], :inti],
@@ -123,7 +126,7 @@ shared_examples_for 'Datastore' do
123
126
  [[[:inti, '>', 10], [:inti, '<', 25], [:inti, '=', 23]], [23], :inti],
124
127
  [[[:inti, '=', 23], [:inti, '>', 10], [:inti, '<', 25]], [23], :inti],
125
128
  [[[:inti, '<', 24], [:inti, '>', 25]], [], :inti],
126
- [[[:inti, '!=', 12], [:inti, '!=', 23], [:inti, '!=', 34]], [1, 44, 45], :inti],
129
+ [[[:inti, '!=', 12], [:inti, '!=', 23], [:inti, '!=', 34]], [1, 44, 45, nil], :inti],
127
130
  [[[:data, '<', 'qux']], ['one', 'forty4', 'forty5'], :data],
128
131
  [[[:data, '<=', 'one']], ['one', 'forty4', 'forty5'], :data],
129
132
  [[[:data, '>=', 'thirty4']], ['twelve', 'twenty3', 'thirty4'], :data],
@@ -144,6 +147,17 @@ shared_examples_for 'Datastore' do
144
147
  end
145
148
 
146
149
  context 'sorts' do
150
+ before :each do
151
+ api.save_many([
152
+ {:kind => 'testing', :inti => 1, :data => 'one' },
153
+ {:kind => 'testing', :inti => 12, :data => 'twelve' },
154
+ {:kind => 'testing', :inti => 23, :data => 'twenty3'},
155
+ {:kind => 'testing', :inti => 34, :data => 'thirty4'},
156
+ {:kind => 'testing', :inti => 45, :data => 'forty5' },
157
+ {:kind => 'testing', :inti => 1, :data => 'the one'},
158
+ {:kind => 'testing', :inti => 44, :data => 'forty4' },
159
+ ])
160
+ end
147
161
 
148
162
  [
149
163
  [[[:inti, :asc]], [1, 1, 12, 23, 34, 44, 45], :inti],
@@ -163,6 +177,18 @@ shared_examples_for 'Datastore' do
163
177
  end
164
178
 
165
179
  context 'limit and offset' do
180
+ before :each do
181
+ api.save_many([
182
+ {:kind => 'testing', :inti => 1, :data => 'one' },
183
+ {:kind => 'testing', :inti => 12, :data => 'twelve' },
184
+ {:kind => 'testing', :inti => 23, :data => 'twenty3'},
185
+ {:kind => 'testing', :inti => 34, :data => 'thirty4'},
186
+ {:kind => 'testing', :inti => 45, :data => 'forty5' },
187
+ {:kind => 'testing', :inti => 1, :data => 'the one'},
188
+ {:kind => 'testing', :inti => 44, :data => 'forty4' },
189
+ ])
190
+ end
191
+
166
192
  specify 'offset n returns results starting at the nth record' do
167
193
  found_records = api.find_by_kind('testing', :sorts => [[:inti, :asc]], :offset => 2)
168
194
  ints = found_records.map {|record| record[:inti]}
@@ -196,8 +222,9 @@ shared_examples_for 'Datastore' do
196
222
 
197
223
  before :each do
198
224
  api.save_many([
199
- {:kind => 'testing', :inti => 1, :data => 'one' },
200
- {:kind => 'testing', :inti => 12, :data => 'twelve' }
225
+ {:kind => 'testing', :inti => 1, :data => 'one' },
226
+ {:kind => 'testing', :inti => 12, :data => 'twelve' },
227
+ {:kind => 'testing', :inti => nil, :data => 'twelve' }
201
228
  ])
202
229
  end
203
230
 
@@ -212,16 +239,19 @@ shared_examples_for 'Datastore' do
212
239
 
213
240
  [
214
241
  [[], []],
215
- [[[:inti, '=', 1]], [12]],
216
- [[[:data, '=', 'one']], [12]],
242
+ [[[:inti, '=', 1]], [12, nil]],
243
+ [[[:data, '=', 'one']], [12, nil]],
217
244
  [[[:inti, '!=', 1]], [1]],
218
- [[[:inti, '<=', 1]], [12]],
219
- [[[:inti, '<=', 2]], [12]],
220
- [[[:inti, '>=', 2]], [1]],
221
- [[[:inti, '>', 1]], [1]],
222
- [[[:inti, 'in', [1]]], [12]],
223
- [[[:inti, 'in', [1, 12]]], []],
224
- [[[:inti, '=', 2]], [1, 12]]
245
+ [[[:inti, '<=', 1]], [12, nil]],
246
+ [[[:inti, '<=', 2]], [12, nil]],
247
+ [[[:inti, '>=', 2]], [1, nil]],
248
+ [[[:inti, '>', 1]], [1, nil]],
249
+ [[[:inti, 'in', [1]]], [12, nil]],
250
+ [[[:inti, 'in', [1, nil]]], [12]],
251
+ [[[:inti, 'in', [1, 12]]], [nil]],
252
+ [[[:inti, '=', 2]], [1, 12, nil]],
253
+ [[[:inti, '=', nil]], [1, 12]],
254
+ [[[:inti, '!=', nil]], [nil]],
225
255
  ].each do |filters, result|
226
256
  it filters.inspect do
227
257
  api.delete_by_kind('testing', :filters => filters)
@@ -237,25 +267,28 @@ shared_examples_for 'Datastore' do
237
267
 
238
268
  before :each do
239
269
  api.save_many([
240
- {:kind => 'testing', :inti => 1, :data => 'one' },
241
- {:kind => 'testing', :inti => 12, :data => 'twelve' }
270
+ {:kind => 'testing', :inti => 1, :data => 'one' },
271
+ {:kind => 'testing', :inti => 12, :data => 'twelve' },
272
+ {:kind => 'testing', :inti => nil, :data => 'twelve' }
242
273
  ])
243
274
  end
244
275
 
245
276
  context 'filters' do
246
277
 
247
278
  [
248
- [[], 2],
279
+ [[], 3],
249
280
  [[[:inti, '=', 1]], 1],
250
281
  [[[:data, '=', 'one']], 1],
251
- [[[:inti, '!=', 1]], 1],
282
+ [[[:inti, '!=', 1]], 2],
252
283
  [[[:inti, '<=', 1]], 1],
253
284
  [[[:inti, '<=', 2]], 1],
254
285
  [[[:inti, '>=', 2]], 1],
255
286
  [[[:inti, '>', 1]], 1],
256
287
  [[[:inti, 'in', [1]]], 1],
257
288
  [[[:inti, 'in', [1, 12]]], 2],
258
- [[[:inti, '=', 2]], 0]
289
+ [[[:inti, '=', 2]], 0],
290
+ [[[:inti, '=', nil]], 1],
291
+ [[[:inti, '!=', nil]], 2],
259
292
  ].each do |filters, result|
260
293
  it filters.inspect do
261
294
  api.count_by_kind('testing', :filters => filters).should == result
@@ -266,7 +299,7 @@ shared_examples_for 'Datastore' do
266
299
  end
267
300
 
268
301
  Hyperion.defentity(:shirt) do |kind|
269
- kind.field(:account_key, :type => Hyperion::Types.foreign_key(:account))
302
+ kind.field(:account_key, :type => Hyperion::Types.foreign_key(:account), :db_name => :account_id)
270
303
  end
271
304
 
272
305
  Hyperion.defentity(:account) do |kind|
@@ -292,5 +325,19 @@ shared_examples_for 'Datastore' do
292
325
  found_shirts = api.find_by_kind(:shirt, :filters => [[:account_key, '=', account_key]])
293
326
  found_shirts[0].should == shirt
294
327
  end
328
+
329
+ it 'unpacks nil foreign keys' do
330
+ shirt = api.save(:kind => :shirt, :account_key => nil)
331
+ shirt[:account_key].should be_nil
332
+ found_shirt = api.find_by_kind(:shirt, :filters => [[:account_key, '=', nil]]).first
333
+ found_shirt[:account_key].should be_nil
334
+ end
335
+
336
+ it 'filters on nil foreign key' do
337
+ account = api.save(:kind => :account)
338
+ shirt = api.save(:kind => :shirt, :account_key => account[:key])
339
+ nil_shirt = api.save(:kind => :shirt, :account_key => nil)
340
+ api.find_by_kind(:shirt, :filters => [[:account_key, '=', nil]]).should == [nil_shirt]
341
+ end
295
342
  end
296
343
  end
@@ -10,12 +10,12 @@ module Hyperion
10
10
  end
11
11
 
12
12
  def format_field(field)
13
- Util.snake_case(field.to_s).to_sym
13
+ field.to_sym
14
14
  end
15
15
 
16
16
  def format_record(record)
17
17
  record = record.reduce({}) do |new_record, (field_name, value)|
18
- new_record[Util.snake_case(field_name.to_s).to_sym] = value
18
+ new_record[format_field(field_name)] = value
19
19
  new_record
20
20
  end
21
21
  record[:kind] = format_kind(record[:kind])
@@ -15,11 +15,12 @@ module Hyperion
15
15
 
16
16
  def compose_key(kind, id=nil)
17
17
  _id = id.nil? || id.to_s.strip == "" ? generate_id : id.to_s
18
- encode_key("#{encode_key(kind.to_s)}:#{encode_key(_id)}")
18
+ encode_key("#{encode_key(kind.to_s)}:#{_id}")
19
19
  end
20
20
 
21
21
  def decompose_key(key)
22
- decode_key(key).split(/:/).map {|part| decode_key(part)}
22
+ kind, sep, id = decode_key(key).partition(/:/)
23
+ [decode_key(kind), id]
23
24
  end
24
25
 
25
26
  def generate_id
@@ -71,10 +71,10 @@ module Hyperion
71
71
  filters.all? do |filter|
72
72
  value = record[filter.field]
73
73
  case filter.operator
74
- when '<'; value < filter.value
75
- when '<='; value <= filter.value
76
- when '>'; value > filter.value
77
- when '>='; value >= filter.value
74
+ when '<'; value && value < filter.value
75
+ when '<='; value && value <= filter.value
76
+ when '>'; value && value > filter.value
77
+ when '>='; value && value >= filter.value
78
78
  when '='; value == filter.value
79
79
  when '!='; value != filter.value
80
80
  when 'contains?'; filter.value.include?(value)
@@ -36,9 +36,9 @@ describe Hyperion::Key do
36
36
  Hyperion::Key.compose_key(:foo, 1).should == Hyperion::Key.compose_key(:foo, 1)
37
37
  end
38
38
 
39
- it 'composes and decomposes' do
40
- kind = "testing"
41
- id = "BLODQF0Z1DMEfQr7S3eBwfsX4ku"
39
+ it 'composes and decomposes a large id' do
40
+ kind = 'testing'
41
+ id = 'BLODQF0Z1DMEfQr7S3eBwfsX4ku'
42
42
  key = Hyperion::Key.compose_key(kind, id)
43
43
  Hyperion::Key.decompose_key(key).should == [kind, id]
44
44
  end
@@ -53,4 +53,9 @@ describe Hyperion::Key do
53
53
  Hyperion::Key.decompose_key(key).should == ['thing', 'my:key']
54
54
  end
55
55
 
56
+ it 'decomposes kinds with a :' do
57
+ key = Hyperion::Key.compose_key("thing:one", 'key')
58
+ Hyperion::Key.decompose_key(key).should == ['thing:one', 'key']
59
+ end
60
+
56
61
  end
@@ -17,12 +17,12 @@ shared_examples_for 'field formatting' do |actor|
17
17
 
18
18
  {
19
19
  'field' => :field,
20
- 'Field' => :field,
21
- 'FieldOne' => :field_one,
22
- 'SomeBigAttr' => :some_big_attr,
23
- :SomeBigAttr => :some_big_attr,
24
- 'one-two-three' => :one_two_three,
25
- 'one two three' => :one_two_three
20
+ 'Field' => :Field,
21
+ 'FieldOne' => :FieldOne,
22
+ 'SomeBigAttr' => :SomeBigAttr,
23
+ :SomeBigAttr => :SomeBigAttr,
24
+ 'one-two-three' => :'one-two-three',
25
+ 'one two three' => :'one two three'
26
26
  }.each_pair do |field, result|
27
27
 
28
28
  it "#{field.inspect} to #{result.inspect}" do
@@ -134,16 +134,24 @@ shared_examples_for 'record packing' do |actor|
134
134
  it 'prefers the custom packer over the type packer' do
135
135
  result = actor.call(:kind => :packable, :two_packer => 'thing')
136
136
  result[:two_packer].should == 'gniht'
137
+ end
137
138
 
138
- Hyperion.defentity(:keyed) do |kind|
139
- kind.field(:widget, :type => Integer)
140
- kind.field(:downed, :type => :down)
141
- kind.field(:thing, :type => :nested_type)
142
- kind.field(:bauble, :packer => lambda {|value| value ? value.reverse : value})
143
- kind.field(:bad_packer, :packer => true)
144
- kind.field(:two_packer, :type => Integer, :packer => lambda {|value| value ? value.reverse : value})
139
+ Hyperion.defentity(:pack_field_alias) do |kind|
140
+ kind.field(:widget, :db_name => :field1)
141
+ kind.field(:widget1, :db_name => "field2")
142
+ end
143
+
144
+ it 'packs field aliases' do
145
+ result = actor.call(:kind => :pack_field_alias, :widget => 'ABC')
146
+ result.should_not have_key(:widget)
147
+ result[:field1].should == 'ABC'
148
+ end
149
+
150
+ it 'packs field aliases as a string' do
151
+ result = actor.call(:kind => :pack_field_alias, :widget1 => 'ABC')
152
+ result.should_not have_key(:widget1)
153
+ result[:field2].should == 'ABC'
145
154
  end
146
- end
147
155
 
148
156
  context 'Timestamps' do
149
157
 
@@ -248,6 +256,24 @@ shared_examples_for 'record unpacking' do |actor|
248
256
  result = actor.call(:kind => :unpackable, :two_packer => 'thing')
249
257
  result[:two_packer].should == 'gniht'
250
258
  end
259
+
260
+ Hyperion.defentity(:unpack_field_alias) do |kind|
261
+ kind.field(:widget, :db_name => :field1)
262
+ kind.field(:widget1, :db_name => "field2")
263
+ end
264
+
265
+ it 'unpacks field aliases' do
266
+ result = actor.call(:kind => :pack_field_alias, :field1 => 'ABC')
267
+ result.should_not have_key(:field1)
268
+ result[:widget].should == 'ABC'
269
+ end
270
+
271
+ it 'unpacks field aliases as a string' do
272
+ result = actor.call(:kind => :pack_field_alias, 'field2' => 'ABC')
273
+ result.should_not have_key(:field2)
274
+ result.should_not have_key('field2')
275
+ result[:widget1].should == 'ABC'
276
+ end
251
277
  end
252
278
 
253
279
  shared_examples_for 'filtering' do |actor|
@@ -256,6 +282,11 @@ shared_examples_for 'filtering' do |actor|
256
282
  include_examples 'field formatting', lambda { |field|
257
283
  actor.call([field, '=', 0]).field
258
284
  }
285
+
286
+ it 'packs db_name aliases' do
287
+ result = actor.call([:test2, '=', 0])
288
+ result.field.should == :_test2
289
+ end
259
290
  end
260
291
 
261
292
  context 'operator' do
@@ -10,6 +10,7 @@ describe Hyperion do
10
10
 
11
11
  Hyperion.defentity(:filtering) do |kind|
12
12
  kind.field(:test, :packer => lambda { |value| 'i was packed' })
13
+ kind.field(:test2, :db_name => :_test2)
13
14
  end
14
15
 
15
16
  context 'datastore' do
@@ -172,6 +173,12 @@ describe Hyperion do
172
173
  Hyperion.find_by_kind('kind', :sorts => [[field, 'desc']])
173
174
  Hyperion.datastore.queries.first.sorts.first.field
174
175
  }
176
+
177
+ it 'packs db_name aliases' do
178
+ api.find_by_kind('filtering', :sorts => [[:test2, 'desc']])
179
+ query = fake_ds.queries.last
180
+ query.sorts.first.field.should == :_test2
181
+ end
175
182
  end
176
183
 
177
184
  context 'order' do
@@ -259,42 +266,50 @@ describe Hyperion do
259
266
  Hyperion.find_by_key('key')
260
267
  }
261
268
  end
262
-
263
269
  end
264
270
 
265
- Hyperion.defentity(:keyed) do |kind|
266
- kind.field(:spouse_key, :type => Hyperion::Types.foreign_key(:spouse))
267
- end
271
+ context 'foreign key type' do
268
272
 
269
- it 'returns the packer key' do
270
- Hyperion::Types.foreign_key(:spouse).should == :spouse_key
271
- end
273
+ Hyperion.defentity(:keyed) do |kind|
274
+ kind.field(:spouse_key, :type => Hyperion::Types.foreign_key(:spouse))
275
+ end
272
276
 
273
- it 'defines a packer for the given kind' do
274
- Hyperion.packer_defined?(:spouse_key)
275
- end
277
+ it 'returns the packer key' do
278
+ Hyperion::Types.foreign_key(:spouse).should == :spouse_key
279
+ end
276
280
 
277
- it 'defines an unpacker for the given kind' do
278
- Hyperion.unpacker_defined?(:spouse_key)
279
- end
281
+ it 'defines a packer for the given kind' do
282
+ Hyperion.packer_defined?(:spouse_key)
283
+ end
280
284
 
281
- it 'formats the kind' do
282
- Hyperion::Types.foreign_key(:SPouse).should == :spouse_key
283
- end
285
+ it 'defines an unpacker for the given kind' do
286
+ Hyperion.unpacker_defined?(:spouse_key)
287
+ end
284
288
 
285
- it 'asks the current datastore to pack the key' do
286
- key = 'the key to pack'
287
- Hyperion.save(:kind => :keyed, :spouse_key => key)
288
- fake_ds.key_pack_queries.first[:kind].should == :spouse
289
- fake_ds.key_pack_queries.first[:key].should == key
290
- end
289
+ it 'formats the kind' do
290
+ Hyperion::Types.foreign_key(:SPouse).should == :spouse_key
291
+ end
292
+
293
+ it 'asks the current datastore to pack the key' do
294
+ key = 'the key to pack'
295
+ Hyperion.save(:kind => :keyed, :spouse_key => key)
296
+ fake_ds.key_pack_queries.first[:kind].should == :spouse
297
+ fake_ds.key_pack_queries.first[:key].should == key
298
+ end
299
+
300
+ it 'handles packing nil' do
301
+ Hyperion.save(:kind => :keyed, :spouse_key => nil)
302
+ fake_ds.key_pack_queries.first[:key].should == nil
303
+ end
304
+
305
+ it 'asks the current datastore to unpack the key' do
306
+ key = 'the key to pack'
307
+ fake_ds.returns = [[{:kind => :keyed, :spouse_key => key}]]
308
+ Hyperion.save(:kind => :keyed)
309
+ fake_ds.key_unpack_queries.first[:kind].should == :spouse
310
+ fake_ds.key_unpack_queries.first[:key].should == key
311
+ end
291
312
 
292
- it 'asks the current datastore to unpack the key' do
293
- key = 'the key to pack'
294
- fake_ds.returns = [[{:kind => :keyed, :spouse_key => key}]]
295
- Hyperion.save(:kind => :keyed)
296
- fake_ds.key_unpack_queries.first[:kind].should == :spouse
297
- fake_ds.key_unpack_queries.first[:key].should == key
298
313
  end
299
314
  end
300
315
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyperion-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-01 00:00:00.000000000 Z
12
+ date: 2012-12-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec