remix 0.4.0 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,4 +1,10 @@
1
- 11/11/201 version 0.4.0
1
+ 12/11/2010 versino 0.4.5
2
+ * added tests to swap_module and replace_module to prevent
3
+ mod1 and mod2 being the same module
4
+ * fixed bug in swap_module when ancestor chains were huge
5
+ * added :before and :after hooks for temp_include and friends
6
+ * added tests for hooks and for swap_module crashing bug
7
+ 11/11/2010 version 0.4.0
2
8
  * added temp_include and temp_extend, and threadsafe variants
3
9
  temp_include_safe etc
4
10
  27/10/2010 version 0.2.5
data/Rakefile CHANGED
@@ -28,7 +28,6 @@ task :test do
28
28
  sh "bacon -k #{direc}/test/test.rb"
29
29
  end
30
30
 
31
-
32
31
  [:mingw32, :mswin32].each do |v|
33
32
  namespace v do
34
33
  spec = Gem::Specification.new do |s|
@@ -57,3 +56,19 @@ namespace :ruby do
57
56
  end
58
57
  end
59
58
 
59
+ desc "build all platform gems at once"
60
+ task :gems => [:rmgems, "mingw32:gem", "mswin32:gem", "ruby:gem"]
61
+
62
+ desc "remove all platform gems"
63
+ task :rmgems => ["ruby:clobber_package"]
64
+
65
+ task :pushgems => :gems do
66
+ chdir("#{direc}/pkg") do
67
+ Dir["*.gem"].each do |gemfile|
68
+ sh "gem push #{gemfile}"
69
+ end
70
+ end
71
+ end
72
+
73
+
74
+
data/ext/remix/remix.c CHANGED
@@ -249,6 +249,7 @@ rb_swap_modules(VALUE self, VALUE mod1, VALUE mod2)
249
249
  VALUE included_mod1, included_mod2;
250
250
 
251
251
  if (mod1 == rb_cObject || mod2 == rb_cObject) rb_raise(rb_eRuntimeError, "can't swap Object");
252
+ if (mod1 == mod2) return self;
252
253
 
253
254
  included_mod1 = retrieve_imod_for_mod(self, mod1);
254
255
  included_mod2 = retrieve_imod_for_mod(self, mod2);
@@ -332,6 +333,8 @@ rb_replace_module(VALUE self, VALUE mod1, VALUE mod2)
332
333
 
333
334
  if (rb_classmod_include_p(self, mod2))
334
335
  return rb_swap_modules(self, mod1, mod2);
336
+
337
+ if (mod1 == mod2) return;
335
338
 
336
339
  VALUE before = retrieve_imod_before_mod(self, mod1);
337
340
  rb_uninclude(1, &mod1, self);
data/lib/remix/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Remix
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.5"
3
3
  end
4
4
 
data/lib/remix.rb CHANGED
@@ -10,154 +10,174 @@ require "#{direc}/remix/c_docs"
10
10
  dlext = Config::CONFIG['DLEXT']
11
11
 
12
12
  begin
13
- if RUBY_VERSION && RUBY_VERSION =~ /1.9/
14
- require "#{direc}/1.9/remix.#{dlext}"
15
- else
16
- require "#{direc}/1.8/remix.#{dlext}"
17
- end
13
+ if RUBY_VERSION && RUBY_VERSION =~ /1.9/
14
+ require "#{direc}/1.9/remix.#{dlext}"
15
+ else
16
+ require "#{direc}/1.8/remix.#{dlext}"
17
+ end
18
18
  rescue LoadError => e
19
- require "#{direc}/remix.#{dlext}"
19
+ require "#{direc}/remix.#{dlext}"
20
20
  end
21
21
 
22
22
  module Kernel
23
- # define a `singleton_class` method for the 1.8 kids
23
+ # Define a `singleton_class` method for the 1.8 kids
24
24
  # @return [Class] The singleton class of the receiver
25
25
  def singleton_class
26
26
  class << self; self; end
27
27
  end if !respond_to?(:singleton_class)
28
28
  end
29
29
 
30
- module Remix::ObjectExtensions
31
-
32
- # Temporarily extends a module for the duration of a block.
33
- # Module will be unextended at end of block.
34
- # @param [Module] mod Module to be temporarily extended
35
- def temp_extend(mod, &block)
36
- begin
37
- extend(mod)
38
- yield
39
- ensure
40
- unextend(mod, true)
41
- end
42
- end
30
+ module Remix
43
31
 
