ampere 1.2.2 → 1.2.3

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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.2
1
+ 1.2.3
data/ampere.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "ampere"
8
- s.version = "1.2.2"
8
+ s.version = "1.2.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Max Thom Stahl"]
12
- s.date = "2012-07-24"
12
+ s.date = "2012-10-02"
13
13
  s.description = "An ActiveRecord/Mongoid-esque object model for the Redis key/value data store."
14
14
  s.email = "max@villainousindustri.es"
15
15
  s.extra_rdoc_files = [
data/lib/ampere/model.rb CHANGED
@@ -315,7 +315,7 @@ module Ampere
315
315
  # Set attr with key where referred model is stored
316
316
  self.send("#{field_name}_id=", val.id)
317
317
  # Also update that model's hash with a pointer back to here
318
- val.send("#{my_klass_name}_id=", self.send("id"))
318
+ val.send("#{my_klass_name}_id=", self.send("id")) if val.respond_to?("#{my_klass_name}_id=")
319
319
  end
320
320
  end
321
321
 
@@ -325,7 +325,7 @@ module Ampere
325
325
  my_klass_name = to_s.downcase
326
326
 
327
327
  define_method(:"#{field_name}") do
328
- (Ampere.connection.smembers(key_for_has_many(to_s.downcase, self.id, field_name))).map do |id|
328
+ (Ampere.connection.smembers(key_for_has_many(my_klass_name, self.id, field_name))).map do |id|
329
329
  eval(klass_name.to_s.capitalize).find(id)
330
330
  end
331
331
  end
@@ -333,7 +333,7 @@ module Ampere
333
333
  define_method(:"#{field_name}=") do |val|
334
334
  val.each do |v|
335
335
  Ampere.connection.multi do
336
- Ampere.connection.sadd(key_for_has_many(to_s.downcase, self.id, field_name), v.id)
336
+ Ampere.connection.sadd(key_for_has_many(my_klass_name, self.id, field_name), v.id)
337
337
  # Set pointer for belongs_to
338
338
  Ampere.connection.hset(key_for_find(v.class, v.id), "#{my_klass_name}_id", self.send("id"))
339
339
  end
@@ -1,21 +1,22 @@
1
1
  require File.join(File.dirname(__FILE__), "..", "spec_helper.rb")
2
2
 
3
3
  describe "Model indices", :indices => true do
4
+
5
+ class Student
6
+ include Ampere::Model
7
+
8
+ field :first_name
9
+ field :last_name
10
+ field :student_id_num
11
+
12
+ index :last_name
13
+ index :student_id_num, :unique => true
14
+ end
15
+
4
16
  before :each do
5
17
  Redis.new.flushall
6
18
  Ampere.connect
7
-
8
- class Student
9
- include Ampere::Model
10
-
11
- field :first_name
12
- field :last_name
13
- field :student_id_num
14
-
15
- index :last_name
16
- index :student_id_num, :unique => true
17
- end
18
-
19
+
19
20
  @a = Student.create :first_name => "Hannibal",
20
21
  :last_name => "Smith",
21
22
  :student_id_num => "1001"
@@ -26,56 +27,56 @@ describe "Model indices", :indices => true do
26
27
  :last_name => "Goldstein",
27
28
  :student_id_num => "1003"
28
29
  end
29
-
30
+
30
31
  ###
31
-
32
+
32
33
  it 'should know about its own indices' do
33
34
  Student.indices.should include(:last_name)
34
35
  Student.indices.should_not include(:first_name)
35
36
  Student.indices.should include(:student_id_num)
36
37
  end
37
-
38
+
38
39
  it 'should find an array of values for a non-unique index' do
39
40
  smiths = Student.where(:last_name => "Smith")
40
41
  smiths.should_not be_empty
41
42
  smiths.to_a.map(&:first_name).should include("Hannibal")
42
43
  smiths.to_a.map(&:first_name).should include("Cindy")
43
44
  end
44
-
45
+
45
46
  it 'should find a single value for a unique index' do
46
47
  emmanuel = Student.where(:student_id_num => "1003")
47
48
  emmanuel.should_not be_empty
48
49
  emmanuel.first.first_name.should == "Emmanuel"
49
50
  end
50
-
51
+
51
52
  it 'should refuse to create an index on a field that does not exist' do
52
53
  (->{
53
- class Student
54
+ class Student1
54
55
  include Ampere::Model
55
-
56
+
56
57
  field :this_field_exists
57
58
 
58
59
  index :this_field_exists
59
60
  end
60
61
  }).should_not raise_error
61
62
  (->{
62
- class Student
63
+ class Student2
63
64
  include Ampere::Model
64
-
65
+
65
66
  index :this_field_does_not_exist
66
67
  end
67
68
  }).should raise_error
68
69
  (->{
69
- class Student
70
+ class Student3
70
71
  include Ampere::Model
71
-
72
+
72
73
  field :this_field_exists
73
-
74
+
74
75
  index [:this_field_exists, :but_this_one_does_not]
75
76
  end
76
77
  }).should raise_error
77
78
  end
78
-
79
+
79
80
  it 'should enforce the uniqueness of unique single-field indices' do
80
81
  # The student_id_num field of Student is unique. If two Students
81
82
  # with the same student_id_num are stored, the second should not
@@ -92,23 +93,23 @@ describe "Model indices", :indices => true do
92
93
  }).should raise_error
