remix 0.2.0-i386-mswin32 → 0.2.5-i386-mswin32

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 27/10/2010 version 0.2.5
2
+ * added tests
3
+ * reversed order of arguments for #include_at
4
+ * made it so first index of #include_at is 1 (not 0, since 0 is host module)
5
+ * added extend-based methods
6
+ * reordered modules (Remix::ObjectExtenstions and Remix::ModuleExtensions)
7
+ * added recursive uninclude
1
8
  26/10/2010 version 0.2.0
2
9
  * added include_at_top, replace_module, module_move_up, etc
3
10
  25/10/2010 version 0.1.0
data/README.markdown CHANGED
@@ -1,54 +1,142 @@
1
1
  Remix
2
- --------------
2
+ =======
3
3
 
4
- (c) John Mair (banisterfiend)
5
- MIT license
4
+ (C) John Mair (banisterfiend) 2010
6
5
 
7
- Ruby modules re-mixed and remastered
6
+ _Ruby modules remixed and remastered_
8
7
 
9
- ** This is BETA software and has not yet been thoroughly tested, use
10
- at own risk **
11
-
12
- install the gem: **for testing purposes only**
13
- `gem install remix`
8
+ Remix is a library to give you total control over class and module ancestor
9
+ chains.
14
10
 
15
- Currently supports:
11
+ Using Remix you can add a module at any point in the chain,
12
+ remove modules, replace modules, move modules around and otherwise
13
+ 'remix' your modules.
16
14
 
