Skip to content

Commit 7c4fee7

Browse files
[FSSDK-11372] assign holdoutIds to feature flags (#578)
* wip: Holdout Model created * wip: add holdout model test cases * wip: assging holdoutids to feature flags * wip: included and excluded flags updated to required * wip: move OptimizelyExperiment compliance to OptmizelyConfig file * wip: fix uint test * wip: make holdouts array empty if no key presented * wip: add id and key to experiement core * wip: clean up * wip: clean up * clean up * wip: address review request * wip: Update holdout sample data * wip: update flag to holdout mapping approach * wip: holdout config struct added * wip: unit tests updated * wip: HoldoutConfig test cases added * wip: fix holdout config tests * clean up: fix test cases * cleanup: add unit test cases * Update Sources/Data Model/HoldoutConfig.swift Co-authored-by: Jae Kim <45045038+jaeopt@users.noreply.github.com> * cleanup: address review changes --------- Co-authored-by: Jae Kim <45045038+jaeopt@users.noreply.github.com>
1 parent 9d635dc commit 7c4fee7

File tree

10 files changed

+525
-30
lines changed

10 files changed

+525
-30
lines changed

OptimizelySwiftSDK.xcodeproj/project.pbxproj

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,6 +2034,24 @@
20342034
984FE51E2CC8AA88004F6F41 /* UserProfileTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984FE5102CC8AA88004F6F41 /* UserProfileTracker.swift */; };
20352035
984FE51F2CC8AA88004F6F41 /* UserProfileTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984FE5102CC8AA88004F6F41 /* UserProfileTracker.swift */; };
20362036
984FE5202CC8AA88004F6F41 /* UserProfileTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984FE5102CC8AA88004F6F41 /* UserProfileTracker.swift */; };
2037+
98AC97E22DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2038+
98AC97E32DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2039+
98AC97E42DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2040+
98AC97E52DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2041+
98AC97E62DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2042+
98AC97E72DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2043+
98AC97E82DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2044+
98AC97E92DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2045+
98AC97EA2DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2046+
98AC97EB2DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2047+
98AC97EC2DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2048+
98AC97ED2DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2049+
98AC97EE2DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2050+
98AC97EF2DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2051+
98AC97F02DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2052+
98AC97F12DAE4579001405DD /* HoldoutConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97E12DAE4579001405DD /* HoldoutConfig.swift */; };
2053+
98AC97F32DAE9685001405DD /* HoldoutConfigTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97F22DAE9685001405DD /* HoldoutConfigTests.swift */; };
2054+
98AC97F42DAE9685001405DD /* HoldoutConfigTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AC97F22DAE9685001405DD /* HoldoutConfigTests.swift */; };
20372055
BD1C3E8524E4399C0084B4DA /* SemanticVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B97DD93249D327F003DE606 /* SemanticVersion.swift */; };
20382056
BD64853C2491474500F30986 /* Optimizely.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E75167A22C520D400B2B157 /* Optimizely.h */; settings = {ATTRIBUTES = (Public, ); }; };
20392057
BD64853E2491474500F30986 /* Audience.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E75169822C520D400B2B157 /* Audience.swift */; };
@@ -2477,6 +2495,8 @@
24772495
982C071E2D8C82AE0068B1FF /* HoldoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoldoutTests.swift; sourceTree = "<group>"; };
24782496
984FE5102CC8AA88004F6F41 /* UserProfileTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileTracker.swift; sourceTree = "<group>"; };
24792497
987F11D92AF3F56F0083D3F9 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
2498+
98AC97E12DAE4579001405DD /* HoldoutConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoldoutConfig.swift; sourceTree = "<group>"; };
2499+
98AC97F22DAE9685001405DD /* HoldoutConfigTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoldoutConfigTests.swift; sourceTree = "<group>"; };
24802500
BD6485812491474500F30986 /* Optimizely.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Optimizely.framework; sourceTree = BUILT_PRODUCTS_DIR; };
24812501
C78CAF572445AD8D009FE876 /* OptimizelyJSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizelyJSON.swift; sourceTree = "<group>"; };
24822502
C78CAF652446DB91009FE876 /* OptimizelyClientTests_OptimizelyJSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizelyClientTests_OptimizelyJSON.swift; sourceTree = "<group>"; };
@@ -2857,6 +2877,7 @@
28572877
6E75169022C520D400B2B157 /* Variation.swift */,
28582878
6E75169122C520D400B2B157 /* TrafficAllocation.swift */,
28592879
6E75169222C520D400B2B157 /* Project.swift */,
2880+
98AC97E12DAE4579001405DD /* HoldoutConfig.swift */,
28602881
6E75169322C520D400B2B157 /* Experiment.swift */,
28612882
980CC9072D833F2800E07D24 /* ExperimentCore.swift */,
28622883
980CC8F62D833F0D00E07D24 /* Holdout.swift */,
@@ -3048,6 +3069,7 @@
30483069
6E7519A622C5211100B2B157 /* AttributeValueTests_Evaluate.swift */,
30493070
6E7519A722C5211100B2B157 /* RolloutTests.swift */,
30503071
6E7519A822C5211100B2B157 /* ProjectConfigTests.swift */,
3072+
98AC97F22DAE9685001405DD /* HoldoutConfigTests.swift */,
30513073
6E7519A922C5211100B2B157 /* UserAttributeTests.swift */,
30523074
6E7519AA22C5211100B2B157 /* GroupTests.swift */,
30533075
6E7519AB22C5211100B2B157 /* VariationTests.swift */,
@@ -4181,6 +4203,7 @@
41814203
845945C3287758A100D13E11 /* OdpConfig.swift in Sources */,
41824204
6E14CD832423F9A100010234 /* DataStoreQueueStackImpl.swift in Sources */,
41834205
848617F12863E21200B7F41B /* OdpEventApiManager.swift in Sources */,
4206+
98AC97E52DAE4579001405DD /* HoldoutConfig.swift in Sources */,
41844207
6E14CD812423F9A100010234 /* DataStoreUserDefaults.swift in Sources */,
41854208
6E14CD802423F9A100010234 /* DataStoreMemory.swift in Sources */,
41864209
6E14CDA02423F9C300010234 /* OptimizelyClient+Extension.swift in Sources */,
@@ -4369,6 +4392,7 @@
43694392
6E424CB926324B1D0081004A /* Constants.swift in Sources */,
43704393
6E424CBA26324B1D0081004A /* Notifications.swift in Sources */,
43714394
6E424CBB26324B1D0081004A /* MurmurHash3.swift in Sources */,
4395+
98AC97EC2DAE4579001405DD /* HoldoutConfig.swift in Sources */,
43724396
8464087628130D3200CCF97D /* Integration.swift in Sources */,
43734397
848617CE2863DC2700B7F41B /* OdpSegmentManager.swift in Sources */,
43744398
848617F02863E21200B7F41B /* OdpEventApiManager.swift in Sources */,
@@ -4410,6 +4434,7 @@
44104434
845945BD2877589E00D13E11 /* OdpConfig.swift in Sources */,
44114435
984FE51C2CC8AA88004F6F41 /* UserProfileTracker.swift in Sources */,
44124436
6E75171322C520D400B2B157 /* OptimizelyClient+ObjC.swift in Sources */,
4437+
98AC97EF2DAE4579001405DD /* HoldoutConfig.swift in Sources */,
44134438
6E75191922C520D500B2B157 /* OPTNotificationCenter.swift in Sources */,
44144439
6E7518A122C520D400B2B157 /* FeatureFlag.swift in Sources */,
44154440
6E994B3525A3E6EA00999262 /* DecisionResponse.swift in Sources */,
@@ -4494,6 +4519,7 @@
44944519
845945C7287758A300D13E11 /* OdpConfig.swift in Sources */,
44954520
6E75175622C520D400B2B157 /* LogMessage.swift in Sources */,
44964521
848617F62863E21200B7F41B /* OdpEventApiManager.swift in Sources */,
4522+
98AC97EB2DAE4579001405DD /* HoldoutConfig.swift in Sources */,
44974523
6E75193822C520D500B2B157 /* OPTDataStore.swift in Sources */,
44984524
6E75191422C520D500B2B157 /* BackgroundingCallbacks.swift in Sources */,
44994525
6E75172622C520D400B2B157 /* OptimizelyResult.swift in Sources */,
@@ -4596,6 +4622,7 @@
45964622
6EF8DE2024BD1BB2008B9488 /* OptimizelyDecideOption.swift in Sources */,
45974623
6E7517D822C520D400B2B157 /* DefaultNotificationCenter.swift in Sources */,
45984624
6E75177622C520D400B2B157 /* SDKVersion.swift in Sources */,
4625+
98AC97E32DAE4579001405DD /* HoldoutConfig.swift in Sources */,
45994626
84518B1F287665020023F104 /* OptimizelyClientTests_ODP.swift in Sources */,
46004627
6E7516FE22C520D400B2B157 /* OptimizelyLogLevel.swift in Sources */,
46014628
6E75173A22C520D400B2B157 /* MurmurHash3.swift in Sources */,
@@ -4720,6 +4747,7 @@
47204747
6EC6DD4A24ABF89B0017D296 /* OptimizelyUserContext.swift in Sources */,
47214748
6E75170122C520D400B2B157 /* OptimizelyLogLevel.swift in Sources */,
47224749
8464087B28130D3200CCF97D /* Integration.swift in Sources */,
4750+
98AC97EA2DAE4579001405DD /* HoldoutConfig.swift in Sources */,
47234751
84E2E96C28540B5E001114AB /* OptimizelySdkSettings.swift in Sources */,
47244752
6EF8DE3A24BF7D69008B9488 /* DecisionReasons.swift in Sources */,
47254753
6E7516B922C520D400B2B157 /* DefaultUserProfileService.swift in Sources */,
@@ -4866,6 +4894,7 @@
48664894
6E7517C522C520D400B2B157 /* DefaultDatafileHandler.swift in Sources */,
48674895
6E75190922C520D500B2B157 /* Attribute.swift in Sources */,
48684896
6E75177B22C520D400B2B157 /* SDKVersion.swift in Sources */,
4897+
98AC97F12DAE4579001405DD /* HoldoutConfig.swift in Sources */,
48694898
84E7ABC827D2A1F100447CAE /* ThreadSafeLogger.swift in Sources */,
48704899
6E7E9B562523F8C6009E4426 /* OptimizelyUserContextTests_Decide_Legacy.swift in Sources */,
48714900
6EC6DD3C24ABF6990017D296 /* OptimizelyClient+Decide.swift in Sources */,
@@ -5035,6 +5064,7 @@
50355064
84E7ABC927D2A1F100447CAE /* ThreadSafeLogger.swift in Sources */,
50365065
6E9B119122C5488300C22D81 /* EventForDispatchTests.swift in Sources */,
50375066
6E7517EA22C520D400B2B157 /* DefaultDecisionService.swift in Sources */,
5067+
98AC97F02DAE4579001405DD /* HoldoutConfig.swift in Sources */,
50385068
6E75171C22C520D400B2B157 /* OptimizelyClient+ObjC.swift in Sources */,
50395069
6E7516B022C520D400B2B157 /* DefaultLogger.swift in Sources */,
50405070
0B97DD9C249D3735003DE606 /* SemanticVersion.swift in Sources */,
@@ -5059,6 +5089,7 @@
50595089
6E8A3D522637408500DAEA13 /* MockDatafileHandler.swift in Sources */,
50605090
6E75180E22C520D400B2B157 /* DataStoreFile.swift in Sources */,
50615091
6E9B11B822C5489600C22D81 /* OTUtils.swift in Sources */,
5092+
98AC97F42DAE9685001405DD /* HoldoutConfigTests.swift in Sources */,
50625093
6E9B119022C5488300C22D81 /* AttributeValueTests.swift in Sources */,
50635094
6E994B4025A3E6EA00999262 /* DecisionResponse.swift in Sources */,
50645095
84E2E9802855875E001114AB /* OdpEventManager.swift in Sources */,
@@ -5159,6 +5190,7 @@
51595190
6E7516B522C520D400B2B157 /* DefaultUserProfileService.swift in Sources */,
51605191
6E7516A922C520D400B2B157 /* DefaultLogger.swift in Sources */,
51615192
6E7517D722C520D400B2B157 /* DefaultNotificationCenter.swift in Sources */,
5193+
98AC97E72DAE4579001405DD /* HoldoutConfig.swift in Sources */,
51625194
6E75181F22C520D400B2B157 /* BatchEventBuilder.swift in Sources */,
51635195
84F6BADD27FD011B004BE62A /* OptimizelyUserContextTests_ODP_Decide.swift in Sources */,
51645196
84E2E9472852A378001114AB /* VuidManager.swift in Sources */,
@@ -5309,6 +5341,7 @@
53095341
84E7ABC427D2A1F100447CAE /* ThreadSafeLogger.swift in Sources */,
53105342
6E9B117B22C5488100C22D81 /* EventForDispatchTests.swift in Sources */,
53115343
6E7517E522C520D400B2B157 /* DefaultDecisionService.swift in Sources */,
5344+
98AC97E92DAE4579001405DD /* HoldoutConfig.swift in Sources */,
53125345
6E75171722C520D400B2B157 /* OptimizelyClient+ObjC.swift in Sources */,
53135346
6E7516AB22C520D400B2B157 /* DefaultLogger.swift in Sources */,
53145347
0B97DD9B249D3733003DE606 /* SemanticVersion.swift in Sources */,
@@ -5333,6 +5366,7 @@
53335366
6E8A3D4D2637408500DAEA13 /* MockDatafileHandler.swift in Sources */,
53345367
6E75180922C520D400B2B157 /* DataStoreFile.swift in Sources */,
53355368
6E9B11AE22C5489300C22D81 /* OTUtils.swift in Sources */,
5369+
98AC97F32DAE9685001405DD /* HoldoutConfigTests.swift in Sources */,
53365370
6E9B117A22C5488100C22D81 /* AttributeValueTests.swift in Sources */,
53375371
6E994B3B25A3E6EA00999262 /* DecisionResponse.swift in Sources */,
53385372
84E2E97B2855875E001114AB /* OdpEventManager.swift in Sources */,
@@ -5433,6 +5467,7 @@
54335467
84E7ABC527D2A1F100447CAE /* ThreadSafeLogger.swift in Sources */,
54345468
6E7518BE22C520D400B2B157 /* Variable.swift in Sources */,
54355469
6E7518CA22C520D400B2B157 /* Audience.swift in Sources */,
5470+
98AC97E62DAE4579001405DD /* HoldoutConfig.swift in Sources */,
54365471
848617E42863E21200B7F41B /* OdpSegmentApiManager.swift in Sources */,
54375472
6E75187622C520D400B2B157 /* Variation.swift in Sources */,
54385473
6E7517F222C520D400B2B157 /* DataStoreMemory.swift in Sources */,
@@ -5537,6 +5572,7 @@
55375572
84E7ABCA27D2A1F100447CAE /* ThreadSafeLogger.swift in Sources */,
55385573
6E7518C322C520D400B2B157 /* Variable.swift in Sources */,
55395574
6E7518CF22C520D400B2B157 /* Audience.swift in Sources */,
5575+
98AC97E42DAE4579001405DD /* HoldoutConfig.swift in Sources */,
55405576
848617E92863E21200B7F41B /* OdpSegmentApiManager.swift in Sources */,
55415577
6E75187B22C520D400B2B157 /* Variation.swift in Sources */,
55425578
6E7517F722C520D400B2B157 /* DataStoreMemory.swift in Sources */,
@@ -5592,6 +5628,7 @@
55925628
845945BC2877589D00D13E11 /* OdpConfig.swift in Sources */,
55935629
984FE5192CC8AA88004F6F41 /* UserProfileTracker.swift in Sources */,
55945630
6E75184022C520D400B2B157 /* Event.swift in Sources */,
5631+
98AC97EE2DAE4579001405DD /* HoldoutConfig.swift in Sources */,
55955632
6E7516E222C520D400B2B157 /* OPTEventDispatcher.swift in Sources */,
55965633
6E7517D422C520D400B2B157 /* DefaultNotificationCenter.swift in Sources */,
55975634
6E994B3425A3E6EA00999262 /* DecisionResponse.swift in Sources */,
@@ -5676,6 +5713,7 @@
56765713
845945C02877589F00D13E11 /* OdpConfig.swift in Sources */,
56775714
6E75175022C520D400B2B157 /* LogMessage.swift in Sources */,
56785715
848617EE2863E21200B7F41B /* OdpEventApiManager.swift in Sources */,
5716+
98AC97E82DAE4579001405DD /* HoldoutConfig.swift in Sources */,
56795717
6E75193222C520D500B2B157 /* OPTDataStore.swift in Sources */,
56805718
6E75190E22C520D500B2B157 /* BackgroundingCallbacks.swift in Sources */,
56815719
6E75172022C520D400B2B157 /* OptimizelyResult.swift in Sources */,
@@ -5841,6 +5879,7 @@
58415879
75C71A3125E454460084187E /* Group.swift in Sources */,
58425880
75C71A3225E454460084187E /* Variable.swift in Sources */,
58435881
848617DD2863E21200B7F41B /* OdpSegmentApiManager.swift in Sources */,
5882+
98AC97E22DAE4579001405DD /* HoldoutConfig.swift in Sources */,
58445883
75C71A3325E454460084187E /* Attribute.swift in Sources */,
58455884
75C71A3425E454460084187E /* BackgroundingCallbacks.swift in Sources */,
58465885
75C71A3525E454460084187E /* OPTNotificationCenter.swift in Sources */,
@@ -5890,6 +5929,7 @@
58905929
845945BE2877589E00D13E11 /* OdpConfig.swift in Sources */,
58915930
984FE51A2CC8AA88004F6F41 /* UserProfileTracker.swift in Sources */,
58925931
BD6485462491474500F30986 /* Event.swift in Sources */,
5932+
98AC97ED2DAE4579001405DD /* HoldoutConfig.swift in Sources */,
58935933
BD6485472491474500F30986 /* OPTEventDispatcher.swift in Sources */,
58945934
BD6485482491474500F30986 /* DefaultNotificationCenter.swift in Sources */,
58955935
6E994B3625A3E6EA00999262 /* DecisionResponse.swift in Sources */,

Sources/Data Model/FeatureFlag.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ struct FeatureFlag: Codable, Equatable, OptimizelyFeature {
3535
case variables
3636
}
3737

38+
// var holdoutIds: [String] = []
39+
3840
// MARK: - OptimizelyConfig
3941

4042
var experimentsMap: [String: OptimizelyExperiment] = [:]

Sources/Data Model/Holdout.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,10 @@ struct Holdout: Codable, ExperimentCore {
3939
case id, key, status, layerId, variations, trafficAllocation, audienceIds, audienceConditions, includedFlags, excludedFlags
4040
}
4141

42-
var variationsMap: [String : OptimizelyVariation] = [:]
42+
var variationsMap: [String: OptimizelyVariation] = [:]
4343
// replace with serialized string representation with audience names when ProjectConfig is ready
4444
var audiences: String = ""
4545

46-
4746
init(from decoder: Decoder) throws {
4847
let container = try decoder.container(keyedBy: CodingKeys.self)
4948

@@ -76,7 +75,6 @@ extension Holdout: Equatable {
7675
}
7776
}
7877

79-
8078
extension Holdout {
8179
var isActivated: Bool {
8280
return status == .running

0 commit comments

Comments
 (0)