93
94
  Student.where(:student_id_num => "2000").first.first_name.should == "Bobby"
94
95
  end
95
-
96
+
96
97
  context 'compound indices' do
97
98
  before :all do
98
99
  class Professor
99
100
  include Ampere::Model
100
-
101
+
101
102
  field :first_name
102
103
  field :last_name
103
104
  field :employee_id_number
104
-
105
+
105
106
  index :employee_id_number
106
107
  index [:last_name, :first_name]
107
108
  end
108
109
  end
109
-
110
+
110
111
  ###
111
-
112
+
112
113
  it 'should define compound indices' do
113
114
  Professor.indices.should include([:first_name, :last_name])
114
115
 
@@ -119,7 +120,7 @@ describe "Model indices", :indices => true do
119
120
  Professor.count.should == 1
120
121
  Ampere.connection.exists("ampere.index.professor.first_name:last_name").should be_true
121
122
  end
122
-
123
+
123
124
  it 'should be able to search on both fields of a compound index' do
124
125
  Professor.create :first_name => "Ava",
125
126
  :last_name => "Jenkins",
@@ -135,16 +136,16 @@ describe "Model indices", :indices => true do
135
136
  brandi.count.should == 1
136
137
  brandi.first.employee_id_number.should == "31415929"
137
138
  end
138
-
139
+
139
140
  # it 'should still be able to search on just one field of a compound index' do
140
141
  # pending
141
142
  # end
142
143
  end
143
-
144
+
144
145
  ###
145
-
146
+
146
147
  after :all do
147
148
  Redis.new.flushall
148
149
  Ampere.disconnect
149
150
  end
150
- end
151
+ end
@@ -4,22 +4,22 @@ describe "Base models", :model => true do
4
4
  context "by themselves" do
5
5
  class Post
6
6
  include Ampere::Model
7
-
7
+
8
8
  field :title
9
9
  field :byline
10
10
  field :content
11
11
  end
12
-
12
+
13
13
  before :all do
14
14
  Ampere.connect
15
-
15
+
16
16
  # Clear out Redis
17
17
  Redis.new.flushall
18
-
18
+
19
19
  # Define a model class here.
20
-
20
+
21
21
  end
22
-
22
+
23
23
  # # #
24
24
 
25
25
  context 'fields' do
@@ -32,46 +32,46 @@ describe "Base models", :model => true do
32
32
  post.should respond_to(:content)
33
33
  post.should respond_to(:"content=")
34
34
  end
35
-
35
+
36
36
  it "should know about its own fields" do
37
37
  Post.fields.should include(:title)
38
38
  Post.fields.should include(:byline)
39
39
  Post.fields.should include(:content)
40
40
  end
41
-
41
+
42
42
  it "should have default values definable" do
43
43
  class Comment
44
44
  include Ampere::Model
45
-
45
+
46
46
  field :subject, :default => "No subject"
47
47
  field :content
48
48
  end
49
-
49
+
50
50
  comment = Comment.new
51
51
  comment.subject.should == "No subject"
52
52
  comment.content.should be_nil
53
53
  end
54
-
54
+
55
55
  it "should raise an exception when you try to set a field that doesn't exist" do
56
56
  (->{Post.new :shazbot => "This isn't the right key"}).should raise_error
57
57
  end
58
-
58
+
59
59
  context 'types', :types => true do
60
60
  before :all do
61
61
  # Just adding a field with a type to Post
62
62
  class Post
63
63
  include Ampere::Model
64
-
64
+
65
65
  field :pageviews, :type => Integer, :default => 0
66
66
  end
67
67
  end
68
-
68
+
69
69
  it "should set field types for fields that have a type" do
70
70
  Post.field_types.should_not be_nil
71
71
  Post.field_types[:pageviews].should_not be_nil
72
72
  Post.field_types[:pageviews].should == 'Integer'
73
73
  end
74
-
74
+
75
75
  it "shouldn't care what the value types are assigned to a field with no type defined" do
76
76
  # Assign an int to the :title of a Post.
77
77
  (->{
@@ -79,10 +79,10 @@ describe "Base models", :model => true do
79
79
  :byline => "",
80
80
  :content => "",
81
81
  :pageviews => 1234
82
-
83
-
82
+
83
+
84
84
  }).should_not raise_error
85
-
85
+
86
86
  # Assign a string to the :title of a Post.
87
87
  (->{
88
88
  Post.create :title => "1234",
@@ -91,20 +91,20 @@ describe "Base models", :model => true do
91
91
  :pageviews => 1234
92
92
  }).should_not raise_error
