Skip to content

Commit

Permalink
feat: add hook hints (#135)
Browse files Browse the repository at this point in the history
Signed-off-by: Manuel Schönlaub <manuel.schoenlaub@gmail.com>
  • Loading branch information
mschoenlaub authored May 6, 2024
1 parent 50bdf48 commit 51155a7
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lib/open_feature/sdk/hooks/hints.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

module OpenFeature
module SDK
module Hooks
class Hints < DelegateClass(Hash)
ALLOWED_TYPES = [String, Symbol, Numeric, TrueClass, FalseClass, Time, Hash, Array].freeze

def initialize(hash = {})
hash.each do |key, value|
assert_allowed_key(key)
assert_allowed_value(value)
end
@hash = hash.dup
super(@hash)
freeze
end

private

def assert_allowed_key(key)
raise ArgumentError, "Only String or Symbol are allowed as keys." unless key.is_a?(String) || key.is_a?(Symbol)
end

def assert_allowed_value(value)
allowed_type = ALLOWED_TYPES.any? { |t| value.is_a?(t) }
raise ArgumentError, "Only #{ALLOWED_TYPES.join(", ")} are allowed as values." unless allowed_type
end
end
end
end
end
48 changes: 48 additions & 0 deletions spec/open_feature/sdk/hooks/hints_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

require "spec_helper"

require "open_feature/sdk/hooks/hints"

RSpec.describe OpenFeature::SDK::Hooks::Hints do
let(:hint_hash) { {key: [], nested: {key: []}} }
subject(:hints) { described_class.new(hint_hash) }
context "Immutability" do
it "is frozen" do
expect(hints).to be_frozen
end

it "does not allow addition of new keys" do
expect { hints[:new_key] = "new_value" }.to raise_error(FrozenError)
end

it "does allow modification of existing values" do
expect(hints[:key]).to_not be_frozen
expect { hints[:key] << "abc" }.to_not raise_error
end

it "does not allow deletion of keys" do
expect { hints.delete(:key) }.to raise_error(FrozenError)
end

it "allows reading of keys" do
expect(hints[:key]).to eq([])
end

it "only allows string keys" do
expect { described_class.new(1 => []) }.to raise_error(ArgumentError) do |e|
expect(e.message).to include("Only String or Symbol are allowed as keys")
end
end

it "only allows values of certain types" do
expect { described_class.new(key: Object.new) }.to raise_error(ArgumentError) do |e|
expect(e.message).to include("Only String, Symbol, Numeric, TrueClass, FalseClass, Time, Hash, Array are allowed as values")
end
end

it "does not freeze the original hash" do
expect(hint_hash).not_to be_frozen
end
end
end

0 comments on commit 51155a7

Please sign in to comment.