Skip to content

Commit eea9d17

Browse files
authored
feat: add integer and float specific resolver methods (#124)
1 parent a6c789d commit eea9d17

File tree

5 files changed

+107
-10
lines changed

5 files changed

+107
-10
lines changed

lib/open_feature/sdk/client.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module SDK
55
# TODO: Write documentation
66
#
77
class Client
8-
RESULT_TYPE = %i[boolean string number object].freeze
8+
RESULT_TYPE = %i[boolean string number integer float object].freeze
99
SUFFIXES = %i[value details].freeze
1010

1111
attr_reader :metadata, :evaluation_context

lib/open_feature/sdk/provider/in_memory_provider.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,15 @@ def fetch_string_value(flag_key:, default_value:, evaluation_context: nil)
3434
end
3535

3636
def fetch_number_value(flag_key:, default_value:, evaluation_context: nil)
37-
fetch_value(allowed_classes: [Integer, Float], flag_key:, default_value:, evaluation_context:)
37+
fetch_value(allowed_classes: [Numeric], flag_key:, default_value:, evaluation_context:)
38+
end
39+
40+
def fetch_integer_value(flag_key:, default_value:, evaluation_context: nil)
41+
fetch_value(allowed_classes: [Integer], flag_key:, default_value:, evaluation_context:)
42+
end
43+
44+
def fetch_float_value(flag_key:, default_value:, evaluation_context: nil)
45+
fetch_value(allowed_classes: [Float], flag_key:, default_value:, evaluation_context:)
3846
end
3947

4048
def fetch_object_value(flag_key:, default_value:, evaluation_context: nil)
@@ -52,7 +60,7 @@ def fetch_value(allowed_classes:, flag_key:, default_value:, evaluation_context:
5260
return ResolutionDetails.new(value: default_value, error_code: ErrorCode::FLAG_NOT_FOUND, reason: Reason::ERROR)
5361
end
5462

55-
if allowed_classes.include?(value.class)
63+
if allowed_classes.any? { |klass| value.is_a?(klass) }
5664
ResolutionDetails.new(value:, reason: Reason::STATIC)
5765
else
5866
ResolutionDetails.new(value: default_value, error_code: ErrorCode::TYPE_MISMATCH, reason: Reason::ERROR)

lib/open_feature/sdk/provider/no_op_provider.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ def fetch_number_value(flag_key:, default_value:, evaluation_context: nil)
4444
no_op(default_value)
4545
end
4646

47+
def fetch_integer_value(flag_key:, default_value:, evaluation_context: nil)
48+
no_op(default_value)
49+
end
50+
51+
def fetch_float_value(flag_key:, default_value:, evaluation_context: nil)
52+
no_op(default_value)
53+
end
54+
4755
def fetch_object_value(flag_key:, default_value:, evaluation_context: nil)
4856
no_op(default_value)
4957
end

spec/open_feature/sdk/client_spec.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,21 @@
6464
expect(client).to respond_to(:fetch_number_value)
6565
end
6666

67-
context "Condition 1.3.2 - The implementation language differentiates between floating-point numbers and integers." do
67+
it do
68+
expect(client.fetch_number_value(flag_key: flag_key, default_value: 4)).is_a?(Integer)
69+
end
70+
71+
it do
72+
expect(client.fetch_number_value(flag_key: flag_key, default_value: 95.5)).is_a?(Float)
73+
end
74+
75+
context "Condition 1.3.3 - The implementation language differentiates between floating-point numbers and integers." do
6876
it do
69-
expect(client.fetch_number_value(flag_key: flag_key, default_value: 4)).is_a?(Integer)
77+
expect(client.fetch_integer_value(flag_key: flag_key, default_value: 4)).is_a?(Integer)
7078
end
7179

7280
it do
73-
expect(client.fetch_number_value(flag_key: flag_key, default_value: 95.5)).is_a?(Float)
81+
expect(client.fetch_float_value(flag_key: flag_key, default_value: 95.5)).is_a?(Float)
7482
end
7583
end
7684
end

spec/open_feature/sdk/provider/in_memory_provider_spec.rb

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
{
77
"bool" => true,
88
"str" => "testing",
9-
"num" => 1,
9+
"int" => 1,
10+
"float" => 1.0,
1011
"struct" => {"more" => "config"}
1112
}
1213
)
@@ -103,12 +104,18 @@
103104
describe "#fetch_number_value" do
104105
context "when flag is found" do
105106
context "when type matches" do
106-
it "returns value as static" do
107-
fetched = provider.fetch_number_value(flag_key: "num", default_value: 0)
107+
it "returns int as static" do
108+
fetched = provider.fetch_number_value(flag_key: "int", default_value: 0)
108109

109110
expect(fetched.value).to eq(1)
110111
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::STATIC)
111112
end
113+
it "returns float as static" do
114+
fetched = provider.fetch_number_value(flag_key: "float", default_value: 0.0)
115+
116+
expect(fetched.value).to eq(1.0)
117+
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::STATIC)
118+
end
112119
end
113120

