dynamoid 0.4.1 → 0.5.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.
@@ -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