dynamoid 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -87,9 +87,13 @@ describe "Dynamoid::Document" do
87
87
 
88
88
  Address.first.update_attributes(:city => 'Chicago')
89
89
 
90
- @address.city.should be_nil
91
90
  @address.reload.city.should == 'Chicago'
92
91
  end
92
+
93
+ it 'reloads document with range key' do
94
+ tweet = Tweet.create(:tweet_id => 'x', :group => 'abc')
95
+ tweet.reload.group.should == 'abc'
96
+ end
93
97
 
94
98
  it 'has default table options' do
95
99
  @address = Address.create
@@ -9,34 +9,34 @@ describe "Dynamoid::Fields" do
9
9
  it 'declares read attributes' do
10
10
  @address.city.should be_nil
11
11
  end
12
-
12
+
13
13
  it 'declares write attributes' do
14
- @address.city = 'Chicago'
14
+ @address.city = 'Chicago'
15
15
  @address.city.should == 'Chicago'
16
16
  end
17
-
17
+
18
18
  it 'declares a query attribute' do
19
19
  @address.city?.should be_false
20
-
20
+
21
21
  @address.city = 'Chicago'
22
-
22
+
23
23
  @address.city?.should be_true
24
24
  end
25
-
25
+
26
26
  it 'automatically declares id' do
27
27
  lambda {@address.id}.should_not raise_error
28
28
  end
29
-
29
+
30
30
  it 'automatically declares and fills in created_at and updated_at' do
31
31
  @address.save
32
-
32
+
33
33
  @address = @address.reload
34
34
  @address.created_at.should_not be_nil
35
35
  @address.created_at.class.should == DateTime
36
36
  @address.updated_at.should_not be_nil
37
37
  @address.updated_at.class.should == DateTime
38
38
  end
39
-
39
+
40
40
  context 'with a saved address' do
41
41
  before do
42
42
  @address = Address.create
@@ -46,35 +46,35 @@ describe "Dynamoid::Fields" do
46
46
  it 'should write an attribute correctly' do
47
47
  @address.write_attribute(:city, 'Chicago')
48
48
  end
49
-
49
+
50
50
  it 'should write an attribute with an alias' do
51
51
  @address[:city] = 'Chicago'
52
52
  end
53
-
53
+
54
54
  it 'should read a written attribute' do
55
55
  @address.write_attribute(:city, 'Chicago')
56
56
  @address.read_attribute(:city).should == 'Chicago'
57
57
  end
58
-
58
+
59
59
  it 'should read a written attribute with the alias' do
60
60
  @address.write_attribute(:city, 'Chicago')
61
61
  @address[:city].should == 'Chicago'
62
62
  end
63
-
63
+
64
64
  it 'should update all attributes' do
65
65
  @address.expects(:save).once.returns(true)
66
66
  @address.update_attributes(:city => 'Chicago')
67
67
  @address[:city].should == 'Chicago'
68
68
  @address.id.should == @original_id
69
69
  end
70
-
70
+
71
71
  it 'should update one attribute' do
72
72
  @address.expects(:save).once.returns(true)
73
73
  @address.update_attribute(:city, 'Chicago')
74
74
  @address[:city].should == 'Chicago'
75
75
  @address.id.should == @original_id
76
76
  end
77
-
77
+
78
78
  it 'adds in dirty methods for attributes' do
79
79
  @address.city = 'Chicago'
80
80
  @address.save
@@ -83,7 +83,7 @@ describe "Dynamoid::Fields" do
83
83
 
84
84
  @address.city_was.should == 'Chicago'
85
85
  end
86
-
86
+
87
87
  it 'returns all attributes' do
88
88
  Address.attributes.should == {:id=>{:type=>:string}, :created_at=>{:type=>:datetime}, :updated_at=>{:type=>:datetime}, :city=>{:type=>:string}, :options=>{:type=>:serialized}}
89
89
  end
