ruby_core_extensions 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +14 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE +21 -0
  7. data/README.md +37 -0
  8. data/Rakefile +12 -0
  9. data/gemfiles/rails3.gemfile +11 -0
  10. data/gemfiles/rails4.gemfile +11 -0
  11. data/lib/ruby_core_extensions.rb +20 -0
  12. data/lib/ruby_core_extensions/array.rb +50 -0
  13. data/lib/ruby_core_extensions/class.rb +8 -0
  14. data/lib/ruby_core_extensions/compact.rb +2 -0
  15. data/lib/ruby_core_extensions/compact/array.rb +20 -0
  16. data/lib/ruby_core_extensions/compact/hash.rb +34 -0
  17. data/lib/ruby_core_extensions/enumerable.rb +39 -0
  18. data/lib/ruby_core_extensions/file.rb +12 -0
  19. data/lib/ruby_core_extensions/hash.rb +34 -0
  20. data/lib/ruby_core_extensions/kernel.rb +11 -0
  21. data/lib/ruby_core_extensions/numeric.rb +7 -0
  22. data/lib/ruby_core_extensions/object.rb +72 -0
  23. data/lib/ruby_core_extensions/recursive.rb +8 -0
  24. data/lib/ruby_core_extensions/recursive/array.rb +45 -0
  25. data/lib/ruby_core_extensions/recursive/big_decimal.rb +5 -0
  26. data/lib/ruby_core_extensions/recursive/date.rb +8 -0
  27. data/lib/ruby_core_extensions/recursive/date_time.rb +8 -0
  28. data/lib/ruby_core_extensions/recursive/fixnum.rb +7 -0
  29. data/lib/ruby_core_extensions/recursive/hash.rb +86 -0
  30. data/lib/ruby_core_extensions/recursive/object.rb +17 -0
  31. data/lib/ruby_core_extensions/recursive/time.rb +8 -0
  32. data/lib/ruby_core_extensions/string.rb +78 -0
  33. data/lib/ruby_core_extensions/version.rb +3 -0
  34. data/ruby_core_extensions.gemspec +32 -0
  35. data/spec/array_spec.rb +67 -0
  36. data/spec/class_spec.rb +12 -0
  37. data/spec/compact_spec.rb +49 -0
  38. data/spec/enumerable_spec.rb +24 -0
  39. data/spec/filename_spec.rb +17 -0
  40. data/spec/hash_spec.rb +107 -0
  41. data/spec/numeric_spec.rb +12 -0
  42. data/spec/object_spec.rb +58 -0
  43. data/spec/spec_helper.rb +17 -0
  44. data/spec/string_spec.rb +62 -0
  45. data/spec/support/coverage.rb +29 -0
  46. metadata +225 -0
