quality_extensions 0.1.1
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/Readme +54 -0
- data/lib/qualitysmith_extensions/all.rb +4 -0
- data/lib/qualitysmith_extensions/array/all.rb +2 -0
- data/lib/qualitysmith_extensions/array/average.rb +44 -0
- data/lib/qualitysmith_extensions/array/classify.rb +97 -0
- data/lib/qualitysmith_extensions/array/expand_ranges.rb +52 -0
- data/lib/qualitysmith_extensions/array/group_by.rb +134 -0
- data/lib/qualitysmith_extensions/array/sequence.rb +66 -0
- data/lib/qualitysmith_extensions/array/shell_escape.rb +36 -0
- data/lib/qualitysmith_extensions/array/to_a_recursive.rb +41 -0
- data/lib/qualitysmith_extensions/array/to_query_string.rb +96 -0
- data/lib/qualitysmith_extensions/collection_extensions_for_cgi.rb +2 -0
- data/lib/qualitysmith_extensions/colored/toggleability.rb +62 -0
- data/lib/qualitysmith_extensions/console/command.facets.1.8.51.rb +749 -0
- data/lib/qualitysmith_extensions/console/command.facets.1.8.54.rb +748 -0
- data/lib/qualitysmith_extensions/console/command.rb +944 -0
- data/lib/qualitysmith_extensions/date/all.rb +2 -0
- data/lib/qualitysmith_extensions/date/deprecated.rb +40 -0
- data/lib/qualitysmith_extensions/date/iso8601.rb +31 -0
- data/lib/qualitysmith_extensions/date/month_ranges.rb +122 -0
- data/lib/qualitysmith_extensions/dir/each_child.rb +58 -0
- data/lib/qualitysmith_extensions/enumerable/enum.rb +69 -0
- data/lib/qualitysmith_extensions/enumerable/select_until.rb +4 -0
- data/lib/qualitysmith_extensions/enumerable/select_while.rb +109 -0
- data/lib/qualitysmith_extensions/exception/inspect_with_backtrace.rb +65 -0
- data/lib/qualitysmith_extensions/file/exact_match_regexp.rb +34 -0
- data/lib/qualitysmith_extensions/file_test/binary_file.rb +110 -0
- data/lib/qualitysmith_extensions/find/select.rb +68 -0
- data/lib/qualitysmith_extensions/global_variable_set.rb +153 -0
- data/lib/qualitysmith_extensions/hash/all.rb +2 -0
- data/lib/qualitysmith_extensions/hash/to_date.rb +34 -0
- data/lib/qualitysmith_extensions/hash/to_query_string.rb +121 -0
- data/lib/qualitysmith_extensions/kernel/all.rb +2 -0
- data/lib/qualitysmith_extensions/kernel/autoreload.rb +128 -0
- data/lib/qualitysmith_extensions/kernel/backtrace.rb +71 -0
- data/lib/qualitysmith_extensions/kernel/capture_output.rb +115 -0
- data/lib/qualitysmith_extensions/kernel/die.rb +49 -0
- data/lib/qualitysmith_extensions/kernel/example_printer.rb +81 -0
- data/lib/qualitysmith_extensions/kernel/filter_output.rb +108 -0
- data/lib/qualitysmith_extensions/kernel/remove_const.rb +178 -0
- data/lib/qualitysmith_extensions/kernel/remove_module.rb +127 -0
- data/lib/qualitysmith_extensions/kernel/require_all.rb +186 -0
- data/lib/qualitysmith_extensions/kernel/require_local_all.rb +4 -0
- data/lib/qualitysmith_extensions/kernel/require_once.rb +18 -0
- data/lib/qualitysmith_extensions/kernel/simulate_input.rb +52 -0
- data/lib/qualitysmith_extensions/kernel/trap_chain.rb +61 -0
- data/lib/qualitysmith_extensions/kernel/windows_platform.rb +46 -0
- data/lib/qualitysmith_extensions/module/alias_method.rb +6 -0
- data/lib/qualitysmith_extensions/module/alias_method_chain.rb +165 -0
- data/lib/qualitysmith_extensions/module/ancestry_of_instance_method.rb +43 -0
- data/lib/qualitysmith_extensions/module/attribute_accessors.rb +49 -0
- data/lib/qualitysmith_extensions/module/basename.rb +76 -0
- data/lib/qualitysmith_extensions/module/bool_attr_accessor.rb +497 -0
- data/lib/qualitysmith_extensions/module/class_methods.rb +87 -0
- data/lib/qualitysmith_extensions/module/create.rb +315 -0
- data/lib/qualitysmith_extensions/module/create_setter.rb +9 -0
- data/lib/qualitysmith_extensions/module/dirname.rb +4 -0
- data/lib/qualitysmith_extensions/module/guard_method.rb +312 -0
- data/lib/qualitysmith_extensions/module/includable_once.rb +10 -0
- data/lib/qualitysmith_extensions/module/join.rb +66 -0
- data/lib/qualitysmith_extensions/module/malias_method_chain.rb +92 -0
- data/lib/qualitysmith_extensions/module/module_methods.rb +4 -0
- data/lib/qualitysmith_extensions/module/namespace.rb +112 -0
- data/lib/qualitysmith_extensions/module/parents.rb +61 -0
- data/lib/qualitysmith_extensions/module/remove_const.rb +117 -0
- data/lib/qualitysmith_extensions/module/split.rb +55 -0
- data/lib/qualitysmith_extensions/month.rb +66 -0
- data/lib/qualitysmith_extensions/mutex/if_available.rb +75 -0
- data/lib/qualitysmith_extensions/object/ancestry_of_method.rb +257 -0
- data/lib/qualitysmith_extensions/object/default.rb +69 -0
- data/lib/qualitysmith_extensions/object/if_else.rb +157 -0
- data/lib/qualitysmith_extensions/object/ignore_access.rb +84 -0
- data/lib/qualitysmith_extensions/object/mcall.rb +92 -0
- data/lib/qualitysmith_extensions/object/methods.rb +63 -0
- data/lib/qualitysmith_extensions/object/send_if.rb +151 -0
- data/lib/qualitysmith_extensions/object/send_if_not_nil.rb +35 -0
- data/lib/qualitysmith_extensions/object/singleton_send.rb +129 -0
- data/lib/qualitysmith_extensions/regexp/join.rb +111 -0
- data/lib/qualitysmith_extensions/string/all.rb +2 -0
- data/lib/qualitysmith_extensions/string/constantize.rb +4 -0
- data/lib/qualitysmith_extensions/string/digits_only.rb +27 -0
- data/lib/qualitysmith_extensions/string/each_char_with_index.rb +41 -0
- data/lib/qualitysmith_extensions/string/md5.rb +29 -0
- data/lib/qualitysmith_extensions/string/shell_escape.rb +43 -0
- data/lib/qualitysmith_extensions/string/to_underscored_label.rb +37 -0
- data/lib/qualitysmith_extensions/string/with_knowledge_of_color.rb +64 -0
- data/lib/qualitysmith_extensions/symbol/constantize.rb +69 -0
- data/lib/qualitysmith_extensions/symbol/match.rb +157 -0
- data/lib/qualitysmith_extensions/template.rb +33 -0
- data/lib/qualitysmith_extensions/test/all.rb +2 -0
- data/lib/qualitysmith_extensions/test/assert_anything.rb +93 -0
- data/lib/qualitysmith_extensions/test/assert_changed.rb +66 -0
- data/lib/qualitysmith_extensions/test/assert_exception.rb +66 -0
- data/lib/qualitysmith_extensions/test/assert_includes.rb +36 -0
- data/lib/qualitysmith_extensions/test/assert_user_error.rb +37 -0
- data/lib/qualitysmith_extensions/test/difference_highlighting.rb +323 -0
- data/lib/qualitysmith_extensions/time/all.rb +2 -0
- data/lib/qualitysmith_extensions/time/deprecated.rb +31 -0
- data/test/all.rb +16 -0
- metadata +148 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Tyler Rick
|
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
|
4
|
+
# License:: Ruby License
|
|
5
|
+
# Submit to Facets?:: Yes
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
require 'rubygems'
|
|
9
|
+
require 'facets/more/filelist'
|
|
10
|
+
|
|
11
|
+
require 'facets/core/kernel/require_local'
|
|
12
|
+
require_local '../file/exact_match_regexp'
|
|
13
|
+
|
|
14
|
+
module Kernel
|
|
15
|
+
|
|
16
|
+
# <tt>require</tt>s all Ruby files specified by <tt>what</tt>, but not matching any of the exclude filters.
|
|
17
|
+
# * If <tt>what</tt> is a string, recursively <tt>require</tt>s all Ruby files in the directory named <tt>what</tt> or any of its subdirectories.
|
|
18
|
+
# * If <tt>what</tt> is a FileList, <tt>require</tt>s all Ruby files that match the <tt>what</tt> FileList.
|
|
19
|
+
#
|
|
20
|
+
# Options:
|
|
21
|
+
# <tt>:exclude</tt>: An array of regular expressions or glob patterns that will be passed to FileList#exclude. If you specify this option, a file will not be included if it matches *any* of these patterns.
|
|
22
|
+
# <tt>:exclude_files</tt>: An array of filenames to exclude. These will be matched exactly, so if you tell it to exclude 'bar.rb', 'foobar.rb' will _not_ be excluded.
|
|
23
|
+
#
|
|
24
|
+
# Examples:
|
|
25
|
+
# require_all 'lib/', :exclude => [/ignore/, /bogus/] # will require 'lib/a.rb', 'lib/long/path/b.rb', but not 'lib/ignore/c.rb'
|
|
26
|
+
# require_all File.dirname(__FILE__), :exclude_files => ['blow_up_stuff.rb']
|
|
27
|
+
def require_all(what, options = {})
|
|
28
|
+
files, exclusions = [nil]*2
|
|
29
|
+
|
|
30
|
+
case what
|
|
31
|
+
when String
|
|
32
|
+
base_dir = what
|
|
33
|
+
base_dir += '/' unless base_dir[-1].chr == '/'
|
|
34
|
+
files = FileList[base_dir + "**/*.rb"]
|
|
35
|
+
when FileList
|
|
36
|
+
files = what
|
|
37
|
+
else
|
|
38
|
+
raise ArgumentError.new("Expected a String or a FileList")
|
|
39
|
+
end
|
|
40
|
+
files = files.exclude(*exclusions) if (exclusions = options.delete(:exclude))
|
|
41
|
+
files = files.exclude(*exclusions.map {|a| File.exact_match_regexp(a) }) if (exclusions = options.delete(:exclude_files))
|
|
42
|
+
|
|
43
|
+
files.each do |filename|
|
|
44
|
+
# puts "requiring #{filename}" if filename =~ /test/
|
|
45
|
+
require filename
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# <tt>require</tt>s all Ruby files in +dir+ (relative to <tt>File.dirname(__FILE__)</tt>) or any of its subdirectories.
|
|
50
|
+
#
|
|
51
|
+
# This is just a shortcut for this:
|
|
52
|
+
# require_all File.join(File.dirname(__FILE__), dir)
|
|
53
|
+
#
|
|
54
|
+
# All of the +options+ available for +require_all+ are still available here.
|
|
55
|
+
#
|
|
56
|
+
def require_local_all(dir = './', options = {})
|
|
57
|
+
raise ArgumentError.new("dir must be a String") unless dir.is_a?(String)
|
|
58
|
+
local_dir = File.dirname( caller[0] )
|
|
59
|
+
require_all(
|
|
60
|
+
File.join(local_dir, dir),
|
|
61
|
+
options
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# _____ _
|
|
68
|
+
# |_ _|__ ___| |_
|
|
69
|
+
# | |/ _ \/ __| __|
|
|
70
|
+
# | | __/\__ \ |_
|
|
71
|
+
# |_|\___||___/\__|
|
|
72
|
+
#
|
|
73
|
+
=begin test
|
|
74
|
+
require 'tmpdir'
|
|
75
|
+
require 'fileutils'
|
|
76
|
+
require 'English'
|
|
77
|
+
|
|
78
|
+
class TheTest < Test::Unit::TestCase
|
|
79
|
+
def setup
|
|
80
|
+
@base_dir = "#{Dir.tmpdir}/require_all_test"
|
|
81
|
+
@base_local_dir = File.dirname(__FILE__) # To allow testing of require_local_all. But tests should put everything in "#{@base_local_dir}/require_all_test" to avoid clutter or name conflicts with other files!
|
|
82
|
+
FileUtils.mkdir @base_dir
|
|
83
|
+
@deep_dir = "really/really/deep/subdir"
|
|
84
|
+
$loaded = []
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
def teardown
|
|
88
|
+
FileUtils.rm_rf @base_dir
|
|
89
|
+
FileUtils.rm_rf "#{@base_local_dir}/require_all_test"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_repeat_requires
|
|
94
|
+
create_ruby_file 'moo.rb'
|
|
95
|
+
|
|
96
|
+
require_all File.dirname(@base_dir)
|
|
97
|
+
assert_equal ['moo.rb'], $loaded
|
|
98
|
+
|
|
99
|
+
require "#{@base_dir}/moo.rb"
|
|
100
|
+
assert_equal ['moo.rb'], $loaded
|
|
101
|
+
|
|
102
|
+
# Good! It refuses to load it again, even if we drop the ".rb" part!
|
|
103
|
+
require "#{@base_dir}/moo"
|
|
104
|
+
assert_equal ['moo.rb'], $loaded
|
|
105
|
+
|
|
106
|
+
# But, we can still trick it!
|
|
107
|
+
$LOAD_PATH << @base_dir
|
|
108
|
+
require "moo"
|
|
109
|
+
assert_equal ['moo.rb', 'moo.rb'], $loaded
|
|
110
|
+
|
|
111
|
+
load "moo.rb"
|
|
112
|
+
assert_equal ['moo.rb', 'moo.rb', 'moo.rb'], $loaded
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_deep_subdir
|
|
116
|
+
create_ruby_file 'flip.rb'
|
|
117
|
+
create_ruby_file @deep_dir + "/flop.rb"
|
|
118
|
+
|
|
119
|
+
require_all File.dirname(@base_dir)
|
|
120
|
+
assert_equal ['flip.rb', @deep_dir + "/flop.rb"], $loaded
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def test_exclude_pattern
|
|
124
|
+
create_ruby_file 'require_me.rb'
|
|
125
|
+
create_ruby_file 'please_ignore_me.rb'
|
|
126
|
+
|
|
127
|
+
require_all File.dirname(@base_dir), :exclude => [/ignore/]
|
|
128
|
+
assert_equal ['require_me.rb'], $loaded
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_require_local_all
|
|
132
|
+
create_ruby_file 'require_all_test/lib/require_me.rb', @base_local_dir
|
|
133
|
+
create_ruby_file 'require_all_test/lib/please_ignore_me.rb', @base_local_dir
|
|
134
|
+
|
|
135
|
+
require_local_all 'require_all_test/lib', :exclude => [/ignore/]
|
|
136
|
+
assert_equal ['require_all_test/lib/require_me.rb'], $loaded
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_exclude_pattern_with_directory
|
|
140
|
+
create_ruby_file 'subdir/test/assert_even.rb'
|
|
141
|
+
create_ruby_file 'subdir/test/assert_odd.rb'
|
|
142
|
+
|
|
143
|
+
require_all File.dirname(@base_dir), :exclude => [/(^|\/)test/]
|
|
144
|
+
assert_equal [], $loaded
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_passing_a_FileList
|
|
148
|
+
create_ruby_file 'subdir/junk/pretty_much_useless.rb'
|
|
149
|
+
create_ruby_file 'subdir/not_junk/good_stuff.rb'
|
|
150
|
+
|
|
151
|
+
require_all FileList[File.dirname(@base_dir) + "/**/*.rb"], :exclude => [/(^|\/)junk/]
|
|
152
|
+
assert_equal ['subdir/not_junk/good_stuff.rb'], $loaded
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_exclude_filename
|
|
156
|
+
create_ruby_file 'yes.rb'
|
|
157
|
+
create_ruby_file 'all.rb'
|
|
158
|
+
|
|
159
|
+
# :todo: Interesting how none of these patterns work. I would have expected them to. Is there a bug in FileList? Find out...
|
|
160
|
+
# /usr/lib/ruby/gems/1.8/gems/facets-1.8.51/lib/facets/more/filelist.rb
|
|
161
|
+
#require_all File.dirname(@base_dir), :exclude => ['all.rb']
|
|
162
|
+
#require_all File.dirname(@base_dir), :exclude => ['**/all']
|
|
163
|
+
#require_all File.dirname(@base_dir), :exclude => [/^all\.rb$/]
|
|
164
|
+
# This works, but it's too much to expect users to type out!:
|
|
165
|
+
#require_all File.dirname(@base_dir), :exclude => [/(\/|^)all\.rb$/]
|
|
166
|
+
|
|
167
|
+
# So...... I added an :exclude_files option so that people wouldn't have to!
|
|
168
|
+
require_all File.dirname(@base_dir), :exclude_files => ['all.rb']
|
|
169
|
+
|
|
170
|
+
assert_equal ['yes.rb'], $loaded
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
#-------------------------------------------------------------------------------------------------------------------------------
|
|
174
|
+
# Helpers
|
|
175
|
+
|
|
176
|
+
def create_ruby_file(file_name, base_dir = @base_dir)
|
|
177
|
+
# use dirname instead?
|
|
178
|
+
if file_name =~ /(.*)\//
|
|
179
|
+
FileUtils.mkdir_p base_dir + '/' + $1
|
|
180
|
+
end
|
|
181
|
+
path = base_dir + '/' + file_name
|
|
182
|
+
File.open(path, "w") {|f| f.puts "$loaded << '#{file_name}'"}
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
end
|
|
186
|
+
=end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Tyler Rick
|
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
|
4
|
+
# License:: Ruby License
|
|
5
|
+
# Submit to Facets?:: No, not yet
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
require 'rubygems'
|
|
9
|
+
|
|
10
|
+
module Kernel
|
|
11
|
+
# Fixes bug in Ruby (1.8, at least -- not sure if 2.0 fixes it) where a file can be required twice if the path is spelled differently.
|
|
12
|
+
def require_once(name)
|
|
13
|
+
raise NotImplementedError
|
|
14
|
+
# store expand_path(name) in an array ($required_files or something)
|
|
15
|
+
# only do the require if it wasn't already in the array
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
require 'stringio'
|
|
10
|
+
require 'rubygems'
|
|
11
|
+
|
|
12
|
+
# Simulates a user typing in +input_string+ on the keyboard.
|
|
13
|
+
#
|
|
14
|
+
# Useful for testing console apps that are ordinarily (they prompt the user for input).
|
|
15
|
+
#
|
|
16
|
+
# output = simulate_inpute('foo') do
|
|
17
|
+
# input = $stdin.gets
|
|
18
|
+
# capture_output { do_stuff() }
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
def simulate_input(input_string, &block)
|
|
22
|
+
|
|
23
|
+
original_stdin = $stdin
|
|
24
|
+
$stdin = StringIO.new(input_string, 'r')
|
|
25
|
+
|
|
26
|
+
begin
|
|
27
|
+
yield
|
|
28
|
+
rescue Exception
|
|
29
|
+
raise
|
|
30
|
+
ensure
|
|
31
|
+
$stdin = original_stdin
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# _____ _
|
|
37
|
+
# |_ _|__ ___| |_
|
|
38
|
+
# | |/ _ \/ __| __|
|
|
39
|
+
# | | __/\__ \ |_
|
|
40
|
+
# |_|\___||___/\__|
|
|
41
|
+
#
|
|
42
|
+
=begin test
|
|
43
|
+
require 'test/unit'
|
|
44
|
+
|
|
45
|
+
class TheTest < Test::Unit::TestCase
|
|
46
|
+
def test_1
|
|
47
|
+
input_received = nil
|
|
48
|
+
simulate_input('foo') { input_received = $stdin.getc.chr }
|
|
49
|
+
assert_equal 'f', input_received
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
=end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Tyler Rick
|
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
|
4
|
+
# License:: Ruby License
|
|
5
|
+
# Submit to Facets?:: Yes!
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module Kernel
|
|
9
|
+
# Calling <tt>Kernel#trap()</tt> by itself will _replace_ any previously registered handler code.
|
|
10
|
+
# <tt>Kernel#trap_chain()</tt>, on the other hand, will _add_ the block you supply to the existing "list" of registered handler blocks.
|
|
11
|
+
# Similar to the way <tt>Kernel#at_exit()</tt> works, <tt>Kernel#trap_chain()</tt> will _prepend_ the given +block+ to the call chain for the given +signal_name+.
|
|
12
|
+
# When the signal occurs, your block will be executed first and then the previously registered handler will be invoked. This can be called repeatedly to create a "chain" of handlers.
|
|
13
|
+
def trap_chain(signal_name, *args, &block)
|
|
14
|
+
previous_interrupt_handler = trap(signal_name, *args) {}
|
|
15
|
+
trap(signal_name, *args) do
|
|
16
|
+
block.call
|
|
17
|
+
previous_interrupt_handler.call unless previous_interrupt_handler == "DEFAULT"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# _____ _
|
|
23
|
+
# |_ _|__ ___| |_
|
|
24
|
+
# | |/ _ \/ __| __|
|
|
25
|
+
# | | __/\__ \ |_
|
|
26
|
+
# |_|\___||___/\__|
|
|
27
|
+
#
|
|
28
|
+
=begin test
|
|
29
|
+
require 'rubygems'
|
|
30
|
+
require 'qualitysmith_extensions/kernel/capture_output'
|
|
31
|
+
require 'fileutils'
|
|
32
|
+
|
|
33
|
+
class TheTest < Test::Unit::TestCase
|
|
34
|
+
def setup
|
|
35
|
+
FileUtils.touch('trap_chain_test_output')
|
|
36
|
+
end
|
|
37
|
+
def teardown
|
|
38
|
+
FileUtils.remove_entry_secure 'trap_chain_test_output'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_1
|
|
42
|
+
output = capture_output do # For some reason, this wasn't capturing the output from the child process when I did plain puts, so I changed it to write to a file instead...
|
|
43
|
+
|
|
44
|
+
pid = fork do
|
|
45
|
+
trap_chain("INT") { File.open('trap_chain_test_output', 'a') {|file| file.puts "Handler 1" } }
|
|
46
|
+
trap_chain("INT") { File.open('trap_chain_test_output', 'a') {|file| file.puts "Handler 2"; file.puts "Exiting..."; }; exit }
|
|
47
|
+
trap_chain("INT") { File.open('trap_chain_test_output', 'a') {|file| file.puts "Handler 3" } }
|
|
48
|
+
puts 'Hello world'
|
|
49
|
+
sleep 5
|
|
50
|
+
end
|
|
51
|
+
Process.kill "INT", pid
|
|
52
|
+
Process.wait
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
assert_equal "Handler 3\nHandler 2\nExiting...\n", File.read('trap_chain_test_output')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
=end
|
|
61
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
module Kernel
|
|
12
|
+
def windows_platform?
|
|
13
|
+
RUBY_PLATFORM =~ /mswin32/
|
|
14
|
+
|
|
15
|
+
# What about mingw32 or cygwin32?
|
|
16
|
+
#RUBY_PLATFORM =~ /(win|w)32$/
|
|
17
|
+
|
|
18
|
+
# What about 64-bit Windows?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# _____ _
|
|
29
|
+
# |_ _|__ ___| |_
|
|
30
|
+
# | |/ _ \/ __| __|
|
|
31
|
+
# | | __/\__ \ |_
|
|
32
|
+
# |_|\___||___/\__|
|
|
33
|
+
#
|
|
34
|
+
=begin test
|
|
35
|
+
require 'test/unit'
|
|
36
|
+
|
|
37
|
+
class TheTest < Test::Unit::TestCase
|
|
38
|
+
def test_1
|
|
39
|
+
# Impossible to test, unless your platform is Windows.
|
|
40
|
+
assert true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
=end
|
|
45
|
+
|
|
46
|
+
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Tyler Rick
|
|
3
|
+
# Copyright:: Copyright (c) 2007 the Rails people; QualitySmith, Inc.
|
|
4
|
+
# License:: Ruby License
|
|
5
|
+
# Submit to Facets?:: Yes.
|
|
6
|
+
# Developer notes::
|
|
7
|
+
# Changes::
|
|
8
|
+
#++
|
|
9
|
+
|
|
10
|
+
require 'rubygems'
|
|
11
|
+
gem 'facets'
|
|
12
|
+
#require 'facets/core/module/alias_method_chain' # Doesn't support blocks or I'd use it.
|
|
13
|
+
require 'facets/core/kernel/singleton_class'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/module/aliasing.rb
|
|
17
|
+
class Module
|
|
18
|
+
def alias_method_chain(target, feature)
|
|
19
|
+
# Strip out punctuation on predicates or bang methods since
|
|
20
|
+
# e.g. target?_without_feature is not a valid method name.
|
|
21
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
|
22
|
+
yield(aliased_target, punctuation) if block_given?
|
|
23
|
+
alias_method "#{aliased_target}_without_#{feature}#{punctuation}", target
|
|
24
|
+
alias_method target, "#{aliased_target}_with_#{feature}#{punctuation}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
# end /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/module/aliasing.rb
|
|
28
|
+
|
|
29
|
+
class Module
|
|
30
|
+
|
|
31
|
+
def alias_method_chain_with_prevent_repeat_aliasing(target, feature, &block)
|
|
32
|
+
# Strip out punctuation on predicates or bang methods since
|
|
33
|
+
# e.g. target?_without_feature is not a valid method name.
|
|
34
|
+
|
|
35
|
+
aliased_target, punctuation = target.to_s.sub(/([?!])$/, ''), $1
|
|
36
|
+
target_without_feature = "#{aliased_target}_without_#{feature}#{punctuation}"
|
|
37
|
+
|
|
38
|
+
#puts "#{target} is #{method_defined?(target)}"
|
|
39
|
+
alias_method_chain_without_prevent_repeat_aliasing(target, feature, &block) unless method_defined?(target_without_feature)
|
|
40
|
+
end
|
|
41
|
+
alias_method_chain :alias_method_chain, :prevent_repeat_aliasing
|
|
42
|
+
|
|
43
|
+
# If you pass <tt>:create_target => true</tt> as one of the +options+:
|
|
44
|
+
# * Guarantees that <tt>alias_method_chain target, feature</tt> will work even if the target method has not been defined yet.
|
|
45
|
+
# If the target method doesn't exist yet, an empty (no-op) target method will be created.
|
|
46
|
+
# * This could come in handy for callback methods (method_added, method_missing, etc.), for instane, when you don't know if that
|
|
47
|
+
# particular callback method has been defined or not.
|
|
48
|
+
# * You want your alias_method_chain to wrap the existing method if there *is* an existing method, but to <b>not break</b> in
|
|
49
|
+
# the case that the method _doesn't_ exist.
|
|
50
|
+
def alias_method_chain_with_target_need_not_exist(target, feature, options = {}, &block)
|
|
51
|
+
create_target = options.delete(:create_target)
|
|
52
|
+
|
|
53
|
+
if create_target && true #!self.methods.include?(target)
|
|
54
|
+
self.send :define_method, target do |*args|
|
|
55
|
+
# Intentionally empty
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
alias_method_chain_without_target_need_not_exist(target, feature, &block)
|
|
60
|
+
end
|
|
61
|
+
alias_method_chain :alias_method_chain, :target_need_not_exist
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
=begin test
|
|
67
|
+
require 'test/unit'
|
|
68
|
+
|
|
69
|
+
class Test_alias_method_chain_basic < Test::Unit::TestCase
|
|
70
|
+
|
|
71
|
+
class X
|
|
72
|
+
def foo?
|
|
73
|
+
'foo?'
|
|
74
|
+
end
|
|
75
|
+
def foo_with_feature?
|
|
76
|
+
foo_without_feature? + '_with_feature'
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_question_mark
|
|
81
|
+
name, punctuation = nil, nil
|
|
82
|
+
X.instance_eval do
|
|
83
|
+
alias_method_chain :foo?, :feature do |a, b|
|
|
84
|
+
name, punctuation = a, b
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
assert_equal 'foo?_with_feature', X.new.foo?
|
|
89
|
+
assert_equal 'foo', name
|
|
90
|
+
assert_equal '?', punctuation
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
class Y
|
|
94
|
+
def foo!
|
|
95
|
+
'foo!'
|
|
96
|
+
end
|
|
97
|
+
def foo_with_feature!
|
|
98
|
+
foo_without_feature! + '_with_feature'
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def test_exclamation_mark
|
|
103
|
+
name, punctuation = nil, nil
|
|
104
|
+
Y.instance_eval do
|
|
105
|
+
alias_method_chain :foo!, :feature do |a, b|
|
|
106
|
+
name, punctuation = a, b
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
assert_equal 'foo!_with_feature', Y.new.foo!
|
|
111
|
+
assert_equal 'foo', name
|
|
112
|
+
assert_equal '!', punctuation
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
class Test_alias_method_chain_with_prevent_repeat_aliasing < Test::Unit::TestCase
|
|
118
|
+
|
|
119
|
+
class X
|
|
120
|
+
def foo
|
|
121
|
+
'foo'
|
|
122
|
+
end
|
|
123
|
+
def foo_with_feature
|
|
124
|
+
foo_without_feature + '_with_feature'
|
|
125
|
+
end
|
|
126
|
+
alias_method_chain :foo, :feature
|
|
127
|
+
alias_method_chain :foo, :feature # We want to test that this won't cause an infinite recursion (stack overflow).
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_1
|
|
131
|
+
assert_equal 'foo_with_feature', X.new.foo
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class Test_alias_method_chain_with_target_need_not_exist < Test::Unit::TestCase
|
|
138
|
+
|
|
139
|
+
# Let's assume that we are *re*-opening X here, and at this point we *don't know* if it has a foo method or not.
|
|
140
|
+
# Also, we *don't want to care*. We just want to add to the chain if the method exists, or *create* the chain
|
|
141
|
+
# if it does not yet.
|
|
142
|
+
class X
|
|
143
|
+
def foo_with_feature
|
|
144
|
+
# *Don't* do this if you're using :create_target => true:
|
|
145
|
+
# foo_without_feature + '_with_feature'
|
|
146
|
+
# If you're using :create_target => true, then you are pretty much saying "I don't know anything about thhe target method".
|
|
147
|
+
# Yet the previous statement shows that you expect it to return a String. You can't do that. You can't pretend to know
|
|
148
|
+
# anything about it's return value. It will always be nil if alias_method_chain created an empty method for you.
|
|
149
|
+
# But, it may be something else if it already existed and alias_method_chain did *not* create an empty method for you.
|
|
150
|
+
|
|
151
|
+
# The safest thing to do is to just call it and pay not attention to its return value. (Or at least *consider* the
|
|
152
|
+
# possibility that it may be nil.)
|
|
153
|
+
|
|
154
|
+
foo_without_feature
|
|
155
|
+
'feature was successfully added'
|
|
156
|
+
end
|
|
157
|
+
alias_method_chain :foo, :feature, :create_target => true
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def test_1
|
|
161
|
+
assert_equal 'feature was successfully added', X.new.foo
|
|
162
|
+
assert_equal 'feature was successfully added', X.new.foo { 'test that it works with a block' }
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
=end
|