@@ -93,5 +93,35 @@ describe "Dynamoid::Fields" do
93
93
  Dynamoid.logger.expects(:warn).with(regexp_matches(/city field has a length of 66000/))
94
94
  Address.new city: ("Ten chars " * 6_600)
95
95
  end
96
-
96
+
97
+
98
+ context 'default values for fields' do
99
+ before do
100
+ @clazz = Class.new do
101
+ include Dynamoid::Document
102
+
103
+ field :name, :string, :default => 'x'
104
+ field :uid, :integer, :default => lambda { 42 }
105
+
106
+ def self.name
107
+ 'Document'
108
+ end
109
+ end
110
+
111
+
112
+ @doc = @clazz.new
113
+ end
114
+
115
+ it 'returns default value' do
116
+ @doc.name.should eq('x')
117
+ @doc.uid.should eq(42)
118
+ end
119
+
120
+ it 'should save default value' do
121
+ @doc.save!
122
+ @doc.reload.name.should eq('x')
123
+ @doc.uid.should eq(42)
124
+ end
125
+ end
126
+
97
127
  end
@@ -8,24 +8,24 @@ describe "Dynamoid::Finders" do
8
8
 
9
9
  it 'finds an existing address' do
10
10
  found = Address.find(@address.id)
11
-
11
+
12
12
  found.should == @address
13
13
  found.city.should == 'Chicago'
14
14
  end
15
-
15
+
16
16
  it 'is not a new object' do
17
17
  found = Address.find(@address.id)
18
-
18
+
19
19
  found.new_record.should_not be_true
20
20
  end
21
-
21
+
22
22
  it 'returns nil when nothing is found' do
23
23
  Address.find('1234').should be_nil
24
24
  end
25
-
25
+
26
26
  it 'finds multiple ids' do
27
27
  @address2 = Address.create(:city => 'Illinois')
28
-
28
+
29
29
  Address.find(@address.id, @address2.id).should include @address, @address2
30
30
  end
31
31
 
@@ -33,12 +33,12 @@ describe "Dynamoid::Finders" do
33
33
  Dynamoid::Adapter.expects(:get_item).with { |table_name, key, options| options[:consistent_read] == true }
34
34
  Address.find('x', :consistent_read => true)
35
35
  end
36
-
36
+
37
37
  context 'with users' do
38
38
  before do
39
39
  User.create_indexes
40
40
  end
41
-
41
+
42
42
  it 'finds using method_missing for attributes' do
43
43
  array = Address.find_by_city('Chicago')
44
44
 
@@ -83,7 +83,7 @@ describe "Dynamoid::Finders" do
83
83
 
84
84
  array.should be_empty
85
85
  end
86
-
86
+
87
87
  it 'finds using method_missing for a single attribute and no results' do
88
88
  @user1 = User.create(:name => 'Josh', :email => 'josh@joshsymonds.com')
89
89
  @user2 = User.create(:name => 'Justin', :email => 'justin@joshsymonds.com')
@@ -108,12 +108,28 @@ describe "Dynamoid::Finders" do
108
108
 
109
109
  array.should == [@user]
110
110
  end
111
-
111
+
112
112
  it 'should return an empty array when fields exist but nothing is found' do
113
113
  array = User.find_all_by_password('Test')
114
-
114
+
115
115
  array.should be_empty
116
116
  end
117
117
 
118
118
  end
