remix 0.4.8-i386-mswin32 → 0.4.9-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 CHANGED
@@ -1,3 +1,5 @@
1
+ 16/11/2010 version 0.4.9
2
+ * added __attached__ method
1
3
  15/11/2010 version 0.4.8
2
4
  * all extend-based methods now return self
3
5
  * added documentation on blocks (@yield)
@@ -21,6 +21,16 @@ VALUE rb_swap_modules(VALUE self, VALUE mod1, VALUE mod2);
21
21
  rb_raise(rb_eTypeError, "Must be a T_MODULE, T_CLASS, T_ICLASS, T_OBJECT, or T_FALSE type."); \
22
22
  } while(0)
23
23
 
24
+ /* Tiny utility method to return an object attached to a singleton */
25
+ static VALUE
26
+ rb_singleton_attached(VALUE self)
27
+ {
28
+ if(FL_TEST(self, FL_SINGLETON))
29
+ return rb_iv_get(self, "__attached__");
30
+ else
31
+ return Qnil;
32
+ }
33
+
24
34
  /* a modified version of include_class_new from class.c */
25
35
  static VALUE
26
36
  j_class_new(VALUE module, VALUE sup)
@@ -365,5 +375,8 @@ Init_remix()
365
375
  rb_define_method(mModuleExtensions, "uninclude", rb_uninclude, -1);
366
376
  rb_define_alias(mModuleExtensions, "remove_module", "uninclude");
367
377
  rb_define_method(mModuleExtensions, "replace_module", rb_replace_module, 2);
378
+
379
+ rb_define_method(mModuleExtensions, "__attached__", rb_singleton_attached, 0);
380
+
368
381
  }
369
382
 
Binary file
Binary file
@@ -1,5 +1,13 @@
1
1
  module Remix
2
2
  module ModuleExtensions
3
+
4
+ # Utility method to return object associated with a singleton class
5
+ # @return Object associated with singleton
6
+ # @example
7
+ # class C; end
8
+ # C.singleton_class.__attached__ #=> C
9
+ def __attached__() end
10
+
3
11
  # Includes a module at a particular index in the ancestor
4
12
  # chain.
5
13
  #
@@ -0,0 +1,116 @@
1
+ module Remix
2
+ module ModuleExtensions
3
+
4
+ # Includes a module at a particular index in the ancestor
5
+ # chain.
6
+ #
7
+ # @param [Fixnum] index The index where the module will be included
8
+ # (must be > 1.)
9
+ # @param [Module] mod The module to include
10
+ # @return [Module] The receiver
11
+ # @example
12
+ # P.ancestors #=> [P, M, N]
13
+ # P.include_at 2, O
14
+ # P.ancestors #=> [P, M, O, N]
15
+ def include_at(index, mod) end
16
+
17
+ # Includes a module below a specific module in the ancestor chain.
18
+ # @param [Module] mod1 Module with position
19
+ # @param [Module] mod2 Module that will be included
20
+ # @return [Module] The receiver
21
+ # @example
22
+ # M.ancestors #=> [M, A, B]
23
+ # M.include_below B, J
24
+ # M.ancestors #=> [M, A, J, B]
25
+ def include_below(mod1, mod2) end
26
+
27
+ # Includes a module above a specific module in the ancestor chain.
28
+ # @param [Module] mod1 Module with position
29
+ # @param [Module] mod2 Module that will be included
30
+ # @return [Module] The receiver
31
+ # @example
32
+ # M.ancestors #=> [M, A, B]
33
+ # M.include_above B, J
34
+ # M.ancestors #=> [M, A, B, J]
35
+ def include_above(mod1, mod) end
36
+
37
+ # Includes a module at top of ancestor chain
38
+ # @param [Module] mod Module that will be included
39
+ # @return [Module] The receiver
40
+ # @example
41
+ # M.ancestors #=> [M, A, B]
42
+ # M.include_at_top J
43
+ # M.ancestors #=> [M, A, B, J]
44
+ def include_at_top(mod) end
45
+
46
+ # Moves a module up one position in the ancestor chain.
47
+ # Module must already be in ancestor chain.
48
+ # @param [Module] mod The module to move up
49
+ # @return [Module] The receiver
50
+ # @example
51
+ # M.ancestors #=> [M, A, B]
52
+ # M.module_move_up A
53
+ # M.ancestors #=> [M, B, A]
54
+ def module_move_up(mod) end
55
+
56
+ # Moves a module down one position in the ancestor chain.
57
+ # Module must already be in ancestor chain.
58
+ # @param [Module] mod The module to move down
59
+ # @return [Module] The receiver
60
+ # @example
61
+ # M.ancestors #=> [M, A, B]
62
+ # M.module_move_down B
63
+ # M.ancestors #=> [M, B, A]
64
+ def module_move_down(mod) end
65
+
66
+ # Unincludes a module from an ancestor chain with optional recursion
67
+ # for nested modules.
68
+ # @param [Module] mod The module to uninclude
69
+ # @param [Boolean] recurse Set to true to remove nested modules
70
+ # @return [Module] The receiver
71
+ # @example Without recursion
72
+ # module C
73
+ # include A, B
74
+ # end
75
+ # M.ancestors #=> [M, C, A, B]
76
+ # M.uninclude C
77
+ # M.ancestors #=> [M, A, B]
78
+ # @example With recursion
79
+ # module C
80
+ # include A, B
81
+ # end
82
+ # M.ancestors #=> [M, C, A, B]
83
+ # M.uninclude C, true
84
+ # M.ancestors #=> [M]
85
+ def uninclude(mod, recurse = false) end
86
+
87
+ # Swaps the position of two modules that already exist in an
88
+ # ancestor chain.
89
+ # @param [Module] mod1 Module to swap
90
+ # @param [Module] mod2 Module to swap
91
+ # @return [Module] The receiver
92
+ # @example
93
+ # M.ancestors #=> [M, A, B, C, D]
94
+ # M.swap_modules A, D
95
+ # M.ancestors #=> [M, D, B, C, A]
96
+ def swap_modules(mod1, mod2) end
97
+
98
+ # Replaces a module with another module that is not already in the
99
+ # ancestor chain.
100
+ # @param [Module] mod1 The module to be replaced
101
+ # @param [Module] mod2 The module that will replace
102
+ # @return [Module] The receiver
103
+ # @example
104
+ # J = Module.new
105
+ # M.ancestors #=> [M, A, B]
106
+ # M.replace_module B, J
107
+ # M.ancestors #=> [M, A, J]
108
+ def replace_module(mod1, mod2) end
109
+
110
+ # Prepares the receiver's ancestor chain for remixing. This method
111
+ # is called automatically by all remixing methods and should
112
+ # never need to be invoked by the user.
113
+ # @return [Object] The receiver
114
+ def ready_remix() end
115
+ end
116
+ end
@@ -1,4 +1,4 @@
1
1
  module Remix
