qualitysmith_extensions 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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
data/Readme ADDED
@@ -0,0 +1,72 @@
1
+ == Our Extensions Readme
2
+
3
+ == Introduction
4
+
5
+ This is a library of miscellaneous general-purpose, reusable Ruby code, quite similar in purpose and layout to {Ruby Facets}[http://facets.rubyforge.org/], but it's certainly not meant to *compete* with it!
6
+
7
+ Instead, developers are encouraged to first check if it the method or class they are looking for already exists in one of the fine existing open-source projects (like {Facets}[http://facets.rubyforge.org/] or {Extensions}[http://extensions.rubyforge.org/rdoc/index.html] or {stdlib}[http://www.ruby-doc.org/stdlib/]).
8
+
9
+ If the code you are needing hasn't already been written by someone else, then you can throw it in this library. Also submit it to an existing extensions project if you think it's any good.
10
+
11
+ Like Facets, this library contains:
12
+ * methods that add functionality to existing Ruby classes (String, Array, etc.)
13
+ * as well as new classes that aren't in core Ruby
14
+
15
+ == Installation
16
+
17
+ === Non-gem
18
+
19
+ Install the plugin from Subversion and add an svn:external to your vendor/plugins directory with this command:
20
+
21
+ ./script/plugin install -x http://code.qualitysmith.com/gemables/qualitysmith_extensions
22
+
23
+ === Gem
24
+
25
+ In your dreams.
26
+
27
+ == Usage
28
+
29
+ === In Rails (non-gem)
30
+
31
+ Install the plugin from Subversion and add an svn:external to your vendor/plugins directory with this command:
32
+
33
+ ./script/plugin install -x http://code.qualitysmith.com/gemables/qualitysmith_extensions
34
+
35
+ Put this in your config/environment.rb :
36
+
37
+ Rails::Initializer.run do |config|
38
+ config.load_paths += %W( #{RAILS_ROOT}/vendor/plugins )
39
+ end
40
+ require "qualitysmith_extensions/lib/qualitysmith_extensions/all.rb"
41
+
42
+ === Include as much or as little as you want
43
+
44
+ To load everything:
45
+
46
+ require "../path/to/qualitysmith_extensions/lib/qualitysmith_extensions/all.rb"
47
+
48
+ To load everything just for one class:
49
+
50
+ require "../path/to/qualitysmith_extensions/lib/qualitysmith_extensions/string/all.rb"
51
+
52
+ To load just an individual method:
53
+
54
+ require "../path/to/qualitysmith_extensions/lib/qualitysmith_extensions/array/average.rb"
55
+
56
+ === Gem
57
+
58
+ It's not packaged as a gem yet,... but if it were, it might work something like this?:
59
+
60
+ require "rubygems"
61
+ require_gem "qualitysmith_extensions"
62
+ require "qualitysmith_extensions/lib/qualitysmith_extensions/array/all.rb"
63
+
64
+ == Running tests
65
+
66
+ Tests are self-contained within the file for the code that is under test.
67
+
68
+ To run the tests directly, you need to use the <tt>rubytest</tt> command that is included with the {Reap}[http://reap.rubyforge.org/] tool.
69
+
70
+ If you use <tt>vim</tt>, you can set up your editor to run the tests just by typing the <tt>:Test</tt> command. To set that up, just include <tt>~/svn/devscripts/vim/include.vim</tt> .
71
+
72
+ At some point in time, we may extract them into separate files using the Reap test extractor tool.
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + "/kernel/require_all"
2
+ require_all File.dirname(__FILE__), :exclude => /[^|\/]test\//, :exclude_files => 'all.rb'
@@ -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,42 @@
1
+ # Author:: Tyler Rick
2
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
3
+ # License:: Ruby License
4
+ # Submit to Facets?:: Yes.
5
+ # Wait, so Facets has mode (http://facets.rubyforge.org/src/doc/rdoc/core/classes/Enumerable.html#M001253) but it doesn't have mean/average?
6
+ # Whether or not this Array#average is included, Facets ought to have an Enumerable#mean/average similar to mode that uses each iterator rather than Array#size. (Still might want to keep this version if it's more efficient for Arrays?)
7
+
8
+ class Array
9
+ # Calculates the arithmetic average (mean) of the elements in the array as a <tt>Float</tt>.
10
+ # irb -> [1, 3, 3].average
11
+ # => 2.33333333333333
12
+ def average
13
+ if self.size == 0
14
+ raise ZeroDivisionError
15
+ end
16
+ self.inject(0.0) do |sum, item|
17
+ sum + item.to_f
18
+ end / self.size
19
+ end
20
+ end
21
+
22
+ # _____ _
23
+ # |_ _|__ ___| |_
24
+ # | |/ _ \/ __| __|
25
+ # | | __/\__ \ |_
26
+ # |_|\___||___/\__|
27
+ #
28
+ =begin test
29
+ require 'test/unit'
30
+ class TheTest < Test::Unit::TestCase
31
+ def test_average
32
+ assert_equal 2, [0, 4].average
33
+ assert_equal Float, [0, 4].average.class
34
+
35
+ assert_equal 2.5, [0, 5].average
36
+
37
+ assert_raise ZeroDivisionError do
38
+ [].average
39
+ end
40
+ end
41
+ end
42
+ =end
@@ -0,0 +1,48 @@
1
+ # Author:: Tyler Rick
2
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
3
+ # License:: Ruby License
4
+ # Submit to Facets?:: Yes.
5
+
6
+ require 'rubygems'
7
+ require 'facets/core/kernel/silence_warnings'
8
+
9
+ class Array
10
+ # Expands (calls to_a on) all Ranges contained in this array, replacing the range with the list of elements that the range represents.
11
+ #
12
+ # [1..3, 5..7].expand_ranges
13
+ # => [1, 2, 3, 5, 6, 7]
14
+ #
15
+ def expand_ranges
16
+ new_array = []
17
+ each do |item|
18
+ silence_warnings do # Object.to_a: warning: default `to_a' will be obsolete
19
+ if item.respond_to?(:to_a)
20
+ new_array.concat item.to_a
21
+ else
22
+ new_array.concat [item]
23
+ end
24
+ end
25
+ end
26
+ new_array
27
+ end
28
+ end
29
+
30
+ # _____ _
31
+ # |_ _|__ ___| |_
32
+ # | |/ _ \/ __| __|
33
+ # | | __/\__ \ |_
34
+ # |_|\___||___/\__|
35
+ #
36
+ =begin test
37
+ require 'test/unit'
38
+ class TheTest < Test::Unit::TestCase
39
+ def test_1
40
+ assert_equal [1, 2, 3], [1, 2, 3].expand_ranges
41
+ end
42
+ def test_2
43
+ assert_equal [1, 2, 3], [1..3].expand_ranges
44
+ assert_equal [1, 2, 3, 5, 6, 7], [1..3, 5..7].expand_ranges
45
+ end
46
+ end
47
+ =end
48
+
@@ -0,0 +1,112 @@
1
+ # Author:: Tyler Rick
2
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
3
+ # License:: Ruby License
4
+ # Submit to Facets?:: Yes
5
+ # Developer notes:
6
+ # * Name is too general? Name it something to do with 'tables'?
7
+
8
+ require 'rubygems'
9
+ require_gem 'facets'
10
+ require 'facet/array/delete_values_at'
11
+ require 'facet/array/to_hash'
12
+ class Array
13
+
14
+ =begin rdoc
15
+ Breaks an array into a hash of smaller arrays, making a new group for each unique value in the specified column. Each unique value becomes a key in the hash.
16
+
17
+ Example:
18
+ [
19
+ ['a', 1],
20
+ ['a', 2],
21
+ ['b', 3],
22
+ ['b', 4],
23
+ ].group_by(0)
24
+ =>
25
+ "a"=>[[1], [2]],
26
+ "b"=>[[3], [4]]
27
+
28
+ Options:
29
+ * <tt>delete_key</tt>: deletes the key from the corresponding array if true (default true)
30
+
31
+ Example:
32
+ [
33
+ ['a', 1],
34
+ ['a', 2],
35
+ ['b', 3],
36
+ ['b', 4],
37
+ ].group_by(0, :delete_key => false)
38
+ =>
39
+ "a"=>[['a', 1], ['a', 2]],
40
+ "b"=>[['b', 3], ['b', 4]]
41
+
42
+ Notes:
43
+ * <tt>self</tt> must be in the shape of a "table" (a non-sparse, rectangular, two-dimensional array).
44
+ * This is different from the GROUP BY in SQL in that it doesn't apply an aggregate (like sum or average) to each group -- it just returns each group unmodified.
45
+
46
+ =end
47
+ def group_by(column_index, *args)
48
+ options = (if args.last.is_a?(Hash) then args.pop else {} end)
49
+ hash = {}
50
+ self.each do |row|
51
+ row_to_keep = row.dup
52
+ row_to_keep.delete_values_at(column_index) unless options[:delete_key] == false
53
+
54
+ hash[row[column_index]] ||= []
55
+ hash[row[column_index]] << row_to_keep
56
+ end
57
+ hash
58
+ end
59
+ end
60
+
61
+ # _____ _
62
+ # |_ _|__ ___| |_
63
+ # | |/ _ \/ __| __|
64
+ # | | __/\__ \ |_
65
+ # |_|\___||___/\__|
66
+ #
67
+ =begin test
68
+ class TheTest < Test::Unit::TestCase
69
+ def test_group_by
70
+ assert_equal({ }, [ ].group_by(column_index = 0))
71
+
72
+ assert_equal({
73
+ "a"=>[[1], [2]],
74
+ "b"=>[[3], [4]]
75
+ }, [
76
+ ['a', 1],
77
+ ['a', 2],
78
+ ['b', 3],
79
+ ['b', 4],
80
+ ].group_by(column_index = 0)
81
+ )
82
+ assert_equal({
83
+ "a"=>[['a', 1], ['a', 2]],
84
+ "b"=>[['b', 3], ['b', 4]]
85
+ }, [
86
+ ['a', 1],
87
+ ['a', 2],
88
+ ['b', 3],
89
+ ['b', 4],
90
+ ].group_by(column_index = 0, :delete_key => false)
91
+ )
92
+
93
+ input = [
94
+ ['Bob', "Bottle of water", 1.00],
95
+ ['Bob', "Expensive stapler", 50.00],
96
+ ['Alice', "Dinner for 2", 100.00],
97
+ ['Alice', "Bus ride to RubyConf", 50.00],
98
+ ]
99
+ assert_equal({
100
+ "Alice"=>[["Dinner for 2", 100.0], ["Bus ride to RubyConf", 50.0]],
101
+ "Bob"=>[["Bottle of water", 1.0], ["Expensive stapler", 50.0]]
102
+ }, input.group_by(column_index = 0)
103
+ )
104
+ assert_equal({
105
+ 50.0=>[["Bob", "Expensive stapler"], ["Alice", "Bus ride to RubyConf"]],
106
+ 100.0=>[["Alice", "Dinner for 2"]],
107
+ 1.0=>[["Bob", "Bottle of water"]]
108
+ }, input.group_by(column_index = 2)
109
+ )
110
+ end
111
+ end
112
+ =end
@@ -0,0 +1,64 @@
1
+ # Author:: Lance Ivy
2
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
3
+ # License:: Ruby License
4
+ # Submit to Facets?:: Not sure.
5
+
6
+ class Array
7
+ =begin rdoc
8
+ Returns the value previous to the given value. The value previous to the first is the last. Returns nil if the given value is not in the array.
9
+
10
+ Example:
11
+ sequence = ['a', 'b', 'c']
12
+ sequence.before('a') => 'c'
13
+ sequence.before('b') => 'a'
14
+ sequence.before('c') => 'b'
15
+ sequence.before('d') => nil
16
+ =end
17
+ def before(value)
18
+ return nil unless include? value
19
+ self[(index(value).to_i - 1) % length]
20
+ end
21
+
22
+ =begin rdoc
23
+ Returns the value after the given value. The value before the last is the first. Returns nil if the given value is not in the array.
24
+
25
+ Example:
26
+ sequence = ['a', 'b', 'c']
27
+ sequence.after('a') => 'b'
28
+ sequence.after('b') => 'c'
29
+ sequence.after('c') => 'a'
30
+ sequence.after('d') => nil
31
+ =end
32
+ def after(value)
33
+ return nil unless include? value
34
+ self[(index(value).to_i + 1) % length]
35
+ end
36
+ end
37
+
38
+ # _____ _
39
+ # |_ _|__ ___| |_
40
+ # | |/ _ \/ __| __|
41
+ # | | __/\__ \ |_
42
+ # |_|\___||___/\__|
43
+ #
44
+ =begin test
45
+ class TheTest < Test::Unit::TestCase
46
+ def setup
47
+ @sequence = ['a', 'b', 'c']
48
+ end
49
+
50
+ def test_before
51
+ assert_equal 'c', @sequence.before('a')
52
+ assert_equal 'a', @sequence.before('b')
53
+ assert_equal 'b', @sequence.before('c')
54
+ assert_equal nil, @sequence.before('d')
55
+ end
56
+
57
+ def test_after
58
+ assert_equal 'b', @sequence.after('a')
59
+ assert_equal 'c', @sequence.after('b')
60
+ assert_equal 'a', @sequence.after('c')
61
+ assert_equal nil, @sequence.after('d')
62
+ end
63
+ end
64
+ =end
@@ -0,0 +1,34 @@
1
+ # Author:: Tyler Rick
2
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
3
+ # License:: Ruby License
4
+ # Submit to Facets?:: Yes. Symbol#to_proc -> Facets
5
+
6
+ require 'rubygems'
7
+ require 'extensions/symbol' unless Symbol.method_defined?(:to_proc)
8
+ require 'facets/core/kernel/require_local'
9
+ require_local '../string/shell_escape.rb'
10
+
11
+ class Array
12
+ def shell_escape
13
+ self.map(&:shell_escape)
14
+ end
15
+ end
16
+
17
+ # _____ _
18
+ # |_ _|__ ___| |_
19
+ # | |/ _ \/ __| __|
20
+ # | | __/\__ \ |_
21
+ # |_|\___||___/\__|
22
+ #
23
+ =begin test
24
+ require 'test/unit'
25
+ class TheTest < Test::Unit::TestCase
26
+ def test_1
27
+ assert_equal ['a'], ['a'].shell_escape
28
+ end
29
+ def test_2
30
+ assert_equal ["arg1", "'multiple words for single argument'"],
31
+ ['arg1', 'multiple words for single argument'].shell_escape
32
+ end
33
+ end
34
+ =end
@@ -0,0 +1,39 @@
1
+ # Author:: Tyler Rick
2
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
3
+ # License:: Ruby License
4
+ # Submit to Facets?:: Yes.
5
+
6
+ class Array
7
+
8
+ # A lot like array.flatten, except that it will also "flatten" ranges (by converting range to range.to_a) and any other objects that respond to to_a contained in the array in addition to arrays contained in the array.
9
+ # Compare with Array#expand_ranges
10
+ def to_a_recursive
11
+ map do |item|
12
+ # Assume that all arrays contain only elements that do not respond to to_a_recursive or arrays.
13
+ if item.respond_to? :to_a_recursive
14
+ item.to_a_recursive
15
+ else
16
+ item.to_a
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ # _____ _
23
+ # |_ _|__ ___| |_
24
+ # | |/ _ \/ __| __|
25
+ # | | __/\__ \ |_
26
+ # |_|\___||___/\__|
27
+ #
28
+ =begin test
29
+ require 'test/unit'
30
+ class TheTest < Test::Unit::TestCase
31
+ def test_1
32
+ assert_equal [[1, 2, 3], [5, 6, 7]], [1..3, 5..7].to_a_recursive
33
+ end
34
+ def test_2
35
+ assert_equal [[1, 2, 3], [ [5, 6, 7], [9, 10] ] ], [1..3, [5..7, 9..10]].to_a_recursive
36
+ end
37
+ end
38
+ =end
39
+
@@ -0,0 +1,94 @@
1
+ # Author:: Anthony Kaufman, Tyler Rick
2
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
3
+ # License:: Ruby License
4
+ # Submit to Facets?:: Yes.
5
+
6
+ autoload :CGI, 'cgi'
7
+ class Array
8
+
9
+ =begin rdoc
10
+ Converts into a string that can be used as the {query string}[http://en.wikipedia.org/wiki/Query_string] of a URL (for example, <tt>?key[]=val1&key[]=val2</tt>).
11
+
12
+ Example:
13
+ [
14
+ 'Fred',
15
+ 'Sam'
16
+ ].to_query_string('names')
17
+ ==> "names[]=Fred&names[]=Sam"
18
+
19
+ <tt>key</tt> is the name of the key in params that will receive the array when you load the page. So, for example, if you go to page with this query string (key = "names"): <tt>?names[]=Fred&names[]=Sam</tt>, params will be have a key "names", like so: <tt>{"names"=>["Fred", "Sam"]}</tt>.
20
+ =end
21
+ def to_query_string(key)
22
+ elements = []
23
+
24
+ self.each do |value|
25
+ _key = key + '[]'
26
+ if value.is_a? Array
27
+ raise "Array#to_query_string only works on flat (1-dimensional) arrays."
28
+ elsif value.respond_to? :to_query_string
29
+ value = value.to_query_string(_key)
30
+ else
31
+ value = CGI.escape value.to_s
32
+ end
33
+ elements << _key + '=' + value
34
+ end
35
+
36
+ elements.join('&')
37
+ end
38
+ end
39
+
40
+ # _____ _
41
+ # |_ _|__ ___| |_
42
+ # | |/ _ \/ __| __|
43
+ # | | __/\__ \ |_
44
+ # |_|\___||___/\__|
45
+ #
46
+ =begin test
47
+ class TheTest < Test::Unit::TestCase
48
+ #-------------------------------------------------------------------------------------------------
49
+ # Array:
50
+
51
+ def test_array_to_query_string_trivial
52
+ data = []
53
+ assert_equal '', data.to_query_string('names')
54
+ end
55
+
56
+ def test_array_to_query_string_basic
57
+ data = [
58
+ 'Fred',
59
+ 'Sam'
60
+ ]
61
+ assert_equal 'names[]=Fred&names[]=Sam', data.to_query_string('names')
62
+ end
63
+
64
+ def test_array_to_query_string_encoding
65
+ data = ['f&r', 'a w$']
66
+
67
+ assert_equal 'foo[]=f%26r&foo[]=a+w%24', data.to_query_string('foo')
68
+ end
69
+
70
+ def test_array_to_query_string_nesting
71
+ data = [
72
+ [
73
+ 'Wilma',
74
+ 'Sara'
75
+ ],
76
+ [
77
+ 'Fred',
78
+ 'Sam'
79
+ ]
80
+ ]
81
+ assert_raise RuntimeError do data.to_query_string('names') end
82
+ end
83
+ end
84
+ =end
85
+
86
+ =begin examples
87
+ require 'irb/xmp'
88
+ xmp <<End
89
+ [
90
+ 'Fred',
91
+ 'Sam'
92
+ ].to_query_string('names')
93
+ End
94
+ =end
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/hash/to_query_string.rb'
2
+ require File.dirname(__FILE__) + '/array/to_query_string.rb'