gorillib 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/LICENSE.textile +81 -0
  4. data/README.textile +153 -0
  5. data/Rakefile +26 -0
  6. data/VERSION +1 -0
  7. data/fiddle/hubahuba.rb +62 -0
  8. data/gorillib.gemspec +142 -0
  9. data/lib/gorillib/array/compact_blank.rb +17 -0
  10. data/lib/gorillib/array/extract_options.rb +29 -0
  11. data/lib/gorillib/base.rb +7 -0
  12. data/lib/gorillib/datetime/flat.rb +29 -0
  13. data/lib/gorillib/datetime/parse.rb +21 -0
  14. data/lib/gorillib/enumerable/sum.rb +38 -0
  15. data/lib/gorillib/hash/compact.rb +31 -0
  16. data/lib/gorillib/hash/deep_merge.rb +16 -0
  17. data/lib/gorillib/hash/keys.rb +42 -0
  18. data/lib/gorillib/hash/reverse_merge.rb +26 -0
  19. data/lib/gorillib/hash/slice.rb +53 -0
  20. data/lib/gorillib/hash/zip.rb +10 -0
  21. data/lib/gorillib/logger/log.rb +14 -0
  22. data/lib/gorillib/metaprogramming/aliasing.rb +43 -0
  23. data/lib/gorillib/metaprogramming/cattr_accessor.rb +79 -0
  24. data/lib/gorillib/metaprogramming/class_attribute.rb +90 -0
  25. data/lib/gorillib/metaprogramming/delegation.rb +146 -0
  26. data/lib/gorillib/metaprogramming/mattr_accessor.rb +61 -0
  27. data/lib/gorillib/metaprogramming/remove_method.rb +11 -0
  28. data/lib/gorillib/metaprogramming/singleton_class.rb +8 -0
  29. data/lib/gorillib/object/blank.rb +89 -0
  30. data/lib/gorillib/some.rb +12 -0
  31. data/lib/gorillib/string/constantize.rb +21 -0
  32. data/lib/gorillib/string/human.rb +52 -0
  33. data/lib/gorillib/string/inflections.rb +78 -0
  34. data/lib/gorillib/string/truncate.rb +33 -0
  35. data/lib/gorillib.rb +1 -0
  36. data/spec/blank_spec.rb +86 -0
  37. data/spec/gorillib_spec.rb +7 -0
  38. data/spec/rcov.opts +6 -0
  39. data/spec/spec.opts +4 -0
  40. data/spec/spec_helper.rb +12 -0
  41. data/spec/spec_tasks.rake +15 -0
  42. data/test/abstract_unit.rb +25 -0
  43. data/test/array/compact_blank_test.rb +33 -0
  44. data/test/array/extract_options_test.rb +39 -0
  45. data/test/datetime/flat_test.rb +0 -0
  46. data/test/datetime/parse_test.rb +0 -0
  47. data/test/enumerable/sum_test.rb +50 -0
  48. data/test/hash/compact_test.rb +38 -0
  49. data/test/hash/deep_merge_test.rb +30 -0
  50. data/test/hash/keys_test.rb +110 -0
  51. data/test/hash/reverse_merge_test.rb +20 -0
  52. data/test/hash/slice_test.rb +47 -0
  53. data/test/hash/zip_test.rb +0 -0
  54. data/test/logger/log_test.rb +0 -0
  55. data/test/metaprogramming/aliasing_test.rb +188 -0
  56. data/test/metaprogramming/cattr_accessor_test.rb +38 -0
  57. data/test/metaprogramming/class_attribute_test.rb +73 -0
  58. data/test/metaprogramming/delegation_test.rb +166 -0
  59. data/test/metaprogramming/mattr_accessor_test.rb +40 -0
  60. data/test/metaprogramming/singleton_class_test.rb +9 -0
  61. data/test/object/blank_test.rb +22 -0
  62. data/test/string/constantize_test.rb +30 -0
  63. data/test/string/human_test.rb +65 -0
  64. data/test/string/inflections_test.rb +57 -0
  65. data/test/string/inflector_test_cases.rb +50 -0
  66. data/test/string/truncate_test.rb +37 -0
  67. metadata +199 -0
