with_model 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ module WithModel
2
+ class Model
3
+ class DSL
4
+ def initialize model
5
+ @model = model
6
+ end
7
+
8
+ def table options = {}, &block
9
+ @model.table_options = options
10
+ @model.table_block = block
11
+ end
12
+
13
+ def model &block
14
+ @model.model_block = block
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ require 'active_record'
2
+
3
+ module WithModel
4
+ class Table
5
+ def initialize name, options = {}, &block
6
+ @name = name.freeze
7
+ @options = options.freeze
8
+ @block = block
9
+ end
10
+
11
+ def create
12
+ connection = ActiveRecord::Base.connection
13
+ connection.drop_table(@name) if connection.table_exists?(@name)
14
+ connection.create_table(@name, @options, &@block)
15
+ end
16
+
17
+ def destroy
18
+ ActiveRecord::Base.connection.drop_table(@name)
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module WithModel
2
- VERSION = "0.3.2"
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -4,9 +4,11 @@ describe "ActiveRecord behaviors" do
4
4
  describe "a temporary ActiveRecord model created with with_model" do
5
5
  context "that has a named scope" do
6
6
  before do
7
- class RegularModel < ActiveRecord::Base
7
+ regular_model = Class.new ActiveRecord::Base do
8
8
  scope :title_is_foo, lambda { where(:title => 'foo') }
9
9
  end
10
+ stub_const 'RegularModel', regular_model
11
+
10
12
  RegularModel.connection.drop_table(RegularModel.table_name) rescue nil
11
13
  RegularModel.connection.create_table(RegularModel.table_name) do |t|
12
14
  t.string 'title'
@@ -32,25 +34,26 @@ describe "ActiveRecord behaviors" do
32
34
  end
33
35
 
34
36
  describe "the named scope" do
35
- it "should work like a regular named scope" do
36
- included = RegularModel.create!(:title => 'foo', :content => "Include me!")
37
- excluded = RegularModel.create!(:title => 'bar', :content => "Include me!")
37
+ it "works like a regular named scope" do
38
+ included = RegularModel.create!(:title => 'foo', :content => 'Include me!')
39
+ excluded = RegularModel.create!(:title => 'bar', :content => 'Include me!')
38
40
 
39
- RegularModel.title_is_foo.should == [included]
41
+ expect(RegularModel.title_is_foo).to eq [included]
40
42
 
41
- included = BlogPost.create!(:title => 'foo', :content => "Include me!")
42
- excluded = BlogPost.create!(:title => 'bar', :content => "Include me!")
43
+ included = BlogPost.create!(:title => 'foo', :content => 'Include me!')
44
+ excluded = BlogPost.create!(:title => 'bar', :content => 'Include me!')
43
45
 
44
- BlogPost.title_is_foo.should == [included]
46
+ expect(BlogPost.title_is_foo).to eq [included]
45
47
  end
46
48
  end
47
49
  end
48
50
 
49
51
  context "that has a polymorphic belongs_to" do
50
52
  before do
51
- class Animal < ActiveRecord::Base
53
+ animal = Class.new ActiveRecord::Base do
52
54
  has_many :tea_cups, :as => :pet
53
55
  end
56
+ stub_const 'Animal', animal
54
57
  end
55
58
 
56
59
  with_model :TeaCup do
@@ -71,17 +74,17 @@ describe "ActiveRecord behaviors" do
71
74
  end
72
75
 
73
76
  describe "the polymorphic belongs_to" do
74
- it "should work like a regular polymorphic belongs_to" do
77
+ it "works like a regular polymorphic belongs_to" do
75
78
  animal = Animal.create!
76
79
  stuffed_animal = StuffedAnimal.create!
77
80
 
78
81
  tea_cup_for_animal = TeaCup.create!(:pet => animal)
79
- tea_cup_for_animal.pet_type.should == "Animal"
80
- animal.tea_cups.should include(tea_cup_for_animal)
82
+ expect(tea_cup_for_animal.pet_type).to eq 'Animal'
83
+ expect(animal.tea_cups).to include(tea_cup_for_animal)
81
84
 