119
+
120
+ context 'find_all' do
121
+ it 'should return a array of users' do
122
+ users = (1..10).map { User.create }
123
+ User.find_all(users.map(&:id)).should eq(users)
124
+ end
125
+
126
+ it 'should return a array of tweets' do
127
+ tweets = (1..10).map { |i| Tweet.create(:tweet_id => "#{i}", :group => "group_#{i}") }
128
+ Tweet.find_all(tweets.map { |t| [t.tweet_id, t.group] }).should eq(tweets)
129
+ end
130
+
131
+ it 'should return an empty array' do
132
+ User.find_all([]).should eq([])
133
+ end
134
+ end
119
135
  end
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Dynamoid::IdentityMap" do
4
+ before :each do
5
+ Dynamoid::Config.identity_map = true
6
+ end
7
+
8
+ after :each do
9
+ Dynamoid::Config.identity_map = false
10
+ end
11
+
12
+ context 'object identity' do
13
+ it 'maintains a single object' do
14
+ tweet = Tweet.create(:tweet_id => "x", :group => "one")
15
+ tweet1 = Tweet.where(:tweet_id => "x", :group => "one").first
16
+ tweet.should equal(tweet1)
17
+ end
18
+ end
19
+
20
+ context 'cache' do
21
+ it 'uses cache' do
22
+ tweet = Tweet.create(:tweet_id => "x", :group => "one")
23
+ Dynamoid::Adapter.expects(:read).never
24
+ tweet1 = Tweet.find_by_id("x", :range_key => "one")
25
+ tweet.should equal(tweet1)
26
+ end
27
+
28
+ it 'clears cache on delete' do
29
+ tweet = Tweet.create(:tweet_id => "x", :group => "one")
30
+ tweet.delete
31
+ Tweet.find_by_id("x", :range_key => "one").should be_nil
32
+ end
33
+ end
34
+
35
+ context 'clear' do
36
+ it 'clears the identiy map' do
37
+ Tweet.create(:tweet_id => "x", :group => "one")
38
+ Tweet.create(:tweet_id => "x", :group => "two")
39
+
40
+ Tweet.identity_map.size.should eq(2)
41
+ Dynamoid::IdentityMap.clear
42
+ Tweet.identity_map.size.should eq(0)
43
+ end
44
+ end
45
+ end
@@ -57,8 +57,6 @@ describe "Dynamoid::Indexes::Index" do
57
57
  @user = User.new(:name => 'Josh', :password => 'test123', :created_at => @time)
58
58
  @user.name = 'Justin'
59
59
 
60
- @index.values(@user, true).should == {:hash_value => 'Josh.test123', :range_value => @time.to_f}
61
-
62
60
  @index.values(@user).should == {:hash_value => 'Justin.test123', :range_value => @time.to_f}
63
61
  end
64
62
 
@@ -12,7 +12,7 @@ describe "Dynamoid::Persistence" do
12
12
  before do
13
13
  Dynamoid::Adapter.delete_table(Address.table_name) if Dynamoid::Adapter.list_tables.include?(Address.table_name)
14
14
  end
15
-
15
+
16
16
  it 'creates a table' do
17
17
  Address.create_table(:table_name => Address.table_name)
18
18
 
@@ -27,57 +27,57 @@ describe "Dynamoid::Persistence" do
27
27
  end
28
28
  end
29
29
  end
30
-
30
+
31
31
  it 'assigns itself an id on save' do
32
32
  @address.save
33
-
33
+
34
34
  Dynamoid::Adapter.read("dynamoid_tests_addresses", @address.id)[:id].should == @address.id
35
35
  end
36
-
36
+
37
37
  it 'assigns itself an id on save only if it does not have one' do
38
38
  @address.id = 'test123'
39
39
  @address.save
40
-
40
+
41
41
  Dynamoid::Adapter.read("dynamoid_tests_addresses", 'test123').should_not be_empty
42
42
  end
43
-
43
+
44
44
  it 'has a table name' do
45
45
  Address.table_name.should == 'dynamoid_tests_addresses'
46
46
  end
47
-
47
+
48
48
  it 'saves indexes along with itself' do
49
49
  @user = User.new(:name => 'Josh')
50
-
50
+
51
51
  @user.expects(:save_indexes).once.returns(true)
52
52
  @user.save
53
53
  end
54
-
54
+
55
55
  it 'deletes an item completely' do
56
56
  @user = User.create(:name => 'Josh')
57
57
  @user.destroy
58
-
58
+
59
59
  Dynamoid::Adapter.read("dynamoid_tests_users", @user.id).should be_nil
