unextendable 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,9 @@
1
1
  = Unextendable CHANGELOG
2
2
 
3
+ == Version 0.1.7 (August 15, 2012)
4
+
5
+ * Support (un-)extending private / protected methods. Thanks Stephan Kaag (@stephankaag) for contributing
6
+
3
7
  == Version 0.1.6 (January 9, 2012)
4
8
 
5
9
  * Being able to tackle 'BlankObject instances' when extending:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.6
1
+ 0.1.7
@@ -1,5 +1,11 @@
1
1
  class Module
2
2
 
3
+ def my_methods(include_private = true)
4
+ public_instance_methods.tap do |methods|
5
+ return methods + private_instance_methods + protected_instance_methods if include_private
6
+ end
7
+ end
8
+
3
9
  def unextendable
4
10
  @unextendable = true
5
11
  end
@@ -43,7 +43,7 @@ private
43
43
  def wrap_unextendable_module(mod)
44
44
  return unless (mod.class == Module) && mod.unextendable?
45
45
 
46
- mod.instance_methods.each do |method_name|
46
+ mod.my_methods.each do |method_name|
47
47
  wrap_unextendable_method method_name
48
48
  end
49
49
 
@@ -51,12 +51,12 @@ private
51
51
 
52
52
  instance_eval <<-CODE
53
53
  def respond_to?(symbol, include_private = false)
54
- meta_class.extended_modules.any?{|x| x.instance_methods.collect(&:to_s).include? symbol.to_s} ||
54
+ meta_class.extended_modules.any?{|x| x.my_methods(include_private).collect(&:to_s).include? symbol.to_s} ||
55
55
  begin
56
56
  if meta_class.method_procs.has_key? symbol.to_s
57
57
  meta_class.method_procs[symbol.to_s].class == Proc
58
58
  else
59
- self.class.instance_methods.collect(&:to_s).include? symbol.to_s
59
+ self.class.my_methods(include_private).collect(&:to_s).include? symbol.to_s
60
60
  end
61
61
  end
62
62
  end
@@ -68,7 +68,7 @@ private
68
68
  def wrap_unextendable_method(method_name)
69
69
  return if meta_class.method_procs.key? method_name.to_s
70
70
 
71
- meta_class.method_procs[method_name.to_s] = respond_to?(method_name) ? method(method_name.to_s).to_proc : nil
71
+ meta_class.method_procs[method_name.to_s] = respond_to?(method_name, true) ? method(method_name.to_s).to_proc : nil
72
72
 
73
73
  instance_eval <<-CODE
74
74
  def #{method_name}(*args, &block)
@@ -91,7 +91,7 @@ private
91
91
  end
92
92
 
93
93
  def method_for(method_name)
94
- mod = meta_class.extended_modules.detect{|x| x.instance_methods.collect(&:to_s).include? method_name.to_s}
94
+ mod = meta_class.extended_modules.detect{|x| x.my_methods.collect(&:to_s).include? method_name.to_s}
95
95
  mod ? mod.instance_method(method_name).bind(self) : proc_for(method_name)
96
96
  end
97
97
 
@@ -1,7 +1,7 @@
1
1
  module Unextendable
2
2
  MAJOR = 0
3
3
  MINOR = 1
4
- TINY = 6
4
+ TINY = 7
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join(".")
7
7
  end
@@ -17,6 +17,10 @@ class ObjectTest < Test::Unit::TestCase
17
17
  def name
18
18
  "C"
19
19
  end
20
+ private
21
+ def id
22
+ "C"
23
+ end
20
24
  end
21
25
  @c = C.new
22
26
  @c.title = "Mr."
@@ -72,6 +76,14 @@ class ObjectTest < Test::Unit::TestCase
72
76
 
73
77
  context "which are unextendable" do
74
78
  setup do
79
+ module B
80
+ unextendable
81
+ public
82
+ def id
83
+ "B"
84
+ end
85
+ end
86
+
75
87
  module U
76
88
  unextendable
77
89
  def name
@@ -80,6 +92,10 @@ class ObjectTest < Test::Unit::TestCase
80
92
  def foo
81
93
  "bar"
82
94
  end
95
+ private
96
+ def id
97
+ "U"
98
+ end
83
99
  end
84
100
  end
85
101
 
@@ -95,14 +111,14 @@ class ObjectTest < Test::Unit::TestCase
95
111
  end
96
112
 
97
113
  should "call wrap_unextendable_method" do
98
- @c.expects(:wrap_unextendable_method).twice
114
+ @c.expects(:wrap_unextendable_method).times(3)
99
115
  @c.extend U
100
116
  end
101
117
 
102
118
  should "add nil value as method proc when not responding to module method name" do
103
119
  @c.extend U
104
120
  assert_equal 1, @c.meta_class.method_procs.select{|k, v| v.nil?}.size
105
- assert_equal 1, @c.meta_class.method_procs.select{|k, v| v.class == Proc}.size
121
+ assert_equal 2, @c.meta_class.method_procs.select{|k, v| v.class == Proc}.size
106
122
  end
