[sub-spm-optional-products] Add LCECryptoKit and LCFeatureControl as optional sub-SPM products
LCEssentials installs standalone; each sub target-depends on it so linking a sub's product always pulls LCEssentials in too, without the consumer having to declare it separately. - LCECryptoKit: internalized from the remote LCECryptoKitBinary git dependency (embedded token URL removed) into a local binaryTarget vendoring Frameworks/LCECryptoKit.xcframework. LCECryptoKitManager moved out of LCEssentials core into its own LCECryptoKitManager target/product; the no-op fallback for when the binary wasn't linked is gone (breaking change for existing consumers, see decisions/2026-09-15-sub-spm-optional-products.md). - LCFeatureControl: new product wrapping Atomenta's Feature Control API (flag evaluation with TTL cache + safe-degrade fallback to defaults, notifications inbox, batched exposure telemetry). 45 new tests.
This commit is contained in:
40
Tests/LCFeatureControlTests/FeatureControlJSONTests.swift
Normal file
40
Tests/LCFeatureControlTests/FeatureControlJSONTests.swift
Normal file
@@ -0,0 +1,40 @@
|
||||
import XCTest
|
||||
@testable import LCFeatureControl
|
||||
|
||||
final class FeatureControlJSONTests: XCTestCase {
|
||||
|
||||
private func decode(_ json: String) throws -> FeatureControlJSON {
|
||||
try JSONDecoder().decode(FeatureControlJSON.self, from: Data(json.utf8))
|
||||
}
|
||||
|
||||
func testDecodesNull() throws {
|
||||
XCTAssertEqual(try decode("null"), .null)
|
||||
}
|
||||
|
||||
func testDecodesBool() throws {
|
||||
XCTAssertEqual(try decode("true"), .bool(true))
|
||||
}
|
||||
|
||||
func testDecodesNumber() throws {
|
||||
XCTAssertEqual(try decode("5"), .number(5))
|
||||
}
|
||||
|
||||
func testDecodesString() throws {
|
||||
XCTAssertEqual(try decode("\"hello\""), .string("hello"))
|
||||
}
|
||||
|
||||
func testDecodesArray() throws {
|
||||
XCTAssertEqual(try decode("[\"a\",\"b\"]"), .array([.string("a"), .string("b")]))
|
||||
}
|
||||
|
||||
func testDecodesNestedObject() throws {
|
||||
let json = #"{"limit": 5, "tags": ["a","b"], "nested": {"x": true}}"#
|
||||
let value = try decode(json)
|
||||
guard case let .object(object) = value else {
|
||||
return XCTFail("expected .object, got \(value)")
|
||||
}
|
||||
XCTAssertEqual(object["limit"], .number(5))
|
||||
XCTAssertEqual(object["tags"], .array([.string("a"), .string("b")]))
|
||||
XCTAssertEqual(object["nested"], .object(["x": .bool(true)]))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user