93
93
  end
94
-
94
+
95
95
  it "should, given a field's type, only accept values for that field of that type" do
96
96
  post = Post.create :title => "",
97
97
  :byline => "",
98
98
  :content => "",
99
99
  :pageviews => 1234
100
-
100
+
101
101
  # Try to assign a string to :year, raising an error.
102
102
  (->{post.pageviews = "this is not an integer"}).should raise_error
103
103
  (->{post.pageviews = 4321}).should_not raise_error
104
104
  end
105
105
  end
106
106
  end
107
-
107
+
108
108
  it "should have a 'new' method that works like we'd expect" do
109
109
  post = Post.new :title => "Amish Give Up - 'This is bullshit!', Elders Say",
110
110
  :byline => "The Onion",
@@ -117,7 +117,7 @@ describe "Base models", :model => true do
117
117
  post.byline.should == "The Onion"
118
118
  post.content.should =~ /Lorem ipsum dolor/
119
119
  end
120
-
120
+
121
121
  it "should be able to convert itself to a hash" do
122
122
  post = Post.new :title => "A title",
123
123
  :byline => "Max",
@@ -127,7 +127,7 @@ describe "Base models", :model => true do
127
127
  hash[:byline].should == "Max"
128
128
  hash[:content].should == "Some content"
129
129
  end
130
-
130
+
131
131
  it "should have a 'save' and 'reload' method that work like we'd expect" do
132
132
  post = Post.new :title => "A title",
133
133
  :byline => "Max",
@@ -140,25 +140,25 @@ describe "Base models", :model => true do
140
140
  post.byline.should == "Max"
141
141
  post.content.should == "Some content"
142
142
  end
143
-
143
+
144
144
  it "should refuse to reload a new record, that hasn't yet been saved" do
145
145
  post = Post.new :title => "A title",
146
146
  :byline => "Max",
147
147
  :content => "Some content"
148
148
  (->{post.reload}).should raise_error
149
149
  end
150
-
150
+
151
151
  it "should be able to tell when two records are equivalent" do
152
152
  foo = Post.create :title => "Kitties!", :byline => "Max", :content => "Kitties are awesome."
153
153
  bar = Post.create :title => "Doggies!", :byline => "Max", :content => "Doggies are cool."
154
-
154
+
155
155
  foo.should == foo
156
156
  foo.should_not == bar
157
-
157
+
158
158
  foo.should eql(foo)
159
159
  foo.should_not eql(bar)
160
160
  end
161
-
161
+
162
162
  it "should also be able to determine the hash of a record, for equivalence testing" do
163
163
  Post.new(title: "Guinea Pigs", byline: "Max", content: "Guinea pigs are super cute.").hash.is_a?(Fixnum).should be_true
164
164
  end
@@ -171,7 +171,7 @@ describe "Base models", :model => true do
171
171
  post.save
172
172
  post.new?.should be_false
173
173
  end
174
-
174
+
175
175
  # context 'deletion' do
176
176
  it "should be deleteable from the model class", wip:true do
177
177
  post = Post.create :title => "This post should be deleted",
@@ -185,7 +185,7 @@ describe "Base models", :model => true do
185
185
  deleted_post.should be_destroyed
186
186
  Post.find(id).should be_nil
187
187
  end
188
-
188
+
189
189
  it "should be destroyable by itself" do
190
190
  another_post = Post.create :title => "This one too, probably.",
191
191
  :byline => "Just seems like one big",
@@ -196,7 +196,7 @@ describe "Base models", :model => true do
196
196
  Post.find(id).should be_nil
197
197
  end
198
198
  # end
199
-
199
+
200
200
  it "should be findable by ID" do
201
201
  post = Post.create :title => "foo",
202
202
  :byline => "bar",
@@ -204,7 +204,7 @@ describe "Base models", :model => true do
204
204
  Post.find(post.id).should == post
205
205
  # Since we're using GUIDs, this should also be true:
206
206
  post2 = Post.find(post.id)
207
-
207
+
208
208
  post.title.should == post2.title
209
209
  post.byline.should == post2.byline
210
210
  post.content.should == post2.content
@@ -217,22 +217,22 @@ describe "Base models", :model => true do
217
217
  post.should be_persisted
218
218
  Post.find(post.id).should == post
219
219
  end
220
-
220
+
221
221
  it "should return an integer for its ID" do
222
222
  post = Post.create :title => "On Motorcycles and Robots",
223
223
  :byline => "Max",
224
224
  :content => "Motorcycles and robots are awesome"
225
225
  post.id.should be_a(Fixnum)
226
226
  end
227
-
227
+
228
228
  # # #
229
-
229
+
230
230
  after :all do
231
231
  # Clear out Redis
232
232
  Redis.new.flushall
233
233
  Ampere.disconnect
234
234
  end
235
-
235
+
236
236
  end
