loading
Generated 2025-11-02T15:47:54+00:00

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

1 files in total.
38 relevant lines, 38 lines covered and 0 lines missed. ( 100.0% )
4 total branches, 4 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/functionable.rb 100.00 % 77 38 38 0 12.95 100.00 % 4 4 0

lib/functionable.rb

100.0% lines covered

100.0% branches covered

38 relevant lines. 38 lines covered and 0 lines missed.
4 total branches, 4 branches covered and 0 branches missed.
    
  1. # frozen_string_literal: true
  2. # Main namespace.
  3. 1 module Functionable
  4. 1 @mutex = Mutex.new
  5. 1 def self.extended descendant
  6. 19 descendant.singleton_class.class_eval do
  7. 19 def extended(*) = fail NoMethodError, "Module extend is disabled."
  8. 19 def included(*) = fail NoMethodError, "Module include is disabled."
  9. 19 def prepended(*) = fail NoMethodError, "Module prepend is disabled."
  10. 19 def module_function(*) = fail NoMethodError, "Module function behavior is disabled."
  11. 19 def public(*) = fail NoMethodError, "Public visibility is disabled."
  12. 19 def protected(*) = fail NoMethodError, "Protected visibility is disabled."
  13. 19 def private(*) = fail NoMethodError, "Private visibility is disabled, use conceal instead."
  14. 19 def conceal(*) = private_class_method(*)
  15. 19 def alias_method to, from
  16. 1 fail NoMethodError, "Aliasing #{from.inspect} as #{to.inspect} is disabled."
  17. end
  18. 19 def class_variable_set(name, ...)
  19. 1 fail NoMethodError, "Setting class variable #{name.inspect} is disabled."
  20. end
  21. 19 def class_variable_get name
  22. 1 fail NoMethodError, "Getting class variable #{name.inspect} is disabled."
  23. end
  24. 19 def const_set(name, ...) = fail NoMethodError, "Setting constant #{name.inspect} is disabled."
  25. 19 def define_method(name, ...)
  26. 1 fail NoMethodError, "Defining method #{name.inspect} is disabled."
  27. end
  28. 19 def remove_method name
  29. 12 then: 11 else: 1 return super if instance_variable_get :@functionable
  30. 1 fail NoMethodError, "Removing method #{name.inspect} is disabled."
  31. end
  32. 19 def undef_method(name) = fail NoMethodError, "Undefining method #{name.inspect} is disabled."
  33. 19 def singleton_method_added name, allowed: %i[method_added singleton_method_added].freeze
  34. 50 then: 49 else: 1 return super(name) if allowed.include?(name) || instance_variable_get(:@functionable)
  35. 1 fail NoMethodError,
  36. "Avoid defining #{name.inspect} as a class method because the method will be " \
  37. "automatically converted to a class method for you."
  38. end
  39. 19 def method_added name
  40. 11 unbound = instance_method name
  41. 11 instance_variable_set :@functionable, true
  42. 11 remove_method name
  43. 11 define_singleton_method name, unbound
  44. 11 instance_variable_set :@functionable, false
  45. 11 super
  46. ensure
  47. 11 instance_variable_set :@functionable, false
  48. end
  49. end
  50. end
  51. 1 def self.included(*) = fail NoMethodError, "Module include is disabled, use extend instead."
  52. 1 def self.prepended(*) = fail NoMethodError, "Module prepend is disabled, use extend instead."
  53. end