with_model 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22f429a5cb8e986623de65004594810d642f7ca21b0bf24a0a1257defa40add9
4
- data.tar.gz: a7a0cbbe47ba722b1359a438c18692a7927ff957c88cd0e0919ac3ab4ac65e92
3
+ metadata.gz: 8a9994ddf84f8fe654f6670173ea2cf6d8a739c1033bc17ca9765001fc0f8f50
4
+ data.tar.gz: f432e1faa7d071b4219dadf9f64a4d7202d67d2fcb0c95b01157848be12252d5
5
5
  SHA512:
6
- metadata.gz: 63d816a1fe0782ee315073325b6eb59b468bc87c7899f3a124c181cc6542ee9c31d55768a3e2af8234ec6ffad9bb92037b012da5328128e835fce4a74d7a6b15
7
- data.tar.gz: 6da66d3cbf860d19d5a2c661e01e75ff7aef341d78d64d12055d5c28ebc5e7401ea5c095b6b006da1c01bcb4b2100bf524681a63292ccf791cff7def6a987115
6
+ metadata.gz: 7654d570583cea72d142bf0d70416d539704198f7ca9d447fb52b1917e016f05622a4d7f53a03ca6c3002d61ce3a2301ddae4ee6982312ff0c3e5d2b57fa4f7c
7
+ data.tar.gz: b90401f8f508ab719cddd294dd5bcc104c09e075df83f55e65e4884cfc0202ed38a1240a8098dc2443fbeba3c6957d392ec17bf717e121d82922e6bdefc128ec
data/.gitignore CHANGED
@@ -1,18 +1,5 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
1
  .yardoc
6
- .idea/
7
2
  Gemfile.lock
8
- InstalledFiles
9
- _yardoc
10
3
  coverage
11
4
  doc/
12
- lib/bundler/man
13
5
  pkg