82
85
  tea_cup_for_stuffed_animal = TeaCup.create!(:pet => stuffed_animal)
83
- tea_cup_for_stuffed_animal.pet_type.should == "StuffedAnimal"
84
- stuffed_animal.tea_cups.should include(tea_cup_for_stuffed_animal)
86
+ expect(tea_cup_for_stuffed_animal.pet_type).to eq 'StuffedAnimal'
87
+ expect(stuffed_animal.tea_cups).to include(tea_cup_for_stuffed_animal)
85
88
  end
86
89
  end
87
90
  end
@@ -97,18 +100,17 @@ describe "ActiveRecord behaviors" do
97
100
  end
98
101
  end
99
102
 
100
- with_model :Country do
101
- end
103
+ with_model :Country
102
104
 
103
105
  context "in earlier examples" do
104
- it "should work as normal" do
106
+ it "works as normal" do
105
107
  Province.create!(:country => Country.create!)
106
108
  end
107
109
  end
108
110
 
109
111
  context "in later examples" do
110
- it "should not hold a reference to earlier example groups' classes" do
111
- Province.reflect_on_association(:country).klass.should == Country
112
+ it "does not hold a reference to earlier example groups' classes" do
113
+ expect(Province.reflect_on_association(:country).klass).to eq Country
112
114
  end
113
115
  end
114
116
  end
@@ -1,86 +1,105 @@
1
- require 'spec_helper'
1
+ require 'spec_helper'
2
2
 
3
- describe "A blog post" do
4
-
5
- with_model :BlogPost do
6
- # The table block works just like a migration.
7
- table do |t|
8
- t.string :title
9
- t.timestamps
10
- end
11
-
12
- # The model block works just like the class definition.
13
- model do
14
- include SomeModule
15
- has_many :comments
16
- validates_presence_of :title
3
+ describe "A blog post" do
4
+ before :all do
5
+ module SomeModule; end
6
+ end
17
7
 
18
- def self.some_class_method
19
- 'chunky'
20
- end
8
+ after :all do
9
+ Object.send :remove_const, :SomeModule
10
+ end
21
11
 
22
- def some_instance_method
23
- 'bacon'
24
- end
25
- end
12
+ with_model :BlogPost do
13
+ # The table block works just like a migration.
14
+ table do |t|
15
+ t.string :title
16
+ t.timestamps
26
17
  end
27
18
 
28
- # with_model classes can have associations.
29
- with_model :Comment do
30
- table do |t|
31
- t.string :text
32
- t.belongs_to :blog_post
33
- t.timestamps
19
+ # The model block works just like the class definition.
20
+ model do
21
+ include SomeModule
22
+ has_many :comments
23
+ validates_presence_of :title
24
+
25
+ def self.some_class_method
26
+ 'chunky'
34
27
  end
35
28
 
36
- model do
37
- belongs_to :blog_post
29
+ def some_instance_method
30
+ 'bacon'
38
31
  end
39
32
  end
33
+ end
40
34
 
41
- it "can be accessed as a constant" do
42
- BlogPost.should be
35
+ # with_model classes can have associations.
36
+ with_model :Comment do
37
+ table do |t|
38
+ t.string :text
39
+ t.belongs_to :blog_post
40
+ t.timestamps
43
41
  end
44
42
 
45
- it "has the module" do
46
- BlogPost.include?(SomeModule).should be_true
43
+ model do
44
+ belongs_to :blog_post
47
45
  end
46
+ end
48
47
 
49
- it "has the class method" do
50
- BlogPost.some_class_method.should == 'chunky'
51
- end
48
+ it "can be accessed as a constant" do
49
+ expect(BlogPost).to be
50
+ end
52
51
 
53
- it "has the instance method" do
54
- BlogPost.new.some_instance_method.should == 'bacon'
55
- end
52
+ it "has the module" do
53
+ expect(BlogPost.include?(SomeModule)).to be_true
54
+ end
56
55
 
