hashmodel 0.3.0.beta1 → 0.3.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.markdown +59 -38
- data/_brainstorm/_readme +1 -0
- data/_brainstorm/inspect.rb +26 -0
- data/features/support/env.rb +1 -1
- data/lib/hash_model/hash_model.rb +44 -11
- data/lib/hash_model/version.rb +1 -1
- data/lib/{hash_model.rb → hashmodel.rb} +0 -0
- data/spec/hash_model/hash_model_spec.rb +108 -9
- data/spec/spec_helper.rb +2 -2
- metadata +6 -4
data/Gemfile.lock
CHANGED
data/README.markdown
CHANGED
@@ -4,9 +4,10 @@ A simple MVC type model class for storing deeply nested hashes as records.
|
|
4
4
|
It's meant to be used for small, in-memory recordset that you want an easy, flexible way to query.
|
5
5
|
It is not meant as a data storage device for managing huge datasets.
|
6
6
|
|
7
|
-
Note:
|
8
|
-
This
|
9
|
-
|
7
|
+
Note:
|
8
|
+
This started out as a programming exercise to learn more about Ruby but is now fairly well featured so can be quite useful.
|
9
|
+
It is not however a thoroughly tested or industrial strength model and it's not meant to be used to parse your entire user database.
|
10
|
+
If you're looking for an excellent model class take a look at ActiveModel, it's probably more of what you're looking for.
|
10
11
|
|
11
12
|
## Synopsis
|
12
13
|
|
@@ -15,31 +16,40 @@ A field can contain anything, including another hash, a string, an array, or eve
|
|
15
16
|
|
16
17
|
Searches are very simple and logical. You can search using just using the value of the default index
|
17
18
|
|
19
|
+
require 'hashmodel'
|
18
20
|
records = [
|
19
21
|
{:switch => ["-x", "--xtended"], :parameter => {:type => String, :require => true}, :description => "Xish stuff"},
|
20
22
|
{:switch => ["-y", "--why"], :description => "lucky what?"},
|
21
23
|
{:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
|
22
24
|
]
|
23
|
-
|
24
|
-
found =
|
25
|
+
hash_model = HashModel.new(:raw_data=>records)
|
26
|
+
found = hash_model.where("-x") => Returns an array of flattened records
|
25
27
|
|
26
28
|
|
27
29
|
Or more powerfully you can search using boolean like logic e.g.
|
28
30
|
|
29
|
-
|
30
|
-
found =
|
31
|
+
hash_model = HashModel.new(:raw_data=>records)
|
32
|
+
found = hash_model.where {:switch == "-x" && :parameter__type == String} => Returns an array of flattened records
|
31
33
|
|
32
34
|
|
33
35
|
## Status
|
34
36
|
|
35
|
-
###**Beta
|
36
|
-
|
37
|
+
###**Beta**
|
38
|
+
|
39
|
+
I'm doing real-world testing now and am fixing design holes and adding functionality so I wouldn't use this version until I'm done. None of the previous versions were all that useful but after I release this version I'll only develop in branches.
|
40
|
+
|
41
|
+
I expect the design to stay pretty stable from this point forward so no more surprising changes in the design or its use.
|
42
|
+
|
43
|
+
## Developer Notes
|
44
|
+
|
45
|
+
If you have problems running Autotest on your RSpecs try including the gem file-tail in your app. You **shouldn't** have to since I include it here but I had problems with Autotest and Sourcify and adding that fixed it.
|
37
46
|
|
38
47
|
## Usage
|
39
48
|
|
40
|
-
|
49
|
+
I've covered most of the major stuff here but to see all of the functionality take a look at the RSpec files.
|
41
50
|
|
42
51
|
### **Creating with an array of hashes**
|
52
|
+
require 'hashmodel'
|
43
53
|
records = [
|
44
54
|
{:switch => ["-x", "--xtended"], :parameter => {:type => String, :require => true}, :description => "Xish stuff"},
|
45
55
|
{:switch => ["-y", "--why"], :description => "lucky what?"},
|
@@ -54,9 +64,13 @@ These are just a few of the major methods of the class, to see all the functiona
|
|
54
64
|
>> {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1}
|
55
65
|
>> {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2}
|
56
66
|
|
67
|
+
|
57
68
|
### **Group ID's and Record ID's**
|
58
|
-
# You may have noticed that there are two fields you didn't add in the
|
59
|
-
#
|
69
|
+
# You may have noticed that there are two fields you didn't add in the
|
70
|
+
# flattened records. These are the :_id field and the :_group_id fields.
|
71
|
+
# :_id is a unique ID for the flattened record while :_group_id is
|
72
|
+
# unique to the raw record you used to create the HashModel record.
|
73
|
+
|
60
74
|
|
61
75
|
### **Adding hashes after creation : <<, +, add, concat, push**
|
62
76
|
hash_model = HashModel.new
|
@@ -91,9 +105,9 @@ These are just a few of the major methods of the class, to see all the functiona
|
|
91
105
|
{:switch => ["-y", "--why"], :description => "lucky what?"},
|
92
106
|
{:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
|
93
107
|
]
|
94
|
-
|
108
|
+
hash_model = HashModel.new(:raw_data=>records)
|
95
109
|
|
96
|
-
puts
|
110
|
+
puts hash_model.raw_data
|
97
111
|
>> {:switch => ["-x", "--xtended"], :parameter => {:type => String, :require => true}, :description => "Xish stuff"}
|
98
112
|
>> {:switch => ["-y", "--why"], :description => "lucky what?"}
|
99
113
|
>> {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"}
|
@@ -105,11 +119,18 @@ These are just a few of the major methods of the class, to see all the functiona
|
|
105
119
|
hash_model.each do |record|
|
106
120
|
# record is a hash
|
107
121
|
end
|
108
|
-
|
122
|
+
|
123
|
+
### **Direct access to flattened records : []**
|
124
|
+
# the HashModel acts a lot like an array so you can iterate over it
|
125
|
+
hash_model = HashModel.new(:raw_data=>records)
|
126
|
+
|
127
|
+
puts hash_model[0]
|
128
|
+
>> {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0}
|
129
|
+
|
109
130
|
|
110
131
|
### **Flattening records : flatten_index**
|
111
132
|
# Flatten index is automatically set to the first field ever given
|
112
|
-
# but you can change it
|
133
|
+
# but you can change it to any field you want.
|
113
134
|
hash_model = HashModel.new(:raw_data=>records)
|
114
135
|
|
115
136
|
puts hash_model.flatten_index
|
@@ -130,24 +151,22 @@ These are just a few of the major methods of the class, to see all the functiona
|
|
130
151
|
|
131
152
|
|
132
153
|
### **Searching Records : where**
|
133
|
-
# This is where the real power of the library is. You can do complex boolean searches using flattened field names.
|
134
|
-
|
135
154
|
# You can search using just a value and it will search based on the flatten_index
|
136
155
|
records = [
|
137
156
|
{:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
|
138
157
|
{:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
|
139
158
|
{:switch => "-z", :parameter => {:type => String, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
|
140
159
|
]
|
141
|
-
|
142
|
-
where =
|
160
|
+
hash_model = HashModel.new(:raw_data=>records)
|
161
|
+
where = hash_model.where("-x")
|
143
162
|
|
144
163
|
puts where
|
145
164
|
>> {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0}
|
146
165
|
|
147
|
-
#
|
166
|
+
# But the real power is the ability to search with complex boolean logic using normal and flattend field names.
|
148
167
|
# Note that flattened field names are seperated with double under lines __
|
149
|
-
|
150
|
-
where =
|
168
|
+
hash_model = HashModel.new(:raw_data=>records)
|
169
|
+
where = hash_model.where {:something == 7 || (:parameter__type == String && :parameter__required == true)}
|
151
170
|
|
152
171
|
puts where
|
153
172
|
>> {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0}
|
@@ -155,25 +174,24 @@ These are just a few of the major methods of the class, to see all the functiona
|
|
155
174
|
>> {:switch=>"-z", :parameter=>{:type=>String, :required=>true}, :description=>"zee svitch zu moost calz", :something=>4, :_id=>4, :_group_id=>2}
|
156
175
|
|
157
176
|
# You can even search using hash values
|
158
|
-
|
159
|
-
where =
|
177
|
+
hash_model = HashModel.new(:raw_data=>records)
|
178
|
+
where = hash_model.where {:parameter == {:type => String, :required => true}}
|
160
179
|
|
161
180
|
puts where
|
162
|
-
|
163
181
|
>> {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
|
164
182
|
>> {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0}
|
165
183
|
|
166
184
|
|
167
185
|
### **Finding Sibling Records : group**
|
168
186
|
# Since the HashModel class flattens records it is sometimes useful to know what records were created from the same raw data record.
|
169
|
-
# This works exactly like a where search so you can send just a value or send a block and get all of the sibling records for your search criteria.
|
187
|
+
# This works exactly like a #where search so you can send just a value or send a block and get all of the sibling records for your search criteria.
|
170
188
|
records = [
|
171
189
|
{:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
|
172
190
|
{:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
|
173
191
|
{:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
|
174
192
|
]
|
175
|
-
|
176
|
-
group =
|
193
|
+
hash_model = HashModel.new(:raw_data=>records)
|
194
|
+
group = hash_model.group {(:parameter__type == String && :parameter__required == true && :something == 4) || :something == 7}
|
177
195
|
|
178
196
|
puts group
|
179
197
|
>> {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0}
|
@@ -183,14 +201,14 @@ These are just a few of the major methods of the class, to see all the functiona
|
|
183
201
|
|
184
202
|
|
185
203
|
### **Unflattening records : unflatten**
|
186
|
-
#
|
187
|
-
|
188
|
-
|
204
|
+
# You can also add flat records in the same way you add raw records.
|
205
|
+
hash_model = HashModel.new
|
206
|
+
hash_model << {:switch=>"-x", :parameter__type=>String, :parameter__require=>true, :description=>"Xish stuff"}
|
189
207
|
|
190
|
-
puts
|
208
|
+
puts hash_model.raw_data
|
191
209
|
>> {:switch => "-x", :parameter => {:type => String, :require => true}, :description => "Xish stuff"}
|
192
210
|
|
193
|
-
# You can also call the unflatten method
|
211
|
+
# You can also call the unflatten method on an instance or the class itself and send it a record. (It won't mess with the existing data.)
|
194
212
|
deep_hash = {
|
195
213
|
:parameter__type=>String,
|
196
214
|
:switch__deep1__deep3 => "deepTwo",
|
@@ -211,12 +229,15 @@ These are just a few of the major methods of the class, to see all the functiona
|
|
211
229
|
|
212
230
|
0.3.0.beta1 - 2011.01.09
|
213
231
|
|
214
|
-
*
|
215
|
-
e.g.
|
232
|
+
* HashModel\#where searches can now use symbols instead of @variables (you can still use @ if you want).
|
233
|
+
e.g. hash_model.where{:x == "x" && :y == "y"} instead of the less natural hash_model.where{@x == "x" && @y == "y"}
|
216
234
|
* Converted the HashModel filter from a proc to a string so it can be viewed and allows the above behavior.
|
217
|
-
*
|
235
|
+
* Changed name for require to mirror name of app (require 'hashmodel' instead of confusing require 'hash_model')
|
236
|
+
* Added flatten to multiple methods (clone, to\_s, to\_a, to\_ary) so they'll return flattened data if called without anything else happening first.
|
237
|
+
* Fixed design flaw that didn't allow arrays of arrays to be used as values or arrays as searches.
|
238
|
+
* Removed Jeweler and converted to Bundler gem building.
|
218
239
|
* Added usage instructions.
|
219
|
-
* To do: Refactor some ugly code
|
240
|
+
* To do: Refactor some ugly code
|
220
241
|
|
221
242
|
0.2.0 - 2011.01.08
|
222
243
|
|
data/_brainstorm/_readme
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
This is my scratchpad area where I try stuff out. Nothing really useful here.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class TestSelf
|
2
|
+
include Enumerable
|
3
|
+
|
4
|
+
attr_accessor :data
|
5
|
+
|
6
|
+
def initialize(data=[])
|
7
|
+
@data = data
|
8
|
+
end
|
9
|
+
|
10
|
+
def each
|
11
|
+
@data.each do |record|
|
12
|
+
yield record
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
@data.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
array = [1,2,3,4,5]
|
24
|
+
ts = TestSelf.new(array)
|
25
|
+
|
26
|
+
puts ts[2]
|
data/features/support/env.rb
CHANGED
@@ -29,8 +29,22 @@ class HashModel
|
|
29
29
|
|
30
30
|
# Sets field name used to flatten the recordset
|
31
31
|
def flatten_index=(value)
|
32
|
+
old_flatten = @flatten_index
|
32
33
|
@flatten_index = value
|
33
34
|
flatten
|
35
|
+
|
36
|
+
# Verify the flatten index is a valid index
|
37
|
+
flatten_found = false
|
38
|
+
@modified_data.each do |record|
|
39
|
+
break (flatten_found = true) if record[value]
|
40
|
+
end
|
41
|
+
|
42
|
+
unless flatten_found
|
43
|
+
@flatten_index = old_flatten
|
44
|
+
flatten
|
45
|
+
raise ArgumentError, "Flatten index could not be created: #{value}"
|
46
|
+
end
|
47
|
+
self
|
34
48
|
end
|
35
49
|
|
36
50
|
# Are the records being filtered?
|
@@ -49,6 +63,7 @@ class HashModel
|
|
49
63
|
raise SyntaxError, "Raw data may only be an array of hashes" if value.class != Array
|
50
64
|
check_field_names(value)
|
51
65
|
@raw_data = value.clone
|
66
|
+
flatten
|
52
67
|
end
|
53
68
|
|
54
69
|
|
@@ -78,8 +93,9 @@ class HashModel
|
|
78
93
|
@filter = nil
|
79
94
|
end
|
80
95
|
|
81
|
-
# Force arrays to be cloned
|
96
|
+
# Force internal arrays to be cloned
|
82
97
|
def clone
|
98
|
+
flatten
|
83
99
|
hm = HashModel.new(:raw_data=>@raw_data.clone)
|
84
100
|
hm.flatten_index = @flatten_index
|
85
101
|
hm.filter = @filter
|
@@ -125,7 +141,7 @@ class HashModel
|
|
125
141
|
@modified_data == value
|
126
142
|
when Array
|
127
143
|
# test for something other than hashes, a flattened recordset, or raw data
|
128
|
-
if
|
144
|
+
if value.empty? || (value[0].class == Hash && value[0].has_key?(:_group_id))
|
129
145
|
@modified_data == value
|
130
146
|
else
|
131
147
|
@raw_data == value
|
@@ -186,16 +202,19 @@ class HashModel
|
|
186
202
|
# If given a parameter make our own search based on the flatten index
|
187
203
|
unless value.nil?
|
188
204
|
# Make sure the field name is available to the proc
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
205
|
+
case value
|
206
|
+
when String
|
207
|
+
string_search = ":#{@flatten_index} == \"#{value}\"".to_s
|
208
|
+
when Symbol
|
209
|
+
string_search = ":#{@flatten_index} == :#{value}".to_s
|
210
|
+
else
|
211
|
+
string_search = ":#{@flatten_index} == #{value}".to_s
|
193
212
|
end
|
194
213
|
else
|
195
214
|
# Convert the proc to a string so it can be viewed
|
196
215
|
# and later have :'s turned into @'s
|
197
216
|
|
198
|
-
# Sourcify can create single or multi-line procs
|
217
|
+
# Sourcify can create single or multi-line procs so we have to make sure we deal with them accordingly
|
199
218
|
source = search.to_source
|
200
219
|
unless (match = source.match(/^proc do\n(.*)\nend$/))
|
201
220
|
match = source.match(/^proc { (.*) }$/)
|
@@ -261,11 +280,12 @@ class HashModel
|
|
261
280
|
proc_filter.sub!(":_group_id", "@_group_id")
|
262
281
|
proc_filter = "proc { #{proc_filter} }.call"
|
263
282
|
end
|
264
|
-
|
283
|
+
|
265
284
|
# Add the records to modified data if they pass the filter
|
266
285
|
new_records.each do |new_record|
|
267
286
|
unless @filter.nil?
|
268
|
-
|
287
|
+
flat = create_object_from_flat_hash(new_record)
|
288
|
+
@modified_data << new_record if flat.instance_eval proc_filter
|
269
289
|
else
|
270
290
|
@modified_data << new_record
|
271
291
|
end
|
@@ -283,14 +303,21 @@ class HashModel
|
|
283
303
|
|
284
304
|
# Return a string consisting of the flattened data
|
285
305
|
def to_s
|
306
|
+
flatten
|
286
307
|
@modified_data.to_s
|
287
308
|
end
|
288
309
|
|
289
310
|
# Return an array of the flattened data
|
290
311
|
def to_ary
|
312
|
+
flatten
|
291
313
|
@modified_data.to_ary
|
292
314
|
end
|
293
315
|
|
316
|
+
def to_a
|
317
|
+
flatten
|
318
|
+
@modified_data.to_a
|
319
|
+
end
|
320
|
+
|
294
321
|
# Iterate over the flattened records
|
295
322
|
def each
|
296
323
|
@modified_data.each do |record|
|
@@ -452,7 +479,12 @@ class HashModel
|
|
452
479
|
end # input.each
|
453
480
|
when Array
|
454
481
|
input.each do |value|
|
455
|
-
|
482
|
+
case value
|
483
|
+
when Hash
|
484
|
+
recordset, duplicate_data = flatten_hash(value, flatten_index, recordset, duplicate_data, parent_key)
|
485
|
+
else
|
486
|
+
recordset << {parent_key.to_sym=>value}
|
487
|
+
end
|
456
488
|
end
|
457
489
|
else
|
458
490
|
recordset << {parent_key.to_sym=>input}
|
@@ -473,8 +505,9 @@ class HashModel
|
|
473
505
|
hash_record = create_object_from_flat_hash(value, hash_record, flat_key)
|
474
506
|
end
|
475
507
|
when Array
|
508
|
+
hash_record.instance_variable_set("@#{parent_key}", record)
|
476
509
|
record.each do |value|
|
477
|
-
hash_record = create_object_from_flat_hash(value, hash_record, parent_key)
|
510
|
+
hash_record = create_object_from_flat_hash(value, hash_record, parent_key) if value.class == Hash
|
478
511
|
end
|
479
512
|
else
|
480
513
|
hash_record.instance_variable_set("@#{parent_key}", record)
|
data/lib/hash_model/version.rb
CHANGED
File without changes
|
@@ -110,6 +110,45 @@ describe "HashModel" do
|
|
110
110
|
@hm.add(@hm2).should == @flat_records_all
|
111
111
|
end
|
112
112
|
|
113
|
+
it "should add a hash with a symbol as a value" do
|
114
|
+
@hm = HashModel.new
|
115
|
+
@hm << {:switch => :default}
|
116
|
+
@hm.should == [{:switch=>:default, :_id=>0, :_group_id=>0}]
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should add an array with mixed value types" do
|
120
|
+
@records = [
|
121
|
+
{:switch => ["-x", "--xtended", :default], :parameter => {:type => String, :require => true}, :description => "Xish stuff"},
|
122
|
+
{:switch => ["-y", "--why"], :description => "lucky what?"},
|
123
|
+
{:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
|
124
|
+
]
|
125
|
+
@hm = HashModel.new(:raw_data=>@records)
|
126
|
+
@hm.should == [
|
127
|
+
{:switch=>"-x", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
|
128
|
+
{:switch=>"--xtended", :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
|
129
|
+
{:switch=>:default, :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>2, :_group_id=>0},
|
130
|
+
{:switch=>"-y", :description=>"lucky what?", :_id=>3, :_group_id=>1},
|
131
|
+
{:switch=>"--why", :description=>"lucky what?", :_id=>4, :_group_id=>1},
|
132
|
+
{:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>5, :_group_id=>2}
|
133
|
+
]
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should add an array of arrays as values and not recurse into them" do
|
137
|
+
@records = [
|
138
|
+
{ :switch => [ [5, 6], [1, 2] ] }
|
139
|
+
]
|
140
|
+
@hm = HashModel.new(:raw_data=>@records)
|
141
|
+
@hm.should == [{:switch=>[5, 6], :_id=>0, :_group_id=>0}, {:switch=>[1, 2], :_id=>1, :_group_id=>0}]
|
142
|
+
end
|
143
|
+
|
144
|
+
it "shouldn't recurse into arrays with hash values" do
|
145
|
+
@records = [
|
146
|
+
{ :switch => [ [5, 6], [1, :blah=>2] ] }
|
147
|
+
]
|
148
|
+
@hm = HashModel.new(:raw_data=>@records)
|
149
|
+
@hm.should == [{:switch=>[5, 6], :_id=>0, :_group_id=>0}, {:switch=>[1, :blah=>2], :_id=>1, :_group_id=>0}]
|
150
|
+
end
|
151
|
+
|
113
152
|
it "should allow an array of HashModels to be added" do
|
114
153
|
@hm.add([@hm, @hm2])
|
115
154
|
@hm.should == [
|
@@ -433,6 +472,27 @@ describe "HashModel" do
|
|
433
472
|
@hm.flatten_index = :description
|
434
473
|
end.should change(@hm, :flatten_index).from(:switch).to(:description)
|
435
474
|
end
|
475
|
+
|
476
|
+
it "should throw an error if an invalid flatten index is given" do
|
477
|
+
@records = [
|
478
|
+
{ :switch => [ [5, 6], [1, :blah=>2] ] }
|
479
|
+
]
|
480
|
+
@hm = HashModel.new(:raw_data=>@records)
|
481
|
+
proc {@hm.flatten_index = :switch__blah}.should raise_error(ArgumentError)
|
482
|
+
end
|
483
|
+
|
484
|
+
it "shouldn't throw an error if a valid flatten index is given" do
|
485
|
+
proc {@hm.flatten_index = :parameter__type}.should_not raise_error
|
486
|
+
end
|
487
|
+
|
488
|
+
it "should reset the flatten index if an invalid flatten index is given" do
|
489
|
+
@records = [
|
490
|
+
{ :switch => [ [5, 6], [1, :blah=>2] ] }
|
491
|
+
]
|
492
|
+
@hm = HashModel.new(:raw_data=>@records)
|
493
|
+
proc {@hm.flatten_index = :switch__blah}.should raise_error(ArgumentError)
|
494
|
+
@hm.flatten_index.should == :switch
|
495
|
+
end
|
436
496
|
|
437
497
|
it "should set the flatten index when adding to an empty HashModel" do
|
438
498
|
@hm.flatten_index.should == :switch
|
@@ -548,6 +608,11 @@ describe "HashModel" do
|
|
548
608
|
(@hm <=> "potato").should == nil
|
549
609
|
end
|
550
610
|
|
611
|
+
it "should compare to an empty array" do
|
612
|
+
@hm.where!("potato")
|
613
|
+
@hm.should == []
|
614
|
+
end
|
615
|
+
|
551
616
|
end # comparisons
|
552
617
|
|
553
618
|
describe "searching and selecting records" do
|
@@ -569,7 +634,48 @@ describe "HashModel" do
|
|
569
634
|
it "should return the same hash model when calling where" do
|
570
635
|
@hm.where!("-x").object_id.should == @hm.object_id
|
571
636
|
end
|
572
|
-
|
637
|
+
|
638
|
+
it "should return the entire flattened recordset if nothing is sent" do
|
639
|
+
@hm.where!("-x")
|
640
|
+
@hm.should == [@flat_records[0]]
|
641
|
+
@hm.where!
|
642
|
+
@hm.should == @flat_records
|
643
|
+
end
|
644
|
+
|
645
|
+
end
|
646
|
+
|
647
|
+
context "non-string search values" do
|
648
|
+
|
649
|
+
it "should search using the flatten_index if a symbol is used with where" do
|
650
|
+
@records = [
|
651
|
+
{:switch => ["-x", "--xtended", :default], :parameter => {:type => String, :require => true}, :description => "Xish stuff"},
|
652
|
+
{:switch => ["-y", "--why"], :description => "lucky what?"},
|
653
|
+
{:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz"},
|
654
|
+
]
|
655
|
+
@hm = HashModel.new(:raw_data=>@records)
|
656
|
+
@hm.where(:default).should == [{:switch=>:default, :parameter=>{:type=>String, :require=>true}, :description=>"Xish stuff", :_id=>2, :_group_id=>0}]
|
657
|
+
end
|
658
|
+
|
659
|
+
it "should search using an array" do
|
660
|
+
@records = [
|
661
|
+
{ :switch => [ [5,6], [1,2] ] }
|
662
|
+
]
|
663
|
+
@hm = HashModel.new(:raw_data=>@records)
|
664
|
+
@hm.where([1,2]).should == [{:switch=>[1,2], :_id=>1, :_group_id=>0}]
|
665
|
+
end
|
666
|
+
|
667
|
+
it "should search using an array including a hash" do
|
668
|
+
@records = [
|
669
|
+
{ :switch => [ [5,6], [1,:blah=>2] ] }
|
670
|
+
]
|
671
|
+
@hm = HashModel.new(:raw_data=>@records)
|
672
|
+
@hm.where([1,:blah=>2]).should == [{:switch=>[1,:blah=>2], :_id=>1, :_group_id=>0}]
|
673
|
+
end
|
674
|
+
|
675
|
+
end
|
676
|
+
|
677
|
+
context "filtering records" do
|
678
|
+
|
573
679
|
it "should filter the recordset" do
|
574
680
|
@hm.where!("-x")
|
575
681
|
@hm.should == [@flat_records[0]]
|
@@ -596,14 +702,7 @@ describe "HashModel" do
|
|
596
702
|
proc {@hm.where!}.should change(@hm, :filtered?).from(true).to(false)
|
597
703
|
end
|
598
704
|
|
599
|
-
|
600
|
-
@hm.where!("-x")
|
601
|
-
@hm.should == [@flat_records[0]]
|
602
|
-
@hm.where!
|
603
|
-
@hm.should == @flat_records
|
604
|
-
end
|
605
|
-
|
606
|
-
end # in place
|
705
|
+
end # filtering
|
607
706
|
|
608
707
|
context "not in place" do
|
609
708
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
$: << '.'
|
2
2
|
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "/../lib"))
|
3
|
-
require '
|
3
|
+
require 'hashmodel'
|
4
4
|
require 'rspec'
|
5
5
|
require 'rspec/matchers'
|
6
6
|
|
@@ -28,7 +28,7 @@ module Kernel
|
|
28
28
|
def dp(value)
|
29
29
|
puts ""
|
30
30
|
puts "*" * 40
|
31
|
-
puts
|
31
|
+
puts value
|
32
32
|
puts "&" * 40
|
33
33
|
puts ""
|
34
34
|
end
|
metadata
CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 0
|
7
7
|
- 3
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.3.0.
|
9
|
+
- beta2
|
10
|
+
version: 0.3.0.beta2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mike Bethany
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-11 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -88,10 +88,12 @@ files:
|
|
88
88
|
- LICENSE.txt
|
89
89
|
- README.markdown
|
90
90
|
- Rakefile
|
91
|
+
- _brainstorm/_readme
|
91
92
|
- _brainstorm/block_wheres.rb
|
92
93
|
- _brainstorm/clone.rb
|
93
94
|
- _brainstorm/hash_model_examples.rb
|
94
95
|
- _brainstorm/hash_test.rb
|
96
|
+
- _brainstorm/inspect.rb
|
95
97
|
- _brainstorm/instance_vars.rb
|
96
98
|
- _brainstorm/proc_tests.rb
|
97
99
|
- _brainstorm/ref_val.rb
|
@@ -108,10 +110,10 @@ files:
|
|
108
110
|
- features/support/env.rb
|
109
111
|
- features/support/helper.rb
|
110
112
|
- hashmodel.gemspec
|
111
|
-
- lib/hash_model.rb
|
112
113
|
- lib/hash_model/exceptions.rb
|
113
114
|
- lib/hash_model/hash_model.rb
|
114
115
|
- lib/hash_model/version.rb
|
116
|
+
- lib/hashmodel.rb
|
115
117
|
- spec/hash_model/hash_model_spec.rb
|
116
118
|
- spec/spec_helper.rb
|
117
119
|
has_rdoc: true
|