qualitysmith_extensions 0.0.34 → 0.0.49

Sign up to get free protection for your applications and to get access to all the features.
Files changed (25) hide show
  1. data/lib/qualitysmith_extensions/array/shell_escape.rb +2 -2
  2. data/lib/qualitysmith_extensions/kernel/remove_const.rb +178 -0
  3. data/lib/qualitysmith_extensions/kernel/remove_module.rb +127 -0
  4. data/lib/qualitysmith_extensions/module/ancestry_of_instance_method.rb +43 -0
  5. data/lib/qualitysmith_extensions/module/attribute_accessors.rb +3 -0
  6. data/lib/qualitysmith_extensions/module/basename.rb +76 -0
  7. data/lib/qualitysmith_extensions/module/class_methods.rb +87 -0
  8. data/lib/qualitysmith_extensions/module/create.rb +315 -0
  9. data/lib/qualitysmith_extensions/module/dirname.rb +4 -0
  10. data/lib/qualitysmith_extensions/module/guard_method.rb +0 -1
  11. data/lib/qualitysmith_extensions/module/join.rb +66 -0
  12. data/lib/qualitysmith_extensions/module/module_methods.rb +4 -0
  13. data/lib/qualitysmith_extensions/module/namespace.rb +111 -0
  14. data/lib/qualitysmith_extensions/module/parents.rb +61 -0
  15. data/lib/qualitysmith_extensions/module/remove_const.rb +117 -0
  16. data/lib/qualitysmith_extensions/module/split.rb +55 -0
  17. data/lib/qualitysmith_extensions/object/ancestry_of_method.rb +257 -0
  18. data/lib/qualitysmith_extensions/object/methods.rb +7 -2
  19. data/lib/qualitysmith_extensions/string/constantize.rb +4 -0
  20. data/lib/qualitysmith_extensions/string/shell_escape.rb +1 -1
  21. data/lib/qualitysmith_extensions/symbol/constantize.rb +69 -0
  22. data/lib/qualitysmith_extensions/template.rb +1 -0
  23. data/lib/qualitysmith_extensions/test/assert_anything.rb +93 -0
  24. metadata +19 -3
  25. data/lib/qualitysmith_extensions/class/class_methods.rb +0 -5
