qualitysmith_extensions 0.0.34 → 0.0.49

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.
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
+