Skip to content

Commit

Permalink
Call out to delegate for control users in experiments (#923)
Browse files Browse the repository at this point in the history
  • Loading branch information
Adlai-Holler committed May 16, 2018
1 parent 0830f6c commit 73cdc1b
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
- Adds an experiment to call ASNetworkImageNode callbacks off main. [Garrett Moon](https://github.com/garrettmoon)
- Prevent UITextView from updating contentOffset while deallocating [Michael Schneider](https://github.com/maicki)
- [ASCollectionNode/ASTableNode] Fix a crash occurs while remeasuring cell nodes. [Huy Nguyen](https://github.com/nguyenhuy) [#917](https://github.com/TextureGroup/Texture/pull/917)
- Fix an issue where ASConfigurationDelegate would not call out for "control" users. If set, it now receives events whenever an experimental feature decision point occurs, whether it's enabled or not. [Adlai Holler](https://github.com/Adlai-Holler)

## 2.6
- [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon)
Expand Down
7 changes: 4 additions & 3 deletions Source/ASConfigurationInternal.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ - (BOOL)activateExperimentalFeature:(ASExperimentalFeatures)requested

NSAssert(__builtin_popcount(requested) == 1, @"Cannot activate multiple features at once with this method.");

// If they're disabled, ignore them.
// We need to call out, whether it's enabled or not.
// A/B testing requires even "control" users to be activated.
ASExperimentalFeatures enabled = requested & _config.experimentalFeatures;
ASExperimentalFeatures prevTriggered = atomic_fetch_or(&_activatedExperiments, enabled);
ASExperimentalFeatures newlyTriggered = enabled & ~prevTriggered;
ASExperimentalFeatures prevTriggered = atomic_fetch_or(&_activatedExperiments, requested);
ASExperimentalFeatures newlyTriggered = requested & ~prevTriggered;

// Notify delegate if needed.
if (newlyTriggered != 0) {
Expand Down
10 changes: 4 additions & 6 deletions Tests/ASConfigurationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,19 @@ - (void)testExperimentalFeatureConfig
[ASConfigurationManager test_resetWithConfiguration:config];

// Set an expectation for a callback, and assert we only get one.
XCTestExpectation *e = [self expectationWithDescription:@"Callback 1 done."];
XCTestExpectation *e = [self expectationWithDescription:@"Callbacks done."];
e.expectedFulfillmentCount = 2;
e.assertForOverFulfill = YES;
onActivate = ^(ASConfigurationTests *self, ASExperimentalFeatures feature) {
XCTAssertEqual(feature, ASExperimentalGraphicsContexts);
[e fulfill];
// Next time it's a fail.
self->onActivate = ^(ASConfigurationTests *self, ASExperimentalFeatures feature) {
XCTFail(@"Too many callbacks.");
};
};

// Now activate the graphics experiment and expect it works.
XCTAssertTrue(ASActivateExperimentalFeature(ASExperimentalGraphicsContexts));
// We should get a callback here
// Now activate text node and expect it fails.
XCTAssertFalse(ASActivateExperimentalFeature(ASExperimentalTextNode));
// But we should get another callback.
[self waitForExpectationsWithTimeout:3 handler:nil];
}

Expand Down

0 comments on commit 73cdc1b

Please sign in to comment.