Skip to content

Commit 65d4f58

Browse files
committed
[APP-2869] Add Combine and SwiftUI bridges (#125)
1 parent 300e800 commit 65d4f58

12 files changed

+702
-30
lines changed

.circleci/config.yml

+45-30
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
version: 2.1
55

66
anchors:
7-
- &test_device "iPhone Xs"
7+
- &test_device "iPhone 14"
8+
- &test_device_os "16.2"
89
- &clean_before_build true
9-
- &test_output_folder test_output
1010
- &default_executor
1111
macos:
12-
xcode: "14.0.0"
12+
xcode: "14.2.0"
1313

1414
env:
1515
global:
@@ -36,11 +36,18 @@ commands:
3636
pod install --verbose
3737
3838
test_main_project:
39+
parameters:
40+
simulator:
41+
type: string
42+
default: *test_device
43+
os_version:
44+
type: string
45+
default: *test_device_os
3946
steps:
4047
- checkout
4148
- test_project_and_store_results:
42-
project: "Flow.xcodeproj"
43-
scheme: "Flow"
49+
simulator: <<parameters.simulator>>
50+
os_version: <<parameters.os_version>>
4451

4552
test_example_project:
4653
parameters:
@@ -54,30 +61,32 @@ commands:
5461
workspace: "Example.xcworkspace"
5562
scheme: "Example"
5663
path: <<parameters.path>>
57-
test_output_folder: *test_output_folder
5864

5965
# We introduced two separate commands for projects and workspaces because we didn't find a generic and non-confusing way to introduce
60-
# a condition to only pass either the project or the workspace environment argument to the fastlane scan
66+
# a condition to only pass either the project or the workspace environment argument to the test output
6167
test_project_and_store_results:
6268
description: "Builds and tests a project and then stores the results of the tests as artifacts and test results report"
6369
parameters:
64-
project:
70+
simulator:
6571
type: string
66-
scheme:
72+
default: *test_device
73+
os_version:
6774
type: string
75+
default: *test_device_os
6876
steps:
6977
- run:
70-
command: fastlane scan
71-
environment:
72-
SCAN_PROJECT: <<parameters.project>>
73-
SCAN_SCHEME: <<parameters.scheme>>
74-
SCAN_DEVICE: *test_device
75-
SCAN_CLEAN: *clean_before_build
78+
name: Run tests on iOS <<parameters.os_version>>
79+
command: |
80+
xcodebuild -scheme Flow \
81+
-project Flow.xcodeproj \
82+
-destination "platform=iOS Simulator,OS=<<parameters.os_version>>,name=<<parameters.simulator>>" \
83+
build test \
84+
| xcpretty --report junit --output 'test_output/report.junit'
7685
- store_artifacts: # This will by default store an html and junit file as artifacts (See "Artifacts" tab in CircleCI report)
77-
path: *test_output_folder # test_output is the default temporary folder for fastlane scan output
78-
destination: *test_output_folder # This will create a sub structure in the artifacts section in CircleCI
86+
path: test_output # test_output is the default temporary folder for test output
87+
destination: test_output # This will create a sub structure in the artifacts section in CircleCI
7988
- store_test_results: # This will store the test results so you can then see them in the "Test Summary" tab in CircleCI report
80-
path: *test_output_folder
89+
path: test_output
8190

8291
test_workspace_and_store_results:
8392
description: "Builds and tests a workspace and then stores the results of the tests as artifacts and test results report"
@@ -88,23 +97,27 @@ commands:
8897
type: string
8998
path:
9099
type: string
91-
test_output_folder:
100+
simulator:
92101
type: string
102+
default: *test_device
103+
os_version:
104+
type: string
105+
default: *test_device_os
93106
steps:
94107
- run:
95-
command: |
108+
name: Run examples
109+
command: |
96110
cd <<parameters.path>>
97-
fastlane scan
98-
environment:
99-
SCAN_WORKSPACE: <<parameters.workspace>>
100-
SCAN_SCHEME: <<parameters.scheme>>
101-
SCAN_DEVICE: *test_device
102-
SCAN_CLEAN: *clean_before_build
111+
xcodebuild -workspace <<parameters.workspace>> \
112+
-scheme <<parameters.scheme>> \
113+
-destination "platform=iOS Simulator,OS=<<parameters.os_version>>,name=<<parameters.simulator>>" \
114+
build test \
115+
| xcpretty --report junit --output 'test_output/report.junit'
103116
- store_artifacts: # This will by default store an html and junit file as artifacts (See "Artifacts" tab in CircleCI report)
104-
path: <<parameters.path>>/<<parameters.test_output_folder>> # test_output is the default temporary folder for fastlane scan output
105-
destination: <<parameters.test_output_folder>> # This will create a sub structure in the artifacts section in CircleCI
117+
path: <<parameters.path>>/test_output # test_output is the default temporary folder for test output
118+
destination: test_output # This will create a sub structure in the artifacts section in CircleCI
106119
- store_test_results: # This will store the test results so you can then see them in the "Test Summary" tab in CircleCI report
107-
path: <<parameters.path>>/<<parameters.test_output_folder>>
120+
path: <<parameters.path>>/test_output
108121

109122
jobs:
110123
swiftlint:
@@ -136,7 +149,9 @@ jobs:
136149
macos:
137150
xcode: "13.0.0"
138151
steps:
139-
- test_main_project
152+
- test_main_project:
153+
simulator: "iPhone 13"
154+
os_version: "15.0"
140155

141156
test-xcode14-ios16:
142157
<<: *default_executor

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# 1.11.0
2+
- Add Compose and SwiftUI bridging functions
3+
14
# 1.10.2
25
- Specify type of the library for `spm` builds as `dynamic`
36

Disposable+CombineTests.swift

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//
2+
// Disposable+CombineTests.swift
3+
// Flow
4+
//
5+
// Created by Carl Ekman on 2023-02-09.
6+
// Copyright © 2023 PayPal Inc. All rights reserved.
7+
//
8+
9+
import XCTest
10+
#if DEBUG
11+
@testable import Flow
12+
#else
13+
import Flow
14+
#endif
15+
import Foundation
16+
#if canImport(Combine)
17+
import Combine
18+
19+
@available(iOS 13.0, macOS 10.15, *)
20+
final class Disposable_CombineTests: XCTestCase {
21+
22+
var bag = CancelBag()
23+
24+
override func tearDownWithError() throws {
25+
bag.cancel()
26+
27+
try super.tearDownWithError()
28+
}
29+
30+
func testCancellingDisposable() {
31+
let disposed = expectation(description: "Disposed")
32+
33+
let disposer = Disposer { disposed.fulfill() }
34+
disposer.asAnyCancellable.cancel()
35+
36+
wait(for: [disposed], timeout: 1)
37+
}
38+
39+
func testCancelBag() {
40+
var bag = CancelBag()
41+
42+
let cancelled1 = expectation(description: "Cancelled 1")
43+
let cancelled2 = expectation(description: "Cancelled 2")
44+
let cancelled3 = expectation(description: "Cancelled 3")
45+
46+
bag += { cancelled1.fulfill() }
47+
bag += { cancelled2.fulfill() }
48+
bag += { cancelled3.fulfill() }
49+
50+
bag.cancel()
51+
XCTAssertFalse(bag.isEmpty)
52+
53+
wait(for: [cancelled1, cancelled2, cancelled3], timeout: 1)
54+
XCTAssertFalse(bag.isEmpty)
55+
56+
bag.empty()
57+
XCTAssertTrue(bag.isEmpty)
58+
}
59+
60+
func testCancellingDisposeBag() {
61+
let bag = DisposeBag()
62+
63+
let cancelled1 = expectation(description: "Cancelled 1")
64+
let cancelled2 = expectation(description: "Cancelled 2")
65+
let cancelled3 = expectation(description: "Cancelled 3")
66+
67+
bag += { cancelled1.fulfill() }
68+
bag += { cancelled2.fulfill() }
69+
bag += { cancelled3.fulfill() }
70+
71+
bag.asAnyCancellable.cancel()
72+
73+
wait(for: [cancelled1, cancelled2, cancelled3], timeout: 1)
74+
}
75+
76+
func testDisposeBagToCancelBag() {
77+
let disposeBag = DisposeBag()
78+
79+
let disposed = expectation(description: "Disposed")
80+
81+
disposeBag += { disposed.fulfill() }
82+
83+
var cancelBag = CancelBag(disposable: disposeBag)
84+
cancelBag.empty()
85+
86+
wait(for: [disposed], timeout: 1)
87+
}
88+
89+
func testCancelPublisherSink() {
90+
let callbacker = Callbacker<Event<Int>>()
91+
92+
let signal = FiniteSignal(callbacker: callbacker)
93+
let publisher = signal.asAnyPublisher
94+
95+
let cancelled = expectation(description: "Cancelled")
96+
97+
bag += { cancelled.fulfill() }
98+
99+
publisher.sink { _ in
100+
XCTFail("Did not expect completion")
101+
} receiveValue: { _ in
102+
XCTFail("Did not expect value")
103+
}.store(in: &bag)
104+
105+
bag.cancel()
106+
callbacker.callAll(with: .value(1))
107+
callbacker.callAll(with: .end(TestError.fatal))
108+
109+
wait(for: [cancelled], timeout: 1)
110+
}
111+
112+
}
113+
114+
#endif

Flow.xcodeproj/project.pbxproj

+45
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,19 @@
1111
215DEF371DEC368700CEB724 /* RecursiveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215DEF351DEC367E00CEB724 /* RecursiveTests.swift */; };
1212
21E1D41C1D9502A300A91CA0 /* Future+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21E1D41B1D9502A300A91CA0 /* Future+Signal.swift */; };
1313
5B46DE3D22E9CC5E00E0A4D9 /* PrefetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B46DE3B22E9CBFA00E0A4D9 /* PrefetchTests.swift */; };
14+
5BB2E8AD2994238C0095F9E1 /* Signal+CombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB2E8AC2994238C0095F9E1 /* Signal+CombineTests.swift */; };
15+
5BB2E8C32994E5360095F9E1 /* Signal+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB2E8C02994E5360095F9E1 /* Signal+SwiftUI.swift */; };
16+
5BB2E8C42994E5360095F9E1 /* Future+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB2E8C22994E5360095F9E1 /* Future+Combine.swift */; };
17+
5BB2E8C52994E5360095F9E1 /* Signal+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB2E8C12994E5360095F9E1 /* Signal+Combine.swift */; };
18+
5BB2E8CC2994F0160095F9E1 /* Future+CombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB2E8CA2994F0080095F9E1 /* Future+CombineTests.swift */; };
1419
5BE9055B3538F1DDAB424AD2 /* FutureAdditionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE90C011B621BC2F0B9C1B8 /* FutureAdditionsTests.swift */; };
1520
7484FA6B212D9E930076FD3E /* Signal+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7484FA6A212D9E930076FD3E /* Signal+Debug.swift */; };
1621
792AC15B227C8A6800F8BBAD /* SignalProviderTests+Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 792AC15A227C8A6800F8BBAD /* SignalProviderTests+Internal.swift */; };
1722
8E890FC106FB7A89BD1727CC /* EitherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E890194B06CBB3311E44757 /* EitherTests.swift */; };
23+
B6B4E3572994FB6500D7FFF2 /* Disposable+Cancellable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4E3562994FB6500D7FFF2 /* Disposable+Cancellable.swift */; };
24+
B6B4E35A299506BF00D7FFF2 /* Disposable+CombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4E3582995028900D7FFF2 /* Disposable+CombineTests.swift */; };
25+
B6B4E35C29952CCC00D7FFF2 /* CancelBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4E35B29952CCC00D7FFF2 /* CancelBag.swift */; };
26+
B6B4E36029954B4600D7FFF2 /* Publisher+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4E35F29954B4600D7FFF2 /* Publisher+Utilities.swift */; };
1827
DA6D58EF230E925700564CC1 /* MemoryUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6D58EB230E918800564CC1 /* MemoryUtilsTests.swift */; };
1928
F610ABAE1D91743500A161AB /* Future+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F610ABA71D91743500A161AB /* Future+Additions.swift */; };
2029
F610ABB01D91743500A161AB /* FutureQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = F610ABA91D91743500A161AB /* FutureQueue.swift */; };
@@ -86,10 +95,19 @@
8695
215DEF351DEC367E00CEB724 /* RecursiveTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RecursiveTests.swift; path = FlowTests/RecursiveTests.swift; sourceTree = SOURCE_ROOT; };
8796
21E1D41B1D9502A300A91CA0 /* Future+Signal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Future+Signal.swift"; path = "Flow/Future+Signal.swift"; sourceTree = SOURCE_ROOT; };
8897
5B46DE3B22E9CBFA00E0A4D9 /* PrefetchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PrefetchTests.swift; path = FlowTests/PrefetchTests.swift; sourceTree = "<group>"; };
98+
5BB2E8AC2994238C0095F9E1 /* Signal+CombineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Signal+CombineTests.swift"; path = "FlowTests/Signal+CombineTests.swift"; sourceTree = "<group>"; };
99+
5BB2E8C02994E5360095F9E1 /* Signal+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Signal+SwiftUI.swift"; sourceTree = "<group>"; };
100+
5BB2E8C12994E5360095F9E1 /* Signal+Combine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Signal+Combine.swift"; sourceTree = "<group>"; };
101+
5BB2E8C22994E5360095F9E1 /* Future+Combine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Future+Combine.swift"; sourceTree = "<group>"; };
102+
5BB2E8CA2994F0080095F9E1 /* Future+CombineTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Future+CombineTests.swift"; path = "FlowTests/Future+CombineTests.swift"; sourceTree = "<group>"; };
89103
5BE90C011B621BC2F0B9C1B8 /* FutureAdditionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FutureAdditionsTests.swift; path = FlowTests/FutureAdditionsTests.swift; sourceTree = "<group>"; };
90104
7484FA6A212D9E930076FD3E /* Signal+Debug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Signal+Debug.swift"; path = "Flow/Signal+Debug.swift"; sourceTree = "<group>"; };
91105
792AC15A227C8A6800F8BBAD /* SignalProviderTests+Internal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "SignalProviderTests+Internal.swift"; path = "FlowTests/SignalProviderTests+Internal.swift"; sourceTree = "<group>"; };
92106
8E890194B06CBB3311E44757 /* EitherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EitherTests.swift; path = FlowTests/EitherTests.swift; sourceTree = "<group>"; };
107+
B6B4E3562994FB6500D7FFF2 /* Disposable+Cancellable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Disposable+Cancellable.swift"; sourceTree = "<group>"; };
108+
B6B4E3582995028900D7FFF2 /* Disposable+CombineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Disposable+CombineTests.swift"; sourceTree = "<group>"; };
109+
B6B4E35B29952CCC00D7FFF2 /* CancelBag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelBag.swift; sourceTree = "<group>"; };
110+
B6B4E35F29954B4600D7FFF2 /* Publisher+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Publisher+Utilities.swift"; sourceTree = "<group>"; };
93111
DA6D58EB230E918800564CC1 /* MemoryUtilsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MemoryUtilsTests.swift; path = FlowTests/MemoryUtilsTests.swift; sourceTree = "<group>"; };
94112
F610ABA61D91743500A161AB /* Future.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Future.swift; path = Flow/Future.swift; sourceTree = SOURCE_ROOT; };
95113
F610ABA71D91743500A161AB /* Future+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Future+Additions.swift"; path = "Flow/Future+Additions.swift"; sourceTree = SOURCE_ROOT; };
@@ -178,6 +196,20 @@
178196
/* End PBXFrameworksBuildPhase section */
179197