57
- it "can do all the things a regular model can" do
58
- record = BlogPost.new
59
- record.should_not be_valid
60
- record.title = "foo"
61
- record.should be_valid
62
- record.save.should be_true
63
- record.reload.should == record
64
- record.comments.create!(:text => "Lorem ipsum")
65
- record.comments.count.should == 1
66
- end
56
+ it "has the class method" do
57
+ expect(BlogPost.some_class_method).to eq 'chunky'
67
58
  end
68
59
 
69
- describe "another example group" do
70
- it "should not have the constant anymore" do
71
- defined?(BlogPost).should be_false
72
- end
60
+ it "has the instance method" do
61
+ expect(BlogPost.new.some_instance_method).to eq 'bacon'
73
62
  end
74
63
 
75
- describe "with table options" do
76
- with_model :WithOptions do
77
- table :id => false do |t|
78
- t.string 'foo'
79
- t.timestamps
80
- end
81
- end
64
+ it "can do all the things a regular model can" do
65
+ record = BlogPost.new
66
+ expect(record).to_not be_valid
67
+ record.title = "foo"
68
+ expect(record).to be_valid
69
+ expect(record.save).to be_true
70
+ expect(record.reload).to eq record
71
+ record.comments.create!(:text => "Lorem ipsum")
72
+ expect(record.comments.count).to eq 1
73
+ end
74
+
75
+ # with_model classes can have inheritance.
76
+ class Car < ActiveRecord::Base
77
+ self.abstract_class = true
78
+ end
79
+
80
+ with_model :Ford, superclass: Car do
81
+ end
82
+
83
+ it "has a specified superclass" do
84
+ expect(Ford < Car).to be_true
85
+ end
86
+ end
82
87
 
83
- it "should respect the additional options" do
84
- WithOptions.columns.map(&:name).should_not include("id")
88
+ describe "another example group" do
89
+ it "does not have the constant anymore" do
90
+ expect(defined?(BlogPost)).to be_false
91
+ end
92
+ end
93
+
94
+ describe "with table options" do
95
+ with_model :WithOptions do
96
+ table :id => false do |t|
97
+ t.string 'foo'
98
+ t.timestamps
85
99
  end
86
100
  end
101
+
102
+ it "respects the additional options" do
103
+ expect(WithOptions.columns.map(&:name)).to_not include("id")
104
+ end
105
+ end
@@ -1,5 +1,5 @@
1
- require "active_record"
2
- require "with_model"
1
+ require 'bundler'
2
+ Bundler.setup
3
3
 
4
4
  begin
5
5
  require 'coveralls'
@@ -7,43 +7,48 @@ begin
7
7
  rescue LoadError
8
8
  end
9
9
 
10
+ require 'with_model'
10
11
  RSpec.configure do |config|
11
12
  config.extend WithModel
13
+
14
+ config.warnings = true
15
+
16
+ config.expect_with :rspec do |c|
17
+ c.syntax = :expect
18
+ end
19
+
20
+ config.mock_with :rspec do |c|
21
+ c.syntax = :expect
22
+ end
12
23
  end
13
24
 
14
- jruby = RUBY_PLATFORM =~ /\bjava\b/
15
- adapter = jruby ? "jdbcsqlite3" : "sqlite3"
25
+ is_jruby = RUBY_PLATFORM =~ /\bjava\b/
26
+ adapter = is_jruby ? 'jdbcsqlite3' : 'sqlite3'
16
27
 
17
28
  # WithModel requires ActiveRecord::Base.connection to be established.
18
29
  # If ActiveRecord already has a connection, as in a Rails app, this is unnecessary.