44
- # Temporarily extends a module for the duration of a block in a
45
- # thread-safe manner.
46
- # Module will be unextended at end of block.
47
- # @param [Module] mod Module to be temporarily extended
48
- def temp_extend_safe(mod, &block)
49
- safe_code = proc do
50
- begin
51
- extend(mod)
52
- yield
53
- ensure
54
- unextend(mod, true)
32
+ # Wraps a block of code so that `before` and `after` lambdas are invoked
33
+ # prior to and after the block.
34
+ # @return [Object] The return value of the block
35
+ def self.wrap_with_hooks(before, after, &block)
36
+ before.call if before
37
+ yield
38
+ ensure
39
+ after.call if after
40
+ end
41
+
42
+ module ObjectExtensions
43
+
44
+ # Temporarily extends a module for the duration of a block.
45
+ # Module will be unextended at end of block.
46
+ # @param [Module] mod Module to be temporarily extended
47
+ def temp_extend(mod, options={}, &block)
48
+ Remix.wrap_with_hooks(options[:before], options[:after]) do
49
+ begin
50
+ extend(mod)
51
+ yield
52
+ ensure
53
+ unextend(mod, true)
54
+ end
55
55
  end
56
56
  end
57
-
58
- if !Thread.current[:__exclusive__]
59
- Thread.exclusive { Thread.current[:__exclusive__] = true; safe_code.call }
60
- Thread.current[:__exclusive__] = false
61
- else
62
- safe_code.call
63
- end
64
- end
65
57
 
66
- # Like `include_at()` but for the singleton class
67
- # @see Remix::ModuleExtensions#include_at
68
- def extend_at(index, mod)
69
- singleton_class.include_at(index, mod)
70
- end
58
+ # Temporarily extends a module for the duration of a block in a
59
+ # thread-safe manner.
60
+ # Module will be unextended at end of block.
61
+ # @param [Module] mod Module to be temporarily extended
62
+ def temp_extend_safe(mod, options={}, &block)
63
+ safe_code = proc do
64
+ Remix.wrap_with_hooks(options[:before], options[:after]) do
65
+ begin
66
+ extend(mod)
67
+ yield
68
+ ensure
69
+ unextend(mod, true)
70
+ end
71
+ end
72
+ end
73
+
74
+ if !Thread.current[:__exclusive__]
75
+ Thread.exclusive { Thread.current[:__exclusive__] = true; safe_code.call }
76
+ Thread.current[:__exclusive__] = false
77
+ else
78
+ safe_code.call
79
+ end
80
+ end
71
81
 
72
- # Like `include_below()` but for the singleton class
73
- # @see Remix::ModuleExtensions#include_below
74
- def extend_below(mod1, mod2)
75
- singleton_class.include_below(mod1, mod2)
76
- end
77
- alias_method :extend_before, :extend_below
82
+ # Like `include_at()` but for the singleton class
83
+ # @see Remix::ModuleExtensions#include_at
84
+ def extend_at(index, mod)
85
+ singleton_class.include_at(index, mod)
86
+ end
78
87
 
79
- # Like `include_above()` but for the singleton class
80
- # @see Remix::ModuleExtensions#include_above
81
- def extend_above(mod1, mod2)
82
- singleton_class.include_above(mod1, mod2)
83
- end
84
- alias_method :extend_after, :extend_above
88
+ # Like `include_below()` but for the singleton class
89
+ # @see Remix::ModuleExtensions#include_below
90
+ def extend_below(mod1, mod2)
91
+ singleton_class.include_below(mod1, mod2)
92
+ end
93
+ alias_method :extend_before, :extend_below
85
94
 
86
- # Like `uninclude()` but for the singleton class
87
- # @see Remix::ModuleExtensions#uninclude
88
- def unextend(mod, recurse = false)
89
- singleton_class.uninclude(mod, recurse)
90
- end
91
- alias_method :remove_extended_module, :unextend
95
+ # Like `include_above()` but for the singleton class
96
+ # @see Remix::ModuleExtensions#include_above
97
+ def extend_above(mod1, mod2)
98
+ singleton_class.include_above(mod1, mod2)
99
+ end
100
+ alias_method :extend_after, :extend_above
92
101
 
