Skip to content

Commit

Permalink
Validate configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-isler committed Nov 12, 2024
1 parent 45459c8 commit 30dc01e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 12 deletions.
5 changes: 2 additions & 3 deletions lib/hotsheet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ def configuration
@configuration ||= Configuration.new
end

def configure
@configuration = Configuration.new
yield configuration
def configure(&block)
@configuration = Configuration.new.tap(&block)
end

def models
Expand Down
40 changes: 36 additions & 4 deletions lib/hotsheet/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,46 @@ def initialize
self.models = {}
end

def model(name, &block)
model_config = ModelConfig.new
yield model_config if block
def model(name)
model_config = ModelConfig.new(name).tap do |config|
yield(config)
Rails.application.config.to_prepare { config.validate! }
end
models[name.to_s] = model_config
end

class ModelConfig
attr_accessor :included_attributes, :excluded_attributes
attr_accessor :included_attributes, :excluded_attributes, :model_name

def initialize(model_name)
@model_name = model_name
@included_attributes = []
@excluded_attributes = []
end

def validate!
ensure_only_one_attribute_set
validate_attribute_existence
end

private

def ensure_only_one_attribute_set
return unless included_attributes.any? && excluded_attributes.any?

raise "Can only specify either included or excluded attributes for '#{model_name}'"
end

def validate_attribute_existence
model_class = model_name.to_s.constantize
all_attributes = model_class.column_names

(included_attributes + excluded_attributes).each do |attr|
unless all_attributes.include?(attr.to_s)
raise "Attribute '#{attr}' doesn't exist on model '#{model_name}'"
end
end
end
end
end
end
83 changes: 78 additions & 5 deletions spec/lib/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@
subject(:config) { Hotsheet.configuration }

context "without model configuration" do
before { Hotsheet.configure {} } # rubocop:disable Lint/EmptyBlock
before { Hotsheet.configure {} } # reset configuration

it "does NOT have any configured model" do
expect(config.models).to eq({})
end
end

context "with a model configuration" do
context "with a valid model configuration" do
let(:model_config) { config.models["Author"] }

before do
Hotsheet.configure do |config|
config.model :Author do |model|
model.included_attributes = %i[name birthdate]
model.excluded_attributes = %i[created_at]
end
end
end
Expand All @@ -30,10 +29,84 @@
expect(config.models["Author"]).to be_a Hotsheet::Configuration::ModelConfig
end

it "has included and excluded attributes" do
it "has included attributes set correctly" do
expect(model_config).to be_a Hotsheet::Configuration::ModelConfig
expect(model_config.included_attributes).to eq %i[name birthdate]
expect(model_config.excluded_attributes).to eq %i[created_at]
end
end

describe "Hotsheet::Configuration::ModelConfig" do
subject(:model_config) { Hotsheet::Configuration::ModelConfig.new("Author") }

let(:model_class) do
Class.new do
def self.name
"Author"
end

def self.column_names
%w[id name birthdate created_at updated_at]
end
end
end

before do
stub_const("Author", model_class)
end

context "when only included attributes are specified" do
before { model_config.included_attributes = %i[name birthdate] }

it "validates without errors" do
expect { model_config.validate! }.not_to raise_error
end
end

context "when only excluded attributes are specified" do
before { model_config.excluded_attributes = %i[created_at updated_at] }

it "validates without errors" do
expect { model_config.validate! }.not_to raise_error
end
end

context "when both included and excluded attributes are specified" do
before do
model_config.included_attributes = %i[name birthdate]
model_config.excluded_attributes = %i[created_at]
end

it "raises an error" do
expect do
model_config.validate!
end.to raise_error("Can only specify either included or excluded attributes for 'Author'")
end
end

context "when included attributes contain a non-existent attribute" do
before { model_config.included_attributes = %i[name non_existent_attribute] }

it "raises an error indicating the attribute does not exist" do
expect do
model_config.validate!
end.to raise_error("Attribute 'non_existent_attribute' doesn't exist on model 'Author'")
end
end

context "when excluded attributes contain a non-existent attribute" do
before { model_config.excluded_attributes = %i[non_existent_attribute] }

it "raises an error indicating the attribute does not exist" do
expect do
model_config.validate!
end.to raise_error("Attribute 'non_existent_attribute' doesn't exist on model 'Author'")
end
end

context "when no included or excluded attributes are specified" do
it "validates without errors" do
expect { model_config.validate! }.not_to raise_error
end
end
end
end

0 comments on commit 30dc01e

Please sign in to comment.