overrides 0.1.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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