poof 0.0.0.dev
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 +7 -0
- data/.gitignore +23 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +58 -0
- data/LICENSE +22 -0
- data/README.md +3 -0
- data/Rakefile +10 -0
- data/circle.yml +9 -0
- data/lib/poof.rb +137 -0
- data/poof.gemspec +21 -0
- data/simplecov_custom_profiles.rb +4 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/syntax_spec.rb +31 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8b06203891a68ed6a363e5bc896d4afa8efad1c4
|
4
|
+
data.tar.gz: dc4fedf4fe3582d90bf95bace3b401e760d583ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c8f27ea89c66c1d1c0245469188e0a69f1e63351c2e4a4ffb1aa18a8a0b566b794a5393656d35438d4d9f104f7572fdaf2d96f50d0c8951519fdad0f2d11e245
|
7
|
+
data.tar.gz: b93b03274ac93140f7d60eae7f98caec24aa15426448394898033e39fac92af43e7d700eaf6d76ec282f31f8c429bc13deb6cff6181a35d49663751454f99a5a
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
### Ruby template
|
2
|
+
*.gem
|
3
|
+
*.rbc
|
4
|
+
/coverage/
|
5
|
+
/spec/reports/
|
6
|
+
|
7
|
+
## Documentation cache and generated files:
|
8
|
+
/.yardoc/
|
9
|
+
/_yardoc/
|
10
|
+
/doc/
|
11
|
+
/rdoc/
|
12
|
+
|
13
|
+
## Environment normalisation:
|
14
|
+
/.bundle/
|
15
|
+
/lib/bundler/man/
|
16
|
+
.idea/
|
17
|
+
|
18
|
+
## Gemfile for development
|
19
|
+
#Gemfile
|
20
|
+
#Gemfile.lock
|
21
|
+
|
22
|
+
## Stupid OSX cruft
|
23
|
+
.DS_Store
|
data/Gemfile
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
gem 'simplecov', :require => false, :group => :test # MIT https://github.com/colszowka/simplecov/blob/master/MIT-LICENSE
|
3
|
+
gem 'yard' # MIT https://github.com/lsegal/yard/blob/master/LICENSE + Ruby license for one file from the Ruby source lib/parser/ruby/legacy/ruby_lex.rb
|
4
|
+
gem 'rspec' # MIT https://github.com/rspec/rspec/blob/master/License.txt
|
5
|
+
gem 'byebug'
|
6
|
+
gem "activerecord", ">= 4.1.5" # MIT https://github.com/rails/rails/blob/master/activerecord/MIT-LICENSE
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activemodel (4.1.7)
|
5
|
+
activesupport (= 4.1.7)
|
6
|
+
builder (~> 3.1)
|
7
|
+
activerecord (4.1.7)
|
8
|
+
activemodel (= 4.1.7)
|
9
|
+
activesupport (= 4.1.7)
|
10
|
+
arel (~> 5.0.0)
|
11
|
+
activesupport (4.1.7)
|
12
|
+
i18n (~> 0.6, >= 0.6.9)
|
13
|
+
json (~> 1.7, >= 1.7.7)
|
14
|
+
minitest (~> 5.1)
|
15
|
+
thread_safe (~> 0.1)
|
16
|
+
tzinfo (~> 1.1)
|
17
|
+
arel (5.0.1.20140414130214)
|
18
|
+
builder (3.2.2)
|
19
|
+
byebug (4.0.5)
|
20
|
+
columnize (= 0.9.0)
|
21
|
+
columnize (0.9.0)
|
22
|
+
diff-lcs (1.2.5)
|
23
|
+
docile (1.1.5)
|
24
|
+
i18n (0.7.0)
|
25
|
+
json (1.8.2)
|
26
|
+
minitest (5.4.3)
|
27
|
+
rspec (3.2.0)
|
28
|
+
rspec-core (~> 3.2.0)
|
29
|
+
rspec-expectations (~> 3.2.0)
|
30
|
+
rspec-mocks (~> 3.2.0)
|
31
|
+
rspec-core (3.2.3)
|
32
|
+
rspec-support (~> 3.2.0)
|
33
|
+
rspec-expectations (3.2.1)
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
+
rspec-support (~> 3.2.0)
|
36
|
+
rspec-mocks (3.2.1)
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
+
rspec-support (~> 3.2.0)
|
39
|
+
rspec-support (3.2.2)
|
40
|
+
simplecov (0.10.0)
|
41
|
+
docile (~> 1.1.0)
|
42
|
+
json (~> 1.8)
|
43
|
+
simplecov-html (~> 0.10.0)
|
44
|
+
simplecov-html (0.10.0)
|
45
|
+
thread_safe (0.3.4)
|
46
|
+
tzinfo (1.2.2)
|
47
|
+
thread_safe (~> 0.1)
|
48
|
+
yard (0.8.7.6)
|
49
|
+
|
50
|
+
PLATFORMS
|
51
|
+
ruby
|
52
|
+
|
53
|
+
DEPENDENCIES
|
54
|
+
activerecord (>= 4.1.5)
|
55
|
+
byebug
|
56
|
+
rspec
|
57
|
+
simplecov
|
58
|
+
yard
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Mattermark
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
data/Rakefile
ADDED
data/circle.yml
ADDED
data/lib/poof.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'active_support/callbacks'
|
2
|
+
module Poof
|
3
|
+
|
4
|
+
# This module is what should be included into the RSpec config so that poof! is available
|
5
|
+
# within specs.
|
6
|
+
module Syntax
|
7
|
+
def poof!(entity)
|
8
|
+
Magic.poof! entity
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Magic
|
13
|
+
# This method acts provides a monotonically increasing integer value
|
14
|
+
# As an example if you wanted to make ten companies and didn't want arbitrary names
|
15
|
+
# you could start all of them with the same string and prepend the next_safe_key
|
16
|
+
# to the domain, ensuring the possibility of uniqueness for the test
|
17
|
+
#
|
18
|
+
# @return [Integer] the next safe key that can be used to avoid unique key collisions
|
19
|
+
def self.next_safe_key
|
20
|
+
@next_safe_key ||= 1
|
21
|
+
@next_safe_key += 1
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get the first item in the container
|
25
|
+
#
|
26
|
+
# @return [Object] the first item in the container
|
27
|
+
def self.get_first
|
28
|
+
@container ||= Array.new
|
29
|
+
first = @container.first if @container.length > 0
|
30
|
+
first ||= nil
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get the last item in the container
|
34
|
+
#
|
35
|
+
# @return [Object] the last item in the container
|
36
|
+
def self.get_last
|
37
|
+
@container ||= Array.new
|
38
|
+
last = @container.last if @container.length > 0
|
39
|
+
last ||= nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get an object matching the description of its factory that is tracked by the container
|
43
|
+
# for later reference or teardown
|
44
|
+
#
|
45
|
+
# @param factory_name [Symbol] the name of the factory you want the container to use
|
46
|
+
# @param attributes [Hash] hash where keys are attribute names and values are attribute values
|
47
|
+
# @return [Object] the instance generated for the factory you requested
|
48
|
+
def self.get(factory_name, attributes = {})
|
49
|
+
@container ||= Array.new
|
50
|
+
e = FactoryGirl.create(factory_name, attributes)
|
51
|
+
@container << e
|
52
|
+
e
|
53
|
+
end
|
54
|
+
|
55
|
+
# Invoking this method will cause the argument entity to be really_destroy!'d or destroy!'d on next cleanup
|
56
|
+
#
|
57
|
+
# @param entity [Model] the model entity that should be lazily destroyed
|
58
|
+
# @param [Model] the entity that was passed as an argument is returned
|
59
|
+
def self.poof!(entity)
|
60
|
+
@hit_list ||= Array.new
|
61
|
+
@hit_list << entity
|
62
|
+
entity
|
63
|
+
end
|
64
|
+
|
65
|
+
# This method applies any coercion in the factory's class that would normally occur
|
66
|
+
# when getting an instance's attribute (for AR objects this is like calling foo.bar
|
67
|
+
# as opposed to foo.read_attribute :bar)
|
68
|
+
#
|
69
|
+
# @param factory_name [Symbol] the name of the factory that should be used for coercing the attribute
|
70
|
+
# @param attribute_name [Symbol] the name of attribute that needs to called on the instance created by the factory
|
71
|
+
# @return [Object] the resulting value of calling the instance's method having the name of attribute_name's value
|
72
|
+
def self.get_attribute(factory_name, attribute_name)
|
73
|
+
e = self.get factory_name
|
74
|
+
e.send attribute_name
|
75
|
+
end
|
76
|
+
|
77
|
+
# This is the general teardown method, it removes any check_orm's that have been applied
|
78
|
+
# to any class for which the container has generated instances, and then it attempts to delete
|
79
|
+
# (using hard deletes when possible) all of the instances it created
|
80
|
+
def self.cleanup
|
81
|
+
@container ||= Array.new
|
82
|
+
@container.each do |dependency|
|
83
|
+
disable_check_orm(dependency.class)
|
84
|
+
teardown_method = :really_destroy! if dependency.respond_to? :really_destroy!
|
85
|
+
teardown_method ||= :destroy!
|
86
|
+
dependency.send(teardown_method)
|
87
|
+
end
|
88
|
+
@hit_list ||= Array.new
|
89
|
+
@hit_list.each do |trash|
|
90
|
+
disable_check_orm(trash.class)
|
91
|
+
teardown_method = :really_destroy! if trash.respond_to? :really_destroy!
|
92
|
+
teardown_method ||= :destroy!
|
93
|
+
trash.send(teardown_method)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Selectively targets check_orm_xxx callbacks to be disabled (skipped) in the callback chains
|
98
|
+
#
|
99
|
+
# @param klasses [Class, Symbol, Array<Class, Symbol>] A Class, Symbol representing a factory_girl factory, or an array Classes or Symbols
|
100
|
+
# @param events_to_disable [Symbol, Array] A symbol or array of Symbols that define which kind of callbacks to disable
|
101
|
+
def disable_check_orm(klasses, events_to_disable = [:create, :update, :destroy])
|
102
|
+
if klasses.is_a? Array
|
103
|
+
klasses.map { |klass| disable_check_orm klass, events_to_disable }
|
104
|
+
else
|
105
|
+
klass = klasses
|
106
|
+
if events_to_disable.is_a? Array
|
107
|
+
events_to_disable.map { |event| disable_check_orm klass, event }
|
108
|
+
else
|
109
|
+
event_to_disable = events_to_disable
|
110
|
+
# Allow the user to pass a symbol instead of a class and instantiate it using the factory
|
111
|
+
# might want to switch to using .new instead, but then you have to figure out how to locate
|
112
|
+
# the klasses modularized name from just a symbol representing the class
|
113
|
+
if klass.is_a? Symbol
|
114
|
+
klass = build(klass).class
|
115
|
+
end
|
116
|
+
# The name of the actual callback method for destroy is check_orm_delete/check_orm_delete_derived, so need to attach properly
|
117
|
+
callback_suffix = :delete if event_to_disable == :destroy
|
118
|
+
callback_suffix ||= event_to_disable
|
119
|
+
# Get the array of registered check_orm_xxx callbacks from the main authorizer on klass
|
120
|
+
registered_check_orm_callbacks = klass.registered_check_orm_callbacks if klass.respond_to? :registered_check_orm_callbacks
|
121
|
+
registered_check_orm_callbacks ||= []
|
122
|
+
# callbacks_to_skip refers to which callbacks should get passed to the skip_callback method (these are the callbacks that should be effectively disabled)
|
123
|
+
callbacks_to_skip = registered_check_orm_callbacks.select { |cb| cb.to_s.include? callback_suffix.to_s }
|
124
|
+
callbacks_to_skip ||= []
|
125
|
+
callbacks_to_skip.map { |cb| klass.skip_callback(event_to_disable, :before, cb) }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class << self
|
131
|
+
alias_method :start, :cleanup
|
132
|
+
alias_method :restart, :cleanup
|
133
|
+
alias_method :new_context, :cleanup
|
134
|
+
alias_method :end, :cleanup
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/poof.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'poof'
|
3
|
+
s.version = '0.0.0.dev'
|
4
|
+
s.date = '2015-05-08'
|
5
|
+
s.summary = "Automatically cleanup and destroy ActiveRecord objects created during tests."
|
6
|
+
s.description = "An alternative to DatabaseCleaner for automatically ensuring that objects created during
|
7
|
+
tests are removed from the database."
|
8
|
+
s.authors = ["Courtland Caldwell"]
|
9
|
+
s.email = 'courtland@mattermark.com'
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
12
|
+
s.homepage =
|
13
|
+
'https://github.com/Referly/poof'
|
14
|
+
s.add_runtime_dependency "activerecord", "~> 4.1", ">= 4.1.5"
|
15
|
+
s.add_development_dependency "rake", "~> 10.3"
|
16
|
+
s.add_development_dependency "simplecov", "~> 0.10"
|
17
|
+
s.add_development_dependency "yard", "~> 0.8"
|
18
|
+
s.add_development_dependency "rspec", "~> 3.2"
|
19
|
+
s.add_development_dependency "byebug", "~> 4.0"
|
20
|
+
s.license = "MIT"
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/syntax_spec.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Poof::Syntax do
|
4
|
+
|
5
|
+
context 'when mixed into the Rspec configuration' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
|
9
|
+
RSpec.configure do |conf|
|
10
|
+
conf.include described_class
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
subject do
|
15
|
+
|
16
|
+
RSpec.describe 'test example' do
|
17
|
+
|
18
|
+
let(:record) { double('ActiveRecord Instance') }
|
19
|
+
|
20
|
+
it 'responds to poof!' do
|
21
|
+
expect(Poof::Magic).to receive(:poof!).with(record).once
|
22
|
+
expect { poof! record }.to_not raise_error
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'exposes the public API to Rspec examples' do
|
28
|
+
subject
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: poof
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0.dev
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Courtland Caldwell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 4.1.5
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 4.1.5
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '10.3'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '10.3'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: simplecov
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.10'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.10'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: yard
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0.8'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0.8'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rspec
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.2'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '3.2'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: byebug
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '4.0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '4.0'
|
103
|
+
description: |-
|
104
|
+
An alternative to DatabaseCleaner for automatically ensuring that objects created during
|
105
|
+
tests are removed from the database.
|
106
|
+
email: courtland@mattermark.com
|
107
|
+
executables: []
|
108
|
+
extensions: []
|
109
|
+
extra_rdoc_files: []
|
110
|
+
files:
|
111
|
+
- ".gitignore"
|
112
|
+
- Gemfile
|
113
|
+
- Gemfile.lock
|
114
|
+
- LICENSE
|
115
|
+
- README.md
|
116
|
+
- Rakefile
|
117
|
+
- circle.yml
|
118
|
+
- lib/poof.rb
|
119
|
+
- poof.gemspec
|
120
|
+
- simplecov_custom_profiles.rb
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
- spec/syntax_spec.rb
|
123
|
+
homepage: https://github.com/Referly/poof
|
124
|
+
licenses:
|
125
|
+
- MIT
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">"
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: 1.3.1
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.2.2
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Automatically cleanup and destroy ActiveRecord objects created during tests.
|
147
|
+
test_files:
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
- spec/syntax_spec.rb
|
150
|
+
has_rdoc:
|