ampere 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
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: