quality_extensions 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/Readme +54 -0
  2. data/lib/qualitysmith_extensions/all.rb +4 -0
  3. data/lib/qualitysmith_extensions/array/all.rb +2 -0
  4. data/lib/qualitysmith_extensions/array/average.rb +44 -0
  5. data/lib/qualitysmith_extensions/array/classify.rb +97 -0
  6. data/lib/qualitysmith_extensions/array/expand_ranges.rb +52 -0
  7. data/lib/qualitysmith_extensions/array/group_by.rb +134 -0
  8. data/lib/qualitysmith_extensions/array/sequence.rb +66 -0
  9. data/lib/qualitysmith_extensions/array/shell_escape.rb +36 -0
  10. data/lib/qualitysmith_extensions/array/to_a_recursive.rb +41 -0
  11. data/lib/qualitysmith_extensions/array/to_query_string.rb +96 -0
  12. data/lib/qualitysmith_extensions/collection_extensions_for_cgi.rb +2 -0
  13. data/lib/qualitysmith_extensions/colored/toggleability.rb +62 -0
  14. data/lib/qualitysmith_extensions/console/command.facets.1.8.51.rb +749 -0
  15. data/lib/qualitysmith_extensions/console/command.facets.1.8.54.rb +748 -0
  16. data/lib/qualitysmith_extensions/console/command.rb +944 -0
  17. data/lib/qualitysmith_extensions/date/all.rb +2 -0
  18. data/lib/qualitysmith_extensions/date/deprecated.rb +40 -0
  19. data/lib/qualitysmith_extensions/date/iso8601.rb +31 -0
  20. data/lib/qualitysmith_extensions/date/month_ranges.rb +122 -0
  21. data/lib/qualitysmith_extensions/dir/each_child.rb +58 -0
  22. data/lib/qualitysmith_extensions/enumerable/enum.rb +69 -0
  23. data/lib/qualitysmith_extensions/enumerable/select_until.rb +4 -0
  24. data/lib/qualitysmith_extensions/enumerable/select_while.rb +109 -0
  25. data/lib/qualitysmith_extensions/exception/inspect_with_backtrace.rb +65 -0
  26. data/lib/qualitysmith_extensions/file/exact_match_regexp.rb +34 -0
  27. data/lib/qualitysmith_extensions/file_test/binary_file.rb +110 -0
  28. data/lib/qualitysmith_extensions/find/select.rb +68 -0
  29. data/lib/qualitysmith_extensions/global_variable_set.rb +153 -0
  30. data/lib/qualitysmith_extensions/hash/all.rb +2 -0
  31. data/lib/qualitysmith_extensions/hash/to_date.rb +34 -0
  32. data/lib/qualitysmith_extensions/hash/to_query_string.rb +121 -0
  33. data/lib/qualitysmith_extensions/kernel/all.rb +2 -0
  34. data/lib/qualitysmith_extensions/kernel/autoreload.rb +128 -0
  35. data/lib/qualitysmith_extensions/kernel/backtrace.rb +71 -0
  36. data/lib/qualitysmith_extensions/kernel/capture_output.rb +115 -0
  37. data/lib/qualitysmith_extensions/kernel/die.rb +49 -0
  38. data/lib/qualitysmith_extensions/kernel/example_printer.rb +81 -0
  39. data/lib/qualitysmith_extensions/kernel/filter_output.rb +108 -0
  40. data/lib/qualitysmith_extensions/kernel/remove_const.rb +178 -0
  41. data/lib/qualitysmith_extensions/kernel/remove_module.rb +127 -0
  42. data/lib/qualitysmith_extensions/kernel/require_all.rb +186 -0
  43. data/lib/qualitysmith_extensions/kernel/require_local_all.rb +4 -0
  44. data/lib/qualitysmith_extensions/kernel/require_once.rb +18 -0
  45. data/lib/qualitysmith_extensions/kernel/simulate_input.rb +52 -0
  46. data/lib/qualitysmith_extensions/kernel/trap_chain.rb +61 -0
  47. data/lib/qualitysmith_extensions/kernel/windows_platform.rb +46 -0
  48. data/lib/qualitysmith_extensions/module/alias_method.rb +6 -0
  49. data/lib/qualitysmith_extensions/module/alias_method_chain.rb +165 -0
  50. data/lib/qualitysmith_extensions/module/ancestry_of_instance_method.rb +43 -0
  51. data/lib/qualitysmith_extensions/module/attribute_accessors.rb +49 -0
  52. data/lib/qualitysmith_extensions/module/basename.rb +76 -0
  53. data/lib/qualitysmith_extensions/module/bool_attr_accessor.rb +497 -0
  54. data/lib/qualitysmith_extensions/module/class_methods.rb +87 -0
  55. data/lib/qualitysmith_extensions/module/create.rb +315 -0
  56. data/lib/qualitysmith_extensions/module/create_setter.rb +9 -0
  57. data/lib/qualitysmith_extensions/module/dirname.rb +4 -0
  58. data/lib/qualitysmith_extensions/module/guard_method.rb +312 -0
  59. data/lib/qualitysmith_extensions/module/includable_once.rb +10 -0
  60. data/lib/qualitysmith_extensions/module/join.rb +66 -0
  61. data/lib/qualitysmith_extensions/module/malias_method_chain.rb +92 -0
  62. data/lib/qualitysmith_extensions/module/module_methods.rb +4 -0
  63. data/lib/qualitysmith_extensions/module/namespace.rb +112 -0
  64. data/lib/qualitysmith_extensions/module/parents.rb +61 -0
  65. data/lib/qualitysmith_extensions/module/remove_const.rb +117 -0
  66. data/lib/qualitysmith_extensions/module/split.rb +55 -0
  67. data/lib/qualitysmith_extensions/month.rb +66 -0
  68. data/lib/qualitysmith_extensions/mutex/if_available.rb +75 -0
  69. data/lib/qualitysmith_extensions/object/ancestry_of_method.rb +257 -0
  70. data/lib/qualitysmith_extensions/object/default.rb +69 -0
  71. data/lib/qualitysmith_extensions/object/if_else.rb +157 -0
  72. data/lib/qualitysmith_extensions/object/ignore_access.rb +84 -0
  73. data/lib/qualitysmith_extensions/object/mcall.rb +92 -0
  74. data/lib/qualitysmith_extensions/object/methods.rb +63 -0
  75. data/lib/qualitysmith_extensions/object/send_if.rb +151 -0
  76. data/lib/qualitysmith_extensions/object/send_if_not_nil.rb +35 -0
  77. data/lib/qualitysmith_extensions/object/singleton_send.rb +129 -0
  78. data/lib/qualitysmith_extensions/regexp/join.rb +111 -0
  79. data/lib/qualitysmith_extensions/string/all.rb +2 -0
  80. data/lib/qualitysmith_extensions/string/constantize.rb +4 -0
  81. data/lib/qualitysmith_extensions/string/digits_only.rb +27 -0
  82. data/lib/qualitysmith_extensions/string/each_char_with_index.rb +41 -0
  83. data/lib/qualitysmith_extensions/string/md5.rb +29 -0
  84. data/lib/qualitysmith_extensions/string/shell_escape.rb +43 -0
  85. data/lib/qualitysmith_extensions/string/to_underscored_label.rb +37 -0
  86. data/lib/qualitysmith_extensions/string/with_knowledge_of_color.rb +64 -0
  87. data/lib/qualitysmith_extensions/symbol/constantize.rb +69 -0
  88. data/lib/qualitysmith_extensions/symbol/match.rb +157 -0
  89. data/lib/qualitysmith_extensions/template.rb +33 -0
  90. data/lib/qualitysmith_extensions/test/all.rb +2 -0
  91. data/lib/qualitysmith_extensions/test/assert_anything.rb +93 -0
  92. data/lib/qualitysmith_extensions/test/assert_changed.rb +66 -0
  93. data/lib/qualitysmith_extensions/test/assert_exception.rb +66 -0
  94. data/lib/qualitysmith_extensions/test/assert_includes.rb +36 -0
  95. data/lib/qualitysmith_extensions/test/assert_user_error.rb +37 -0
  96. data/lib/qualitysmith_extensions/test/difference_highlighting.rb +323 -0
  97. data/lib/qualitysmith_extensions/time/all.rb +2 -0
  98. data/lib/qualitysmith_extensions/time/deprecated.rb +31 -0
  99. data/test/all.rb +16 -0
  100. metadata +148 -0