237
-
238
- end
237
+
238
+ end
@@ -4,19 +4,19 @@ describe 'queries', :queries => true do
4
4
  before :each do
5
5
  Redis.new.flushall
6
6
  Ampere.connect
7
-
7
+
8
8
  class Kitty
9
9
  include Ampere::Model
10
-
10
+
11
11
  field :name
12
12
  field :breed
13
13
  field :age
14
14
  field :color
15
-
15
+
16
16
  index :name # => Unique
17
17
  index :color # => Non-unique
18
18
  end
19
-
19
+
20
20
  @kitty_paws = Kitty.create name: 'Kitty Paws',
21
21
  breed: 'Domestic shorthair',
22
22
  age: 19,
@@ -39,13 +39,13 @@ describe 'queries', :queries => true do
39
39
  color: 'grey'
40
40
  [@kitty_paws, @nate, @jinxii, @italics, @serif]. each {|k| k.reload}
41
41
  end
42
-
42
+
43
43
  ###
44
-
44
+
45
45
  it 'should pass a basic sanity check' do
46
46
  Kitty.count.should == 5
47
47
  end
48
-
48
+
49
49
  it 'should be able to select all kitties' do
50
50
  Kitty.all.map(&:name).should include('Kitty Paws')
51
51
  Kitty.all.map(&:name).should include('Nate')
@@ -53,35 +53,35 @@ describe 'queries', :queries => true do
53
53
  Kitty.all.map(&:name).should include('Italics')
54
54
  Kitty.all.map(&:name).should include('Serif')
55
55
  end
56
-
56
+
57
57
  context 'with no fields' do
58
58
  it 'should return the empty set with no conditions given' do
59
59
  Kitty.where().should be_empty
60
60
  end
61
61
  end
62
-
62
+
63
63
  context 'with one field' do
64
64
  it 'should be able to find by an indexed field using where()' do
65
65
  Kitty.where(:name => 'Nate').to_a.map(&:name).should include('Nate')
66
66
  end
67
-
67
+
68
68
  it 'should be able to find by a non-indexed field using where()' do
69
69
  Kitty.where(:breed => 'Siberian').to_a.map(&:name).should include('Italics')
70
70
  Kitty.where(:breed => 'Siberian').to_a.map(&:name).should include('Serif')
71
71
  end
72
72
  end
73
-
73
+
74
74
  it 'should be able to find by two indexed fields at once' do
75
75
  kitty = Kitty.where(:name => "Kitty Paws", :color => "orange")
76
76
  kitty.count.should == 1
77
77
  kitty.first.name.should == "Kitty Paws"
78
78
  end
79
-
79
+
80
80
  it 'should be able to find by two non-indexed fields at once' do
81
81
  # :breed and :age are not indexed
82
82
  Kitty.where(:breed => "Domestic shorthair", :age => 17).count.should == 1
83
83
  end
84
-
84
+
85
85
  it 'should be able to find by a mix of indexed and non-indexed fields' do
86
86
  # :color is indexed, :breed is not
87
87
  Kitty.where(:color => "orange").count.should == 2
@@ -89,9 +89,9 @@ describe 'queries', :queries => true do
89
89
  Kitty.where(:color => "orange", :breed => "Siberian").count.should == 1
90
90
  Kitty.where(:color => "orange", :breed => "Siberian").first.name.should == "Italics"
91
91
  end
92
-
92
+
93
93
  ###
94
-
94
+
95
95
  after :all do
96
96
  Redis.new.flushall
97
97
  Ampere.connect
@@ -1,41 +1,41 @@
1
1
  require File.join(File.dirname(__FILE__), "..", "..", "spec_helper.rb")
2
2
 
3
3
  describe 'belongs_to relationships', :belongs_to => true do
4
+
5
+ class Car
6
+ include Ampere::Model
7
+
8
+ field :make
9
+ field :model
10
+ field :year
11
+
12
+ has_one :engine
13
+ has_many :passengers
14
+ end
15
+
16
+ class Engine
17
+ include Ampere::Model
18
+
19
+ field :displacement
20
+ field :cylinders
21
+ field :configuration
22
+
23
+ belongs_to :car
24
+ end
25
+
26
+ class Passenger
27
+ include Ampere::Model
28
+
29
+ field :name
30
+ field :seat
31
+
32
+ belongs_to :car
33
+ end
34
+
4
35
  before :all do
5
36
  Redis.new.flushall
6
37
  Ampere.connect
7
38
 
8
- # These are used by the has_one/belongs_to example below
9
- class Car
10
- include Ampere::Model
11
-
12
- field :make
13
- field :model
14
- field :year
15
-
16
- has_one :engine
17
- has_many :passengers
18
- end
19
-
20
- class Engine
21
- include Ampere::Model
22
-
23
- field :displacement
24
- field :cylinders
25
- field :configuration
26
-
27
- belongs_to :car
28
- end
29
-
30
- class Passenger
31
- include Ampere::Model
32
-
33
- field :name
34
- field :seat
35
-
36
- belongs_to :car
37
- end
38
-
39
39
  @car = Car.create :make => "Lamborghini",