114121
context "when type does not match" do
@@ -133,6 +140,72 @@
133140
end
134141
end
135142

143+
describe "#fetch_integer_value" do
144+
context "when flag is found" do
145+
context "when type matches" do
146+
it "returns value as static" do
147+
fetched = provider.fetch_integer_value(flag_key: "int", default_value: 0)
148+
149+
expect(fetched.value).to eq(1)
150+
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::STATIC)
151+
end
152+
end
153+
154+
context "when type does not match" do
155+
it "returns default as type mismatch" do
156+
fetched = provider.fetch_integer_value(flag_key: "float", default_value: 0)
157+
158+
expect(fetched.value).to eq(0)
159+
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH)
160+
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR)
161+
end
162+
end
163+
end
164+
165+
context "when flag is not found" do
166+
it "returns default as flag not found" do
167+
fetched = provider.fetch_number_value(flag_key: "not here", default_value: 0)
168+
169+
expect(fetched.value).to eq(0)
170+
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::FLAG_NOT_FOUND)
171+
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR)
172+
end
173+
end
174+
end
175+
176+
describe "#fetch_integer_value" do
177+
context "when flag is found" do
178+
context "when type matches" do
179+
it "returns value as static" do
180+
fetched = provider.fetch_float_value(flag_key: "float", default_value: 0.0)
181+
182+
expect(fetched.value).to eq(1.0)
183+
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::STATIC)
184+
end
185+
end
186+
187+
context "when type does not match" do
188+
it "returns default as type mismatch" do
189+
fetched = provider.fetch_float_value(flag_key: "int", default_value: 0.0)
190+
191+
expect(fetched.value).to eq(0)
192+
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH)
193+
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR)
194+
end
195+
end
196+
end
197+
198+
context "when flag is not found" do
199+
it "returns default as flag not found" do
200+
fetched = provider.fetch_number_value(flag_key: "not here", default_value: 0)
201+
202+
expect(fetched.value).to eq(0)
203+
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::FLAG_NOT_FOUND)
204+
expect(fetched.reason).to eq(OpenFeature::SDK::Provider::Reason::ERROR)
205+
end
206+
end
207+
end
208+
136209
describe "#fetch_object_value" do
137210
context "when flag is found" do
138211
context "when type matches" do
@@ -146,7 +219,7 @@
146219

147220
context "when type does not match" do
148221
it "returns default as type mismatch" do
149-
fetched = provider.fetch_object_value(flag_key: "num", default_value: {})
222+
fetched = provider.fetch_object_value(flag_key: "int", default_value: {})
150223

151224
expect(fetched.value).to eq({})
152225
expect(fetched.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::TYPE_MISMATCH)

0 commit comments

Comments
 (0)