Skip to content

Commit

Permalink
Implement Validators.get
Browse files Browse the repository at this point in the history
  • Loading branch information
apexatoll committed Nov 19, 2023
1 parent 2c1647b commit 6ffc4a6
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
29 changes: 29 additions & 0 deletions lib/kangaru/validators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Kangaru
module Validators
using Patches::Inflections

def self.get(name)
class_name = name.to_s.to_class_name(suffix: :validator)

from_kangaru(class_name) || from_application(class_name) ||
raise("#{class_name} is not defined")
end

def self.from_kangaru(class_name)
return unless const_defined?(class_name)

const_get(class_name)
end

def self.from_application(class_name)
namespace = Kangaru.application&.const_get(:Validators)

return unless namespace&.const_defined?(class_name)

namespace.const_get(class_name)
end

private_class_method :from_kangaru
private_class_method :from_application
end
end
11 changes: 11 additions & 0 deletions sig/kangaru/validators.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Kangaru
module Validators
def self.get: (String | Symbol) -> singleton(Validator)

private

def self.from_kangaru: (String | Symbol) -> singleton(Validator)?

def self.from_application: (String | Symbol) -> singleton(Validator)?
end
end
92 changes: 92 additions & 0 deletions spec/kangaru/validators_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
RSpec.describe Kangaru::Validators do
describe ".get", :stub_application do
subject(:validator) { described_class.get(name) }

let(:validator_class) do
Class.new(Kangaru::Validator)
end

let(:name) { "example" }

shared_examples :raises_error do
it "raises an error" do
expect { validator }.to raise_error(
"ExampleValidator is not defined"
)
end
end

shared_examples :returns_validator_class do
it "does not raise any errors" do
expect { validator }.not_to raise_error
end

it "returns the validator class" do
expect(validator).to eq(validator_class)
end
end

context "when application is not set" do
let(:application) { nil }

context "and validator is not defined by Kangaru" do
include_examples :raises_error
end

context "and validator is defined by Kangaru" do
before do
stub_const "#{described_class}::ExampleValidator", validator_class
end

include_examples :returns_validator_class
end
end

context "when application is set" do
let(:application) { instance_double(Kangaru::Application, namespace:) }

let(:validators_namespace) { nil }

before do
allow(application)
.to receive(:const_get)
.with(:Validators)
.and_return(validators_namespace)
end

context "and validator is not defined by Kangaru" do
context "and validators namespace is not defined by application" do
let(:validators_namespace) { nil }

include_examples :raises_error
end

context "and validators namespace is defined by application" do
let(:validators_namespace) { Module.new }

before do
allow(application)
.to receive(:const_get)
.with(:Validators)
.and_return(validators_namespace)

stub_const "#{namespace}::Validators", validators_namespace
end

context "and validator class is not defined" do
include_examples :raises_error
end

context "and validator class is defined" do
before do
stub_const "#{validators_namespace}::ExampleValidator",
validator_class
end

include_examples :returns_validator_class
end
end
end
end
end
end

0 comments on commit 6ffc4a6

Please sign in to comment.