19
- ActiveRecord::Base.establish_connection(:adapter => adapter, :database => ":memory:")
20
-
21
- # For readme_spec.rb
22
- module SomeModule; end
23
-
24
- if defined?(ActiveModel)
25
- shared_examples_for "ActiveModel" do
26
- require 'test/unit/assertions'
27
- require 'active_model/lint'
28
- include Test::Unit::Assertions
29
- include ActiveModel::Lint::Tests
30
-
31
- # to_s is to support ruby-1.9
32
- ActiveModel::Lint::Tests.public_instance_methods.map{|m| m.to_s}.grep(/^test/).each do |m|
33
- example m.gsub('_',' ') do
34
- begin
35
- send m
36
- rescue
37
- puts $!.message
38
- end
39
- end
40
- end
30
+ require 'active_record'
31
+ ActiveRecord::Base.establish_connection(:adapter => adapter, :database => ':memory:')
41
32
 
42
- before { @model = subject }
43
- end
33
+ if defined?(I18n) && I18n.respond_to?(:enforce_available_locales=)
34
+ I18n.enforce_available_locales = true
35
+ end
36
+
37
+ if ENV['LOGGER']
38
+ require 'logger'
39
+ ActiveRecord::Base.logger = Logger.new($stdout)
44
40
  end
45
41
 
46
- if ENV["LOGGER"]
47
- require "logger"
48
- ActiveRecord::Base.logger = Logger.new(STDOUT)
42
+ module SpecHelper
43
+ module RailsTestCompatability
44
+ if ::ActiveRecord::VERSION::STRING >= '4.1.0'
45
+ require 'minitest'
46
+ include Minitest::Assertions
47
+ def assertions; @assertions || 0; end
48
+ def assertions= value; @assertions = value; end
49
+ else
50
+ require 'test/unit/assertions'
51
+ include Test::Unit::Assertions
52
+ end
53
+ end
49
54
  end
@@ -1,5 +1,24 @@
1
+ require 'active_model'
1
2
  require 'spec_helper'
2
3
 
4
+ shared_examples_for "ActiveModel" do
5
+ require 'active_model/lint'
6
+ include SpecHelper::RailsTestCompatability
7
+ include ActiveModel::Lint::Tests
8
+
9
+ active_model_methods = ActiveModel::Lint::Tests.public_instance_methods
10
+ active_model_lint_tests = active_model_methods.map(&:to_s).grep(/^test/)
11
+
12
+ active_model_lint_tests.each do |method_name|
13
+ friendly_name = method_name.gsub('_', ' ')
14
+ example friendly_name do
15
+ public_send method_name.to_sym
16
+ end
17
+ end
18
+
19
+ before { @model = subject }
20
+ end
21
+
3
22
  describe "a temporary ActiveRecord model created with with_model" do
4
23
  non_shadowing_example_ran = false
5
24
 
@@ -22,52 +41,48 @@ describe "a temporary ActiveRecord model created with with_model" do
22
41
  non_shadowing_example_ran = true
23
42
  end
24
43
 
25
- it "should act like a normal ActiveRecord model" do
26
- record = BlogPost.create!(:title => 'New blog post', :content => "Hello, world!")
44
+ it "acts like a normal ActiveRecord model" do
45
+ record = BlogPost.create!(:title => 'New blog post', :content => 'Hello, world!')
27
46
 
28
47
  record.reload
29
48
 
30
- record.title.should == 'New blog post'
31
- record.content.should == 'Hello, world!'
32
- record.updated_at.should be_present
49
+ expect(record.title).to eq 'New blog post'
50
+ expect(record.content).to eq 'Hello, world!'
51
+ expect(record.updated_at).to be_present
33
52
 
34
53
  record.destroy
35
54
 
36
- lambda {
37
- record.reload
38
- }.should raise_error(ActiveRecord::RecordNotFound)
55
+ expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
39
56
  end
40
57
 
41
- if defined?(ActiveModel)
42
- describe "the class" do
43
- subject { BlogPost.new }
44
- it_should_behave_like "ActiveModel"
45
- end
58
+ describe "the class" do
59
+ subject { BlogPost.new }
60
+ it_should_behave_like "ActiveModel"
46
61
  end
47
62
 
48
- it "should have methods defined in its model block" do
49
- BlogPost.new(:title => 'New blog post').fancy_title.should == "Title: New blog post"
63
+ it "has the methods defined in its model block" do
64
+ expect(BlogPost.new(:title => 'New blog post').fancy_title).to eq 'Title: New blog post'
50
65
  end