@@ -0,0 +1,87 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Yes!
6
+ # Developer notes::
7
+ #++
8
+
9
+ class Object
10
+
11
+ def class_methods(include_super = true)
12
+ (
13
+ methods(include_super) \
14
+ - instance_methods
15
+ ).
16
+ sort
17
+ end
18
+ alias_method :module_methods, :class_methods
19
+
20
+ end
21
+
22
+
23
+ # _____ _
24
+ # |_ _|__ ___| |_
25
+ # | |/ _ \/ __| __|
26
+ # | | __/\__ \ |_
27
+ # |_|\___||___/\__|
28
+ #
29
+ =begin test
30
+ require 'test/unit'
31
+ require 'qualitysmith_extensions/test/assert_anything'
32
+ require 'set'
33
+
34
+ module M
35
+ def instance_meth; end
36
+ def self.module_meth; end
37
+ end
38
+ class C
39
+ def instance_meth; end
40
+ def self.module_meth; end
41
+ end
42
+ class CSub < C
43
+ def sub_instance_meth; end
44
+ def self.sub_module_meth; end
45
+ end
46
+
47
+
48
+ class TheTest < Test::Unit::TestCase
49
+ C_common_instance_methods = ['object_id', 'dup', 'send', 'is_a?']
50
+ C_common_class_methods = ['instance_methods']
51
+ def test_class
52
+ assert_subset? (['instance_meth'] + C_common_instance_methods).to_set,
53
+ C.instance_methods.to_set
54
+ assert_subset? (['module_meth'] + C_common_class_methods).to_set,
55
+ C.class_methods.to_set
56
+ end
57
+ def test_class__no_super
58
+ assert_subset? ['instance_meth'].to_set,
59
+ C.instance_methods(false).to_set
60
+ assert_subset? ['module_meth'].to_set,
61
+ C.class_methods(false).to_set
62
+ end
63
+
64
+ def test_module
65
+ assert_equal ['instance_meth'], M.instance_methods # Unlike a class, modules don't have all the common instance methods from Object
66
+ assert_subset? (['module_meth'] + C_common_class_methods).to_set,
67
+ M.class_methods.to_set
68
+ end
69
+ def test_module__no_super
70
+ assert_equal ['instance_meth'], M.instance_methods(false) # Unlike a class, modules don't have all the common instance methods from Object
71
+ assert_subset? (['module_meth']).to_set,
72
+ M.class_methods(false).to_set
73
+ end
74
+
75
+ def test_subclass
76
+ assert_subset? (['instance_meth', 'sub_instance_meth'] + C_common_instance_methods).to_set,
77
+ CSub.instance_methods.to_set
78
+ assert_subset? ['module_meth', 'sub_module_meth'].to_set,
79
+ CSub.class_methods.to_set
80
+ end
81
+ def test_subclass__no_super
82
+ assert_equal ['sub_instance_meth'], CSub.instance_methods(false)
83
+ assert_equal ['sub_module_meth'], CSub.class_methods(false)
84
+ end
85
+ end
86
+ =end
87
+
@@ -0,0 +1,315 @@
1
+ #--
2
+ # Author:: Aaron Pfeifer, Neil Abraham, Tyler Rick
3
+ # Copyright:: Copyright (c) 2006-2007 Aaron Pfeifer & Neil Abraham
4
+ # License:: MIT License
5
+ # Submit to Facets?:: Yes!
6
+ # Developer notes::
7
+ # * Why are we calling it create? Why not just new? Would that cause any problems?
8
+ # To do::
9
+ # * Submit to pluginaweek mailing list
10
+ # Changes:
11
+ # r2964 (Tyler):
12
+ # * Started from http://svn.pluginaweek.org/trunk/plugins/ruby/module/module_creation_helper/ (Last Changed Rev: 320)
13
+ # * Renamed :parent option to :namespace. (:parent is still allowed for backwards compatibility)
14
+ # * Changed examples and tests to pass in the name as a symbol instead of a string.
15
+ # * Made it so you can pass in the namespace as part of the name if you want: Module.create(:'Foo::Bar') instead of Module.create(:Foo, :parent => Bar)
16
+ # * Added to the documentation
17
+ # * Added new tests
18
+ # * test_with_block_2
19
+ # * test_nested_class_with_superclass_with_same_name
20
+ # * test_referencing_a_namespace_that_isnt_defined
21
+ # * test_creating_a_class_more_than_once
22
+ # * test_using_return_value_of_one_create_within_another_create
23
+ # * Added __FILE__, __LINE__ to class_eval so that error messages would be more helpful.
24
+ #++
25
+
26
+ require 'rubygems'
27
+ require 'facets/core/hash/assert_has_only_keys'
28
+ require 'facets/core/hash/reverse_merge'
29
+ require 'facets/core/kernel/constant'
30
+ require 'facets/core/symbol/to_proc'
31
+ require 'qualitysmith_extensions/module/split'
32
+ require 'qualitysmith_extensions/module/basename'
33
+ require 'qualitysmith_extensions/module/dirname'
34
+
35
+ class Module
36
+ # Creates a new module with the specified name. This is essentially the
37
+ # same as actually defining the module like so:
38
+ #
39
+ # module NewModule
40
+ # end
41
+ #
42
+ # or as a class:
43
+ #
44
+ # class NewClass < SuperKlass
45
+ # end
46
+ #
47
+ # Configuration options:
48
+ # <tt>superclass</tt> - The class to inherit from. This only applies when using Class#create. Default is Object.
49
+ # <tt>namespace</tt>/<tt>parent</tt> - The class/module namespace that contains this module. Default is Object.
50
+ #
51
+ # You can also include the namespace in the +name+ if you'd prefer. For instance, name = <tt>:'Foo::Bar'</tt> is the same as specifying <tt>name = :Bar, :namespace => Foo</tt>. (Note: The namespace module specified must already be defined, just like it would have to be defined if you used the <tt>:namespace</tt> option.)
52
+ #
53
+ # Examples:
54
+ #
55
+ # Module.create(:Foo) # => Foo
56
+ # Module.create(:'Foo::Bar', :namespace => Foo) # => Foo::Bar
57
+ # Module.create(:Bar, :namespace => Foo) # => Foo::Bar
58
+ #
59
+ # Class.create(:Base) # => Base
60
+ # Class.create(:'Foo::Klass', :superclass => Base) # => Foo::Klass
61
+ #
62
+ # Unlike the built-in Ruby +module+/+class+ directive, this actually returns the newly created module/class as the return value. So, for example, you can do things like this:
63
+ #
64
+ # klass = Class.create(:'Foo::Klass', :superclass => Class.create(:Base)) # => Foo::Klass
65
+ # klass.name # => Foo::Klass
66
+ # klass.superclass # => Base
67
+ #
68
+ # You can also pass a block to create. This:
69
+ #
70
+ # Class.create(:ClassWithBlock, :superclass => BaseClass) do
71
+ # def self.say_hello
72
+ # 'hello'
73
+ # end
74
+ # end
75
+ #
76
+ # is equivalent to this:
77
+ #
78
+ # class ClassWithBlock < BaseClass do
79
+ # def self.say_hello
80
+ # 'hello'
81
+ # end
82
+ # end
83
+ #
84
+ def create(name, options = {}, &block)
85
+ # Validate arguments
86
+ raise ArgumentError unless name.respond_to?(:to_s)
87
+ options[:namespace] = options.delete(:parent) if options.has_key?(:parent)
88
+ options.assert_has_only_keys(
89
+ :superclass,
90
+ :namespace
91
+ )
92
+ module_or_class = self.to_s.downcase
93
+ raise ArgumentError, 'Modules cannot have superclasses' if options[:superclass] && module_or_class == 'module'
94
+
95
+ # Set defaults
96
+ namespace_module, superclass =
97
+ options[:namespace] || ::Object,
98
+ options[:superclass] || ::Object
99
+
100
+ # Determine the namespace to create it in
101
+ nesting = Module.split_name(name)
102
+ if nesting.size > 1
103
+ namespace_module = Module.namespace_of(name) # For example, would be A::B for A::B::C
104
+ base_name = Module.basename(name) # For example, would be :C for A::B::C
105
+ else
106
+ base_name = name
107
+ end
108
+
109
+ # Actually create the new module
110
+ if superclass != ::Object
111
+ superclass = " < ::#{superclass}"
112
+ else
113
+ superclass = ''
114
+ end
115
+ namespace_module.class_eval <<-end_eval, __FILE__, __LINE__
116
+ #{module_or_class} #{base_name}#{superclass}
117
+ # Empty
118
+ end
119
+ end_eval
120
+ our_new_module = namespace_module.const_get(base_name)
121
+
122
+ our_new_module.class_eval(&block) if block_given?
123
+ our_new_module
124
+ end
125
+ end
126
+
127
+
128
+
129
+
130
+ # _____ _
131
+ # |_ _|__ ___| |_
132
+ # | |/ _ \/ __| __|
133
+ # | | __/\__ \ |_
134
+ # |_|\___||___/\__|
135
+ #
136
+ =begin test
137
+ require 'test/unit'
138
+ require 'rubygems'
139
+ require 'qualitysmith_extensions/module/attribute_accessors'
140
+ require 'qualitysmith_extensions/module/namespace'
141
+ require 'qualitysmith_extensions/symbol/constantize'
142
+ require 'facets/core/module/basename'
143
+
144
+ module Namespace
145
+ end
146
+
147
+ class BaseClass
148
+ cattr_accessor :test_name
149
+ cattr_accessor :test_inspect
150
+ cattr_accessor :test_to_s
151
+
152
+ def self.inherited(base)
153
+ self.test_name = base.name
154
+ self.test_inspect = base.inspect
155
+ self.test_to_s = base.to_s
156
+ end
157
+ end
158
+
159
+ class ModuleCreationHelperTest < Test::Unit::TestCase
160
+ def setup
161
+ BaseClass.test_name = nil
162
+ BaseClass.test_inspect = nil
163
+ BaseClass.test_to_s = nil
164
+ end
165
+
166
+ def test_no_options_for_class
167
+ klass = Class.create(:Foo)
168
+ assert_equal Object, klass.superclass
169
+ assert_equal Object, klass.namespace
170
+ assert Object.const_defined?('Foo')
171
+ end
172
+
173
+ def test_no_options_for_module
174
+ mod = Module.create(:FooMod)
175
+ assert_equal Object, mod.namespace
176
+ assert Object.const_defined?('FooMod')
177
+ end
178
+
179
+ def test_invalid_option
180
+ assert_raise(ArgumentError) {Class.create(nil, :invalid => true)}
181
+ end
182
+
183
+ def test_superclass_for_module
184
+ assert_raise(ArgumentError) {Module.create(nil, :superclass => Object)}
185
+ end
186
+
187
+ def test_superclass
188
+ klass = Class.create(:Bar, :superclass => BaseClass)
189
+ assert_equal BaseClass, klass.superclass
190
+ assert_equal Object, klass.namespace
191
+ assert Object.const_defined?('Bar')
192
+ end
193
+
194
+ def test_namespace_for_class
195
+ klass = Class.create(:Baz, :namespace => Namespace)
196
+ assert_equal Object, klass.superclass
197
+ assert_equal Namespace, klass.namespace
198
+ assert Namespace.const_defined?('Baz')
199
+ end
200
+
201
+ def test_namespace_for_class__namespace_as_part_of_name
202
+ klass = Class.create(:'Namespace::Baz')
203
+ assert_equal Object, klass.superclass
204
+ assert_equal Namespace, klass.namespace
205
+ assert Namespace.const_defined?('Baz')
206
+ end
207
+
208
+ def test_namespace_for_module
209
+ mod = Module.create(:BazMod, :namespace => Namespace)
210
+ assert_equal Namespace, mod.namespace
211
+ assert Namespace.const_defined?('BazMod')
212
+ end
213
+
214
+ def test_superclass_and_namespace
215
+ klass = Class.create(:Biz, :superclass => BaseClass, :namespace => Namespace)
216
+ assert_equal BaseClass, klass.superclass
217
+ assert_equal Namespace, klass.namespace
218
+ assert Namespace.const_defined?('Biz')
219
+ end
220
+
221
+ def test_name_before_evaluated
222
+ klass = Class.create(:Waddle, :superclass => BaseClass)
223
+ assert_equal 'Waddle', BaseClass.test_name
224
+ end
225
+
226
+ def test_inspect_before_evaluated
227
+ klass = Class.create(:Widdle, :superclass => BaseClass)
228
+ assert_equal 'Widdle', BaseClass.test_inspect
229
+ end
230
+
231
+ def test_to_s_before_evaluated
232
+ klass = Class.create(:Wuddle, :superclass => BaseClass)
233
+ assert_equal 'Wuddle', BaseClass.test_to_s
234
+ end
235
+
236
+ def test_name_before_evaluated_with_namespace
237
+ klass = Class.create(:Waddle, :superclass => BaseClass, :namespace => Namespace)
238
+ assert_equal 'Namespace::Waddle', BaseClass.test_name
239
+ end
240
+
241
+ def test_inspect_before_evaluated_with_namespace
242
+ klass = Class.create(:Widdle, :superclass => BaseClass, :namespace => Namespace)
243
+ assert_equal 'Namespace::Widdle', BaseClass.test_inspect
244
+ end
245
+
246
+ def test_to_s_before_evaluated_with_namespace
247
+ klass = klass = Class.create(:Wuddle, :superclass => BaseClass, :namespace => Namespace)
248
+ assert_equal 'Namespace::Wuddle', BaseClass.test_to_s
249
+ end
250
+
251
+ def test_subclass_of_dynamic_class
252
+ klass = Class.create(:Foobar)
253
+ subclass = Class.create(:Foobaz, :superclass => klass)
254
+
255
+ assert_equal klass, subclass.superclass
256
+ assert_equal 'Foobaz', subclass.name
257
+ assert_equal 'Foobaz', subclass.inspect
258
+ assert_equal 'Foobaz', subclass.to_s
259
+ end
260
+
261
+ def test_with_block_1
262
+ klass = Class.create(:ClassWithBlock, :superclass => BaseClass) do
263
+ def self.say_hello
264
+ 'hello'
265
+ end
266
+ end
267
+ assert_equal 'hello', ClassWithBlock.say_hello
268
+ end
269
+
270
+ def test_with_block_2
271
+ klass = Class.create(:ClassWithBlock, :superclass => BaseClass) do
272
+ def say_hello
273
+ 'hello'
274
+ end
275
+ end
276
+ assert_equal 'hello', ClassWithBlock.new.say_hello
277
+ end
278
+
279
+ def test_nested_class_with_superclass_with_same_name
280
+ klass = Class.create(:Employee)
281
+ nested_class = Class.create(:Employee, :superclass => klass, :namespace => Namespace)
282
+ assert_equal klass, nested_class.superclass
283
+ assert_equal klass.basename, nested_class.basename
284
+ end
285
+
286
+ def test_nested_class_with_superclass_with_same_name
287
+ klass = Class.create(:Employee)
288
+ nested_class = Class.create(:Employee, :superclass => klass, :namespace => Namespace)
289
+ assert_equal klass, nested_class.superclass
290
+ assert_equal klass.basename, nested_class.basename
291
+ end
292
+
293
+ def test_referencing_a_namespace_that_isnt_defined
294
+ assert_raise(NameError) { Class.create(:'Zzt::Klass') }
295
+ end
296
+
297
+ def test_creating_a_class_more_than_once
298
+ klass = Class.create(:'Foo')
299
+ klass = Class.create(:'Foo')
300
+ end
301
+
302
+ def test_using_return_value_of_one_create_within_another_create
303
+ klass = Class.create(:'Foo')
304
+ klass = Class.create(:'Base')
305
+ klass = Class.create(:'Foo::Klass',
306
+ :superclass => Class.create(:Base)
307
+ )
308
+ assert_equal 'Foo::Klass', klass.name
309
+ assert_equal Base, klass.superclass
310
+ end
311
+
312
+
313
+ end
314
+ =end
315
+
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ # Alias for:
3
+ require 'qualitysmith_extensions/module/namespace'
4
+
@@ -17,7 +17,6 @@ require 'facets/core/kernel/require_local'
17
17
  require_local 'bool_attr_accessor'
