hashmodel 0.1.1
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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +41 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +44 -0
- data/Rakefile +49 -0
- data/autotest/discover.rb +3 -0
- data/features/README +9 -0
- data/features/hash_model_flatten.feature +34 -0
- data/features/hash_model_grouping.feature +18 -0
- data/features/hash_model_search.feature +34 -0
- data/features/step_definitions/hash_model_steps.rb +60 -0
- data/features/support/env.rb +14 -0
- data/features/support/helper.rb +18 -0
- data/lib/hash_model.rb +4 -0
- data/lib/hash_model/exceptions.rb +5 -0
- data/lib/hash_model/hash_model.rb +411 -0
- data/lib/hash_model/version.rb +14 -0
- data/spec/hash_model/hash_model_spec.rb +774 -0
- data/spec/spec_helper.rb +23 -0
- metadata +160 -0
@@ -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
|