hashmodel 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ module MikBe
2
+ class HashModel
3
+ module VERSION # :nodoc:
4
+ MAJOR = 0
5
+ MINOR = 1
6
+ TINY = 1
7
+ PRE = nil
8
+
9
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
10
+
11
+ SUMMARY = "HashModel #{STRING}"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,774 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module MikBe
4
+
5
+ # RSpec's change just does not work with arrays in tests because of how Ruby changes the data arrays point to
6
+ # So we have to manually check before and after
7
+
8
+ describe "HashModel" do
9
+
10
+ before(:each) do
11
+ @records = [
12
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :require => true}, :description => "Xish stuff"},
13
+ {:switch => ["-y", "--why"], :description => "lucky what?"},
14
+ {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
15
+ ]
16
+ @hm = HashModel.new(:raw_data=>@records)
17
+
18
+ @records2 = [
19
+ {:switch => ["-p", "--pea"], :parameter => {:type => Hash, :require => false}, :description => "Pea soup"},
20
+ {:switch => ["-q", "--quit"], :description => "exit the game"},
21
+ {:switch => "-r", :parameter => {:type => Fixnum}, :description => "Arrrrrrrrrrgh!"},
22
+ ]
23
+ @hm2 = HashModel.new(:raw_data=>@records2)
24
+
25
+ @flat_records = [
26
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
27
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
28
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1}, {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1},
29
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2}
30
+ ]
31
+
32
+ @flat_records2 =[
33
+ {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>0, :hm_group_id=>0},
34
+ {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>1, :hm_group_id=>0},
35
+ {:switch=>"-q", :description=>"exit the game", :hm_id=>2, :hm_group_id=>1},
36
+ {:switch=>"--quit", :description=>"exit the game", :hm_id=>3, :hm_group_id=>1},
37
+ {:switch=>"-r", :parameter=>{:type=>Fixnum}, :description=>"Arrrrrrrrrrgh!", :hm_id=>4, :hm_group_id=>2}
38
+ ]
39
+
40
+ @flat_records_all = [
41
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
42
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
43
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1},
44
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1},
45
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2},
46
+ {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>5, :hm_group_id=>3},
47
+ {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>6, :hm_group_id=>3},
48
+ {:switch=>"-q", :description=>"exit the game", :hm_id=>7, :hm_group_id=>4},
49
+ {:switch=>"--quit", :description=>"exit the game", :hm_id=>8, :hm_group_id=>4},
50
+ {:switch=>"-r", :parameter=>{:type=>Fixnum}, :description=>"Arrrrrrrrrrgh!", :hm_id=>9, :hm_group_id=>5}
51
+ ]
52
+
53
+ end
54
+
55
+ describe "general properties" do
56
+
57
+ describe "raw data" do
58
+
59
+ it "should always allow access to the raw, unflattened records" do
60
+ @hm.should respond_to(:raw_data)
61
+ end
62
+
63
+ it "should have raw data equal to the data that is input" do
64
+ @hm.raw_data.should == @records
65
+ end
66
+
67
+ it "should clear the raw data when clear is called" do
68
+ @hm = HashModel.new
69
+ @hm << @records[0]
70
+ proc{@hm.clear}.should change(@hm, :raw_data)
71
+ .from([{:switch => ["-x", "--xtended"], :parameter => {:type => String, :require => true}, :description => "Xish stuff"}])
72
+ .to([])
73
+ end
74
+
75
+ it "should only allow arrays to be set as the raw data" do
76
+ proc {@hm.raw_data = "string"}.should raise_error
77
+ end
78
+
79
+ it "should allow arrays to be set as the raw data" do
80
+ proc {@hm.raw_data = [ { :switch => ["-x", "--xtended"] } ] }.should_not raise_error
81
+ end
82
+
83
+ it "should allow nil to be set as the raw data" do
84
+ proc {@hm.raw_data = nil }.should_not raise_error
85
+ end
86
+
87
+ end # "raw data"
88
+
89
+ end # "general properties"
90
+
91
+ describe "adding records" do
92
+
93
+ it "should allow a hash of values to be added" do
94
+ proc { @hm << {:switch => ["-x", "--xtended"], :description => "Xish stuff"} }.should_not raise_error
95
+ end
96
+
97
+ it "should allow a hash of values to be added using the keyword 'add'" do
98
+ proc { @hm.add(:switch => ["-x", "--xtended"], :description => "Xish stuff") }.should_not raise_error
99
+ end
100
+
101
+ it "should allow an array of hashes to be added as if they were multiple records" do
102
+ proc { @hm << @records }.should_not raise_error
103
+ end
104
+
105
+ it "should allow another HashModel to be added" do
106
+ @hm.add(@hm2).should == @flat_records_all
107
+ end
108
+
109
+ it "should allow an array of HashModels to be added" do
110
+ @hm.add([@hm, @hm2])
111
+ @hm.should == [
112
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
113
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
114
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1},
115
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1},
116
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2},
117
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>5, :hm_group_id=>3},
118
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>6, :hm_group_id=>3},
119
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>7, :hm_group_id=>4},
120
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>8, :hm_group_id=>4},
121
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>9, :hm_group_id=>5},
122
+ {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>10, :hm_group_id=>6},
123
+ {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>11, :hm_group_id=>6},
124
+ {:switch=>"-q", :description=>"exit the game", :hm_id=>12, :hm_group_id=>7},
125
+ {:switch=>"--quit", :description=>"exit the game", :hm_id=>13, :hm_group_id=>7},
126
+ {:switch=>"-r", :parameter=>{:type=>Fixnum}, :description=>"Arrrrrrrrrrgh!", :hm_id=>14, :hm_group_id=>8}
127
+ ]
128
+ end
129
+
130
+ 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
131
+ proc { @hm << ["-x", "--xtended", "Xish stuff"] }.should raise_error
132
+ end
133
+
134
+ context "reserved field names" do
135
+
136
+ it "should raise an error if a protected field name is used" do
137
+ proc { @hm << {:hm_id => 1} }.should raise_error(MikBe::ReservedNameError)
138
+ proc { @hm << {:hm_group_id => 1} }.should raise_error(MikBe::ReservedNameError)
139
+ end
140
+
141
+ it "should raise an error if a reserved field name is used deep within the raw data" do
142
+ proc { @hm.raw_data = [{:switch => "--potato", :should_error=>[:hm_group_id => 1, :another => 2] }] }
143
+ .should raise_error(MikBe::ReservedNameError)
144
+ end
145
+
146
+ it "should raise an error if a reserved field name is used deep within the raw data" do
147
+ proc { @hm = HashModel.new(:raw_data=>[{:switch => "--potato", :should_error=>[:hm_group_id => 1, :another => 2] }] ) }
148
+ .should raise_error(MikBe::ReservedNameError)
149
+ end
150
+
151
+ end
152
+
153
+ it "should allow an array of hashes to be specified when creating the HashModel" do
154
+ proc { HashModel.new(:raw_data=>@records) }.should_not raise_error
155
+ end
156
+
157
+ it "should retain the raw data used when creating the HashModel" do
158
+ @hm.raw_data.should == @records
159
+ end
160
+
161
+ it "should return a HashModel object when adding records using <<" do
162
+ (@hm << @records[0]).class.should == HashModel
163
+ end
164
+
165
+ it "should return the same HashModel instance when adding records using <<" do
166
+ (@hm << @records[0]).object_id.should == @hm.object_id
167
+ end
168
+
169
+ it "should allow chaining of record adds using <<" do
170
+ proc {@hm << @records[0] << @records[1] << @records[2]}.should_not raise_error
171
+ end
172
+
173
+ it "should contain all of the records when chaining record adds" do
174
+ @hm << @records[0] << @records[1] << @records[2]
175
+ @hm.raw_data.should == @records
176
+ end
177
+
178
+ context "using the + sign" do
179
+
180
+ it "should return a HashModel class when adding an Array" do
181
+ (@hm + @records2).class.should == HashModel
182
+ end
183
+
184
+ it "should return a HashModel class when adding a HashModel" do
185
+ (@hm + @hm2).class.should == HashModel
186
+ end
187
+
188
+ it "should return a different HashModel instance" do
189
+ (@hm + @records2).object_id.should_not == @hm.object_id
190
+ end
191
+
192
+ it "should contain the records of both recordsets when adding an Array" do
193
+ (@hm + @records2).raw_data.should == (@records + @records2)
194
+ end
195
+
196
+ it "should contain the records of both recordsets when adding a HashModel" do
197
+ (@hm + @hm2).raw_data.should == (@records + @records2)
198
+ end
199
+
200
+ it "should use the flatten index of the receiver HashModel" do
201
+ hm2 = HashModel.new
202
+ hm2 << {:potato=>7}
203
+ (@hm + hm2).flatten_index.should == :switch
204
+ (hm2 + @hm).flatten_index.should == :potato
205
+ end
206
+
207
+ end # "when using the plus sign"
208
+
209
+ context "using the += sign" do
210
+
211
+ it "should return a HashModel class" do
212
+ (@hm += @records2).class.should == HashModel
213
+ end
214
+
215
+ it "should return the same HashModel instance when using += to add an array" do
216
+ (@hm += @records2).object_id.should == @hm.object_id
217
+ end
218
+
219
+ it "should contain the records of both recordsets when adding an Array" do
220
+ @hm += @records2
221
+ @hm.raw_data.should == (@records + @records2)
222
+ end
223
+
224
+ it "should contain the records of both recordsets when adding a HashModel" do
225
+ @hm += @hm2
226
+ @hm.raw_data.should == (@records + @records2)
227
+ end
228
+
229
+ it "should not alter the added HashModel" do
230
+ proc{@hm += @hm2}.should_not change(@hm2, :raw_data)
231
+ end
232
+
233
+ end # "when using the += sign"
234
+
235
+ context "using the * sign" do
236
+
237
+ it "should return a HashRecord" do
238
+ (@hm * 2).class.should == HashModel
239
+ end
240
+
241
+ it "should return a different HashRecord" do
242
+ (@hm * 2).object_id.should_not == @hm.object_id
243
+ end
244
+
245
+ it "should return a HashModel with twice the amount of raw data if * 2'd" do
246
+ (@hm * 2).raw_data.should == [
247
+ {:switch=>["-x", "--xtended"], :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff"},
248
+ {:switch=>["-y", "--why"], :description=>"lucky what?"},
249
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz"},
250
+ {:switch=>["-x", "--xtended"], :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff"},
251
+ {:switch=>["-y", "--why"], :description=>"lucky what?"},
252
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz"}
253
+ ]
254
+ end
255
+
256
+ end
257
+
258
+ context "using the *= sign" do
259
+
260
+ it "should return the same HashModel" do
261
+ (@hm *= 2).object_id.should == @hm.object_id
262
+ end
263
+
264
+ it "should change current raw to twice its old raw data if *= 2'd" do
265
+ @hm *= 2
266
+ @hm.should == [
267
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
268
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
269
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1},
270
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1},
271
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2},
272
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>5, :hm_group_id=>3},
273
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>6, :hm_group_id=>3},
274
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>7, :hm_group_id=>4},
275
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>8, :hm_group_id=>4},
276
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>9, :hm_group_id=>5}
277
+ ]
278
+ end
279
+
280
+ end
281
+
282
+ context "using concat" do
283
+
284
+ it "should concatinate using a single Hash" do
285
+ @hm.concat(@records2[0]).should == [
286
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
287
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
288
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1},
289
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1},
290
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2},
291
+ {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>5, :hm_group_id=>3},
292
+ {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>6, :hm_group_id=>3}
293
+ ]
294
+ end
295
+
296
+ it "should concatinate using an array" do
297
+ @hm.concat(@records2).should == @flat_records_all
298
+ end
299
+
300
+ it "should concatinate using a HashModel" do
301
+ @hm.concat(@hm2).should == @flat_records_all
302
+ end
303
+
304
+ end
305
+
306
+ context "using push" do
307
+
308
+ it "should add a single Hash" do
309
+ @hm.push(@records2[0]).should == [
310
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
311
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
312
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1},
313
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1},
314
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2},
315
+ {:switch=>"-p", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>5, :hm_group_id=>3},
316
+ {:switch=>"--pea", :parameter=>{:type=>Hash, :require=>false}, :description=>"Pea soup", :hm_id=>6, :hm_group_id=>3}
317
+ ]
318
+ end
319
+
320
+ it "should add an array" do
321
+ @hm.push(@records2).should == @flat_records_all
322
+ end
323
+
324
+ it "should add a HashModel" do
325
+ @hm.push(@hm2).should == @flat_records_all
326
+ end
327
+
328
+ end
329
+
330
+ end # adding records
331
+
332
+ describe "using the [] sign" do
333
+
334
+ it "should return flat records" do
335
+ @hm.each_with_index do |record, index|
336
+ record.should == @flat_records[index]
337
+ end
338
+ end
339
+
340
+ end
341
+
342
+ describe "flattening behavior" do
343
+
344
+ it "should set the first field given as the default flatten index" do
345
+ @hm << {:switch => ["-x", "--xtended"], :description => "Xish stuff"}
346
+ @hm.add(:description => "blah,blah,blah")
347
+ @hm.flatten_index.should == :switch
348
+ end
349
+
350
+ it "should set the flatten index properly if specified using parameter :flatten_index" do
351
+ @hm = HashModel.new(:raw_data=>@records, :flatten_index=>:parameter)
352
+ @hm.should == [
353
+ {:parameter=>{:type=>String}, :switch=>["-x", "--xtended"], :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
354
+ {:parameter=>{:require=>true}, :switch=>["-x", "--xtended"], :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
355
+ {:parameter=>nil, :switch=>["-y", "--why"], :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1},
356
+ {:parameter=>{:type=>String}, :switch=>"-z", :description=>"zee svitch zu moost calz", :hm_id=>3, :hm_group_id=>2}
357
+ ]
358
+
359
+ end
360
+
361
+ it "should allow you to change the flatten index" do
362
+ @hm << {:switch => ["-x", "--xtended"], :description => "Xish stuff"}
363
+ proc do
364
+ @hm.flatten_index = :description
365
+ end.should change(@hm, :flatten_index).from(:switch).to(:description)
366
+ end
367
+
368
+ it "should set the flatten index when adding to an empty HashModel" do
369
+ @hm.flatten_index.should == :switch
370
+ end
371
+
372
+ it "should assign the flattened data to self correctly when adding records using <<" do
373
+ @hm = HashModel.new
374
+ @hm << @records[0]
375
+ @hm << @records[1]
376
+ @hm << @records[2]
377
+ @hm.should == @flat_records
378
+ end
379
+
380
+ it "should assign the flattened data to self correctly when adding with :raw_data=>records" do
381
+ @hm.should == @flat_records
382
+ end
383
+
384
+ it "should add a nil value for the field index for records that don't have a field with the field index" do
385
+ @hm = HashModel.new
386
+ @hm << @records[0]
387
+ @hm << {:foo=>"bar"}
388
+ @hm.last.should == {:switch=>nil, :foo=>"bar", :hm_id=>2, :hm_group_id=>1}
389
+ end
390
+
391
+ it "should change the flattened data when changing the flatten index" do
392
+ @hm = HashModel.new(:raw_data=>@records)
393
+ @hm.flatten_index = :parameter_type
394
+ @hm.should == [
395
+ {:parameter_type=>String, :switch=>["-x", "--xtended"], :parameter_require=>true, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
396
+ {:parameter_type=>nil, :switch=>["-y", "--why"], :description=>"lucky what?", :hm_id=>1, :hm_group_id=>1},
397
+ {:parameter_type=>String, :switch=>"-z", :description=>"zee svitch zu moost calz", :hm_id=>2, :hm_group_id=>2}
398
+ ]
399
+ end
400
+
401
+ it "should update the flattened data if the raw data is changed" do
402
+ @hm.raw_data = @records2.clone
403
+ @hm.should == @flat_records2
404
+ end
405
+
406
+ end # flattening behvior
407
+
408
+ describe "comparisons" do
409
+
410
+ it "should allow arrays to be compared to the HashModel" do
411
+ @hm.should == @flat_records
412
+ end
413
+
414
+ it "should allow HashModels to be compared to the HashModel" do
415
+ hm2 = HashModel.new(:raw_data=>@records)
416
+ @hm.should == hm2
417
+ end
418
+
419
+ it "should compare using the raw data if sent an array without group_id's or id's" do
420
+ @hm.should == @records
421
+ end
422
+
423
+ it "should return false if compared to something other than an Array or a HashModel" do
424
+ @hm.should_not == "potato"
425
+ end
426
+
427
+ it "should allow arrays to be compared to the HashModel using eql?" do
428
+ @hm.eql?(@hm).should == true
429
+ end
430
+
431
+ it "should return false if compared to an array of something other than hashes" do
432
+ @hm.should_not == ["potato"]
433
+ end
434
+
435
+ it "should use flattened records if <=>'d with an array with a group_id" do
436
+ (@hm <=> @flat_records).should == 0
437
+ end
438
+
439
+ it "should use flattened records if <=>'d with an array without a group_id" do
440
+ (@hm <=> @records).should == 0
441
+ end
442
+
443
+ it "should use flattened data if <=>'d with another HashModel" do
444
+ hm2 = @hm.clone
445
+ (@hm <=> hm2).should == 0
446
+ end
447
+
448
+ it "should return nil if <=>'d with something other than an Array or a HashModel" do
449
+ (@hm <=> "potato").should == nil
450
+ end
451
+
452
+ end # comparisons
453
+
454
+ describe "searching and selecting records" do
455
+
456
+ context "in place" do
457
+
458
+ it "should accept a parameter as input" do
459
+ proc{@hm.where!("-x")}.should_not raise_error
460
+ end
461
+
462
+ it "should raise an error if a block and a parameter are given" do
463
+ proc{@hm.where!("-x"){@switch == "-x"}}.should raise_error
464
+ end
465
+
466
+ it "should return a HashModel when searching" do
467
+ @hm.where!("-x").class.should == HashModel
468
+ end
469
+
470
+ it "should return the same hash model when calling where" do
471
+ @hm.where!("-x").object_id.should == @hm.object_id
472
+ end
473
+
474
+ it "should filter the recordset" do
475
+ @hm.where!("-x")
476
+ @hm.should == [@flat_records[0]]
477
+ end
478
+
479
+ it "should tell you if it is filtering records" do
480
+ @hm.where!("-x")
481
+ @hm.filtered?.should == true
482
+ end
483
+
484
+ it "should let you clear the filter" do
485
+ @hm.where!("-x")
486
+ proc {@hm.clear_filter}.should change(@hm, :filtered?).from(true).to(false)
487
+ end
488
+
489
+ it "should show all the records when the filter is cleared" do
490
+ @hm.where!("-x")
491
+ @hm.clear_filter
492
+ @hm.should == @flat_records
493
+ end
494
+
495
+ it "should clear the filter if nothing is sent" do
496
+ @hm.where!("-x")
497
+ proc {@hm.where!}.should change(@hm, :filtered?).from(true).to(false)
498
+ end
499
+
500
+ it "should return the entire flattened recordset if nothing is sent" do
501
+ @hm.where!("-x")
502
+ @hm.should == [@flat_records[0]]
503
+ @hm.where!
504
+ @hm.should == @flat_records
505
+ end
506
+
507
+ end # in place
508
+
509
+ context "not in place" do
510
+
511
+ it "should return a HashModel object" do
512
+ @hm = HashModel.new(:raw_data=>@records)
513
+ @hm.where("-x").class.should == HashModel
514
+ end
515
+
516
+ it "should return a new HashModel" do
517
+ @hm.where("-x").object_id.should_not == @hm.object_id
518
+ end
519
+
520
+ it "should search the flatten index if given a parameter" do
521
+ @hm = HashModel.new(:raw_data=>@records)
522
+ @hm.where("-x").should == [@flat_records[0]]
523
+ end
524
+
525
+ it "should search the flatten index if given a block" do
526
+ @hm = HashModel.new(:raw_data=>@records)
527
+ @hm.where{@parameter_type == String}.should == [
528
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
529
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
530
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2}
531
+ ]
532
+ end
533
+
534
+ end # not in place
535
+
536
+ it "should return false if tested for inclusion of anything other than a hash" do
537
+ @hm.include?([:switch=>"-x"]).should == false
538
+ end
539
+
540
+ it "should match flat data if search criteria includes an hm_group_id field" do
541
+ @hm.include?(@flat_records[2]).should == true
542
+ end
543
+
544
+ it "should search raw data if search criteria includes an hm_group_id field" do
545
+ @hm.include?(@records[2]).should == true
546
+ end
547
+
548
+ it "should return the flattened record index using the index method" do
549
+ @hm.index(@flat_records[3]).should == 3
550
+ end
551
+
552
+ context "when using take" do
553
+ it "should return the first n flat records" do
554
+ @hm.take(2).should == @flat_records.take(2)
555
+ end
556
+
557
+ it "should return the first n flat records while block is true" do
558
+ @hm.take_while {|record| record[:hm_id] < 4}.should == @flat_records[0..3]
559
+ end
560
+
561
+ end
562
+
563
+ it "should return values at x,y,z" do
564
+ @hm.values_at(1,3,5).should == @flat_records.values_at(1,3,5)
565
+ end
566
+
567
+ it "should zip things" do
568
+ hm2 = HashModel.new(:raw_data=>@records2)
569
+ @hm.zip(hm2).should == @flat_records.zip(@flat_records2)
570
+ end
571
+
572
+ end # searching records
573
+
574
+ describe "grouping" do
575
+
576
+ context "not in place" do
577
+
578
+ it "should return a HashModel object" do
579
+ @hm.group("-x").class.should == HashModel
580
+ end
581
+
582
+ it "should return a different HashModel object" do
583
+ @hm.group("-x").object_id.should_not == @hm.object_id
584
+ end
585
+
586
+ it "should return the records in the same raw data record when using a parameter" do
587
+ @hm.group("-x").should == [@flat_records[0], @flat_records[1]]
588
+ end
589
+
590
+ it "should be chainable on a filtered HashModel" do
591
+ @hm.where("-x").group.should == [@flat_records[0],@flat_records[1]]
592
+ end
593
+
594
+ it "should return the records in the same raw data record when using a block" do
595
+ @hm.group{@switch == "-y"}.should == [@flat_records[2], @flat_records[3]]
596
+ end
597
+
598
+ it "should work across group_id's if searching for something that returns records from multiple groups" do
599
+ @hm.group{@parameter_type == String}.should == [
600
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
601
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
602
+ {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2}
603
+ ]
604
+ end
605
+
606
+ end # not in place
607
+
608
+ context "in place" do
609
+
610
+ it "should return the same HashModel object" do
611
+ @hm.group!("-x").object_id.should == @hm.object_id
612
+ end
613
+
614
+ it "should return the records in the same raw data record when using a parameter" do
615
+ @hm.group!("-x").should == [@flat_records[0],@flat_records[1]]
616
+ end
617
+
618
+ it "should be chainable on a filtered HashModel" do
619
+ @hm.where("-x").group!.should == [@flat_records[0],@flat_records[1]]
620
+ end
621
+
622
+ it "should be chainable on an in-place filtered HashModel" do
623
+ @hm.where!("-x").group!.should == [@flat_records[0],@flat_records[1]]
624
+ end
625
+
626
+ it "should return the records in the same raw data record when using a block" do
627
+ @hm.group!{@switch == "-y"}.should == [
628
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1},
629
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1}
630
+ ]
631
+ end
632
+
633
+ it "should work across group_id's if searching for something that returns records from multiple groups" do
634
+ @hm.group!{@parameter_type == String}.should == [
635
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0},
636
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0},
637
+ {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2}
638
+ ]
639
+ end
640
+
641
+ end
642
+
643
+ end # grouping
644
+
645
+ describe "miscellaneous array methods and properties" do
646
+
647
+ it "should return an array when calling to_ary" do
648
+ @hm.to_ary.class.should == Array
649
+ end
650
+
651
+ it "should not return a HashModel when calling to_ary" do
652
+ @hm.to_ary.class.should_not == HashModel
653
+ end
654
+
655
+ it "should return the flat records when calling to_ary" do
656
+ @hm.to_ary.should == @flat_records
657
+ end
658
+
659
+ it "should return an array when calling to_a" do
660
+ @hm.to_a.class.should == Array
661
+ end
662
+
663
+ it "should not return a HashModel when calling to_a" do
664
+ @hm.to_a.class.should_not == HashModel
665
+ end
666
+
667
+ it "should return the flat records when calling to_a" do
668
+ @hm.to_a.should == @flat_records
669
+ end
670
+
671
+ it "should report the length of the flat data" do
672
+ @hm.length.should == @flat_records.length
673
+ end
674
+
675
+ it "should report the size of the flat data" do
676
+ @hm.size.should == @flat_records.size
677
+ end
678
+
679
+ it "should return the correct flat record when using at" do
680
+ @hm.at(0).should == @flat_records[0]
681
+ @hm.at(2).should == @flat_records[2]
682
+ end
683
+
684
+ it "should collect across the flat data" do
685
+ extra = -1
686
+ @hm.collect {|record| record.merge!(:extra=>extra+=1)}.should == [
687
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0, :extra=>0},
688
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0, :extra=>1},
689
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1, :extra=>2},
690
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1, :extra=>3},
691
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2, :extra=>4}
692
+ ]
693
+ end
694
+
695
+ it "should map across the flat data" do
696
+ extra = -1
697
+ @hm.map {|record| record.merge!(:extra=>extra+=1)}.should == [
698
+ {:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>0, :hm_group_id=>0, :extra=>0},
699
+ {:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :hm_id=>1, :hm_group_id=>0, :extra=>1},
700
+ {:switch=>"-y", :description=>"lucky what?", :hm_id=>2, :hm_group_id=>1, :extra=>2},
701
+ {:switch=>"--why", :description=>"lucky what?", :hm_id=>3, :hm_group_id=>1, :extra=>3},
702
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :hm_id=>4, :hm_group_id=>2, :extra=>4}
703
+ ]
704
+ end
705
+
706
+ it "should combination'ize the flat data" do
707
+ hm_combo = []
708
+ flat_combo = []
709
+ @hm.combination(2).each { |record| hm_combo << record }
710
+ @flat_records.combination(2) { |record| flat_combo << record }
711
+ hm_combo.should == flat_combo
712
+ end
713
+
714
+ it "should count the flat data" do
715
+ @hm.count.should == @flat_records.count
716
+ end
717
+
718
+ it "should cycle over the flat data" do
719
+ cycle = cycle2 = []
720
+ @hm.cycle(2) {|record| cycle << record}
721
+ @flat_records.cycle(2) {|record| cycle2 << record}
722
+ cycle.should == cycle2
723
+ end
724
+
725
+ it "should iterate with an index" do
726
+ collect = []
727
+ @hm.each_index {|index| collect << @hm[index][:switch]}
728
+ collect.should == ["-x", "--xtended", "-y", "--why", "-z"]
729
+ end
730
+
731
+ it "should say if it's empty" do
732
+ @hm = HashModel.new
733
+ @hm.empty?.should == true
734
+ @hm << @records[0]
735
+ @hm.empty?.should == false
736
+ end
737
+
738
+ it "should fetch records given an index" do
739
+ @hm.fetch(2).should == @flat_records[2]
740
+ end
741
+
742
+ it "should return the default value if fetch index is out of bounds" do
743
+ @hm.fetch(10, "potato").should == "potato"
744
+ end
745
+
746
+ it "should run a block if fetch index is out of bounds" do
747
+ (@hm.fetch(10) {|index| index }).should == 10
748
+ end
749
+
750
+ it "should return the first flattened record" do
751
+ @hm.first.should == @flat_records.first
752
+ end
753
+
754
+ it "should return the last flattened record" do
755
+ @hm.last.should == @flat_records.last
756
+ end
757
+
758
+ it "should freeze the raw records" do
759
+ proc{@hm.freeze}.should change(@hm.raw_data,:frozen?)
760
+ .from(false)
761
+ .to(true)
762
+ end
763
+
764
+ it "should permutate over the flat data" do
765
+ @hm.permutation(2).to_a.should == @flat_records.permutation(2).to_a
766
+ @hm.permutation.to_a.should == @flat_records.permutation.to_a
767
+ @hm.permutation.to_a.should_not == @records.permutation.to_a
768
+ end
769
+
770
+ end
771
+
772
+ end # describe "HashModel"
773
+
774
+ end # MikBe