Skip to content
This repository has been archived by the owner on Sep 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #10 from spotify/ctx-passed-in
Browse files Browse the repository at this point in the history
Global ctx passed into the provider via FeatureProvider
  • Loading branch information
fabriziodemaria authored May 30, 2023
2 parents 6f0eb18 + eb0b745 commit 239d101
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 40 deletions.
10 changes: 5 additions & 5 deletions Sources/OpenFeature/FeatureProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ public protocol FeatureProvider {
// Called by OpenFeatureAPI whenever a new EvaluationContext is set by the application
func onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext) async

func getBooleanEvaluation(key: String, defaultValue: Bool) throws -> ProviderEvaluation<
func getBooleanEvaluation(key: String, defaultValue: Bool, context: EvaluationContext?) throws -> ProviderEvaluation<
Bool
>
func getStringEvaluation(key: String, defaultValue: String) throws -> ProviderEvaluation<
func getStringEvaluation(key: String, defaultValue: String, context: EvaluationContext?) throws -> ProviderEvaluation<
String
>
func getIntegerEvaluation(key: String, defaultValue: Int64) throws -> ProviderEvaluation<
func getIntegerEvaluation(key: String, defaultValue: Int64, context: EvaluationContext?) throws -> ProviderEvaluation<
Int64
>
func getDoubleEvaluation(key: String, defaultValue: Double) throws -> ProviderEvaluation<
func getDoubleEvaluation(key: String, defaultValue: Double, context: EvaluationContext?) throws -> ProviderEvaluation<
Double
>
func getObjectEvaluation(key: String, defaultValue: Value) throws -> ProviderEvaluation<
func getObjectEvaluation(key: String, defaultValue: Value, context: EvaluationContext?) throws -> ProviderEvaluation<
Value
>
}
2 changes: 1 addition & 1 deletion Sources/OpenFeature/HookContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public struct HookContext<T> {
var flagKey: String
var type: FlagValueType
var defaultValue: T
var ctx: EvaluationContext
var ctx: EvaluationContext?
var clientMetadata: Metadata?
var providerMetadata: Metadata?
}
10 changes: 5 additions & 5 deletions Sources/OpenFeature/NoOpProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,35 @@ class NoOpProvider: FeatureProvider {
// no-op
}

func getBooleanEvaluation(key: String, defaultValue: Bool) throws -> ProviderEvaluation<
func getBooleanEvaluation(key: String, defaultValue: Bool, context: EvaluationContext?) throws -> ProviderEvaluation<
Bool
> {
return ProviderEvaluation(
value: defaultValue, variant: NoOpProvider.passedInDefault, reason: Reason.defaultReason.rawValue)
}

func getStringEvaluation(key: String, defaultValue: String) throws -> ProviderEvaluation<
func getStringEvaluation(key: String, defaultValue: String, context: EvaluationContext?) throws -> ProviderEvaluation<
String
> {
return ProviderEvaluation(
value: defaultValue, variant: NoOpProvider.passedInDefault, reason: Reason.defaultReason.rawValue)
}

func getIntegerEvaluation(key: String, defaultValue: Int64) throws -> ProviderEvaluation<
func getIntegerEvaluation(key: String, defaultValue: Int64, context: EvaluationContext?) throws -> ProviderEvaluation<
Int64
> {
return ProviderEvaluation(
value: defaultValue, variant: NoOpProvider.passedInDefault, reason: Reason.defaultReason.rawValue)
}

func getDoubleEvaluation(key: String, defaultValue: Double) throws -> ProviderEvaluation<
func getDoubleEvaluation(key: String, defaultValue: Double, context: EvaluationContext?) throws -> ProviderEvaluation<
Double
> {
return ProviderEvaluation(
value: defaultValue, variant: NoOpProvider.passedInDefault, reason: Reason.defaultReason.rawValue)
}

