massive_record 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,81 @@
1
+ require 'spec_helper'
2
+ require 'orm/models/person'
3
+ require 'orm/models/test_class'
4
+
5
+ describe "table classes" do
6
+ before do
7
+ @subject = MassiveRecord::ORM::Table
8
+
9
+ @subject.column_family(:info) do
10
+ field :first_name
11
+ field :last_name
12
+ end
13
+
14
+ @subject.column_family(:misc) do
15
+ field :status, :boolean, :default => false
16
+ end
17
+
18
+ @subject.column_family(:sandbox) do
19
+ autoload_fields
20
+ end
21
+ end
22
+
23
+ after do
24
+ @subject.column_families = nil
25
+ end
26
+
27
+ describe "column_families" do
28
+ it "should have a collection of column families" do
29
+ @subject.column_families.should be_a_kind_of(Set)
30
+ end
31
+
32
+ it "should have an attributes schema" do
33
+ @subject.attributes_schema.should include("first_name", "last_name", "status")
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "Person which is a table" do
39
+ include SetUpHbaseConnectionBeforeAll
40
+ include SetTableNamesToTestTable
41
+
42
+ before do
43
+ @person = Person.new
44
+ @person.id = "test"
45
+ @person.points = "25"
46
+ @person.date_of_birth = "19850730"
47
+ @person.status = "0"
48
+ end
49
+
50
+ it "should have a list of column families" do
51
+ Person.column_families.collect(&:name).should include("info")
52
+ end
53
+
54
+ it "should keep different column families per sub class" do
55
+ Person.column_families.collect(&:name).should == ["info"]
56
+ TestClass.column_families.collect(&:name).should == ["test_family"]
57
+ end
58
+
59
+ it "should have a list of attributes created from the column family 'info'" do
60
+ @person.attributes.keys.should include("name", "email", "points", "date_of_birth", "status")
61
+ end
62
+
63
+ it "should default an attribute to its default value" do
64
+ @person.points.should == 25
65
+ end
66
+
67
+ it "should parse a Date field properly" do
68
+ @person.date_of_birth.should be_a_kind_of(Date)
69
+ end
70
+
71
+ it "should parse a Boolean field properly" do
72
+ @person.status.should be_false
73
+ end
74
+
75
+ it "should decode/encode empty hashes correctly" do
76
+ @person.addresses = {}
77
+ @person.save! :validate => false
78
+ @person.reload
79
+ @person.addresses.should be_instance_of Hash
80
+ end
81
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+ require 'orm/models/person'
3
+ require 'orm/models/address'
4
+
5
+ shared_examples_for "validateable massive record model" do
6
+ it "should include ActiveModel::Validations" do
7
+ @model.class.included_modules.should include(ActiveModel::Validations)
8
+ end
9
+
10
+ describe "behaviour from active model" do
11
+ it "should respond to valid?" do
12
+ @model.should respond_to :valid?
13
+ end
14
+
15
+ it "should respond to errors" do
16
+ @model.should respond_to :errors
17
+ end
18
+
19
+ it "should have one error" do
20
+ @invalidate_model.call(@model)
21
+ @model.valid?
22
+ @model.should have(1).error
23
+ end
24
+ end
25
+
26
+ describe "persistance" do
27
+ it "should not interrupt saving of a model if its valid" do
28
+ @model.save.should be_true
29
+ @model.should be_persisted
30
+ end
31
+
32
+
33
+ it "should return false on save if record is not valid" do
34
+ @invalidate_model.call(@model)
35
+ @model.save.should be_false
36
+ end
37
+
38
+ it "should not save recurd if record is not valid" do
39
+ @invalidate_model.call(@model)
40
+ @model.save
41
+ @model.should be_new_record
42
+ end
43
+
44
+ it "should skip validation if asked to" do
45
+ @invalidate_model.call(@model)
46
+ @model.save :validate => false
47
+ @model.should be_persisted
48
+ end
49
+
50
+ it "should raise record invalid if save! is called on invalid record" do
51
+ @invalidate_model.call(@model)
52
+ @model.should_receive(:valid?).and_return(false)
53
+ lambda { @model.save! }.should raise_error MassiveRecord::ORM::RecordInvalid
54
+ end
55
+
56
+ it "should raise record invalid if create! is called with invalid attributes" do
57
+ @invalidate_model.call(@model)
58
+ @model.class.stub(:new).and_return(@model)
59
+ lambda { @model.class.create! }.should raise_error MassiveRecord::ORM::RecordInvalid
60
+ end
61
+ end
62
+ end
63
+
64
+
65
+ describe "MassiveRecord::Base::Table" do
66
+ include MockMassiveRecordConnection
67
+
68
+ before do
69
+ @model = Person.new :id => "1", :name => "Alice", :email => "alice@gmail.com", :age => 20
70
+ @invalidate_model = Proc.new { |p| p.name = nil }
71
+ end
72
+
73
+ it_should_behave_like "validateable massive record model"
74
+ end
75
+
76
+ #
77
+ # TODO We might have to decouple some stuff when it comes to calling
78
+ # save on a column, as it's save call should populate up to it's parent
79
+ # and so..
80
+ #
81
+ # Guess we have some thinking to do..
82
+ #
83
+ #describe "MassiveRecord::Base::Column" do
84
+ #include MockMassiveRecordConnection
85
+
86
+ #before do
87
+ #@model = Address.new :id => "1", :street => "Henrik Ibsens gate 1"
88
+ #@invalidate_model = Proc.new { |a| a.street = nil }
89
+ #end
90
+
91
+ #it_should_behave_like "validateable massive record model"
92
+ #end
@@ -0,0 +1,7 @@
1
+ class Address < MassiveRecord::ORM::Column
2
+ field :street
3
+ field :number, :integer
4
+ field :nice_place, :boolean, :default => true
5
+
6
+ validates_presence_of :street
7
+ end
@@ -0,0 +1,15 @@
1
+ class Person < MassiveRecord::ORM::Table
2
+ validates_presence_of :name, :age
3
+ validates_numericality_of :age, :greater_than_or_equal_to => 0
4
+ validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :allow_blank => true
5
+
6
+ column_family :info do
7
+ field :name
8
+ field :email
9
+ field :age, :integer
10
+ field :points, :integer, :default => 1, :column => :pts
11
+ field :date_of_birth, :date
12
+ field :status, :boolean, :default => false
13
+ field :addresses, :hash, :default => {}
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ class TestClass < MassiveRecord::ORM::Table
2
+ column_family :test_family do
3
+ field :foo, :string
4
+ end
5
+ end
@@ -0,0 +1,186 @@
1
+ require 'spec_helper'
2
+
3
+ describe MassiveRecord::ORM::Schema::ColumnFamilies do
4
+ before do
5
+ @column_families = MassiveRecord::ORM::Schema::ColumnFamilies.new
6
+ end
7
+
8
+ it "should be a kind of set" do
9
+ @column_families.should be_a_kind_of Set
10
+ end
11
+
12
+ it "should be possible to add column families" do
13
+ family = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :info)
14
+ @column_families << family
15
+ @column_families.first.should == family
16
+ end
17
+
18
+ describe "add column families to the set" do
19
+ it "should not be possible to add two column families with the same name" do
20
+ family_1 = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :info)
21
+ family_2 = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :info)
22
+ @column_families << family_1
23
+ @column_families.add?(family_2).should be_nil
24
+ end
25
+
26
+ it "should add self to column_family when familiy is added" do
27
+ family = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :info)
28
+ @column_families << family
29
+ family.column_families.should == @column_families
30
+ end
31
+
32
+ it "should add self to column_family when familiy is added with a question" do
33
+ family = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :info)
34
+ @column_families.add? family
35
+ family.column_families.should == @column_families
36
+ end
37
+
38
+ it "should raise error if invalid column familiy is added" do
39
+ invalid_family = MassiveRecord::ORM::Schema::ColumnFamily.new
40
+ lambda { @column_families << invalid_family }.should raise_error MassiveRecord::ORM::Schema::InvalidColumnFamily
41
+ end
42
+
43
+ it "should raise an error if a two column families are added with the same field names" do
44
+ family_1 = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :misc)
45
+ family_2 = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :info)
46
+
47
+ family_1 << MassiveRecord::ORM::Schema::Field.new(:name => "Foo")
48
+ @column_families << family_1
49
+
50
+ family_2 << MassiveRecord::ORM::Schema::Field.new(:name => "Foo")
51
+ lambda { @column_families << family_2 }.should raise_error MassiveRecord::ORM::Schema::InvalidColumnFamily
52
+ end
53
+ end
54
+
55
+ describe "#to_hash" do
56
+ before do
57
+ @column_families = MassiveRecord::ORM::Schema::ColumnFamilies.new
58
+ @column_family_info = MassiveRecord::ORM::Schema::ColumnFamily.new :name => :info
59
+ @column_family_misc = MassiveRecord::ORM::Schema::ColumnFamily.new :name => :misc
60
+
61
+ @column_families << @column_family_info << @column_family_misc
62
+
63
+ @name_field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
64
+ @phone_field = MassiveRecord::ORM::Schema::Field.new(:name => :phone)
65
+ @column_family_info << @name_field << @phone_field
66
+
67
+ @misc_field = MassiveRecord::ORM::Schema::Field.new(:name => :misc)
68
+ @other_field = MassiveRecord::ORM::Schema::Field.new(:name => :other)
69
+ @column_family_misc << @misc_field << @other_field
70
+ end
71
+
72
+ it "should return nil if no fields are added" do
73
+ @column_families.clear
74
+ @column_families.to_hash.should == {}
75
+ end
76
+
77
+ it "should contain added fields from info" do
78
+ @column_families.to_hash.should include("name" => @name_field)
79
+ @column_families.to_hash.should include("phone" => @phone_field)
80
+ end
81
+
82
+ it "should contain added fields from misc" do
83
+ @column_families.to_hash.should include("misc" => @misc_field)
84
+ @column_families.to_hash.should include("other" => @other_field)
85
+ end
86
+ end
87
+
88
+ describe "#attribute_names" do
89
+ before do
90
+ @column_families = MassiveRecord::ORM::Schema::ColumnFamilies.new
91
+ @column_family_info = MassiveRecord::ORM::Schema::ColumnFamily.new :name => :info
92
+ @column_family_misc = MassiveRecord::ORM::Schema::ColumnFamily.new :name => :misc
93
+
94
+ @column_families << @column_family_info << @column_family_misc
95
+
96
+ @name_field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
97
+ @phone_field = MassiveRecord::ORM::Schema::Field.new(:name => :phone)
98
+ @column_family_info << @name_field << @phone_field
99
+
100
+ @misc_field = MassiveRecord::ORM::Schema::Field.new(:name => :misc)
101
+ @other_field = MassiveRecord::ORM::Schema::Field.new(:name => :other)
102
+ @column_family_misc << @misc_field << @other_field
103
+ end
104
+
105
+ it "should return nil if no fields are added" do
106
+ @column_families.clear
107
+ @column_families.attribute_names.should == []
108
+ end
109
+
110
+ it "should contain added fields from info" do
111
+ @column_families.attribute_names.should include("name", "phone")
112
+ end
113
+
114
+ it "should contain added fields from misc" do
115
+ @column_families.attribute_names.should include("misc", "other")
116
+ end
117
+ end
118
+
119
+ describe "#attribute_name_taken?" do
120
+ before do
121
+ @column_families = MassiveRecord::ORM::Schema::ColumnFamilies.new
122
+ @column_family_info = MassiveRecord::ORM::Schema::ColumnFamily.new :name => :info
123
+ @column_family_misc = MassiveRecord::ORM::Schema::ColumnFamily.new :name => :misc
124
+
125
+ @column_families << @column_family_info << @column_family_misc
126
+
127
+ @name_field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
128
+ @phone_field = MassiveRecord::ORM::Schema::Field.new(:name => :phone)
129
+ @column_family_info << @name_field << @phone_field
130
+
131
+ @misc_field = MassiveRecord::ORM::Schema::Field.new(:name => :misc)
132
+ @other_field = MassiveRecord::ORM::Schema::Field.new(:name => :other)
133
+ @column_family_misc << @misc_field << @other_field
134
+ end
135
+
136
+ it "should return true if name is taken" do
137
+ @column_families.attribute_name_taken?("phone").should be_true
138
+ end
139
+
140
+ it "should accept and return true if name, given as a symbol, is taken" do
141
+ @column_families.attribute_name_taken?(:other).should be_true
142
+ end
143
+
144
+ it "should return false if name is not taken" do
145
+ @column_families.attribute_name_taken?("not_taken").should be_false
146
+ end
147
+
148
+ it "should return the same answer if asked from a field" do
149
+ @name_field.fields.attribute_name_taken?("misc").should be_true
150
+ end
151
+
152
+ it "should return false if only asked to check inside of it's own set" do
153
+ @name_field.fields.attribute_name_taken?("misc", true).should be_false
154
+ end
155
+ end
156
+
157
+ describe "#family_by_name and or_new" do
158
+ before do
159
+ @family_info = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :info)
160
+ @family_misc = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :misc)
161
+ @column_families << @family_info << @family_misc
162
+ end
163
+
164
+ it "should return nil if name is not found" do
165
+ @column_families.family_by_name("foo").should be_nil
166
+ end
167
+
168
+ it "should return family object for given name" do
169
+ @column_families.family_by_name("info").should == @family_info
170
+ end
171
+
172
+ it "should return family object for given name as symbol" do
173
+ @column_families.family_by_name(:info).should == @family_info
174
+ end
175
+
176
+ it "should create and add new family on to self" do
177
+ family = @column_families.family_by_name_or_new("foo")
178
+ family.should be_instance_of MassiveRecord::ORM::Schema::ColumnFamily
179
+ @column_families.should include(family)
180
+ end
181
+
182
+ it "should simply return known method when asked for family_or_new when name exists" do
183
+ @column_families.family_by_name_or_new("info").should == @family_info
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe MassiveRecord::ORM::Schema::ColumnFamily do
4
+ describe "initializer" do
5
+ it "should take a name" do
6
+ column_family = MassiveRecord::ORM::Schema::ColumnFamily.new :name => "family_name"
7
+ column_family.name.should == "family_name"
8
+ end
9
+
10
+ it "should take the column families it belongs to" do
11
+ families = MassiveRecord::ORM::Schema::ColumnFamilies.new
12
+ column_family = MassiveRecord::ORM::Schema::ColumnFamily.new :name => "family_name"
13
+ column_family.column_families = families
14
+ column_family.column_families.should == families
15
+ end
16
+
17
+ it "should set fields contained_in" do
18
+ column_family = MassiveRecord::ORM::Schema::ColumnFamily.new :name => "family_name"
19
+ column_family.fields.contained_in.should == column_family
20
+ end
21
+
22
+ it "should set autoload_fields to true" do
23
+ column_family = MassiveRecord::ORM::Schema::ColumnFamily.new :name => "family_name", :autoload_fields => true
24
+ column_family.should be_autoload_fields
25
+ end
26
+ end
27
+
28
+ describe "validations" do
29
+ before do
30
+ @families = MassiveRecord::ORM::Schema::ColumnFamilies.new
31
+ @column_family = MassiveRecord::ORM::Schema::ColumnFamily.new :name => "family_name", :column_families => @families
32
+ end
33
+
34
+ it "should be valid from before hook" do
35
+ @column_family.should be_valid
36
+ end
37
+
38
+ it "should not be valid with a blank name" do
39
+ @column_family.send(:name=, nil)
40
+ @column_family.should_not be_valid
41
+ end
42
+
43
+ it "should not be valid without column_families" do
44
+ @column_family.column_families = nil
45
+ @column_family.should_not be_valid
46
+ end
47
+
48
+ it "should not be valid if one of it's field is not valid" do
49
+ @field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
50
+ @column_family << @field
51
+ @field.should_receive(:valid?).and_return(false)
52
+ @column_family.should_not be_valid
53
+ end
54
+ end
55
+
56
+
57
+ it "should cast name to string" do
58
+ column_family = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :name)
59
+ column_family.name.should == "name"
60
+ end
61
+
62
+ it "should compare two column families based on name" do
63
+ column_family_1 = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :name)
64
+ column_family_2 = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :name)
65
+
66
+ column_family_1.should == column_family_2
67
+ column_family_1.eql?(column_family_2).should be_true
68
+ end
69
+
70
+ it "should have the same hash value for two families with the same name" do
71
+ column_family_1 = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :name)
72
+ column_family_2 = MassiveRecord::ORM::Schema::ColumnFamily.new(:name => :name)
73
+
74
+ column_family_1.hash.should == column_family_2.hash
75
+ end
76
+
77
+
78
+
79
+ describe "delegation to fields" do
80
+ before do
81
+ @families = MassiveRecord::ORM::Schema::ColumnFamilies.new
82
+ @column_family = MassiveRecord::ORM::Schema::ColumnFamily.new :name => "family_name", :column_families => @families
83
+ end
84
+
85
+ %w(add add? << to_hash attribute_names field_by_name).each do |method_to_delegate_to_fields|
86
+ it "should delegate #{method_to_delegate_to_fields} to fields" do
87
+ @column_family.fields.should_receive(method_to_delegate_to_fields)
88
+ @column_family.send(method_to_delegate_to_fields)
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#attribute_name_taken?" do
94
+ before do
95
+ @column_family = MassiveRecord::ORM::Schema::ColumnFamily.new :name => "family_name", :column_families => @families
96
+ @name_field = MassiveRecord::ORM::Schema::Field.new(:name => :name)
97
+ @phone_field = MassiveRecord::ORM::Schema::Field.new(:name => :phone)
98
+ @column_family << @name_field << @phone_field
99
+ end
100
+
101
+ describe "with no contained_in" do
102
+ it "should return true if name is taken" do
103
+ @column_family.attribute_name_taken?("phone").should be_true
104
+ end
105
+
106
+ it "should accept and return true if name, given as a symbol, is taken" do
107
+ @column_family.attribute_name_taken?(:phone).should be_true
108
+ end
109
+
110
+ it "should return false if name is not taken" do
111
+ @column_family.attribute_name_taken?("not_taken").should be_false
112
+ end
113
+ end
114
+
115
+ describe "with contained_in set" do
116
+ before do
117
+ @column_family.contained_in = MassiveRecord::ORM::Schema::ColumnFamilies
118
+ end
119
+
120
+ it "should ask object it is contained in for the truth about if attribute name is taken" do
121
+ @column_family.contained_in.should_receive(:attribute_name_taken?).and_return true
122
+ @column_family.attribute_name_taken?(:foo).should be_true
123
+ end
124
+
125
+ it "should not ask object it is contained in if asked not to" do
126
+ @column_family.contained_in.should_not_receive(:attribute_name_taken?)
127
+ @column_family.attribute_name_taken?(:foo, true).should be_false
128
+ end
129
+ end
130
+ end
131
+ end