40
40
  :model => "Countach",
41
41
  :year => "1974"
@@ -47,66 +47,66 @@ describe 'belongs_to relationships', :belongs_to => true do
47
47
  @passenger = Passenger.create :name => "Leila",
48
48
  :seat => "passenger"
49
49
  end
50
-
50
+
51
51
  ###
52
-
52
+
53
53
  it 'sets accessor methods for a belongs_to relationship' do
54
54
  # Other side of a has_many
55
55
  @driver.should respond_to(:car)
56
56
  # Other side of a has_one
57
57
  @engine.should respond_to(:car)
58
58
  end
59
-
59
+
60
60
  it 'sets belongs_to pointer for has_one relationship that is set from the parent' do
61
61
  @car.engine = @engine
62
62
  @car.save
63
63
  @engine.save
64
-
64
+
65
65
  car = Car.find(@car.id)
66
66
  engine = Engine.find(@engine.id)
67
-
67
+
68
68
  car.engine.should == @engine
69
69
  engine.car.should == @car
70
-
70
+
71
71
  # Cleanup
72
72
  @car.engine = nil
73
73
  @engine.car = nil
74
74
  @car.save
75
75
  @engine.save
76
76
  end
77
-
77
+
78
78
  it 'sets belongs_to pointer for has_one relationship that is set from the child' do
79
79
  @engine.car = @car
80
80
  @car.save
81
81
  @engine.save
82
-
82
+
83
83
  car = Car.find(@car.id)
84
84
  engine = Engine.find(@engine.id)
85
-
85
+
86
86
  car.engine.should == @engine
87
87
  engine.car.should == @car
88
-
88
+
89
89
  # Cleanup
90
90
  @car.engine = nil
91
91
  @engine.car = nil
92
92
  @car.save
93
93
  @engine.save
94
94
  end
95
-
95
+
96
96
  it 'sets belongs_to pointer for has_many relationship' do
97
97
  @car.passengers = @car.passengers + [@driver]
98
98
  @car.passengers = @car.passengers + [@passenger]
99
99
  @car.save
100
-
100
+
101
101
  @driver.reload
102
102
  @passenger.reload
103
-
103
+
104
104
  @driver.car.should == @car
105
105
  @passenger.car.should == @car
106
106
  end
107
-
107
+
108
108
  ###
109
-
109
+
110
110
  after :all do
111
111
  Redis.new.flushall
112
112
  Ampere.connect
@@ -1,30 +1,30 @@
1
1
  require File.join(File.dirname(__FILE__), "..", "..", "spec_helper.rb")
2
2
 
3
3
  describe 'has_many relationships', :has_many => true do
4
+
5
+ class Car
6
+ include Ampere::Model
7
+
8
+ field :make
9
+ field :model
10
+ field :year
11
+
12
+ has_many :passengers
13
+ end
14
+
15
+ class Passenger
16
+ include Ampere::Model
17
+
18
+ field :name
19
+ field :seat
20
+
21
+ belongs_to :car
22
+ end
23
+
4
24
  before :each do
5
25
  Redis.new.flushall
6
26
  Ampere.connect
7
-
8
- # These are used by the has_one/belongs_to example below
9
- class Car
10
- include Ampere::Model
11
-
12
- field :make
13
- field :model
14
- field :year
15
-
16
- has_many :passengers
17
- end
18
-
19
- class Passenger
20
- include Ampere::Model
21
-
22
- field :name
23
- field :seat
24
-
25
- belongs_to :car
26
- end
27
-
27
+
28
28
  @car = Car.create :make => "Lamborghini",
29
29
  :model => "Countach",
30
30
  :year => "1974"
@@ -34,22 +34,22 @@ describe 'has_many relationships', :has_many => true do
34
34
  :seat => "passenger"
35
35
 
36
36
  end
37
-
37
+
38
38
  ###
39
-
39
+
40
40
  it 'should define the necessary methods for has_many relationships' do
41
41
  # Attr accessors
42
42
  @car.should respond_to(:passengers)
43
43
  @car.should respond_to(:"passengers=")
44
44
  end
45
-
45
+
46
46
  it 'should be able to add items to has_many relationships' do
47
47
  @car.passengers = @car.passengers + [@driver]
48
48
  @car.passengers = @car.passengers + [@passenger]
49
49
 
50
50
  @car.save
51
51
  @car.reload
52
-
52
+
53
53
  @driver.reload
54
54
  @passenger.reload
55
55
 
@@ -57,19 +57,24 @@ describe 'has_many relationships', :has_many => true do
57
57
  @car.passengers.should include(@passenger)
58
58
  end
59
59
 
60
+ it 'should add a set of IDs to Redis', wip:true do
61
+ @car.passengers = @car.passengers + [@driver]
62
+ Ampere.connection.keys.should include("car.#{@car.id}.has_many.passengers")
63
+ end
64
+
60
65
  # it 'should be able to remove items from has_many relationships' do
