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.
- checksums.yaml +4 -4
- data/.gitignore +5 -4
- data/.travis.yml +6 -16
- data/CHANGELOG.md +70 -0
- data/Gemfile +5 -6
- data/LICENSE +1 -1
- data/README.md +164 -0
- data/Rakefile +5 -13
- data/lib/with_model.rb +14 -15
- data/lib/with_model/constant_stubber.rb +24 -0
- data/lib/with_model/methods.rb +7 -0
- data/lib/with_model/model.rb +76 -0
- data/lib/with_model/model/dsl.rb +18 -0
- data/lib/with_model/table.rb +21 -0
- data/lib/with_model/version.rb +1 -1
- data/spec/active_record_behaviors_spec.rb +21 -19
- data/spec/readme_spec.rb +82 -63
- data/spec/spec_helper.rb +36 -31
- data/spec/with_model_spec.rb +136 -107
- data/with_model.gemspec +25 -19
- metadata +47 -16
- data/.autotest +0 -5
- data/CHANGELOG +0 -62
- data/README.rdoc +0 -122
- data/lib/with_model/base.rb +0 -10
- data/lib/with_model/dsl.rb +0 -53
@@ -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
|
data/lib/with_model/version.rb
CHANGED
@@ -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
|
-
|
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 "
|
36
|
-
included = RegularModel.create!(:title => 'foo', :content =>
|
37
|
-
excluded = RegularModel.create!(:title => 'bar', :content =>
|
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.
|
41
|
+
expect(RegularModel.title_is_foo).to eq [included]
|
40
42
|
|
41
|
-
included = BlogPost.create!(:title => 'foo', :content =>
|
42
|
-
excluded = BlogPost.create!(:title => 'bar', :content =>
|
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.
|
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
|
-
|
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 "
|
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.
|
80
|
-
animal.tea_cups.
|
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.
|
84
|
-
stuffed_animal.tea_cups.
|
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
|
101
|
-
end
|
103
|
+
with_model :Country
|
102
104
|
|
103
105
|
context "in earlier examples" do
|
104
|
-
it "
|
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 "
|
111
|
-
Province.reflect_on_association(:country).klass.
|
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
|
data/spec/readme_spec.rb
CHANGED
@@ -1,86 +1,105 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
8
|
+
after :all do
|
9
|
+
Object.send :remove_const, :SomeModule
|
10
|
+
end
|
21
11
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
37
|
-
|
29
|
+
def some_instance_method
|
30
|
+
'bacon'
|
38
31
|
end
|
39
32
|
end
|
33
|
+
end
|
40
34
|
|
41
|
-
|
42
|
-
|
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
|
-
|
46
|
-
|
43
|
+
model do
|
44
|
+
belongs_to :blog_post
|
47
45
|
end
|
46
|
+
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
it "can be accessed as a constant" do
|
49
|
+
expect(BlogPost).to be
|
50
|
+
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
it "has the module" do
|
53
|
+
expect(BlogPost.include?(SomeModule)).to be_true
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
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
|
-
|
70
|
-
|
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
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
-
|
84
|
-
|
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
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
|
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
|
-
|
15
|
-
adapter =
|
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
|
-
|
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
|
-
|
43
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
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
|
data/spec/with_model_spec.rb
CHANGED
@@ -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 "
|
26
|
-
record = BlogPost.create!(:title => 'New blog post', :content =>
|
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.
|
31
|
-
record.content.
|
32
|
-
record.updated_at.
|
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
|
-
|
37
|
-
record.reload
|
38
|
-
}.should raise_error(ActiveRecord::RecordNotFound)
|
55
|
+
expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
39
56
|
end
|
40
57
|
|
41
|
-
|
42
|
-
|
43
|
-
|
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 "
|
49
|
-
BlogPost.new(:title => 'New blog post').fancy_title.
|
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 "
|
53
|
-
BlogPost.
|
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 "
|
58
|
-
BlogPost.with_model
|
72
|
+
it "returns true" do
|
73
|
+
expect(BlogPost.with_model?).to be_true
|
59
74
|
end
|
60
75
|
end
|
61
76
|
|
62
|
-
it "
|
63
|
-
BlogPost.base_class.
|
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 "
|
69
|
-
non_shadowing_example_ran.
|
70
|
-
defined?(BlogPost).
|
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 "
|
86
|
-
MyConst.
|
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 "
|
92
|
-
shadowing_example_ran.
|
93
|
-
MyConst.
|
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 "
|
101
|
-
BlogPosts.
|
102
|
-
lambda { BlogPost }.
|
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 "
|
110
|
-
BlogPost.table_name.
|
111
|
-
BlogPost.table_name.
|
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 "
|
119
|
-
BlogPost.
|
133
|
+
it "constantizes the name" do
|
134
|
+
expect(BlogPost).to be
|
120
135
|
end
|
121
136
|
|
122
|
-
it "
|
123
|
-
BlogPost.table_name.
|
124
|
-
BlogPost.table_name.
|
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 "
|
143
|
-
lambda { ::ModelWithMixin.new.foo }.
|
144
|
-
::ModelWithMixin.include?(AMixin).
|
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 "
|
167
|
-
subject.
|
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 "
|
172
|
-
subject.
|
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 "
|
195
|
-
WithOptions.columns.map(&:name).
|
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 "
|
218
|
+
it "acts like a normal ActiveRecord model" do
|
203
219
|
record = BlogPost.create!
|
204
220
|
record.reload
|
205
221
|
record.destroy
|
206
|
-
|
207
|
-
record.reload
|
208
|
-
}.should raise_error(ActiveRecord::RecordNotFound)
|
222
|
+
expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
209
223
|
end
|
210
224
|
|
211
|
-
|
212
|
-
|
213
|
-
|
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 "
|
234
|
+
it "acts like a normal ActiveRecord model" do
|
223
235
|
record = BlogPost.create!
|
224
236
|
record.reload
|
225
237
|
record.destroy
|
226
|
-
|
227
|
-
record.reload
|
228
|
-
}.should raise_error(ActiveRecord::RecordNotFound)
|
238
|
+
expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
229
239
|
end
|
230
240
|
|
231
|
-
|
232
|
-
|
233
|
-
|
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 "
|
249
|
-
record = BlogPost.create!(:title => 'New blog post', :content =>
|
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.
|
254
|
-
record.content.
|
255
|
-
record.updated_at.
|
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
|
-
|
260
|
-
record.reload
|
261
|
-
}.should raise_error(ActiveRecord::RecordNotFound)
|
267
|
+
expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
262
268
|
end
|
263
269
|
|
264
|
-
|
265
|
-
|
266
|
-
|
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
|
275
|
-
end
|
276
|
+
context "without a table or model block" do
|
277
|
+
with_model :BlogPost
|
276
278
|
|
277
|
-
it "
|
278
|
-
BlogPost.columns.map(&:name).
|
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
|
-
|
283
|
-
record.reload
|
284
|
-
}.should raise_error(ActiveRecord::RecordNotFound)
|
284
|
+
expect { record.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
285
285
|
end
|
286
286
|
|
287
|
-
|
288
|
-
|
289
|
-
|
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
|
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
|
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
|