18
18
  #require 'qualitysmith_extensions/module/bool_attr_accessor'
19
19
  require 'qualitysmith_extensions/symbol/match'
20
- require 'qualitysmith_extensions/class/class_methods'
21
20
 
22
21
 
23
22
  class Module
@@ -0,0 +1,66 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Yes.
6
+ # Developer notes::
7
+ # Changes::
8
+ #++
9
+
10
+
11
+ require 'rubygems'
12
+ require 'facets/core/symbol/to_proc'
13
+ require 'qualitysmith_extensions/symbol/constantize'
14
+ require 'qualitysmith_extensions/module/namespace' # dirname
15
+ require 'qualitysmith_extensions/module/basename'
16
+
17
+ class Module
18
+ # Joins pieces of a "module path" together in the same sense that <tt>File.join</tt> joins pieces of a _filesystem_ path.
19
+ #
20
+ # See also <tt>Module.dirname</tt>/<tt>Module.namespace_name_of</tt> and <tt>Module.basename</tt>.
21
+ #
22
+ # These can be used together, such that the following is always true:
23
+ # OuterModule::MiddleModule::InnerModule == Module.join(Module.dirname(some_module), Module.basename(some_module)).constantize
24
+ #
25
+ def self.join(*path_parts)
26
+ path_parts.map(&:to_s).join('::')
27
+ end
28
+ end
29
+
30
+
31
+
32
+
33
+ # _____ _
34
+ # |_ _|__ ___| |_
35
+ # | |/ _ \/ __| __|
36
+ # | | __/\__ \ |_
37
+ # |_|\___||___/\__|
38
+ #
39
+ =begin test
40
+ require 'test/unit'
41
+
42
+ module OuterModule; end
43
+ module OuterModule::MiddleModule; end
44
+ module OuterModule::MiddleModule::InnerModule; end
45
+
46
+ class JoinTest < Test::Unit::TestCase
47
+ def test_join
48
+ assert_equal 'OuterModule::MiddleModule::InnerModule',
49
+ Module.join('OuterModule', 'MiddleModule', 'InnerModule')
50
+ end
51
+ end
52
+
53
+ class TeamworkTest < Test::Unit::TestCase
54
+ def test_join
55
+ assert_equal ['OuterModule::MiddleModule', 'InnerModule'],
56
+ [Module.dirname(OuterModule::MiddleModule::InnerModule), Module.basename(OuterModule::MiddleModule::InnerModule)]
57
+ assert_equal 'OuterModule::MiddleModule::InnerModule',
58
+ Module.join(Module.dirname(OuterModule::MiddleModule::InnerModule), Module.basename(OuterModule::MiddleModule::InnerModule))
59
+ assert_equal OuterModule::MiddleModule::InnerModule,
60
+ Module.join(Module.dirname(OuterModule::MiddleModule::InnerModule), Module.basename(OuterModule::MiddleModule::InnerModule)).constantize
61
+ end
62
+ end
63
+ =end
64
+
65
+
66
+