more_core_extensions 1.0.0

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 (33) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +63 -0
  7. data/Rakefile +6 -0
  8. data/lib/more_core_extensions/all.rb +5 -0
  9. data/lib/more_core_extensions/core_ext/array/duplicates.rb +11 -0
  10. data/lib/more_core_extensions/core_ext/array/inclusions.rb +33 -0
  11. data/lib/more_core_extensions/core_ext/array/random.rb +19 -0
  12. data/lib/more_core_extensions/core_ext/array/stretch.rb +49 -0
  13. data/lib/more_core_extensions/core_ext/array/tableize.rb +89 -0
  14. data/lib/more_core_extensions/core_ext/array.rb +5 -0
  15. data/lib/more_core_extensions/core_ext/hash/deletes.rb +19 -0
  16. data/lib/more_core_extensions/core_ext/hash/nested.rb +56 -0
  17. data/lib/more_core_extensions/core_ext/hash.rb +2 -0
  18. data/lib/more_core_extensions/core_ext/string/formats.rb +41 -0
  19. data/lib/more_core_extensions/core_ext/string/hex_dump.rb +55 -0
  20. data/lib/more_core_extensions/core_ext/string.rb +2 -0
  21. data/lib/more_core_extensions/version.rb +3 -0
  22. data/lib/more_core_extensions.rb +1 -0
  23. data/more_core_extensions.gemspec +27 -0
  24. data/spec/core_ext/array/duplicates_spec.rb +11 -0
  25. data/spec/core_ext/array/inclusions_spec.rb +33 -0
  26. data/spec/core_ext/array/stretch_spec.rb +96 -0
  27. data/spec/core_ext/array/tableize_spec.rb +158 -0
  28. data/spec/core_ext/hash/deletes_spec.rb +17 -0
  29. data/spec/core_ext/hash/nested_spec.rb +125 -0
  30. data/spec/core_ext/string/formats_spec.rb +63 -0
  31. data/spec/core_ext/string/hex_dump_spec.rb +86 -0
  32. data/spec/spec_helper.rb +21 -0
  33. metadata +175 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.2"
