qualitysmith_extensions 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme +72 -0
- data/lib/qualitysmith_extensions/all.rb +2 -0
- data/lib/qualitysmith_extensions/array/all.rb +2 -0
- data/lib/qualitysmith_extensions/array/average.rb +42 -0
- data/lib/qualitysmith_extensions/array/expand_ranges.rb +48 -0
- data/lib/qualitysmith_extensions/array/group_by.rb +112 -0
- data/lib/qualitysmith_extensions/array/sequence.rb +64 -0
- data/lib/qualitysmith_extensions/array/shell_escape.rb +34 -0
- data/lib/qualitysmith_extensions/array/to_a_recursive.rb +39 -0
- data/lib/qualitysmith_extensions/array/to_query_string.rb +94 -0
- data/lib/qualitysmith_extensions/collection_extensions_for_cgi.rb +2 -0
- data/lib/qualitysmith_extensions/console/command.facets.1.8.51.rb +749 -0
- data/lib/qualitysmith_extensions/console/command.rb +940 -0
- data/lib/qualitysmith_extensions/date/all.rb +2 -0
- data/lib/qualitysmith_extensions/date/deprecated.rb +38 -0
- data/lib/qualitysmith_extensions/date/iso8601.rb +29 -0
- data/lib/qualitysmith_extensions/date/month_ranges.rb +120 -0
- data/lib/qualitysmith_extensions/enumerable/enum.rb +72 -0
- data/lib/qualitysmith_extensions/file/exact_match_regexp.rb +32 -0
- data/lib/qualitysmith_extensions/file_test/binary_file.rb +108 -0
- data/lib/qualitysmith_extensions/filter_output.rb +107 -0
- data/lib/qualitysmith_extensions/global_variable_set.rb +151 -0
- data/lib/qualitysmith_extensions/hash/all.rb +2 -0
- data/lib/qualitysmith_extensions/hash/to_date.rb +32 -0
- data/lib/qualitysmith_extensions/hash/to_query_string.rb +119 -0
- data/lib/qualitysmith_extensions/kernel/all.rb +2 -0
- data/lib/qualitysmith_extensions/kernel/backtrace.rb +69 -0
- data/lib/qualitysmith_extensions/kernel/capture_output.rb +113 -0
- data/lib/qualitysmith_extensions/kernel/die.rb +34 -0
- data/lib/qualitysmith_extensions/kernel/require_all.rb +118 -0
- data/lib/qualitysmith_extensions/kernel/require_once.rb +16 -0
- data/lib/qualitysmith_extensions/month.rb +62 -0
- data/lib/qualitysmith_extensions/object/singleton.rb +95 -0
- data/lib/qualitysmith_extensions/simulate_input.rb +51 -0
- data/lib/qualitysmith_extensions/string/all.rb +2 -0
- data/lib/qualitysmith_extensions/string/digits_only.rb +25 -0
- data/lib/qualitysmith_extensions/string/md5.rb +27 -0
- data/lib/qualitysmith_extensions/string/shell_escape.rb +41 -0
- data/lib/qualitysmith_extensions/string/to_underscored_label.rb +35 -0
- data/lib/qualitysmith_extensions/test/assert_changed.rb +64 -0
- data/lib/qualitysmith_extensions/test/assert_exception.rb +63 -0
- data/lib/qualitysmith_extensions/test/assert_includes.rb +34 -0
- data/lib/qualitysmith_extensions/test/assert_user_error.rb +34 -0
- data/lib/qualitysmith_extensions/time/all.rb +2 -0
- data/lib/qualitysmith_extensions/time/deprecated.rb +29 -0
- data/test/all.rb +16 -0
- metadata +94 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
# Author:: Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
3
|
+
# License:: Ruby License
|
4
|
+
# Submit to Facets?:: No!
|
5
|
+
|
6
|
+
# Depends on some niceties from ActiveSupport (which really should be in core Ruby but aren't)...
|
7
|
+
require "rubygems"
|
8
|
+
require "active_support"
|
9
|
+
require "pp"
|
10
|
+
|
11
|
+
class Date
|
12
|
+
# These should be moved elsewhere because they are subjective and depend on the context where they're used.
|
13
|
+
def date_for_report
|
14
|
+
strftime("%b %d, %Y") # Example: "Jun 18, 2006"
|
15
|
+
end
|
16
|
+
def month_for_report
|
17
|
+
strftime("%B %Y") # Example: "June 2006"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# _____ _
|
22
|
+
# |_ _|__ ___| |_
|
23
|
+
# | |/ _ \/ __| __|
|
24
|
+
# | | __/\__ \ |_
|
25
|
+
# |_|\___||___/\__|
|
26
|
+
#
|
27
|
+
=begin test
|
28
|
+
class TheTest < Test::Unit::TestCase
|
29
|
+
def test_date_for_report
|
30
|
+
assert_equal 'Jun 18, 2006', Date.new(2006, 6, 18).date_for_report()
|
31
|
+
assert_equal 'Jun 03, 2006', Date.new(2006, 6, 3).date_for_report()
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_month_for_report
|
35
|
+
assert_equal 'June 2006', Date.new(2006, 6).month_for_report()
|
36
|
+
end
|
37
|
+
end
|
38
|
+
=end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Author:: Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
3
|
+
# License:: Ruby License
|
4
|
+
# Submit to Facets?:: Yes.
|
5
|
+
|
6
|
+
require 'date'
|
7
|
+
require 'rubygems'
|
8
|
+
require 'facets/core/date/to_time'
|
9
|
+
|
10
|
+
class Date
|
11
|
+
def iso8601
|
12
|
+
# Useful for SQL dates, among other things
|
13
|
+
to_time().iso8601()[0..9]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# _____ _
|
18
|
+
# |_ _|__ ___| |_
|
19
|
+
# | |/ _ \/ __| __|
|
20
|
+
# | | __/\__ \ |_
|
21
|
+
# |_|\___||___/\__|
|
22
|
+
#
|
23
|
+
=begin test
|
24
|
+
class TheTest < Test::Unit::TestCase
|
25
|
+
def test_iso8601
|
26
|
+
assert_equal '2006-07-18', Date.civil(2006, 7, 18).iso8601()
|
27
|
+
end
|
28
|
+
end
|
29
|
+
=end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# Author:: Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
3
|
+
# License:: Ruby License
|
4
|
+
# Submit to Facets?:: Not sure.
|
5
|
+
|
6
|
+
# Depends on some niceties from ActiveSupport (which really should be in core Ruby but aren't)... Date.new(a, b, c)
|
7
|
+
require "rubygems"
|
8
|
+
require "active_support"
|
9
|
+
|
10
|
+
# Attempts in part to make the Date class do everything (or at least some of the things) that the Time class can do (ActiveSupport::CoreExtensions::Time::Calculations).
|
11
|
+
# Maybe that would be better accomplished with a method_missing() that calls to_time.send(:the_same_method) if Time.respond_to?(:that_method).
|
12
|
+
class Date
|
13
|
+
|
14
|
+
# This is based on the implementation of Time.step. The main difference is that it uses
|
15
|
+
# >>= (increment by 1 month) instead of += (increment by 1 day).
|
16
|
+
def month_step(max, step, &block) # { |date| ...}
|
17
|
+
time = self
|
18
|
+
op = [:-,:<=,:>=][step<=>0]
|
19
|
+
while time.__send__(op, max)
|
20
|
+
block.call time
|
21
|
+
time >>= step
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
# Step forward one month at a time until we reach max (inclusive), yielding each date as we go
|
27
|
+
def months_upto(max, &block) # { |date| ...}
|
28
|
+
month_step(max, +1, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_month
|
32
|
+
Month.new(year, month)
|
33
|
+
end
|
34
|
+
|
35
|
+
def next_month
|
36
|
+
# Uses http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Time/Calculations.html#M000336
|
37
|
+
self.to_time.next_month
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# _____ _
|
43
|
+
# |_ _|__ ___| |_
|
44
|
+
# | |/ _ \/ __| __|
|
45
|
+
# | | __/\__ \ |_
|
46
|
+
# |_|\___||___/\__|
|
47
|
+
#
|
48
|
+
=begin test
|
49
|
+
class TheTest < Test::Unit::TestCase
|
50
|
+
|
51
|
+
#-------------------------------------------------------------------------------------------------
|
52
|
+
# Ranges, step, and upto for *days*
|
53
|
+
# (This is built-in behavior.)
|
54
|
+
|
55
|
+
def test_step
|
56
|
+
list = []
|
57
|
+
collect_as_array = lambda do |date|
|
58
|
+
list << date
|
59
|
+
end
|
60
|
+
|
61
|
+
list = []
|
62
|
+
Date.new(2006, 6, 1).step(Date.new(2006, 6, 3), 1, &collect_as_array)
|
63
|
+
assert_equal [
|
64
|
+
Date.new(2006, 6, 1),
|
65
|
+
Date.new(2006, 6, 2),
|
66
|
+
Date.new(2006, 6, 3)
|
67
|
+
],
|
68
|
+
list
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_range
|
72
|
+
list = Date.new(2006, 6, 1)..Date.new(2006, 6, 3)
|
73
|
+
assert_equal Range.new(Date.new(2006, 6, 1), Date.new(2006, 6, 3)), list
|
74
|
+
end
|
75
|
+
|
76
|
+
#-------------------------------------------------------------------------------------------------
|
77
|
+
# Ranges, step, and upto for *months*
|
78
|
+
|
79
|
+
def test_month_step
|
80
|
+
list = []
|
81
|
+
collect_as_array = lambda do |date|
|
82
|
+
list << date
|
83
|
+
end
|
84
|
+
|
85
|
+
list = []
|
86
|
+
Date.new(2006, 6, 1).month_step(Date.new(2006, 7, 1), 1, &collect_as_array)
|
87
|
+
assert_equal [
|
88
|
+
Date.new(2006, 6, 1),
|
89
|
+
Date.new(2006, 7, 1)
|
90
|
+
],
|
91
|
+
list
|
92
|
+
|
93
|
+
# Test that it ignores days
|
94
|
+
list = []
|
95
|
+
Date.new(2006, 6, 1).month_step(Date.new(2006, 8, 31), 1, &collect_as_array)
|
96
|
+
assert_equal [
|
97
|
+
Date.new(2006, 6, 1),
|
98
|
+
Date.new(2006, 7, 1),
|
99
|
+
Date.new(2006, 8, 1)
|
100
|
+
],
|
101
|
+
list
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_months_upto
|
105
|
+
list = []
|
106
|
+
collect_as_array = lambda do |date|
|
107
|
+
list << date
|
108
|
+
end
|
109
|
+
|
110
|
+
list = []
|
111
|
+
Date.new(2006, 6, 1).months_upto(Date.new(2006, 7, 1), &collect_as_array)
|
112
|
+
assert_equal [
|
113
|
+
Date.new(2006, 6, 1),
|
114
|
+
Date.new(2006, 7, 1)
|
115
|
+
],
|
116
|
+
list
|
117
|
+
end
|
118
|
+
end
|
119
|
+
=end
|
120
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Author:: Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
3
|
+
# License:: Ruby License
|
4
|
+
# Submit to Facets?:: Yes!
|
5
|
+
|
6
|
+
require 'enumerator'
|
7
|
+
module Enumerable
|
8
|
+
|
9
|
+
# The core Enumerable module provides the following enumerator methods;
|
10
|
+
# * enum_cons()
|
11
|
+
# * enum_slice()
|
12
|
+
# * enum_with_index()
|
13
|
+
# but for some reason they didn't provide a generic enum() method for the cases they didn't think of!
|
14
|
+
#
|
15
|
+
# +enum+ lets you turn *any* iterator into a general-purpose Enumerator, which, according to the RDocs, is
|
16
|
+
# "A class which provides a method `each' to be used as an Enumerable object."
|
17
|
+
#
|
18
|
+
# This lets you turn any 'each'-type iterator (each_byte, each_line, ...) into a 'map'-type iterator, or into an array, etc.
|
19
|
+
#
|
20
|
+
# So if an object responds to :each_line but not to :map_lines or :lines, you could just do:
|
21
|
+
# object.enum(:each_line).map { block }
|
22
|
+
# object.enum(:each_line).to_a
|
23
|
+
# object.enum(:each_line).min
|
24
|
+
# object.enum(:each_line).grep /pattern/
|
25
|
+
#
|
26
|
+
# If no iterator is specified, :each is assumed:
|
27
|
+
# object.enum.map { block }
|
28
|
+
#
|
29
|
+
# More examples:
|
30
|
+
# Dir.new('.').enum.to_a
|
31
|
+
# #=> ['file1', 'file2']
|
32
|
+
#
|
33
|
+
# "abc".enum(:each_byte).map{|byte| byte.chr.upcase}
|
34
|
+
# #=> ["A", "B", "C"]
|
35
|
+
#
|
36
|
+
def enum(iterator = :each)
|
37
|
+
Enumerable::Enumerator.new(self, iterator)
|
38
|
+
end
|
39
|
+
# Old version, which I don't think was accurate since enum requires obj to be Enumerable as a prerequisite!:
|
40
|
+
#
|
41
|
+
# Lets you add the methods available to Enumerables to any object that responds to :each (or any other iterator).
|
42
|
+
# +enum+ returns a general-purpose Enumerator, which, according to the RDocs, is "A class which provides a method `each' to be used as an Enumerable object."
|
43
|
+
#
|
44
|
+
# This lets you use 'map'-type iterator, for example, on an object that only provides an 'each'-type iterator.
|
45
|
+
# So if an object only responds to :each, but you want to send it :map, you could just do:
|
46
|
+
end
|
47
|
+
|
48
|
+
# _____ _
|
49
|
+
# |_ _|__ ___| |_
|
50
|
+
# | |/ _ \/ __| __|
|
51
|
+
# | | __/\__ \ |_
|
52
|
+
# |_|\___||___/\__|
|
53
|
+
#
|
54
|
+
=begin test
|
55
|
+
require 'test/unit'
|
56
|
+
|
57
|
+
class TheTest < Test::Unit::TestCase
|
58
|
+
def test_1
|
59
|
+
# @options.enum(:each).map { |key, value|
|
60
|
+
# values = [value].flatten
|
61
|
+
# key +
|
62
|
+
# (values.empty? ? " #{flatten.join(' ')}" : '')
|
63
|
+
# }.join(' ')
|
64
|
+
|
65
|
+
# Yes we could use the built-in Array#map method, but...not every class that provides iterators (each, ...) provides a map().
|
66
|
+
assert_equal ['A', 'B', 'C'], ['a', 'b', 'c'].enum(:each).map {|v| v.upcase}
|
67
|
+
end
|
68
|
+
def test_2
|
69
|
+
assert Dir.new('.').enum.to_a.size > 0
|
70
|
+
end
|
71
|
+
end
|
72
|
+
=end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Author:: Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
3
|
+
# License:: Ruby License
|
4
|
+
# Submit to Facets?:: Yes
|
5
|
+
|
6
|
+
# To do:
|
7
|
+
# * Is there a more object-oriented way to do this? Instance method instead of class method?
|
8
|
+
|
9
|
+
class File
|
10
|
+
def self.exact_match_regexp(filename)
|
11
|
+
/(^|\/)#{Regexp.escape(filename)}$/
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# _____ _
|
16
|
+
# |_ _|__ ___| |_
|
17
|
+
# | |/ _ \/ __| __|
|
18
|
+
# | | __/\__ \ |_
|
19
|
+
# |_|\___||___/\__|
|
20
|
+
#
|
21
|
+
=begin test
|
22
|
+
|
23
|
+
class TheTest < Test::Unit::TestCase
|
24
|
+
def test_1
|
25
|
+
assert 'bar.rb' =~ File.exact_match_regexp('bar.rb')
|
26
|
+
assert '/path/to/bar.rb' =~ File.exact_match_regexp('bar.rb')
|
27
|
+
# But:
|
28
|
+
assert 'foobar.rb' !~ File.exact_match_regexp('bar.rb')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
=end
|
32
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# Author:: Lloyd Zusman, Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2002-2007 Lloyd Zusman
|
3
|
+
# License:: Ruby License
|
4
|
+
# History::
|
5
|
+
# * 2002-10-05: Based on code posted by Lloyd Zusman on ruby-talk on 2002-10-05 (http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/52548)
|
6
|
+
# * 2007-03-15: Cleaned up a bit and wrote tests.
|
7
|
+
# Submit to Facets?:: Yes
|
8
|
+
|
9
|
+
module FileTest
|
10
|
+
|
11
|
+
private
|
12
|
+
def self.is_text?(block)
|
13
|
+
return (block.count("^ -~", "^\b\f\t\r\n") < (block.size / 3.0) &&
|
14
|
+
block.count("\x00") < 1)
|
15
|
+
end
|
16
|
+
|
17
|
+
public
|
18
|
+
# The text_file? and binary_file? methods are not inverses of each other. Both return false if the item is not a file, or if it
|
19
|
+
# is a zero-length file. The "textness" or "binariness" of a file can only be determined if it's a file that contains at least
|
20
|
+
# one byte.
|
21
|
+
|
22
|
+
def self._binary_file?(filename)
|
23
|
+
size = self.size(filename)
|
24
|
+
blksize = File.stat(filename).blksize
|
25
|
+
return nil if !File.file?(filename) || size < 1
|
26
|
+
size = [size, blksize].min
|
27
|
+
begin
|
28
|
+
open(filename) {
|
29
|
+
|file|
|
30
|
+
block = file.read(size)
|
31
|
+
return !self.is_text?(block)
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.binary_file?(filename)
|
37
|
+
self._binary_file?(filename)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.text_file?(filename)
|
41
|
+
return_value = self._binary_file?(filename)
|
42
|
+
if return_value.nil?
|
43
|
+
return_value
|
44
|
+
else
|
45
|
+
!return_value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# _____ _
|
51
|
+
# |_ _|__ ___| |_
|
52
|
+
# | |/ _ \/ __| __|
|
53
|
+
# | | __/\__ \ |_
|
54
|
+
# |_|\___||___/\__|
|
55
|
+
#
|
56
|
+
=begin test
|
57
|
+
require 'test/unit'
|
58
|
+
require 'fileutils'
|
59
|
+
|
60
|
+
class TheTest < Test::Unit::TestCase
|
61
|
+
def empty_file
|
62
|
+
File.open(filename = 'test_file', 'w') do |file|
|
63
|
+
end
|
64
|
+
yield filename
|
65
|
+
ensure
|
66
|
+
FileUtils.rm filename
|
67
|
+
end
|
68
|
+
|
69
|
+
def binary_file
|
70
|
+
File.open(filename = 'test_file', 'wb') do |file|
|
71
|
+
bin_data = [0].pack('c')*(1024)
|
72
|
+
file.write(bin_data)
|
73
|
+
end
|
74
|
+
yield filename
|
75
|
+
ensure
|
76
|
+
FileUtils.rm filename
|
77
|
+
end
|
78
|
+
|
79
|
+
def text_file
|
80
|
+
File.open(filename = 'test_file', 'w') do |file|
|
81
|
+
file.puts('Guten Tag!')
|
82
|
+
end
|
83
|
+
yield filename
|
84
|
+
ensure
|
85
|
+
FileUtils.rm filename
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_empty
|
89
|
+
empty_file do |filename|
|
90
|
+
assert !FileTest.binary_file?(filename)
|
91
|
+
assert !FileTest.text_file?(filename)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
def test_binary
|
95
|
+
binary_file do |filename|
|
96
|
+
assert FileTest.binary_file?(filename)
|
97
|
+
assert !FileTest.text_file?(filename)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
def test_text
|
101
|
+
text_file do |filename|
|
102
|
+
assert !FileTest.binary_file?(filename)
|
103
|
+
assert FileTest.text_file?(filename)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
=end
|
108
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# Author:: Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
3
|
+
# License:: Ruby License
|
4
|
+
# Submit to Facets?:: Yes.
|
5
|
+
# Developer notes:
|
6
|
+
# * Move to kernel/?
|
7
|
+
|
8
|
+
require 'stringio'
|
9
|
+
|
10
|
+
# Applies +filter+ to any $stderr output that +block+ tries to generate.
|
11
|
+
#
|
12
|
+
# +filter+ should be a Proc that accepts +attempted_output+ as its parameter and returns the string that should _actually_ be output.
|
13
|
+
#
|
14
|
+
# filter_stderr(lambda{''}) do
|
15
|
+
# noisy_command
|
16
|
+
# end
|
17
|
+
def filter_stderr(filter, &block)
|
18
|
+
old_stderr = $stderr
|
19
|
+
$stderr = StringIO.new
|
20
|
+
begin
|
21
|
+
yield
|
22
|
+
ensure
|
23
|
+
what_they_tried_to_output = $stderr.string
|
24
|
+
$stderr = old_stderr
|
25
|
+
$stderr.print filter.call(what_they_tried_to_output)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def filter_stdout(filter, &block)
|
29
|
+
old_stderr = $stdout
|
30
|
+
$stdout = StringIO.new
|
31
|
+
begin
|
32
|
+
yield
|
33
|
+
ensure
|
34
|
+
what_they_tried_to_output = $stdout.string
|
35
|
+
$stdout = old_stderr
|
36
|
+
$stdout.print filter.call(what_they_tried_to_output)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# _____ _
|
41
|
+
# |_ _|__ ___| |_
|
42
|
+
# | |/ _ \/ __| __|
|
43
|
+
# | | __/\__ \ |_
|
44
|
+
# |_|\___||___/\__|
|
45
|
+
#
|
46
|
+
=begin test
|
47
|
+
require 'test/unit'
|
48
|
+
|
49
|
+
# Not sure whether it's better to duplicate for increased readability or metaprogram for decreased duplication...
|
50
|
+
|
51
|
+
# Duplicate for increased readability:
|
52
|
+
def noisy_command
|
53
|
+
$stderr.puts "Some annoying error message"
|
54
|
+
$stderr.puts "Some error message that we actually care to see"
|
55
|
+
end
|
56
|
+
class TheTest < Test::Unit::TestCase
|
57
|
+
def setup
|
58
|
+
$stderr = StringIO.new
|
59
|
+
end
|
60
|
+
def test_simple_filter
|
61
|
+
filter_stderr(lambda{|input| ''}) do
|
62
|
+
noisy_command
|
63
|
+
end
|
64
|
+
assert_equal '', $stderr.string
|
65
|
+
end
|
66
|
+
def test_sub_filter
|
67
|
+
filter_stderr(Proc.new { |attempted_output|
|
68
|
+
attempted_output.sub(/^Some annoying error message\n/, '')
|
69
|
+
}
|
70
|
+
) do
|
71
|
+
noisy_command
|
72
|
+
end
|
73
|
+
assert_equal "Some error message that we actually care to see\n", $stderr.string
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Metaprogram for decreased duplication...
|
78
|
+
['stdout', 'stderr'].each do |stream_name|
|
79
|
+
eval(%Q{
|
80
|
+
def noisy_command_#{stream_name}
|
81
|
+
$#{stream_name}.puts "Some annoying error message"
|
82
|
+
$#{stream_name}.puts "Some error message that we actually care to see"
|
83
|
+
end
|
84
|
+
|
85
|
+
class TheTest#{stream_name} < Test::Unit::TestCase
|
86
|
+
def setup
|
87
|
+
$#{stream_name} = StringIO.new
|
88
|
+
end
|
89
|
+
def test_simple_filter
|
90
|
+
filter_#{stream_name}(lambda{|input| ''}) do
|
91
|
+
noisy_command_#{stream_name}
|
92
|
+
end
|
93
|
+
assert_equal '', $#{stream_name}.string
|
94
|
+
end
|
95
|
+
def test_sub_filter
|
96
|
+
filter_#{stream_name}(Proc.new { |attempted_output|
|
97
|
+
attempted_output.sub(/^Some annoying error message\n/, '')
|
98
|
+
}
|
99
|
+
) do
|
100
|
+
noisy_command_#{stream_name}
|
101
|
+
end
|
102
|
+
assert_equal "Some error message that we actually care to see\n", $#{stream_name}.string
|
103
|
+
end
|
104
|
+
end
|
105
|
+
})
|
106
|
+
end
|
107
|
+
=end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# Author:: Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
3
|
+
# License:: Ruby License
|
4
|
+
# Submit to Facets?:: No, too ugly and unreliable.
|
5
|
+
|
6
|
+
module Kernel
|
7
|
+
# Gets the global variable +var+, which can either be a symbol or an actual global variable (use +:match_object+).
|
8
|
+
# global_variable_get(:$a)
|
9
|
+
# global_variable_get($a, :match_object => true)
|
10
|
+
def global_variable_get(var, options = {})
|
11
|
+
if options.delete(:match_object)
|
12
|
+
return global_variable_get(global_variable_name(var), options)
|
13
|
+
else
|
14
|
+
if var.is_a? Symbol
|
15
|
+
raise NameError.new("#{var} is not a valid global variable name") unless var.to_s[0..0] == '$'
|
16
|
+
return eval("#{var}")
|
17
|
+
else
|
18
|
+
raise ArgumentError.new("var must be a symbol unless :match_object => true")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Looks up the name of global variable +var+, which must be an actual global variable.
|
24
|
+
# global_variable_name($a)
|
25
|
+
def global_variable_name(var)
|
26
|
+
global_variables.each do |test_var|
|
27
|
+
#if eval(test_var).eql?(var)
|
28
|
+
if eval(test_var).object_id == var.object_id
|
29
|
+
#$stderr.puts "Checking #{test_var}. #{eval(test_var).inspect}"
|
30
|
+
#$stderr.puts " #{$stdout.inspect}"
|
31
|
+
return test_var.to_sym
|
32
|
+
end
|
33
|
+
end
|
34
|
+
raise ArgumentError.new("The given object (#{var.inspect}) (#{var.object_id}) is not a valid global variable")
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sets the global variable +var+, which can either be a symbol or an actual global variable (use +:match_object+).
|
38
|
+
# global_variable_set(:$a, 'new')
|
39
|
+
# global_variable_set($a, 'new', :match_object => true)
|
40
|
+
# global_variable_set(:$a, "StringIO.new", :eval_string => true)
|
41
|
+
def global_variable_set(var, value, options = {})
|
42
|
+
#puts "global_variable_set(#{var}, #{value.inspect}, #{options.inspect}"
|
43
|
+
if options.delete(:match_object)
|
44
|
+
return global_variable_set(global_variable_name(var), value, options)
|
45
|
+
else
|
46
|
+
if var.is_a? Symbol
|
47
|
+
raise NameError.new("#{var} is not a valid global variable name") unless var.to_s[0..0] == '$'
|
48
|
+
if options.delete(:eval_string)
|
49
|
+
#puts("About to eval: #{var} = #{value}")
|
50
|
+
eval("#{var} = #{value}")
|
51
|
+
else
|
52
|
+
marshalled_data = Marshal.dump(value)
|
53
|
+
eval("#{var} = Marshal.load(%Q<#{marshalled_data}>)")
|
54
|
+
end
|
55
|
+
return var
|
56
|
+
else
|
57
|
+
raise ArgumentError.new("var must be a symbol unless :match_object => true")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# _____ _
|
64
|
+
# |_ _|__ ___| |_
|
65
|
+
# | |/ _ \/ __| __|
|
66
|
+
# | | __/\__ \ |_
|
67
|
+
# |_|\___||___/\__|
|
68
|
+
#
|
69
|
+
=begin test
|
70
|
+
require 'test/unit'
|
71
|
+
require 'stringio'
|
72
|
+
|
73
|
+
class MyClass
|
74
|
+
attr_reader :data
|
75
|
+
@data = [:foo]
|
76
|
+
def ==(other)
|
77
|
+
self.data == other.data
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class GlobalVariableGetTest < Test::Unit::TestCase
|
82
|
+
def test_simple
|
83
|
+
$a = 'old'
|
84
|
+
assert_equal 'old', global_variable_get(:$a)
|
85
|
+
assert_equal :$a, global_variable_name($a)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_can_pass_variable_instead_of_symbol
|
89
|
+
$a = 'old'
|
90
|
+
assert_equal 'old', global_variable_get($a, :match_object => true)
|
91
|
+
|
92
|
+
$a = :already_a_symbol
|
93
|
+
assert_raise(NameError) { global_variable_get($a) } # If the global ($a) contains a symbol, it will assume we want to get the global variable *named* :$already_a_symbol . Wrong! That's why the :match_object option was introduced.
|
94
|
+
assert_nothing_raised { global_variable_get($a, :match_object => true) }
|
95
|
+
assert_equal :already_a_symbol, global_variable_get($a, :match_object => true)
|
96
|
+
assert_equal :$a, global_variable_name($a)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_error
|
100
|
+
assert_raise(NameError) { global_variable_get(:a) } # Must be :$a, not :a
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class GlobalVariableSetTest < Test::Unit::TestCase
|
105
|
+
def test_simple
|
106
|
+
$a = 'old'
|
107
|
+
global_variable_set(:$a, 'new')
|
108
|
+
assert_equal('new', $a)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_can_pass_variable_instead_of_symbol
|
112
|
+
$a = 'old'
|
113
|
+
global_variable_set($a, 'new', :match_object => true)
|
114
|
+
assert_equal('new', $a)
|
115
|
+
|
116
|
+
$a = :already_a_symbol
|
117
|
+
assert_raise(NameError) { global_variable_set($a, expected = :a_symbol) } # If the global ($a) contains a symbol, it will assume we want to set the global variable *named* :$already_a_symbol . Wrong! That's why the :match_object option was introduced.
|
118
|
+
assert_nothing_raised { global_variable_set($a, expected = :a_symbol, :match_object => true) }
|
119
|
+
global_variable_set(:$a, expected = :a_symbol)
|
120
|
+
assert_equal(expected, $a)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_returns_name_of_variable
|
124
|
+
$a = 'old'
|
125
|
+
assert_equal(:$a, global_variable_set(:$a, 'new'))
|
126
|
+
|
127
|
+
$a = 'old'
|
128
|
+
assert_equal(:$a, global_variable_set($a, 'new', :match_object => true))
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_works_for_complex_data_types
|
132
|
+
$a = 'old'
|
133
|
+
global_variable_set(:$a, expected = {:a => 'a', :b => ['1', 2]})
|
134
|
+
assert_equal(expected, $a)
|
135
|
+
|
136
|
+
global_variable_set(:$a, expected = MyClass.new)
|
137
|
+
assert !expected.eql?( $a ) # :bug: The way we do it currently, they'll have different object_id's
|
138
|
+
assert_equal(expected, $a)
|
139
|
+
|
140
|
+
assert_raise(TypeError) { global_variable_set(:$a, expected = $stdout) } # "can't dump IO".
|
141
|
+
assert_raise(TypeError) { global_variable_set(:$a, expected = StringIO.new) } # "no marshal_dump is defined for class StringIO". That's why the :eval_string option was introduced.
|
142
|
+
assert_nothing_raised { global_variable_set(:$a, expected = "StringIO.new", :eval_string => true) }
|
143
|
+
assert $a.is_a?(StringIO)
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_error
|
147
|
+
assert_raise(NameError) { global_variable_set(:a, 'new') } # Must be :$a, not :a
|
148
|
+
end
|
149
|
+
end
|
150
|
+
=end
|
151
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Author:: Tyler Rick
|
2
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
3
|
+
# License:: Ruby License
|
4
|
+
# Submit to Facets?:: Yes. Unless it is deemed not generally reusable enough. Also, only if we can get a Date.new(y,m,d) added to Facets.
|
5
|
+
|
6
|
+
require "rubygems"
|
7
|
+
require "active_support"
|
8
|
+
|
9
|
+
class Hash
|
10
|
+
# Converts a <tt>{:year => ..., :month => ..., :day => ...}</tt> hash into an actual Date object.
|
11
|
+
# Useful for when you have a date element in your <tt>params</tt> hash.
|
12
|
+
def to_date
|
13
|
+
Date.new(fetch(:year).to_i, fetch(:month).to_i, fetch(:day).to_i)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# _____ _
|
18
|
+
# |_ _|__ ___| |_
|
19
|
+
# | |/ _ \/ __| __|
|
20
|
+
# | | __/\__ \ |_
|
21
|
+
# |_|\___||___/\__|
|
22
|
+
#
|
23
|
+
=begin test
|
24
|
+
class TheTest < Test::Unit::TestCase
|
25
|
+
def test_Hash_to_date
|
26
|
+
assert_equal Date.new(2007, 1, 22), {:year => "2007", :month => "01", :day => 22}.to_date
|
27
|
+
end
|
28
|
+
def test_HashWithIndifferentAccess_to_date
|
29
|
+
assert_equal Date.new(2007, 1, 22), HashWithIndifferentAccess.new({:year => "2007", 'month' => 01, :day => 22}).to_date
|
30
|
+
end
|
31
|
+
end
|
32
|
+
=end
|