func getObjectEvaluation(key: String, defaultValue: Value) throws -> ProviderEvaluation<
func getObjectEvaluation(key: String, defaultValue: Value, context: EvaluationContext?) throws -> ProviderEvaluation<
Value
> {
return ProviderEvaluation(
Expand Down
19 changes: 13 additions & 6 deletions Sources/OpenFeature/OpenFeatureClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ extension OpenFeatureClient {
) -> FlagEvaluationDetails<T> {
let options = options ?? FlagEvaluationOptions(hooks: [], hookHints: [:])
let hints = options.hookHints
let context = openFeatureApi.getEvaluationContext() ?? MutableContext()
let context = openFeatureApi.getEvaluationContext()

var details = FlagEvaluationDetails(flagKey: key, value: defaultValue)
let provider = openFeatureApi.getProvider() ?? NoOpProvider()
Expand All @@ -213,6 +213,7 @@ extension OpenFeatureClient {
let providerEval = try createProviderEvaluation(
flagValueType: flagValueType,
key: key,
context: context,
defaultValue: defaultValue,
provider: provider)

Expand Down Expand Up @@ -247,6 +248,7 @@ extension OpenFeatureClient {
private func createProviderEvaluation<V>(
flagValueType: FlagValueType,
key: String,
context: EvaluationContext?,
defaultValue: V,
provider: FeatureProvider
) throws -> ProviderEvaluation<V> {
Expand All @@ -258,7 +260,8 @@ extension OpenFeatureClient {

if let evaluation = try provider.getBooleanEvaluation(
key: key,
defaultValue: defaultValue) as? ProviderEvaluation<V>
defaultValue: defaultValue,
context: context) as? ProviderEvaluation<V>
{
return evaluation
}
Expand All @@ -269,7 +272,8 @@ extension OpenFeatureClient {

if let evaluation = try provider.getStringEvaluation(
key: key,
defaultValue: defaultValue) as? ProviderEvaluation<V>
defaultValue: defaultValue,
context: context) as? ProviderEvaluation<V>
{
return evaluation
}
Expand All @@ -280,7 +284,8 @@ extension OpenFeatureClient {

if let evaluation = try provider.getIntegerEvaluation(
key: key,
defaultValue: defaultValue) as? ProviderEvaluation<V>
defaultValue: defaultValue,
context: context) as? ProviderEvaluation<V>
{
return evaluation
}
Expand All @@ -291,7 +296,8 @@ extension OpenFeatureClient {

if let evaluation = try provider.getDoubleEvaluation(
key: key,
defaultValue: defaultValue) as? ProviderEvaluation<V>
defaultValue: defaultValue,
context: context) as? ProviderEvaluation<V>
{
return evaluation
}
Expand All @@ -302,7 +308,8 @@ extension OpenFeatureClient {

if let evaluation = try provider.getObjectEvaluation(
key: key,
defaultValue: defaultValue) as? ProviderEvaluation<V>
defaultValue: defaultValue,
context: context) as? ProviderEvaluation<V>
{
return evaluation
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenFeature/exceptions/OpenFeatureError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extension OpenFeatureError: CustomStringConvertible {
case .generalError(let message):
return "General error: \(message)"
case .invalidContextError:
return "Invalid context"
return "Invalid or missing context"
case .parseError(let message):
return "Parse error: \(message)"
case .targetingKeyMissingError:
Expand Down
10 changes: 5 additions & 5 deletions Tests/OpenFeatureTests/Helpers/AlwaysBrokenProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,31 @@ class AlwaysBrokenProvider: FeatureProvider {
// no-op
}

func getBooleanEvaluation(key: String, defaultValue: Bool) throws
func getBooleanEvaluation(key: String, defaultValue: Bool, context: EvaluationContext?) throws
-> OpenFeature.ProviderEvaluation<Bool>
{
throw OpenFeatureError.flagNotFoundError(key: key)
}

func getStringEvaluation(key: String, defaultValue: String) throws
func getStringEvaluation(key: String, defaultValue: String, context: EvaluationContext?) throws
-> OpenFeature.ProviderEvaluation<String>
{
throw OpenFeatureError.flagNotFoundError(key: key)
}

func getIntegerEvaluation(key: String, defaultValue: Int64) throws
func getIntegerEvaluation(key: String, defaultValue: Int64, context: EvaluationContext?) throws
-> OpenFeature.ProviderEvaluation<Int64>
{
throw OpenFeatureError.flagNotFoundError(key: key)
}

func getDoubleEvaluation(key: String, defaultValue: Double) throws
func getDoubleEvaluation(key: String, defaultValue: Double, context: EvaluationContext?) throws
-> OpenFeature.ProviderEvaluation<Double>
{
throw OpenFeatureError.flagNotFoundError(key: key)
}

func getObjectEvaluation(key: String, defaultValue: OpenFeature.Value) throws
func getObjectEvaluation(key: String, defaultValue: OpenFeature.Value, context: EvaluationContext?) throws
-> OpenFeature.ProviderEvaluation<OpenFeature.Value>
{
throw OpenFeatureError.flagNotFoundError(key: key)
Expand Down
10 changes: 5 additions & 5 deletions Tests/OpenFeatureTests/Helpers/DoSomethingProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,31 @@ class DoSomethingProvider: FeatureProvider {
var hooks: [OpenFeature.AnyHook] = []
var metadata: OpenFeature.Metadata = DoMetadata()

func getBooleanEvaluation(key: String, defaultValue: Bool) throws -> ProviderEvaluation<
func getBooleanEvaluation(key: String, defaultValue: Bool, context: EvaluationContext?) throws -> ProviderEvaluation<
Bool
> {
return ProviderEvaluation(value: !defaultValue)
}

func getStringEvaluation(key: String, defaultValue: String) throws -> ProviderEvaluation<
func getStringEvaluation(key: String, defaultValue: String, context: EvaluationContext?) throws -> ProviderEvaluation<
String
> {
return ProviderEvaluation(value: String(defaultValue.reversed()))
}

func getIntegerEvaluation(key: String, defaultValue: Int64) throws -> ProviderEvaluation<
func getIntegerEvaluation(key: String, defaultValue: Int64, context: EvaluationContext?) throws -> ProviderEvaluation<
Int64
> {
return ProviderEvaluation(value: defaultValue * 100)
}

func getDoubleEvaluation(key: String, defaultValue: Double) throws -> ProviderEvaluation<
func getDoubleEvaluation(key: String, defaultValue: Double, context: EvaluationContext?) throws -> ProviderEvaluation<
Double
> {
return ProviderEvaluation(value: defaultValue * 100)
}

func getObjectEvaluation(key: String, defaultValue: Value) throws -> ProviderEvaluation<
func getObjectEvaluation(key: String, defaultValue: Value, context: EvaluationContext?) throws -> ProviderEvaluation<
Value
> {
return ProviderEvaluation(value: .null)
Expand Down
24 changes: 12 additions & 12 deletions Tests/OpenFeatureTests/ProviderSpecTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,52 @@ final class ProviderSpecTests: XCTestCase {
func testFlagValueSet() throws {
let provider = NoOpProvider()

let boolResult = try provider.getBooleanEvaluation(key: "key", defaultValue: false)
let boolResult = try provider.getBooleanEvaluation(key: "key", defaultValue: false, context: MutableContext())
XCTAssertNotNil(boolResult.value)

let stringResult = try provider.getStringEvaluation(key: "key", defaultValue: "test")
let stringResult = try provider.getStringEvaluation(key: "key", defaultValue: "test", context: MutableContext())
XCTAssertNotNil(stringResult.value)

let intResult = try provider.getIntegerEvaluation(key: "key", defaultValue: 4)
let intResult = try provider.getIntegerEvaluation(key: "key", defaultValue: 4, context: MutableContext())
XCTAssertNotNil(intResult.value)

let doubleResult = try provider.getDoubleEvaluation(key: "key", defaultValue: 0.4)
let doubleResult = try provider.getDoubleEvaluation(key: "key", defaultValue: 0.4, context: MutableContext())
XCTAssertNotNil(doubleResult.value)

let objectResult = try provider.getObjectEvaluation(key: "key", defaultValue: .null)
let objectResult = try provider.getObjectEvaluation(key: "key", defaultValue: .null, context: MutableContext())
XCTAssertNotNil(objectResult.value)
}

func testHasReason() throws {
let provider = NoOpProvider()

let boolResult = try provider.getBooleanEvaluation(key: "key", defaultValue: false)
let boolResult = try provider.getBooleanEvaluation(key: "key", defaultValue: false, context: MutableContext())
XCTAssertEqual(boolResult.reason, Reason.defaultReason.rawValue)
}

func testNoErrorCodeByDefault() throws {
let provider = NoOpProvider()

let boolResult = try provider.getBooleanEvaluation(key: "key", defaultValue: false)
let boolResult = try provider.getBooleanEvaluation(key: "key", defaultValue: false, context: MutableContext())
XCTAssertNil(boolResult.errorCode)
}

func testVariantIsSet() throws {
let provider = NoOpProvider()

let boolResult = try provider.getBooleanEvaluation(key: "key", defaultValue: false)
let boolResult = try provider.getBooleanEvaluation(key: "key", defaultValue: false, context: MutableContext())
XCTAssertNotNil(boolResult.variant)

let stringResult = try provider.getStringEvaluation(key: "key", defaultValue: "test")
let stringResult = try provider.getStringEvaluation(key: "key", defaultValue: "test", context: MutableContext())
XCTAssertNotNil(stringResult.variant)

let intResult = try provider.getIntegerEvaluation(key: "key", defaultValue: 4)
let intResult = try provider.getIntegerEvaluation(key: "key", defaultValue: 4, context: MutableContext())
XCTAssertNotNil(intResult.variant)

let doubleResult = try provider.getDoubleEvaluation(key: "key", defaultValue: 0.4)
let doubleResult = try provider.getDoubleEvaluation(key: "key", defaultValue: 0.4, context: MutableContext())
XCTAssertNotNil(doubleResult.variant)

let objectResult = try provider.getObjectEvaluation(key: "key", defaultValue: .null)
let objectResult = try provider.getObjectEvaluation(key: "key", defaultValue: .null, context: MutableContext())
XCTAssertNotNil(objectResult.variant)
}
}

0 comments on commit 239d101

Please sign in to comment.