with_model 0.3.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b88698902a3eed64e0fc34a173d4758e4f108dc5
|
4
|
+
data.tar.gz: 49b3e03abeccfc847d9f5751e5107ff3c486233e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e021cf0aa7032ea90c7572f28172d2158062682f382fbe8036489b88120607e986638c3b059cf3be30605f93465c90e3c417ff616f8b385a2eff0f097a4d1814
|
7
|
+
data.tar.gz: efd6470ae68ea7ae8861f8b0067c8fddb67062553e68eb88ec6c6afa53fc8f7160f8e05490fb1521da135e6c2fde76ec473dab85f0e48e3caa13a9781e12ca67
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,30 +1,20 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
|
-
script: "bundle exec rspec spec"
|
4
|
-
|
5
3
|
rvm:
|
6
|
-
- 1.8.7
|
7
4
|
- 1.9.3
|
8
5
|
- 2.0.0
|
9
|
-
- jruby-18mode
|
10
6
|
- jruby-19mode
|
11
|
-
- rbx-
|
12
|
-
- rbx-19mode
|
13
|
-
- ree
|
7
|
+
- rbx-2.2
|
14
8
|
|
15
9
|
env:
|
16
|
-
-
|
10
|
+
- ACTIVE_RECORD_BRANCH="master"
|
11
|
+
- ACTIVE_RECORD_BRANCH="4-0-stable"
|
12
|
+
- ACTIVE_RECORD_VERSION="~> 4.0.0"
|
17
13
|
- ACTIVE_RECORD_VERSION="~> 3.2.0"
|
18
14
|
- ACTIVE_RECORD_VERSION="~> 3.1.0"
|
19
15
|
- ACTIVE_RECORD_VERSION="~> 3.0.0"
|
20
16
|
|
21
17
|
matrix:
|
22
18
|
allow_failures:
|
23
|
-
- env:
|
24
|
-
|
25
|
-
- rvm:
|
26
|
-
- 1.8.7
|
27
|
-
- jruby-18mode
|
28
|
-
- rbx-18mode
|
29
|
-
- ree
|
30
|
-
env: ACTIVE_RECORD_VERSION="~> 4.0.0.rc1"
|
19
|
+
- env: ACTIVE_RECORD_BRANCH="master"
|
20
|
+
- env: ACTIVE_RECORD_BRANCH="4-0-stable"
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
### 1.0.0
|
2
|
+
- Start using [Semantic Versioning 2.0.0](http://semver.org/spec/v2.0.0.html)
|
3
|
+
- Complete refactor of internals (Andrew Marshall)
|
4
|
+
- Remove support for Active Record 2 (Andrew Marshall)
|
5
|
+
- Remove dependency on RSpec (Andrew Marshall)
|
6
|
+
- Add support for MiniTest (Andrew Marshall)
|
7
|
+
- Add option for specifying superclass (Miks Miķelsons)
|
8
|
+
|
9
|
+
### 0.3.2
|
10
|
+
|
11
|
+
- Allow calling with_model without a block. (Andrew Marshall)
|
12
|
+
- Ensure that ActiveSupport's descendants works correctly between tests. (Andrew Marshall)
|
13
|
+
- Allow Active Record 4 in gemspec.
|
14
|
+
|
15
|
+
### 0.3.1
|
16
|
+
|
17
|
+
- Don't cache connection between tests. (Ryan Ong & Richard Nuno)
|
18
|
+
|
19
|
+
### 0.3
|
20
|
+
|
21
|
+
- Use RSpec 2.11's built-in constant stubbing.
|
22
|
+
- Remove RSpec 1.x and Active Record 2.x support.
|
23
|
+
- Remove Mixico support.
|
24
|
+
|
25
|
+
### 0.2.6
|
26
|
+
|
27
|
+
- Active Record 3.2 compatible. (Steven Harman / Brent Wheeldon)
|
28
|
+
|
29
|
+
### 0.2.5
|
30
|
+
|
31
|
+
- Clear Active Record 3.x associations class cache between specs to clean up test
|
32
|
+
- pollution.
|
33
|
+
|
34
|
+
### 0.2.4
|
35
|
+
|
36
|
+
- Active Record 3.1 compatible.
|
37
|
+
- Fix bug where column information was being cached incorrectly by Active
|
38
|
+
- Record.
|
39
|
+
|
40
|
+
### 0.2.3
|
41
|
+
|
42
|
+
- Create a new class each run to prevent test pollution. (J. Andrew Marshall)
|
43
|
+
- Use :UpperCase in examples.
|
44
|
+
|
45
|
+
### 0.2.2
|
46
|
+
|
47
|
+
- The table block is now optional.
|
48
|
+
|
49
|
+
### 0.2.1
|
50
|
+
|
51
|
+
- Fix a bug when the with_model name contains capital letters. Now you can
|
52
|
+
- safely make calls like `with_model :BlogPost`
|
53
|
+
|
54
|
+
### 0.2
|
55
|
+
|
56
|
+
- Remove the buggy attr_accessor method for accessing with_model classes. Now
|
57
|
+
- there is only the constant available in the example group.
|
58
|
+
|
59
|
+
### 0.1.5
|
60
|
+
|
61
|
+
- WithModel::Base is now marked as an abstract_class, which makes polymorphic
|
62
|
+
- belongs_to work properly.
|
63
|
+
|
64
|
+
### 0.1.4
|
65
|
+
|
66
|
+
- Add ability to pass arguments to create_table.
|
67
|
+
|
68
|
+
### 0.1.2
|
69
|
+
|
70
|
+
- Make Mixico optional.
|
data/Gemfile
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
gem
|
8
|
-
gem "rdoc"
|
5
|
+
gem 'activerecord', :github => 'rails', :branch => ENV['ACTIVE_RECORD_BRANCH'] if ENV['ACTIVE_RECORD_BRANCH']
|
6
|
+
gem 'activerecord', ENV['ACTIVE_RECORD_VERSION'] if ENV['ACTIVE_RECORD_VERSION']
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter', :platforms => :jruby
|
9
8
|
gem 'coveralls', :require => false, :platform => :mri_20
|
10
|
-
gem '
|
9
|
+
gem 'sqlite3', :platforms => :ruby
|
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
# [with_model](https://github.com/Casecommons/with_model)
|
2
|
+
|
3
|
+
[](https://travis-ci.org/Casecommons/with_model)
|
4
|
+
[](https://codeclimate.com/github/Casecommons/with_model)
|
5
|
+
[](https://coveralls.io/r/Casecommons/with_model)
|
6
|
+
[](https://rubygems.org/gems/with_model)
|
7
|
+
[](https://gemnasium.com/Casecommons/with_model)
|
8
|
+
|
9
|
+
`with_model` dynamically builds an ActiveRecord model (with table) before each test in a group and destroys it afterwards.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install as usual: `gem install with_model` or add `gem 'with_model'` to your Gemfile. See `.travis.yml` for supported (tested) Ruby versions.
|
14
|
+
|
15
|
+
## RSpec
|
16
|
+
|
17
|
+
Extend `WithModel` into RSpec:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require 'with_model'
|
21
|
+
|
22
|
+
RSpec.configure do |config|
|
23
|
+
config.extend WithModel
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
## minitest/spec
|
28
|
+
|
29
|
+
Extend `WithModel` into minitest/spec:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'with_model'
|
33
|
+
|
34
|
+
class Minitest::Spec
|
35
|
+
extend WithModel
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
After setting up as above, call `with_model` and inside its block pass it a `table` block and a `model` block.
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
require 'spec_helper'
|
45
|
+
|
46
|
+
describe "A blog post" do
|
47
|
+
before :all do
|
48
|
+
module SomeModule; end
|
49
|
+
end
|
50
|
+
|
51
|
+
after :all do
|
52
|
+
Object.send :remove_const, :SomeModule
|
53
|
+
end
|
54
|
+
|
55
|
+
with_model :BlogPost do
|
56
|
+
# The table block works just like a migration.
|
57
|
+
table do |t|
|
58
|
+
t.string :title
|
59
|
+
t.timestamps
|
60
|
+
end
|
61
|
+
|
62
|
+
# The model block works just like the class definition.
|
63
|
+
model do
|
64
|
+
include SomeModule
|
65
|
+
has_many :comments
|
66
|
+
validates_presence_of :title
|
67
|
+
|
68
|
+
def self.some_class_method
|
69
|
+
'chunky'
|
70
|
+
end
|
71
|
+
|
72
|
+
def some_instance_method
|
73
|
+
'bacon'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# with_model classes can have associations.
|
79
|
+
with_model :Comment do
|
80
|
+
table do |t|
|
81
|
+
t.string :text
|
82
|
+
t.belongs_to :blog_post
|
83
|
+
t.timestamps
|
84
|
+
end
|
85
|
+
|
86
|
+
model do
|
87
|
+
belongs_to :blog_post
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "can be accessed as a constant" do
|
92
|
+
expect(BlogPost).to be
|
93
|
+
end
|
94
|
+
|
95
|
+
it "has the module" do
|
96
|
+
expect(BlogPost.include?(SomeModule)).to be_true
|
97
|
+
end
|
98
|
+
|
99
|
+
it "has the class method" do
|
100
|
+
expect(BlogPost.some_class_method).to eq 'chunky'
|
101
|
+
end
|
102
|
+
|
103
|
+
it "has the instance method" do
|
104
|
+
expect(BlogPost.new.some_instance_method).to eq 'bacon'
|
105
|
+
end
|
106
|
+
|
107
|
+
it "can do all the things a regular model can" do
|
108
|
+
record = BlogPost.new
|
109
|
+
expect(record).to_not be_valid
|
110
|
+
record.title = "foo"
|
111
|
+
expect(record).to be_valid
|
112
|
+
expect(record.save).to be_true
|
113
|
+
expect(record.reload).to eq record
|
114
|
+
record.comments.create!(:text => "Lorem ipsum")
|
115
|
+
expect(record.comments.count).to eq 1
|
116
|
+
end
|
117
|
+
|
118
|
+
# with_model classes can have inheritance.
|
119
|
+
class Car < ActiveRecord::Base
|
120
|
+
self.abstract_class = true
|
121
|
+
end
|
122
|
+
|
123
|
+
with_model :Ford, superclass: Car do
|
124
|
+
end
|
125
|
+
|
126
|
+
it "has a specified superclass" do
|
127
|
+
expect(Ford < Car).to be_true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "another example group" do
|
132
|
+
it "does not have the constant anymore" do
|
133
|
+
expect(defined?(BlogPost)).to be_false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "with table options" do
|
138
|
+
with_model :WithOptions do
|
139
|
+
table :id => false do |t|
|
140
|
+
t.string 'foo'
|
141
|
+
t.timestamps
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it "respects the additional options" do
|
146
|
+
expect(WithOptions.columns.map(&:name)).to_not include("id")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
```
|
150
|
+
|
151
|
+
## Requirements
|
152
|
+
|
153
|
+
- Ruby 1.9.3+
|
154
|
+
- RSpec or minitest/spec
|
155
|
+
- ActiveRecord 3+ (for ActiveRecord 2, use with_model 0.2.x)
|
156
|
+
|
157
|
+
## Versioning
|
158
|
+
|
159
|
+
As of version 1.0.0, with_model uses [Semantic Versioning 2.0.0](http://semver.org/spec/v2.0.0.html). Previous versions used an ad-hoc versioning scheme.
|
160
|
+
|
161
|
+
## License
|
162
|
+
|
163
|
+
Copyright © 2010-2014 Case Commons, LLC.
|
164
|
+
Licensed under the MIT license, available in the “LICENSE” file.
|
data/Rakefile
CHANGED
@@ -1,21 +1,13 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
def bundle_exec(command)
|
7
|
-
sh %Q{bundle update && bundle exec #{command}}
|
8
|
-
end
|
9
|
-
|
10
|
-
desc "Run all specs"
|
11
|
-
task "spec" do
|
12
|
-
bundle_exec("rspec spec")
|
13
|
-
end
|
4
|
+
desc 'Run specs'
|
5
|
+
RSpec::Core::RakeTask.new
|
14
6
|
|
15
7
|
namespace "doc" do
|
16
8
|
desc "Generate README and preview in browser"
|
17
9
|
task "readme" do
|
18
|
-
sh "
|
10
|
+
sh "markdown README.md > README.html && open README.html"
|
19
11
|
end
|
20
12
|
end
|
21
13
|
|
data/lib/with_model.rb
CHANGED
@@ -1,23 +1,22 @@
|
|
1
|
+
require 'with_model/model'
|
2
|
+
require 'with_model/model/dsl'
|
3
|
+
require 'with_model/table'
|
4
|
+
require 'with_model/version'
|
5
|
+
|
1
6
|
module WithModel
|
2
|
-
|
3
|
-
|
4
|
-
|
7
|
+
def with_model(name, options = {}, &block)
|
8
|
+
model = Model.new name, options
|
9
|
+
dsl = Model::DSL.new model
|
10
|
+
dsl.instance_exec(&block) if block
|
5
11
|
|
6
|
-
|
7
|
-
|
8
|
-
dsl.instance_eval(&block) if block
|
9
|
-
dsl.execute
|
12
|
+
before { model.create }
|
13
|
+
after { model.destroy }
|
10
14
|
end
|
11
15
|
|
12
16
|
def with_table(name, options = {}, &block)
|
13
|
-
|
14
|
-
connection = ActiveRecord::Base.connection
|
15
|
-
connection.drop_table(name) if connection.table_exists?(name)
|
16
|
-
connection.create_table(name, options, &block)
|
17
|
-
end
|
17
|
+
table = Table.new name, options, &block
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
19
|
+
before { table.create }
|
20
|
+
after { table.destroy }
|
22
21
|
end
|
23
22
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WithModel
|
2
|
+
class ConstantStubber
|
3
|
+
def initialize const_name
|
4
|
+
@const_name = const_name.to_sym
|
5
|
+
@original_value = nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def stub_const value
|
9
|
+
if Object.const_defined?(@const_name)
|
10
|
+
@original_value = Object.const_get(@const_name)
|
11
|
+
Object.send :remove_const, @const_name
|
12
|
+
end
|
13
|
+
|
14
|
+
Object.const_set @const_name, value
|
15
|
+
end
|
16
|
+
|
17
|
+
def unstub_const
|
18
|
+
Object.send :remove_const, @const_name
|
19
|
+
Object.const_set @const_name, @original_value if @original_value
|
20
|
+
@original_value = nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
private_constant :ConstantStubber
|
24
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
require 'with_model/constant_stubber'
|
3
|
+
require 'with_model/methods'
|
4
|
+
require 'with_model/table'
|
5
|
+
|
6
|
+
module WithModel
|
7
|
+
class Model
|
8
|
+
attr_writer :model_block, :table_block, :table_options
|
9
|
+
|
10
|
+
def initialize name, options = {}
|
11
|
+
@name = name.to_sym
|
12
|
+
@options = options
|
13
|
+
@model_block = proc {}
|
14
|
+
@table_block = proc {}
|
15
|
+
@table_options = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
table.create
|
20
|
+
@model = Class.new(superclass)
|
21
|
+
|
22
|
+
class << @model
|
23
|
+
include WithModel::Methods
|
24
|
+
end
|
25
|
+
|
26
|
+
stubber.stub_const @model
|
27
|
+
setup_model
|
28
|
+
end
|
29
|
+
|
30
|
+
def superclass
|
31
|
+
@options.fetch(:superclass) { ActiveRecord::Base }
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
stubber.unstub_const
|
36
|
+
remove_from_superclass_descendants
|
37
|
+
reset_dependencies_cache
|
38
|
+
table.destroy
|
39
|
+
@model = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def const_name
|
45
|
+
@name.to_s.camelize.freeze
|
46
|
+
end
|
47
|
+
|
48
|
+
def setup_model
|
49
|
+
@model.table_name = table_name
|
50
|
+
@model.class_eval(&@model_block)
|
51
|
+
@model.reset_column_information
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove_from_superclass_descendants
|
55
|
+
return unless @model.superclass.respond_to?(:direct_descendants)
|
56
|
+
@model.superclass.direct_descendants.delete(@model)
|
57
|
+
end
|
58
|
+
|
59
|
+
def reset_dependencies_cache
|
60
|
+
return unless defined?(ActiveSupport::Dependencies::Reference)
|
61
|
+
ActiveSupport::Dependencies::Reference.clear!
|
62
|
+
end
|
63
|
+
|
64
|
+
def stubber
|
65
|
+
@stubber ||= ConstantStubber.new const_name
|
66
|
+
end
|
67
|
+
|
68
|
+
def table
|
69
|
+
@table ||= Table.new table_name, @table_options, &@table_block
|
70
|
+
end
|
71
|
+
|
72
|
+
def table_name
|
73
|
+
"with_model_#{@name.to_s.tableize}_#{$$}".freeze
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|