hashmodel 0.3.0.beta1 → 0.3.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.
- 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
|