massive_record 0.1.0

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 (81) hide show
  1. data/.autotest +15 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +38 -0
  6. data/Manifest +24 -0
  7. data/README.md +225 -0
  8. data/Rakefile +16 -0
  9. data/TODO.md +8 -0
  10. data/autotest/discover.rb +1 -0
  11. data/lib/massive_record.rb +18 -0
  12. data/lib/massive_record/exceptions.rb +11 -0
  13. data/lib/massive_record/orm/attribute_methods.rb +61 -0
  14. data/lib/massive_record/orm/attribute_methods/dirty.rb +80 -0
  15. data/lib/massive_record/orm/attribute_methods/read.rb +23 -0
  16. data/lib/massive_record/orm/attribute_methods/write.rb +24 -0
  17. data/lib/massive_record/orm/base.rb +176 -0
  18. data/lib/massive_record/orm/callbacks.rb +52 -0
  19. data/lib/massive_record/orm/column.rb +18 -0
  20. data/lib/massive_record/orm/config.rb +47 -0
  21. data/lib/massive_record/orm/errors.rb +47 -0
  22. data/lib/massive_record/orm/finders.rb +125 -0
  23. data/lib/massive_record/orm/id_factory.rb +133 -0
  24. data/lib/massive_record/orm/persistence.rb +199 -0
  25. data/lib/massive_record/orm/schema.rb +4 -0
  26. data/lib/massive_record/orm/schema/column_families.rb +48 -0
  27. data/lib/massive_record/orm/schema/column_family.rb +102 -0
  28. data/lib/massive_record/orm/schema/column_interface.rb +91 -0
  29. data/lib/massive_record/orm/schema/common_interface.rb +48 -0
  30. data/lib/massive_record/orm/schema/field.rb +128 -0
  31. data/lib/massive_record/orm/schema/fields.rb +37 -0
  32. data/lib/massive_record/orm/schema/table_interface.rb +96 -0
  33. data/lib/massive_record/orm/table.rb +9 -0
  34. data/lib/massive_record/orm/validations.rb +52 -0
  35. data/lib/massive_record/spec/support/simple_database_cleaner.rb +52 -0
  36. data/lib/massive_record/thrift/hbase.rb +2307 -0
  37. data/lib/massive_record/thrift/hbase_constants.rb +14 -0
  38. data/lib/massive_record/thrift/hbase_types.rb +225 -0
  39. data/lib/massive_record/version.rb +3 -0
  40. data/lib/massive_record/wrapper/base.rb +28 -0
  41. data/lib/massive_record/wrapper/cell.rb +45 -0
  42. data/lib/massive_record/wrapper/column_families_collection.rb +19 -0
  43. data/lib/massive_record/wrapper/column_family.rb +22 -0
  44. data/lib/massive_record/wrapper/connection.rb +71 -0
  45. data/lib/massive_record/wrapper/row.rb +170 -0
  46. data/lib/massive_record/wrapper/scanner.rb +50 -0
  47. data/lib/massive_record/wrapper/table.rb +148 -0
  48. data/lib/massive_record/wrapper/tables_collection.rb +13 -0
  49. data/massive_record.gemspec +28 -0
  50. data/spec/config.yml.example +4 -0
  51. data/spec/orm/cases/attribute_methods_spec.rb +47 -0
  52. data/spec/orm/cases/auto_generate_id_spec.rb +54 -0
  53. data/spec/orm/cases/base_spec.rb +176 -0
  54. data/spec/orm/cases/callbacks_spec.rb +309 -0
  55. data/spec/orm/cases/column_spec.rb +49 -0
  56. data/spec/orm/cases/config_spec.rb +103 -0
  57. data/spec/orm/cases/dirty_spec.rb +129 -0
  58. data/spec/orm/cases/encoding_spec.rb +49 -0
  59. data/spec/orm/cases/finders_spec.rb +208 -0
  60. data/spec/orm/cases/hbase/connection_spec.rb +13 -0
  61. data/spec/orm/cases/i18n_spec.rb +32 -0
  62. data/spec/orm/cases/id_factory_spec.rb +75 -0
  63. data/spec/orm/cases/persistence_spec.rb +479 -0
  64. data/spec/orm/cases/table_spec.rb +81 -0
  65. data/spec/orm/cases/validation_spec.rb +92 -0
  66. data/spec/orm/models/address.rb +7 -0
  67. data/spec/orm/models/person.rb +15 -0
  68. data/spec/orm/models/test_class.rb +5 -0
  69. data/spec/orm/schema/column_families_spec.rb +186 -0
  70. data/spec/orm/schema/column_family_spec.rb +131 -0
  71. data/spec/orm/schema/column_interface_spec.rb +115 -0
  72. data/spec/orm/schema/field_spec.rb +196 -0
  73. data/spec/orm/schema/fields_spec.rb +126 -0
  74. data/spec/orm/schema/table_interface_spec.rb +171 -0
  75. data/spec/spec_helper.rb +15 -0
  76. data/spec/support/connection_helpers.rb +76 -0
  77. data/spec/support/mock_massive_record_connection.rb +80 -0
  78. data/spec/thrift/cases/encoding_spec.rb +48 -0
  79. data/spec/wrapper/cases/connection_spec.rb +53 -0
  80. data/spec/wrapper/cases/table_spec.rb +231 -0
  81. metadata +228 -0
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ class TestColumnInterface
4
+ include MassiveRecord::ORM::Schema::ColumnInterface
5
+ end
6
+
7
+ describe MassiveRecord::ORM::Schema::TableInterface do
8
+ after do
9
+ TestColumnInterface.fields = nil
10
+ end
11
+
12
+ it "should respond_to default_attributes_from_schema" do
13
+ TestColumnInterface.should respond_to :default_attributes_from_schema
14
+ end
15
+
16
+ it "should have fields set to nil if no fields are defined" do
17
+ TestColumnInterface.fields.should be_nil
18
+ end
19
+
20
+ it "should have one field if one field is added" do
21
+ class TestColumnInterface
22
+ field :field_name, :string
23
+ end
24
+
25
+ TestColumnInterface.should have(1).fields
26
+ TestColumnInterface.fields.first.name.should == "field_name"
27
+ end
28
+
29
+ it "should not be possible to have to fields with the same name" do
30
+ lambda {
31
+ class TestColumnInterface
32
+ field :will_raise_error
33
+ field :will_raise_error
34
+ end
35
+ }.should raise_error MassiveRecord::ORM::Schema::InvalidField
36
+ end
37
+
38
+ it "should return attributes schema based on DSL" do
39
+ class TestColumnInterface
40
+ field :name
41
+ field :age, :integer, :default => 1
42
+ end
43
+
44
+ TestColumnInterface.attributes_schema["name"].type.should == :string
45
+ TestColumnInterface.attributes_schema["age"].type.should == :integer
46
+ TestColumnInterface.attributes_schema["age"].default.should == 1
47
+ end
48
+
49
+ it "should make attributes_schema readable from instances" do
50
+ class TestColumnInterface
51
+ field :name
52
+ end
53
+
54
+ TestColumnInterface.new.attributes_schema["name"].type.should == :string
55
+ end
56
+
57
+ it "should have a list of known attribute names" do
58
+ class TestColumnInterface
59
+ field :name, :string
60
+ field :age, :integer
61
+ end
62
+
63
+ TestColumnInterface.should have(2).known_attribute_names
64
+ TestColumnInterface.known_attribute_names.should include("name", "age")
65
+ end
66
+
67
+ it "should give us default attributes from schema" do
68
+ class TestColumnInterface
69
+ field :name
70
+ field :age, :integer, :default => 1
71
+ end
72
+
73
+ defaults = TestColumnInterface.default_attributes_from_schema
74
+ defaults["name"].should be_nil
75
+ defaults["age"].should == 1
76
+ end
77
+
78
+
79
+ describe "dynamically adding a field" do
80
+ it "should be possible to dynamically add a field" do
81
+ TestColumnInterface.add_field :name, :default => "NA"
82
+
83
+ TestColumnInterface.should have(1).fields
84
+
85
+ field = TestColumnInterface.fields.first
86
+
87
+ field.name.should == "name"
88
+ field.default.should == "NA"
89
+ end
90
+
91
+ it "should be possible to set field's type just like the DSL" do
92
+ TestColumnInterface.add_field :age, :integer, :default => 0
93
+
94
+ TestColumnInterface.fields.first.name.should == "age"
95
+ TestColumnInterface.fields.first.type.should == :integer
96
+ TestColumnInterface.fields.first.default.should == 0
97
+ end
98
+
99
+ it "should call class' undefine_attribute_methods to make sure it regenerates for newly added" do
100
+ TestColumnInterface.should_receive(:undefine_attribute_methods)
101
+ TestColumnInterface.add_field :name, :default => "NA"
102
+ end
103
+
104
+ it "should return the new field" do
105
+ field = TestColumnInterface.add_field :age, :integer, :default => 0
106
+ field.should == TestColumnInterface.fields.first
107
+ end
108
+
109
+ it "should insert the new field's default value right away" do
110
+ test_interface = TestColumnInterface.new
111
+ test_interface.should_receive("age=").with(1)
112
+ test_interface.add_field :age, :integer, :default => 1
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,196 @@
1
+ require 'spec_helper'
2
+
3
+ describe MassiveRecord::ORM::Schema::Field do
4
+ describe "initializer" do
5
+ %w(name column default).each do |attr_name|
6
+ it "should set #{attr_name}" do
7
+ field = MassiveRecord::ORM::Schema::Field.new attr_name => "a_value"
8
+ field.send(attr_name).should == "a_value"
9
+ end
10
+ end
11
+
12
+ it "should set type, cast it to a symbol" do
13
+ MassiveRecord::ORM::Schema::Field.new(:type => "a_value").type.should == :a_value
14
+ end
15
+
16
+ it "should default to type string" do
17
+ MassiveRecord::ORM::Schema::Field.new(:name => "a_value").type.should == :string
18
+ end
19
+ end
20
+
21
+ describe "new_with_arguments_from_dsl" do
22
+ it "should take the first argument as name" do
23
+ field = MassiveRecord::ORM::Schema::Field.new_with_arguments_from_dsl("info")
24
+ field.name.should == "info"
25
+ end
26
+
27
+ it "should take the second argument as type" do
28
+ field = MassiveRecord::ORM::Schema::Field.new_with_arguments_from_dsl("info", "integer")
29
+ field.type.should == :integer
30
+ end
31
+
32
+ it "should take the rest as options" do
33
+ field = MassiveRecord::ORM::Schema::Field.new_with_arguments_from_dsl("info", "integer", :default => 0)
34
+ field.default.should == 0
35
+ end
36
+ end
37
+
38
+ describe "validations" do
39
+ before do
40
+ @fields = MassiveRecord::ORM::Schema::Fields.new
41
+ @field = MassiveRecord::ORM::Schema::Field.new :name => "field_name", :fields => @fields
42
+ end
43
+
44
+ it "should be valid from before hook" do
45
+ @field.should be_valid
46
+ end
47
+
48
+ it "should not be valid if name is blank" do
49
+ @field.send(:name=, nil)
50
+ @field.should_not be_valid
51
+ end
52
+
53
+ it "should not be valid without fields to belong to" do
54
+ @field.fields = nil
55
+ @field.should_not be_valid
56
+ end
57
+
58
+ it "should not be valid if it's parent some how knows that it's name has been taken" do
59
+ @fields.should_receive(:attribute_name_taken?).with("field_name").and_return true
60
+ @field.should_not be_valid
61
+ end
62
+
63
+ MassiveRecord::ORM::Schema::Field::TYPES.each do |type|
64
+ it "should be valid with type #{type}" do
65
+ @field.type = type
66
+ @field.should be_valid
67
+ end
68
+ end
69
+
70
+ it "should not be valid with foo as type" do
71
+ @field.type = :foo
72
+ @field.should_not be_valid
73
+ end
74
+ end
75
+
76
+ it "should cast name to string" do
77
+ field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
78
+ field.name.should == "name"
79
+ end
80
+
81
+ it "should compare two column families based on name" do
82
+ field_1 = MassiveRecord::ORM::Schema::Field.new(:name => :name)
83
+ field_2 = MassiveRecord::ORM::Schema::Field.new(:name => :name)
84
+
85
+ field_1.should == field_2
86
+ field_1.eql?(field_2).should be_true
87
+ end
88
+
89
+ it "should have the same hash value for two families with the same name" do
90
+ field_1 = MassiveRecord::ORM::Schema::Field.new(:name => :name)
91
+ field_2 = MassiveRecord::ORM::Schema::Field.new(:name => :name)
92
+
93
+ field_1.hash.should == field_2.hash
94
+ end
95
+
96
+ describe "#decode" do
97
+ it "should return a value if value is of correct class" do
98
+ today = Date.today
99
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :created_at, :type => :date)
100
+ @subject.decode(today) == today
101
+ end
102
+
103
+ it "should decode a boolean value" do
104
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :boolean)
105
+ @subject.decode("1").should be_true
106
+ @subject.decode("0").should be_false
107
+ @subject.decode("").should be_nil
108
+ @subject.decode(nil).should be_nil
109
+ end
110
+
111
+ it "should decode a string value" do
112
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :string)
113
+ @subject.decode("value").should == "value"
114
+ @subject.decode("").should == ""
115
+ @subject.decode(nil).should be_nil
116
+ end
117
+
118
+ it "should decode an integer value" do
119
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :integer)
120
+ @subject.decode("1").should == 1
121
+ @subject.decode("").should be_nil
122
+ @subject.decode(nil).should be_nil
123
+ end
124
+
125
+ it "should decode an float value" do
126
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :code, :type => :float)
127
+ @subject.decode("12.345").should == 12.345
128
+ @subject.decode("").should be_nil
129
+ @subject.decode(nil).should be_nil
130
+ end
131
+
132
+ it "should decode a date type" do
133
+ today = Date.today
134
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :created_at, :type => :date)
135
+ @subject.decode(today.to_s) == today
136
+ @subject.decode("").should be_nil
137
+ @subject.decode(nil).should be_nil
138
+ end
139
+
140
+ it "should decode a time type" do
141
+ today = Time.now
142
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :created_at, :type => :time)
143
+ @subject.decode(today.to_s) == today
144
+ @subject.decode("").should be_nil
145
+ @subject.decode(nil).should be_nil
146
+ end
147
+ end
148
+
149
+ describe "#unique_name" do
150
+ before do
151
+ @family = MassiveRecord::ORM::Schema::ColumnFamily.new :name => :info
152
+ @field = MassiveRecord::ORM::Schema::Field.new :name => "field_name"
153
+ @field_with_column = MassiveRecord::ORM::Schema::Field.new :name => "field_name", :column => "fn"
154
+ end
155
+
156
+ it "should raise an error if it has no contained_in" do
157
+ lambda { @field.unique_name }.should raise_error "Can't generate a unique name as I don't have a column family!"
158
+ end
159
+
160
+ it "should return correct unique name" do
161
+ @family << @field
162
+ @field.unique_name.should == "info:field_name"
163
+ end
164
+
165
+ it "should return a correct unique name when using column" do
166
+ @family << @field_with_column
167
+ @field_with_column.unique_name.should == "info:fn"
168
+ end
169
+ end
170
+
171
+ describe "#column" do
172
+ before do
173
+ @field = MassiveRecord::ORM::Schema::Field.new :name => "field_name"
174
+ end
175
+
176
+ it "should default to name" do
177
+ @field.column.should == "field_name"
178
+ end
179
+
180
+ it "should be overridable" do
181
+ @field.column = "new"
182
+ @field.column.should == "new"
183
+ end
184
+
185
+ it "should be returned as a string" do
186
+ @field.column = :new
187
+ @field.column.should == "new"
188
+ end
189
+ end
190
+
191
+ it "should duplicate the default value" do
192
+ default_array = []
193
+ field = MassiveRecord::ORM::Schema::Field.new :name => "array", :type => :array, :default => default_array
194
+ field.default.object_id.should_not == default_array.object_id
195
+ end
196
+ end
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ describe MassiveRecord::ORM::Schema::Fields do
4
+ before do
5
+ @fields = MassiveRecord::ORM::Schema::Fields.new
6
+ end
7
+
8
+ it "should be a kind of set" do
9
+ @fields.should be_a_kind_of Set
10
+ end
11
+
12
+ describe "add fields to the set" do
13
+ it "should be possible to add fields" do
14
+ @fields << MassiveRecord::ORM::Schema::Field.new(:name => "field")
15
+ end
16
+
17
+ it "should add self to field's fields attribute" do
18
+ field = MassiveRecord::ORM::Schema::Field.new(:name => :field)
19
+ @fields << field
20
+ field.fields.should == @fields
21
+ end
22
+
23
+ it "should not be possible to add two fields with the same name" do
24
+ @fields << MassiveRecord::ORM::Schema::Field.new(:name => "attr")
25
+ @fields.add?(MassiveRecord::ORM::Schema::Field.new(:name => "attr")).should be_nil
26
+ end
27
+
28
+ it "should raise error if invalid column familiy is added" do
29
+ invalid_field = MassiveRecord::ORM::Schema::Field.new
30
+ lambda { @fields << invalid_field }.should raise_error MassiveRecord::ORM::Schema::InvalidField
31
+ end
32
+ end
33
+
34
+ describe "#to_hash" do
35
+ before do
36
+ @name_field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
37
+ @phone_field = MassiveRecord::ORM::Schema::Field.new(:name => :phone)
38
+ @fields << @name_field << @phone_field
39
+ end
40
+
41
+ it "should return nil if no fields are added" do
42
+ @fields.clear
43
+ @fields.to_hash.should == {}
44
+ end
45
+
46
+ it "should contain added fields" do
47
+ @fields.to_hash.should include("name" => @name_field)
48
+ @fields.to_hash.should include("phone" => @phone_field)
49
+ end
50
+ end
51
+
52
+ describe "#attribute_names" do
53
+ before do
54
+ @name_field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
55
+ @phone_field = MassiveRecord::ORM::Schema::Field.new(:name => :phone)
56
+ @fields << @name_field << @phone_field
57
+ end
58
+
59
+ it "should return nil if no fields are added" do
60
+ @fields.clear
61
+ @fields.attribute_names.should == []
62
+ end
63
+
64
+ it "should contain added fields" do
65
+ @fields.attribute_names.should include("name", "phone")
66
+ end
67
+ end
68
+
69
+ describe "#attribute_name_taken?" do
70
+ before do
71
+ @name_field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
72
+ @phone_field = MassiveRecord::ORM::Schema::Field.new(:name => :phone)
73
+ @fields << @name_field << @phone_field
74
+ end
75
+
76
+ describe "with no contained_in" do
77
+ it "should return true if name is taken" do
78
+ @fields.attribute_name_taken?("phone").should be_true
79
+ end
80
+
81
+ it "should accept and return true if name, given as a symbol, is taken" do
82
+ @fields.attribute_name_taken?(:phone).should be_true
83
+ end
84
+
85
+ it "should return false if name is not taken" do
86
+ @fields.attribute_name_taken?("not_taken").should be_false
87
+ end
88
+ end
89
+
90
+ describe "with contained_in set" do
91
+ before do
92
+ @fields.contained_in = MassiveRecord::ORM::Schema::ColumnFamily.new :name => "Family"
93
+ end
94
+
95
+ it "should ask object it is contained in for the truth about if attribute name is taken" do
96
+ @fields.contained_in.should_receive(:attribute_name_taken?).and_return true
97
+ @fields.attribute_name_taken?(:foo).should be_true
98
+ end
99
+
100
+ it "should not ask object it is contained in if asked not to" do
101
+ @fields.contained_in.should_not_receive(:attribute_name_taken?)
102
+ @fields.attribute_name_taken?(:foo, true).should be_false
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "#field_by_name" do
108
+ before do
109
+ @name_field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
110
+ @phone_field = MassiveRecord::ORM::Schema::Field.new(:name => :phone)
111
+ @fields << @name_field << @phone_field
112
+ end
113
+
114
+ it "should return nil if nothing is found" do
115
+ @fields.field_by_name("unkown").should be_nil
116
+ end
117
+
118
+ it "should return found field" do
119
+ @fields.field_by_name("name").should == @name_field
120
+ end
121
+
122
+ it "should return found field given as symbol" do
123
+ @fields.field_by_name(:name).should == @name_field
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,171 @@
1
+ require 'spec_helper'
2
+
3
+ class TestInterface
4
+ include MassiveRecord::ORM::Schema::TableInterface
5
+ end
6
+
7
+ class TestInterfaceSubClass < TestInterface
8
+ end
9
+
10
+ describe MassiveRecord::ORM::Schema::TableInterface do
11
+ after do
12
+ TestInterface.column_families = nil
13
+ TestInterfaceSubClass.column_families = nil
14
+ end
15
+
16
+
17
+ it "should respond_to column_family" do
18
+ TestInterface.should respond_to :column_family
19
+ end
20
+
21
+ it "should respond_to column_families" do
22
+ TestInterface.should respond_to :column_families
23
+ end
24
+
25
+ it "should be possible to add column familiy through DSL" do
26
+ class TestInterface
27
+ column_family :misc do; end
28
+ end
29
+
30
+ TestInterface.column_families.collect(&:name).should include("misc")
31
+ end
32
+
33
+ it "should be possible to add fields to a column families" do
34
+ class TestInterface
35
+ column_family :info do
36
+ field :name
37
+ end
38
+ end
39
+
40
+ TestInterface.known_attribute_names.should == ["name"]
41
+ end
42
+
43
+ it "should return attributes schema based on DSL" do
44
+ class TestInterface
45
+ column_family :info do
46
+ field :name
47
+ field :age, :integer, :default => 1
48
+ end
49
+ end
50
+
51
+ TestInterface.attributes_schema["name"].type.should == :string
52
+ TestInterface.attributes_schema["age"].type.should == :integer
53
+ TestInterface.attributes_schema["age"].default.should == 1
54
+ end
55
+
56
+ it "should raise an error if you try to add same field name twice" do
57
+ lambda {
58
+ class TestInterface
59
+ column_family :info do
60
+ field :name
61
+ field :name
62
+ end
63
+ end
64
+ }.should raise_error MassiveRecord::ORM::Schema::InvalidField
65
+ end
66
+
67
+ it "should give us default attributes from schema" do
68
+ class TestInterface
69
+ column_family :info do
70
+ field :name
71
+ field :age, :integer, :default => 1
72
+ end
73
+ end
74
+
75
+ defaults = TestInterface.default_attributes_from_schema
76
+ defaults["name"].should be_nil
77
+ defaults["age"].should == 1
78
+ end
79
+
80
+ it "should make attributes_schema readable from instances" do
81
+ class TestInterface
82
+ column_family :info do
83
+ field :name
84
+ end
85
+ end
86
+
87
+ TestInterface.new.attributes_schema["name"].type.should == :string
88
+ end
89
+
90
+ it "should not be shared amonb subclasses" do
91
+ class TestInterface
92
+ column_family :info do
93
+ autoload_fields
94
+ end
95
+ end
96
+
97
+ TestInterface.column_families.should_not be_nil
98
+ TestInterfaceSubClass.column_families.should be_nil
99
+ end
100
+
101
+
102
+ describe "dynamically adding a field" do
103
+ it "should be possible to dynamically add a field" do
104
+ TestInterface.add_field_to_column_family :info, :name, :default => "NA"
105
+
106
+ TestInterface.should have(1).column_families
107
+
108
+ family = TestInterface.column_families.first
109
+ family.name.should == "info"
110
+
111
+ family.fields.first.name.should == "name"
112
+ family.fields.first.default.should == "NA"
113
+ end
114
+
115
+ it "should be possible to set field's type just like the DSL" do
116
+ TestInterface.add_field_to_column_family :info, :age, :integer, :default => 0
117
+
118
+ TestInterface.column_families.first.fields.first.name.should == "age"
119
+ TestInterface.column_families.first.fields.first.type.should == :integer
120
+ TestInterface.column_families.first.fields.first.default.should == 0
121
+ end
122
+
123
+ it "should call class' undefine_attribute_methods to make sure it regenerates for newly added" do
124
+ TestInterface.should_receive(:undefine_attribute_methods)
125
+ TestInterface.add_field_to_column_family :info, :name, :default => "NA"
126
+ end
127
+
128
+ it "should return the new field" do
129
+ field = TestInterface.add_field_to_column_family :info, :age, :integer, :default => 0
130
+ field.should == TestInterface.column_families.first.fields.first
131
+ end
132
+
133
+ it "should insert the new field's default value right away" do
134
+ test_interface = TestInterface.new
135
+ test_interface.should_receive("age=").with(1)
136
+ test_interface.add_field_to_column_family :info, :age, :integer, :default => 1
137
+ end
138
+ end
139
+
140
+
141
+
142
+ describe "autoload_column_families_and_fields_with" do
143
+ before do
144
+ class TestInterface
145
+ column_family :info do
146
+ autoload_fields
147
+ end
148
+
149
+ column_family :misc do
150
+ field :text
151
+ end
152
+ end
153
+
154
+ @column_names = %w(info:name misc:other)
155
+ end
156
+
157
+ it "should not add fields to misc" do
158
+ TestInterface.column_families.family_by_name("misc").should_not_receive(:add?)
159
+ TestInterface.autoload_column_families_and_fields_with(@column_names)
160
+ end
161
+
162
+ it "should add fields to info" do
163
+ TestInterface.column_families.family_by_name("info").should_receive(:add?)
164
+ TestInterface.autoload_column_families_and_fields_with(@column_names)
165
+ end
166
+
167
+ it "should be possible to run twice" do
168
+ 2.times { TestInterface.autoload_column_families_and_fields_with(@column_names) }
169
+ end
170
+ end
171
+ end