-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Max VelDink <maxveldink@gmail.com>
- Loading branch information
1 parent
db48cd5
commit 25680a4
Showing
10 changed files
with
262 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
module OpenFeature | ||
module SDK | ||
module Provider | ||
# TODO: Add evaluation context support | ||
class InMemoryProvider | ||
NAME = "In-memory Provider" | ||
|
||
def initialize(flags = {}) | ||
@metadata = Metadata.new(name: NAME).freeze | ||
@flags = flags | ||
end | ||
|
||
def init | ||
# Intentional no-op, used for testing | ||
end | ||
|
||
def shutdown | ||
# Intentional no-op, used for testing | ||
end | ||
|
||
def add_flag(flag_key:, value:) | ||
flags[flag_key] = value | ||
# TODO: Emit PROVIDER_CONFIGURATION_CHANGED event once events are implemented | ||
end | ||
|
||
def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil) | ||
fetch_value(allowed_classes: [TrueClass, FalseClass], flag_key:, default_value:, evaluation_context:) | ||
end | ||
|
||
def fetch_string_value(flag_key:, default_value:, evaluation_context: nil) | ||
fetch_value(allowed_classes: [String], flag_key:, default_value:, evaluation_context:) | ||
end | ||
|
||
def fetch_number_value(flag_key:, default_value:, evaluation_context: nil) | ||
fetch_value(allowed_classes: [Integer, Float], flag_key:, default_value:, evaluation_context:) | ||
end | ||
|
||
def fetch_object_value(flag_key:, default_value:, evaluation_context: nil) | ||
fetch_value(allowed_classes: [Array, Hash], flag_key:, default_value:, evaluation_context:) | ||
end | ||
|
||
private | ||
|
||
attr_reader :flags | ||
|
||
def fetch_value(allowed_classes:, flag_key:, default_value:, evaluation_context:) | ||
value = flags[flag_key] | ||
|
||
if value.nil? | ||
return ResolutionDetails.new(value: default_value, error_code: ErrorCode::FLAG_NOT_FOUND, reason: Reason::ERROR) | ||
end | ||
|
||
if allowed_classes.include?(value.class) | ||
ResolutionDetails.new(value:, reason: Reason::STATIC) | ||
else | ||
ResolutionDetails.new(value: default_value, error_code: ErrorCode::TYPE_MISMATCH, reason: Reason::ERROR) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
168 changes: 168 additions & 0 deletions
168
spec/open_feature/sdk/provider/in_memory_provider_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
require "spec_helper" | ||
|
||
RSpec.describe OpenFeature::SDK::Provider::InMemoryProvider do | ||
subject(:provider) do | ||
described_class.new( | ||
{ | ||
"bool" => true, | ||
"str" => "testing", | ||
"num" => 1, | ||
"struct" => {"more" => "config"} | ||
} | ||
) | ||
end | ||
|
||
describe "#add_flag" do | ||
context "when flag doesn't exist" do | ||
it "adds flag" do | ||
provider.add_flag(flag_key: "new_flag", value: "new_value") | ||
|
||
fetched = provider.fetch_string_value(flag_key: "new_flag", default_value: "fallback") | ||
|
||
expect(fetched.value).to eq("new_value") | ||
end | ||
end | ||
|
||
context "when flag exists" do | ||
it "updates flag" do | ||
provider.add_flag(flag_key: "bool", value: false) | ||
|
||
fetched = provider.fetch_boolean_value(flag_key: "bool", default_value: true) | ||
|
||
expect(fetched.value).to eq(false) | ||
end | ||
end | ||
end | ||
|
||
describe "#fetch_boolean_value" do | ||
context "when flag is found" do | ||
context "when type matches" do | ||
it "returns value as static" do | ||
fetched = provider.fetch_boolean_value(flag_key: "bool", default_value: false) | ||
|
||
expect(fetched.value).to eq(true) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::STATIC) | ||
end | ||
end | ||
|
||
context "when type does not match" do | ||
it "returns default as type mismatch" do | ||
fetched = provider.fetch_boolean_value(flag_key: "str", default_value: false) | ||
|
||
expect(fetched.value).to eq(false) | ||
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR) | ||
end | ||
end | ||
end | ||
|
||
context "when flag is not found" do | ||
it "returns default as flag not found" do | ||
fetched = provider.fetch_boolean_value(flag_key: "not here", default_value: false) | ||
|
||
expect(fetched.value).to eq(false) | ||
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::FLAG_NOT_FOUND) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR) | ||
end | ||
end | ||
end | ||
|
||
describe "#fetch_string_value" do | ||
context "when flag is found" do | ||
context "when type matches" do | ||
it "returns value as static" do | ||
fetched = provider.fetch_string_value(flag_key: "str", default_value: "fallback") | ||
|
||
expect(fetched.value).to eq("testing") | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::STATIC) | ||
end | ||
end | ||
|
||
context "when type does not match" do | ||
it "returns default as type mismatch" do | ||
fetched = provider.fetch_string_value(flag_key: "bool", default_value: "fallback") | ||
|
||
expect(fetched.value).to eq("fallback") | ||
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR) | ||
end | ||
end | ||
end | ||
|
||
context "when flag is not found" do | ||
it "returns default as flag not found" do | ||
fetched = provider.fetch_string_value(flag_key: "not here", default_value: "fallback") | ||
|
||
expect(fetched.value).to eq("fallback") | ||
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::FLAG_NOT_FOUND) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR) | ||
end | ||
end | ||
end | ||
|
||
describe "#fetch_number_value" do | ||
context "when flag is found" do | ||
context "when type matches" do | ||
it "returns value as static" do | ||
fetched = provider.fetch_number_value(flag_key: "num", default_value: 0) | ||
|
||
expect(fetched.value).to eq(1) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::STATIC) | ||
end | ||
end | ||
|
||
context "when type does not match" do | ||
it "returns default as type mismatch" do | ||
fetched = provider.fetch_number_value(flag_key: "str", default_value: 0) | ||
|
||
expect(fetched.value).to eq(0) | ||
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR) | ||
end | ||
end | ||
end | ||
|
||
context "when flag is not found" do | ||
it "returns default as flag not found" do | ||
fetched = provider.fetch_number_value(flag_key: "not here", default_value: 0) | ||
|
||
expect(fetched.value).to eq(0) | ||
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::FLAG_NOT_FOUND) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR) | ||
end | ||
end | ||
end | ||
|
||
describe "#fetch_object_value" do | ||
context "when flag is found" do | ||
context "when type matches" do | ||
it "returns value as static" do | ||
fetched = provider.fetch_object_value(flag_key: "struct", default_value: {}) | ||
|
||
expect(fetched.value).to eq({"more" => "config"}) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::STATIC) | ||
end | ||
end | ||
|
||
context "when type does not match" do | ||
it "returns default as type mismatch" do | ||
fetched = provider.fetch_object_value(flag_key: "num", default_value: {}) | ||
|
||
expect(fetched.value).to eq({}) | ||
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR) | ||
end | ||
end | ||
end | ||
|
||
context "when flag is not found" do | ||
it "returns default as flag not found" do | ||
fetched = provider.fetch_object_value(flag_key: "not here", default_value: {}) | ||
|
||
expect(fetched.value).to eq({}) | ||
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::FLAG_NOT_FOUND) | ||
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.