hashmodel 0.4.0.beta1 → 0.4.0.beta2

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.
Files changed (45) hide show
  1. data/Gemfile.lock +1 -1
  2. data/LICENSE.txt +1 -1
  3. data/README.markdown +65 -27
  4. data/hashmodel.gemspec +1 -1
  5. data/lib/hash_model/hash_model.rb +13 -105
  6. data/lib/hash_model/hash_model_create_object.rb +62 -0
  7. data/lib/hash_model/hash_model_delete.rb +13 -0
  8. data/lib/hash_model/hash_model_filter.rb +37 -0
  9. data/lib/hash_model/hash_model_flatten.rb +47 -0
  10. data/lib/hash_model/hash_model_group.rb +18 -0
  11. data/lib/hash_model/hash_model_update.rb +118 -0
  12. data/lib/hash_model/hash_model_where.rb +27 -0
  13. data/lib/hash_model/version.rb +1 -1
  14. data/lib/hashmodel.rb +1 -0
  15. data/lib/monkey_patch/deep_clone.rb +27 -0
  16. data/spec/hash_model/_current_spec.rb +6 -0
  17. data/spec/hash_model/hash_model_adding_records_spec.rb +338 -0
  18. data/spec/hash_model/hash_model_array_methods_spec.rb +132 -0
  19. data/spec/hash_model/hash_model_comparisons_spec.rb +55 -0
  20. data/spec/hash_model/hash_model_delete_spec.rb +51 -0
  21. data/spec/hash_model/hash_model_flattening_spec.rb +92 -0
  22. data/spec/hash_model/hash_model_group_spec.rb +67 -0
  23. data/spec/hash_model/hash_model_searching_spec.rb +245 -0
  24. data/spec/hash_model/hash_model_spec.rb +1 -1
  25. data/spec/hash_model/hash_model_unflattening_spec.rb +34 -0
  26. data/spec/hash_model/hash_model_update_spec.rb +147 -0
  27. data/spec/hash_model/hash_model_where_spec.rb +287 -0
  28. data/spec/support/configuration.rb +50 -0
  29. data/spec/support/debug_print.rb +13 -0
  30. data/spec/support/proc_tester.rb +17 -0
  31. metadata +49 -27
  32. data/_brainstorm/StrangeMarshal.txt +0 -0
  33. data/_brainstorm/_readme +0 -1
  34. data/_brainstorm/block_wheres.rb +0 -80
  35. data/_brainstorm/clone.rb +0 -19
  36. data/_brainstorm/hash_model_examples.rb +0 -57
  37. data/_brainstorm/hash_test.rb +0 -169
  38. data/_brainstorm/inspect.rb +0 -26
  39. data/_brainstorm/instance_vars.rb +0 -24
  40. data/_brainstorm/proc_tests.rb +0 -14
  41. data/_brainstorm/ref_val.rb +0 -16
  42. data/_brainstorm/regex_captures.rb +0 -18
  43. data/_brainstorm/spliting.rb +0 -46
  44. data/_brainstorm/test.rb +0 -27
  45. data/_brainstorm/unflat.rb +0 -16
@@ -18,7 +18,7 @@ describe HashModel do
18
18
  @hm = HashModel.new
19
19
  @hm << @records[0]
20
20
  proc{@hm.clear}.should change(@hm, :raw_data)