@@ -0,0 +1,8 @@
1
+ require 'ruby_core_extensions/recursive/array'
2
+ require 'ruby_core_extensions/recursive/big_decimal'
3
+ require 'ruby_core_extensions/recursive/date'
4
+ require 'ruby_core_extensions/recursive/date_time'
5
+ require 'ruby_core_extensions/recursive/fixnum'
6
+ require 'ruby_core_extensions/recursive/hash'
7
+ require 'ruby_core_extensions/recursive/object'
8
+ require 'ruby_core_extensions/recursive/time'
@@ -0,0 +1,45 @@
1
+ class Array
2
+
3
+ def convert
4
+ self
5
+ end
6
+
7
+ def convert_keys_recursively(&converter)
8
+ map { |v| v.convert_keys_recursively(&converter) }
9
+ end
10
+
11
+ def convert_values_recursively(&converter)
12
+ map { |v| v.convert_values_recursively(&converter) }
13
+ end
14
+
15
+ def symbolize_keys_recursively
16
+ map(&:symbolize_keys_recursively)
17
+ end
18
+
19
+ def stringify_values_recursively
20
+ map(&:stringify_values_recursively)
21
+ end
22
+
23
+ def make_indifferent_access_recursively
24
+ map(&:make_indifferent_access_recursively)
25
+ end
26
+
27
+ def recursive_blank?
28
+ each do |v|
29
+ if v.respond_to?(:recursive_blank?)
30
+ return false unless v.recursive_blank?
31
+ else
32
+ return false unless v.blank?
33
+ end
34
+ end
35
+ true
36
+ end
37
+
38
+ def recursively(&block)
39
+ each do |element|
40
+ block.call(element)
41
+ element.recursively(&block) if element.respond_to?(:recursively)
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,5 @@
1
+ class BigDecimal
2
+ def stringify_values_recursively
3
+ self.to_s
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ class Date
2
+
3
+ def stringify_values_recursively
4
+ self.to_s
5
+ end
6
+
7
+ end
8
+
@@ -0,0 +1,8 @@
1
+ class DateTime
2
+
3
+ def stringify_values_recursively
4
+ self.to_s
5
+ end
6
+
7
+ end
8
+
@@ -0,0 +1,7 @@
1
+ class Fixnum
2
+
3
+ def stringify_values_recursively
4
+ to_s
5
+ end
6
+
7
+ end
@@ -0,0 +1,86 @@
1
+ class Hash
2
+
3
+ def recursive_blank?
4
+ each do |k, v|
5
+ if v.respond_to?(:recursive_blank?)
6
+ return false unless v.recursive_blank?
7
+ else
8
+ return false unless v.blank?
9
+ end
10
+ end
11
+ true
12
+ end
13
+
14
+ def convert
15
+ self
16
+ end
17
+
18
+ def convert_keys(&converter)
19
+ inject({}) do |hash, (key, value)|
20
+ hash[converter.call(key)] = value
21
+ hash
22
+ end
23
+ end
24
+
25
+ def convert_values(*keys, &converter)
26
+ inject(clone) do |hash, (key, value)|
27
+ hash[key] = value.convert(&converter) if keys.blank? || keys.include?(key)
28
+ hash
29
+ end
30
+ end
31
+
32
+ def convert_keys_recursively(&converter)
33
+ Hash[map do |key, value|
34
+ k = converter.call(key)
35
+ v = value.convert_keys_recursively(&converter)
36
+ [k,v]
37
+ end]
38
+ end
39
+
40
+ def convert_values_recursively(&converter)
41
+ inject({}) do |hash, (key, value)|
42
+ hash[key] = value.convert_values_recursively(&converter)
43
+ hash
44
+ end
45
+ end
46
+
47
+ def symbolize_keys_recursively
48
+ Hash[map do |key, value|
49
+ k = key.is_a?(String) ? key.to_sym : key
50
+ v = value.symbolize_keys_recursively
51
+ [k,v]
52
+ end]
53
+ end
54
+
55
+ def stringify_values_recursively
56
+ inject({}) do |options, (key, value)|
57
+ options[key] = value.stringify_values_recursively
58
+ options
59
+ end
60
+ end
61
+
62
+ def make_indifferent_access_recursively
63
+ HashWithIndifferentAccess.new(inject({}) do |options, (key, value)|
64
+ options[key] = value.make_indifferent_access_recursively
65
+ options
66
+ end)
67
+ end
68
+
69
+ def deep_dup
70
+ duplicate = self.dup
71
+ duplicate.each_pair do |k,v|
72
+ tv = duplicate[k]
73
+ duplicate[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_dup : v
74
+ end
75
+ duplicate
76
+ end
77
+
78
+ def recursively(&block)
79
+ each do |key,value|
80
+ block.call(key,value)
81
+ value.recursively(&block) if value.respond_to?(:recursively)
82
+ end
83
+ end
84
+
85
+ end
86
+
@@ -0,0 +1,17 @@
1
+ class Object
2
+ def convert(&converter)
3
+ converter.call(self)
4
+ end
5
+
6
+ def return_self
7
+ self
8
+ end
9
+
10
+ alias_method :convert_values_recursively, :convert
11
+ alias_method :convert_recursively, :convert
12
+
13
+ alias_method :convert_keys_recursively, :return_self
14
+ alias_method :symbolize_keys_recursively, :return_self
15
+ alias_method :stringify_values_recursively, :return_self
16
+ alias_method :make_indifferent_access_recursively, :return_self
17
+ end
@@ -0,0 +1,8 @@
1
+ class Time
2
+
3
+ def stringify_values_recursively
4
+ self.to_s
5
+ end
6
+
7
+ end
8
+
@@ -0,0 +1,78 @@
1
+ class String
2
+ def proper_underscore
3
+ self.titleize.gsub(" ","").underscore
4
+ end
5
+
6
+ # Generate a phonetic code - which is the same for similar sounding names
7
+ def phonetic_code
8
+ # Currently using 'metaphone' which is more accurate than soundex
9
+ Text::Metaphone.metaphone(self)
10
+ end
11
+
12
+ # Solr requires numbers and letters to be separated
13
+ def separate_numbers_and_letters
14
+ gsub(/[a-z][0-9]|[0-9][a-z]/i){ |s| s[0].chr + ' ' + s[1].chr }
15
+ end
16
+
17
+ # convert newlines to breaks
18
+ def nl2br
19
+ gsub(/\n/, '<br />')
20
+ end
21
+
22
+ # Squash will reduce words from the end of the string to 3 characters until it
23
+ # fits within the limit, shrinking all words evenly.
24
+ # Where not all words can be shrunk evenly, the last words will be reduced by 1
25
+ # Until within the limit
26
+ # e.g.
27
+ # "Adelaide University".squash(30)
28
+ # => "Adelaide University"
29
+ # "Adelaide University".squash(10)
30
+ # => "Adela Univ"
31
+ # "Adelaide University".squash(7)
32
+ # => "Ade Uni"
33
+ # "Adelaide University".squash(3)
34
+ # => "AU"
35
+ # "Adelaide University".squash(2)
36
+ # => "AU"
37
+ # "Adelaide University".squash(1)
38
+ # => "A"
39
+ def squash(limit)
40
+ return self if size <= limit
41
+
42
+ words = split(' ')
43
+
44
+ # Return first letter of <limit> words
45
+ return words.first(limit).map{|w| w.chars.first}.join if (words.size * 2 - 1) >= limit
46
+
47
+ spaces = words.size - 1
48
+ word_char_min = (limit - spaces) / words.size
49
+ word_char_max = word_char_min + 1
50
+
51
+ words = words.map{|word| word[0..(word_char_max - 1)]}
52
+
53
+ words.reverse.each.with_index do |word, index|
54
+ letters_to_remove = words.join(' ').size - limit
55
+
56
+ letters_to_keep = if (last_case = (letters_to_remove <= (word.size - word_char_min)))
57
+ word.size - letters_to_remove # Removing final characters
58
+ else
59
+ word_char_min
60
+ end
61
+
62
+ # Replace word
63
+ words[words.size - index - 1] = word[0..(letters_to_keep - 1)]
64
+
65
+ break if last_case
66
+ end
67
+
68
+ words.join(' ')
69
+ end
70
+
71
+
72
+ def to_bool
73
+ return true if self == true || self =~ (/(true|t|yes|y|1)$/i)
74
+ return false if self == false || self.blank? || self =~ (/(false|f|no|n|0)$/i)
75
+ raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
76
+ end
77
+ end
78
+
@@ -0,0 +1,3 @@
1
+ module RubyCoreExtensions
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ruby_core_extensions/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'ruby_core_extensions'
8
+ spec.version = RubyCoreExtensions::VERSION
9
+ spec.authors = ['Michael Noack', 'Alessandro Berardi']
10
+ spec.email = 'development@travellink.com.au'
11
+ spec.description = 'These are extensions from core ruby classes.'
12
+ spec.summary = 'Set of extensions to core ruby libraries used by TravelLink Technology.'
13
+ spec.homepage = 'http://github.com/sealink/ruby_core_extensions'
14
+
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency 'activesupport', '>= 2.0'
23
+ spec.add_dependency 'tzinfo'
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency 'rspec'
28
+ spec.add_development_dependency 'simplecov'
29
+ spec.add_development_dependency 'simplecov-rcov'
30
+ spec.add_development_dependency 'coveralls'
31
+ spec.add_development_dependency 'travis'
32
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Array do
4
+
5
+ it "should allow converting all values to strings recursively" do
6
+ @now = Time.now
7
+ expect([1, 2, @now, [3, 4]].stringify_values_recursively).to eq ['1', '2', @now.to_s, ['3', '4']]
8
+ end
9
+
10
+ it "should allow removing all blank values" do
11
+ a = [1, nil, 3, '']
12
+ a.compact_blank!
13
+ expect(a).to eq [1, 3]
14
+ end
15
+
16
+ it "should allow removing all blank values recursively" do
17
+ a = [1, 2, [" Kan", {}], nil, {:a => "", :b => {}}, ["garoos", " "]]
18
+ a.recursive_compact_blank!
19
+ expect(a.join).to eq "12 Kangaroos"
20
+ end
21
+
22
+ it "should allow verifying if all elements are blank recursively" do
23
+ expect(['',nil,[nil,['']]]).to be_recursive_blank
24
+ expect(['',nil,[nil,['',1]]]).to_not be_recursive_blank
25
+ end
26
+
27
+ it "should allow converting to hash given a key" do
28
+ expect([1,2,3].hash_by(:ordinalize)).to eq({'1st' => 1, "2nd" => 2, "3rd" => 3})
29
+ expect([1,2,3].hash_by(:ordinalize, :to_s)).to eq({'1st' => '1', "2nd" => '2', "3rd" => '3'})
30
+ expect([1,2,3].hash_by(:ordinalize){ |v| v + 1 }).to eq({'1st' => 2, "2nd" => 3, "3rd" => 4})
31
+ expect([1,2,3].hash_by{|k| k * 2}).to eq({2 => 1, 4 => 2, 6 => 3})
32
+ end
33
+
34
+ it "should allow executing blocks recursively" do
35
+ array = [1,[2,3],[4,[5,6],7,[8]],9,[[10]]]
36
+ result = []
37
+ array.recursively do |e|
38
+ result << e unless e.is_a?(Array)
39
+ end
40
+ expect(result).to eq [1,2,3,4,5,6,7,8,9,10]
41
+ end
42
+
43
+ it '#intersects?' do
44
+ array1 = [1, 2, 3]
45
+ array2 = [3, 4, 5]
46
+ array3 = [6, 7, 8]
47
+
48
+ expect(array1.intersects?(array2)).to be true
49
+ expect(array1.intersects?(array3)).to be false
50
+ expect(array2.intersects?(array3)).to be false
51
+
52
+ array1same = [1, 2, 3]
53
+ expect(array1.intersects?(array1same)).to be true
54
+ end
55
+
56
+ it '#first' do
57
+ expect(Array.first([])).to be nil
58
+ expect(Array.first([4, 2])).to eq 4
59
+ expect(Array.first(4)).to eq 4
60
+ end
61
+
62
+ it '#last' do
63
+ expect(Array.last([])).to be nil
64
+ expect(Array.last([4, 2])).to eq 2
65
+ expect(Array.last(4)).to eq 4
66
+ end
67
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Class do
4
+
5
+ it 'should downcase class name to symbol' do
6
+ class CamelCaseClass; end
7
+
8
+ expect(Object.downcase_symbol).to eq :object
9
+ expect(CamelCaseClass.downcase_symbol).to eq :camelcaseclass
10
+ end
11
+
12
+ end
@@ -0,0 +1,49 @@
1
+ describe Array, 'compact' do
2
+ it 'should compact blank' do
3
+ a = [1, nil, 3]
4
+ a.compact_blank!
5
+ expect(a).to eq [1, 3]
6
+ end
7
+
8
+ it 'should recursive compact blank' do
9
+ a = [1, nil, {:a => nil, :b => 2}]
10
+ a.recursive_compact_blank!
11
+ expect(a).to eq [1, {:b => 2}]
12
+
13
+ b = [1, nil, {:a => nil}]
14
+ b.recursive_compact_blank!
15
+ expect(b).to eq [1]
16
+ end
17
+ end
18
+
19
+ describe Hash, 'compact' do
20
+ it 'should compact' do
21
+ expect({:a => 1, :b => nil}.compact).to eq({:a => 1})
22
+ end
23
+
24
+ it 'should compact!' do
25
+ a = {:a => 1, :b => nil}
26
+ a.compact!
27
+ expect(a).to eq({:a => 1})
28
+ end
29
+
30
+ it 'should compact blank' do
31
+ expect({:a => 1, :b => ''}.compact_blank).to eq({:a => 1})
32
+ end
33
+
34
+ it 'should compact blank!' do
35
+ a = {:a => 1, :b => ''}
36
+ a.compact_blank!
37
+ expect(a).to eq({:a => 1})
38
+ end
39
+
40
+ it 'should recursive compact blank!' do
41
+ a = {:a => 1, :b => {:c => 1, :d => ''}}
42
+ a.recursive_compact_blank!
43
+ expect(a).to eq({:a => 1, :b => {:c => 1}})
44
+
45
+ a = {:a => 1, :b => {:c => [], :d => ''}}
46
+ a.recursive_compact_blank!
47
+ expect(a).to eq({:a => 1})
48
+ end
49
+ end