abstract_type 0.0.6 → 0.0.7
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 +13 -5
- data/.rspec +1 -0
- data/.travis.yml +8 -17
- data/Gemfile +5 -2
- data/Gemfile.devtools +21 -24
- data/README.md +8 -36
- data/abstract_type.gemspec +2 -1
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/reek.yml +1 -1
- data/config/rubocop.yml +61 -0
- data/lib/abstract_type.rb +29 -23
- data/lib/abstract_type/version.rb +1 -1
- data/spec/shared/create_new_method_shared_spec.rb +20 -0
- data/spec/spec_helper.rb +24 -1
- data/spec/unit/abstract_type/{class_methods → abstract_method_declarations}/abstract_method_spec.rb +9 -6
- data/spec/unit/abstract_type/{class_methods → abstract_method_declarations}/abstract_singleton_method_spec.rb +10 -6
- data/spec/unit/abstract_type/abstract_method_declarations/included_spec.rb +33 -0
- data/spec/unit/abstract_type/module_methods/create_new_method_spec.rb +54 -0
- metadata +20 -16
- data/spec/unit/abstract_type/class_methods/included_spec.rb +0 -26
- data/spec/unit/abstract_type/class_methods/new_spec.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MTFlYTk3ZTQ2MjNjOGEyMDY1YjIzMTZhMTI0ZTkyMDc5ZDExMDMyNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ODg1ZTE2MWY2ZWQyNjFiY2JkZTEwODA3MmNiOGJmMzQ2YWNkMGVmMA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NWEwMTVmMDVkZWU3ZDQ2MDk3ZmUzOWQxODc0MDFhNWQ2MmUzYzgxN2IwM2Nj
|
10
|
+
OTc1MDI5M2QyNWQ2ZWQ4NDZhZWYwMzkzMDYwNGExNjdkNjE2ZjNjMDE2MjBl
|
11
|
+
ZGFjMTNjMjdjMzQ3ZmM3MWQwOWNiNmY3MGNhMGExMGIwZTY2Nzg=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODBlYTJmN2VkODU0YjhjYjZkMTMyZDIyMjMwODkyYjdmOTdmOGU3OWNlNzA1
|
14
|
+
ZDM0MGFjMDM5ODE5NGFiNmI4MDZmMjIzNzMyMjgyYjk2MzcyYjliZmYxZjZk
|
15
|
+
YmU5ODRlZDRiOTljOTFjMmYxMmRkZGM5ZmRjYWJjZTUxMDJjMTY=
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -1,30 +1,21 @@
|
|
1
1
|
language: ruby
|
2
2
|
before_install: gem install bundler
|
3
|
-
bundler_args: --without yard guard
|
3
|
+
bundler_args: --without yard guard benchmarks
|
4
4
|
script: "bundle exec rake ci"
|
5
5
|
rvm:
|
6
|
-
- 1.9.2
|
7
6
|
- 1.9.3
|
8
7
|
- 2.0.0
|
9
|
-
- rbx-19mode
|
10
|
-
- jruby-19mode
|
11
8
|
- ruby-head
|
12
|
-
|
13
|
-
irc:
|
14
|
-
channels:
|
15
|
-
- irc.freenode.org#rom-rb
|
16
|
-
on_success: never
|
17
|
-
on_failure: change
|
18
|
-
email:
|
19
|
-
recipients:
|
20
|
-
- dan.kubb@gmail.com
|
21
|
-
on_success: never
|
22
|
-
on_failure: change
|
9
|
+
- rbx-19mode
|
23
10
|
matrix:
|
24
|
-
allow_failures:
|
25
|
-
- rvm: ruby-head
|
26
11
|
include:
|
27
12
|
- rvm: jruby-19mode
|
28
13
|
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
29
14
|
- rvm: jruby-head
|
30
15
|
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
16
|
+
notifications:
|
17
|
+
irc:
|
18
|
+
channels:
|
19
|
+
- irc.freenode.org#rom-rb
|
20
|
+
on_success: never
|
21
|
+
on_failure: change
|
data/Gemfile
CHANGED
@@ -4,5 +4,8 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
gemspec
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
group :development, :test do
|
8
|
+
gem 'devtools', git: 'https://github.com/rom-rb/devtools.git'
|
9
|
+
end
|
10
|
+
|
11
|
+
eval_gemfile 'Gemfile.devtools'
|
data/Gemfile.devtools
CHANGED
@@ -2,49 +2,46 @@
|
|
2
2
|
|
3
3
|
group :development do
|
4
4
|
gem 'rake', '~> 10.1.0'
|
5
|
-
gem 'rspec', '~> 2.
|
6
|
-
gem 'yard', '~> 0.8.
|
5
|
+
gem 'rspec', '~> 2.14.1'
|
6
|
+
gem 'yard', '~> 0.8.7'
|
7
7
|
end
|
8
8
|
|
9
9
|
group :yard do
|
10
|
-
gem 'kramdown', '~> 1.0
|
10
|
+
gem 'kramdown', '~> 1.2.0'
|
11
11
|
end
|
12
12
|
|
13
13
|
group :guard do
|
14
14
|
gem 'guard', '~> 1.8.1'
|
15
15
|
gem 'guard-bundler', '~> 1.0.0'
|
16
16
|
gem 'guard-rspec', '~> 3.0.2'
|
17
|
+
gem 'guard-rubocop', '~> 0.2.0'
|
18
|
+
gem 'guard-mutant', '~> 0.0.1'
|
17
19
|
|
18
20
|
# file system change event handling
|
19
|
-
gem 'listen', '~> 1.
|
20
|
-
gem 'rb-fchange', '~> 0.0.6', :
|
21
|
-
gem 'rb-fsevent', '~> 0.9.3', :
|
22
|
-
gem 'rb-inotify', '~> 0.9.0', :
|
21
|
+
gem 'listen', '~> 1.3.0'
|
22
|
+
gem 'rb-fchange', '~> 0.0.6', require: false
|
23
|
+
gem 'rb-fsevent', '~> 0.9.3', require: false
|
24
|
+
gem 'rb-inotify', '~> 0.9.0', require: false
|
23
25
|
|
24
26
|
# notification handling
|
25
|
-
gem 'libnotify', '~> 0.8.0', :
|
26
|
-
gem 'rb-notifu', '~> 0.0.4', :
|
27
|
-
gem 'terminal-notifier-guard', '~> 1.5.3', :
|
27
|
+
gem 'libnotify', '~> 0.8.0', require: false
|
28
|
+
gem 'rb-notifu', '~> 0.0.4', require: false
|
29
|
+
gem 'terminal-notifier-guard', '~> 1.5.3', require: false
|
28
30
|
end
|
29
31
|
|
30
32
|
group :metrics do
|
31
|
-
gem 'coveralls', '~> 0.
|
32
|
-
gem 'flay', '~> 2.
|
33
|
-
gem 'flog', '~> 4.
|
34
|
-
gem 'reek', '~> 1.3.
|
33
|
+
gem 'coveralls', '~> 0.7.0'
|
34
|
+
gem 'flay', '~> 2.4.0'
|
35
|
+
gem 'flog', '~> 4.2.0'
|
36
|
+
gem 'reek', '~> 1.3.2'
|
37
|
+
gem 'rubocop', '~> 0.14.1'
|
35
38
|
gem 'simplecov', '~> 0.7.1'
|
36
|
-
gem 'yardstick', '~> 0.9.
|
37
|
-
|
38
|
-
platforms :ruby_19 do
|
39
|
-
gem 'yard-spellcheck', '~> 0.1.5'
|
40
|
-
end
|
39
|
+
gem 'yardstick', '~> 0.9.7', git: 'https://github.com/dkubb/yardstick.git'
|
41
40
|
|
42
41
|
platforms :ruby_19, :ruby_20 do
|
43
|
-
gem 'mutant',
|
44
|
-
|
45
|
-
|
46
|
-
platforms :rbx do
|
47
|
-
gem 'pelusa', '~> 0.2.2'
|
42
|
+
gem 'mutant', '~> 0.3.0.rc3', git: 'https://github.com/mbj/mutant.git'
|
43
|
+
gem 'unparser', '~> 0.1.3', git: 'https://github.com/mbj/unparser.git'
|
44
|
+
gem 'yard-spellcheck', '~> 0.1.5'
|
48
45
|
end
|
49
46
|
end
|
50
47
|
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
abstract_type
|
2
|
-
|
1
|
+
# abstract_type
|
2
|
+
|
3
|
+
This is a small standalone gem featuring a module ripped out from [axiom](https://github.com/dkubb/axiom).
|
4
|
+
It allows to declare abstract_type classes and modules in an unobstrusive way.
|
3
5
|
|
4
6
|
[][gem]
|
5
7
|
[][travis]
|
@@ -13,34 +15,7 @@ abstract_type
|
|
13
15
|
[codeclimate]: https://codeclimate.com/github/dkubb/abstract_type
|
14
16
|
[coveralls]: https://coveralls.io/r/dkubb/abstract_type
|
15
17
|
|
16
|
-
|
17
|
-
It allows to declare abstract_type classes and modules in an unobstrusive way.
|
18
|
-
|
19
|
-
Installation
|
20
|
-
------------
|
21
|
-
|
22
|
-
With Rubygems:
|
23
|
-
|
24
|
-
```bash
|
25
|
-
$ gem install abstract_type
|
26
|
-
$ irb -rubygems
|
27
|
-
>> require 'abstract_type'
|
28
|
-
=> true
|
29
|
-
```
|
30
|
-
|
31
|
-
With git and local working copy:
|
32
|
-
|
33
|
-
```bash
|
34
|
-
$ git clone git://github.com/dkubb/abstract_type.git
|
35
|
-
$ cd abstract_type
|
36
|
-
$ rake install
|
37
|
-
$ irb -rubygems
|
38
|
-
>> require 'abstract_type'
|
39
|
-
=> true
|
40
|
-
```
|
41
|
-
|
42
|
-
Examples
|
43
|
-
--------
|
18
|
+
## Examples
|
44
19
|
|
45
20
|
``` ruby
|
46
21
|
class Foo
|
@@ -64,18 +39,15 @@ object.bar # raises NotImplementedError: Baz#bar is not implemented
|
|
64
39
|
|
65
40
|
```
|
66
41
|
|
67
|
-
Credits
|
68
|
-
-------
|
42
|
+
## Credits
|
69
43
|
|
70
44
|
* Dan Kubb ([dkubb](https://github.com/dkubb))
|
71
45
|
* Markus Schirp ([mbj](https://github.com/mbj))
|
72
46
|
|
73
|
-
Contributing
|
74
|
-
------------
|
47
|
+
## Contributing
|
75
48
|
|
76
49
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
77
50
|
|
78
|
-
Copyright
|
79
|
-
---------
|
51
|
+
## Copyright
|
80
52
|
|
81
53
|
Copyright © 2009-2013 Dan Kubb. See LICENSE for details.
|
data/abstract_type.gemspec
CHANGED
@@ -10,10 +10,11 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.description = 'Module to declare abstract classes and methods'
|
11
11
|
gem.summary = gem.description
|
12
12
|
gem.homepage = 'https://github.com/dkubb/abstract_type'
|
13
|
+
gem.license = 'MIT'
|
13
14
|
|
14
15
|
gem.files = `git ls-files`.split($/)
|
15
16
|
gem.test_files = `git ls-files -- spec/unit`.split($/)
|
16
|
-
gem.extra_rdoc_files = %w[LICENSE README.md TODO]
|
17
|
+
gem.extra_rdoc_files = %w[LICENSE README.md CONTRIBUTING.md TODO]
|
17
18
|
|
18
19
|
gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
|
19
20
|
end
|
data/config/flay.yml
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
3
|
-
total_score:
|
2
|
+
threshold: 8
|
3
|
+
total_score: 20
|
data/config/flog.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
2
|
+
threshold: 8.2
|
data/config/reek.yml
CHANGED
@@ -47,7 +47,7 @@ UncommunicativeModuleName:
|
|
47
47
|
NestedIterators:
|
48
48
|
ignore_iterators: []
|
49
49
|
exclude: [
|
50
|
-
'AbstractType::
|
50
|
+
'AbstractType::AbstractMethodDeclarations#create_abstract_singleton_method'
|
51
51
|
]
|
52
52
|
enabled: true
|
53
53
|
max_allowed_nesting: 1
|
data/config/rubocop.yml
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
AllCops:
|
2
|
+
Includes:
|
3
|
+
- '../**/*.rake'
|
4
|
+
- 'Gemfile'
|
5
|
+
Excludes:
|
6
|
+
- '**/vendor/**'
|
7
|
+
- '**/benchmarks/**'
|
8
|
+
|
9
|
+
# Avoid parameter lists longer than five parameters.
|
10
|
+
ParameterLists:
|
11
|
+
Max: 3
|
12
|
+
CountKeywordArgs: true
|
13
|
+
|
14
|
+
# Avoid more than `Max` levels of nesting.
|
15
|
+
BlockNesting:
|
16
|
+
Max: 3
|
17
|
+
|
18
|
+
# Align with the style guide.
|
19
|
+
CollectionMethods:
|
20
|
+
PreferredMethods:
|
21
|
+
collect: 'map'
|
22
|
+
inject: 'reduce'
|
23
|
+
find: 'detect'
|
24
|
+
find_all: 'select'
|
25
|
+
|
26
|
+
# Do not force public/protected/private keyword to be indented at the same
|
27
|
+
# level as the def keyword. My personal preference is to outdent these keywords
|
28
|
+
# because I think when scanning code it makes it easier to identify the
|
29
|
+
# sections of code and visually separate them. When the keyword is at the same
|
30
|
+
# level I think it sort of blends in with the def keywords and makes it harder
|
31
|
+
# to scan the code and see where the sections are.
|
32
|
+
AccessControl:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
# Limit line length
|
36
|
+
LineLength:
|
37
|
+
Max: 79
|
38
|
+
|
39
|
+
# Disable documentation checking until a class needs to be documented once
|
40
|
+
Documentation:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
# Do not always use &&/|| instead of and/or.
|
44
|
+
AndOr:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
# Do not favor modifier if/unless usage when you have a single-line body
|
48
|
+
IfUnlessModifier:
|
49
|
+
Enabled: false
|
50
|
+
|
51
|
+
# Allow case equality operator (in limited use within the specs)
|
52
|
+
CaseEquality:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
# Constants do not always have to use SCREAMING_SNAKE_CASE
|
56
|
+
ConstantName:
|
57
|
+
Enabled: false
|
58
|
+
|
59
|
+
# Not all trivial readers/writers can be defined with attr_* methods
|
60
|
+
TrivialAccessors:
|
61
|
+
Enabled: false
|
data/lib/abstract_type.rb
CHANGED
@@ -13,31 +13,35 @@ module AbstractType
|
|
13
13
|
# @api private
|
14
14
|
def self.included(descendant)
|
15
15
|
super
|
16
|
-
descendant
|
16
|
+
create_new_method(descendant)
|
17
|
+
descendant.extend(AbstractMethodDeclarations)
|
17
18
|
end
|
18
19
|
|
19
20
|
private_class_method :included
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
if superclass.equal?(Object)
|
36
|
-
raise NotImplementedError, "#{inspect} is an abstract type"
|
22
|
+
# Define the new method on the abstract type
|
23
|
+
#
|
24
|
+
# Ensures that the instance cannot be of the abstract type
|
25
|
+
# and must be a descendant.
|
26
|
+
#
|
27
|
+
# @param [Class] abstract_class
|
28
|
+
#
|
29
|
+
# @return [undefined]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
def self.create_new_method(abstract_class)
|
33
|
+
abstract_class.define_singleton_method(:new) do |*args, &block|
|
34
|
+
if equal?(abstract_class)
|
35
|
+
fail NotImplementedError, "#{inspect} is an abstract type"
|
37
36
|
else
|
38
|
-
super
|
37
|
+
super(*args, &block)
|
39
38
|
end
|
40
39
|
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private_class_method :create_new_method
|
43
|
+
|
44
|
+
module AbstractMethodDeclarations
|
41
45
|
|
42
46
|
# Create abstract instance methods
|
43
47
|
#
|
@@ -55,7 +59,7 @@ module AbstractType
|
|
55
59
|
#
|
56
60
|
# @api public
|
57
61
|
def abstract_method(*names)
|
58
|
-
names.each
|
62
|
+
names.each(&method(:create_abstract_instance_method))
|
59
63
|
self
|
60
64
|
end
|
61
65
|
|
@@ -75,7 +79,7 @@ module AbstractType
|
|
75
79
|
#
|
76
80
|
# @api private
|
77
81
|
def abstract_singleton_method(*names)
|
78
|
-
names.each
|
82
|
+
names.each(&method(:create_abstract_singleton_method))
|
79
83
|
self
|
80
84
|
end
|
81
85
|
|
@@ -91,7 +95,7 @@ module AbstractType
|
|
91
95
|
# @api private
|
92
96
|
def create_abstract_singleton_method(name)
|
93
97
|
define_singleton_method(name) do |*|
|
94
|
-
|
98
|
+
fail NotImplementedError, "#{inspect}.#{name} is not implemented"
|
95
99
|
end
|
96
100
|
end
|
97
101
|
|
@@ -105,9 +109,11 @@ module AbstractType
|
|
105
109
|
# @api private
|
106
110
|
def create_abstract_instance_method(name)
|
107
111
|
define_method(name) do |*|
|
108
|
-
|
112
|
+
fail NotImplementedError, "#{self.class}##{name} is not implemented"
|
109
113
|
end
|
110
114
|
end
|
111
115
|
|
112
|
-
end # module
|
116
|
+
end # module AbstractMethodDeclarations
|
113
117
|
end # module AbstractType
|
118
|
+
|
119
|
+
require 'abstract_type/version'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
shared_examples 'AbstractType.create_new_method' do
|
4
|
+
context 'called on a subclass' do
|
5
|
+
let(:object) { Class.new(abstract_type) }
|
6
|
+
|
7
|
+
it { should be_instance_of(object) }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'called on the class' do
|
11
|
+
let(:object) { abstract_type }
|
12
|
+
|
13
|
+
specify do
|
14
|
+
expect { subject }.to raise_error(
|
15
|
+
NotImplementedError,
|
16
|
+
"#{object} is an abstract type"
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,30 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
if ENV['COVERAGE'] == 'true'
|
4
|
+
require 'simplecov'
|
5
|
+
require 'coveralls'
|
6
|
+
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
8
|
+
SimpleCov::Formatter::HTMLFormatter,
|
9
|
+
Coveralls::SimpleCov::Formatter
|
10
|
+
]
|
11
|
+
|
12
|
+
SimpleCov.start do
|
13
|
+
command_name 'spec:unit'
|
14
|
+
|
15
|
+
add_filter 'config'
|
16
|
+
add_filter 'spec'
|
17
|
+
add_filter 'vendor'
|
18
|
+
|
19
|
+
minimum_coverage 100
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
4
23
|
require 'devtools/spec_helper'
|
24
|
+
require 'abstract_type'
|
5
25
|
|
6
26
|
RSpec.configure do |config|
|
27
|
+
config.expect_with :rspec do |expect_with|
|
28
|
+
expect_with.syntax = :expect
|
29
|
+
end
|
7
30
|
end
|
data/spec/unit/abstract_type/{class_methods → abstract_method_declarations}/abstract_method_spec.rb
RENAMED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe AbstractType::
|
5
|
+
describe AbstractType::AbstractMethodDeclarations, '#abstract_method' do
|
6
6
|
subject { object.abstract_method(:some_method) }
|
7
7
|
|
8
8
|
let(:object) { Class.new { include AbstractType } }
|
@@ -19,18 +19,21 @@ describe AbstractType::ClassMethods, '#abstract_method' do
|
|
19
19
|
it { should equal(object) }
|
20
20
|
|
21
21
|
it 'creates an abstract method' do
|
22
|
-
expect { subject }.to change { subclass.method_defined?(:some_method) }
|
23
|
-
from(false)
|
24
|
-
to(true)
|
22
|
+
expect { subject }.to change { subclass.method_defined?(:some_method) }
|
23
|
+
.from(false)
|
24
|
+
.to(true)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'creates an abstract method with the expected arity' do
|
28
28
|
subject
|
29
|
-
object.instance_method(:some_method).arity.
|
29
|
+
expect(object.instance_method(:some_method).arity).to be(-1)
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'creates a method that raises an exception' do
|
33
33
|
subject
|
34
|
-
expect { subclass.new.some_method }.to raise_error(
|
34
|
+
expect { subclass.new.some_method }.to raise_error(
|
35
|
+
NotImplementedError,
|
36
|
+
'Subclass#some_method is not implemented'
|
37
|
+
)
|
35
38
|
end
|
36
39
|
end
|
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe AbstractType::
|
5
|
+
describe AbstractType::AbstractMethodDeclarations,
|
6
|
+
'#abstract_singleton_method' do
|
6
7
|
subject { object.abstract_singleton_method(:some_method) }
|
7
8
|
|
8
9
|
let(:object) { Class.new { include AbstractType } }
|
@@ -19,18 +20,21 @@ describe AbstractType::ClassMethods, '#abstract_singleton_method' do
|
|
19
20
|
it { should equal(object) }
|
20
21
|
|
21
22
|
it 'creates an abstract method' do
|
22
|
-
expect { subject }.to change { subclass.respond_to?(:some_method) }
|
23
|
-
from(false)
|
24
|
-
to(true)
|
23
|
+
expect { subject }.to change { subclass.respond_to?(:some_method) }
|
24
|
+
.from(false)
|
25
|
+
.to(true)
|
25
26
|
end
|
26
27
|
|
27
28
|
it 'creates an abstract method with the expected arity' do
|
28
29
|
subject
|
29
|
-
object.method(:some_method).arity.
|
30
|
+
expect(object.method(:some_method).arity).to be(-1)
|
30
31
|
end
|
31
32
|
|
32
33
|
it 'creates a method that raises an exception' do
|
33
34
|
subject
|
34
|
-
expect { subclass.some_method }.to raise_error(
|
35
|
+
expect { subclass.some_method }.to raise_error(
|
36
|
+
NotImplementedError,
|
37
|
+
'Subclass.some_method is not implemented'
|
38
|
+
)
|
35
39
|
end
|
36
40
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AbstractType, '.included' do
|
6
|
+
subject { object }
|
7
|
+
|
8
|
+
let(:object) { described_class }
|
9
|
+
let(:klass) { Class.new }
|
10
|
+
|
11
|
+
it 'extends the klass' do
|
12
|
+
expect(klass.singleton_class)
|
13
|
+
.to_not include(described_class::AbstractMethodDeclarations)
|
14
|
+
klass.send(:include, subject)
|
15
|
+
expect(klass.singleton_class)
|
16
|
+
.to include(described_class::AbstractMethodDeclarations)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'overrides the new singleton method' do
|
20
|
+
expect(klass.method(:new).owner).to eq(Class)
|
21
|
+
klass.send(:include, subject)
|
22
|
+
expect(klass.method(:new).owner).to eq(klass.singleton_class)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'delegates to the ancestor' do
|
26
|
+
included_ancestor = false
|
27
|
+
subject.extend Module.new {
|
28
|
+
define_method(:included) { |_| included_ancestor = true }
|
29
|
+
}
|
30
|
+
expect { klass.send(:include, subject) }
|
31
|
+
.to change { included_ancestor }.from(false).to(true)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AbstractType, '.create_new_method' do
|
6
|
+
context 'with arguments' do
|
7
|
+
subject { object.new(:foo) }
|
8
|
+
|
9
|
+
let(:abstract_type) do
|
10
|
+
Class.new do
|
11
|
+
include AbstractType
|
12
|
+
|
13
|
+
def initialize(foo)
|
14
|
+
@foo = foo
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it_behaves_like 'AbstractType.create_new_method'
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with a block' do
|
23
|
+
subject { object.new(:foo) { nil } }
|
24
|
+
|
25
|
+
let(:abstract_type) do
|
26
|
+
Class.new do
|
27
|
+
include AbstractType
|
28
|
+
|
29
|
+
def initialize(foo)
|
30
|
+
@foo = foo
|
31
|
+
yield
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it_behaves_like 'AbstractType.create_new_method'
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'without arguments' do
|
40
|
+
subject { object.new }
|
41
|
+
|
42
|
+
let(:abstract_type) { Class.new { include AbstractType } }
|
43
|
+
|
44
|
+
it_behaves_like 'AbstractType.create_new_method'
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'on an class that doesn\'t have Object as its superclass' do
|
48
|
+
subject { object.new }
|
49
|
+
|
50
|
+
let(:abstract_type) { Class.new(RuntimeError) { include AbstractType } }
|
51
|
+
|
52
|
+
it_behaves_like 'AbstractType.create_new_method'
|
53
|
+
end
|
54
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abstract_type
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Kubb
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -17,7 +17,7 @@ dependencies:
|
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
|
-
- - '>='
|
20
|
+
- - ! '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 1.3.5
|
23
23
|
type: :development
|
@@ -27,7 +27,7 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '1.3'
|
30
|
-
- - '>='
|
30
|
+
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.3.5
|
33
33
|
description: Module to declare abstract classes and methods
|
@@ -38,6 +38,7 @@ extensions: []
|
|
38
38
|
extra_rdoc_files:
|
39
39
|
- LICENSE
|
40
40
|
- README.md
|
41
|
+
- CONTRIBUTING.md
|
41
42
|
- TODO
|
42
43
|
files:
|
43
44
|
- .gitignore
|
@@ -58,17 +59,20 @@ files:
|
|
58
59
|
- config/mutant.yml
|
59
60
|
- config/reek.yml
|
60
61
|
- config/roodi.yml
|
62
|
+
- config/rubocop.yml
|
61
63
|
- config/yardstick.yml
|
62
64
|
- lib/abstract_type.rb
|
63
65
|
- lib/abstract_type/version.rb
|
66
|
+
- spec/shared/create_new_method_shared_spec.rb
|
64
67
|
- spec/spec_helper.rb
|
65
68
|
- spec/support/config_alias.rb
|
66
|
-
- spec/unit/abstract_type/
|
67
|
-
- spec/unit/abstract_type/
|
68
|
-
- spec/unit/abstract_type/
|
69
|
-
- spec/unit/abstract_type/
|
69
|
+
- spec/unit/abstract_type/abstract_method_declarations/abstract_method_spec.rb
|
70
|
+
- spec/unit/abstract_type/abstract_method_declarations/abstract_singleton_method_spec.rb
|
71
|
+
- spec/unit/abstract_type/abstract_method_declarations/included_spec.rb
|
72
|
+
- spec/unit/abstract_type/module_methods/create_new_method_spec.rb
|
70
73
|
homepage: https://github.com/dkubb/abstract_type
|
71
|
-
licenses:
|
74
|
+
licenses:
|
75
|
+
- MIT
|
72
76
|
metadata: {}
|
73
77
|
post_install_message:
|
74
78
|
rdoc_options: []
|
@@ -76,23 +80,23 @@ require_paths:
|
|
76
80
|
- lib
|
77
81
|
required_ruby_version: !ruby/object:Gem::Requirement
|
78
82
|
requirements:
|
79
|
-
- - '>='
|
83
|
+
- - ! '>='
|
80
84
|
- !ruby/object:Gem::Version
|
81
85
|
version: '0'
|
82
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
87
|
requirements:
|
84
|
-
- - '>='
|
88
|
+
- - ! '>='
|
85
89
|
- !ruby/object:Gem::Version
|
86
90
|
version: '0'
|
87
91
|
requirements: []
|
88
92
|
rubyforge_project:
|
89
|
-
rubygems_version: 2.
|
93
|
+
rubygems_version: 2.1.8
|
90
94
|
signing_key:
|
91
95
|
specification_version: 4
|
92
96
|
summary: Module to declare abstract classes and methods
|
93
97
|
test_files:
|
94
|
-
- spec/unit/abstract_type/
|
95
|
-
- spec/unit/abstract_type/
|
96
|
-
- spec/unit/abstract_type/
|
97
|
-
- spec/unit/abstract_type/
|
98
|
+
- spec/unit/abstract_type/abstract_method_declarations/abstract_method_spec.rb
|
99
|
+
- spec/unit/abstract_type/abstract_method_declarations/abstract_singleton_method_spec.rb
|
100
|
+
- spec/unit/abstract_type/abstract_method_declarations/included_spec.rb
|
101
|
+
- spec/unit/abstract_type/module_methods/create_new_method_spec.rb
|
98
102
|
has_rdoc:
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe AbstractType, '.included' do
|
6
|
-
subject { object }
|
7
|
-
|
8
|
-
let(:object) { described_class }
|
9
|
-
let(:klass) { Class.new }
|
10
|
-
|
11
|
-
it 'extends the klass' do
|
12
|
-
klass.singleton_class.should_not include(described_class::ClassMethods)
|
13
|
-
klass.send(:include, subject)
|
14
|
-
klass.singleton_class.should include(described_class::ClassMethods)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'delegates to the ancestor' do
|
18
|
-
included_ancestor = false
|
19
|
-
subject.extend Module.new {
|
20
|
-
define_method(:included) { |_| included_ancestor = true }
|
21
|
-
}
|
22
|
-
expect {
|
23
|
-
klass.send(:include, subject)
|
24
|
-
}.to change { included_ancestor }.from(false).to(true)
|
25
|
-
end
|
26
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe AbstractType::ClassMethods, '#new' do
|
6
|
-
context 'with arguments' do
|
7
|
-
subject { object.new(:foo) }
|
8
|
-
|
9
|
-
let(:abstract_type) do
|
10
|
-
Class.new do
|
11
|
-
include AbstractType
|
12
|
-
|
13
|
-
def initialize(foo)
|
14
|
-
@foo = foo
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'called on a subclass' do
|
20
|
-
let(:object) { Class.new(abstract_type) }
|
21
|
-
|
22
|
-
it { should be_instance_of(object) }
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'called on the class' do
|
26
|
-
let(:object) { abstract_type }
|
27
|
-
|
28
|
-
specify { expect { subject }.to raise_error(NotImplementedError, "#{object} is an abstract type") }
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context 'without arguments' do
|
33
|
-
subject { object.new }
|
34
|
-
|
35
|
-
let(:abstract_type) { Class.new { include AbstractType } }
|
36
|
-
|
37
|
-
context 'called on a subclass' do
|
38
|
-
let(:object) { Class.new(abstract_type) }
|
39
|
-
|
40
|
-
it { should be_instance_of(object) }
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'called on the class' do
|
44
|
-
let(:object) { abstract_type }
|
45
|
-
|
46
|
-
specify { expect { subject }.to raise_error(NotImplementedError, "#{object} is an abstract type") }
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|