21
- .from([{:switch => ["-x", "--xtended"], :parameter => {:type => String, :require => true}, :description => "Xish stuff"}])
21
+ .from([{:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff"}])
22
22
  .to([])
23
23
  end
24
24
 
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashModel do
4
+
5
+ context "when unflattening behavior" do
6
+
7
+ it "should allow access to the unflatten without an instance of HashModel" do
8
+ deep_hash = {
9
+ :parameter__type=>String,
10
+ :switch__deep1__deep3 => "deepTwo",
11
+ :parameter__type__ruby=>true,
12
+ :parameter => "glorp",
13
+ :parameter__required=>true,
14
+ :switch__deep2 => "deepTwo",
15
+ :description=>"Xish stuff",
16
+ :switch => "--xtend",
17
+ }
18
+ HashModel.unflatten(deep_hash).should == {
19
+ :parameter => [
20
+ {:type=>String},
21
+ "glorp",
22
+ {:required=>true}
23
+ ],
24
+ :switch => [
25
+ {:deep1 => {:deep3=>"deepTwo"}},
26
+ {:deep2=>"deepTwo"},
27
+ "--xtend"
28
+ ],
29
+ :description=>"Xish stuff"
30
+ }
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,147 @@
1
+ require "spec_helper"
2
+
3
+ describe HashModel do
4
+
5
+ context "when updating records" do
6
+
7
+ let(:hm){HashModel.new(:raw_data=> {:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a =>"b2a", :b2b=>"b2b"}}} )}
8
+
9
+
10
+ context "and the search key exists in the target" do
11
+
12
+ it "should update the value properly" do
13
+ update = {:b__b2__b2b=>"potato"}
14
+ lambda{hm.update!(update)}.should change{hm.deep_clone}
15
+ .from([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"b2b"}}, :_id=>0, :_group_id=>0}])
16
+ .to([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"potato"}}, :_id=>0, :_group_id=>0}])
17
+ end
18
+
19
+ it "should update a mid-level hash" do
20
+ update = {:b__b2=>"potato"}
21
+ lambda{hm.update!(update)}.should change{hm.deep_clone}
22
+ .from([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"b2b"}}, :_id=>0, :_group_id=>0}])
23
+ .to([{:a=>"a", :b=>{:b1=>"b1", :b2=>"potato"}, :_id=>0, :_group_id=>0}])
24
+ end
25
+
26
+ it "should update a multiple update hashes at once" do
27
+ update = {:b__b2=>"potato", :a=>"blorg", :b__b1=>"fish"}
28
+ lambda{hm.update!(update)}.should change{hm.deep_clone}
29
+ .from([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"b2b"}}, :_id=>0, :_group_id=>0}])
30
+ .to([{:a=>"blorg", :b=>{:b1=>"fish", :b2=>"potato"}, :_id=>0, :_group_id=>0}])
31
+ end
32
+
33
+ it "should update with a hash as the value" do
34
+ update = {:b__b2=>{:d=>"d"}}
35
+ lambda{hm.update!(update)}.should change{hm.deep_clone}
36
+ .from([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"b2b"}}, :_id=>0, :_group_id=>0}])
37
+ .to([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:d=>"d"}}, :_id=>0, :_group_id=>0}])
38
+ end
39
+
40
+ it "should update with an array as the value" do
41
+ update = {:b__b2=>[1,2,3]}
42
+ lambda{hm.update!(update)}.should change{hm.deep_clone}
43
+ .from([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"b2b"}}, :_id=>0, :_group_id=>0}])
44
+ .to([{:a=>"a", :b=>{:b1=>"b1", :b2=>[1,2,3]}, :_id=>0, :_group_id=>0}])
45
+ end
46
+
47
+
48
+ end
49
+
50
+ context "but the search key does NOT exist in the target" do
51
+
52
+ it "should NOT by default add a field" do
53
+ update = {:b__b2__b2c=>"potato"}
54
+ lambda{hm.update!(update)}.should_not change{hm.deep_clone}
55
+ end
56
+
57
+ it "should add a field if told to do so (by using update_and_add)" do
58
+ update = {:b__b2__b2c=>"potato"}
59
+ lambda{hm.update_and_add!(update)}.should change{hm.deep_clone}
60
+ .from([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"b2b"}}, :_id=>0, :_group_id=>0}])
61
+ .to([{:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"b2b", :b2c=>"potato"}}, :_id=>0, :_group_id=>0}])
62
+ end
63
+
64
+ it "should only return records that are changed" do
65
+ hm << {:a=>"17", :b=>"1870"}
66
+ update = {:b__b2__b2b=>"potato"}
67
+ hm.update!(update).should == [
68
+ {:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"potato"}}, :_id=>0, :_group_id=>0}
69
+ ]
70
+ end
71
+
72
+ end
73
+
74
+ context "when updating a filtered HashModel" do
75
+
76
+ before(:each) do
77
+ hm << {:a=>"17", :b=>"7291", :c=>"0"}
78
+ hm << {:a=>"17", :b=>"080", :c=>"1"}
79
+ hm << {:a=>"17", :b=>"24134", :c=>2}
80
+ hm.filter("17")
81
+ end
82
+
83
+ it "should return the updated records" do
84
+ hm.update!(:b=>"23").should == [
85
+ {:a=>"17", :b=>"23", :c=>"0", :_id=>1, :_group_id=>1},
86
+ {:a=>"17", :b=>"23", :c=>"1", :_id=>2, :_group_id=>2},
87
+ {:a=>"17", :b=>"23", :c=>2, :_id=>3, :_group_id=>3}
88
+ ]
89
+ end
90
+
91
+ it "should not update records not in the current filter" do
92
+ lambda{hm.update!(:b=>"23")}.should_not change{hm.raw_data.clone[0]}
93
+ end
94
+
95
+ it "should return the updated records even if the primary key is the one changed" do
96
+ hm.update!(:a=>"BBBB").should == [
97
+ {:a=>"BBBB", :b=>"7291", :c=>"0", :_id=>1, :_group_id=>1},
98
+ {:a=>"BBBB", :b=>"080", :c=>"1", :_id=>2, :_group_id=>2},
99
+ {:a=>"BBBB", :b=>"24134", :c=>2, :_id=>3, :_group_id=>3}
100
+ ]
101
+ end
102
+
103
+ context "after changing the filtered field to something that doesn't match the filter" do
104
+ it {hm.update!(:a=>"BBBB"); hm.length.should == 0}
105
+ end
106
+
107
+ end
108
+
109
+ context "when using non-destructive methods" do
110
+
111
+ it {lambda{hm.update(:b__b2__b2b=>"potato")}.should_not change{hm.deep_clone}}
112
+
113
+ it {lambda{hm.update_and_add(:b__b2__b2j=>"potato")}.should_not change{hm.deep_clone}}
114
+
115
+ end
116
+
117
+ context "when sending a filter with the update" do
118
+
119
+ before(:each) do
120
+ hm << {:a=>"17", :b=>"7291", :c=>"0"}
121
+ hm << {:a=>"17", :b=>"080", :c=>"1"}
122
+ hm << {:a=>"17", :b=>"24134", :c=>2}
123
+ end
124
+
125
+ it {hm.update("17", {:b=>3434}).should == [
126
+ {:a=>"17", :b=>3434, :c=>"0", :_id=>1, :_group_id=>1},
127
+ {:a=>"17", :b=>3434, :c=>"1", :_id=>2, :_group_id=>2},
128
+ {:a=>"17", :b=>3434, :c=>2, :_id=>3, :_group_id=>3}]
129
+ }
130
+
131
+ it "should reset the original filter" do
132
+ hm.update("17", {:b=>3434})
133
+ hm.should == [
134
+ {:a=>"a", :b=>{:b1=>"b1", :b2=>{:b2a=>"b2a", :b2b=>"b2b"}}, :_id=>0, :_group_id=>0},
135
+ {:a=>"17", :b=>"7291", :c=>"0", :_id=>1, :_group_id=>1},
136
+ {:a=>"17", :b=>"080", :c=>"1", :_id=>2, :_group_id=>2},
137
+ {:a=>"17", :b=>"24134", :c=>2, :_id=>3, :_group_id=>3}
138
+ ]
139
+
140
+ end
141
+
142
+
143
+ end
144
+
145
+ end
146
+
147
+ end
@@ -0,0 +1,287 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashModel do
4
+
5
+ describe "searching and selecting records" do
6
+
7
+ context "when searhing non-destructively" do
8
+
9
+ it "should return an empty set if the HashModel is empty" do
10
+ empty = HashModel.new
11
+ empty.where("fudge").should == []
12
+ end
13
+
14
+ it "should have a length of 0 if the HashModel is empty" do
15
+ empty = HashModel.new
16
+ empty.length.should == 0
17
+ end
18
+
19
+ it "should accept a parameter as input" do
20
+ proc{@hm.where("-x")}.should_not raise_error
21
+ end
22
+
23
+ it "should raise an error if a block and a parameter are given" do
24
+ proc{@hm.where("-x"){@switch == "-x"}}.should raise_error
25
+ end
26
+
27
+ it "should return a HashModel when searching" do
28
+ @hm.where("-x").class.should == HashModel
29
+ end
30
+
31
+ it "should return a different hash model when calling where" do
32
+ @hm.where("-x").object_id.should_not == @hm.object_id
33
+ end
34
+
35
+ it "should shouldn't destroy records" do
36
+ lambda{@hm.where("-x")}.should_not change{@hm}
37
+ end
38
+
39
+ it "should delete data from raw records if that data doesn't fit the search criteria" do
40
+ records = {:switch=>[[1,2],[3,4]]}
41
+ hm = HashModel.new(:raw_data=>records)
42
+ hm.where([1,2]).raw_data[0][:switch].should_not include([3,4])
43
+ end
44
+
45
+ end
46
+
47
+ context "when searhing destructively" do
48
+
49
+ it "should return the same hash model when calling where!" do
50
+ @hm.where!("-x").object_id.should == @hm.object_id
51
+ end
52
+
53
+ it "should should destroy records" do
54
+ lambda{@hm.where!("-x")}.should change{@hm.raw_data.clone}
55
+ end
56
+
57
+ end
58
+
59
+ context "non-string search values" do
60
+
61
+ it "should search using the flatten_index if a symbol is used with where" do
62
+ @records = [
63
+ {:switch => ["-x", "--xtended", :default], :parameter => {:type => String, :required => true}, :description => "Xish stuff"},
64
+ {:switch => ["-y", "--why"], :description => "lucky what?"},
65
+ {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
66
+ ]
67
+ @hm = HashModel.new(:raw_data=>@records)
68
+ @hm.where(:default).should == [{:switch=>:default, :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0}]
69
+ end
70
+
71
+ it "should search using an array" do
72
+ recs = [[1,2],[3,4]]
73
+ hm = HashModel.new(:raw_data=>{:switch=>recs})
74
+ hm.where([1,2]).should == [{:switch=>[1, 2], :_id=>0, :_group_id=>0}]
75
+ end
76
+
77
+ end
78
+
79
+ context "filtering records" do
80
+
81
+ it "should filter the recordset" do
82
+ @hm.filter("-x")
83
+ @hm.should == [@flat_records[0]]
84
+ end
85
+
86
+ it "should tell you if it is filtering records" do
87
+ @hm.filter("-x")
88
+ @hm.filtered?.should == true
89
+ end
90
+
91
+ it "should let you clear the filter" do
92
+ @hm.filter("-x")
93
+ proc {@hm.clear_filter}.should change(@hm, :filtered?).from(true).to(false)
94
+ end
95
+
96
+ it "should show all the records when the filter is cleared" do
97
+ @hm.filter("-x")
98
+ @hm.clear_filter
99
+ @hm.should == @flat_records
100
+ end
101
+
102
+ it "should clear the filter if nothing is sent" do
103
+ @hm.filter("-x")
104
+ proc {@hm.where!}.should change(@hm, :filtered?).from(true).to(false)
105
+ end
106
+
107
+ context "when searching for records with nil values" do
108
+
109
+ it "should search the flatten index" do
110
+ @hm.flatten_index = :parameter__type
111
+ @hm.filter(nil).should == [
112
+ {:parameter__type=>nil, :switch=>["-y", "--why"], :description=>"lucky what?", :_id=>1, :_group_id=>1}
113
+ ]
114
+ end
115
+
116
+ it "should search using a block" do
117
+ @hm.filter{:parameter__type == nil}.should == [@flat_records[2], @flat_records[3]]
118
+ end
119
+
120
+ end
121
+
122
+ end # filtering
123
+
124
+ context "not in place" do
125
+
126
+ it "should return a HashModel object" do
127
+ @hm = HashModel.new(:raw_data=>@records)
128
+ @hm.where("-x").class.should == HashModel
129
+ end
130
+
131
+ it "should return a new HashModel" do
132
+ @hm.where("-x").object_id.should_not == @hm.object_id
133
+ end
134
+
135
+ it "should search the flatten index if given a parameter" do
136
+ @hm = HashModel.new(:raw_data=>@records)
137
+ @hm.where("-x").should == [@flat_records[0]]
138
+ end
139
+
140
+ it "should search the flatten index if given a block" do
141
+ @hm.where{:parameter__type == String}.should == [
142
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
143
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
144
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>2, :_group_id=>1}
145
+ ]
146
+ end
147
+
148
+ end # not in place
149
+
150
+ context "when using blocks" do
151
+
152
+ it "should search using a single value boolean block" do
153
+ @hm.where {:switch == "-x"}.should == [@flat_records[0]]
154
+ end
155
+
156
+ it "should search using a complex boolean block" do
157
+ records = [
158
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
159
+ {:switch => ["-y", "--why"], :description => "lucky what?"},
160
+ {:switch => "-z", :parameter => {:type => String, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
161
+ ]
162
+ @hm = HashModel.new(:raw_data=>records)
163
+ @hm.where {:something == 4 && :parameter__required == true}.should == [
164
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
165
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
166
+ {:switch=>"-z", :parameter=>{:type=>String, :required=>true}, :description=>"zee svitch zu moost calz", :something=>4, :_id=>2, :_group_id=>1}
167
+ ]
168
+ end
169
+
170
+ it "should search a complex boolean block regardless of order" do
171
+ records = [
172
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
173
+ {:switch => ["-y", "--why"], :description => "lucky what?"},
174
+ {:switch => "-z", :parameter => {:type => String, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
175
+ ]
176
+ @hm = HashModel.new(:raw_data=>records)
177
+ @hm.where {:parameter__type == String && :parameter__required == true && :something == 4}.should == [
178
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
179
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
180
+ {:switch=>"-z", :parameter=>{:type=>String, :required=>true}, :description=>"zee svitch zu moost calz", :something=>4, :_id=>2, :_group_id=>1}
181
+ ]
182
+ end
183
+
184
+ it "should search using a complex, multi-line boolean block" do
185
+ records = [
186
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
187
+ {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
188
+ {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
189
+ ]
190
+ @hm = HashModel.new(:raw_data=>records)
191
+ @hm.where {(:parameter__type == String && :parameter__required == true && :something == 4) || :something == 7}.should == [
192
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
193
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
194
+ {:switch=>"-y", :description=>"lucky what?", :something=>7, :_id=>2, :_group_id=>1},
195
+ {:switch=>"--why", :description=>"lucky what?", :something=>7, :_id=>3, :_group_id=>1}
196
+ ]
197
+ end
198
+
199
+ it "should search with nested hashes in a block" do
200
+ records = [
201
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
202
+ {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
203
+ {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
204
+ ]
205
+ @hm = HashModel.new(:raw_data=>records)
206
+ @hm.where {:parameter == {:type => String, :required => true}}.should == [
207
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
208
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0}
209
+ ]
210
+ end
211
+
212
+ end
213
+
214
+ context "when using variables to search" do
215
+
216
+ it "should work with a block" do
217
+ variable = "-x"
218
+ @hm.filter{:switch == variable}.should == [@flat_records[0]]
219
+ end
220
+
221
+ it "should work with a default index search" do
222
+ variable = "-x"
223
+ @hm.filter(variable).should == [@flat_records[0]]
224
+ end
225
+
226
+ it "should work with classes" do
227
+ variable = String
228
+ @hm.filter{:parameter__type == variable}.should == [@flat_records[0], @flat_records[1], @flat_records[4]]
229
+ end
230
+
231
+ it "should work with deeply nested default indexes" do
232
+ @hm.flatten_index = :parameter__type
233
+ variable = nil
234
+ @hm.filter(variable).should == [
235
+ {:parameter__type=>nil, :switch=>["-y", "--why"], :description=>"lucky what?", :_id=>1, :_group_id=>1}
236
+ ]
237
+ end
238
+
239
+ end
240
+
241
+ context "searching for the parent" do
242
+ it "should return the raw record the child record is based on" do
243
+ @hm.parents("-x").should == [@records[0]]
244
+ end
245
+ it "should return all the parents if there are more than one base on the search" do
246
+ @hm.parents{:parameter__type == String}.should == [@records[0],@records[2]]
247
+ end
248
+ end
249
+
250
+ it "should return false if tested for inclusion of anything other than a hash" do
251
+ @hm.include?([:switch=>"-x"]).should == false
252
+ end
253
+
254
+ it "should match flat data if search criteria includes an _group_id field" do
255
+ @hm.include?(@flat_records[2]).should == true
256
+ end
257
+
258
+ it "should search raw data if search criteria includes an _group_id field" do
259
+ @hm.include?(@records[2]).should == true
260
+ end
261
+
262
+ it "should return the flattened record index using the index method" do
263
+ @hm.index(@flat_records[3]).should == 3
264
+ end
265
+
266
+ context "when using take" do
267
+ it "should return the first n flat records" do
268
+ @hm.take(2).should == @flat_records.take(2)
269
+ end
270
+
271
+ it "should return the first n flat records while block is true" do
272
+ @hm.take_while {|record| record[:_id] < 4}.should == @flat_records[0..3]
273
+ end
274
+
275
+ end
276
+
277
+ it "should return values at x,y,z" do
278
+ @hm.values_at(1,3,5).should == @flat_records.values_at(1,3,5)
279
+ end
280
+
281
+ it "should zip things" do
282
+ hm2 = HashModel.new(:raw_data=>@records2)
283
+ @hm.zip(hm2).should == @flat_records.zip(@flat_records2)
284
+ end
285
+
286
+ end # searching records
287
+ end