61
66
  # pending
62
67
  # end
63
-
68
+
64
69
  # it 'should be able to query has_many relationships' do
65
70
  # pending
66
71
  # end
67
-
72
+
68
73
  ###
69
-
74
+
70
75
  after :all do
71
76
  Ampere.disconnect
72
77
  Redis.new.flushall
73
78
  end
74
-
79
+
75
80
  end
@@ -1,31 +1,32 @@
1
1
  require File.join(File.dirname(__FILE__), "..", "..", "spec_helper.rb")
2
2
 
3
3
  describe 'has_one relationships', has_one:true do
4
+
5
+ class Car
6
+ include Ampere::Model
7
+
8
+ field :make
9
+ field :model
10
+ field :year
11
+
12
+ has_one :engine
13
+ end
14
+
15
+ class Engine
16
+ include Ampere::Model
17
+
18
+ field :displacement
19
+ field :cylinders
20
+ field :configuration
21
+
22
+ belongs_to :car
23
+ end
24
+
25
+
4
26
  before :all do
5
27
  Redis.new.flushall
6
28
  Ampere.connect
7
29
 
8
- # These are used by the has_one/belongs_to example below
9
- class Car
10
- include Ampere::Model
11
-
12
- field :make
13
- field :model
14
- field :year
15
-
16
- has_one :engine
17
- end
18
-
19
- class Engine
20
- include Ampere::Model
21
-
22
- field :displacement
23
- field :cylinders
24
- field :configuration
25
-
26
- belongs_to :car
27
- end
28
-
29
30
  @car = Car.create :make => "Lamborghini",
30
31
  :model => "Countach",
31
32
  :year => "1974"
@@ -33,9 +34,9 @@ describe 'has_one relationships', has_one:true do
33
34
  :cylinders => "12",
34
35
  :configuration => "V"
35
36
  end
36
-
37
+
37
38
  ###
38
-
39
+
39
40
  it 'can store a relationship to one model instance from another using an attr_accessor' do
40
41
  @car.engine_id = @engine.id
41
42
  @car.save
@@ -43,12 +44,12 @@ describe 'has_one relationships', has_one:true do
43
44
  @engine.reload
44
45
  @car.engine_id.should == @engine.id
45
46
  @car.engine.should == @engine
46
-
47
+
47
48
  @car.engine_id = nil
48
49
  @car.save
49
50
  @car.engine.should be_nil
50
51
  end
51
-
52
+
52
53
  it 'can store a relationship to one model instance from another using custom accessor methods' do
53
54
  @car.engine = @engine
54
55
  @car.save
@@ -56,12 +57,12 @@ describe 'has_one relationships', has_one:true do
56
57
  @engine.reload
57
58
  @car.engine_id.should == @engine.id
58
59
  @car.engine.should == @engine
59
-
60
+
60
61
  @car.engine_id = nil
61
62
  @car.save
62
63
  @car.engine.should be_nil
63
64
  end
64
-
65
+
65
66
  it 'can delete the object related to it in a has_one relationship' do
66
67
  @car.engine = @engine
67
68
  @car.engine.destroy
@@ -69,11 +70,11 @@ describe 'has_one relationships', has_one:true do
69
70
  @car.engine.should be_nil
70
71
  Engine.find(@engine.id).should be_nil
71
72
  end
72
-
73
+
73
74
  ###
74
-
75
+
75
76
  after :all do
76
77
  Ampere.disconnect
77
78
  Redis.new.flushall
78
79
  end
79
- end
80
+ end
@@ -1,45 +1,45 @@
1
1
  describe Ampere::Timestamps do
2
2
  before :all do
3
3
  Ampere.connect
4
-
4
+
5
5
  Ampere.connection.flushall
6
-
6
+
7
7
  class Comment
8
8
  include Ampere::Model
9
9
  include Ampere::Timestamps
10
-
10
+
11
11
  field :body
12
12
  end
13
13
  end
14
-
14
+
15
15
  context 'when included in models' do
16
16
  it 'sets created_at for newly-created record' do
17
17
  Timecop.freeze(Time.now) do
18
18
  time = Time.now
19
-
19
+
20
20
  c = Comment.create body: "I am intrigued by your ideas, and would like to subscribe to your newsletter."
21
21
  c.created_at.should eq(time)
22
22
  c.updated_at.should eq(time)
23
23
  end
24
24
  end
25
-
25
+
26
26
  it 'sets updated_at when changing records' do
27
27
  c = Comment.create body: "I am intrigued by your ideas, and would like to subscribe to your newsletter."
28
28
  created_at = c.created_at
29
-
29
+
30
30
  time = 0
31
-
31
+
32
32
  Timecop.freeze(Time.now + 30) do
33
33
  time = Time.now
34
-
34
+
35
35
  c.body = "Theodore Roosevelt riding a moose, therefore your argument is invalid."
