Skip to content

Commit

Permalink
Allow converting a configuration object back to a Hash
Browse files Browse the repository at this point in the history
While this is somewhat complicated code, I am sure it'll come in handy -
not just for testing the `config.yml` file.
  • Loading branch information
mamhoff committed Feb 6, 2025
1 parent f6d81cb commit 72b3269
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
35 changes: 35 additions & 0 deletions lib/alchemy/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,33 @@ def set_from_yaml(file)
)
end

def to_h
self.class.defined_options.map do |option|
[option, send(option)]
end.concat(
self.class.defined_configurations.map do |configuration|
[configuration, send(configuration).to_h]
end
).to_h
end

class << self
def defined_configurations = []

def defined_options = []

def configuration(name, configuration_class)
# The defined configurations on a class are all those defined directly on
# that class as well as those defined on ancestors.
# We store these as a class instance variable on each class which has a
# configuration. super() collects configurations defined on ancestors.
singleton_configurations = (@defined_singleton_configurations ||= [])
singleton_configurations << name.to_sym

define_singleton_method :defined_configurations do
super() + singleton_configurations
end

define_method(name) do
unless instance_variable_get(:"@#{name}")
send(:"#{name}=", configuration_class.new)
Expand All @@ -63,6 +88,16 @@ def configuration(name, configuration_class)

def option(name, type, default: nil, **args)
klass = "Alchemy::Configuration::#{type.to_s.camelize}Option".constantize
# The defined options on a class are all those defined directly on
# that class as well as those defined on ancestors.
# We store these as a class instance variable on each class which has a
# option. super() collects options defined on ancestors.
singleton_options = (@defined_singleton_options ||= [])
singleton_options << name.to_sym

define_singleton_method :defined_options do
super() + singleton_options
end

define_method(name) do
unless instance_variable_defined?(:"@#{name}")
Expand Down
2 changes: 2 additions & 0 deletions lib/alchemy/configuration/class_set_option.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def each
end
end

def as_json = @value

private

def validate(value)
Expand Down
13 changes: 13 additions & 0 deletions spec/libraries/alchemy/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@
subject { configuration.get(:mail_success_page) }

it { is_expected.to eq("thanks") }

it "can be converted to a Hash" do
expect(configuration.to_h).to eq(
mail_success_page: "thanks",
link_target_options: ["blank"]
)
end
end

describe "nested configurations" do
Expand Down Expand Up @@ -256,5 +263,11 @@
expect(configuration.uploader.upload_limit).to eq(30)
expect(configuration.uploader.file_size_limit).to eq(80)
end

it "can be converted to a Hash" do
expect(configuration.to_h).to eq(
uploader: {file_size_limit: 100, upload_limit: 50}
)
end
end
end

0 comments on commit 72b3269

Please sign in to comment.