2
- VERSION = "0.4.8"
2
+ VERSION = "0.4.9"
3
3
  end
4
4
 
@@ -0,0 +1,4 @@
1
+ module Remix
2
+ VERSION = "0.4.9"
3
+ end
4
+
@@ -206,6 +206,13 @@ describe 'Test basic remix functionality' do
206
206
  end
207
207
  end
208
208
 
209
+ describe '__attached__' do
210
+ it 'should return the correct attached object' do
211
+ o = Object.new
212
+ o.singleton_class.__attached__.should == o
213
+ end
214
+ end
215
+
209
216
  describe 'module_move_up' do
210
217
  it 'should move module up the chain' do
211
218
  M.ancestors[1..2].should == [A, B]
@@ -0,0 +1,269 @@
1
+ direc = File.dirname(__FILE__)
2
+ require 'rubygems'
3
+ require "#{direc}/../lib/remix"
4
+ require 'bacon'
5
+
6
+ class Module
7
+ public :include, :remove_const
8
+ end
9
+
10
+ puts "testing Remix version #{Remix::VERSION}..."
11
+ puts "Ruby version: #{RUBY_VERSION}"
12
+
13
+ describe 'Test basic remix functionality' do
14
+ before do
15
+ A = Module.new { def hello; :hello; end }
16
+ B = Module.new
17
+ C = Module.new
18
+ J = Module.new
19
+
20
+ M = Module.new
21
+
22
+ M.include A, B
23
+ M.extend A, B
24
+
25
+ C1 = Class.new
26
+ C2 = Class.new(C1)
27
+ C2.include A
28
+ end
29
+
30
+ after do
31
+ Object.remove_const(:A)
32
+ Object.remove_const(:B)
33
+ Object.remove_const(:C)
34
+ Object.remove_const(:M)
35
+ Object.remove_const(:J)
36
+ Object.remove_const(:C1)
37
+ Object.remove_const(:C2)
38
+ end
39
+
40
+ describe 'extend-based methods' do
41
+ describe 'extend_after' do
42
+ it 'should insert module into correct position in singleton class' do
43
+ M.extend_above B, J
44
+ M.singleton_class.ancestors
45
+ M.singleton_class.ancestors[0..2].should == [A, B, J]
46
+ end
47
+ end
48
+
49
+ describe 'temp_extend' do
50
+ it 'should temporarily extend the module for the duration of a block' do
51
+ lambda { B.hello }.should.raise NoMethodError
52
+ B.temp_extend(A) do
53
+ B.hello.should == :hello
54
+ end
55
+ lambda { B.hello }.should.raise NoMethodError
56
+ end
57
+
58
+ it 'should execute before and after hooks prior to and after running the temp_extend block' do
59
+ lambda { B.hello }.should.raise NoMethodError
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
67
+ B.hello.should == :hello
68
+ end
69
+ B.instance_variable_get(:@after).should == true
70
+ B.instance_variable_get(:@before).should == true
71
+ lambda { B.hello }.should.raise NoMethodError
72
+ end
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
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
92
+
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
101
+
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
108
+ end
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
117
+ end
118
+ end
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
126
+ end
127
+
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
135
+ end
136
+
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
150
+ end
151
+
152
+ end
153
+
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
162
+ end
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
169
+ end
170
+
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
176
+ 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
184
+
185
+ it 'should do a no-op when source/dest modules are the same' do
186
+ M.ancestors[1..2].should == [A, B]
187
+ M.swap_modules A, A
188
+ M.ancestors[1..2].should == [A, B]
189
+ M.swap_modules B, B
190
+ M.ancestors[1..2].should == [A, B]
191
+ end
192
+
193
+ it 'should handle huge ancestor chains without crashing or returning the wrong result' do
194
+ size = 100
195
+ m = Module.new
196
+ size.times do
197
+ m.include Module.new
198
+ end
199
+
200
+ m.ancestors.size.should == size + 1
201
+ size.times do
202
+ m.swap_modules(m.ancestors[rand(size - 1) + 1],
203
+ m.ancestors[rand(size - 1) + 1])
204
+ end
205
+ m.ancestors.size.should == size + 1
206
+ end
207
+ end
208
+
209
+ describe 'module_move_up' do
210
+ it 'should move module up the chain' do
211
+ M.ancestors[1..2].should == [A, B]
212
+ M.module_move_up A
213
+ M.ancestors[1..2].should == [B, A]
214
+ end
215
+ end
216
+
217
+ describe 'module_move_down' do
218
+ it 'should move module down the chain' do
219
+ M.ancestors[1..2].should == [A, B]
220
+ M.module_move_down B
221
+ M.ancestors[1..2].should == [B, A]
222
+ end
223
+ end
224
+
225
+ describe 'include_at' do
226
+ it 'should include module at specified index' do
227
+ M.include_at(1, C)
228
+ M.ancestors[1].should == C
229
+ end
230
+ end
231
+
232
+ describe 'remove_module' do
233
+ it 'should remove the module' do
234
+ M.ancestors[1..2].should == [A, B]
235
+ M.remove_module A
236
+ M.ancestors[1..2].should == [B]
237
+ end
238
+
239
+ it 'should remove recursively if second parameter is true' do
240
+ klass = Module.new
241
+ klass.include J, M, C
242
+ klass.ancestors[1..-1].should == [J, M, A, B, C]
243
+ klass.remove_module M, true
244
+ klass.ancestors[1..-1].should == [J, C]
245
+ end
246
+ end
247
+
248
+ describe 'replace_module' do
249
+ it 'should replace the module with another' do
250
+ M.ancestors[1..2].should == [A, B]
251
+ M.replace_module B, C
252
+ M.ancestors[1..2].should == [A, C]
253
+ end
254
+
255
+
256
+ it 'should replace a class with a module' do
257
+ C2.ancestors[0..2].should == [C2, A, C1]
258
+ C2.replace_module C1, B
259
+ C2.ancestors[0..2].should == [C2, A, B]
260
+ end
261
+
262
+ it 'should raise when replace_module target is the root module of the chain' do
263
+ M.ancestors[0..2].should == [M, A, B]
264
+ lambda { M.replace_module M, J }.should.raise RuntimeError
265
+ end
266
+ end
267
+ end
268
+ end
269
+ end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remix
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 29
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 4
8
- - 8
9
- version: 0.4.8
9
+ - 9
10
+ version: 0.4.9
10
11
  platform: i386-mswin32
11
12
  authors:
12
13
  - John Mair (banisterfiend)
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-11-15 00:00:00 +13:00
18
+ date: 2010-11-16 00:00:00 +13:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -31,9 +32,12 @@ files:
31
32
  - ext/remix/compat.h
32
33
  - ext/remix/remix.c
33
34
  - lib/remix/c_docs.rb
35
+ - lib/remix/c_docs_flymake.rb
34
36
  - lib/remix/version.rb
37
+ - lib/remix/version_flymake.rb
35
38
  - lib/remix.rb
36
39
  - test/test.rb
40
+ - test/test_flymake.rb
37
41
  - test/test_with_object2module.rb
38
42
  - CHANGELOG
39
43
  - README.markdown
@@ -54,6 +58,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
58
  requirements:
55
59
  - - ">="
56
60
  - !ruby/object:Gem::Version
61
+ hash: 3
57
62
  segments:
58
63
  - 0
59
64
  version: "0"
@@ -62,6 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
67
  requirements:
63
68
  - - ">="
64
69
  - !ruby/object:Gem::Version
70
+ hash: 3
65
71
  segments:
66
72
  - 0
67
73
  version: "0"