@@ -0,0 +1,89 @@
1
+ class Object
2
+ ##
3
+ # Returns true if the object is nil or empty (if applicable)
4
+ #
5
+ # [].blank? #=> true
6
+ # [1].blank? #=> false
7
+ # [nil].blank? #=> false
8
+ #
9
+ # @return [TrueClass, FalseClass]
10
+ #
11
+ # @api public
12
+ def blank?
13
+ nil? || (respond_to?(:empty?) && empty?)
14
+ end
15
+ end # class Object
16
+
17
+ class Numeric
18
+ ##
19
+ # Numerics are never blank
20
+ #
21
+ # 0.blank? #=> false
22
+ # 1.blank? #=> false
23
+ # 6.54321.blank? #=> false
24
+ #
25
+ # @return [FalseClass]
26
+ #
27
+ # @api public
28
+ def blank?
29
+ false
30
+ end
31
+ end # class Numeric
32
+
33
+ class NilClass
34
+ ##
35
+ # Nil is always blank
36
+ #
37
+ # nil.blank? #=> true
38
+ #
39
+ # @return [TrueClass]
40
+ #
41
+ # @api public
42
+ def blank?
43
+ true
44
+ end
45
+ end # class NilClass
46
+
47
+ class TrueClass
48
+ ##
49
+ # True is never blank.
50
+ #
51
+ # true.blank? #=> false
52
+ #
53
+ # @return [FalseClass]
54
+ #
55
+ # @api public
56
+ def blank?
57
+ false
58
+ end
59
+ end # class TrueClass
60
+
61
+ class FalseClass
62
+ ##
63
+ # False is always blank.
64
+ #
65
+ # false.blank? #=> true
66
+ #
67
+ # @return [TrueClass]
68
+ #
69
+ # @api public
70
+ def blank?
71
+ true
72
+ end
73
+ end # class FalseClass
74
+
75
+ class String
76
+ ##
77
+ # Strips out whitespace then tests if the string is empty.
78
+ #
79
+ # "".blank? #=> true
80
+ # " ".blank? #=> true
81
+ # " hey ho ".blank? #=> false
82
+ #
83
+ # @return [TrueClass, FalseClass]
84
+ #
85
+ # @api public
86
+ def blank?
87
+ strip.empty?
88
+ end
89
+ end # class String
@@ -0,0 +1,12 @@
1
+ require 'gorillib/base'
2
+ require 'set'
3
+ require 'time'
4
+ require 'date'
5
+ require 'gorillib/array/compact_flat'
6
+ require 'gorillib/hash/compact'
7
+ require 'gorillib/enumerable/sum'
8
+ require 'gorillib/datetime/flat'
9
+ require 'gorillib/datetime/parse'
10
+ require 'gorillib/hash/zip'
11
+ require 'gorillib/hash/slice'
12
+ require 'gorillib/hash/keys'
@@ -0,0 +1,21 @@
1
+ class String
2
+
3
+ # Constantize tries to find a declared constant with the name specified
4
+ # in the string. It raises a NameError when the name is not in CamelCase
5
+ # or is not initialized.
6
+ #
7
+ # @example
8
+ # "Module".constantize #=> Module
9
+ # "Class".constantize #=> Class
10
+ #
11
+ # This is the extlib version of String#constantize, which has different
12
+ # behavior wrt using lexical context: see active_support/inflector/methods.rb
13
+ #
14
+ def constantize
15
+ unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
16
+ raise NameError, "#{self.inspect} is not a valid constant name!"
17
+ end
18
+
19
+ Object.module_eval("::#{$1}", __FILE__, __LINE__)
20
+ end unless method_defined?(:constantize)
21
+ end
@@ -0,0 +1,52 @@
1
+ require 'gorillib/string/inflections'
2
+ require 'gorillib/array/extract_options'
3
+
4
+ class String
5
+
6
+ # Capitalizes the first word and turns underscores into spaces and strips a
7
+ # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
8
+ #
9
+ # @example
10
+ # "employee_salary" #=> "Employee salary"
11
+ # "author_id" #=> "Author"
12
+ def humanize
13
+ self.gsub(/_id$/, '').tr('_', ' ').capitalize
14
+ end unless method_defined?(:humanize)
15
+
16
+ # Capitalizes all the words and replaces some characters in the string to create
17
+ # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
18
+ # used in the Rails internals.
19
+ #
20
+ # Examples:
21
+ # "man from the boondocks".titleize # => "Man From The Boondocks"
22
+ # "x-men: the last stand".titleize # => "X Men: The Last Stand"
23
+ def titleize
24
+ self.underscore.humanize.gsub(/\b('?[a-z])/){ $1.capitalize }
25
+ end unless method_defined?(:titleize)
26
+ end
27
+
28
+ class Array
29
+ # Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
30
+ # * <tt>:words_connector</tt> - The sign or word used to join the elements in arrays with two or more elements (default: ", ")
31
+ # * <tt>:two_words_connector</tt> - The sign or word used to join the elements in arrays with two elements (default: " and ")
32
+ # * <tt>:last_word_connector</tt> - The sign or word used to join the last element in arrays with three or more elements (default: ", and ")
33
+ def to_sentence(options = {})
34
+ default_words_connector = ", "
35
+ default_two_words_connector = " and "
36
+ default_last_word_connector = ", and "
37
+
38
+ options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
39
+ options.reverse_merge! :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector
40
+
41
+ case length
42
+ when 0
43
+ ""
44
+ when 1
45
+ self[0].to_s.dup
46
+ when 2
47
+ "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
48
+ else
49
+ "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
50
+ end
51
+ end unless method_defined?(:to_sentence)
52
+ end
@@ -0,0 +1,78 @@
1
+ # String inflections define new methods on the String class to transform names for different purposes.
2
+ #
3
+ # "ScaleScore".underscore # => "scale_score"
4
+ #
5
+ # This doesn't define the full set of inflections -- only
6
+ #
7
+ # * camelize
8
+ # * snakeize
9
+ # * underscore
10
+ # * demodulize
11
+ #
12
+ class String
13
+
14
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
15
+ # is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
16
+ #
17
+ # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
18
+ #
19
+ # @example:
20
+ # "active_record".camelize # => "ActiveRecord"
21
+ # "active_record".camelize(:lower) # => "activeRecord"
22
+ # "active_record/errors".camelize # => "ActiveRecord::Errors"
23
+ # "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
24
+ #
25
+ # As a rule of thumb you can think of +camelize+ as the inverse of +underscore+,
26
+ # though there are cases where that does not hold:
27
+ #
28
+ # "SSLError".underscore.camelize # => "SslError"
29
+ #
30
+ def camelize(first_letter = :upper)
31
+ camelized = self.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
32
+ (first_letter == :lower) ? (self[0..0].downcase + camelized[1..-1]) : camelized
33
+ end unless method_defined?(:camelize)
34
+
35
+ # Converts strings to snakeCase, also known as lowerCamelCase.
36
+ #
37
+ # +snakeize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
38
+ #
39
+ # @example:
40
+ # "active_record".snakeize # => "activeRecord"
41
+ # "active_record/errors".snakeize # => "activeRecord::Errors"
42
+ #
43
+ def snakeize
44
+ camelize :lower
45
+ end unless method_defined?(:snakeize)
46
+
47
+ # Makes an underscored, lowercase form from the expression in the string.
48
+ #
49
+ # +underscore+ will also change '::' to '/' to convert namespaces to paths.
50
+ #
51
+ # Examples:
52
+ # "ActiveRecord".underscore # => "active_record"
53
+ # "ActiveRecord::Errors".underscore # => active_record/errors
54
+ #
55
+ # As a rule of thumb you can think of +underscore+ as the inverse of +camelize+,
56
+ # though there are cases where that does not hold:
57
+ #
58
+ # "SSLError".underscore.camelize # => "SslError"
59
+ def underscore
60
+ word = self.dup
61
+ word.gsub!(/::/, '/')
62
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
63
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
64
+ word.tr!("-", "_")
65
+ word.downcase!
66
+ word
67
+ end unless method_defined?(:underscore)
68
+
69
+ # Removes the module part from the expression in the string
70
+ #
71
+ # @example
72
+ # "ActiveRecord::CoreExtensions::String::Inflections".demodulize #=> "Inflections"
73
+ # "Inflections".demodulize #=> "Inflections"
74
+ def demodulize
75
+ self.gsub(/^.*::/, '')
76
+ end unless method_defined?(:demodulize)
77
+
78
+ end
@@ -0,0 +1,33 @@
1
+ class String
2
+ # Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:
3
+ #
4
+ # "Once upon a time in a world far far away".truncate(27)
5
+ # # => "Once upon a time in a wo..."
6
+ #
7
+ # The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
8
+ # for a total length not exceeding <tt>:length</tt>:
9
+ #
10
+ # "Once upon a time in a world far far away".truncate(27, :separator => ' ')
11
+ # # => "Once upon a time in a..."
12
+ #
13
+ # Pass a <tt>:separator</tt> to truncate +text+ at a natural break:
14
+ #
15
+ # "And they found that many people were sleeping better.".truncate(25, :omission => "... (continued)")
16
+ # # => "And they f... (continued)"
17
+ def truncate(length, options = {})
18
+ text = self.dup
19
+ chars = text.respond_to?(:mb_chars) ? text.mb_chars : text.chars
20
+ omission = options[:omission] || "..."
21
+ omission_len = omission.respond_to?(:mb_chars) ? omission.mb_chars.length : omission.length
22
+ length_with_room_for_omission = length - omission_len
23
+
24
+ if (separator = options[:separator])
25
+ separator_chars = separator.respond_to?(:mb_chars) ? separator.to_s.mb_chars : separator.to_s.chars
26
+ stop = chars.rindex(separator_chars, length_with_room_for_omission) || length_with_room_for_omission
27
+ else
28
+ stop = length_with_room_for_omission
29
+ end
30
+
31
+ (chars.length > length ? chars[0...stop] + omission : text).to_s
32
+ end unless method_defined?(:truncate)
33
+ end
data/lib/gorillib.rb ADDED
@@ -0,0 +1 @@
1
+ require 'gorillib/base'
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+ require 'extlib/blank'
3
+
4
+ describe Object do
5
+ it 'should provide blank?' do
6
+ Object.new.should respond_to(:blank?)
7
+ end
8
+
9
+ it 'should be blank if it is nil' do
10
+ object = Object.new
11
+ class << object
12
+ def nil?; true end
13
+ end
14
+ object.should be_blank
15
+ end
16
+
17
+ it 'should be blank if it is empty' do
18
+ {}.should be_blank
19
+ [].should be_blank
20
+ end
21
+
22
+ it 'should not be blank if not nil or empty' do
23
+ Object.new.should_not be_blank
24
+ [nil].should_not be_blank
25
+ { nil => 0 }.should_not be_blank
26
+ end
27
+ end
28
+
29
+ describe Numeric do
30
+ it 'should provide blank?' do
31
+ 1.should respond_to(:blank?)
32
+ end
33
+
34
+ it 'should never be blank' do
35
+ 1.should_not be_blank
36
+ end
37
+ end
38
+
39
+ describe NilClass do
40
+ it 'should provide blank?' do
41
+ nil.should respond_to(:blank?)
42
+ end
43
+
44
+ it 'should always be blank' do
45
+ nil.should be_blank
46
+ end
47
+ end
48
+
49
+ describe TrueClass do
50
+ it 'should provide blank?' do
51
+ true.should respond_to(:blank?)
52
+ end
53
+
54
+ it 'should never be blank' do
55
+ true.should_not be_blank
56
+ end
57
+ end
58
+
59
+ describe FalseClass do
60
+ it 'should provide blank?' do
61
+ false.should respond_to(:blank?)
62
+ end
63
+
64
+ it 'should always be blank' do
65
+ false.should be_blank
66
+ end
67
+ end
68
+
69
+ describe String do
70
+ it 'should provide blank?' do
71
+ 'string'.should respond_to(:blank?)
72
+ end
73
+
74
+ it 'should be blank if empty' do
75
+ ''.should be_blank
76
+ end
77
+
78
+ it 'should be blank if it only contains whitespace' do
79
+ ' '.should be_blank
80
+ " \r \n \t ".should be_blank
81
+ end
82
+
83
+ it 'should not be blank if it contains non-whitespace' do
84
+ ' a '.should_not be_blank
85
+ end
86
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Gorillib" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1,6 @@
1
+ --exclude "spec"
2
+ --sort coverage
3
+ --callsites
4
+ --xrefs
5
+ --profile
6
+ --text-summary
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --loadby random
3
+ --format profile
4
+ --backtrace
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'gorillib'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
11
+ spec.pattern = 'spec/**/*_spec.rb'
12
+ spec.rcov = true
13
+ end
14
+
15
+ task :default => :spec
@@ -0,0 +1,25 @@
1
+ ORIG_ARGV = ARGV.dup
2
+
3
+ curr = File.expand_path(File.dirname(__FILE__))
4
+ $:.unshift(curr) unless $:.include?('curr') || $:.include?(curr)
5
+ lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
6
+ $:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
7
+
8
+ require 'test/unit'
9
+
10
+ def with_kcode(code)
11
+ if RUBY_VERSION < '1.9'
12
+ begin
13
+ old_kcode, $KCODE = $KCODE, code
14
+ yield
15
+ ensure
16
+ $KCODE = old_kcode
17
+ end
18
+ else
19
+ yield
20
+ end
21
+ end
22
+
23
+ if RUBY_VERSION < '1.9'
24
+ $KCODE = 'UTF8'
25
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__)+'/../abstract_unit'
2
+ require 'gorillib/array/compact_blank'
3
+
4
+ class ArrayCompactBlankTests < Test::Unit::TestCase
5
+
6
+ def test_compact_blank_with_empty
7
+ [ [nil], [nil, false, {}, ""] ].each do |arr|
8
+ assert_equal([], arr.compact_blank)
9
+ assert_not_equal(0, arr.length)
10
+ end
11
+ end
12
+
13
+ def test_compact_blank_bang_with_empty
14
+ assert_equal([], [].compact_blank!)
15
+ #
16
+ [ [nil], [nil, false, {}, ""] ].each do |arr|
17
+ assert_equal([], arr.compact_blank!)
18
+ assert_equal(0, arr.length)
19
+ end
20
+ end
21
+
22
+ def test_compact_blank_with_full
23
+ [ [nil, 1, nil, 2], [nil, 1, false, 2, {}, ""] ].each do |arr|
24
+ assert_equal([1, 2], arr.compact_blank)
25
+ end
26
+ end
27
+
28
+ def test_compact_blank_bang_with_full
29
+ [ [nil, 1, nil, 2], [nil, 1, false, 2, {}, ""] ].each do |arr|
30
+ assert_equal([1, 2], arr.compact_blank!)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__)+'/../abstract_unit'
2
+ require 'gorillib/array/extract_options'
3
+
4
+ class ArrayExtractOptionsTests < Test::Unit::TestCase
5
+ class HashSubclass < Hash
6
+ end
7
+
8
+ class ExtractableHashSubclass < Hash
9
+ def extractable_options?
10
+ true
11
+ end
12
+ end
13
+
14
+ def test_extract_options
15
+ assert_equal({}, [].extract_options!)
16
+ assert_equal({}, [1].extract_options!)
17
+ assert_equal({:a=>:b}, [{:a=>:b}].extract_options!)
18
+ assert_equal({:a=>:b}, [1, {:a=>:b}].extract_options!)
19
+ end
20
+
21
+ def test_extract_options_doesnt_extract_hash_subclasses
22
+ hash = HashSubclass.new
23
+ hash[:foo] = 1
24
+ array = [hash]
25
+ options = array.extract_options!
26
+ assert_equal({}, options)
27
+ assert_equal [hash], array
28
+ end
29
+
30
+ def test_extract_options_extracts_extractable_subclass
31
+ hash = ExtractableHashSubclass.new
32
+ hash[:foo] = 1
33
+ array = [hash]
34
+ options = array.extract_options!
35
+ assert_equal({:foo => 1}, options)
36
+ assert_equal [], array
37
+ end
38
+
39
+ end
File without changes
File without changes
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__)+'/../abstract_unit'
2
+ require 'gorillib/enumerable/sum'
3
+
4
+ Payment = Struct.new(:price)
5
+ class SummablePayment < Payment
6
+ def +(p) self.class.new(price + p.price) end
7
+ end
8
+
9
+ class EnumerableTests < Test::Unit::TestCase
10
+ def test_sums
11
+ assert_equal 30, [5, 15, 10].sum
12
+ assert_equal 30, [5, 15, 10].sum { |i| i }
13
+
14
+ assert_equal 'abc', %w(a b c).sum
15
+ assert_equal 'abc', %w(a b c).sum { |i| i }
16
+
17
+ payments = [ Payment.new(5), Payment.new(15), Payment.new(10) ]
18
+ assert_equal 30, payments.sum(&:price)
19
+ assert_equal 60, payments.sum { |p| p.price * 2 }
20
+
21
+ payments = [ SummablePayment.new(5), SummablePayment.new(15) ]
22
+ assert_equal SummablePayment.new(20), payments.sum
23
+ assert_equal SummablePayment.new(20), payments.sum { |p| p }
24
+ end
25
+
26
+ def test_nil_sums
27
+ expected_raise = TypeError
28
+
29
+ assert_raise(expected_raise) { [5, 15, nil].sum }
30
+
31
+ payments = [ Payment.new(5), Payment.new(15), Payment.new(10), Payment.new(nil) ]
32
+ assert_raise(expected_raise) { payments.sum(&:price) }
33
+
34
+ assert_equal 60, payments.sum { |p| p.price.to_i * 2 }
35
+ end
36
+
37
+ def test_empty_sums
38
+ assert_equal 0, [].sum
39
+ assert_equal 0, [].sum { |i| i }
40
+ assert_equal Payment.new(0), [].sum(Payment.new(0))
41
+ end
42
+
43
+ def test_enumerable_sums
44
+ assert_equal 20, (1..4).sum { |i| i * 2 }
45
+ assert_equal 10, (1..4).sum
46
+ assert_equal 10, (1..4.5).sum
47
+ assert_equal 6, (1...4).sum
48
+ assert_equal 'abc', ('a'..'c').sum
49
+ end
50
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__)+'/../abstract_unit'
2
+ require 'gorillib/hash/compact'
3
+
4
+ class HashCompactTests < Test::Unit::TestCase
5
+
6
+ def test_compact_blank_with_empty
7
+ [ { 1 => nil}, { 1 => nil, 2 => false, 3 => {}, 4 => ""} ].each do |hsh|
8
+ assert_equal({}, hsh.compact_blank)
9
+ assert_not_equal(0, hsh.length)
10
+ end
11
+ end
12
+
13
+ def test_compact_blank_with_empty
14
+ [ { 1 => nil}, { 1 => nil, 2 => false, 3 => {}, 4 => ""} ].each do |hsh|
15
+ assert_equal({}, hsh.compact_blank!)
16
+ assert_equal(0, hsh.length)
17
+ end
18
+ end
19
+
20
+ def test_compact_blank_with_full
21
+ assert_equal(
22
+ { nil => 2 },
23
+ { 1 => nil, nil => 2 }.compact_blank )
24
+ assert_equal(
25
+ { 2 => :val_2, 4 => :val_4 },
26
+ { 1 => nil, 2 => :val_2, 3 => {}, 4 => :val_4}.compact_blank )
27
+ end
28
+
29
+ def test_compact_blank_bang_with_full
30
+ assert_equal(
31
+ { nil => 2 },
32
+ { 1 => nil, nil => 2 }.compact_blank! )
33
+ assert_equal(
34
+ { 2 => :val_2, 4 => :val_4 },
35
+ { 1 => nil, 2 => :val_2, 3 => {}, 4 => :val_4}.compact_blank! )
36
+ end
37
+
38
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__)+'/../abstract_unit'
2
+ require 'gorillib/hash/deep_merge'
3
+
4
+ class HashDeepMergeTest < Test::Unit::TestCase
5
+
6
+ def test_deep_merge
7
+ hash_1 = { :a => "a", :b => "b", :c => { :c1 => "c1", :c2 => "c2", :c3 => { :d1 => "d1" } } }
8
+ hash_2 = { :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } }
9
+ expected = { :a => 1, :b => "b", :c => { :c1 => 2, :c2 => "c2", :c3 => { :d1 => "d1", :d2 => "d2" } } }
10
+ assert_equal expected, hash_1.deep_merge(hash_2)
11
+
12
+ hash_1.deep_merge!(hash_2)
13
+ assert_equal expected, hash_1
14
+ end
15
+
16
+ # def test_deep_dup
17
+ # hash = { :a => { :b => 'b' } }
18
+ # dup = hash.deep_dup
19
+ # dup[:a][:c] = 'c'
20
+ # assert_equal nil, hash[:a][:c]
21
+ # assert_equal 'c', dup[:a][:c]
22
+ # end
23
+ #
24
+ # def test_deep_dup_initialize
25
+ # zero_hash = Hash.new 0
26
+ # hash = { :a => zero_hash }
27
+ # dup = hash.deep_dup
28
+ # assert_equal 0, dup[:a][44]
29
+ # end
30
+ end