36
36
  c.save
37
37
  end
38
-
38
+
39
39
  c.updated_at.should eq(time)
40
40
  c.created_at.should eq(created_at)
41
41
  end
42
-
43
- end
44
42
 
43
+ end
44
+
45
45
  end
@@ -4,33 +4,33 @@ describe 'queries', :queries => true do
4
4
  before :each do
5
5
  Redis.new.flushall
6
6
  Ampere.connect
7
-
7
+
8
8
  class Motorcycle
9
9
  include Ampere::Model
10
-
10
+
11
11
  field :make
12
12
  field :model
13
13
  field :year
14
14
  end
15
-
15
+
16
16
  @bike = Motorcycle.create make: "Honda", model: "CB400", year: "1990"
17
17
  end
18
-
18
+
19
19
  ###
20
-
20
+
21
21
  it 'should be able to update one field atomically' do
22
22
  @bike.model.should == "CB400"
23
23
  @bike.update_attribute :model, "CB450SC"
24
24
  @bike.model.should == "CB450SC"
25
25
  @bike.reload.model.should == "CB450SC"
26
-
26
+
27
27
  @bike.year.should == "1990"
28
28
  @bike.update_attribute :year, "1986"
29
29
  @bike.year.should == "1986"
30
30
  @bike.reload
31
31
  @bike.year.should == "1986"
32
32
  end
33
-
33
+
34
34
  it 'should be able to update multiple fields atomically' do
35
35
  @bike.update_attributes model: "CB750",
36
36
  year: "1996"
@@ -54,9 +54,9 @@ describe 'queries', :queries => true do
54
54
  neither_does_this_one: "Duis aute irure dolor in."
55
55
  }).should raise_error
56
56
  end
57
-
57
+
58
58
  ###
59
-
59
+
60
60
  after :all do
61
61
  Redis.new.flushall
62
62
  Ampere.connect
@@ -4,17 +4,17 @@ describe 'Validations', :validations => true do
4
4
  before :all do
5
5
  class Person
6
6
  include Ampere::Model
7
-
7
+
8
8
  field :first_name
9
9
  field :last_name
10
10
  field :email
11
-
11
+
12
12
  validates_presence_of :last_name
13
13
  validates_format_of :email, :with => /\A\w+@\w+\.com\Z/i
14
14
  end
15
-
16
- end
17
15
 
16
+ end
17
+
18
18
  it 'should validate presence of items' do
19
19
  alice = Person.new :first_name => 'Alice',
20
20
  :last_name => 'Steel',
@@ -26,16 +26,15 @@ describe 'Validations', :validations => true do
26
26
  bob.should be_invalid
27
27
  bob.errors.should_not be_empty
28
28
  end
29
-
29
+
30
30
  it 'should validate format of items' do
31
31
  charlie = Person.new :first_name => 'Charlie',
32
32
  :last_name => 'Steel',
33
33
  :email => 'c h a r l i e @ charlie .com'
34
34
  charlie.should_not be_valid
35
35
  end
36
-
36
+
37
37
  # Since this is accomplished by including a module, what is being tested here
38
38
  # is that the module got included correctly and works. For testing of all the
39
39
  # other kinds of validations, run the tests for ActiveModel::Validations.
40
40
  end
41
-
@@ -4,13 +4,13 @@ describe 'Collections are Ennumerable', :collections => true, :ennumerable => tr
4
4
  before :all do
5
5
  Redis.new.flushall
6
6
  Ampere.connect
7
-
7
+
8
8
  class President
9
9
  include Ampere::Model
10
-
10
+
11
11
  field :name
12
12
  field :party
13
-
13
+
14
14
  index :party
15
15
  end
16
16
 
@@ -21,32 +21,32 @@ describe 'Collections are Ennumerable', :collections => true, :ennumerable => tr
21
21
  President.create :name => "John F. Kennedy" , :party => "Democratic"
22
22
  President.create :name => "Jimmy Carter" , :party => "Democratic"
23
23
  end
24
-
24
+
25
25
  it 'should implement the #each method correctly' do
26
26
  presidents = []
27
27
  President.all.each {|p| presidents << p.name}
