From 6bb03d5e06fa4a57ee5d5356d1b925ca207ef993 Mon Sep 17 00:00:00 2001 From: Nicklas Lundin Date: Wed, 10 Jul 2024 10:21:43 +0200 Subject: [PATCH] fix: handle Int32 and Int64 in defaultValue evaluations (#162) * test: write failing test for Integer issue * fix: handle Int32 and Int64 in defaultValue evaluations * fixup! test: write failing test for Integer issue --- Sources/Confidence/FlagEvaluation.swift | 12 ++++++- Tests/ConfidenceTests/ConfidenceTest.swift | 38 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Sources/Confidence/FlagEvaluation.swift b/Sources/Confidence/FlagEvaluation.swift index c69afa93..55eddd54 100644 --- a/Sources/Confidence/FlagEvaluation.swift +++ b/Sources/Confidence/FlagEvaluation.swift @@ -86,6 +86,7 @@ extension FlagResolution { } } + // swiftlint:disable:next cyclomatic_complexity private func getTyped(value: ConfidenceValue) -> T? { if let value = self as? T { return value @@ -97,7 +98,16 @@ extension FlagResolution { case .string: return value.asString() as? T case .integer: - return value.asInteger() as? T + if let intValue = value.asInteger() as? T { + return intValue + } + if T.self == Int32.self, let intValue = value.asInteger() { + return Int32(intValue) as? T + } + if T.self == Int64.self, let intValue = value.asInteger() { + return Int64(intValue) as? T + } + return nil case .double: return value.asDouble() as? T case .date: diff --git a/Tests/ConfidenceTests/ConfidenceTest.swift b/Tests/ConfidenceTests/ConfidenceTest.swift index 25543438..8444ad12 100644 --- a/Tests/ConfidenceTests/ConfidenceTest.swift +++ b/Tests/ConfidenceTests/ConfidenceTest.swift @@ -210,6 +210,44 @@ class ConfidenceTest: XCTestCase { } + func testResolveIntegerFlagWithInt64() async throws { + class FakeClient: ConfidenceResolveClient { + var resolveStats: Int = 0 + var resolvedValues: [ResolvedValue] = [] + func resolve(ctx: ConfidenceStruct) async throws -> ResolvesResult { + self.resolveStats += 1 + return .init(resolvedValues: resolvedValues, resolveToken: "token") + } + } + + let client = FakeClient() + client.resolvedValues = [ + ResolvedValue( + variant: "control", + value: .init(structure: ["size": .init(integer: 3)]), + flag: "flag", + resolveReason: .match) + ] + + let confidence = Confidence.Builder(clientSecret: "test") + .withContext(initialContext: ["targeting_key": .init(string: "user2")]) + .withFlagResolverClient(flagResolver: client) + .withFlagApplier(flagApplier: flagApplier) + .build() + + try await confidence.fetchAndActivate() + let value = try confidence.getValue( + key: "flag.size", + defaultValue: 0 as Int64) + + XCTAssertEqual(client.resolveStats, 1) + XCTAssertEqual(value, 3) + XCTAssertEqual(client.resolveStats, 1) + await fulfillment(of: [flagApplier.applyExpectation], timeout: 1) + XCTAssertEqual(flagApplier.applyCallCount, 1) + } + + func testResolveAndApplyIntegerFlagNoSegmentMatch() async throws { class FakeClient: ConfidenceResolveClient { var resolveStats: Int = 0