unextendable 0.1.6 → 0.1.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.
@@ -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: