loading
Generated 2025-10-09T00:00:36+00:00

All Files ( 100.0% covered at 10.22 hits/line )

17 files in total.
330 relevant lines, 330 lines covered and 0 lines missed. ( 100.0% )
108 total branches, 108 branches covered and 0 branches missed. ( 100.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line Branch Coverage Branches Covered branches Missed branches
lib/refinements.rb 100.00 % 15 13 13 0 1.00 100.00 % 0 0 0
lib/refinements/array.rb 100.00 % 86 46 46 0 4.52 100.00 % 17 17 0
lib/refinements/binding.rb 100.00 % 13 7 7 0 1.00 100.00 % 0 0 0
lib/refinements/data.rb 100.00 % 12 5 5 0 1.00 100.00 % 0 0 0
lib/refinements/date_time.rb 100.00 % 12 5 5 0 1.00 100.00 % 0 0 0
lib/refinements/hash.rb 100.00 % 126 65 65 0 7.75 100.00 % 26 26 0
lib/refinements/io.rb 100.00 % 34 18 18 0 2.50 100.00 % 4 4 0
lib/refinements/module.rb 100.00 % 12 5 5 0 1.80 100.00 % 0 0 0
lib/refinements/object.rb 100.00 % 22 11 11 0 4.00 100.00 % 5 5 0
lib/refinements/pathname.rb 100.00 % 96 49 49 0 10.33 100.00 % 16 16 0
lib/refinements/shared/diff.rb 100.00 % 17 8 8 0 5.75 100.00 % 2 2 0
lib/refinements/shared/many.rb 100.00 % 15 7 7 0 3.86 100.00 % 4 4 0
lib/refinements/shared/reread.rb 100.00 % 10 4 4 0 1.00 100.00 % 0 0 0
lib/refinements/string.rb 100.00 % 104 55 55 0 27.67 100.00 % 34 34 0
lib/refinements/string_io.rb 100.00 % 16 8 8 0 1.00 100.00 % 0 0 0
lib/refinements/struct.rb 100.00 % 40 19 19 0 21.00 100.00 % 0 0 0
lib/refinements/symbol.rb 100.00 % 12 5 5 0 4.40 100.00 % 0 0 0

lib/refinements.rb

100.0% lines covered

100.0% branches covered

13 relevant lines. 13 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "refinements/array"
  3. 1 require "refinements/binding"
  4. 1 require "refinements/data"
  5. 1 require "refinements/date_time"
  6. 1 require "refinements/hash"
  7. 1 require "refinements/io"
  8. 1 require "refinements/module"
  9. 1 require "refinements/object"
  10. 1 require "refinements/pathname"
  11. 1 require "refinements/string"
  12. 1 require "refinements/string_io"
  13. 1 require "refinements/struct"
  14. 1 require "refinements/symbol"

lib/refinements/array.rb

100.0% lines covered

100.0% branches covered

46 relevant lines. 46 lines covered and 0 lines missed.
17 total branches, 17 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "refinements/shared/many"
  3. 1 module Refinements
  4. # Provides additional enhancements to the Array primitive.
  5. 1 module Array
  6. 1 refine ::Array do
  7. 1 import_methods Shared::Many
  8. 1 def combinatorial?(other) = !other.empty? && size == union(other).size
  9. 15 def compress = compact.delete_if { |element| element.respond_to?(:empty?) && element.empty? }
  10. 1 def compress!
  11. 20 delete_if { |element| element.respond_to?(:empty?) && element.empty? }
  12. 4 compact!
  13. end
  14. 1 def excluding(*elements) = self - elements.flatten
  15. 1 def including(*elements) = self + elements.flatten
  16. 1 def intersperse(*elements) = product([elements]).tap(&:pop).flatten.push(last)
  17. 1 def maximum(key) = map(&key).max
  18. 7 then: 1 else: 5 def mean = size.zero? ? 0 : sum(0.0) / size
  19. 1 def minimum(key) = map(&key).min
  20. 7 def pad(value, max = size) = dup.fill(value, size..(max - 1))
  21. 1 def pick(*keys)
  22. 4 then: 1 else: 3 return if empty?
  23. 5 then: 1 else: 2 keys.many? ? keys.map { |key| first[key] } : first[keys.first]
  24. end
  25. 1 def pluck(*keys)
  26. 5 then: 2 else: 3 return dup if empty?
  27. 3 then: 1 else: 2 return [] if keys.empty?
  28. 2 then: 1 if keys.many?
  29. 10 map { |element| keys.map { |key| element[key] } }
  30. else: 1 else
  31. 1 key = keys.first
  32. 4 map { |element| element[key] }
  33. end
  34. end
  35. 1 def replace_at(index, *elements)
  36. 7 delete_at index
  37. 7 insert(index, *elements)
  38. end
  39. 1 def ring(&) = [last, *self, first].each_cons(3, &)
  40. 1 def supplant target, *replacements
  41. 9 index(target).then do |position|
  42. 9 delete_at position
  43. 9 insert position, *replacements
  44. end
  45. 9 self
  46. end
  47. 1 def supplant_if target, *replacements
  48. 17 then: 6 else: 8 each { |item| supplant target, *replacements if item == target }
  49. 3 self
  50. end
  51. 1 def to_sentence conjunction = "and", delimiter: ", "
  52. 11 when: 6 case length
  53. 11 when: 1 when (3..) then "#{self[..-2].join delimiter}#{delimiter}#{conjunction} #{last}"
  54. 1 else: 4 when 2 then join " #{conjunction} "
  55. 4 else join
  56. end
  57. end
  58. 1 def to_usage conjunction = "and", delimiter: ", "
  59. 4 map(&:inspect).to_sentence conjunction, delimiter:
  60. end
  61. end
  62. end
  63. end

lib/refinements/binding.rb

100.0% lines covered

100.0% branches covered

7 relevant lines. 7 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module Refinements
  3. # Provides additional enhancements to the Binding class.
  4. 1 module Binding
  5. 1 refine ::Binding do
  6. 1 alias_method :[], :local_variable_get
  7. 1 alias_method :[]=, :local_variable_set
  8. 1 alias_method :local?, :local_variable_defined?
  9. 1 alias_method :locals, :local_variables
  10. end
  11. end
  12. end

lib/refinements/data.rb

100.0% lines covered

100.0% branches covered

5 relevant lines. 5 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "refinements/shared/diff"
  3. 1 module Refinements
  4. # Provides additional enhancements to the Struct primitive.
  5. 1 module Data
  6. 1 refine ::Data do
  7. 1 import_methods Shared::Diff
  8. end
  9. end
  10. end

lib/refinements/date_time.rb

100.0% lines covered

100.0% branches covered

5 relevant lines. 5 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "date"
  3. 1 module Refinements
  4. # Provides additional enhancements to the DateTime primitive.
  5. 1 module DateTime
  6. 1 refine ::DateTime.singleton_class do
  7. 1 def utc = now.new_offset(0)
  8. end
  9. end
  10. end

lib/refinements/hash.rb

100.0% lines covered

100.0% branches covered

65 relevant lines. 65 lines covered and 0 lines missed.
26 total branches, 26 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "refinements/shared/many"
  3. 1 module Refinements
  4. # Provides additional enhancements to the Hash primitive.
  5. 1 module Hash
  6. 1 refine ::Hash.singleton_class do
  7. 5 def infinite = new { |nascence, lacuna| nascence[lacuna] = new(&nascence.default_proc) }
  8. 2 def with_default(value) = new { |nascence, lacuna| nascence[lacuna] = value }
  9. end
  10. 1 refine ::Hash do
  11. 1 import_methods Shared::Many
  12. 14 def compress = compact.delete_if { |_key, value| value.respond_to?(:empty?) && value.empty? }
  13. 1 def compress!
  14. 19 delete_if { |_key, value| value.respond_to?(:empty?) && value.empty? }
  15. 4 compact!
  16. end
  17. 1 def deep_merge other
  18. 12 clazz = self.class
  19. 12 merge other do |_key, this_value, other_value|
  20. 14 then: 6 if this_value.is_a?(clazz) && other_value.is_a?(clazz)
  21. 6 this_value.deep_merge other_value
  22. else: 8 else
  23. 8 other_value
  24. end
  25. end
  26. end
  27. 1 def deep_merge!(other) = replace(deep_merge(other))
  28. 1 def deep_stringify_keys = recurse(&:stringify_keys)
  29. 1 def deep_stringify_keys! = replace(deep_stringify_keys)
  30. 1 def deep_symbolize_keys = recurse(&:symbolize_keys)
  31. 1 def deep_symbolize_keys! = replace(deep_symbolize_keys)
  32. 1 def diff other
  33. 5 then: 3 else: 2 return differences_from other if other.is_a?(self.class) && keys.sort! == other.keys.sort!
  34. 7 each.with_object({}) { |(key, value), diff| diff[key] = [value, nil] }
  35. end
  36. 1 def fetch_deep(*keys, default: NilClass, &)
  37. 10 keys.reduce fallback(keys.shift, default, &) do |value, key|
  38. 13 else: 12 then: 1 unless value.is_a?(::Hash) || (value.is_a?(::Array) && key.is_a?(::Integer))
  39. 1 fail KeyError, "Unable to find #{key.inspect} in #{value.inspect}."
  40. end
  41. 12 then: 11 else: 1 default == NilClass ? value.fetch(key, &) : value.fetch(key, default)
  42. end
  43. end
  44. 1 def fetch_value(key, *default, &)
  45. 6 then: 1 else: 1 fetch(key, *default, &) || (yield if block_given?) || default.first
  46. end
  47. 1 def flatten_keys prefix: nil, delimiter: "_"
  48. 28 reduce({}) do |accumulator, (key, value)|
  49. 38 then: 18 else: 20 flat_key = prefix ? :"#{prefix}#{delimiter}#{key}" : key
  50. 38 else: 14 then: 24 next accumulator.merge flat_key => value unless value.is_a? ::Hash
  51. 28 accumulator.merge(recurse { value.flatten_keys prefix: flat_key, delimiter: })
  52. end
  53. end
  54. 1 def flatten_keys!(prefix: nil, delimiter: "_") = replace flatten_keys(prefix:, delimiter:)
  55. 1 def recurse &block
  56. 29 else: 28 then: 1 return self unless block
  57. 28 transform = yield self
  58. 61 then: 4 else: 29 transform.each { |key, value| transform[key] = value.recurse(&block) if value.is_a? ::Hash }
  59. end
  60. 1 def stringify_keys = transform_keys(&:to_s)
  61. 1 def stringify_keys! = transform_keys!(&:to_s)
  62. 1 def symbolize_keys = transform_keys(&:to_sym)
  63. 1 def symbolize_keys! = transform_keys!(&:to_sym)
  64. 1 def transform_value(key, &) = dup.transform_value!(key, &)
  65. 1 def transform_value! key
  66. 10 then: 6 else: 4 block_given? && key?(key) ? merge!(key => yield(self[key])) : self
  67. end
  68. 1 def transform_with(**) = dup.transform_with!(**)
  69. 1 def transform_with!(**operations)
  70. 14 then: 6 else: 2 operations.each { |key, function| self[key] = function.call self[key] if key? key }
  71. 6 self
  72. end
  73. 1 def use &block
  74. 3 else: 2 then: 1 return [] unless block
  75. 2 block.parameters
  76. 4 .map { |(_type, key)| self[key] || self[key.to_s] }
  77. 2 .then { |values| yield values }
  78. end
  79. 1 private
  80. 1 def differences_from other
  81. 11 result = merge(other.to_h) { |_, one, two| [one, two].uniq }
  82. 11 result.select { |_, diff| diff.size == 2 }
  83. end
  84. 1 def fallback(key, default, &)
  85. 10 then: 8 else: 2 default == NilClass ? fetch(key, &) : fetch(key, default)
  86. end
  87. end
  88. end
  89. end

lib/refinements/io.rb

100.0% lines covered

100.0% branches covered

18 relevant lines. 18 lines covered and 0 lines missed.
4 total branches, 4 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "refinements/shared/reread"
  3. 1 module Refinements
  4. # Provides additional enhancements to the IO primitive.
  5. 1 module IO
  6. 1 refine ::IO.singleton_class do
  7. 1 def void
  8. 7 new(sysopen(File::NULL, "w+")).then do |io|
  9. 7 else: 1 then: 6 return io unless block_given?
  10. 1 yield io
  11. 1 io.tap(&:close)
  12. end
  13. end
  14. end
  15. 1 refine ::IO do
  16. 1 import_methods Shared::Reread
  17. 1 def redirect other
  18. 5 else: 3 then: 2 return self unless block_given?
  19. 3 backup = dup
  20. 3 reopen other
  21. 3 yield self
  22. 3 reopen backup
  23. end
  24. 4 def squelch(&) = self.class.void.then { |void| redirect(void, &) }
  25. end
  26. end
  27. end

lib/refinements/module.rb

100.0% lines covered

100.0% branches covered

5 relevant lines. 5 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module Refinements
  3. # Provides additional enhancements to the Symbol primitive.
  4. 1 module Module
  5. 1 refine ::Module do
  6. 1 def pseudonym prefix, suffix = object_id, delimiter: "-"
  7. 5 set_temporary_name "#{prefix}#{delimiter}#{suffix}"
  8. end
  9. end
  10. end
  11. end

lib/refinements/object.rb

100.0% lines covered

100.0% branches covered

11 relevant lines. 11 lines covered and 0 lines missed.
5 total branches, 5 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module Refinements
  3. # Provides additional enhancements to the Object class.
  4. 1 module Object
  5. 1 refine ::Object do
  6. 1 def in? other
  7. 18 when: 2 case other
  8. 2 when: 10 when Range then other.cover? self
  9. 10 else: 6 when ::Array, Enumerable, ::Hash, Set, ::String then other.include? self
  10. 6 else fail NoMethodError, "`#{self.class}#include?` must be implemented."
  11. end
  12. end
  13. 1 def to_proc
  14. 2 then: 1 else: 1 return method(:call).to_proc if respond_to? :call
  15. 1 fail NoMethodError, "`#{self.class}#call` must be implemented."
  16. end
  17. end
  18. end
  19. end

lib/refinements/pathname.rb

100.0% lines covered

100.0% branches covered

49 relevant lines. 49 lines covered and 0 lines missed.
16 total branches, 16 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "pathname"
  3. 1 module Refinements
  4. # Provides additional enhancements to the Pathname primitive.
  5. 1 module Pathname
  6. 1 refine Kernel do
  7. 1 def Pathname object
  8. 41 else: 40 then: 1 return super(String(object)) unless object
  9. 40 super
  10. end
  11. end
  12. 1 refine ::Pathname.singleton_class do
  13. 1 def home = new ENV.fetch("HOME", "")
  14. 4 def require_tree(root) = new(root).files("**/*.rb").each { |path| require path.to_s }
  15. 1 def root = new(File::SEPARATOR)
  16. end
  17. 1 refine ::Pathname do
  18. 1 def change_dir
  19. 7 then: 3 if block_given?
  20. 6 Dir.chdir(self) { |path| yield Pathname(path) }
  21. else: 4 else
  22. 4 Dir.chdir self and self
  23. end
  24. end
  25. 1 def clear = children.each(&:rmtree) && self
  26. 1 def copy to
  27. 5 then: 2 else: 3 destination = to.directory? ? to.join(basename) : to
  28. 5 ::IO.copy_stream self, destination
  29. 3 self
  30. end
  31. 1 def deep_touch(...)
  32. 8 warn "`#{self.class}##{__method__}` is deprecated, use `#touch_deep` instead.",
  33. category: :deprecated
  34. 8 touch_deep(...)
  35. end
  36. 1 def delete = super && self
  37. 1 def delete_prefix(pattern) = parent.join %(#{name.sub(/\A#{pattern}/, "")}#{extname})
  38. 1 def delete_suffix(pattern) = parent.join %(#{name.sub(/#{pattern}\z/, "")}#{extname})
  39. 1 def directories pattern = "*", flag: File::FNM_SYSCASE
  40. 5 glob(pattern, flag).select(&:directory?)
  41. end
  42. 8 then: 2 else: 5 def empty = file? ? (truncate(0) and self) : rmtree.make_dir
  43. 1 def extensions = basename.to_s.split(/(?=\.)+/).tap(&:shift)
  44. 1 def files(pattern = "*", flag: File::FNM_SYSCASE) = glob(pattern, flag).select(&:file?)
  45. 1 def gsub(pattern, replacement) = self.class.new(to_s.gsub(pattern, replacement))
  46. 1 def make_ancestors
  47. 20 dirname.mkpath
  48. 20 self
  49. end
  50. 18 then: 1 else: 16 def make_dir = exist? ? self : (mkdir and self)
  51. 1 def name = basename extname
  52. 1 def puts(content) = write "#{content}\n"
  53. 1 def relative_parent(root_dir) = relative_path_from(root_dir).parent
  54. 6 then: 2 else: 3 def remove_dir = exist? ? (rmdir and self) : self
  55. 4 then: 2 else: 1 def rewrite = read.then { |content| write yield(content) if block_given? }
  56. 1 def touch at = Time.now
  57. 68 then: 21 else: 47 exist? ? utime(at, at) : write("")
  58. 67 self
  59. end
  60. 1 def touch_deep(...) = make_ancestors.touch(...)
  61. 1 def write content, offset: nil, **options
  62. 67 super content, offset, **options
  63. 65 self
  64. end
  65. end
  66. end
  67. end

lib/refinements/shared/diff.rb

100.0% lines covered

100.0% branches covered

8 relevant lines. 8 lines covered and 0 lines missed.
2 total branches, 2 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module Refinements
  3. 1 module Shared
  4. # Provides functionality for knowing the difference between two whole value objects.
  5. 1 module Diff
  6. 1 def diff other
  7. 6 then: 4 if other.is_a? self.class
  8. 16 to_h.merge(other.to_h) { |_, one, two| [one, two].uniq }
  9. 12 .select { |_, diff| diff.size == 2 }
  10. else: 2 else
  11. 8 to_h.each.with_object({}) { |(key, value), diff| diff[key] = [value, nil] }
  12. end
  13. end
  14. end
  15. end
  16. end

lib/refinements/shared/many.rb

100.0% lines covered

100.0% branches covered

7 relevant lines. 7 lines covered and 0 lines missed.
4 total branches, 4 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module Refinements
  3. 1 module Shared
  4. # Provides functionality for knowing whether an enumerable has many elements or not.
  5. 1 module Many
  6. 1 def many?
  7. 13 else: 2 then: 11 return size > 1 unless block_given?
  8. 8 then: 4 else: 2 total = reduce(0) { |count, item| yield(item) ? count + 1 : count }
  9. 2 total > 1
  10. end
  11. end
  12. end
  13. end

lib/refinements/shared/reread.rb

100.0% lines covered

100.0% branches covered

4 relevant lines. 4 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module Refinements
  3. 1 module Shared
  4. # Provides functionality for I/O object rewinding.
  5. 1 module Reread
  6. 1 def reread(length = nil, buffer: nil) = tap(&:rewind).read(length, buffer)
  7. end
  8. end
  9. end

lib/refinements/string.rb

100.0% lines covered

100.0% branches covered

55 relevant lines. 55 lines covered and 0 lines missed.
34 total branches, 34 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module Refinements
  3. # Provides additional enhancements to the String primitive.
  4. 1 module String
  5. 1 DELIMITERS = %r([a-z][A-Z]|\s*-\s*|\s*/\s*|\s*:+\s*|\s*_\s*|\s+)
  6. 1 refine ::String do
  7. 1 def blank? = empty? || match?(/\A[[:space:]]*\z/)
  8. 1 def camelcase
  9. 24 else: 20 then: 4 return up unless match? DELIMITERS
  10. 40 split(%r(\s*-\s*|\s*/\s*|\s*:+\s*)).then { |parts| combine parts, :up, "::" }
  11. 20 .then { |text| text.split(/\s*_\s*|\s+/) }
  12. 20 .then { |parts| combine parts, :up }
  13. end
  14. 64 then: 1 else: 62 def down = empty? ? self : first.downcase + self[1, size]
  15. 1 def falsey? = !truthy?
  16. 1 def first maximum = 0
  17. 205 then: 1 else: 204 return self if empty?
  18. 204 then: 202 else: 2 return self[0] if maximum.zero?
  19. 2 then: 1 else: 1 return "" if maximum.negative?
  20. 1 self[..(maximum - 1)]
  21. end
  22. 1 def indent multiplier = 1, pad: " "
  23. 6 then: 1 else: 5 multiplier.negative? ? self : (pad * multiplier) + self
  24. end
  25. 1 def last minimum = 0
  26. 4 then: 1 else: 3 return self if empty?
  27. 3 then: 1 else: 2 return self[size - 1] if minimum.zero?
  28. 2 then: 1 else: 1 return "" if minimum.negative?
  29. 1 self[(minimum + 1)..]
  30. end
  31. 9 then: 2 else: 6 def pluralize(suffix, count = 0, replace: /$/) = count.abs == 1 ? self : sub(replace, suffix)
  32. 10 then: 6 else: 3 def singularize(suffix, count = 1, replace: "") = count.abs == 1 ? sub(suffix, replace) : self
  33. 1 def snakecase
  34. 22 else: 20 then: 2 return downcase unless match? DELIMITERS
  35. 40 split(%r(\s*-\s*|\s*/\s*|\s*:+\s*)).then { |parts| combine parts, :down, "/" }
  36. 20 .then { |text| text.split(/(?=[A-Z])|\s*_\s*|\s+/) }
  37. 20 .then { |parts| combine parts, :down, "_" }
  38. end
  39. 1 def squish = gsub(/[[:space:]]+/, " ").tap(&:strip!)
  40. 1 def titleize
  41. 23 else: 21 then: 2 return capitalize unless match? DELIMITERS
  42. 42 split(/(?=[A-Z])|\s*_\s*|\s*-\s*|\s+/).then { |parts| combine parts, :up, " " }
  43. 21 .then { |text| text.split %r(\s*/\s*|\s*:+\s*) }
  44. 21 .then { |parts| combine parts, :up, "/" }
  45. end
  46. 1 def trim_end to, delimiter = nil, trailer: "..."
  47. 21 then: 4 else: 17 return dup if length <= to
  48. 17 offset = to - trailer.length
  49. 17 then: 4 else: 13 maximum = delimiter ? rindex(delimiter, offset) || offset : offset
  50. 17 "#{self[...maximum]}#{trailer}"
  51. end
  52. 1 def truthy? = %w[true yes on t y 1].include? downcase.strip
  53. 1 def truncate(...)
  54. 11 warn "`#{self.class}##{__method__}` is deprecated, use `#trim_end` instead.",
  55. category: :deprecated
  56. 11 trim_end(...)
  57. end
  58. # rubocop:disable Naming/PredicateMethod
  59. 1 def to_bool
  60. 11 warn "`#{self.class}##{__method__}` is deprecated, use `#truthy?` or `#falsey?` instead.",
  61. category: :deprecated
  62. 11 truthy?
  63. end
  64. # rubocop:enable Naming/PredicateMethod
  65. 142 then: 2 else: 139 def up = empty? ? self : first.upcase + self[1, size]
  66. 1 private
  67. # :reek:UtilityFunction
  68. 1 def combine parts, method, delimiter = ""
  69. 122 parts.reduce "" do |result, part|
  70. 196 then: 93 else: 103 next part.public_send method if result.empty?
  71. 103 "#{result}#{delimiter}#{part.__send__ method}"
  72. end
  73. end
  74. end
  75. end
  76. end

lib/refinements/string_io.rb

100.0% lines covered

100.0% branches covered

8 relevant lines. 8 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "refinements/shared/reread"
  3. 1 require "stringio"
  4. 1 module Refinements
  5. # Provides additional enhancements to the StringIO primitive.
  6. 1 module StringIO
  7. 1 refine ::StringIO do
  8. 1 import_methods Shared::Reread
  9. 1 alias_method :to_s, :string
  10. 1 alias_method :to_str, :string
  11. end
  12. end
  13. end

lib/refinements/struct.rb

100.0% lines covered

100.0% branches covered

19 relevant lines. 19 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "refinements/shared/diff"
  3. 1 module Refinements
  4. # Provides additional enhancements to the Struct primitive.
  5. 1 module Struct
  6. 1 refine ::Struct do
  7. 1 import_methods Shared::Diff
  8. 1 def merge(...)
  9. 8 warn "`#{self.class}##{__method__}` is deprecated, use `#with` instead.",
  10. category: :deprecated
  11. 8 with(...)
  12. end
  13. 1 def merge!(...)
  14. 34 warn "`#{self.class}##{__method__}` is deprecated, use `#with!` instead.",
  15. category: :deprecated
  16. 34 with!(...)
  17. end
  18. 1 def transmute(...) = dup.transmute!(...)
  19. 1 def transmute! object, **key_map
  20. 14 mapping = key_map.invert
  21. 14 merge! object.to_h.slice(*mapping.keys).transform_keys!(mapping)
  22. end
  23. 1 def with(...) = dup.with!(...)
  24. 1 def with! object = nil
  25. 220 to_h.merge!(**object.to_h).each { |key, value| self[key] = value }
  26. 56 self
  27. end
  28. end
  29. end
  30. end

lib/refinements/symbol.rb

100.0% lines covered

100.0% branches covered

5 relevant lines. 5 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 module Refinements
  3. # Provides additional enhancements to the Symbol primitive.
  4. 1 module Symbol
  5. 1 refine ::Symbol do
  6. 1 def call(*positionals, **keywords, &)
  7. 18 proc { |receiver| receiver.public_send(self, *positionals, **keywords, &) }
  8. end
  9. end
  10. end
  11. end