1+ import Combine
2+ import Foundation
3+
4+ @testable import OpenFeature
5+
6+ /// A mock provider that can be used to test provider events with payloads.
7+ /// It can be configured with a set of callbacks that will be called when the provider is initialized
8+ class MockProvider : FeatureProvider {
9+ static let name = " MockProvider "
10+ var metadata : ProviderMetadata = MockProviderMetadata ( )
11+
12+ var hooks : [ any Hook ] = [ ]
13+ var throwFatal = false
14+ private let eventHandler = EventHandler ( )
15+ private let _onContextSet : ( EvaluationContext ? , EvaluationContext ) async throws -> Void
16+ private let _initialize : ( EvaluationContext ? ) async throws -> Void
17+ private let _getBooleanEvaluation : ( String , Bool , EvaluationContext ? ) throws -> ProviderEvaluation < Bool >
18+ private let _getStringEvaluation : ( String , String , EvaluationContext ? ) throws -> ProviderEvaluation < String >
19+ private let _getIntegerEvaluation : ( String , Int64 , EvaluationContext ? ) throws -> ProviderEvaluation < Int64 >
20+ private let _getDoubleEvaluation : ( String , Double , EvaluationContext ? ) throws -> ProviderEvaluation < Double >
21+ private let _getObjectEvaluation : ( String , Value , EvaluationContext ? ) throws -> ProviderEvaluation < Value >
22+ private let _observe : ( ) -> AnyPublisher < ProviderEvent ? , Never >
23+
24+ /// Initialize the provider with a set of callbacks that will be called when the provider is initialized,
25+ init (
26+ onContextSet: @escaping ( EvaluationContext ? , EvaluationContext ) async throws -> Void = { _, _ in } ,
27+ initialize: @escaping ( EvaluationContext ? ) async throws -> Void = { _ in } ,
28+ getBooleanEvaluation: @escaping (
29+ String ,
30+ Bool ,
31+ EvaluationContext ?
32+ ) throws -> ProviderEvaluation < Bool > = { _, fallback, _ in
33+ return ProviderEvaluation ( value: fallback, flagMetadata: [ : ] )
34+ } ,
35+ getStringEvaluation: @escaping (
36+ String ,
37+ String ,
38+ EvaluationContext ?
39+ ) throws -> ProviderEvaluation < String > = { _, fallback, _ in
40+ return ProviderEvaluation ( value: fallback, flagMetadata: [ : ] )
41+ } ,
42+ getIntegerEvaluation: @escaping (
43+ String ,
44+ Int64 ,
45+ EvaluationContext ?
46+ ) throws -> ProviderEvaluation < Int64 > = { _, fallback, _ in
47+ return ProviderEvaluation ( value: fallback, flagMetadata: [ : ] )
48+ } ,
49+ getDoubleEvaluation: @escaping (
50+ String ,
51+ Double ,
52+ EvaluationContext ?
53+ ) throws -> ProviderEvaluation < Double > = { _, fallback, _ in
54+ return ProviderEvaluation ( value: fallback, flagMetadata: [ : ] )
55+ } ,
56+ getObjectEvaluation: @escaping (
57+ String ,
58+ Value ,
59+ EvaluationContext ?
60+ ) throws -> ProviderEvaluation < Value > = { _, fallback, _ in
61+ return ProviderEvaluation ( value: fallback, flagMetadata: [ : ] )
62+ } ,
63+ observe: @escaping ( ) -> AnyPublisher < ProviderEvent ? , Never > = { Just ( nil ) . eraseToAnyPublisher ( ) }
64+ ) {
65+ self . _onContextSet = onContextSet
66+ self . _initialize = initialize
67+ self . _getBooleanEvaluation = getBooleanEvaluation
68+ self . _getStringEvaluation = getStringEvaluation
69+ self . _getIntegerEvaluation = getIntegerEvaluation
70+ self . _getDoubleEvaluation = getDoubleEvaluation
71+ self . _getObjectEvaluation = getObjectEvaluation
72+ self . _observe = observe
73+ }
74+
75+ func onContextSet( oldContext: EvaluationContext ? , newContext: EvaluationContext ) async throws {
76+ try await _onContextSet ( oldContext, newContext)
77+ }
78+
79+ func initialize( initialContext: EvaluationContext ? ) async throws {
80+ try await _initialize ( initialContext)
81+ }
82+
83+ func getBooleanEvaluation( key: String , defaultValue: Bool , context: EvaluationContext ? ) throws
84+ -> ProviderEvaluation < Bool >
85+ {
86+ try _getBooleanEvaluation ( key, defaultValue, context)
87+ }
88+
89+ func getStringEvaluation( key: String , defaultValue: String , context: EvaluationContext ? ) throws
90+ -> ProviderEvaluation < String >
91+ {
92+ try _getStringEvaluation ( key, defaultValue, context)
93+ }
94+
95+ func getIntegerEvaluation( key: String , defaultValue: Int64 , context: EvaluationContext ? ) throws
96+ -> ProviderEvaluation < Int64 >
97+ {
98+ try _getIntegerEvaluation ( key, defaultValue, context)
99+ }
100+
101+ func getDoubleEvaluation( key: String , defaultValue: Double , context: EvaluationContext ? ) throws
102+ -> ProviderEvaluation < Double >
103+ {
104+ try _getDoubleEvaluation ( key, defaultValue, context)
105+ }
106+
107+ func getObjectEvaluation( key: String , defaultValue: Value , context: EvaluationContext ? ) throws
108+ -> ProviderEvaluation < Value >
109+ {
110+ try _getObjectEvaluation ( key, defaultValue, context)
111+ }
112+
113+ func observe( ) -> AnyPublisher < ProviderEvent ? , Never > {
114+ _observe ( )
115+ }
116+ }
117+
118+ extension MockProvider {
119+ struct MockProviderMetadata : ProviderMetadata {
120+ var name : String ? = MockProvider . name
121+ }
122+ }
123+
124+ extension MockProvider {
125+ enum MockProviderError : LocalizedError {
126+ case message( String )
127+
128+ var errorDescription : String ? {
129+ switch self {
130+ case . message( let message) :
131+ return message
132+ }
133+ }
134+ }
135+ }
0 commit comments