loading
Generated 2025-10-08T23:59:23+00:00

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

2 files in total.
42 relevant lines, 42 lines covered and 0 lines missed. ( 100.0% )
2 total branches, 2 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/initable.rb 100.00 % 14 6 6 0 1.00 100.00 % 0 0 0
lib/initable/builder.rb 100.00 % 59 36 36 0 30.81 100.00 % 2 2 0

lib/initable.rb

100.0% lines covered

100.0% branches covered

6 relevant lines. 6 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "initable/builder"
  3. # Main namespace.
  4. 1 module Initable
  5. 1 METHOD_SCOPES = %i[public protected private].freeze
  6. 1 def self.[](*, **) = Builder.new(*, **)
  7. 1 def self.protected(*, **) = Builder.new(*, method_scope: __method__, **)
  8. 1 def self.public(*, **) = Builder.new(*, method_scope: __method__, **)
  9. end

lib/initable/builder.rb

100.0% lines covered

100.0% branches covered

36 relevant lines. 36 lines covered and 0 lines missed.
2 total branches, 2 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. 1 require "marameters"
  3. 1 module Initable
  4. # Builds initialization behavior.
  5. 1 class Builder < Module
  6. 1 def initialize *parameters, method_scope: :private, **keywords
  7. 57 super()
  8. 70 keywords.each { |key, value| parameters.push [:key, key, value] }
  9. 57 @parameters = Marameters.for parameters
  10. 57 @method_scope = method_scope
  11. 57 @names = @parameters.names.compact
  12. 57 @instance_module = Module.new.set_temporary_name "initable"
  13. 57 freeze
  14. end
  15. 1 def included descendant
  16. 57 super
  17. 57 define_initialize descendant
  18. 57 descendant.include instance_module
  19. end
  20. 1 private
  21. 1 attr_reader :method_scope, :parameters, :names, :instance_module
  22. 1 def define_initialize descendant,
  23. inheritor: Marameters::Signatures::Inheritor.new,
  24. forwarder: Marameters::Signatures::Super.new
  25. 57 ancestor = Marameters.of(descendant, :initialize).first
  26. 114 signature = inheritor.call(ancestor, parameters).then { |params| Marameters.signature params }
  27. 57 instance_module.module_eval <<-METHOD, __FILE__, __LINE__ + 1
  28. 1 def initialize(#{signature})
  29. 1 #{build_instance_variables ancestor}
  30. 1 super(#{forwarder.call ancestor, parameters})
  31. 1 end
  32. 1 METHOD
  33. 1
  34. 10 define_readers ancestor
  35. 1 end
  36. 1
  37. 1 def build_instance_variables ancestor
  38. 154 (names - ancestor.names).map { |name| "@#{name} = #{name}" }
  39. .join "\n"
  40. end
  41. 1 def define_readers ancestor
  42. 57 instance_module.module_eval <<-READERS, __FILE__, __LINE__ + 1
  43. 1 #{compute_scope} attr_reader(*#{names - ancestor.names})
  44. READERS
  45. end
  46. 58 then: 54 else: 3 def compute_scope = METHOD_SCOPES.include?(method_scope) ? method_scope : :private
  47. end
  48. end