abstract_type 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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 Version](https://badge.fury.io/rb/abstract_type.png)][gem]
|
5
7
|
[![Build Status](https://secure.travis-ci.org/dkubb/abstract_type.png?branch=master)][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
|