hashmodel 0.3.1 → 0.4.0.beta1

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.
@@ -1,9 +1,9 @@
1
1
  class HashModel
2
2
  module VERSION # :nodoc:
3
3
  MAJOR = 0
4
- MINOR = 3
5
- TINY = 1
6
- PRE = nil
4
+ MINOR = 4
5
+ TINY = 0
6
+ PRE = "beta1"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
 
@@ -1,5 +1,5 @@
1
1
  $: << '.'
2
2
  require 'sourcify'
3
- require 'hash_model/hash_model'
3
+ require 'hash_model/version'
4
4
  require 'hash_model/exceptions'
5
- require 'hash_model/version'
5
+ require 'hash_model/hash_model'
@@ -1,10 +1,9 @@
1
1
  require "spec_helper"
2
2
 
3
- # WARNING!
4
- # The following test is valid ONLY if it is run by itself!
5
- # If a HashModel object has been instantiated before this test
6
- # the test will not properly verify that the dynamic methods are
7
- # recreated.
3
+ # IMPORTANT:
4
+ # The following test is valid ONLY if it is run first or by itself.
5
+ # If a HashModel object has been instantiated before this test the
6
+ # test will not properly verify that the dynamic methods are recreated.
8
7
 
9
8
  describe HashModel do
10
9
 
@@ -1,54 +1,6 @@
1
- require_relative '../spec_helper'
2
-
3
- # RSpec's change just does not work with arrays in tests because of how Ruby changes the data arrays point to
4
- # So we have to manually check before and after
1
+ require 'spec_helper'
5
2
 
6
- describe "HashModel" do
7
-
8
- before(:each) do
9
- @records = [
10
- {:switch => ["-x", "--xtended"], :parameter => {:type => String, :require => true}, :description => "Xish stuff"},
11
- {:switch => ["-y", "--why"], :description => "lucky what?"},
12
- {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
13
- ]
14
- @hm = HashModel.new(:raw_data=>@records)
15
-
16
- @records2 = [
17
- {:switch => ["-p", "--pea"], :parameter => {:type => Hash, :require => false}, :description => "Pea soup"},
18
- {:switch => ["-q", "--quit"], :description => "exit the game"},
19
- {:switch => "-r", :parameter => {:type => Fixnum}, :description => "Arrrrrrrrrrgh!"},
20
- ]
21
- @hm2 = HashModel.new(:raw_data=>@records2)
22
-
23
- @flat_records = [
24
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
25
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
26
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1}, {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1},
27
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2}
28
- ]
29
-
30
- @flat_records2 =[
31
- {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>0, :_group_id=>0},
32
- {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>1, :_group_id=>0},
33
- {:switch=>"-q", :description=>"exit the game", :_id=>2, :_group_id=>1},
34
- {:switch=>"--quit", :description=>"exit the game", :_id=>3, :_group_id=>1},
35
- {:switch=>"-r", :parameter=>{:type=>Fixnum}, :description=>"Arrrrrrrrrrgh!", :_id=>4, :_group_id=>2}
36
- ]
37
-
38
- @flat_records_all = [
39
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
40
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
41
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1},
42
- {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1},
43
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2},
44
- {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>5, :_group_id=>3},
45
- {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>6, :_group_id=>3},
46
- {:switch=>"-q", :description=>"exit the game", :_id=>7, :_group_id=>4},
47
- {:switch=>"--quit", :description=>"exit the game", :_id=>8, :_group_id=>4},
48
- {:switch=>"-r", :parameter=>{:type=>Fixnum}, :description=>"Arrrrrrrrrrgh!", :_id=>9, :_group_id=>5}
49
- ]
50
-
51
- end
3
+ describe HashModel do
52
4
 
53
5
  describe "general properties" do
54
6
 
@@ -94,339 +46,7 @@ describe "HashModel" do
94
46
 
95
47
  end # "general properties"
96
48
 