60
60
  end
61
-
61
+
62
62
  it 'keeps string attributes as strings' do
63
63
  @user = User.new(:name => 'Josh')
64
64
  @user.send(:dump)[:name].should == 'Josh'
65
65
  end
66
-
66
+
67
67
  it 'dumps datetime attributes' do
68
68
  @user = User.create(:name => 'Josh')
69
69
  @user.send(:dump)[:name].should == 'Josh'
70
70
  end
71
-
71
+
72
72
  it 'dumps integer attributes' do
73
73
  @subscription = Subscription.create(:length => 10)
74
74
  @subscription.send(:dump)[:length].should == 10
75
75
  end
76
-
76
+
77
77
  it 'dumps set attributes' do
78
78
  @subscription = Subscription.create(:length => 10)
79
79
  @magazine = @subscription.magazine.create
80
-
80
+
81
81
  @subscription.send(:dump)[:magazine_ids].should == Set[@magazine.id]
82
82
  end
83
83
 
@@ -94,11 +94,11 @@ describe "Dynamoid::Persistence" do
94
94
  hash = {foo: :bar}
95
95
  Address.new(options: hash).options.should == hash
96
96
  end
97
-
97
+
98
98
  it 'loads attributes from a hash' do
99
99
  @time = DateTime.now
100
100
  @hash = {:name => 'Josh', :created_at => @time.to_f}
101
-
101
+
102
102
  User.undump(@hash)[:name].should == 'Josh'
103
103
  User.undump(@hash)[:created_at].to_f == @time.to_f
104
104
  end
@@ -120,21 +120,57 @@ describe "Dynamoid::Persistence" do
120
120
 
121
121
  CamelCase.new.save
122
122
  end
123
-
124
- it 'tracks previous changes on save or update' do
125
- @address.city = 'Chicago'
126
- @address.save
127
-
128
- @address.city = 'San Francisco'
129
- @address.save
130
-
131
- @address.city_was.should == 'Chicago'
132
- end
133
-
123
+
134
124
  it 'works with a HashWithIndifferentAccess' do
135
125
  hash = ActiveSupport::HashWithIndifferentAccess.new("city" => "Atlanta")
136
-
126
+
137
127
  lambda {Address.create(hash)}.should_not raise_error
138
128
  end
139
129
 
130
+ context 'update' do
131
+
132
+ before :each do
133
+ @tweet = Tweet.create(:tweet_id => 1, :group => 'abc', :count => 5, :tags => ['db', 'sql'], :user_name => 'john')
134
+ end
135
+
136
+ it 'support add/delete operation on a field' do
137
+ @tweet.update do |t|
138
+ t.add(:count => 3)
139
+ t.delete(:tags => ['db'])
140
+ end
141
+
142
+ @tweet.count.should eq(8)
143
+ @tweet.tags.to_a.should eq(['sql'])
144
+ end
145
+
146
+ it 'checks the conditions on update' do
147
+ @tweet.update(:if => { :count => 5 }) do |t|
148
+ t.add(:count => 3)
149
+ end.should be_true
150
+
151
+ @tweet.count.should eq(8)
152
+
153
+ @tweet.update(:if => { :count => 5 }) do |t|
154
+ t.add(:count => 3)
155
+ end.should be_false
156
+
157
+ @tweet.count.should eq(8)
158
+
159
+ expect {
160
+ @tweet.update!(:if => { :count => 5 }) do |t|
161
+ t.add(:count => 3)
162
+ end
163
+ }.to raise_error(Dynamoid::Errors::ConditionalCheckFailedException)
164
+ end
165
+
166
+ end
167
+
168
+ context 'delete' do
169
+ it 'deletes model with datetime range key' do
170
+ lambda {
171
+ msg = Message.create!(:message_id => 1, :time => DateTime.now, :text => "Hell yeah")
172
+ msg.destroy
173
+ }.should_not raise_error
174
+ end
175
+ end
140
176
  end