qualitysmith_extensions 0.0.3

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 (47) hide show
  1. data/Readme +72 -0
  2. data/lib/qualitysmith_extensions/all.rb +2 -0
  3. data/lib/qualitysmith_extensions/array/all.rb +2 -0
  4. data/lib/qualitysmith_extensions/array/average.rb +42 -0
  5. data/lib/qualitysmith_extensions/array/expand_ranges.rb +48 -0
  6. data/lib/qualitysmith_extensions/array/group_by.rb +112 -0
  7. data/lib/qualitysmith_extensions/array/sequence.rb +64 -0
  8. data/lib/qualitysmith_extensions/array/shell_escape.rb +34 -0
  9. data/lib/qualitysmith_extensions/array/to_a_recursive.rb +39 -0
  10. data/lib/qualitysmith_extensions/array/to_query_string.rb +94 -0
  11. data/lib/qualitysmith_extensions/collection_extensions_for_cgi.rb +2 -0
  12. data/lib/qualitysmith_extensions/console/command.facets.1.8.51.rb +749 -0
  13. data/lib/qualitysmith_extensions/console/command.rb +940 -0
  14. data/lib/qualitysmith_extensions/date/all.rb +2 -0
  15. data/lib/qualitysmith_extensions/date/deprecated.rb +38 -0
  16. data/lib/qualitysmith_extensions/date/iso8601.rb +29 -0
  17. data/lib/qualitysmith_extensions/date/month_ranges.rb +120 -0
  18. data/lib/qualitysmith_extensions/enumerable/enum.rb +72 -0
  19. data/lib/qualitysmith_extensions/file/exact_match_regexp.rb +32 -0
  20. data/lib/qualitysmith_extensions/file_test/binary_file.rb +108 -0
  21. data/lib/qualitysmith_extensions/filter_output.rb +107 -0
  22. data/lib/qualitysmith_extensions/global_variable_set.rb +151 -0
  23. data/lib/qualitysmith_extensions/hash/all.rb +2 -0
  24. data/lib/qualitysmith_extensions/hash/to_date.rb +32 -0
  25. data/lib/qualitysmith_extensions/hash/to_query_string.rb +119 -0
  26. data/lib/qualitysmith_extensions/kernel/all.rb +2 -0
  27. data/lib/qualitysmith_extensions/kernel/backtrace.rb +69 -0
  28. data/lib/qualitysmith_extensions/kernel/capture_output.rb +113 -0
  29. data/lib/qualitysmith_extensions/kernel/die.rb +34 -0
  30. data/lib/qualitysmith_extensions/kernel/require_all.rb +118 -0
  31. data/lib/qualitysmith_extensions/kernel/require_once.rb +16 -0
  32. data/lib/qualitysmith_extensions/month.rb +62 -0
  33. data/lib/qualitysmith_extensions/object/singleton.rb +95 -0
  34. data/lib/qualitysmith_extensions/simulate_input.rb +51 -0
  35. data/lib/qualitysmith_extensions/string/all.rb +2 -0
  36. data/lib/qualitysmith_extensions/string/digits_only.rb +25 -0
  37. data/lib/qualitysmith_extensions/string/md5.rb +27 -0
  38. data/lib/qualitysmith_extensions/string/shell_escape.rb +41 -0
  39. data/lib/qualitysmith_extensions/string/to_underscored_label.rb +35 -0
  40. data/lib/qualitysmith_extensions/test/assert_changed.rb +64 -0
  41. data/lib/qualitysmith_extensions/test/assert_exception.rb +63 -0
  42. data/lib/qualitysmith_extensions/test/assert_includes.rb +34 -0
  43. data/lib/qualitysmith_extensions/test/assert_user_error.rb +34 -0
  44. data/lib/qualitysmith_extensions/time/all.rb +2 -0
  45. data/lib/qualitysmith_extensions/time/deprecated.rb +29 -0
  46. data/test/all.rb +16 -0
  47. metadata +94 -0
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + "/../kernel/require_all"
2
+ require_all File.dirname(__FILE__), :exclude_files => 'all.rb'
@@ -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,2 @@
1
+ require File.dirname(__FILE__) + "/../kernel/require_all"
2
+ require_all File.dirname(__FILE__), :exclude_files => 'all.rb'
@@ -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