93
- # Like `include_at_top()` but for the singleton class
94
- # @see Remix::ModuleExtensions#include_at_top
95
- def extend_at_top(mod)
96
- singleton_class.include_at_top(mod)
97
- end
102
+ # Like `uninclude()` but for the singleton class
103
+ # @see Remix::ModuleExtensions#uninclude
104
+ def unextend(mod, recurse = false)
105
+ singleton_class.uninclude(mod, recurse)
106
+ end
107
+ alias_method :remove_extended_module, :unextend
98
108
 
99
- # Like `swap_modules()` but for the singleton class
100
- # @see Remix::ModuleExtensions#swap_modules
101
- def swap_extended_modules(mod1, mod2)
102
- singleton_class.swap_modules(mod1, mod2)
103
- end
109
+ # Like `include_at_top()` but for the singleton class
110
+ # @see Remix::ModuleExtensions#include_at_top
111
+ def extend_at_top(mod)
112
+ singleton_class.include_at_top(mod)
113
+ end
104
114
 
105
- # Like `module_move_up()` but for the singleton class
106
- # @see Remix::ModuleExtensions#module_move_up
107
- def extended_module_move_up(mod)
108
- singleton_class.module_move_up(mod)
109
- end
110
-
111
- # Like `module_move_down()` but for the singleton class
112
- # @see Remix::ModuleExtensions#module_move_down
113
- def extended_module_move_down(mod)
114
- singleton_class.module_move_down(mod)
115
- end
115
+ # Like `swap_modules()` but for the singleton class
116
+ # @see Remix::ModuleExtensions#swap_modules
117
+ def swap_extended_modules(mod1, mod2)
118
+ singleton_class.swap_modules(mod1, mod2)
119
+ end
116
120
 
117
- # Like `replace_module()` but for the singleton class
118
- # @see Remix::ModuleExtensions#replace_module_down
119
- def replace_extended_module(mod1, mod2)
120
- singleton_class.replace_module(mod1, mod2)
121
- end
122
- end
121
+ # Like `module_move_up()` but for the singleton class
122
+ # @see Remix::ModuleExtensions#module_move_up
123
+ def extended_module_move_up(mod)
124
+ singleton_class.module_move_up(mod)
125
+ end
126
+
127
+ # Like `module_move_down()` but for the singleton class
128
+ # @see Remix::ModuleExtensions#module_move_down
129
+ def extended_module_move_down(mod)
130
+ singleton_class.module_move_down(mod)
131
+ end
123
132
 
124
- module Remix::ModuleExtensions
125
-
126
- # Temporarily includes a module for the duration of a block.
127
- # Module will be unincluded at end of block.
128
- # @param [Module] mod Module to be temporarily included
129
- def temp_include(mod, &block)
130
- begin
131
- include(mod)
132
- yield
133
- ensure
134
- uninclude(mod, true)
133
+ # Like `replace_module()` but for the singleton class
134
+ # @see Remix::ModuleExtensions#replace_module_down
135
+ def replace_extended_module(mod1, mod2)
136
+ singleton_class.replace_module(mod1, mod2)
135
137
  end
136
138
  end
137
139
 
138
- # Temporarily includes a module for the duration of a block in a
139
- # thread-safe manner.
140
- # Module will be unincluded at end of block.
141
- # @param [Module] mod Module to be temporarily included
142
- def temp_include_safe(mod, &block)
143
- safe_code = proc do
144
- begin
145
- include(mod)
146
- yield
147
- ensure
148
- uninclude(mod, true)
140
+ module Remix::ModuleExtensions
141
+
142
+ # Temporarily includes a module for the duration of a block.
143
+ # Module will be unincluded at end of block.
144
+ # @param [Module] mod Module to be temporarily included
145
+ def temp_include(mod, options={}, &block)
146
+ Remix.wrap_with_hooks(options[:before], options[:after]) do
147
+ begin
148
+ include(mod)
149
+ yield
150
+ ensure
151
+ uninclude(mod, true)
152
+ end
149
153
  end
150
154
  end