14
- rdoc
15
- spec/reports
16
- test/tmp
17
- test/version_tmp
18
- tmp
@@ -0,0 +1 @@
1
+ --markup markdown
@@ -1,3 +1,16 @@
1
+ ### 2.1.1
2
+
3
+ - Don't fail erroneously when running the after hook when the before hook failed
4
+ - Improve documentation
5
+
6
+ ### 2.1.0
7
+
8
+ - Support creating constant in an existing namespace (#26)
9
+ - Prefer keyword arguments over manually-validated hash argument
10
+ - Improve documentation
11
+ - Remove support for obsolete Ruby
12
+ - Internal cleanup
13
+
1
14
  ### 2.0.0
2
15
 
3
16
  - Require Ruby 2.1 or later
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://img.shields.io/gem/v/with_model.svg?style=flat)](https://rubygems.org/gems/with_model)
4
4
  [![Build Status](https://secure.travis-ci.org/Casecommons/with_model.svg?branch=master)](https://travis-ci.org/Casecommons/with_model)
5
+ [![API Documentation](https://img.shields.io/badge/yard-api%20docs-lightgrey.svg)](https://www.rubydoc.info/gems/with_model)
5
6
 
6
7
  `with_model` dynamically builds an ActiveRecord model (with table) before each test in a group and destroys it afterwards.
7
8
 
@@ -161,9 +162,18 @@ end
161
162
 
162
163
  ## Requirements
163
164
 
164
- - Ruby 2.1+
165
- - RSpec or minitest/spec
166
- - ActiveRecord 4.2+
165
+ See the [gemspec metadata](https://rubygems.org/gems/with_model) for dependency requirements. RSpec and minitest are indirect dependencies, and `with_model` should support any maintained version of both.
166
+
167
+ ## Thread-safety
168
+
169
+ - A unique table name is used for tables generated via `with_model`/`WithModel::Model.new`. This allows `with_model` (when limited to this API) to run concurrently (in processes or threads) with a single database schema. While there is a possibility of collision, it is very small.
170
+ - A user-supplied table name is used for tables generated via `with_table`/`WithModel::Table.new`. This may cause collisions at runtime if tests are run concurrently against a single database schema, unless the caller takes care to ensure the table names passed as arguments are unique across threads/processes.
171
+ - Generated models are created in stubbed constants, which are global; no guarantee is made to the uniqueness of a constant, and this may be unsafe.
172
+ - Generated classes are ActiveRecord subclasses:
173
+ - This library makes no guarantee is made as to the thread-safety of creating ActiveRecord subclasses concurrently.
174
+ - This library makes no guarantee is made as to the thread-safety of cleaning up ActiveRecord/ActiveSupport’s internals which are polluted upon class creation.
175
+
176
+ In general, `with_model` is not guaranteed to be thread-safe, but is, in certain usages, safe to use concurrently across multiple processes with a single database schema.
167
177
 
168
178
  ## Versioning
169
179
 
@@ -6,6 +6,10 @@ require 'with_model/table'
6
6
  require 'with_model/version'
7
7
 
8
8
  module WithModel
9
+ # @param name The constant name (as a symbol) to assign the model class to.
10
+ # @param scope Passed to `before`/`after` in the test context.
11
+ # @param options Passed to {WithModel::Model#initialize}.
12
+ # @param block Yielded an instance of {WithModel::Model::DSL}.
9
13
  def with_model(name, scope: nil, **options, &block)
10
14
  model = Model.new name, options
11
15
  dsl = Model::DSL.new model
@@ -20,6 +24,10 @@ module WithModel
20
24
  end
21
25
  end
22
26
 
27
+ # @param name The table name (as a symbol) to create.
28
+ # @param scope Passed to `before`/`after` in the test context.
29
+ # @param options Passed to {WithModel::Table#initialize}.
30
+ # @param block Passed to {WithModel::Table#initialize} (like {WithModel::Model::DSL#table}).
23
31
  def with_table(name, scope: nil, **options, &block)
24
32
  table = Table.new name, options, &block
25
33
 
@@ -19,9 +19,11 @@ module WithModel
19
19
  end
20
20
 
21
21
  def unstub_const
22
- @namespace.__send__ :remove_const, basename
23
- @namespace.const_set basename, @original_value if @original_value
24
- @namespace = nil
22
+ if @namespace
23
+ @namespace.__send__ :remove_const, basename
24
+ @namespace.const_set basename, @original_value if @original_value
25
+ @namespace = nil
26
+ end
25
27
  @original_value = nil
26
28
  end
27
29
 
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WithModel
4
+ # Extended into all ActiveRecord models created by with_model.
4
5
  module Methods
6
+ # Since model classes not created by with_model won't have this
7
+ # method, one should instead test `respond_to?(:with_model?)`.
5
8
  def with_model?
6
9
  true
7
10
  end
@@ -8,9 +8,14 @@ require 'with_model/methods'
8
8
  require 'with_model/table'
9
9
 
10
10
  module WithModel
11
+ # In general, direct use of this class should be avoided. Instead use
12
+ # either the {WithModel high-level API} or {WithModel::Model::DSL low-level API}.
11
13
  class Model
12
14
  attr_writer :model_block, :table_block, :table_options
13
15
 
16
+ # @param name The constant name (as a symbol) to assign the model class to.
17
+ # @param superclass The superclass for the created class. Should
18
+ # have `ActiveRecord::Base` as an ancestor.
14
19
  def initialize(name, superclass: ActiveRecord::Base)
15
20
  @name = name.to_sym
16
21
  @model_block = nil
@@ -3,6 +3,7 @@
3
3
  module WithModel
4
4
  class Model
5
5
  class DSL
6
+ # @param model [WithModel::Model] The Model to mutate via this DSL.
6
7
  def initialize(model)
7
8
  @model = model
8
9
  end
@@ -3,20 +3,28 @@
3
3
  require 'active_record'
4
4
 
5
5
  module WithModel
6
+ # In general, direct use of this class should be avoided. Instead use
7
+ # either the {WithModel high-level API} or {WithModel::Model::DSL low-level API}.
6
8
  class Table
9
+ # @param name The name of the table to create.
10
+ # @param options Passed to ActiveRecord `create_table`.
11
+ # @param block Passed to ActiveRecord `create_table`.
12
+ # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-create_table
7
13
  def initialize(name, options = {}, &block)
8
14
  @name = name.freeze
9
15
  @options = options.freeze
10
16
  @block = block
11
17
  end
12
18
 
19
+ # Creates the table with the initialized options. Drops the table if
20
+ # it already exists.
13
21
  def create
14
22
  connection.drop_table(@name) if exists?
15
23
  connection.create_table(@name, @options, &@block)
16
24
  end
17
25
 
18
26
  def destroy
19
- ActiveRecord::Base.connection.drop_table(@name)
27
+ connection.drop_table(@name)
20
28
  end
21
29
 
22
30
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WithModel
4
- VERSION = '2.1.0'
4
+ VERSION = '2.1.1'
5
5
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ module WithModel
6
+ describe ConstantStubber do
7
+ it 'allows calling unstub_const multiple times' do
8
+ stubber = described_class.new('Foo')
9
+ stubber.stub_const(1)
10
+ stubber.unstub_const
11
+ stubber.unstub_const
12
+ end
13
+
14
+ it 'allows calling unstub_const without stub_const' do
15
+ stubber = described_class.new('Foo')
16
+ stubber.unstub_const
17
+ end
18
+ end
19
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: with_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Case Commons, LLC
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-10-09 00:00:00.000000000 Z
13
+ date: 2018-11-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -116,6 +116,7 @@ files:
116
116
  - ".rspec"
117
117
  - ".rubocop.yml"
118
118
  - ".travis.yml"
119
+ - ".yardopts"
119
120
  - CHANGELOG.md
120
121
  - Gemfile
121
122
  - LICENSE
@@ -130,6 +131,7 @@ files:
130
131
  - lib/with_model/table.rb
131
132
  - lib/with_model/version.rb
132
133
  - spec/active_record_behaviors_spec.rb
134
+ - spec/constant_stubber_spec.rb
133
135
  - spec/readme_spec.rb
134
136
  - spec/spec_helper.rb
135
137
  - spec/with_model_spec.rb
@@ -154,12 +156,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
156
  version: '0'
155
157
  requirements: []
156
158
  rubyforge_project:
157
- rubygems_version: 2.7.4
159
+ rubygems_version: 2.7.6
158
160
  signing_key:
159
161
  specification_version: 4
160
162
  summary: Dynamically build a model within an RSpec context
161
163
  test_files:
162
164
  - spec/active_record_behaviors_spec.rb
165
+ - spec/constant_stubber_spec.rb
163
166
  - spec/readme_spec.rb
164
167
  - spec/spec_helper.rb
165
168
  - spec/with_model_spec.rb