4
+ - "1.9.3"
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ - rbx-19mode
7
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in more_core_extensions.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Red Hat, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # MoreCoreExtensions
2
+
3
+ MoreCoreExtensions are a set of core extensions beyond those provided by ActiveSupport.
4
+
5
+ [![Build Status](https://travis-ci.org/ManageIQ/more_core_extensions.png?branch=master)](https://travis-ci.org/ManageIQ/more_core_extensions)
6
+ [![Code Climate](https://codeclimate.com/github/ManageIQ/more_core_extensions.png)](https://codeclimate.com/github/ManageIQ/more_core_extensions)
7
+ [![Coverage Status](https://coveralls.io/repos/ManageIQ/more_core_extensions/badge.png)](https://coveralls.io/r/ManageIQ/more_core_extensions)
8
+ [![Dependency Status](https://gemnasium.com/ManageIQ/more_core_extensions.png)](https://gemnasium.com/ManageIQ/more_core_extensions)
9
+
10
+ ## Extensions Provided
11
+
12
+ * Array
13
+ * duplicates
14
+ * include_any?
15
+ * include_none?
16
+ * include_all?
17
+ * random_index
18
+ * random_element
19
+ * stretch
20
+ * stretch!
21
+ * zip_stretched
22
+ * tableize
23
+ * Hash
24
+ * delete_nils
25
+ * delete_blanks
26
+ * fetch_path
27
+ * has_key_path?
28
+ * include_path?
29
+ * key_path?
30
+ * member_path?
31
+ * store_path
32
+ * delete_path
33
+ * String
34
+ * email?
35
+ * domain_name?
36
+ * ipv4?
37
+ * ipv6?
38
+ * ipaddress?
39
+ * integer?
40
+ * guid?
41
+ * hex_dump
42
+
43
+ ## Installation
44
+
45
+ Add this line to your application's Gemfile:
46
+
47
+ gem 'more_core_extensions'
48
+
49
+ And then execute:
50
+
51
+ $ bundle
52
+
53
+ Or install it yourself as:
54
+
55
+ $ gem install more_core_extensions
56
+
57
+ ## Contributing
58
+
59
+ 1. Fork it
60
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
61
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
62
+ 4. Push to the branch (`git push origin my-new-feature`)
63
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new('spec')
5
+ task :test => :spec
6
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ require 'more_core_extensions/version'
2
+
3
+ require 'more_core_extensions/core_ext/array'
4
+ require 'more_core_extensions/core_ext/hash'
5
+ require 'more_core_extensions/core_ext/string'
@@ -0,0 +1,11 @@
1
+ module MoreCoreExtensions::ArrayDuplicates
2
+ #
3
+ # Returns an Array of the duplicates found.
4
+ #
5
+ # [1, 2, 3, 4, 2, 4].duplicates #=> [2, 4]
6
+ def duplicates
7
+ self.inject(Hash.new(0)) { |h, v| h[v] += 1; h }.reject { |k, v| v == 1 }.keys
8
+ end
9
+ end
10
+
11
+ Array.send(:include, MoreCoreExtensions::ArrayDuplicates)
@@ -0,0 +1,33 @@
1
+ module MoreCoreExtensions::ArrayInclusions
2
+ #
3
+ # Returns whether the Array contains any of the items.
4
+ #
5
+ # [1, 2, 3].include_any?(1, 2) #=> true
6
+ # [1, 2, 3].include_any?(1, 4) #=> true
7
+ # [1, 2, 3].include_any?(4, 5) #=> false
8
+ def include_any?(*items)
9
+ !(self & items).empty?
10
+ end
11
+
12
+ #
13
+ # Returns whether the Array contains none of the items.
14
+ #
15
+ # [1, 2, 3].include_none?(1, 2) #=> false
16
+ # [1, 2, 3].include_none?(1, 4) #=> false
17
+ # [1, 2, 3].include_none?(4, 5) #=> true
18
+ def include_none?(*items)
19
+ (self & items).empty?
20
+ end
21
+
22
+ #
23
+ # Returns whether the Array contains all of the items.
24
+ #
25
+ # [1, 2, 3].include_all?(1, 2) #=> true
26
+ # [1, 2, 3].include_all?(1, 4) #=> false
27
+ # [1, 2, 3].include_all?(4, 5) #=> false
28
+ def include_all?(*items)
29
+ (items - self).empty?
30
+ end
31
+ end
32
+
33
+ Array.send(:include, MoreCoreExtensions::ArrayInclusions)
@@ -0,0 +1,19 @@
1
+ module MoreCoreExtensions::ArrayRandom
2
+ #
3
+ # Picks a valid index randomly
4
+ #
5
+ # [1, 2, 3, 4, 2, 4].random_index #=> random number between 0..5
6
+ def random_index
7
+ rand(self.size)
8
+ end
9
+
10
+ #
11
+ # Picks an element randomly
12
+ #
13
+ # [1, 2, 3, 4, 2, 4].random_element #=> any randomly selected element in Array
14
+ def random_element
15
+ self[self.random_index]
16
+ end
17
+ end
18
+
19
+ Array.send(:include, MoreCoreExtensions::ArrayRandom)
@@ -0,0 +1,49 @@
1
+ module MoreCoreExtensions::ArrayStretch
2
+ module ClassMethods
3
+ # Stretch all argument Arrays to make them the same size.
4
+ #
5
+ # Array.stretch([1, 2], [3, 4], [5, 6, 7]) #=> [[1, 2, nil], [3, 4, nil], [5, 6, 7]]
6
+ def stretch(*arys)
7
+ self.stretch!(*arys.collect { |a| a.dup })
8
+ end
9
+
10
+ # Stretch all argument Arrays to make them the same size. Modifies the arguments in place.
11
+ #
12
+ # Array.stretch!([1, 2], [3, 4], [5, 6, 7]) #=> [[1, 2, nil], [3, 4, nil], [5, 6, 7]]
13
+ def stretch!(*arys)
14
+ max_size = arys.collect { |a| a.length }.max
15
+ arys.each { |a| a[max_size - 1] = nil unless a.length == max_size }
16
+ return *arys
17
+ end
18
+ end
19
+
20
+ # Stretch receiver to be the same size as the longest argument Array.
21
+ #
22
+ # [1, 2].stretch([3, 4], [5, 6, 7]) #=> [1, 2, nil]
23
+ def stretch(*arys)
24
+ self.dup.stretch!(*arys)
25
+ end
26
+
27
+ # Stretch receiver to be the same size as the longest argument Array. Modifies the receiver in place.
28
+ #
29
+ # [1, 2].stretch!([3, 4], [5, 6, 7]) #=> [1, 2, nil]
30
+ def stretch!(*arys)
31
+ max_size = (arys + [self]).collect { |a| a.length }.max
32
+ self[max_size - 1] = nil unless self.length == max_size
33
+ return self
34
+ end
35
+
36
+ # Zip arguments stretching the receiver if necessary. Ruby's +zip+ method
37
+ # will only zip up to the number of the receiver's elements if the receiver
38
+ # is shorter than the argument Arrays. This method will zip nils instead of
39
+ # stopping.
40
+ #
41
+ # [1, 2].zip([3, 4], [5, 6, 7]) #=> [[1, 3, 5], [2, 4, 6]]
42
+ # [1, 2].zip_stretched([3, 4], [5, 6, 7]) #=> [[1, 3, 5], [2, 4, 6], [nil, nil, 7]
43
+ def zip_stretched(*arys)
44
+ self.stretch(*arys).zip(*arys)
45
+ end
46
+ end
47
+
48
+ Array.send(:extend, MoreCoreExtensions::ArrayStretch::ClassMethods)
49
+ Array.send(:include, MoreCoreExtensions::ArrayStretch)
@@ -0,0 +1,89 @@
1
+ module MoreCoreExtensions::ArrayTableize
2
+ # Create a string representation of _self_ in a tabular format if self is an
3
+ # Array of Arrays or an Array of Hashes.
4
+ #
5
+ # If an Array of Hashes is passed, the headers are assumed from the keys in
6
+ # the first element of the Array, and the header option is ignored. Also,
7
+ # the headers are sorted, unless overridden with options.
8
+ #
9
+ # General options:
10
+ # ::max_width: Maximum column width, in order to limit wide columns.
11
+ #
12
+ # Options with Array of Arrays:
13
+ # ::header: Whether or not the first row of data is a header row. Default is
14
+ # true.
15
+ #
16
+ # Options with Array of Hashes:
17
+ # ::columns: An Array of keys that define the order of all columns.
18
+ # ::leading_columns: An Array of keys that should be moved to the left side
19
+ # of the table. This option is ignored if columns option
20
+ # is passed.
21
+ # ::trailing_columns: An Array of keys that should be moved to the right side
22
+ # of the table. This option is ignored if columns option
23
+ # is passed.
24
+ #
25
+ # [["Col1", "Col2"], ["Val1", "Val2"], ["Value3", "Value4"]].tableize #=>
26
+ #
27
+ # Col1 | Col2
28
+ # --------+--------
29
+ # Val1 | Val2
30
+ # Value3 | Value4
31
+ #
32
+ def tableize(options = {})
33
+ case self.first
34
+ when Array; tableize_arrays(options)
35
+ when Hash; tableize_hashes(options)
36
+ else raise "must be an Array of Arrays or Array of Hashes"
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def tableize_arrays(options)
43
+ options[:header] = true unless options.has_key?(:header)
44
+
45
+ widths = []
46
+ justifications = []
47
+ self.each do |row|
48
+ row.each_with_index do |field, field_i|
49
+ widths[field_i] = [widths[field_i].to_i, field.to_s.length].max
50
+ widths[field_i] = [options[:max_width], widths[field_i].to_i].min if options[:max_width]
51
+
52
+ justifications[field_i] = field.kind_of?(Numeric) ? "" : "-"
53
+ end
54
+ end
55
+
56
+ header_separator = widths.collect { |w| "-" * (w + 2) }.join("+")
57
+
58
+ table = []
59
+ self.each_with_index do |row, row_i|
60
+ r = []
61
+ row.each_with_index do |field, field_i|
62
+ r << sprintf("%0#{justifications[field_i]}#{widths[field_i]}s", field.to_s.gsub(/\n|\r/, '').slice(0, widths[field_i]))
63
+ end
64
+ r = " #{r.join(' | ')} ".rstrip
65
+
66
+ table << r
67
+ table << header_separator if row_i == 0 && options[:header]
68
+ end
69
+ table.join("\n") << "\n"
70
+ end
71
+
72
+ def tableize_hashes(options)
73
+ if options[:columns]
74
+ keys = options[:columns]
75
+ elsif options[:leading_columns] || options[:trailing_columns]
76
+ keys = self.first.keys.sort_by(&:to_s)
77
+ options[:leading_columns].reverse.each { |h| keys.unshift(keys.delete(h)) } if options[:leading_columns]
78
+ options[:trailing_columns].each { |h| keys.push(keys.delete(h)) } if options[:trailing_columns]
79
+ else
80
+ keys = self.first.keys.sort_by(&:to_s)
81
+ end
82
+
83
+ options = options.dup
84
+ options[:header] = true
85
+ self.collect { |h| h.values_at(*keys) }.unshift(keys).tableize(options)
86
+ end
87
+ end
88
+
89
+ Array.send(:include, MoreCoreExtensions::ArrayTableize)
@@ -0,0 +1,5 @@
1
+ require 'more_core_extensions/core_ext/array/duplicates'
2
+ require 'more_core_extensions/core_ext/array/inclusions'
3
+ require 'more_core_extensions/core_ext/array/random'
4
+ require 'more_core_extensions/core_ext/array/stretch'
5
+ require 'more_core_extensions/core_ext/array/tableize'
@@ -0,0 +1,19 @@
1
+ require 'active_support/core_ext/object/blank'
2
+
3
+ module MoreCoreExtensions::HashDeletes
4
+ # Deletes all keys where the value is nil
5
+ #
6
+ # {:a => 1, :b => [], :c => nil}.delete_nils # => {:a => 1, :b => []}
7
+ def delete_nils
8
+ delete_if { |k, v| v.nil? }
9
+ end
10
+
11
+ # Deletes all keys where the value is blank
12
+ #
13
+ # {:a => 1, :b => [], :c => nil}.delete_blanks # => {:a => 1}
14
+ def delete_blanks
15
+ delete_if { |k, v| v.blank? }
16
+ end
17
+ end
18
+
19
+ Hash.send(:include, MoreCoreExtensions::HashDeletes)
@@ -0,0 +1,56 @@
1
+ module MoreCoreExtensions::HashNested
2
+ def fetch_path(*args)
3
+ args = args.first if args.length == 1 && args.first.kind_of?(Array)
4
+ raise ArgumentError, "must pass at least one key" if args.empty?
5
+
6
+ child = self[args.first]
7
+ return child if args.length == 1
8
+ return nil unless child.kind_of?(Hash)
9
+ return child.fetch_path(args[1..-1])
10
+ end
11
+
12
+ def has_key_path?(*args)
13
+ args = args.first if args.length == 1 && args.first.kind_of?(Array)
14
+ raise ArgumentError, "must pass at least one key" if args.empty?
15
+
16
+ key = args.first
17
+ has_child = self.has_key?(key)
18
+ return has_child if args.length == 1
19
+
20
+ child = self[key]
21
+ return false unless child.kind_of?(Hash)
22
+ return child.has_key_path?(args[1..-1])
23
+ end
24
+ alias include_path? has_key_path?
25
+ alias key_path? has_key_path?
26
+ alias member_path? has_key_path?
27
+
28
+ def store_path(*args)
29
+ raise ArgumentError, "must pass at least one key, and a value" if args.length < 2
30
+ value = args.pop
31
+ args = args.first if args.length == 1 && args.first.kind_of?(Array)
32
+
33
+ key = args.first
34
+ if args.length == 1
35
+ self[key] = value
36
+ else
37
+ child = self[key]
38
+ child = self[key] = {} unless child.kind_of?(Hash)
39
+ child.store_path(args[1..-1], value)
40
+ end
41
+ end
42
+
43
+ def delete_path(*args)
44
+ args = args.first if args.length == 1 && args.first.kind_of?(Array)
45
+ raise ArgumentError, "must pass at least one key" if args.empty?
46
+
47
+ key = args.first
48
+ if args.length == 1 || !(child = self[key]).kind_of?(Hash)
49
+ self.delete(key)
50
+ else
51
+ child.delete_path(args[1..-1])
52
+ end
53
+ end
54
+ end
55
+
56
+ Hash.send(:include, MoreCoreExtensions::HashNested)
@@ -0,0 +1,2 @@
1
+ require 'more_core_extensions/core_ext/hash/nested'
2
+ require 'more_core_extensions/core_ext/hash/deletes'
@@ -0,0 +1,41 @@
1
+ module MoreCoreExtensions::StringFormats
2
+ # From: Regular Expression Cookbook: 4.1 Validate Email Addresses
3
+ RE_EMAIL = %r{\A[\w!#$\%&'*+/=?`\{|\}~^-]+(?:\.[\w!#$\%&'*+/=?`\{|\}~^-]+)*@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}\Z}i
4
+ def email?
5
+ !!(self =~ RE_EMAIL)
6
+ end
7
+
8
+ # From: Regular Expression Cookbook: 7.15 Validating Domain Names
9
+ RE_DOMAINNAME = %r{^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$}i
10
+ def domain_name?
11
+ !!(self =~ RE_DOMAINNAME)
12
+ end
13
+
14
+ # From: Regular Expression Cookbook: 7.16 Matching IPv4 Addresses
15
+ RE_IPV4 = %r{^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$}
16
+ def ipv4?
17
+ !!(self =~ RE_IPV4)
18
+ end
19
+
20
+ # From: Regular Expression Cookbook: 7.17 Matching IPv6 Addresses
21
+ RE_IPV6 = %r{^(?:(?:(?:[A-F0-9]{1,4}:){6}|(?=(?:[A-F0-9]{0,4}:){0,6}(?:[0-9]{1,3}\.){3}[0-9]{1,3}$)(([0-9A-F]{1,4}:){0,5}|:)((:[0-9A-F]{1,4}){1,5}:|:))(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}|(?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4}$)(([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:))$}i
22
+ def ipv6?
23
+ !!(self =~ RE_IPV6)
24
+ end
25
+
26
+ def ipaddress?
27
+ ipv4? || ipv6?
28
+ end
29
+
30
+ RE_INTEGER = %r{^[0-9]+$}
31
+ def integer?
32
+ !!(self =~ RE_INTEGER)
33
+ end
34
+
35
+ RE_GUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
36
+ def guid?
37
+ !!(self =~ RE_GUID)
38
+ end
39
+ end
40
+
41
+ String.send(:include, MoreCoreExtensions::StringFormats)
@@ -0,0 +1,55 @@
1
+ module MoreCoreExtensions::StringHexDump
2
+ # Dumps the string in a hex editor style format. Options include:
3
+ #
4
+ # :grouping:: The number of bytes in a line. Default is 16.
5
+ # :newline:: Whether or not to add a \n after each line. Default is true.
6
+ # :start_pos:: The number at which byte counts will start. Default is 0.
7
+ # :obj:: Used in conjunction with _:meth_ to send each line to an object
8
+ # instead of returning as a string.
9
+ # :meth:: Used in conjunction with _:obj_ to send each line to an object
10
+ # instead of returning as a string.
11
+ def hex_dump(*opts)
12
+ opts = opts[0] if opts.empty? || (opts.length == 1 && opts[0].kind_of?(Hash))
13
+ raise ArgumentError, "opts must be a Hash" unless opts.nil? || opts.kind_of?(Hash)
14
+
15
+ opts = {:grouping => 16, :newline => true, :start_pos => 0}.merge!(opts || {})
16
+ obj, meth, grouping, newline, pos = opts.values_at(:obj, :meth, :grouping, :newline, :start_pos)
17
+ raise ArgumentError, "obj and meth must both be set, or both not set" if (obj.nil? && !meth.nil?) || (!obj.nil? && meth.nil?)
18
+
19
+ row_format = "0x%08x #{"%02x " * grouping} "
20
+
21
+ i = 0
22
+ last_i = self.length - 1
23
+
24
+ ret = ''
25
+ row_vals = []
26
+ row_chars = ''
27
+
28
+ self.each_byte do |c|
29
+ row_vals << c
30
+ row_chars << (c < 0x20 || (c >= 0x7F && c < 0xA0) ? '.' : c.chr)
31
+
32
+ if (i + 1) % grouping == 0 || i == last_i
33
+ row_format = "0x%08x #{"%02x " * row_vals.length}#{" " * (grouping - row_vals.length)} " if i == last_i
34
+
35
+ row_vals.unshift(pos)
36
+ ret << (row_format % row_vals) << row_chars
37
+ ret << "\n" if newline
38
+ if obj
39
+ obj.send(meth, ret)
40
+ ret.replace('')
41
+ end
42
+
43
+ pos += grouping
44
+ row_vals.clear
45
+ row_chars = ''
46
+ end
47
+
48
+ i += 1
49
+ end
50
+
51
+ return ret
52
+ end
53
+ end
54
+
55
+ String.send(:include, MoreCoreExtensions::StringHexDump)
@@ -0,0 +1,2 @@
1
+ require 'more_core_extensions/core_ext/string/formats'
2
+ require 'more_core_extensions/core_ext/string/hex_dump'
@@ -0,0 +1,3 @@
1
+ module MoreCoreExtensions
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1 @@
1
+ require "more_core_extensions/version"
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'more_core_extensions/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "more_core_extensions"
8
+ spec.version = MoreCoreExtensions::VERSION
9
+ spec.authors = ["Jason Frey"]
10
+ spec.email = ["fryguy9@gmail.com"]
11
+ spec.description = %q{MoreCoreExtensions are a set of core extensions beyond those provided by ActiveSupport.}
12
+ spec.summary = spec.description
13
+ spec.homepage = "http://github.com/ManageIQ/more_core_extensions"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "coveralls"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec"
25
+
26
+ spec.add_dependency "activesupport"
27
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "../../spec_helper"
2
+
3
+ describe Array do
4
+ it '#duplicates' do
5
+ [1, 2, 3, 4].duplicates.should be_empty
6
+ [1, 2, 3, 4, 2, 4].duplicates.should match_array [2, 4]
7
+
8
+ ['1', '2', '3', '4'].duplicates.should be_empty
9
+ ['1', '2', '3', '4', '2', '4'].duplicates.should match_array ['2', '4']
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ require_relative "../../spec_helper"
2
+
3
+ describe Array do
4
+ it '#include_any?' do
5
+ [1, 2, 3].include_any?(1, 2).should be_true
6
+ [1, 2, 3].include_any?(1, 4).should be_true
7
+ [1, 2, 3].include_any?(4, 5).should be_false
8
+
9
+ ['1', '2', '3'].include_any?('1', '2').should be_true
10
+ ['1', '2', '3'].include_any?('1', '4').should be_true
11
+ ['1', '2', '3'].include_any?('4', '5').should be_false
12
+ end
13
+
14
+ it '#include_none?' do
15
+ [1, 2, 3].include_none?(1, 2).should be_false
16
+ [1, 2, 3].include_none?(1, 4).should be_false
17
+ [1, 2, 3].include_none?(4, 5).should be_true
18
+
19
+ ['1', '2', '3'].include_none?('1', '2').should be_false
20
+ ['1', '2', '3'].include_none?('1', '4').should be_false
21
+ ['1', '2', '3'].include_none?('4', '5').should be_true
22
+ end
23
+
24
+ it '#include_all?' do
25
+ [1, 2, 3].include_all?(1, 2).should be_true
26
+ [1, 2, 3].include_all?(1, 4).should be_false
27
+ [1, 2, 3].include_all?(4, 5).should be_false
28
+
29
+ ['1', '2', '3'].include_all?('1', '2').should be_true
30
+ ['1', '2', '3'].include_all?('1', '4').should be_false
31
+ ['1', '2', '3'].include_all?('4', '5').should be_false
32
+ end
33
+ end