28
- presidents.should == [
29
- "Millard Fillmore" ,
30
- "Ulysses S. Grant" ,
28
+ presidents.sort.should == [
31
29
  "Abraham Lincoln" ,
32
30
  "Franklin D. Roosevelt",
31
+ "Jimmy Carter" ,
33
32
  "John F. Kennedy" ,
34
- "Jimmy Carter"
33
+ "Millard Fillmore" ,
34
+ "Ulysses S. Grant"
35
35
  ]
36
36
  end
37
-
37
+
38
38
  it 'should lazily evaluate the #[] method' do
39
39
  presidents = President.all
40
-
40
+
41
41
  presidents[2].name.should eq('Abraham Lincoln')
42
42
  presidents[2].name.should eq('Abraham Lincoln')
43
43
  end
44
-
44
+
45
45
  it 'should be comparable to an array' do
46
46
  President.all.should == President.all.to_a
47
47
  President.all.should_not be(President.all.to_a)
48
48
  end
49
-
49
+
50
50
  # These are just a handful of methods to ensure that the Enumerable module is
51
51
  # being included correctly. They can safely be factored out since the #each
52
52
  # one above should cover Enumerable if it's being included correctly.
@@ -59,9 +59,9 @@ describe 'Collections are Ennumerable', :collections => true, :ennumerable => tr
59
59
  President.all.any? {|p| p.party == 'Whig'}.should be_true
60
60
  President.all.any? {|p| p.party == 'Green'}.should be_false
61
61
  end
62
-
62
+
63
63
  it 'should implement the #map method correctly' do
64
- President.all.map(&:party).should == %w{Whig Republican Republican Democratic Democratic Democratic}
64
+ President.all.map(&:party).sort.should == %w{Whig Republican Republican Democratic Democratic Democratic}.sort
65
65
  end
66
66
 
67
67
  it 'should implement the #inject method correctly' do
@@ -77,6 +77,6 @@ describe 'Collections are Ennumerable', :collections => true, :ennumerable => tr
77
77
  }
78
78
  end
79
79
 
80
-
80
+
81
81
  end
82
82
 
@@ -3,13 +3,13 @@ require File.join(File.dirname(__FILE__), "..", "spec_helper.rb")
3
3
  describe 'Collections', :collections => true do
4
4
  class President
5
5
  include Ampere::Model
6
-
6
+
7
7
  field :name
8
8
  field :party
9
-
9
+
10
10
  index :party
11
11
  end
12
-
12
+
13
13
  before :all do
14
14
  Redis.new.flushall
15
15
  Ampere.connect
@@ -21,7 +21,7 @@ describe 'Collections', :collections => true do
21
21
  President.create :name => "John F. Kennedy" , :party => "Democratic"
22
22
  President.create :name => "Jimmy Carter" , :party => "Democratic"
23
23
  end
24
-
24
+
25
25
  ###
26
26
 
27
27
  it 'should be returned by President.all' do
@@ -31,7 +31,7 @@ describe 'Collections', :collections => true do
31
31
  democrats.raw_array.length.should == 6
32
32
  democrats.count.should == 6
33
33
  end
34
-
34
+
35
35
  it 'should be returned by where() queries' do
36
36
  democrats = President.where(:party => "Democratic")
37
37
  democrats.class.should == Ampere::Collection
@@ -39,46 +39,46 @@ describe 'Collections', :collections => true do
39
39
  democrats.raw_array.length.should == 3
40
40
  democrats.count.should == 3
41
41
  end
42
-
42
+
43
43
  it 'should be accessible via [] like an Array' do
44
44
  whigs = President.where(:party => "Whig")
45
45
  whigs[0].name.should == "Millard Fillmore"
46
46
  end
47
-
47
+
48
48
  it 'should lazily load model instances searched for with indexed fields' do
49
49
  whigs = President.where(:party => "Whig")
50
50
  whigs.raw_array.first.class.should == String
51
51
  whigs[0].name.should == "Millard Fillmore"
52
52
  whigs.raw_array.first.class.should == President
53
53
  end
54
-
54
+
55
55
  it 'should return its first() item' do
56
56
  republicans = President.where(:party => "Republican")
57
57
  republicans.first.name.should == "Ulysses S. Grant"
58
58
  end
59
-
59
+
60
60
  it 'should return its first(n) items' do
61
61
  republicans = President.where(:party => "Republican")
62
62
  republicans.first(2).map(&:name).should == ["Ulysses S. Grant", "Abraham Lincoln"]
63
63
  end
64
-
64
+
65
65
  it 'should return its last() item' do
66
66
  democrats = President.where(:party => "Democratic")
67
67
  democrats.last.name.should == "Jimmy Carter"
68
68
  end
69
-
69
+
70
70
  it 'should be convertible to an array' do
71
71
  republicans = President.where(:party => "Republican")
72
72
  republicans.to_a.map(&:name).should == ["Ulysses S. Grant", "Abraham Lincoln"]
73
73
  end
74
-
74
+
75
75
  it 'should give its first and last elements non-lazily' do
76
76
  President.first.name.should eq("Millard Fillmore")
77
77
  President.last.name.should eq("Jimmy Carter")
78
78
  end
79
-
79
+
80
80
  ###
81
-
81
+
82
82
  after :all do
83
83
  Ampere.disconnect
84
84
  Redis.new.flushall
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ampere
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-24 00:00:00.000000000 Z
12
+ date: 2012-10-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -315,7 +315,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
315
315
  version: '0'
316
316
  segments:
317
317
  - 0
318
- hash: -2731344431471118659
318
+ hash: 2670808373290565057
319
319
  required_rubygems_version: !ruby/object:Gem::Requirement
320
320
  none: false
321
321
  requirements: