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.
- data/.autotest +15 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +38 -0
- data/Manifest +24 -0
- data/README.md +225 -0
- data/Rakefile +16 -0
- data/TODO.md +8 -0
- data/autotest/discover.rb +1 -0
- data/lib/massive_record.rb +18 -0
- data/lib/massive_record/exceptions.rb +11 -0
- data/lib/massive_record/orm/attribute_methods.rb +61 -0
- data/lib/massive_record/orm/attribute_methods/dirty.rb +80 -0
- data/lib/massive_record/orm/attribute_methods/read.rb +23 -0
- data/lib/massive_record/orm/attribute_methods/write.rb +24 -0
- data/lib/massive_record/orm/base.rb +176 -0
- data/lib/massive_record/orm/callbacks.rb +52 -0
- data/lib/massive_record/orm/column.rb +18 -0
- data/lib/massive_record/orm/config.rb +47 -0
- data/lib/massive_record/orm/errors.rb +47 -0
- data/lib/massive_record/orm/finders.rb +125 -0
- data/lib/massive_record/orm/id_factory.rb +133 -0
- data/lib/massive_record/orm/persistence.rb +199 -0
- data/lib/massive_record/orm/schema.rb +4 -0
- data/lib/massive_record/orm/schema/column_families.rb +48 -0
- data/lib/massive_record/orm/schema/column_family.rb +102 -0
- data/lib/massive_record/orm/schema/column_interface.rb +91 -0
- data/lib/massive_record/orm/schema/common_interface.rb +48 -0
- data/lib/massive_record/orm/schema/field.rb +128 -0
- data/lib/massive_record/orm/schema/fields.rb +37 -0
- data/lib/massive_record/orm/schema/table_interface.rb +96 -0
- data/lib/massive_record/orm/table.rb +9 -0
- data/lib/massive_record/orm/validations.rb +52 -0
- data/lib/massive_record/spec/support/simple_database_cleaner.rb +52 -0
- data/lib/massive_record/thrift/hbase.rb +2307 -0
- data/lib/massive_record/thrift/hbase_constants.rb +14 -0
- data/lib/massive_record/thrift/hbase_types.rb +225 -0
- data/lib/massive_record/version.rb +3 -0
- data/lib/massive_record/wrapper/base.rb +28 -0
- data/lib/massive_record/wrapper/cell.rb +45 -0
- data/lib/massive_record/wrapper/column_families_collection.rb +19 -0
- data/lib/massive_record/wrapper/column_family.rb +22 -0
- data/lib/massive_record/wrapper/connection.rb +71 -0
- data/lib/massive_record/wrapper/row.rb +170 -0
- data/lib/massive_record/wrapper/scanner.rb +50 -0
- data/lib/massive_record/wrapper/table.rb +148 -0
- data/lib/massive_record/wrapper/tables_collection.rb +13 -0
- data/massive_record.gemspec +28 -0
- data/spec/config.yml.example +4 -0
- data/spec/orm/cases/attribute_methods_spec.rb +47 -0
- data/spec/orm/cases/auto_generate_id_spec.rb +54 -0
- data/spec/orm/cases/base_spec.rb +176 -0
- data/spec/orm/cases/callbacks_spec.rb +309 -0
- data/spec/orm/cases/column_spec.rb +49 -0
- data/spec/orm/cases/config_spec.rb +103 -0
- data/spec/orm/cases/dirty_spec.rb +129 -0
- data/spec/orm/cases/encoding_spec.rb +49 -0
- data/spec/orm/cases/finders_spec.rb +208 -0
- data/spec/orm/cases/hbase/connection_spec.rb +13 -0
- data/spec/orm/cases/i18n_spec.rb +32 -0
- data/spec/orm/cases/id_factory_spec.rb +75 -0
- data/spec/orm/cases/persistence_spec.rb +479 -0
- data/spec/orm/cases/table_spec.rb +81 -0
- data/spec/orm/cases/validation_spec.rb +92 -0
- data/spec/orm/models/address.rb +7 -0
- data/spec/orm/models/person.rb +15 -0
- data/spec/orm/models/test_class.rb +5 -0
- data/spec/orm/schema/column_families_spec.rb +186 -0
- data/spec/orm/schema/column_family_spec.rb +131 -0
- data/spec/orm/schema/column_interface_spec.rb +115 -0
- data/spec/orm/schema/field_spec.rb +196 -0
- data/spec/orm/schema/fields_spec.rb +126 -0
- data/spec/orm/schema/table_interface_spec.rb +171 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/connection_helpers.rb +76 -0
- data/spec/support/mock_massive_record_connection.rb +80 -0
- data/spec/thrift/cases/encoding_spec.rb +48 -0
- data/spec/wrapper/cases/connection_spec.rb +53 -0
- data/spec/wrapper/cases/table_spec.rb +231 -0
- 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,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,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
|