remix 0.4.0-i386-mswin32 → 0.4.5-i386-mswin32
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.
- data/CHANGELOG +7 -1
- data/Rakefile +16 -1
- data/ext/remix/remix.c +3 -0
- data/lib/1.8/remix.so +0 -0
- data/lib/1.9/remix.so +0 -0
- data/lib/remix.rb +138 -118
- data/lib/remix/version.rb +1 -1
- data/test/test.rb +161 -115
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
|
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/1.8/remix.so
CHANGED
Binary file
|
data/lib/1.9/remix.so
CHANGED
Binary file
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
19
|
+
require "#{direc}/remix.#{dlext}"
|
20
20
|
end
|
21
21
|
|
22
22
|
module Kernel
|
23
|
-
#
|
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
|
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
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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/lib/remix/version.rb
CHANGED
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
|
-
|
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.
|
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
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
-
|
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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
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
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
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
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
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
|
-
|
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
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
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
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
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
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
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:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 5
|
10
|
+
version: 0.4.5
|
11
11
|
platform: i386-mswin32
|
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-
|
18
|
+
date: 2010-11-12 00:00:00 +13:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|