51
66
 
52
- it "should define a constant" do
53
- BlogPost.should be_a(Class)
67
+ it "defines a constant" do
68
+ expect(BlogPost).to be_a(Class)
54
69
  end
55
70
 
56
71
  describe ".with_model?" do
57
- it "should return true" do
58
- BlogPost.with_model?.should be_true
72
+ it "returns true" do
73
+ expect(BlogPost.with_model?).to be_true
59
74
  end
60
75
  end
61
76
 
62
- it "should have a base_class of itself" do
63
- BlogPost.base_class.should == BlogPost
77
+ it "is its own base_class" do
78
+ expect(BlogPost.base_class).to eq BlogPost
64
79
  end
65
80
  end
66
81
 
67
82
  context "after an example which uses with_model without shadowing an existing constant" do
68
- it "should return the constant to its undefined state" do
69
- non_shadowing_example_ran.should be_true
70
- defined?(BlogPost).should be_false
83
+ it "returns the constant to its undefined state" do
84
+ expect(non_shadowing_example_ran).to be_true
85
+ expect(defined?(BlogPost)).to be_false
71
86
  end
72
87
  end
73
88
 
@@ -82,49 +97,59 @@ describe "a temporary ActiveRecord model created with with_model" do
82
97
  shadowing_example_ran = true
83
98
  end
84
99
 
85
- it "should shadow that constant" do
86
- MyConst.should be_a(Class)
100
+ it "shadows that constant" do
101
+ expect(MyConst).to be_a(Class)
87
102
  end
88
103
  end
89
104
 
90
105
  context "in later examples" do
91
- it "should return the constant to its original value" do
92
- shadowing_example_ran.should be_true
93
- MyConst.should == 1
106
+ it "returns the constant to its original value" do
107
+ expect(shadowing_example_ran).to be_true
108
+ expect(MyConst).to eq 1
94
109
  end
95
110
  end
96
111
 
97
112
  describe "with a plural name" do
98
113
  with_model :BlogPosts
99
114
 
100
- it "should not singularize the constant name" do
101
- BlogPosts.should be
102
- lambda { BlogPost }.should raise_error(NameError)
115
+ it "does not singularize the constant name" do
116
+ expect(BlogPosts).to be
117
+ expect(lambda { BlogPost }).to raise_error(NameError)
103
118
  end
104
119
  end
105
120
 
106
121
  describe "with a name containing capital letters" do
107
122
  with_model :BlogPost
108
123
 
109
- it "should tableize the table name" do
110
- BlogPost.table_name.should match(/_blog_posts_/)
111
- BlogPost.table_name.should == BlogPost.table_name.downcase
124
+ it "tableizes the table name" do
125
+ expect(BlogPost.table_name).to match(/_blog_posts_/)
126
+ expect(BlogPost.table_name).to eq BlogPost.table_name.downcase
112
127
  end
113
128
  end
114
129
 
115
130
  describe "with a name with underscores" do
116
131
  with_model :blog_post
117
132
 
118
- it "should constantize the name" do
119
- BlogPost.should be
133
+ it "constantizes the name" do
134
+ expect(BlogPost).to be
120
135
  end
121
136
 
122
- it "should tableize the table name" do
123
- BlogPost.table_name.should match(/_blog_posts_/)
124
- BlogPost.table_name.should == BlogPost.table_name.downcase
137
+ it "tableizes the table name" do
138
+ expect(BlogPost.table_name).to match(/_blog_posts_/)
139
+ expect(BlogPost.table_name).to eq BlogPost.table_name.downcase
125
140
  end
126
141
  end
127
142
 
143
+ describe "using the constant in the model block" do
144
+ with_model :BlogPost do
145
+ model do
146
+ raise 'I am not myself!' unless self == BlogPost
147
+ end
148
+ end
149
+
150
+ it "is available" do end
151
+ end
152
+
128
153
  module AMixin
129
154
  def foo