151
-
152
- if !Thread.current[:__exclusive__]
153
- Thread.exclusive { Thread.current[:__exclusive__] = true; safe_code.call }
154
- Thread.current[:__exclusive__] = false
155
- else
156
- safe_code.call
155
+
156
+ # Temporarily includes a module for the duration of a block in a
157
+ # thread-safe manner.
158
+ # Module will be unincluded at end of block.
159
+ # @param [Module] mod Module to be temporarily included
160
+ def temp_include_safe(mod, options={}, &block)
161
+ safe_code = proc do
162
+ Remix.wrap_with_hooks(options[:before], options[:after]) do
163
+ begin
164
+ include(mod)
165
+ yield
166
+ ensure
167
+ uninclude(mod, true)
168
+ end
169
+ end
170
+ end
171
+
172
+ if !Thread.current[:__exclusive__]
173
+ Thread.exclusive { Thread.current[:__exclusive__] = true; safe_code.call }
174
+ Thread.current[:__exclusive__] = false
175
+ else
176
+ safe_code.call
177
+ end
157
178
  end
158
179
  end
159
180
  end
160
-
161
181
 
162
182
  # bring extend-based methods into Object
163
183
  class Object
data/test/test.rb CHANGED
@@ -54,156 +54,202 @@ describe 'Test basic remix functionality' do
54
54
  end
55
55
  lambda { B.hello }.should.raise NoMethodError
56
56
  end
57
- end
58
57
 
59
- describe 'temp_extend_safe' do
60
- it 'should temporarily extend the module for the duration of a block in a threadsafe manner' do
58
+ it 'should execute before and after hooks prior to and after running the temp_extend block' do
61
59
  lambda { B.hello }.should.raise NoMethodError
62
- B.temp_extend_safe(A) do
60
+ B.instance_variable_defined?(:@before).should == false
61
+ B.instance_variable_defined?(:@after).should == false
62
+ B.temp_extend(A,
63
+ :before => proc { B.instance_variable_set(:@before, true) },
64
+ :after => proc { B.instance_variable_set(:@after, true) } ) do
65
+ B.instance_variable_get(:@before).should == true
66
+ B.instance_variable_defined?(:@after).should == false
63
67
  B.hello.should == :hello
64
68
  end
69
+ B.instance_variable_get(:@after).should == true
70
+ B.instance_variable_get(:@before).should == true
65
71
  lambda { B.hello }.should.raise NoMethodError
66
72
  end
67
- end
68
-
69
- describe 'unextend' do
70
- it 'should unextend the module' do
71
- C.include A, B
72
- M.extend C
73
- M.singleton_class.ancestors[0..2].should == [C, A, B]
74
- M.unextend C
75
- M.singleton_class.ancestors[0..1].should == [A, B]
73
+
74
+ describe 'temp_extend_safe' do
75
+ it 'should temporarily extend the module for the duration of a block in a threadsafe manner' do
76
+ lambda { B.hello }.should.raise NoMethodError
77
+ B.temp_extend_safe(A) do
78
+ B.hello.should == :hello
79
+ end
80
+ lambda { B.hello }.should.raise NoMethodError
81
+ end
76
82
  end
83
+
84
+ describe 'unextend' do
85
+ it 'should unextend the module' do
86
+ C.include A, B
87
+ M.extend C
88
+ M.singleton_class.ancestors[0..2].should == [C, A, B]
89
+ M.unextend C
90
+ M.singleton_class.ancestors[0..1].should == [A, B]
91
+ end
77
92
 
78
- it 'should unextend the nested module' do
79
- C.include A, B
80
- M.extend C
81
- M.extend J
82
- M.singleton_class.ancestors[0..3].should == [J, C, A, B]
83
- M.unextend C, true
84
- M.singleton_class.ancestors[0..1].should == [J, Module]
85
- end
93
+ it 'should unextend the nested module' do
94
+ C.include A, B
95
+ M.extend C
96
+ M.extend J
97
+ M.singleton_class.ancestors[0..3].should == [J, C, A, B]
98
+ M.unextend C, true
99
+ M.singleton_class.ancestors[0..1].should == [J, Module]
100
+ end
86
101
 
87
- it 'should unextend the class of the object' do
88
- o = C2.new
89
- o.singleton_class.ancestors.first.should == C2
90
- o.unextend(C2)
91
- o.singleton_class.ancestors.first.should == A
102
+ it 'should unextend the class of the object' do
103
+ o = C2.new
104
+ o.singleton_class.ancestors.first.should == C2
105
+ o.unextend(C2)
106
+ o.singleton_class.ancestors.first.should == A
107
+ end
92
108
  end