17
- * include_at(index)
18
- * include_at_top(Mod)
19
- * include_before(BeforeMod, Mod)
20
- * include_after(AfterMod, Mod)
21
- * swap_modules(Mod1, Mod2)
22
- * remove_module(Mod)
23
- * module_move_up(Mod)
24
- * module_move_down(Mod)
25
- * replace_module(Mod1, Mod2)
26
- * ...more to come!
15
+ * Install the [gem](https://rubygems.org/gems/remix): `gem install remix`
16
+ * Read the [documentation](http://rdoc.info/github/banister/remix/master/file/README.markdown)
17
+ * See the [source code](http://github.com/banister/remix)
27
18
 
28
- example:
19
+ example: include_at_top():
20
+ --------------------------
29
21
 
30
- module M end
22
+ Using `include_at_top` we can include a module at the top of a chain
23
+ rather than at the bottom (the default).
24
+
25
+ # ... modules A, B, C, and J defined above...
26
+
27
+ module M
28
+ include A, B, C
29
+ end
30
+
31
+ M.ancestors #=> [M, A, B, C]
32
+
33
+ # Now let's insert a module between A and B
34
+ M.include_at_top J
35
+
36
+ # Modified ancestor chain
37
+ M.ancestors #=> [M, A, B, C, J]
38
+
39
+ example: unextend()
40
+ --------------------
41
+
42
+ Like the Mixico library Remix allows you to unextend
43
+ (or uninclude) modules from inheritance chains; but also extends this
44
+ functionality by (optionally) removing nested modules too:
45
+
46
+
47
+ # ...modules A, B defined above...
48
+
49
+ module C
50
+ include A, B
51
+ end
52
+
53
+ D = Object.new
54
+ D.extend C
55
+ D.singleton_class.ancestors #=> [C, A, B, Object, ...]
56
+
57
+ # remove entire nested module C by passing true as second parameter
58
+ D.unextend C, true
59
+
60
+ D.singleton_class.ancestors #=> [Object, ...]
61
+
62
+ Special features
63
+ ------------------
31
64
 
32
- class A; end
65
+ Remix is intelligent enough to manipulate classes as well as
66
+ modules:
33
67
 
34
- class B < A
35
- include_after(A, M)
68
+ class D < C
69
+ include M
36
70
  end
71
+
72
+ D.ancestors #=> [D, M, C]
73
+
74
+ D.swap_modules C, M
75
+
76
+ D.ancestors #=> [D, C, M]
77
+
78
+ It does this by first converting all superclasses to Included Modules
79
+ before remixing takes place.
37
80
 
38
- B.ancestors #=> [B, A, M, ...]
81
+ How it works
82
+ --------------
39
83
 
40
- B.swap_modules A, M
84
+ Remix is a C-based extension that directly manipulates the superclass
85
+ pointers of Included Modules.
41
86
 
42
- B.ancestors #=> [B, M, A, ...]
87
+ Companion Libraries
88
+ --------------------
43
89
 
44
- module J end
90
+ Remix is one of a series of experimental libraries that mess with
91
+ the internals of Ruby to bring new and interesting functionality to
92
+ the language, see also:
45
93
 
46
- B.include_before A, J
94
+ * [Real Include](http://github.com/banister/real_include) - Brings in
95
+ module singleton classes during an include. No more ugly ClassMethods and included() hook hacks.
96
+ * [Object2module](http://github.com/banister/object2module) - Convert Classes and Objects to Modules so they can be extended/included
97
+ * [Prepend](http://github.com/banister/prepend) - Prepends modules in front of a class; so method lookup starts with the module
98
+ * [GenEval](http://github.com/banister/gen_eval) - A strange new breed of instance_eval
47
99
 
48
- B.ancestors #=> [B, M, J, A, ...]
100
+ Full list of functions
101
+ ----------------------
49
102
 
50
- B.remove_module M
103
+ **include-based functions:**
51
104
 
52
- B.ancestors #=> [B, J, A, ...]
53
-
54
-
105
+ * include_at(index)
106
+ * include_at_top(mod)
107
+ * include_before(before_mod, mod)
108
+ * include_after(after_mod, mod)
109
+ * swap_modules(mod1, mod2)
110
+ * uninclude(mod, recurse=fale)
111
+ * module_move_up(mod)
112
+ * module_move_down(mod)
113
+ * replace_module(mod1, mod2)
114
+
115
+ **extend-based functions:**
116
+
117
+ * extend_at(index)
118
+ * extend_at_top(mod)
119
+ * extend_before(before_mod, mod)
120
+ * extend_after(after_mod, mod)
121
+ * swap_extended_modules(mod1, mod2)
122
+ * replace_module(mod1, mod2)
123
+ * unextend(mod, recurse=false)
124
+ * extended_module_move_up(mod)
125
+ * extended_module_move_down(mod)
126
+
127
+ Limitations
128
+ ------------
129
+
130
+ Remix does not currently reorder the singleton classes of superclasses
131
+ to reflect the new position of the class. This functionality is coming
132
+ soon.
133
+
134
+ Contact
135
+ -------
136
+
137
+ Problems or questions contact me at [github](http://github.com/banister)
138
+
139
+ Dedication
140
+ ----------
141
+
142
+ For Rue (1977-)
data/Rakefile CHANGED
@@ -25,10 +25,10 @@ specification = Gem::Specification.new do |s|
25
25
  s.has_rdoc = 'yard'
26
26
 
27
27
  #s.extensions = ["ext/remix/extconf.rb"]
28
- s.files = ["Rakefile", "README.markdown", "CHANGELOG",
29
- "lib/remix.rb", "lib/remix/version.rb"] +
28
+ s.files =
30
29
  ["lib/1.9/remix.so", "lib/1.8/remix.so"] +
31
- FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c"].to_a
30
+ FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb", "test/*.rb",
31
+ "CHANGELOG", "README.markdown", "Rakefile"].to_a
32
32
  end
33
33
 
34
34
  Rake::GemPackageTask.new(specification) do |package|
data/ext/remix/remix.c CHANGED
@@ -106,6 +106,9 @@ get_source_module(VALUE mod)
106
106
  static VALUE
107
107
  retrieve_before_mod(VALUE m, VALUE before)
108
108
  {
109
+ if (!RTEST(rb_obj_is_kind_of(before, rb_cModule)) && TYPE(before) != T_FALSE)
110
+ rb_raise(rb_eTypeError, "Must be a Module or Class type.");
111
+
109
112
  VALUE k = get_source_module(RCLASS_SUPER(m));
110
113
  while(k != before && m != 0 && m != rb_cObject) {
111
114
  m = RCLASS_SUPER(m);
@@ -120,6 +123,9 @@ retrieve_before_mod(VALUE m, VALUE before)
120
123
  static VALUE
121
124
  retrieve_mod(VALUE m, VALUE after)
122
125
  {
126
+ if (!RTEST(rb_obj_is_kind_of(after, rb_cModule)) && TYPE(after) != T_FALSE)
127
+ rb_raise(rb_eTypeError, "Must be a Module or Class type.");
128
+
123
129
  VALUE k = get_source_module(m);
124
130
  while(k != after && m != 0 && m != rb_cObject) {
125
131
  m = RCLASS_SUPER(m);
@@ -191,19 +197,25 @@ VALUE
191
197
  rb_include_before(VALUE self, VALUE before, VALUE mod)
192
198
  {
193
199
  rb_prepare_for_remix(self);
200
+
201
+ if (before == self)
202
+ rb_raise(rb_eRuntimeError, "Prepend not supported yet!");
203
+
194
204
  rb_include_module(retrieve_before_mod(self, before), mod);
195
205
  return self;
196
206
  }
197
207
 
198
208
  VALUE
199
- rb_include_at(VALUE self, VALUE mod, VALUE rb_index)
209
+ rb_include_at(VALUE self, VALUE rb_index, VALUE mod)
200
210
  {
201
211
  rb_prepare_for_remix(self);
212
+
213
+ Check_Type(rb_index, T_FIXNUM);
202
214
 
203
215
  int index = FIX2INT(rb_index);
204
216
  VALUE m = self;
205
217
 
206
- int i = 0;
218
+ int i = 1;
207
219
  while(i++ < index && RCLASS_SUPER(m) != 0 && RCLASS_SUPER(m) != rb_cObject)
208
220
  m = RCLASS_SUPER(m);
209
221
 
@@ -236,16 +248,40 @@ rb_swap_modules(VALUE self, VALUE mod1, VALUE mod2)
236
248
  return self;
237
249
  }
238
250
 
251
+ static void
252
+ remove_nested_module(VALUE included_mod, VALUE module)
253
+ {
254
+ VALUE source_mod = get_source_module(RCLASS_SUPER(included_mod));
255
+
256
+ if (source_mod == rb_cObject || source_mod == Qfalse)
257
+ return;
258
+ else if (source_mod == get_source_module(RCLASS_SUPER(module))) {
259
+ remove_nested_module(RCLASS_SUPER(included_mod), RCLASS_SUPER(module));
260
+ RCLASS_SUPER(included_mod) = RCLASS_SUPER(RCLASS_SUPER(included_mod));
261
+ }
262
+ }
263
+
239
264
  VALUE
240
- rb_remove_module(VALUE self, VALUE mod1)
265
+ rb_uninclude(int argc, VALUE * argv, VALUE self)
241
266
  {
242
267
  rb_prepare_for_remix(self);
243
268
 
269
+ VALUE mod1, recurse = Qfalse;
270
+ rb_scan_args(argc, argv, "11", &mod1, &recurse);
271
+
272
+ if (!RTEST(rb_mod_include_p(self, mod1)))
273
+ rb_raise(rb_eArgError, "Module not found");
274
+
244
275
  VALUE before = retrieve_before_mod(self, mod1);
245
276
  VALUE included_mod = retrieve_mod(self, mod1);
246
277
 
247
278
  if (mod1 == rb_cObject) rb_raise(rb_eRuntimeError, "can't delete Object");
279
+
280
+ if (RTEST(recurse))
281
+ remove_nested_module(included_mod, mod1);
282
+
248
283
  RCLASS_SUPER(before) = RCLASS_SUPER(included_mod);
284
+
249
285
  rb_clear_cache();
250
286
 
251
287
  return self;
@@ -260,7 +296,7 @@ rb_replace_module(VALUE self, VALUE mod1, VALUE mod2)
260
296
  return rb_swap_modules(self, mod1, mod2);
261
297
 
262
298
  VALUE before = retrieve_before_mod(self, mod1);
263
- rb_remove_module(self, mod1);
299
+ rb_uninclude(1, &mod1, self);
264
300
  rb_include_module(before, mod2);
265
301
  return self;
266
302
  }
@@ -268,17 +304,25 @@ rb_replace_module(VALUE self, VALUE mod1, VALUE mod2)
268
304
  void
269
305
  Init_remix()
270
306
  {
271
- rb_define_method(rb_cObject, "ready_remix", rb_prepare_for_remix, 0);
272
- rb_define_method(rb_cModule, "module_move_up", rb_module_move_up, 1);
273
- rb_define_method(rb_cModule, "module_move_down", rb_module_move_down, 1);
274
-
275
- rb_define_method(rb_cModule, "include_at", rb_include_at, 2);
276
- rb_define_method(rb_cModule, "include_before", rb_include_before, 2);
277
- rb_define_method(rb_cModule, "include_after", rb_include_after, 2);
278
- rb_define_method(rb_cModule, "include_at_top", rb_include_at_top, 1);
279
-
280
- rb_define_method(rb_cModule, "swap_modules", rb_swap_modules, 2);
281
- rb_define_method(rb_cModule, "remove_module", rb_remove_module, 1);
282
- rb_define_method(rb_cModule, "replace_module", rb_replace_module, 2);
307
+ VALUE mRemix = rb_define_module("Remix");
308
+ VALUE mModuleExtensions = rb_define_module_under(mRemix, "ModuleExtensions");
309
+
310
+ rb_define_method(mModuleExtensions, "ready_remix", rb_prepare_for_remix, 0);
311
+ rb_define_method(mModuleExtensions, "module_move_up", rb_module_move_up, 1);
312
+ rb_define_method(mModuleExtensions, "module_move_down", rb_module_move_down, 1);
313
+
314
+ rb_define_method(mModuleExtensions, "include_at", rb_include_at, 2);
315
+ rb_define_method(mModuleExtensions, "include_below", rb_include_before, 2);
316
+ rb_define_alias(mModuleExtensions, "include_before", "include_below");
317
+ rb_define_method(mModuleExtensions, "include_above", rb_include_after, 2);
318
+ rb_define_alias(mModuleExtensions, "include_after", "include_above");
319
+ rb_define_method(mModuleExtensions, "include_at_top", rb_include_at_top, 1);
320
+
321
+ rb_define_method(mModuleExtensions, "swap_modules", rb_swap_modules, 2);
322
+ rb_define_method(mModuleExtensions, "uninclude", rb_uninclude, -1);
323
+ rb_define_alias(mModuleExtensions, "remove_module", "uninclude");
324
+ rb_define_method(mModuleExtensions, "replace_module", rb_replace_module, 2);
325
+
326
+ rb_include_module(rb_cModule, mModuleExtensions);
283
327
  }
284
328
 
data/lib/1.8/remix.so CHANGED
Binary file
data/lib/1.9/remix.so CHANGED
Binary file
data/lib/remix.rb CHANGED
@@ -2,6 +2,7 @@ direc = File.dirname(__FILE__)
2
2
 
3
3
  require 'rbconfig'
4
4
  require "#{direc}/remix/version"
5
+ require "#{direc}/remix/c_docs"
5
6
 
6
7
  dlext = Config::CONFIG['DLEXT']
7
8
 
@@ -15,3 +16,74 @@ rescue LoadError => e
15
16
  require "#{direc}/remix.#{dlext}"
16
17
  end
17
18
 
19
+ module Kernel
20
+ # :nodoc:
21
+ def singleton_class
22
+ class << self; self; end
23
+ end if !respond_to?(:singleton_class)
24
+ end
25
+
26
+ module Remix::ObjectExtensions
27
+
28
+ # Like `include_at()` but for the singleton class
29
+ # @see Module#include_at
30
+ def extend_at(index, mod)
31
+ singleton_class.include_at(index, mod)
32
+ end
33
+
34
+ # Like `include_below()` but for the singleton class
35
+ # @see Module#include_below
36
+ def extend_below(mod1, mod2)
37
+ singleton_class.include_below(mod1, mod2)
38
+ end
39
+ alias_method :extend_before, :extend_below
40
+
41
+ # Like `include_above()` but for the singleton class
42
+ # @see Module#include_above
43
+ def extend_above(mod1, mod2)
44
+ singleton_class.include_above(mod1, mod2)
45
+ end
46
+ alias_method :extend_after, :extend_above
47
+
48
+ # Like `uninclude()` but for the singleton class
49
+ # @see Module#uninclude
50
+ def unextend(mod, recurse = false)
51
+ singleton_class.uninclude(mod, recurse)
52
+ end
53
+ alias_method :remove_extended_module, :unextend
54
+
55
+ # Like `include_at_top()` but for the singleton class
56
+ # @see Module#include_at_top
57
+ def extend_at_top(mod)
58
+ singleton_class.include_at_top(mod)
59
+ end
60
+
61
+ # Like `swap_modules()` but for the singleton class
62
+ # @see Module#swap_modules
63
+ def swap_extended_modules(mod1, mod2)
64
+ singleton_class.swap_modules(mod1, mod2)
65
+ end
66
+
67
+ # Like `module_move_up()` but for the singleton class
68
+ # @see Module#module_move_up
69
+ def extended_module_move_up(mod)
70
+ singleton_class.module_move_up(mod)
71
+ end
72
+
73
+ # Like `module_move_down()` but for the singleton class
74
+ # @see Module#module_move_down
75
+ def extended_module_move_down(mod)
76
+ singleton_class.module_move_down(mod)
77
+ end
78
+
79
+ # Like `replace_module()` but for the singleton class
80
+ # @see Module#replace_module_down
81
+ def replace_extended_module(mod1, mod2)
82
+ singleton_class.replace_module(mod1, mod2)
83
+ end
84
+ end
85
+
86
+
87
+ class Object
88
+ include Remix::ObjectExtensions
89
+ end
@@ -0,0 +1,114 @@
1
+ module Remix
2
+ module ModuleExtensions
3
+ # Includes a module at a particular index in the ancestor
4
+ # chain.
5
+ #
6
+ # @param [Fixnum] index The index where the module will be included
7
+ # (must be > 1.)
8
+ # @param [Module] mod The module to include
9
+ # @return [Module] The receiver
10
+ # @example
11
+ # module M end
12
+ # module N end
13
+ # module O end
14
+ # module P
15
+ # include M, N
16
+ # end
17
+ # P.include_at 2, O
18
+ # P.ancestors #=> [P, M, O, N]
19
+ def include_at(index, mod) end
20
+
21
+ # Includes a module below a specific module in the ancestor chain.
22
+ # @param [Module] mod1 Module with position
23
+ # @param [Module] mod2 Module that will be included
24
+ # @return [Module] The receiver
25
+ # @example
26
+ # M.ancestors #=> [M, A, B]
27
+ # M.include_below B, J
28
+ # M.ancestors #=> [M, A, J, B]
29
+ def include_below(mod1, mod2) end
30
+
31
+ # Includes a module above a specific module in the ancestor chain.
32
+ # @param [Module] mod1 Module with position
33
+ # @param [Module] mod2 Module that will be included
34
+ # @return [Module] The receiver
35
+ # @example
36
+ # M.ancestors #=> [M, A, B]
37
+ # M.include_above B, J
38
+ # M.ancestors #=> [M, A, B, J]
39
+ def include_above(mod1, mod) end
40
+
41
+ # Includes a module at top of ancestor chain
42
+ # @param [Module] mod Module that will be included
43
+ # @return [Module] The receiver
44
+ # @example
45
+ # M.ancestors #=> [M, A, B]
46
+ # M.include_at_top J
47
+ # M.ancestors #=> [M, A, B, J]
48
+ def include_at_top(mod) end
49
+
50
+ # Moves a module up one position in the ancestor chain.
51
+ # Module must already be in ancestor chain.
52
+ # @param [Module] Module to move up
53
+ # @return [Module] The receiver
54
+ # @example
55
+ # M.ancestors #=> [M, A, B]
56
+ # M.module_move_up A
57
+ # M.ancestors #=> [M, B, A]
58
+ def module_move_up(mod) end
59
+
60
+ # Moves a module down one position in the ancestor chain.
61
+ # Module must already be in ancestor chain.
62
+ # @param [Module] Module to move down
63
+ # @return [Module] The receiver
64
+ # @example
65
+ # M.ancestors #=> [M, A, B]
66
+ # M.module_move_down B
67
+ # M.ancestors #=> [M, B, A]
68
+ def module_move_down(mod) end
69
+
70
+ # Unincludes a module from an ancestor chain with optional recursion
71
+ # for nested modules.
72
+ # @param [Module] mod The module to uninclude
73
+ # @param [Boolean] recurse Set to true to remove nested modules
74
+ # @return [Module] The receiver
75
+ # @example
76
+ # module C
77
+ # include A, B
78
+ # end
79
+ # M.ancestors #=> [M, C, A, B]
80
+ # M.uninclude C
81
+ # M.ancestors #=> [M, A, B]
82
+ # @example With recursion
83
+ # module C
84
+ # include A, B
85
+ # end
86
+ # M.ancestors #=> [M, C, A, B]
87
+ # M.uninclude C, true
88
+ # M.ancestors #=> [M]
89
+ def uninclude(mod, recurse = false) end
90
+
91
+ # Swaps the position of two modules that already exist in an
92
+ # ancestor chain.
93
+ # @param [Module] mod1 Module to swap
94
+ # @param [Module] mod2 Module to swap
95
+ # @return [Module] The receiver
96
+ # @example
97
+ # M.ancestors #=> [M, A, B, C, D]
98
+ # M.swap_modules A, D
99
+ # M.ancestors #=> [M, D, B, C, A]
100
+ def swap_modules(mod1, mod2) end
101
+
102
+ # Replaces a module with another module that is not already in the
103
+ # ancestor chain.
104
+ # @param [Module] mod1 The module to be replaced
105
+ # @param [Module] mod2 The module that will replace
106
+ # @return [Module] The receiver
107
+ # @example
108
+ # J = Module.new
109
+ # M.ancestors #=> [M, A, B]
110
+ # M.replace_module B, J
111
+ # M.ancestors #=> [M, A, J]
112
+ def replace_module(mod1, mod2) end
113
+ end
114
+ end
data/lib/remix/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Remix
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.5"
3
3
  end
data/test/test.rb ADDED
@@ -0,0 +1,137 @@
1
+ require 'rubygems'
2
+ require '../lib/remix'
3
+ require 'bacon'
4
+
5
+ class Module
6
+ public :include, :remove_const
7
+ end
8
+
9
+ describe 'Test basic remix functionality' do
10
+ before do
11
+ A = Module.new
12
+ B = Module.new
13
+ C = Module.new
14
+ J = Module.new
15
+
16
+ M = Module.new
17
+
18
+ M.include A, B
19
+ M.extend A, B
20
+ end
21
+
22
+ after do
23
+ Object.remove_const(:A)
24
+ Object.remove_const(:B)
25
+ Object.remove_const(:C)
26
+ Object.remove_const(:M)
27
+ Object.remove_const(:J)
28
+ end
29
+
30
+ describe 'extend-based methods' do
31
+ describe 'extend_after' do
32
+ it 'should insert module into correct position in singleton class' do
33
+ M.extend_above B, J
34
+ M.singleton_class.ancestors
35
+ M.singleton_class.ancestors[0..2].should == [A, B, J]
36
+ end
37
+ end
38
+
39
+ describe 'unextend' do
40
+ it 'should unextend the module' do
41
+ C.include A, B
42
+ M.extend C
43
+ M.singleton_class.ancestors[0..2].should == [C, A, B]
44
+ M.unextend C
45
+ M.singleton_class.ancestors[0..1].should == [A, B]
46
+ end
47
+
48
+ it 'should unextend the nested module' do
49
+ C.include A, B
50
+ M.extend C
51
+ M.extend J
52
+ M.singleton_class.ancestors[0..3].should == [J, C, A, B]
53
+ M.unextend C, true
54
+ M.singleton_class.ancestors[0..1].should == [J, Module]
55
+ end
56
+ end
57
+ end
58
+
59
+ describe 'include-based methods' do
60
+ describe 'include_after' do
61
+ it 'should insert module into correct position' do
62
+ M.include_after A, C
63
+ M.ancestors[2].should == C
64
+ end
65
+ end
66
+
67
+ describe 'include_before' do
68
+ it 'should insert module into correct position' do
69
+ M.include_before B, C
70
+ M.ancestors[2].should == C
71
+ end
72
+ end
73
+
74
+ describe 'include_at_top' do
75
+ it 'should insert module at top of chain' do
76
+ M.include_at_top C
77
+ M.ancestors.last.should == C
78
+ end
79
+ end
80
+
81
+ describe 'swap_modules' do
82
+ it 'should interchange modules' do
83
+ M.ancestors[1..2].should == [A, B]
84
+ M.swap_modules A, B
85
+ M.ancestors[1..2].should == [B, A]
86
+ end
87
+ end
88
+
89
+ describe 'module_move_up' do
90
+ it 'should move module up the chain' do
91
+ M.ancestors[1..2].should == [A, B]
92
+ M.module_move_up A
93
+ M.ancestors[1..2].should == [B, A]
94
+ end
95
+ end
96
+
97
+ describe 'module_move_down' do
98
+ it 'should move module down the chain' do
99
+ M.ancestors[1..2].should == [A, B]
100
+ M.module_move_down B
101
+ M.ancestors[1..2].should == [B, A]
102
+ end
103
+ end
104
+
105
+ describe 'include_at' do
106
+ it 'should include module at specified index' do
107
+ M.include_at(1, C)
108
+ M.ancestors[1].should == C
109
+ end
110
+ end
111
+
112
+ describe 'remove_module' do
113
+ it 'should remove the module' do
114
+ M.ancestors[1..2].should == [A, B]
115
+ M.remove_module A
116
+ M.ancestors[1..2].should == [B]
117
+ end
118
+
119
+ it 'should remove recursively if second parameter is true' do
120
+ klass = Module.new
121
+ klass.include J, M, C
122
+ klass.ancestors[1..-1].should == [J, M, A, B, C]
123
+ klass.remove_module M, true
124
+ klass.ancestors[1..-1].should == [J, C]
125
+ end
126
+ end
127
+
128
+ describe 'replace_module' do
129
+ it 'should replace the module with another' do
130
+ M.ancestors[1..2].should == [A, B]
131
+ M.replace_module B, C
132
+ M.ancestors[1..2].should == [A, C]
133
+ end
134
+ end
135
+
136
+ end
137
+ end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remix
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 2
9
- - 0
10
- version: 0.2.0
8
+ - 5
9
+ version: 0.2.5
11
10
  platform: i386-mswin32
12
11
  authors:
13
12
  - John Mair (banisterfiend)
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-10-26 00:00:00 +13:00
17
+ date: 2010-10-27 00:00:00 +13:00
19
18
  default_executable:
20
19
  dependencies: []
21
20
 
@@ -28,16 +27,18 @@ extensions: []
28
27
  extra_rdoc_files: []
29
28
 
30
29
  files:
31
- - Rakefile
32
- - README.markdown
33
- - CHANGELOG
34
- - lib/remix.rb
35
- - lib/remix/version.rb
36
30
  - lib/1.9/remix.so
37
31
  - lib/1.8/remix.so
38
32
  - ext/remix/extconf.rb
39
33
  - ext/remix/compat.h
40
34
  - ext/remix/remix.c
35
+ - lib/remix/c_docs.rb
36
+ - lib/remix/version.rb
37
+ - lib/remix.rb
38
+ - test/test.rb
39
+ - CHANGELOG
40
+ - README.markdown
41
+ - Rakefile
41
42
  has_rdoc: yard
42
43
  homepage: http://banisterfiend.wordpress.com
43
44
  licenses: []
@@ -52,7 +53,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
52
53
  requirements:
53
54
  - - ">="
54
55
  - !ruby/object:Gem::Version
55
- hash: 3
56
56
  segments:
57
57
  - 0
58
58
  version: "0"
@@ -61,7 +61,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
61
  requirements:
62
62
  - - ">="
63
63
  - !ruby/object:Gem::Version
64
- hash: 3
65
64
  segments:
66
65
  - 0
67
66
  version: "0"