130
155
  end
@@ -139,9 +164,9 @@ describe "a temporary ActiveRecord model created with with_model" do
139
164
 
140
165
  before { ::ModelWithMixin = WithAMixin }
141
166
 
142
- it "should have the mixin" do
143
- lambda { ::ModelWithMixin.new.foo }.should_not raise_error
144
- ::ModelWithMixin.include?(AMixin).should be_true
167
+ it "has the mixin" do
168
+ expect(lambda { ::ModelWithMixin.new.foo }).to_not raise_error
169
+ expect(::ModelWithMixin.include?(AMixin)).to be_true
145
170
  end
146
171
  end
147
172
 
@@ -163,26 +188,17 @@ describe "a temporary ActiveRecord model created with with_model" do
163
188
  end
164
189
  end
165
190
 
166
- it "should only have one after_save callback" do
167
- subject.should_receive(:my_method).once
191
+ it "only has one after_save callback" do
192
+ expect(subject).to receive(:my_method).once
168
193
  subject.save
169
194
  end
170
195
 
171
- it "should still only have one after_save callback in future tests" do
172
- subject.should_receive(:my_method).once
196
+ it "still only has one after_save callback in future tests" do
197
+ expect(subject).to receive(:my_method).once
173
198
  subject.save
174
199
  end
175
200
  end
176
201
 
177
- if defined?(Mixico)
178
- context "after a context that uses a mixin" do
179
- it "should not have the mixin" do
180
- lambda { ::ModelWithMixin.new.foo }.should raise_error(NoMethodError)
181
- ::ModelWithMixin.include?(AMixin).should be_false
182
- end
183
- end
184
- end
185
-
186
202
  context "with table options" do
187
203
  with_model :WithOptions do
188
204
  table :id => false do |t|
@@ -191,48 +207,40 @@ describe "a temporary ActiveRecord model created with with_model" do
191
207
  end
192
208
  end
193
209
 
194
- it "should respect the additional options" do
195
- WithOptions.columns.map(&:name).should_not include("id")
210
+ it "respects the additional options" do
211
+ expect(WithOptions.columns.map(&:name)).to_not include('id')
196
212
  end
197
213
  end
198
214
 
199
215
  context "without a block" do
200
216
  with_model :BlogPost
201
217
 
202
- it "should act like a normal ActiveRecord model" do
218
+ it "acts like a normal ActiveRecord model" do
203
219
  record = BlogPost.create!
204
220
  record.reload
205
221
  record.destroy
206
- lambda {
207
- record.reload
208
- }.should raise_error(ActiveRecord::RecordNotFound)
222
+ expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
209
223
  end
210
224
 
211
- if defined?(ActiveModel)
212
- describe "the class" do
213
- subject { BlogPost.new }
214
- it_should_behave_like "ActiveModel"
215
- end
225
+ describe "the class" do
226
+ subject { BlogPost.new }
227
+ it_should_behave_like "ActiveModel"
216
228
  end
217
229
  end
218
230
 
219
231
  context "with an empty block" do
220
232
  with_model(:BlogPost) {}
221
233
 
222
- it "should act like a normal ActiveRecord model" do
234
+ it "acts like a normal ActiveRecord model" do
223
235
  record = BlogPost.create!
224
236
  record.reload
225
237
  record.destroy
226
- lambda {
227
- record.reload
228
- }.should raise_error(ActiveRecord::RecordNotFound)
238
+ expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
229
239
  end
230
240
 
231
- if defined?(ActiveModel)
232
- describe "the class" do
233
- subject { BlogPost.new }
234
- it_should_behave_like "ActiveModel"
235
- end
241
+ describe "the class" do
242
+ subject { BlogPost.new }
243
+ it_should_behave_like "ActiveModel"
236
244
  end
237
245
  end
238
246
 
@@ -245,50 +253,40 @@ describe "a temporary ActiveRecord model created with with_model" do
245
253
  end
246
254
  end
247
255
 