97
- describe "adding records" do
98
-
99
- it "should allow a hash of values to be added" do
100
- proc { @hm << {:switch => ["-x", "--xtended"], :description => "Xish stuff"} }.should_not raise_error
101
- end
102
-
103
- it "should allow a single hash to be added with :raw_data" do
104
- hash = {:switch => ["-x", "--xtended"], :description => "Xish stuff"}
105
- @hm = HashModel.new(:raw_data => hash)
106
- @hm.raw_data.should == [{:switch=>["-x", "--xtended"], :description=>"Xish stuff"}]
107
- end
108
-
109
- it "should allow a hash of values to be added using the keyword 'add'" do
110
- proc { @hm.add(:switch => ["-x", "--xtended"], :description => "Xish stuff") }.should_not raise_error
111
- end
112
-
113
- it "should allow an array of hashes to be added as if they were multiple records" do
114
- proc { @hm << @records }.should_not raise_error
115
- end
116
-
117
- it "should allow another HashModel to be added" do
118
- @hm.add(@hm2).should == @flat_records_all
119
- end
120
-
121
- it "should add a hash with a symbol as a value" do
122
- @hm = HashModel.new
123
- @hm << {:switch => :default}
124
- @hm.should == [{:switch=>:default, :_id=>0, :_group_id=>0}]
125
- end
126
-
127
- it "should add an array with mixed value types" do
128
- @records = [
129
- {:switch => ["-x", "--xtended", :default], :parameter => {:type => String, :require => true}, :description => "Xish stuff"},
130
- {:switch => ["-y", "--why"], :description => "lucky what?"},
131
- {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
132
- ]
133
- @hm = HashModel.new(:raw_data=>@records)
134
- @hm.should == [
135
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
136
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
137
- {:switch=>:default, :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>2, :_group_id=>0},
138
- {:switch=>"-y", :description=>"lucky what?", :_id=>3, :_group_id=>1},
139
- {:switch=>"--why", :description=>"lucky what?", :_id=>4, :_group_id=>1},
140
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>5, :_group_id=>2}
141
- ]
142
- end
143
-
144
- it "should add an array of arrays as values and not recurse into them" do
145
- @records = [
146
- { :switch => [ [5, 6], [1, 2] ] }
147
- ]
148
- @hm = HashModel.new(:raw_data=>@records)
149
- @hm.should == [{:switch=>[5, 6], :_id=>0, :_group_id=>0}, {:switch=>[1, 2], :_id=>1, :_group_id=>0}]
150
- end
151
-
152
- it "shouldn't recurse into arrays with hash values" do
153
- @records = [
154
- { :switch => [ [5, 6], [1, :blah=>2] ] }
155
- ]
156
- @hm = HashModel.new(:raw_data=>@records)
157
- @hm.should == [{:switch=>[5, 6], :_id=>0, :_group_id=>0}, {:switch=>[1, :blah=>2], :_id=>1, :_group_id=>0}]
158
- end
159
-
160
- it "should allow an array of HashModels to be added" do
161
- @hm.add([@hm, @hm2])
162
- @hm.should == [
163
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
164
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
165
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1},
166
- {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1},
167
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2},
168
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>5, :_group_id=>3},
169
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>6, :_group_id=>3},
170
- {:switch=>"-y", :description=>"lucky what?", :_id=>7, :_group_id=>4},
171
- {:switch=>"--why", :description=>"lucky what?", :_id=>8, :_group_id=>4},
172
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>9, :_group_id=>5},
173
- {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>10, :_group_id=>6},
174
- {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>11, :_group_id=>6},
175
- {:switch=>"-q", :description=>"exit the game", :_id=>12, :_group_id=>7},
176
- {:switch=>"--quit", :description=>"exit the game", :_id=>13, :_group_id=>7},
177
- {:switch=>"-r", :parameter=>{:type=>Fixnum}, :description=>"Arrrrrrrrrrgh!", :_id=>14, :_group_id=>8}
178
- ]
179
- end
180
-
181
- it "should allow field names that are longer versions of other names" do
182
- @hm = HashModel.new
183
- @hm << {:long => "short", :longer => "long"}
184
- @hm.should == [{:long => "short", :longer => "long"}]
185
- end
186
-
187
- it "should raise an error if something other than a hash, an array of hashes, or another HashModel (or an array of them) is added" do
188
- proc { @hm << ["-x", "--xtended", "Xish stuff"] }.should raise_error
189
- end
190
-
191
- it "should allow an array of hashes to be specified when creating the HashModel" do
192
- proc { HashModel.new(:raw_data=>@records) }.should_not raise_error
193
- end
194
-
195
- it "should retain the raw data used when creating the HashModel" do
196
- @hm.raw_data.should == @records
197
- end
198
-
199
- it "should return a HashModel object when adding records using <<" do
200
- (@hm << @records[0]).class.should == HashModel
201
- end
202
-
203
- it "should return the same HashModel instance when adding records using <<" do
204
- (@hm << @records[0]).object_id.should == @hm.object_id
205
- end
206
-
207
- it "should allow chaining of record adds using <<" do
208
- proc {@hm << @records[0] << @records[1] << @records[2]}.should_not raise_error
209
- end
210
-
211
- it "should contain all of the records when chaining record adds" do
212
- @hm << @records[0] << @records[1] << @records[2]
213
- @hm.raw_data.should == @records
214
- end
215
-
216
- context "flattened records" do
217
-
218
- it "should allow a flattened record to be added" do
219
- @hm = HashModel.new
220
- @hm << {:switch=>"-x", :parameter__type=>String, :parameter__require=>true, :description=>"Xish stuff"}
221
- @hm.raw_data.should == [{:switch => "-x", :parameter => {:type => String, :require => true}, :description => "Xish stuff"}]
222
- end
223
-
224
- it "should allow a flattened record to be added even with arrays in it" do
225
- @hm = HashModel.new
226
- @hm << {:switch=>["-x", "--xtend"],
227
- :parameter__type=>String,
228
- :parameter__require=>true,
229
- :description=>"Xish stuff",
230
- :field__field2 => {:field3 => "ff3", :field4 => "ff4"}
231
- }
232
- @hm.raw_data.should == [
233
- {
234
- :switch => ["-x", "--xtend"],
235
- :parameter => {:type => String, :require => true},
236
- :description => "Xish stuff",
237
- :field => {:field2 => {:field3 => "ff3", :field4 => "ff4"}}
238
- }
239
- ]
240
- end
241
-
242
- it "should allow deeply flattened record to be added" do
243
- deep_hash = {
244
- :parameter__type=>String,
245
- :switch__deep1__deep3 => "deepTwo",
246
- :parameter__type__ruby=>true,
247
- :parameter => "glorp",
248
- :parameter__require=>true,
249
- :switch__deep2 => "deepTwo",
250
- :description=>"Xish stuff",
251
- :switch => "--xtend",
252
- }
253
- @hm = HashModel.new
254
- @hm << deep_hash
255
- @hm.raw_data.should == [
256
- {
257
- :parameter => [
258
- {:type=>String},
259
- "glorp",
260
- {:require=>true}
261
- ],
262
- :switch => [
263
- {:deep1 => {:deep3=>"deepTwo"}},
264
- {:deep2=>"deepTwo"},
265
- "--xtend"
266
- ],
267
- :description=>"Xish stuff"
268
- }
269
- ]
270
- end
271
-
272
-
273
- end
274
-
275
- context "using the + sign" do
276
-
277
- it "should return a HashModel class when adding an Array" do
278
- (@hm + @records2).class.should == HashModel
279
- end
280
-
281
- it "should return a HashModel class when adding a HashModel" do
282
- (@hm + @hm2).class.should == HashModel
283
- end
284
-
285
- it "should return a different HashModel instance" do
286
- (@hm + @records2).object_id.should_not == @hm.object_id
287
- end
288
-
289
- it "should contain the records of both recordsets when adding an Array" do
290
- (@hm + @records2).raw_data.should == (@records + @records2)
291
- end
292
-
293
- it "should contain the records of both recordsets when adding a HashModel" do
294
- (@hm + @hm2).raw_data.should == (@records + @records2)
295
- end
296
-
297
- it "should use the flatten index of the receiver HashModel" do
298
- hm2 = HashModel.new
299
- hm2 << {:potato=>7}
300
- (@hm + hm2).flatten_index.should == :switch
301
- (hm2 + @hm).flatten_index.should == :potato
302
- end
303
-
304
- end # "when using the plus sign"
305
-
306
- context "using the += sign" do
307
-
308
- it "should return a HashModel class" do
309
- (@hm += @records2).class.should == HashModel
310
- end
311
-
312
- it "should return the same HashModel instance when using += to add an array" do
313
- (@hm += @records2).object_id.should == @hm.object_id
314
- end
315
-
316
- it "should contain the records of both recordsets when adding an Array" do
317
- @hm += @records2
318
- @hm.raw_data.should == (@records + @records2)
319
- end
320
-
321
- it "should contain the records of both recordsets when adding a HashModel" do
322
- @hm += @hm2
323
- @hm.raw_data.should == (@records + @records2)
324
- end
325
-
326
- it "should not alter the added HashModel" do
327
- proc{@hm += @hm2}.should_not change(@hm2, :raw_data)
328
- end
329
-
330
- end # "when using the += sign"
331
-
332
- context "using the * sign" do
333
-
334
- it "should return a HashRecord" do
335
- (@hm * 2).class.should == HashModel
336
- end
337
-
338
- it "should return a different HashRecord" do
339
- (@hm * 2).object_id.should_not == @hm.object_id
340
- end
341
-
342
- it "should return a HashModel with twice the amount of raw data if * 2'd" do
343
- (@hm * 2).raw_data.should == [
344
- {:switch=>["-x", "--xtended"], :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff"},
345
- {:switch=>["-y", "--why"], :description=>"lucky what?"},
346
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz"},
347
- {:switch=>["-x", "--xtended"], :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff"},
348
- {:switch=>["-y", "--why"], :description=>"lucky what?"},
349
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz"}
350
- ]
351
- end
352
-
353
- end
354
-
355
- context "using the *= sign" do
356
-
357
- it "should return the same HashModel" do
358
- (@hm *= 2).object_id.should == @hm.object_id
359
- end
360
-
361
- it "should change current raw to twice its old raw data if *= 2'd" do
362
- @hm *= 2
363
- @hm.should == [
364
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
365
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
366
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1},
367
- {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1},
368
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2},
369
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>5, :_group_id=>3},
370
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>6, :_group_id=>3},
371
- {:switch=>"-y", :description=>"lucky what?", :_id=>7, :_group_id=>4},
372
- {:switch=>"--why", :description=>"lucky what?", :_id=>8, :_group_id=>4},
373
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>9, :_group_id=>5}
374
- ]
375
- end
376
-
377
- end
378
-
379
- context "using concat" do
380
-
381
- it "should concatinate using a single Hash" do
382
- @hm.concat(@records2[0]).should == [
383
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
384
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
385
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1},
386
- {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1},
387
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2},
388
- {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>5, :_group_id=>3},
389
- {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>6, :_group_id=>3}
390
- ]
391
- end
392
-
393
- it "should concatinate using an array" do
394
- @hm.concat(@records2).should == @flat_records_all
395
- end
396
-
397
- it "should concatinate using a HashModel" do
398
- @hm.concat(@hm2).should == @flat_records_all
399
- end
400
-
401
- end
402
-
403
- context "using push" do
404
-
405
- it "should add a single Hash" do
406
- @hm.push(@records2[0]).should == [
407
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
408
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
409
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1},
410
- {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1},
411
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2},
412
- {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>5, :_group_id=>3},
413
- {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :_id=>6, :_group_id=>3}
414
- ]
415
- end
416
-
417
- it "should add an array" do
418
- @hm.push(@records2).should == @flat_records_all
419
- end
420
-
421
- it "should add a HashModel" do
422
- @hm.push(@hm2).should == @flat_records_all
423
- end
424
-
425
- end
426
-
427
- end # adding records
428
-
429
- describe "reserved field names" do
49
+ context "a reserved field name is used" do
430
50
 