180198
/* Begin PBXGroup section */
199+
5BB2E8C72994E54C0095F9E1 /* Bridges */ = {
200+
isa = PBXGroup;
201+
children = (
202+
B6B4E35B29952CCC00D7FFF2 /* CancelBag.swift */,
203+
5BB2E8C22994E5360095F9E1 /* Future+Combine.swift */,
204+
5BB2E8C12994E5360095F9E1 /* Signal+Combine.swift */,
205+
5BB2E8C02994E5360095F9E1 /* Signal+SwiftUI.swift */,
206+
B6B4E3562994FB6500D7FFF2 /* Disposable+Cancellable.swift */,
207+
B6B4E35F29954B4600D7FFF2 /* Publisher+Utilities.swift */,
208+
);
209+
name = Bridges;
210+
path = Flow/Bridges;
211+
sourceTree = "<group>";
212+
};
181213
F6442D7220C6C9A400319327 /* Frameworks */ = {
182214
isa = PBXGroup;
183215
children = (
@@ -254,6 +286,7 @@
254286
F688B944205FB78B00BA5A70 /* FlowFramework.podspec */,
255287
F688B943205FB78A00BA5A70 /* Package.swift */,
256288
F6EDC6DE2066BD39007AC39B /* Documentation */,
289+
5BB2E8C72994E54C0095F9E1 /* Bridges */,
257290
F6A8803C1D9181EC00CA257F /* Signal */,
258291
F6D80B5B1BBBB2ED008F8574 /* Future */,
259292
F66F8528205AAE5700347601 /* Scheduler */,
@@ -315,6 +348,9 @@
315348
5BE90C011B621BC2F0B9C1B8 /* FutureAdditionsTests.swift */,
316349
5B46DE3B22E9CBFA00E0A4D9 /* PrefetchTests.swift */,
317350
DA6D58EB230E918800564CC1 /* MemoryUtilsTests.swift */,
351+
5BB2E8AC2994238C0095F9E1 /* Signal+CombineTests.swift */,
352+
5BB2E8CA2994F0080095F9E1 /* Future+CombineTests.swift */,
353+
B6B4E3582995028900D7FFF2 /* Disposable+CombineTests.swift */,
318354
);
319355
name = Tests;
320356
sourceTree = "<group>";
@@ -476,6 +512,7 @@
476512
F6B6A65F2056AEA400B9FC9D /* ReadSignal.swift in Sources */,
477513
F6FF03E71D926AC300B93771 /* Utilities.swift in Sources */,
478514
F66C47A720077B2500333410 /* Signal+Combiners.swift in Sources */,
515+
5BB2E8C42994E5360095F9E1 /* Future+Combine.swift in Sources */,
479516
F662C0A71FDFDEB300E5F869 /* Signal+Scheduling.swift in Sources */,
480517
F6FF03E41D926AC300B93771 /* CoreSignal.swift in Sources */,
481518
F67C4798206CDDCC00BEBDFD /* FiniteSignal.swift in Sources */,
@@ -486,18 +523,23 @@
486523
F6FF03E21D926AC300B93771 /* Signal+Transforms.swift in Sources */,
487524
F6FF03E31D926AC300B93771 /* Signal+KeyValueObserving.swift in Sources */,
488525
F68EF3551FD58FD20001129C /* UIView+Signal.swift in Sources */,
526+
B6B4E36029954B4600D7FFF2 /* Publisher+Utilities.swift in Sources */,
489527
F6B6A6632056AF4300B9FC9D /* ReadWriteSignal.swift in Sources */,
490528
F68EF3531FD58FC70001129C /* Event.swift in Sources */,
529+
B6B4E35C29952CCC00D7FFF2 /* CancelBag.swift in Sources */,
491530
F6462A421EFAAD06007E2198 /* Scheduler.swift in Sources */,
492531
7484FA6B212D9E930076FD3E /* Signal+Debug.swift in Sources */,
532+
5BB2E8C32994E5360095F9E1 /* Signal+SwiftUI.swift in Sources */,
493533
F6B6A6652056B2CA00B9FC9D /* EventType.swift in Sources */,
534+
B6B4E3572994FB6500D7FFF2 /* Disposable+Cancellable.swift in Sources */,
494535
F610ABB21D91743500A161AB /* Result.swift in Sources */,
495536
F66C47A920077BC700333410 /* Signal+Listeners.swift in Sources */,
496537
F64E975F201888EB00865380 /* Future+Combiners.swift in Sources */,
497538
F6714C711F25E97600C96931 /* Future.swift in Sources */,
498539
F66835CF2091B887002D2676 /* UIView+EditingMenu.swift in Sources */,
499540
F6FF03E51D926AC300B93771 /* TargetActionable.swift in Sources */,
500541
F699C483205C1A5C001378C0 /* Signal+Utilities.swift in Sources */,
542+
5BB2E8C52994E5360095F9E1 /* Signal+Combine.swift in Sources */,
501543
F667FCD8200604570014DA7D /* Enablable.swift in Sources */,
502544
F681B3481DB6566E00E44ABD /* Either.swift in Sources */,
503545
);
@@ -507,7 +549,9 @@
507549
isa = PBXSourcesBuildPhase;
508550
buildActionMask = 2147483647;
509551
files = (
552+
5BB2E8AD2994238C0095F9E1 /* Signal+CombineTests.swift in Sources */,
510553
F610ABBC1D91747000A161AB /* FutureBasicTests.swift in Sources */,
554+
5BB2E8CC2994F0160095F9E1 /* Future+CombineTests.swift in Sources */,
511555
F6A880921D9182B900CA257F /* SignalProviderTests.swift in Sources */,
512556
F610ABBF1D91747000A161AB /* FutureSchedulingTests.swift in Sources */,
513557
F6AC447F1FDE6F240090FBE7 /* SignalConcurrenceyTests.swift in Sources */,
@@ -523,6 +567,7 @@
523567
792AC15B227C8A6800F8BBAD /* SignalProviderTests+Internal.swift in Sources */,
524568
F6C0FED2202B44360076B877 /* DelegateTests.swift in Sources */,
525569
F6F679A320A966D1004C7AA7 /* EventListenerTests.swift in Sources */,
570+
B6B4E35A299506BF00D7FFF2 /* Disposable+CombineTests.swift in Sources */,
526571
5B46DE3D22E9CC5E00E0A4D9 /* PrefetchTests.swift in Sources */,
527572
F610ABBD1D91747000A161AB /* FutureQueueTests.swift in Sources */,
528573
DA6D58EF230E925700564CC1 /* MemoryUtilsTests.swift in Sources */,

0 commit comments

Comments
 (0)