In the following situation, where include_class is a preference, can I somehow dynamically change the value of include_class and reload Image such that it instead includes the new value of include_class?
module Foo
included do
@test_var = :foo
end
end
module Bar
included do
@test_var = :bar
end
end
Config.include_class = Foo
class Image
include Config.include_class
end
# ... run tests with default configuration for Image, where Image.test_var = :foo
Config.include_class = OtherClass
# ... how can I reload or re-evaluate Image such that Image.test_var = :bar?
Context
I am trying to test whether a configuration option (that is normally set by an initializer) has the correct effects on the application. Because this is part of a test suite the the modules and classes might be loaded before and all configuration changes need to be reset after the test.
CodePudding user response:
I'd suggest to use refinements instead, in this case class will be reset after the test (on any other stuff). I implemented an example without active_concern, but the idea should be clear. This example can be executed with plain ruby as a single script.
# This part is just to keep close to your example
class Config
def self.include_class=(klass)
@@include_class = klass
end
def self.include_class
@@include_class ||= nil
end
end
# Assuming Bar is a default module and Foo will be used in tests
module Bar
def print_something
puts 'I am Bar'
end
end
module Foo
def print_something
puts 'I am Foo'
end
end
# Setting default module
Config.include_class = Bar
# Defining Image class
class Image
include Config.include_class
end
#Changing config
Config.include_class = Foo
# This is a refinement
module ImagePatch
# It will include current Config.include_class
# Note that methods from Bar that are not present in Foo will not be removed
refine Image do
include Config.include_class
end
end
# Here we will create module where refinement is activated
module TestEnv
# Activating the patch
using ImagePatch
Image.new.print_something #=>I am Foo
end
#Outside of the TestEnv module we enjoy the default Image class
Image.new.print_something #=>I am Bar
