overrides 0.1.0 → 0.10.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.
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby
6
+ # before_script: gem install bundler
@@ -0,0 +1,83 @@
1
+ # Overrides
2
+
3
+ An #overrides annotation for your (Ruby) methods.
4
+
5
+ Inspired by Java's [@Override][1].
6
+
7
+
8
+ ## Install
9
+
10
+ $ gem install overrides
11
+
12
+ or add this line to your application's *Gemfile* (and `bundle`) :
13
+
14
+ gem 'overrides'
15
+
16
+ optionally add `:require => 'overrides/for_all'` to have `overrides` available
17
+ in all classes/modules as a built-in (singleton) method.
18
+
19
+
20
+ ## Usage
21
+
22
+ Let's have a base class with `Overrides` pulled in :
23
+
24
+ class Message
25
+ extend Overrides
26
+
27
+ def self.deliver(msg); end
28
+
29
+ def do_send; end
30
+ def sent_at; end
31
+ def reply?; end
32
+ end
33
+
34
+ a notice would be a message sub-type, note how `overrides` gets used :
35
+
36
+ class Notice < Message
37
+ overrides
38
+ def do_send; super; end
39
+
40
+ def reply?; nil; end
41
+ def sent_at; nil; end
42
+
43
+ overrides :reply?, :sent_at
44
+ end
45
+
46
+ without args (before method) works with singleton methods as well :
47
+
48
+ class Notice < Message
49
+ overrides
50
+ def self.deliver(msg); end
51
+ end
52
+
53
+ **NOTE:** there's no global name-space pollution by default, thus you'll need
54
+ to hook up the `Overrides` module (or extend `Object` to pull it in for all).
55
+
56
+ ### "Java"
57
+
58
+ Here's how you use it with JRuby to "annotate" method overrides :
59
+
60
+ require 'overrides/for_all'
61
+
62
+ class NonEmptyList < java.util.ArrayList
63
+
64
+ def initialize
65
+ super(); add nil
66
+ end
67
+
68
+ overrides
69
+ def clear; super; add nil; end
70
+
71
+ def isEmpty; false; end
72
+ overrides :isEmpty
73
+
74
+ end
75
+
76
+
77
+ ## Copyright
78
+
79
+ Copyright (c) 2013 [Karol Bucek](http://kares.org).
80
+ See LICENSE.txt (http://en.wikipedia.org/wiki/MIT_License) for details.
81
+
82
+ [0]: https://github.com/kares/overrides
83
+ [1]: http://docs.oracle.com/javase/7/docs/api/java/lang/Override.html
data/Rakefile CHANGED
@@ -1 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new do |t|
5
+ t.pattern = "test/*_test.rb"
6
+ end
7
+
8
+ task :default => :test
@@ -2,10 +2,11 @@ require 'overrides/version'
2
2
 
3
3
  # Allows for an #overrides annotation for your methods.
4
4
  #
5
- # Thus might help you e.g. during refactoring (method renaming) to assure methods
6
- # expected to call a super will fail early during def time instead of when called.
5
+ # This might help during refactoring (method renaming) to assure methods
6
+ # expected to be overriding another (and calling super) fail early during
7
+ # definition time instead of when called.
7
8
  #
8
- # Sample :
9
+ # Usage :
9
10
  #
10
11
  # class Message
11
12
  # extend Overrides
@@ -26,7 +27,7 @@ require 'overrides/version'
26
27
  # end
27
28
  #
28
29
  #
29
- # Without arguments works with singleton methods as well :
30
+ # Without arguments (before method) works with singleton methods as well :
30
31
  #
31
32
  # class Message
32
33
  # extend Overrides
@@ -47,13 +48,19 @@ require 'overrides/version'
47
48
  #
48
49
  module Overrides
49
50
 
50
- Error = NoMethodError
51
+ # Custom (missing method error) raised from {#overrides}.
52
+ class Error < NoMethodError; end
51
53
 
52
54
  def overrides(*names)
53
- if names.empty? # next method
55
+ if names.empty? # next method def - singleton or instance
54
56
  @_override = true
55
57
  else
56
- names.each do |name|
58
+ names.each do |name| # only for instance methods
59
+ unless Overrides.includes_method? self.instance_methods(false), name
60
+ msg = "(instance) method #{name.inspect} not found in "
61
+ raise NoMethodError,
62
+ msg << ( self.is_a?(Class) ? 'class ' : 'module ' ) << self.inspect
63
+ end
57
64
  unless Overrides.overriden?(self, name)
58
65
  raise Error, "previous (instance) method #{name.inspect} not found"
59
66
  end
@@ -61,6 +68,7 @@ module Overrides
61
68
  end
62
69
  end
63
70
 
71
+ # @private
64
72
  def method_added(name)
65
73
  return super unless (@_override ||= nil); @_override = false
66
74
  unless Overrides.overriden?(self, name, true)
@@ -69,6 +77,7 @@ module Overrides
69
77
  super
70
78
  end
71
79
 
80
+ # @private
72
81
  def singleton_method_added(name)
73
82
  return super unless (@_override ||= nil); @_override = false
74
83
  unless Overrides.overriden?(self, name, false)
@@ -77,20 +86,32 @@ module Overrides
77
86
  super
78
87
  end
79
88
 
89
+ # Checks if a method was previously available in the given module's method
90
+ # resolution chain. Assumes instance methods by default.
80
91
  def self.overriden?(klass, method, instance = true)
81
92
  if instance
82
93
  klass.included_modules.each do |mod|
83
- return true if mod.instance_methods(true).include? method
94
+ return true if includes_method? mod.instance_methods(true), method
84
95
  end
85
96
  return false unless klass.is_a?(Class) # "only" a Module ...
86
- return klass.superclass.instance_methods(true).include? method
97
+ return includes_method? klass.superclass.instance_methods(true), method
87
98
  else
88
99
  (class << klass; self; end).included_modules.each do |mod|
89
- return true if mod.instance_methods(true).include? method
100
+ return true if includes_method? mod.instance_methods(true), method
90
101
  end
91
102
  return false unless klass.is_a?(Class) # "only" a Module ...
92
- return klass.superclass.methods(true).include? method
103
+ return includes_method? klass.superclass.methods(true), method
93
104
  end
94
105
  end
95
106
 
107
+ # @private
108
+ def self.includes_method?(methods, name)
109
+ methods.include? name
110
+ end
111
+
112
+ # @private
113
+ def self.includes_method?(methods, name)
114
+ methods.include? name.to_s
115
+ end if RUBY_VERSION < '1.9'
116
+
96
117
  end
@@ -0,0 +1,2 @@
1
+ require 'overrides'
2
+ Object.extend Overrides
@@ -1,3 +1,3 @@
1
1
  module Overrides
2
- VERSION = '0.1.0'
2
+ VERSION = '0.10.0'
3
3
  end
@@ -9,7 +9,9 @@ Gem::Specification.new do |gem|
9
9
  gem.authors = ["Karol Bucek"]
10
10
  gem.email = ["self@kares.org"]
11
11
  gem.summary = %q{an #overrides annotation for your methods}
12
- gem.description = %q{An #overrides annotation for your (Ruby) methods.}
12
+ gem.description = %q{Helps during refactoring (method renaming) to assure
13
+ methods expected to be overriding another (and calling super) fail early during
14
+ definition time instead of when called.}
13
15
  gem.homepage = "http://github.com/kares/overrides"
14
16
  gem.license = "MIT"
15
17
 
@@ -18,6 +20,7 @@ Gem::Specification.new do |gem|
18
20
  gem.test_files = gem.files.grep(%r{^(test)/})
19
21
  gem.require_paths = ["lib"]
20
22
 
23
+ gem.add_development_dependency "minitest", "~> 3.0"
21
24
  gem.add_development_dependency "bundler", "~> 1.3"
22
25
  gem.add_development_dependency "rake", "~> 10.1"
23
26
  end
@@ -0,0 +1,178 @@
1
+ require 'bundler/setup' # if RUBY_VERSION < '1.9'
2
+
3
+ require 'overrides'
4
+
5
+ require 'minitest/autorun'
6
+
7
+ class OverridesTest < MiniTest::Unit::TestCase; end
8
+
9
+ # ========================================
10
+
11
+ class Ferko
12
+
13
+ extend Overrides
14
+
15
+ def kuk; 'ferko-kuk'; end
16
+ def muk; 'ferko-muk'; end
17
+
18
+ overrides
19
+ def to_s
20
+ 'ferko' + super.to_s
21
+ end
22
+
23
+ def self.hoja; 'hoja-ferko'; end
24
+
25
+ end
26
+
27
+ OverridesTest.class_eval do
28
+
29
+ def test_overrides_builtin_method
30
+ assert Ferko.new.to_s
31
+ end
32
+
33
+ def test_methods_stay_the_same
34
+ assert_equal 'ferko-kuk', Ferko.new.kuk
35
+ assert_equal 'hoja-ferko', Ferko.hoja
36
+ end
37
+
38
+ end
39
+
40
+ # ========================================
41
+
42
+ class Jozko < Ferko
43
+
44
+ overrides
45
+ def kuk; super; 'jozko-kuk'; end
46
+
47
+ def muk; 'jozko-muk'; end
48
+ def tuk; 'jozko-tuk'; end
49
+
50
+ overrides :muk
51
+
52
+ end
53
+
54
+ OverridesTest.class_eval do
55
+
56
+ def test_overrides_inherited_methods
57
+ assert_equal 'jozko-kuk', Jozko.new.kuk
58
+ assert_equal 'jozko-muk', Jozko.new.muk
59
+ assert_equal 'jozko-tuk', Jozko.new.tuk
60
+ end
61
+
62
+ end
63
+
64
+ # ========================================
65
+
66
+ class Jozko
67
+
68
+ overrides
69
+ def self.hoja; super; 'hoja-jozko'; end
70
+
71
+ end
72
+
73
+ OverridesTest.class_eval do
74
+
75
+ def test_overrides_singleton_method
76
+ assert_equal 'hoja-jozko', Jozko.hoja
77
+ end
78
+
79
+ end
80
+
81
+ # ========================================
82
+
83
+ class Janko < Ferko
84
+
85
+ def kuk; super; 'janko-kuk'; end
86
+ def muk; super; 'janko-muk'; end
87
+
88
+ overrides :muk, :kuk
89
+
90
+ end
91
+
92
+ OverridesTest.class_eval do
93
+
94
+ def test_overrides_multiple_at_once
95
+ assert_equal 'janko-kuk', Janko.new.kuk
96
+ assert_equal 'janko-muk', Janko.new.muk
97
+ end
98
+
99
+ end
100
+
101
+ # ========================================
102
+
103
+ class Jozko
104
+
105
+ def jak; 'jozko-jak'; end
106
+
107
+ end
108
+
109
+ OverridesTest.class_eval do
110
+
111
+ def test_uses_no_method_error
112
+ assert_kind_of NoMethodError, Overrides::Error.new
113
+ end
114
+
115
+ def test_fails_when_override_not_met
116
+ assert_raises Overrides::Error do
117
+ Jozko.class_eval do
118
+ overrides :jak
119
+ end
120
+ end
121
+
122
+ assert_raises Overrides::Error do
123
+ Jozko.class_eval do
124
+ overrides
125
+ def tak; end
126
+ end
127
+ end
128
+
129
+ assert_raises Overrides::Error do
130
+ Jozko.class_eval do
131
+ overrides
132
+ def self.kuk; end
133
+ end
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ # ========================================
140
+
141
+ class Ferko
142
+ def sak; end
143
+ end
144
+
145
+ class Petko < Ferko
146
+ end
147
+
148
+ OverridesTest.class_eval do
149
+
150
+ def test_fails_when_method_not_defined
151
+ assert_raises NoMethodError do
152
+ Petko.class_eval do
153
+ overrides :sak
154
+ end
155
+ end
156
+ end
157
+
158
+ end
159
+
160
+ # ========================================
161
+
162
+ class Otakar
163
+ def coje; 'tha-nic'; end
164
+ end
165
+
166
+ class Bohuslav < Otakar; end
167
+
168
+ OverridesTest.class_eval do
169
+
170
+ def test_works_for_all_when_required
171
+ require 'overrides/for_all'
172
+ Bohuslav.class_eval do
173
+ overrides
174
+ def coje; 'ta-daco'; end
175
+ end
176
+ end
177
+
178
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: overrides
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-15 00:00:00.000000000 Z
12
+ date: 2013-11-16 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: bundler
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -43,7 +59,9 @@ dependencies:
43
59
  - - ~>
44
60
  - !ruby/object:Gem::Version
45
61
  version: '10.1'
46
- description: ! 'An #overrides annotation for your (Ruby) methods.'
62
+ description: ! "Helps during refactoring (method renaming) to assure\n methods expected
63
+ to be overriding another (and calling super) fail early during\n definition time
64
+ instead of when called."
47
65
  email:
48
66
  - self@kares.org
49
67
  executables: []
@@ -51,12 +69,16 @@ extensions: []
51
69
  extra_rdoc_files: []
52
70
  files:
53
71
  - .gitignore
72
+ - .travis.yml
54
73
  - Gemfile
55
74
  - LICENSE.txt
75
+ - README.md
56
76
  - Rakefile
57
77
  - lib/overrides.rb
78
+ - lib/overrides/for_all.rb
58
79
  - lib/overrides/version.rb
59
80
  - overrides.gemspec
81
+ - test/overrides_test.rb
60
82
  homepage: http://github.com/kares/overrides
61
83
  licenses:
62
84
  - MIT
@@ -72,7 +94,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
94
  version: '0'
73
95
  segments:
74
96
  - 0
75
- hash: -1605842409600528455
97
+ hash: 3588119150367271522
76
98
  required_rubygems_version: !ruby/object:Gem::Requirement
77
99
  none: false
78
100
  requirements:
@@ -81,11 +103,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
103
  version: '0'
82
104
  segments:
83
105
  - 0
84
- hash: -1605842409600528455
106
+ hash: 3588119150367271522
85
107
  requirements: []
86
108
  rubyforge_project:
87
109
  rubygems_version: 1.8.25
88
110
  signing_key:
89
111
  specification_version: 3
90
112
  summary: ! 'an #overrides annotation for your methods'
91
- test_files: []
113
+ test_files:
114
+ - test/overrides_test.rb