more_core_extensions 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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