248
- it "should act like a normal ActiveRecord model" do
249
- record = BlogPost.create!(:title => 'New blog post', :content => "Hello, world!")
256
+ it "acts like a normal ActiveRecord model" do
257
+ record = BlogPost.create!(:title => 'New blog post', :content => 'Hello, world!')
250
258
 
251
259
  record.reload
252
260
 
253
- record.title.should == 'New blog post'
254
- record.content.should == 'Hello, world!'
255
- record.updated_at.should be_present
261
+ expect(record.title).to eq 'New blog post'
262
+ expect(record.content).to eq 'Hello, world!'
263
+ expect(record.updated_at).to be_present
256
264
 
257
265
  record.destroy
258
266
 
259
- lambda {
260
- record.reload
261
- }.should raise_error(ActiveRecord::RecordNotFound)
267
+ expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
262
268
  end
263
269
 
264
- if defined?(ActiveModel)
265
- describe "the class" do
266
- subject { BlogPost.new }
267
- it_should_behave_like "ActiveModel"
268
- end
270
+ describe "the class" do
271
+ subject { BlogPost.new }
272
+ it_should_behave_like "ActiveModel"
269
273
  end
270
-
271
274
  end
272
275
 
273
- context "without a table block" do
274
- with_model :BlogPost do
275
- end
276
+ context "without a table or model block" do
277
+ with_model :BlogPost
276
278
 
277
- it "should act like a normal ActiveRecord model" do
278
- BlogPost.columns.map(&:name).should == ["id"]
279
+ it "acts like a normal ActiveRecord model" do
280
+ expect(BlogPost.columns.map(&:name)).to eq ['id']
279
281
  record = BlogPost.create!
280
282
  record.reload
281
283
  record.destroy
282
- lambda {
283
- record.reload
284
- }.should raise_error(ActiveRecord::RecordNotFound)
284
+ expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
285
285
  end
286
286
 
287
- if defined?(ActiveModel)
288
- describe "the class" do
289
- subject { BlogPost.new }
290
- it_should_behave_like "ActiveModel"
291
- end
287
+ describe "the class" do
288
+ subject { BlogPost.new }
289
+ it_should_behave_like "ActiveModel"
292
290
  end
293
291
  end
294
292
 
@@ -296,15 +294,46 @@ describe "a temporary ActiveRecord model created with with_model" do
296
294
  with_model :BlogPost
297
295
 
298
296
  it "includes the correct model class in descendants on the first test run" do
299
- ActiveRecord::Base.descendants.detect do |c|
297
+ descendant = ActiveRecord::Base.descendants.detect do |c|
300
298
  c.table_name == BlogPost.table_name
301
- end.should == BlogPost
299
+ end
300
+ expect(descendant).to eq BlogPost
302
301
  end
303
302
 
304
303
  it "includes the correct model class in descendants on the second test run" do
305
- ActiveRecord::Base.descendants.detect do |c|
304
+ descendant = ActiveRecord::Base.descendants.detect do |c|
306
305
  c.table_name == BlogPost.table_name
307
- end.should == BlogPost
306
+ end
307
+ expect(descendant).to eq BlogPost
308
+ end
309
+ end
310
+
311
+ context "with 'superclass' option" do
312
+ class BlogPostParent < ActiveRecord::Base
313
+ self.abstract_class = true
314
+ end
315
+
316
+ with_model :BlogPost, superclass: BlogPostParent do
317
+ table do |t|
318
+ t.string 'title'
319
+ end
320
+ end
321
+
322
+ describe "the class" do
323
+ subject { BlogPost.new }
324
+ it_should_behave_like "ActiveModel"
325
+ end
326
+
327
+ it "is a subclass of the supplied superclass" do
328
+ expect(BlogPost < BlogPostParent).to be_true
329
+ end
330
+
331
+ it "is its own base_class" do
332
+ expect(BlogPost.base_class).to eq BlogPost
333
+ end
334
+
335
+ it "responds to .with_model? with true" do
336
+ expect(BlogPost.with_model?).to be_true
308
337
  end
309
338
  end
310
339
  end