93
- end
94
-
95
- describe 'replace_extended_module' do
96
- it 'should replace the class of the object with a module' do
97
- o = C2.new
98
- o.singleton_class.ancestors.first.should == C2
99
- o.replace_extended_module C2, J
100
- o.singleton_class.ancestors.first.should == J
109
+
110
+ describe 'replace_extended_module' do
111
+ it 'should replace the class of the object with a module' do
112
+ o = C2.new
113
+ o.singleton_class.ancestors.first.should == C2
114
+ o.replace_extended_module C2, J
115
+ o.singleton_class.ancestors.first.should == J
116
+ end
101
117
  end
102
118
  end
103
- end
104
-
105
- describe 'include-based methods' do
106
- describe 'include_after' do
107
- it 'should insert module into correct position' do
108
- M.include_after A, C
109
- M.ancestors[2].should == C
119
+
120
+ describe 'include-based methods' do
121
+ describe 'include_after' do
122
+ it 'should insert module into correct position' do
123
+ M.include_after A, C
124
+ M.ancestors[2].should == C
125
+ end
110
126
  end
111
- end
112
127
 
113
- describe 'temp_include' do
114
- it 'should temporarily include the module for the duration of a block' do
115
- lambda { "john".hello }.should.raise NoMethodError
116
- String.temp_include(A) do
117
- "john".hello.should == :hello
128
+ describe 'temp_include' do
129
+ it 'should temporarily include the module for the duration of a block' do
130
+ lambda { "john".hello }.should.raise NoMethodError
131
+ String.temp_include(A) do
132
+ "john".hello.should == :hello
133
+ end
134
+ lambda { "john".hello }.should.raise NoMethodError
118
135
  end
119
- lambda { "john".hello }.should.raise NoMethodError
120
- end
121
- end
122
136
 
123
- describe 'temp_include_safe' do
124
- it 'should temporarily include the module for the duration of a block in a threadsafe manner' do
125
- lambda { "john".hello }.should.raise NoMethodError
126
- String.temp_include_safe(A) do
127
- "john".hello.should == :hello
137
+ it 'should execute before and after hooks prior to and after running the temp_include block' do
138
+ lambda { B.hello }.should.raise NoMethodError
139
+ B.instance_variable_defined?(:@before).should == false
140
+ B.instance_variable_defined?(:@after).should == false
141
+ B.temp_include(A,
142
+ :before => proc { B.instance_variable_set(:@before, true) },
143
+ :after => proc { B.instance_variable_set(:@after, true) } ) do
144
+ B.instance_variable_get(:@before).should == true
145
+ B.instance_variable_defined?(:@after).should == false
146
+ end
147
+ B.instance_variable_get(:@after).should == true
148
+ B.instance_variable_get(:@before).should == true
149
+ lambda { B.hello }.should.raise NoMethodError
128
150
  end
129
- lambda { "john".hello }.should.raise NoMethodError
151
+
130
152
  end
131
- end
132
-
133
- describe 'include_before' do
134
- it 'should insert module into correct position' do
135
- M.include_before B, C
136
- M.ancestors[2].should == C
137
- end
138
- end
139
153
 
140
- describe 'include_at_top' do
141
- it 'should insert module at top of chain' do
142
- M.include_at_top C
143
- M.ancestors.last.should == C
154
+ describe 'temp_include_safe' do
155
+ it 'should temporarily include the module for the duration of a block in a threadsafe manner' do
156
+ lambda { "john".hello }.should.raise NoMethodError
157
+ String.temp_include_safe(A) do
158
+ "john".hello.should == :hello
159
+ end
160
+ lambda { "john".hello }.should.raise NoMethodError
161
+ end
144
162
  end
145
- end
146
-
147
- describe 'swap_modules' do
148
- it 'should interchange modules' do
149
- M.ancestors[1..2].should == [A, B]
150
- M.swap_modules A, B
151
- M.ancestors[1..2].should == [B, A]
163
+
164
+ describe 'include_before' do
165
+ it 'should insert module into correct position' do
166
+ M.include_before B, C
167
+ M.ancestors[2].should == C
168
+ end
152
169
  end
153
- end
154
170
 
155
- describe 'module_move_up' do
156
- it 'should move module up the chain' do
157
- M.ancestors[1..2].should == [A, B]
158
- M.module_move_up A
159
- M.ancestors[1..2].should == [B, A]
171
+ describe 'include_at_top' do
172
+ it 'should insert module at top of chain' do
173
+ M.include_at_top C
174
+ M.ancestors.last.should == C
175
+ end
160
176
  end