107
123
 
108
124
  should "add the module to extended_modules" do
@@ -114,7 +130,7 @@ class ObjectTest < Test::Unit::TestCase
114
130
  should "add method proc to method_procs" do
115
131
  assert @c.meta_class.send(:method_procs).empty?
116
132
  @c.extend U
117
- assert_equal 2, @c.meta_class.send(:method_procs).size
133
+ assert_equal 3, @c.meta_class.send(:method_procs).size
118
134
  end
119
135
 
120
136
  context "when calling an unextendable method" do
@@ -151,11 +167,24 @@ class ObjectTest < Test::Unit::TestCase
151
167
 
152
168
  context "when unextending the module afterwards" do
153
169
  should "remove the module from extended_modules" do
170
+ exception = assert_raises(NoMethodError) do
171
+ @c.id
172
+ end
173
+ assert_equal "private method `id' called for", exception.message[0..29]
174
+ assert_equal "C", @c.send(:id)
175
+
154
176
  @c.extend U
155
177
  assert @c.meta_class.extended_modules.include?(U)
178
+ assert_equal "private method `id' called for", exception.message[0..29]
179
+ assert_equal "U", @c.send(:id)
180
+
181
+ @c.extend B
182
+ assert_equal "B", @c.send(:id)
156
183
 
157
- @c.unextend U
184
+ @c.unextend
158
185
  assert !@c.meta_class.extended_modules.include?(U)
186
+ assert_equal "private method `id' called for", exception.message[0..29]
187
+ assert_equal "C", @c.send(:id)
159
188
  end
160
189
 
161
190
  should "remove the module but when passed a block only when it passes" do
metadata CHANGED
@@ -1,52 +1,49 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: unextendable
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.6
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.1.7
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Paul Engel
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-09 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
12
+
13
+ date: 2012-08-15 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
15
16
  name: shoulda
16
- requirement: &2152388140 !ruby/object:Gem::Requirement
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
17
19
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
22
24
  type: :development
23
- prerelease: false
24
- version_requirements: *2152388140
25
- - !ruby/object:Gem::Dependency
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
26
27
  name: mocha
27
- requirement: &2152384460 !ruby/object:Gem::Requirement
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
28
30
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
33
35
  type: :development
34
- prerelease: false
35
- version_requirements: *2152384460
36
- description: ! 'Unextendable originated from the thought of being able to implement
37
- the State pattern within object instances using modules. In other words: I wanted
38
- object instances to behave dependent on their state using modules. I really want
39
- to use modules because they are commonly used to define a set of methods which you
40
- can extend within an object instance. Unfortunately, you cannot just unexclude a
41
- module. So after searching the web for solutions, I came across Mixology, evil-ruby
42
- and StatePattern. But they slightly did not fit the picture. So after doing some
43
- research, I came up with Unextendable.'
44
- email:
36
+ version_requirements: *id002
37
+ description: "Unextendable originated from the thought of being able to implement the State pattern within object instances using modules. In other words: I wanted object instances to behave dependent on their state using modules. I really want to use modules because they are commonly used to define a set of methods which you can extend within an object instance. Unfortunately, you cannot just unexclude a module. So after searching the web for solutions, I came across Mixology, evil-ruby and StatePattern. But they slightly did not fit the picture. So after doing some research, I came up with Unextendable."
38
+ email:
45
39
  - paul.engel@holder.nl
46
40
  executables: []
41
+
47
42
  extensions: []
43
+
48
44
  extra_rdoc_files: []
49
- files:
45
+
46
+ files:
50
47
  - .gitignore
51
48
  - CHANGELOG.rdoc
52
49
  - Gemfile
@@ -68,31 +65,34 @@ files:
68
65
  - unextendable.gemspec
69
66
  homepage: https://github.com/archan937/unextendable
70
67
  licenses: []
68
+
71
69
  post_install_message:
72
70
  rdoc_options: []
73
- require_paths:
71
+
72
+ require_paths:
74
73
  - lib
75
- required_ruby_version: !ruby/object:Gem::Requirement
74
+ required_ruby_version: !ruby/object:Gem::Requirement
76
75
  none: false
77
- requirements:
78
- - - ! '>='
79
- - !ruby/object:Gem::Version
80
- version: '0'
81
- required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
81
  none: false
83
- requirements:
84
- - - ! '>='
85
- - !ruby/object:Gem::Version
86
- version: '0'
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
87
86
  requirements: []
87
+
88
88
  rubyforge_project: unextendable
89
- rubygems_version: 1.8.10
89
+ rubygems_version: 1.8.17
90
90
  signing_key:
91
91
  specification_version: 3
92
- summary: A small gem making unextending extended module methods within object instances
93
- possible
94
- test_files:
92
+ summary: A small gem making unextending extended module methods within object instances possible
93
+ test_files:
95
94
  - test/blank_object_test.rb
96
95
  - test/module_test.rb
97
96
  - test/object_test.rb
98
97
  - test/test_helper.rb
98
+ has_rdoc: