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
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashModel do
4
+
5
+
6
+ context "when using array methods and properties" do
7
+
8
+ it "should return an array when calling to_ary" do
9
+ @hm.to_ary.class.should == Array
10
+ end
11
+
12
+ it "should not return a HashModel when calling to_ary" do
13
+ @hm.to_ary.class.should_not == HashModel
14
+ end
15
+
16
+ it "should return the flat records when calling to_ary" do
17
+ @hm.to_ary.should == @flat_records
18
+ end
19
+
20
+ it "should return an array when calling to_a" do
21
+ @hm.to_a.class.should == Array
22
+ end
23
+
24
+ it "should not return a HashModel when calling to_a" do
25
+ @hm.to_a.class.should_not == HashModel
26
+ end
27
+
28
+ it "should return the flat records when calling to_a" do
29
+ @hm.to_a.should == @flat_records
30
+ end
31
+
32
+ it "should report the length of the flat data" do
33
+ @hm.length.should == @flat_records.length
34
+ end
35
+
36
+ it "should report the size of the flat data" do
37
+ @hm.size.should == @flat_records.size
38
+ end
39
+
40
+ it "should return the correct flat record when using at" do
41
+ @hm.at(0).should == @flat_records[0]
42
+ @hm.at(2).should == @flat_records[2]
43
+ end
44
+
45
+ it "should collect across the flat data" do
46
+ extra = -1
47
+ @hm.collect {|record| record.merge!(:extra=>extra+=1)}.should == [
48
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0, :extra=>0},
49
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0, :extra=>1},
50
+ {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1, :extra=>2},
51
+ {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1, :extra=>3},
52
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2, :extra=>4}
53
+ ]
54
+ end
55
+
56
+ it "should map across the flat data" do
57
+ extra = -1
58
+ @hm.map {|record| record.merge!(:extra=>extra+=1)}.should == [
59
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0, :extra=>0},
60
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0, :extra=>1},
61
+ {:switch=>"-y", :description=>"lucky what?", :_id=>2, :_group_id=>1, :extra=>2},
62
+ {:switch=>"--why", :description=>"lucky what?", :_id=>3, :_group_id=>1, :extra=>3},
63
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>4, :_group_id=>2, :extra=>4}
64
+ ]
65
+ end
66
+
67
+ it "should combination'ize the flat data" do
68
+ hm_combo = []
69
+ flat_combo = []
70
+ @hm.combination(2).each { |record| hm_combo << record }
71
+ @flat_records.combination(2) { |record| flat_combo << record }
72
+ hm_combo.should == flat_combo
73
+ end
74
+
75
+ it "should count the flat data" do
76
+ @hm.count.should == @flat_records.count
77
+ end
78
+
79
+ it "should cycle over the flat data" do
80
+ cycle = cycle2 = []
81
+ @hm.cycle(2) {|record| cycle << record}
82
+ @flat_records.cycle(2) {|record| cycle2 << record}
83
+ cycle.should == cycle2
84
+ end
85
+
86
+ it "should iterate with an index" do
87
+ collect = []
88
+ @hm.each_index {|index| collect << @hm[index][:switch]}
89
+ collect.should == ["-x", "--xtended", "-y", "--why", "-z"]
90
+ end
91
+
92
+ it "should say if it's empty" do
93
+ @hm = HashModel.new
94
+ @hm.empty?.should == true
95
+ @hm << @records[0]
96
+ @hm.empty?.should == false
97
+ end
98
+
99
+ it "should fetch records given an index" do
100
+ @hm.fetch(2).should == @flat_records[2]
101
+ end
102
+
103
+ it "should return the default value if fetch index is out of bounds" do
104
+ @hm.fetch(10, "potato").should == "potato"
105
+ end
106
+
107
+ it "should run a block if fetch index is out of bounds" do
108
+ (@hm.fetch(10) {|index| index }).should == 10
109
+ end
110
+
111
+ it "should return the first flattened record" do
112
+ @hm.first.should == @flat_records.first
113
+ end
114
+
115
+ it "should return the last flattened record" do
116
+ @hm.last.should == @flat_records.last
117
+ end
118
+
119
+ it "should freeze the raw records" do
120
+ proc{@hm.freeze}.should change(@hm.raw_data,:frozen?)
121
+ .from(false)
122
+ .to(true)
123
+ end
124
+
125
+ it "should permutate over the flat data" do
126
+ @hm.permutation(2).to_a.should == @flat_records.permutation(2).to_a
127
+ @hm.permutation.to_a.should == @flat_records.permutation.to_a
128
+ @hm.permutation.to_a.should_not == @records.permutation.to_a
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashModel do
4
+
5
+ context "when making comparisons" do
6
+
7
+ it "should allow arrays to be compared to the HashModel" do
8
+ @hm.should == @flat_records
9
+ end
10
+
11
+ it "should allow HashModels to be compared to the HashModel" do
12
+ hm2 = HashModel.new(:raw_data=>@records)
13
+ @hm.should == hm2
14
+ end
15
+
16
+ it "should compare using the raw data if sent an array without group_id's or id's" do
17
+ @hm.should == @records
18
+ end
19
+
20
+ it "should return false if compared to something other than an Array or a HashModel" do
21
+ @hm.should_not == "potato"
22
+ end
23
+
24
+ it "should allow arrays to be compared to the HashModel using eql?" do
25
+ @hm.eql?(@hm).should == true
26
+ end
27
+
28
+ it "should return false if compared to an array of something other than hashes" do
29
+ @hm.should_not == ["potato"]
30
+ end
31
+
32
+ it "should use flattened records if <=>'d with an array with a group_id" do
33
+ (@hm <=> @flat_records).should == 0
34
+ end
35
+
36
+ it "should use flattened records if <=>'d with an array without a group_id" do
37
+ (@hm <=> @records).should == 0
38
+ end
39
+
40
+ it "should use flattened data if <=>'d with another HashModel" do
41
+ hm2 = @hm.clone
42
+ (@hm <=> hm2).should == 0
43
+ end
44
+
45
+ it "should return nil if <=>'d with something other than an Array or a HashModel" do
46
+ (@hm <=> "potato").should == nil
47
+ end
48
+
49
+ it "should compare to an empty array" do
50
+ @hm.where!("potato")
51
+ @hm.should == []
52
+ end
53
+
54
+ end # comparisons
55
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashModel do
4
+
5
+ context "when deleting records" do
6
+
7
+ context "and doing it destructively" do
8
+ it "should delete the raw record the child record is based on" do
9
+ hm = HashModel.new << @records[1] << @records[2]
10
+ @hm.delete!("-x")
11
+ @hm.should == hm
12
+ end
13
+ it "should delete all the parents if there are more than one base on the search" do
14
+ hm = HashModel.new(:raw_data=>@records[1])
15
+ @hm.delete!{:parameter__type == String}
16
+ @hm.should == hm
17
+ end
18
+ it "returns the parent records that are deleted" do
19
+ @hm.delete!{:parameter__type == String}.should == [@records[0], @records[2]]
20
+ end
21
+ end
22
+
23
+ context "NON-destructively" do
24
+ # Arrays returns the records deleted, not the original array minus the deletion.
25
+ # The class now mimics that behavior to be less surprising and more Ruby like.
26
+
27
+ it "should delete the raw record the child record is based on" do
28
+ hm = HashModel.new << @records[1] << @records[2]
29
+ @hm.delete("-x")
30
+ @hm.should_not == hm
31
+ end
32
+ it "should delete all the parents if there are more than one base on the search" do
33
+ hm = HashModel.new(:raw_data=>@records[1])
34
+ @hm.delete{:parameter__type == String}
35
+ @hm.should_not == hm
36
+ end
37
+ it "should delete the raw record the child record is based on" do
38
+ hm = HashModel.new << @records[0]
39
+ hm2 = @hm.delete("-x")
40
+ hm2.should == hm
41
+ end
42
+ it "should delete all the parents if there are more than one base on the search" do
43
+ hm = HashModel.new(:raw_data=>[@records[0], @records[2]])
44
+ hm2 = @hm.delete{:parameter__type == String}
45
+ hm2.should == hm
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashModel do
4
+
5
+ context "when flattening" do
6
+
7
+ it "should set the first field given as the default flatten index" do
8
+ @hm << {:switch => ["-x", "--xtended"], :description => "Xish stuff"}
9
+ @hm.add(:description => "blah,blah,blah")
10
+ @hm.flatten_index.should == :switch
11
+ end
12
+
13
+ it "should set the flatten index properly if specified using parameter :flatten_index" do
14
+ @hm = HashModel.new(:raw_data=>@records, :flatten_index=>:parameter)
15
+ @hm.should == [
16
+ {:parameter=>{:type=>String}, :switch=>["-x", "--xtended"], :description=>"Xish stuff", :_id=>0, :_group_id=>0},
17
+ {:parameter=>{:required=>true}, :switch=>["-x", "--xtended"], :description=>"Xish stuff", :_id=>1, :_group_id=>0},
18
+ {:parameter=>nil, :switch=>["-y", "--why"], :description=>"lucky what?", :_id=>2, :_group_id=>1},
19
+ {:parameter=>{:type=>String}, :switch=>"-z", :description=>"zee svitch zu moost calz", :_id=>3, :_group_id=>2}
20
+ ]
21
+
22
+ end
23
+
24
+ it "should allow you to change the flatten index" do
25
+ @hm << {:switch => ["-x", "--xtended"], :description => "Xish stuff"}
26
+ proc do
27
+ @hm.flatten_index = :description
28
+ end.should change(@hm, :flatten_index).from(:switch).to(:description)
29
+ end
30
+
31
+ it "should throw an error if an invalid flatten index is given" do
32
+ @records = [
33
+ { :switch => [ [5, 6], [1, :blah=>2] ] }
34
+ ]
35
+ @hm = HashModel.new(:raw_data=>@records)
36
+ proc {@hm.flatten_index = :switch__blah}.should raise_error(ArgumentError)
37
+ end
38
+
39
+ it "shouldn't throw an error if a valid flatten index is given" do
40
+ proc {@hm.flatten_index = :parameter__type}.should_not raise_error
41
+ end
42
+
43
+ it "should reset the flatten index if an invalid flatten index is given" do
44
+ @records = [
45
+ { :switch => [ [5, 6], [1, :blah=>2] ] }
46
+ ]
47
+ @hm = HashModel.new(:raw_data=>@records)
48
+ proc {@hm.flatten_index = :switch__blah}.should raise_error(ArgumentError)
49
+ @hm.flatten_index.should == :switch
50
+ end
51
+
52
+ it "should set the flatten index when adding to an empty HashModel" do
53
+ @hm.flatten_index.should == :switch
54
+ end
55
+
56
+ it "should assign the flattened data to self correctly when adding records using <<" do
57
+ @hm = HashModel.new
58
+ @hm << @records[0]
59
+ @hm << @records[1]
60
+ @hm << @records[2]
61
+ @hm.should == @flat_records
62
+ end
63
+
64
+ it "should assign the flattened data to self correctly when adding with :raw_data=>records" do
65
+ @hm.should == @flat_records
66
+ end
67
+
68
+ it "should add a nil value for the field index for records that don't have a field with the field index" do
69
+ @hm = HashModel.new
70
+ @hm << @records[0]
71
+ @hm << {:foo=>"bar"}
72
+ @hm.last.should == {:switch=>nil, :foo=>"bar", :_id=>2, :_group_id=>1}
73
+ end
74
+
75
+ it "should change the flattened data when changing the flatten index" do
76
+ @hm = HashModel.new(:raw_data=>@records)
77
+ @hm.flatten_index = :parameter__type
78
+ @hm.should == [
79
+ {:parameter__type=>String, :switch=>["-x", "--xtended"], :parameter__required=>true, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
80
+ {:parameter__type=>nil, :switch=>["-y", "--why"], :description=>"lucky what?", :_id=>1, :_group_id=>1},
81
+ {:parameter__type=>String, :switch=>"-z", :description=>"zee svitch zu moost calz", :_id=>2, :_group_id=>2}
82
+ ]
83
+ end
84
+
85
+ it "should update the flattened data if the raw data is changed" do
86
+ @hm.raw_data = @records2.clone
87
+ @hm.should == @flat_records2
88
+ end
89
+
90
+ end # flattening behvior
91
+
92
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashModel do
4
+
5
+ context "when grouping" do
6
+
7
+ it "should return a HashModel object" do
8
+ @hm.group("-x").class.should == HashModel
9
+ end
10
+
11
+ it "should return a different HashModel object" do
12
+ @hm.group("-x").object_id.should_not == @hm.object_id
13
+ end
14
+
15
+ it "should return the records in the same raw data record when using a parameter" do
16
+ @hm.group("-x").should == [@flat_records[0], @flat_records[1]]
17
+ end
18
+
19
+ it "should be chainable on a filtered HashModel" do
20
+ # Doesn't make logical sense anymore to do it this way since
21
+ # when you #where the HashModel you've deleted all the other data
22
+ # Just use group like a #group like a where like above
23
+ # @hm.where("-x").group.should == [@flat_records[0],@flat_records[1]]
24
+ end
25
+
26
+ it "should return the records in the same raw data record when using a block" do
27
+ @hm.group{:switch == "-y"}.should == [@flat_records[2], @flat_records[3]]
28
+ end
29
+
30
+ it "should group across group_id's if searching for something that returns records from multiple groups" do
31
+ @hm.group{:parameter__type == String}.should == [
32
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
33
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
34
+ {:switch => "-z", :parameter => {:type => String}, :description => "zee svitch zu moost calz", :_id=>4, :_group_id=>2}
35
+ ]
36
+ end
37
+
38
+ it "should group with a complex block" do
39
+ records = [
40
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
41
+ {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
42
+ {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
43
+ ]
44
+ @hm = HashModel.new(:raw_data=>records)
45
+ @hm.group {(:parameter__type == String && :parameter__required == true && :something == 4) || :something == 7}.should == [
46
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
47
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
48
+ {:switch=>"-y", :description=>"lucky what?", :something=>7, :_id=>2, :_group_id=>1},
49
+ {:switch=>"--why", :description=>"lucky what?", :something=>7, :_id=>3, :_group_id=>1}
50
+ ]
51
+ end
52
+
53
+ it "should group with nested hashes block" do
54
+ records = [
55
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
56
+ {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
57
+ {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
58
+ ]
59
+ @hm = HashModel.new(:raw_data=>records)
60
+ @hm.group {:parameter == {:type => String, :required => true}}.should == [
61
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
62
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0}
63
+ ]
64
+ end
65
+
66
+ end # grouping
67
+ end
@@ -0,0 +1,245 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashModel do
4
+
5
+ context "when 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
+ end # filtering
108
+
109
+ context "not in place" do
110
+
111
+ it "should return a HashModel object" do
112
+ @hm = HashModel.new(:raw_data=>@records)
113
+ @hm.where("-x").class.should == HashModel
114
+ end
115
+
116
+ it "should return a new HashModel" do
117
+ @hm.where("-x").object_id.should_not == @hm.object_id
118
+ end
119
+
120
+ it "should search the flatten index if given a parameter" do
121
+ @hm = HashModel.new(:raw_data=>@records)
122
+ @hm.where("-x").should == [@flat_records[0]]
123
+ end
124
+
125
+ it "should search the flatten index if given a block" do
126
+ @hm.where{@parameter__type == String}.should == [
127
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>0, :_group_id=>0},
128
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :_id=>1, :_group_id=>0},
129
+ {:switch=>"-z", :parameter=>{:type=>String}, :description=>"zee svitch zu moost calz", :_id=>2, :_group_id=>1}
130
+ ]
131
+ end
132
+
133
+ end # not in place
134
+
135
+ context "using blocks" do
136
+
137
+ it "should search using a single value boolean block" do
138
+ @hm.where {:switch == "-x"}.should == [@flat_records[0]]
139
+ end
140
+
141
+ it "should search using a complex boolean block" do
142
+ records = [
143
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
144
+ {:switch => ["-y", "--why"], :description => "lucky what?"},
145
+ {:switch => "-z", :parameter => {:type => String, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
146
+ ]
147
+ @hm = HashModel.new(:raw_data=>records)
148
+ @hm.where {:something == 4 && :parameter__required == true}.should == [
149
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
150
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
151
+ {:switch=>"-z", :parameter=>{:type=>String, :required=>true}, :description=>"zee svitch zu moost calz", :something=>4, :_id=>2, :_group_id=>1}
152
+ ]
153
+ end
154
+
155
+ it "should search a complex boolean block regardless of order" do
156
+ records = [
157
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
158
+ {:switch => ["-y", "--why"], :description => "lucky what?"},
159
+ {:switch => "-z", :parameter => {:type => String, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
160
+ ]
161
+ @hm = HashModel.new(:raw_data=>records)
162
+ @hm.where {:parameter__type == String && :parameter__required == true && :something == 4}.should == [
163
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
164
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
165
+ {:switch=>"-z", :parameter=>{:type=>String, :required=>true}, :description=>"zee svitch zu moost calz", :something=>4, :_id=>2, :_group_id=>1}
166
+ ]
167
+ end
168
+
169
+ it "should search using a complex, multi-line boolean block" do
170
+ records = [
171
+ {:switch => ["-x", "--xtended"], :parameter => {:type => String, :required => true}, :description => "Xish stuff", :something => 4},
172
+ {:switch => ["-y", "--why"], :description => "lucky what?", :something => 7},
173
+ {:switch => "-z", :parameter => {:type => Integer, :required => true}, :description => "zee svitch zu moost calz", :something => 4},
174
+ ]
175
+ @hm = HashModel.new(:raw_data=>records)
176
+ @hm.where {(:parameter__type == String && :parameter__required == true && :something == 4) || :something == 7}.should == [
177
+ {:switch=>"-x", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>0, :_group_id=>0},
178
+ {:switch=>"--xtended", :parameter=>{:type=>String, :required=>true}, :description=>"Xish stuff", :something=>4, :_id=>1, :_group_id=>0},
179
+ {:switch=>"-y", :description=>"lucky what?", :something=>7, :_id=>2, :_group_id=>1},
180
+ {:switch=>"--why", :description=>"lucky what?", :something=>7, :_id=>3, :_group_id=>1}
181
+ ]
182
+ end
183
+
184
+ it "should search with nested hashes in a 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, :required => true}}.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
+ ]
195
+ end
196
+
197
+ end
198
+
199
+ context "searching for the parent" do
200
+ it "should return the raw record the child record is based on" do
201
+ @hm.parents("-x").should == [@records[0]]
202
+ end
203
+ it "should return all the parents if there are more than one base on the search" do
204
+ @hm.parents{:parameter__type == String}.should == [@records[0],@records[2]]
205
+ end
206
+ end
207
+
208
+ it "should return false if tested for inclusion of anything other than a hash" do
209
+ @hm.include?([:switch=>"-x"]).should == false
210
+ end
211
+
212
+ it "should match flat data if search criteria includes an _group_id field" do
213
+ @hm.include?(@flat_records[2]).should == true
214
+ end
215
+
216
+ it "should search raw data if search criteria includes an _group_id field" do
217
+ @hm.include?(@records[2]).should == true
218
+ end
219
+
220
+ it "should return the flattened record index using the index method" do
221
+ @hm.index(@flat_records[3]).should == 3
222
+ end
223
+
224
+ context "when using take" do
225
+ it "should return the first n flat records" do
226
+ @hm.take(2).should == @flat_records.take(2)
227
+ end
228
+
229
+ it "should return the first n flat records while block is true" do
230
+ @hm.take_while {|record| record[:_id] < 4}.should == @flat_records[0..3]
231
+ end
232
+
233
+ end
234
+
235
+ it "should return values at x,y,z" do
236
+ @hm.values_at(1,3,5).should == @flat_records.values_at(1,3,5)
237
+ end
238
+
239
+ it "should zip things" do
240
+ hm2 = HashModel.new(:raw_data=>@records2)
241
+ @hm.zip(hm2).should == @flat_records.zip(@flat_records2)
242
+ end
243
+
244
+ end # searching records
245
+ end