Skip to content

Commit

Permalink
Remove context on child instance
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziodemaria committed Apr 9, 2024
1 parent 7947fdf commit 2b1ec7a
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 13 deletions.
13 changes: 10 additions & 3 deletions Sources/Confidence/Confidence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class Confidence: ConfidenceEventSender {
public var timeout: TimeInterval
public var region: ConfidenceRegion
public var initializationStrategy: InitializationStrategy
private var removedContextKeys: Set<String> = Set()

required public init(
clientSecret: String,
Expand All @@ -31,22 +32,28 @@ public class Confidence: ConfidenceEventSender {


public func getContext() -> ConfidenceStruct {
var mergedContext = parent?.getContext() ?? [:]
let parentContext = parent?.getContext() ?? [:]
var reconciledCtx = parentContext.filter {
!removedContextKeys.contains($0.key)
}
self.context.forEach { entry in
mergedContext.updateValue(entry.value, forKey: entry.key)
reconciledCtx.updateValue(entry.value, forKey: entry.key)
}
return mergedContext
return reconciledCtx
}

public func updateContextEntry(key: String, value: ConfidenceValue) {
context[key] = value
removedContextKeys.remove(key)
}

public func removeContextEntry(key: String) {
context.removeValue(forKey: key)
removedContextKeys.insert(key)
}

public func clearContext() {
removedContextKeys.removeAll()
context = [:]
}

Expand Down
10 changes: 7 additions & 3 deletions Sources/Confidence/Contextual.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import Foundation

/// A Contextual implementer maintains context data and can create child instances
/// A Contextual implementer maintains local context data and can create child instances
/// that can still access their parent's data
/// Each ConfidenceContextProvider returns local data reconciled with parents' data. Local data has precedence
public protocol Contextual: ConfidenceContextProvider {
/// Adds entry to local data
func updateContextEntry(key: String, value: ConfidenceValue)
/// Removes entry from local data
/// It hides entries with this key from parents' data (without modifying parents' data)
func removeContextEntry(key: String)
/// Clear local data. Parents' data is still reconciled. Previously removed parent entries are not hidden anymore
func clearContext()
/// Creates a child Contextual instance that still has access
/// to its parent context
/// Creates a child Contextual instance that maintains access to its parent's data
func withContext(_ context: ConfidenceStruct) -> Self
}
97 changes: 90 additions & 7 deletions Tests/ConfidenceTests/ConfidenceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ final class ConfidenceTests: XCTestCase {
XCTAssertEqual(confidenceChild.getContext(), expected)
}

func testUpdateContextWithOverride() {
func testUpdateLocalContext() {
let confidence = Confidence.init(
clientSecret: "",
timeout: TimeInterval(),
Expand All @@ -59,7 +59,7 @@ final class ConfidenceTests: XCTestCase {
XCTAssertEqual(confidence.getContext(), expected)
}

func testWithContextUpdateParentWithoutOverride() {
func testUpdateLocalContextWithoutOverride() {
let confidenceParent = Confidence.init(
clientSecret: "",
timeout: TimeInterval(),
Expand All @@ -70,17 +70,17 @@ final class ConfidenceTests: XCTestCase {
let confidenceChild: ConfidenceEventSender = confidenceParent.withContext(
["k2": ConfidenceValue(string: "v2")]
)
confidenceParent.updateContextEntry(
confidenceChild.updateContextEntry(
key: "k2",
value: ConfidenceValue(string: "v4"))
let expected = [
"k1": ConfidenceValue(string: "v1"),
"k2": ConfidenceValue(string: "v2"),
"k2": ConfidenceValue(string: "v4"),
]
XCTAssertEqual(confidenceChild.getContext(), expected)
}

func testWithContextUpdateChildWithOverride() {
func testUpdateParentContextWithOverride() {
let confidenceParent = Confidence.init(
clientSecret: "",
timeout: TimeInterval(),
Expand All @@ -91,12 +91,12 @@ final class ConfidenceTests: XCTestCase {
let confidenceChild: ConfidenceEventSender = confidenceParent.withContext(
["k2": ConfidenceValue(string: "v2")]
)
confidenceChild.updateContextEntry(
confidenceParent.updateContextEntry(
key: "k2",
value: ConfidenceValue(string: "v4"))
let expected = [
"k1": ConfidenceValue(string: "v1"),
"k2": ConfidenceValue(string: "v4"),
"k2": ConfidenceValue(string: "v2"),
]
XCTAssertEqual(confidenceChild.getContext(), expected)
}
Expand All @@ -119,6 +119,68 @@ final class ConfidenceTests: XCTestCase {
XCTAssertEqual(confidence.getContext(), expected)
}

func testRemoveContextEntryFromParent() {
let confidenceParent = Confidence.init(
clientSecret: "",
timeout: TimeInterval(),
region: .europe,
initializationStrategy: .activateAndFetchAsync,
context: ["k1": ConfidenceValue(string: "v1")]
)
let confidenceChild: ConfidenceEventSender = confidenceParent.withContext(
["k2": ConfidenceValue(string: "v2")]
)
confidenceChild.removeContextEntry(key: "k1")
let expected = [
"k2": ConfidenceValue(string: "v2")
]
XCTAssertEqual(confidenceChild.getContext(), expected)
}

func testRemoveContextEntryFromParentAndChild() {
let confidenceParent = Confidence.init(
clientSecret: "",
timeout: TimeInterval(),
region: .europe,
initializationStrategy: .activateAndFetchAsync,
context: ["k1": ConfidenceValue(string: "v1")]
)
let confidenceChild: ConfidenceEventSender = confidenceParent.withContext(
[
"k2": ConfidenceValue(string: "v2"),
"k1": ConfidenceValue(string: "v3"),
]
)
confidenceChild.removeContextEntry(key: "k1")
let expected = [
"k2": ConfidenceValue(string: "v2")
]
XCTAssertEqual(confidenceChild.getContext(), expected)
}

func testRemoveContextEntryFromParentAndChildThenUpdate() {
let confidenceParent = Confidence.init(
clientSecret: "",
timeout: TimeInterval(),
region: .europe,
initializationStrategy: .activateAndFetchAsync,
context: ["k1": ConfidenceValue(string: "v1")]
)
let confidenceChild: ConfidenceEventSender = confidenceParent.withContext(
[
"k2": ConfidenceValue(string: "v2"),
"k1": ConfidenceValue(string: "v3"),
]
)
confidenceChild.removeContextEntry(key: "k1")
confidenceChild.updateContextEntry(key: "k1", value: ConfidenceValue(string: "v4"))
let expected = [
"k2": ConfidenceValue(string: "v2"),
"k1": ConfidenceValue(string: "v4"),
]
XCTAssertEqual(confidenceChild.getContext(), expected)
}

func testClearContext() {
let confidence = Confidence.init(
clientSecret: "",
Expand All @@ -134,4 +196,25 @@ final class ConfidenceTests: XCTestCase {
let expected: ConfidenceStruct = [:]
XCTAssertEqual(confidence.getContext(), expected)
}

func testClearContextReturnsParentContext() {
let confidenceParent = Confidence.init(
clientSecret: "",
timeout: TimeInterval(),
region: .europe,
initializationStrategy: .activateAndFetchAsync,
context: ["k1": ConfidenceValue(string: "v1")]
)
let confidenceChild: ConfidenceEventSender = confidenceParent.withContext(
[
"k1": ConfidenceValue(string: "v1"),
"k2": ConfidenceValue(string: "v2")
]
)
confidenceChild.clearContext()
let expected = [
"k1": ConfidenceValue(string: "v1")
]
XCTAssertEqual(confidenceChild.getContext(), expected)
}
}

0 comments on commit 2b1ec7a

Please sign in to comment.