161
- end
177
+
178
+ describe 'swap_modules' do
179
+ it 'should interchange modules' do
180
+ M.ancestors[1..2].should == [A, B]
181
+ M.swap_modules A, B
182
+ M.ancestors[1..2].should == [B, A]
183
+ end
162
184
 
163
- describe 'module_move_down' do
164
- it 'should move module down the chain' do
165
- M.ancestors[1..2].should == [A, B]
166
- M.module_move_down B
167
- M.ancestors[1..2].should == [B, A]
185
+ it 'should handle huge ancestor chains without crashing or returning the wrong result' do
186
+ size = 100
187
+ m = Module.new
188
+ size.times do
189
+ m.include Module.new
190
+ end
191
+
192
+ m.ancestors.size.should == size + 1
193
+ size.times do
194
+ m.swap_modules(m.ancestors[rand(size - 1) + 1],
195
+ m.ancestors[rand(size - 1) + 1])
196
+ end
197
+ m.ancestors.size.should == size + 1
198
+ end
168
199
  end
169
- end
170
200
 
171
- describe 'include_at' do
172
- it 'should include module at specified index' do
173
- M.include_at(1, C)
174
- M.ancestors[1].should == C
201
+ describe 'module_move_up' do
202
+ it 'should move module up the chain' do
203
+ M.ancestors[1..2].should == [A, B]
204
+ M.module_move_up A
205
+ M.ancestors[1..2].should == [B, A]
206
+ end
175
207
  end
176
- end
177
208
 
178
- describe 'remove_module' do
179
- it 'should remove the module' do
180
- M.ancestors[1..2].should == [A, B]
181
- M.remove_module A
182
- M.ancestors[1..2].should == [B]
209
+ describe 'module_move_down' do
210
+ it 'should move module down the chain' do
211
+ M.ancestors[1..2].should == [A, B]
212
+ M.module_move_down B
213
+ M.ancestors[1..2].should == [B, A]
214
+ end
183
215
  end
184
216
 
185
- it 'should remove recursively if second parameter is true' do
186
- klass = Module.new
187
- klass.include J, M, C
188
- klass.ancestors[1..-1].should == [J, M, A, B, C]
189
- klass.remove_module M, true
190
- klass.ancestors[1..-1].should == [J, C]
217
+ describe 'include_at' do
218
+ it 'should include module at specified index' do
219
+ M.include_at(1, C)
220
+ M.ancestors[1].should == C
221
+ end
191
222
  end
192
- end
193
223
 
194
- describe 'replace_module' do
195
- it 'should replace the module with another' do
196
- M.ancestors[1..2].should == [A, B]
197
- M.replace_module B, C
198
- M.ancestors[1..2].should == [A, C]
224
+ describe 'remove_module' do
225
+ it 'should remove the module' do
226
+ M.ancestors[1..2].should == [A, B]
227
+ M.remove_module A
228
+ M.ancestors[1..2].should == [B]
229
+ end
230
+
231
+ it 'should remove recursively if second parameter is true' do
232
+ klass = Module.new
233
+ klass.include J, M, C
234
+ klass.ancestors[1..-1].should == [J, M, A, B, C]
235
+ klass.remove_module M, true
236
+ klass.ancestors[1..-1].should == [J, C]
237
+ end
199
238
  end
200
239
 
201
- it 'should replace a class with a module' do
202
- C2.ancestors[0..2].should == [C2, A, C1]
203
- C2.replace_module C1, B
204
- C2.ancestors[0..2].should == [C2, A, B]
240
+ describe 'replace_module' do
241
+ it 'should replace the module with another' do
242
+ M.ancestors[1..2].should == [A, B]
243
+ M.replace_module B, C
244
+ M.ancestors[1..2].should == [A, C]
245
+ end
246
+
247
+ it 'should replace a class with a module' do
248
+ C2.ancestors[0..2].should == [C2, A, C1]
249
+ C2.replace_module C1, B
250
+ C2.ancestors[0..2].should == [C2, A, B]
251
+ end
205
252
  end
206
253
  end
207
-
208
254
  end
209
255
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remix
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 0
10
- version: 0.4.0
9
+ - 5
10
+ version: 0.4.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Mair (banisterfiend)
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-11 00:00:00 +13:00
18
+ date: 2010-11-12 00:00:00 +13:00
19
19
  default_executable:
20
20
  dependencies: []
21
21