431
51
  it "should raise an error if a protected field name is used" do
432
52
  proc { @hm << {:_id => 1} }.should raise_error(HashModel::ReservedNameError)
@@ -445,7 +65,7 @@ describe "HashModel" do
445
65
 
446
66
  end
447
67
 
448
- describe "using the [] sign" do
68
+ context "when using the [] sign" do
449
69
 
450
70
  it "should return flat records" do
451
71
  @hm.each_with_index do |record, index|
@@ -454,608 +74,5 @@ describe "HashModel" do
454
74
  end
455
75
 
456
76
  end
457
-
458
- describe "flattening behavior" do
459
-
460
- it "should set the first field given as the default flatten index" do
461
- @hm << {:switch => ["-x", "--xtended"], :description => "Xish stuff"}
462
- @hm.add(:description => "blah,blah,blah")
463
- @hm.flatten_index.should == :switch
464
- end
465
-
466
- it "should set the flatten index properly if specified using parameter :flatten_index" do
467
- @hm = HashModel.new(:raw_data=>@records, :flatten_index=>:parameter)
468
- @hm.should == [
469
- {:parameter=>{:type=>String}, :switch=>["-x", "--xtended"], :description=>"Xish stuff", :_id=>0, :_group_id=>0},
470
- {:parameter=>{:require=>true}, :switch=>["-x", "--xtended"], :description=>"Xish stuff", :_id=>1, :_group_id=>0},
471
- {:parameter=>nil, :switch=>["-y", "--why"], :description=>"lucky what?", :_id=>2, :_group_id=>1},
472
- {:parameter=>{:type=>String}, :switch=>"-z", :description=>"zee svitch zu moost calz", :_id=>3, :_group_id=>2}
473
- ]
474
-
475
- end
476
-
477
- it "should allow you to change the flatten index" do
478
- @hm << {:switch => ["-x", "--xtended"], :description => "Xish stuff"}
479
- proc do
480
- @hm.flatten_index = :description
481
- end.should change(@hm, :flatten_index).from(:switch).to(:description)
482
- end
483
-
484
- it "should throw an error if an invalid flatten index is given" do
485
- @records = [
486
- { :switch => [ [5, 6], [1, :blah=>2] ] }
487
- ]
488
- @hm = HashModel.new(:raw_data=>@records)
489
- proc {@hm.flatten_index = :switch__blah}.should raise_error(ArgumentError)
490
- end
491
-
492
- it "shouldn't throw an error if a valid flatten index is given" do
493
- proc {@hm.flatten_index = :parameter__type}.should_not raise_error
494
- end
495
-
496
- it "should reset the flatten index if an invalid flatten index is given" do
497
- @records = [
498
- { :switch => [ [5, 6], [1, :blah=>2] ] }
499
- ]
500
- @hm = HashModel.new(:raw_data=>@records)
501
- proc {@hm.flatten_index = :switch__blah}.should raise_error(ArgumentError)
502
- @hm.flatten_index.should == :switch
503
- end
504
-
505
- it "should set the flatten index when adding to an empty HashModel" do
506
- @hm.flatten_index.should == :switch
507
- end
508
-
509
- it "should assign the flattened data to self correctly when adding records using <<" do
510
- @hm = HashModel.new
511
- @hm << @records[0]
512
- @hm << @records[1]
513
- @hm << @records[2]
514
- @hm.should == @flat_records
515
- end
516
-
517
- it "should assign the flattened data to self correctly when adding with :raw_data=>records" do
518
- @hm.should == @flat_records
519
- end
520
-
521
- it "should add a nil value for the field index for records that don't have a field with the field index" do
522
- @hm = HashModel.new
523
- @hm << @records[0]
524
- @hm << {:foo=>"bar"}
525
- @hm.last.should == {:switch=>nil, :foo=>"bar", :_id=>2, :_group_id=>1}
526
- end
527
-
528
- it "should change the flattened data when changing the flatten index" do
529
- @hm = HashModel.new(:raw_data=>@records)
530
- @hm.flatten_index = :parameter__type
531
- @hm.should == [
532
- {:parameter__type=>String, :switch=>["-x", "--xtended"], :parameter__require=>true, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
533
- {:parameter__type=>nil, :switch=>["-y", "--why"], :description=>"lucky what?", :_id=>1, :_group_id=>1},
534
- {:parameter__type=>String, :switch=>"-z", :description=>"zee svitch zu moost calz", :_id=>2, :_group_id=>2}
535
- ]
536
- end
537
-
538
- it "should update the flattened data if the raw data is changed" do
539
- @hm.raw_data = @records2.clone
540
- @hm.should == @flat_records2
541
- end
542
-
543
- end # flattening behvior
544
-
545
- describe "unflattening behavior" do
546
-
547
- it "should allow access to the unflatten without an instance of HashModel" do
548
- deep_hash = {
549
- :parameter__type=>String,
550
- :switch__deep1__deep3 => "deepTwo",
551
- :parameter__type__ruby=>true,
552
- :parameter => "glorp",
553
- :parameter__require=>true,
554
- :switch__deep2 => "deepTwo",
555
- :description=>"Xish stuff",
556
- :switch => "--xtend",
557
- }
558
- HashModel.unflatten(deep_hash).should == {
559
- :parameter => [
560
- {:type=>String},
561
- "glorp",
562
- {:require=>true}
563
- ],
564
- :switch => [
565
- {:deep1 => {:deep3=>"deepTwo"}},
566
- {:deep2=>"deepTwo"},
567
- "--xtend"
568
- ],
569
- :description=>"Xish stuff"
570
- }
571
- end
572
-
573
- end
574
-
575
- describe "comparisons" do
576
-
577
- it "should allow arrays to be compared to the HashModel" do
578
- @hm.should == @flat_records
579
- end
580
-
581
- it "should allow HashModels to be compared to the HashModel" do
582
- hm2 = HashModel.new(:raw_data=>@records)
583
- @hm.should == hm2
584
- end
585
-
586
- it "should compare using the raw data if sent an array without group_id's or id's" do
587
- @hm.should == @records
588
- end
589
-
590
- it "should return false if compared to something other than an Array or a HashModel" do
591
- @hm.should_not == "potato"
592
- end
593
-
594
- it "should allow arrays to be compared to the HashModel using eql?" do
595
- @hm.eql?(@hm).should == true
596
- end
597
-
598
- it "should return false if compared to an array of something other than hashes" do
599
- @hm.should_not == ["potato"]
600
- end
601
-
602
- it "should use flattened records if <=>'d with an array with a group_id" do
603
- (@hm <=> @flat_records).should == 0
604
- end
605
-
606
- it "should use flattened records if <=>'d with an array without a group_id" do
607
- (@hm <=> @records).should == 0
608
- end
609
-
610
- it "should use flattened data if <=>'d with another HashModel" do
611
- hm2 = @hm.clone
612
- (@hm <=> hm2).should == 0
613
- end
614
-
615
- it "should return nil if <=>'d with something other than an Array or a HashModel" do
616
- (@hm <=> "potato").should == nil
617
- end
618
-
619
- it "should compare to an empty array" do
620
- @hm.where!("potato")
621
- @hm.should == []
622
- end
623
-
624
- end # comparisons
625
-
626
- describe "searching and selecting records" do
627
-
628
- context "in place" do
629
-
630
- it "should accept a parameter as input" do
631
- proc{@hm.where!("-x")}.should_not raise_error
632
- end
633
-
634
- it "should raise an error if a block and a parameter are given" do
635
- proc{@hm.where!("-x"){@switch == "-x"}}.should raise_error
636
- end
637
-
638
- it "should return a HashModel when searching" do
639
- @hm.where!("-x").class.should == HashModel
640
- end
641
-
642
- it "should return the same hash model when calling where" do
643
- @hm.where!("-x").object_id.should == @hm.object_id
644
- end
645
-
646
- it "should return the entire flattened recordset if nothing is sent" do
647
- @hm.where!("-x")
648
- @hm.should == [@flat_records[0]]
649
- @hm.where!
650
- @hm.should == @flat_records
651
- end
652
-
653
- end
654
-
655
- context "non-string search values" do
656
-
657
- it "should search using the flatten_index if a symbol is used with where" do
658
- @records = [
659
- {:switch => ["-x", "--xtended", :default], :parameter => {:type => String, :require => true}, :description => "Xish stuff"},
660
- {:switch => ["-y", "--why"], :description => "lucky what?"},
661
- {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
662
- ]
663
- @hm = HashModel.new(:raw_data=>@records)
664
- @hm.where(:default).should == [{:switch=>:default, :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>2, :_group_id=>0}]
665
- end
666
-
667
- it "should search using an array" do
668
- @records = [
669
- { :switch => [ [5,6], [1,2] ] }
670
- ]
671
- @hm = HashModel.new(:raw_data=>@records)
672
- @hm.where([1,2]).should == [{:switch=>[1,2], :_id=>1, :_group_id=>0}]
673
- end
674
-
675
- it "should search using an array including a hash" do
676
- @records = [
677
- { :switch => [ [5,6], [1,:blah=>2] ] }
678
- ]
679
- @hm = HashModel.new(:raw_data=>@records)
680
- @hm.where([1,:blah=>2]).should == [{:switch=>[1,:blah=>2], :_id=>1, :_group_id=>0}]
681
- end
682
-
683
- end
684
-
685
- context "filtering records" do
686
-
687
- it "should filter the recordset" do
688
- @hm.where!("-x")
689
- @hm.should == [@flat_records[0]]
690
- end
691
-
692
- it "should tell you if it is filtering records" do
693
- @hm.where!("-x")
694
- @hm.filtered?.should == true
695
- end
696
-
697
- it "should let you clear the filter" do
698
- @hm.where!("-x")
699
- proc {@hm.clear_filter}.should change(@hm, :filtered?).from(true).to(false)
700
- end
701
-
702
- it "should show all the records when the filter is cleared" do
703
- @hm.where!("-x")
704
- @hm.clear_filter
705
- @hm.should == @flat_records
706
- end
707
-
708
- it "should clear the filter if nothing is sent" do
709
- @hm.where!("-x")
710
- proc {@hm.where!}.should change(@hm, :filtered?).from(true).to(false)
711
- end
712
-
713
- end # filtering
714
-
715
- context "not in place" do
716
-
717
- it "should return a HashModel object" do
718
- @hm = HashModel.new(:raw_data=>@records)
719
- @hm.where("-x").class.should == HashModel
720
- end
721
-
722
- it "should return a new HashModel" do
723
- @hm.where("-x").object_id.should_not == @hm.object_id
724
- end
725
-
726
- it "should search the flatten index if given a parameter" do
727
- @hm = HashModel.new(:raw_data=>@records)
728
- @hm.where("-x").should == [@flat_records[0]]
729
- end
730
-
731
- it "should search the flatten index if given a block" do
732
- @hm = HashModel.new(:raw_data=>@records)
733
- @hm.where{@parameter__type == String}.should == [
734
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
735
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
736
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2}
737
- ]
738
- end
739
-
740
- end # not in place
741
-
742
- context "using blocks" do
743
-
744
- it "should search using a single value boolean block" do
745
- @hm.where {:switch == "-x"}.should == [@flat_records[0]]
746
- end
747
-
748
- it "should search using a complex boolean block" do
749
- records = [
750
- {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
751
- {:switch => ["-y", "--why"], :description => "lucky what?"},
752
- {:switch => "-z", :parameter => {:type => String, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
753
- ]
754
- @hm = HashModel.new(:raw_data=>records)
755
- @hm.where {:something == 4 && :parameter__required == true}.should == [
756
- {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
757
- {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
758
- {:switch=>"-z", :parameter=>{:type=>String, :required=>true}, :description=>"zee svitch zu moost calz", :something=>4, :_id=>4, :_group_id=>2}
759
- ]
760
- @hm.where {:parameter__type == String && :parameter__required == true && :something == 4}.should == [
761
- {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
762
- {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
763
- {:switch=>"-z", :parameter=>{:type=>String, :required=>true}, :description=>"zee svitch zu moost calz", :something=>4, :_id=>4, :_group_id=>2}
764
- ]
765
- end
766
-
767
- it "should search using a complex, multi-line boolean block" do
768
- records = [
769
- {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
770
- {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
771
- {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
772
- ]
773
- @hm = HashModel.new(:raw_data=>records)
774
- @hm.where {(:parameter__type == String && :parameter__required == true && :something == 4) || :something == 7}.should == [
775
- {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
776
- {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
777
- {:switch=>"-y", :description=>"lucky what?", :something=>7, :_id=>2, :_group_id=>1},
778
- {:switch=>"--why", :description=>"lucky what?", :something=>7, :_id=>3, :_group_id=>1}
779
- ]
780
- end
781
-
782
- it "should search with nested hashes in a block" do
783
- records = [
784
- {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
785
- {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
786
- {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
787
- ]
788
- @hm = HashModel.new(:raw_data=>records)
789
- @hm.where {:parameter == {:type => String, :required => true}}.should == [
790
- {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
791
- {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0}
792
- ]
793
- end
794
-
795
- end
796
-
797
- it "should return false if tested for inclusion of anything other than a hash" do
798
- @hm.include?([:switch=>"-x"]).should == false
799
- end
800
-
801
- it "should match flat data if search criteria includes an _group_id field" do
802
- @hm.include?(@flat_records[2]).should == true
803
- end
804
-
805
- it "should search raw data if search criteria includes an _group_id field" do
806
- @hm.include?(@records[2]).should == true
807
- end
808
-
809
- it "should return the flattened record index using the index method" do
810
- @hm.index(@flat_records[3]).should == 3
811
- end
812
-
813
- context "when using take" do
814
- it "should return the first n flat records" do
815
- @hm.take(2).should == @flat_records.take(2)
816
- end
817
-
818
- it "should return the first n flat records while block is true" do
819
- @hm.take_while {|record| record[:_id] < 4}.should == @flat_records[0..3]
820
- end
821
-
822
- end
823
-
824
- it "should return values at x,y,z" do
825
- @hm.values_at(1,3,5).should == @flat_records.values_at(1,3,5)
826
- end
827
-
828
- it "should zip things" do
829
- hm2 = HashModel.new(:raw_data=>@records2)
830
- @hm.zip(hm2).should == @flat_records.zip(@flat_records2)
831
- end
832
-
833
- end # searching records
834
-
835
- describe "grouping" do
836
-
837
- context "not in place" do
838
-
839
- it "should return a HashModel object" do
840
- @hm.group("-x").class.should == HashModel
841
- end
842
-
843
- it "should return a different HashModel object" do
844
- @hm.group("-x").object_id.should_not == @hm.object_id
845
- end
846
-
847
- it "should return the records in the same raw data record when using a parameter" do
848
- @hm.group("-x").should == [@flat_records[0], @flat_records[1]]
849
- end
850
-
851
- it "should be chainable on a filtered HashModel" do
852
- @hm.where("-x").group.should == [@flat_records[0],@flat_records[1]]
853
- end
854
-
855
- it "should return the records in the same raw data record when using a block" do
856
- @hm.group{:switch == "-y"}.should == [@flat_records[2], @flat_records[3]]
857
- end
858
-
859
- it "should group across group_id's if searching for something that returns records from multiple groups" do
860
- @hm.group{:parameter__type == String}.should == [
861
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
862
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
863
- {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz", :_id=>4, :_group_id=>2}
864
- ]
865
- end
866
-
867
- it "should group with a complex block" do
868
- records = [
869
- {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
870
- {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
871
- {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
872
- ]
873
- @hm = HashModel.new(:raw_data=>records)
874
- @hm.group {(:parameter__type == String && :parameter__required == true && :something == 4) || :something == 7}.should == [
875
- {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
876
- {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
877
- {:switch=>"-y", :description=>"lucky what?", :something=>7, :_id=>2, :_group_id=>1},
878
- {:switch=>"--why", :description=>"lucky what?", :something=>7, :_id=>3, :_group_id=>1}
879
- ]
880
- end
881
-
882
- it "should group with nested hashes block" do
883
- records = [
884
- {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
885
- {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
886
- {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
887
- ]
888
- @hm = HashModel.new(:raw_data=>records)
889
- @hm.group {:parameter == {:type => String, :required => true}}.should == [
890
- {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
891
- {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0}
892
- ]
893
- end
894
-
895
- end # not in place
896
-
897
- context "in place" do
898
-
899
- it "should return the same HashModel object" do
900
- @hm.group!("-x").object_id.should == @hm.object_id
901
- end
902
-
903
- it "should return the records in the same raw data record when using a parameter" do
904
- @hm.group!("-x").should == [@flat_records[0],@flat_records[1]]
905
- end
906
-
907
- it "should be chainable on a filtered HashModel" do
908
- @hm.where("-x").group!.should == [@flat_records[0],@flat_records[1]]
909
- end
910
-
911
- it "should be chainable on an in-place filtered HashModel" do
912
- @hm.where!("-x").group!.should == [@flat_records[0],@flat_records[1]]
913
- end
914
-
915
- it "should return the records in the same raw data record when using a block" do
916
- @hm.group!{@switch == "-y"}.should == [
917
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1},
918
- {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1}
919
- ]
920
- end
921
-
922
- it "should work across group_id's if searching for something that returns records from multiple groups" do
923
- @hm.group!{@parameter__type == String}.should == [
924
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
925
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
926
- {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz", :_id=>4, :_group_id=>2}
927
- ]
928
- end
929
-
930
- end
931
-
932
- end # grouping
933
-
934
- describe "miscellaneous array methods and properties" do
935
-
936
- it "should return an array when calling to_ary" do
937
- @hm.to_ary.class.should == Array
938
- end
939
-
940
- it "should not return a HashModel when calling to_ary" do
941
- @hm.to_ary.class.should_not == HashModel
942
- end
943
-
944
- it "should return the flat records when calling to_ary" do
945
- @hm.to_ary.should == @flat_records
946
- end
947
-
948
- it "should return an array when calling to_a" do
949
- @hm.to_a.class.should == Array
950
- end
951
-
952
- it "should not return a HashModel when calling to_a" do
953
- @hm.to_a.class.should_not == HashModel
954
- end
955
-
956
- it "should return the flat records when calling to_a" do
957
- @hm.to_a.should == @flat_records
958
- end
959
-
960
- it "should report the length of the flat data" do
961
- @hm.length.should == @flat_records.length
962
- end
963
-
964
- it "should report the size of the flat data" do
965
- @hm.size.should == @flat_records.size
966
- end
967
-
968
- it "should return the correct flat record when using at" do
969
- @hm.at(0).should == @flat_records[0]
970
- @hm.at(2).should == @flat_records[2]
971
- end
972
-
973
- it "should collect across the flat data" do
974
- extra = -1
975
- @hm.collect {|record| record.merge!(:extra=>extra+=1)}.should == [
976
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0, :extra=>0},
977
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0, :extra=>1},
978
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1, :extra=>2},
979
- {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1, :extra=>3},
980
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2, :extra=>4}
981
- ]
982
- end
983
-
984
- it "should map across the flat data" do
985
- extra = -1
986
- @hm.map {|record| record.merge!(:extra=>extra+=1)}.should == [
987
- {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0, :extra=>0},
988
- {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0, :extra=>1},
989
- {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1, :extra=>2},
990
- {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1, :extra=>3},
991
- {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2, :extra=>4}
992
- ]
993
- end
994
-
995
- it "should combination'ize the flat data" do
996
- hm_combo = []
997
- flat_combo = []
998
- @hm.combination(2).each { |record| hm_combo << record }
999
- @flat_records.combination(2) { |record| flat_combo << record }
1000
- hm_combo.should == flat_combo
1001
- end
1002
-
1003
- it "should count the flat data" do
1004
- @hm.count.should == @flat_records.count
1005
- end
1006
-
1007
- it "should cycle over the flat data" do
1008
- cycle = cycle2 = []
1009
- @hm.cycle(2) {|record| cycle << record}
1010
- @flat_records.cycle(2) {|record| cycle2 << record}
1011
- cycle.should == cycle2
1012
- end
1013
-
1014
- it "should iterate with an index" do
1015
- collect = []
1016
- @hm.each_index {|index| collect << @hm[index][:switch]}
1017
- collect.should == ["-x", "--xtended", "-y", "--why", "-z"]
1018
- end
1019
-
1020
- it "should say if it's empty" do
1021
- @hm = HashModel.new
1022
- @hm.empty?.should == true
1023
- @hm << @records[0]
1024
- @hm.empty?.should == false
1025
- end
1026
-
1027
- it "should fetch records given an index" do
1028
- @hm.fetch(2).should == @flat_records[2]
1029
- end
1030
-
1031
- it "should return the default value if fetch index is out of bounds" do
1032
- @hm.fetch(10, "potato").should == "potato"
1033
- end
1034
-
1035
- it "should run a block if fetch index is out of bounds" do
1036
- (@hm.fetch(10) {|index| index }).should == 10
1037
- end
1038
-
1039
- it "should return the first flattened record" do
1040
- @hm.first.should == @flat_records.first
1041
- end
1042
-
1043
- it "should return the last flattened record" do
1044
- @hm.last.should == @flat_records.last
1045
- end
1046
-
1047
- it "should freeze the raw records" do
1048
- proc{@hm.freeze}.should change(@hm.raw_data,:frozen?)
1049
- .from(false)
1050
- .to(true)
1051
- end
1052
-
1053
- it "should permutate over the flat data" do
1054
- @hm.permutation(2).to_a.should == @flat_records.permutation(2).to_a
1055
- @hm.permutation.to_a.should == @flat_records.permutation.to_a
1056
- @hm.permutation.to_a.should_not == @records.permutation.to_a
1057
- end
1058
-
1059
- end
1060
77
 
1061
78
  end # describe "HashModel"