@@ -0,0 +1,65 @@
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
+ # * Add depth argument to inspect()?
8
+ #++
9
+
10
+ require 'rubygems'
11
+ require 'facets/core/module/alias_method_chain'
12
+
13
+ class Exception
14
+ # Use this if you want to output an exception with all the details that you'd *normally* see if the exception went unrescued
15
+ # (since exception.inspect/p exception doesn't provide a backtrace!)
16
+ #
17
+ # This is mostly useful if you rescue an exception, want to print or log it and then re-raise it...
18
+ #
19
+ # Use inspect_without_backtrace if you want to access the previous behavior (<tt>#<MissingSourceFile: no such file to load -- whatever></tt>).
20
+ #
21
+ def inspect_with_backtrace
22
+ exception.class.name + ": " + exception.message + "\n" +
23
+ exception.backtrace.map {|v| ' ' + v}.join( "\n" )
24
+ end
25
+ alias_method_chain :inspect, :backtrace
26
+ end
27
+
28
+
29
+ # _____ _
30
+ # |_ _|__ ___| |_
31
+ # | |/ _ \/ __| __|
32
+ # | | __/\__ \ |_
33
+ # |_|\___||___/\__|
34
+ #
35
+ =begin test
36
+ require 'rubygems'
37
+ require 'facets/core/string/lines'
38
+
39
+ class TheTest < Test::Unit::TestCase
40
+ def raise_an_error(arg = nil)
41
+ raise ArgumentError, "You passed in the wrong argument!"
42
+ end
43
+ def test_1
44
+ begin
45
+ raise_an_error
46
+ rescue ArgumentError => exception
47
+ #puts exception.inspect
48
+ assert_equal 'ArgumentError: You passed in the wrong argument!', exception.inspect.lines[0]
49
+ assert_match /[^:]+:\d+:in `raise_an_error'/, exception.inspect.lines[1]
50
+ assert exception.inspect.lines.size > 3
51
+ end
52
+ end
53
+
54
+ end
55
+ =end
56
+
57
+
58
+ =begin
59
+ Sightings of other exception -> string formatters
60
+
61
+ log4r/formatter/formatter.rb
62
+ return "Caught #{obj.class}: #{obj.message}\n\t" +\
63
+ obj.backtrace[0...@depth].join("\n\t")
64
+
65
+ =end
@@ -0,0 +1,34 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Yes
6
+ #++
7
+
8
+ # To do:
9
+ # * Is there a more object-oriented way to do this? Instance method instead of class method?
10
+
11
+ class File
12
+ def self.exact_match_regexp(filename)
13
+ /(^|\/)#{Regexp.escape(filename)}$/
14
+ end
15
+ end
16
+
17
+ # _____ _
18
+ # |_ _|__ ___| |_
19
+ # | |/ _ \/ __| __|
20
+ # | | __/\__ \ |_
21
+ # |_|\___||___/\__|
22
+ #
23
+ =begin test
24
+
25
+ class TheTest < Test::Unit::TestCase
26
+ def test_1
27
+ assert 'bar.rb' =~ File.exact_match_regexp('bar.rb')
28
+ assert '/path/to/bar.rb' =~ File.exact_match_regexp('bar.rb')
29
+ # But:
30
+ assert 'foobar.rb' !~ File.exact_match_regexp('bar.rb')
31
+ end
32
+ end
33
+ =end
34
+
@@ -0,0 +1,110 @@
1
+ #--
2
+ # Author:: Lloyd Zusman, Tyler Rick
3
+ # Copyright:: Copyright (c) 2002-2007 Lloyd Zusman
4
+ # License:: Ruby License
5
+ # History::
6
+ # * 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)
7
+ # * 2007-03-15: Cleaned up a bit and wrote tests.
8
+ # Submit to Facets?:: Yes
9
+ #++
10
+
11
+ module FileTest
12
+
13
+ private
14
+ def self.is_text?(block)
15
+ return (block.count("^ -~", "^\b\f\t\r\n") < (block.size / 3.0) &&
16
+ block.count("\x00") < 1)
17
+ end
18
+
19
+ public
20
+ # 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
21
+ # 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
22
+ # one byte.
23
+
24
+ def self._binary_file?(filename)
25
+ size = self.size(filename)
26
+ blksize = File.stat(filename).blksize
27
+ return nil if !File.file?(filename) || size < 1
28
+ size = [size, blksize].min
29
+ begin
30
+ open(filename) {
31
+ |file|
32
+ block = file.read(size)
33
+ return !self.is_text?(block)
34
+ }
35
+ end
36
+ end
37
+
38
+ def self.binary_file?(filename)
39
+ self._binary_file?(filename)
40
+ end
41
+
42
+ def self.text_file?(filename)
43
+ return_value = self._binary_file?(filename)
44
+ if return_value.nil?
45
+ return_value
46
+ else
47
+ !return_value
48
+ end
49
+ end
50
+ end
51
+
52
+ # _____ _
53
+ # |_ _|__ ___| |_
54
+ # | |/ _ \/ __| __|
55
+ # | | __/\__ \ |_
56
+ # |_|\___||___/\__|
57
+ #
58
+ =begin test
59
+ require 'test/unit'
60
+ require 'fileutils'
61
+
62
+ class TheTest < Test::Unit::TestCase
63
+ def empty_file
64
+ File.open(filename = 'test_file', 'w') do |file|
65
+ end
66
+ yield filename
67
+ ensure
68
+ FileUtils.rm filename
69
+ end
70
+
71
+ def binary_file
72
+ File.open(filename = 'test_file', 'wb') do |file|
73
+ bin_data = [0].pack('c')*(1024)
74
+ file.write(bin_data)
75
+ end
76
+ yield filename
77
+ ensure
78
+ FileUtils.rm filename
79
+ end
80
+
81
+ def text_file
82
+ File.open(filename = 'test_file', 'w') do |file|
83
+ file.puts('Guten Tag!')
84
+ end
85
+ yield filename
86
+ ensure
87
+ FileUtils.rm filename
88
+ end
89
+
90
+ def test_empty
91
+ empty_file do |filename|
92
+ assert !FileTest.binary_file?(filename)
93
+ assert !FileTest.text_file?(filename)
94
+ end
95
+ end
96
+ def test_binary
97
+ binary_file do |filename|
98
+ assert FileTest.binary_file?(filename)
99
+ assert !FileTest.text_file?(filename)
100
+ end
101
+ end
102
+ def test_text
103
+ text_file do |filename|
104
+ assert !FileTest.binary_file?(filename)
105
+ assert FileTest.text_file?(filename)
106
+ end
107
+ end
108
+ end
109
+ =end
110
+
@@ -0,0 +1,68 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?::
6
+ # Developer notes::
7
+ # Changes::
8
+ #++
9
+
10
+
11
+ require 'find'
12
+ require 'enumerator'
13
+
14
+ module Find
15
+ # Identical to +find+ except +select+ returns the matching files as an _array_. (+find+ returns nil, which is not very useful if you actually wanted an array.)
16
+ #
17
+ # Calls the associated block with the name of every file and directory listed as arguments, then recursively on their subdirectories, and so on.
18
+ #
19
+ # Return a true (non-false) value from the block for every path that you want to be returned in the resulting array.
20
+ #
21
+ # You can still use <tt>Find.prune</tt>.
22
+ #
23
+ def self.select(*paths, &block)
24
+ Enumerable::Enumerator.new(self, :find, *paths).select{|value| yield value}
25
+ end
26
+ end
27
+
28
+
29
+
30
+
31
+
32
+
33
+ # _____ _
34
+ # |_ _|__ ___| |_
35
+ # | |/ _ \/ __| __|
36
+ # | | __/\__ \ |_
37
+ # |_|\___||___/\__|
38
+ #
39
+ =begin test
40
+ require 'test/unit'
41
+
42
+ class TheTest < Test::Unit::TestCase
43
+ # to do: would probably be safer if we *created* our own files/directories during setup, rather than expecting there to be some for us to use in cwd
44
+
45
+ def test_true
46
+ dir = '.'
47
+ files_expected = []
48
+ Find.find(dir) { |path| files_expected << path }
49
+
50
+ files = Find.select(dir) { |path| true }
51
+ assert_equal files_expected, files
52
+
53
+ # Doesn't have to be true necessarily -- can be a string
54
+ files = Find.select(dir) { |path| path }
55
+ assert_equal files_expected, files
56
+ end
57
+
58
+ def test_false
59
+ dir = '.'
60
+ files = Find.select(dir) { |path| false }
61
+
62
+ assert_equal [], files
63
+ end
64
+
65
+ end
66
+ =end
67
+
68
+
@@ -0,0 +1,153 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: No, too ugly and unreliable.
6
+ #++
7
+
8
+ module Kernel
9
+ # Gets the global variable +var+, which can either be a symbol or an actual global variable (use +:match_object+).
10
+ # global_variable_get(:$a)
11
+ # global_variable_get($a, :match_object => true)
12
+ def global_variable_get(var, options = {})
13
+ if options.delete(:match_object)
14
+ return global_variable_get(global_variable_name(var), options)
15
+ else
16
+ if var.is_a? Symbol
17
+ raise NameError.new("#{var} is not a valid global variable name") unless var.to_s[0..0] == '$'
18
+ return eval("#{var}")
19
+ else
20
+ raise ArgumentError.new("var must be a symbol unless :match_object => true")
21
+ end
22
+ end
23
+ end
24
+
25
+ # Looks up the name of global variable +var+, which must be an actual global variable.
26
+ # global_variable_name($a)
27
+ def global_variable_name(var)
28
+ global_variables.each do |test_var|
29
+ #if eval(test_var).eql?(var)
30
+ if eval(test_var).object_id == var.object_id
31
+ #$stderr.puts "Checking #{test_var}. #{eval(test_var).inspect}"
32
+ #$stderr.puts " #{$stdout.inspect}"
33
+ return test_var.to_sym
34
+ end
35
+ end
36
+ raise ArgumentError.new("The given object (#{var.inspect}) (#{var.object_id}) is not a valid global variable")
37
+ end
38
+
39
+ # Sets the global variable +var+, which can either be a symbol or an actual global variable (use +:match_object+).
40
+ # global_variable_set(:$a, 'new')
41
+ # global_variable_set($a, 'new', :match_object => true)
42
+ # global_variable_set(:$a, "StringIO.new", :eval_string => true)
43
+ def global_variable_set(var, value, options = {})
44
+ #puts "global_variable_set(#{var}, #{value.inspect}, #{options.inspect}"
45
+ if options.delete(:match_object)
46
+ return global_variable_set(global_variable_name(var), value, options)
47
+ else
48
+ if var.is_a? Symbol
49
+ raise NameError.new("#{var} is not a valid global variable name") unless var.to_s[0..0] == '$'
50
+ if options.delete(:eval_string)
51
+ #puts("About to eval: #{var} = #{value}")
52
+ eval("#{var} = #{value}")
53
+ else
54
+ marshalled_data = Marshal.dump(value)
55
+ eval("#{var} = Marshal.load(%Q<#{marshalled_data}>)")
56
+ end
57
+ return var
58
+ else
59
+ raise ArgumentError.new("var must be a symbol unless :match_object => true")
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ # _____ _
66
+ # |_ _|__ ___| |_
67
+ # | |/ _ \/ __| __|
68
+ # | | __/\__ \ |_
69
+ # |_|\___||___/\__|
70
+ #
71
+ =begin test
72
+ require 'test/unit'
73
+ require 'stringio'
74
+
75
+ class MyClass
76
+ attr_reader :data
77
+ @data = [:foo]
78
+ def ==(other)
79
+ self.data == other.data
80
+ end
81
+ end
82
+
83
+ class GlobalVariableGetTest < Test::Unit::TestCase
84
+ def test_simple
85
+ $a = 'old'
86
+ assert_equal 'old', global_variable_get(:$a)
87
+ assert_equal :$a, global_variable_name($a)
88
+ end
89
+
90
+ def test_can_pass_variable_instead_of_symbol
91
+ $a = 'old'
92
+ assert_equal 'old', global_variable_get($a, :match_object => true)
93
+
94
+ $a = :already_a_symbol
95
+ 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.
96
+ assert_nothing_raised { global_variable_get($a, :match_object => true) }
97
+ assert_equal :already_a_symbol, global_variable_get($a, :match_object => true)
98
+ assert_equal :$a, global_variable_name($a)
99
+ end
100
+
101
+ def test_error
102
+ assert_raise(NameError) { global_variable_get(:a) } # Must be :$a, not :a
103
+ end
104
+ end
105
+
106
+ class GlobalVariableSetTest < Test::Unit::TestCase
107
+ def test_simple
108
+ $a = 'old'
109
+ global_variable_set(:$a, 'new')
110
+ assert_equal('new', $a)
111
+ end
112
+
113
+ def test_can_pass_variable_instead_of_symbol
114
+ $a = 'old'
115
+ global_variable_set($a, 'new', :match_object => true)
116
+ assert_equal('new', $a)
117
+
118
+ $a = :already_a_symbol
119
+ 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.
120
+ assert_nothing_raised { global_variable_set($a, expected = :a_symbol, :match_object => true) }
121
+ global_variable_set(:$a, expected = :a_symbol)
122
+ assert_equal(expected, $a)
123
+ end
124
+
125
+ def test_returns_name_of_variable
126
+ $a = 'old'
127
+ assert_equal(:$a, global_variable_set(:$a, 'new'))
128
+
129
+ $a = 'old'
130
+ assert_equal(:$a, global_variable_set($a, 'new', :match_object => true))
131
+ end
132
+
133
+ def test_works_for_complex_data_types
134
+ $a = 'old'
135
+ global_variable_set(:$a, expected = {:a => 'a', :b => ['1', 2]})
136
+ assert_equal(expected, $a)
137
+
138
+ global_variable_set(:$a, expected = MyClass.new)
139
+ assert !expected.eql?( $a ) # :bug: The way we do it currently, they'll have different object_id's
140
+ assert_equal(expected, $a)
141
+
142
+ assert_raise(TypeError) { global_variable_set(:$a, expected = $stdout) } # "can't dump IO".
143
+ 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.
144
+ assert_nothing_raised { global_variable_set(:$a, expected = "StringIO.new", :eval_string => true) }
145
+ assert $a.is_a?(StringIO)
146
+ end
147
+
148
+ def test_error
149
+ assert_raise(NameError) { global_variable_set(:a, 'new') } # Must be :$a, not :a
150
+ end
151
+ end
152
+ =end
153
+
@@ -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,34 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # 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.
6
+ #++
7
+
8
+ require "rubygems"
9
+ require "active_support"
10
+
11
+ class Hash
12
+ # Converts a <tt>{:year => ..., :month => ..., :day => ...}</tt> hash into an actual Date object.
13
+ # Useful for when you have a date element in your <tt>params</tt> hash.
14
+ def to_date
15
+ Date.new(fetch(:year).to_i, fetch(:month).to_i, fetch(:day).to_i)
16
+ end
17
+ end
18
+
19
+ # _____ _
20
+ # |_ _|__ ___| |_
21
+ # | |/ _ \/ __| __|
22
+ # | | __/\__ \ |_
23
+ # |_|\___||___/\__|
24
+ #
25
+ =begin test
26
+ class TheTest < Test::Unit::TestCase
27
+ def test_Hash_to_date
28
+ assert_equal Date.new(2007, 1, 22), {:year => "2007", :month => "01", :day => 22}.to_date
29
+ end
30
+ def test_HashWithIndifferentAccess_to_date
31
+ assert_equal Date.new(2007, 1, 22), HashWithIndifferentAccess.new({:year => "2007", 'month' => 01, :day => 22}).to_date
32
+ end
33
+ end
34
+ =end