Skip to content

Commit

Permalink
Add global events
Browse files Browse the repository at this point in the history
Signed-off-by: Fabrizio Demaria <[email protected]>
  • Loading branch information
fabriziodemaria committed Jan 22, 2024
1 parent 4492d91 commit 1914b88
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 22 deletions.
4 changes: 4 additions & 0 deletions Sources/OpenFeature/EventHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ public protocol EventPublisher {
func observe() -> CurrentValueSubject<ProviderEvent, Never>
}

public protocol GlobalEventPublisher {
func observe() -> PassthroughSubject<ProviderEvent, Never>
}

public protocol EventSender {
func send(_ event: ProviderEvent)
}
12 changes: 9 additions & 3 deletions Sources/OpenFeature/OpenFeatureAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import Combine

/// A global singleton which holds base configuration for the OpenFeature library.
/// Configuration here will be shared across all ``Client``s.
public class OpenFeatureAPI: EventPublisher {
public class OpenFeatureAPI: GlobalEventPublisher {
private var _provider: FeatureProvider?
private var _context: EvaluationContext?
private(set) var hooks: [any Hook] = []
private(set) var handlers: [Handler] = []
private var providerObserver: AnyCancellable?
private var globalEventState = PassthroughSubject<ProviderEvent, Never>()

/// The ``OpenFeatureAPI`` singleton
static public let shared = OpenFeatureAPI()
Expand All @@ -21,6 +23,9 @@ public class OpenFeatureAPI: EventPublisher {

public func setProvider(provider: FeatureProvider, initialContext: EvaluationContext?) {
self._provider = provider
self.providerObserver = provider.observe().sink { event in
self.globalEventState.send(event)
}
if let context = initialContext {
self._context = context
}
Expand All @@ -33,6 +38,7 @@ public class OpenFeatureAPI: EventPublisher {

public func clearProvider() {
self._provider = nil
self.providerObserver = nil
}

public func setEvaluationContext(evaluationContext: EvaluationContext) {
Expand Down Expand Up @@ -65,8 +71,8 @@ public class OpenFeatureAPI: EventPublisher {
self.hooks.removeAll()
}

public func observe() -> CurrentValueSubject<ProviderEvent, Never> {
getProvider()!.observe() // TODO Fix!
public func observe() -> PassthroughSubject<ProviderEvent, Never> {
return globalEventState
}

struct Handler {
Expand Down
35 changes: 20 additions & 15 deletions Tests/OpenFeatureTests/DeveloperExperienceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import XCTest
@testable import OpenFeature

final class DeveloperExperienceTests: XCTestCase {
let readyExpectation = XCTestExpectation(description: "Ready")

func testNoProviderSet() {
OpenFeatureAPI.shared.clearProvider()
let client = OpenFeatureAPI.shared.getClient()
Expand All @@ -21,19 +19,26 @@ final class DeveloperExperienceTests: XCTestCase {
XCTAssertFalse(flagValue)
}

// func testObserveProviderReady() {
// let cancellable = OpenFeatureAPI.shared.observe().sink { notification in
// switch notification.name {
// case ProviderEvent.ready.notificationName:
// self.readyExpectation.fulfill()
// default:
// XCTFail("Unexpected event")
// }
// }
// OpenFeatureAPI.shared.setProvider(provider: DoSomethingProvider())
// wait(for: [readyExpectation], timeout: 5)
// XCTAssertNotNil(cancellable)
// }
func testObserveProviderReady() {
let readyExpectation = XCTestExpectation(description: "Ready")
let errorExpectation = XCTestExpectation(description: "Error")
let staleExpectation = XCTestExpectation(description: "Stale")
let eventState = OpenFeatureAPI.shared.observe().sink { event in
switch event {
case ProviderEvent.ready:
readyExpectation.fulfill()
case ProviderEvent.error:
errorExpectation.fulfill()
case ProviderEvent.stale:
staleExpectation.fulfill()
default:
XCTFail("Unexpected event")
}
}
OpenFeatureAPI.shared.setProvider(provider: DoSomethingProvider())
wait(for: [readyExpectation], timeout: 5)
XCTAssertNotNil(eventState)
}

func testClientHooks() {
OpenFeatureAPI.shared.setProvider(provider: NoOpProvider())
Expand Down
8 changes: 4 additions & 4 deletions Tests/OpenFeatureTests/ProviderEventsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import XCTest

final class ProviderEventsTests: XCTestCase {
let provider = DoSomethingProvider()
let readyExpectation = XCTestExpectation(description: "Ready")

func testReadyEventSent() {
let sink = provider
let readyExpectation = XCTestExpectation(description: "Ready")
let eventState = provider
.observe()
.filter { event in
event == ProviderEvent.ready
}
.sink { _ in
self.readyExpectation.fulfill()
readyExpectation.fulfill()
}
OpenFeatureAPI.shared.setProvider(provider: provider)
wait(for: [readyExpectation], timeout: 5)
XCTAssertNotNil(sink)
XCTAssertNotNil(eventState)
}
}

0 comments on commit 1914b88

Please sign in to comment.