Skip to content

Commit

Permalink
Fix tests and Linux support
Browse files Browse the repository at this point in the history
## Changes

- Fix unit tests.

- Remove unnecessary Combine imports

- Fix imports on Linux.

- Fix unit tests on Linux
  + Add missing compile checks for `XCTExpectFailure` in Linux
  + Disable tests that use `@MainActor` on Linux because of an issue
  gathering tests:
  https://github.com/apple/swift-corelibs-xctest/issues/424

- Remove Swift installation from SwiftPM Linux job, as Swift is already
included in `ubuntu-latest` (`ubuntu-20.04`):
https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2004-Readme.md#language-and-runtime
  • Loading branch information
p4checo authored and mluisbrown committed Dec 21, 2022
1 parent 5904a8d commit 33ce925
Show file tree
Hide file tree
Showing 40 changed files with 2,192 additions and 2,151 deletions.
15 changes: 4 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,8 @@ jobs:
name: SwiftPM Linux
runs-on: ubuntu-latest
steps:
- name: Install Swift
run: |
eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
- name: Checkout
uses: actions/checkout@v2
- name: Pull dependencies
run: |
swift package resolve
- uses: actions/checkout@v2
- name: Swift version
run: swift --version
- name: Test via SwiftPM
run: |
swift --version
swift test --enable-test-discovery
run: swift test --enable-test-discovery
1 change: 1 addition & 0 deletions Examples/CaseStudies/CaseStudies.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@
DC4C6EA82450DD380066A05D /* UIKitCaseStudies */,
DC4C6EBF2450DD390066A05D /* UIKitCaseStudiesTests */,
);
indentWidth = 2;
sourceTree = "<group>";
};
DC89C41424460F95006900B9 /* Products */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import XCTest

@MainActor
class AnimationTests: XCTestCase {
func testRainbow() {
func testRainbow() async {
let mainQueue = TestScheduler()

let store = TestStore(
Expand All @@ -17,44 +17,44 @@ class AnimationTests: XCTestCase {
)
)

store.send(.rainbowButtonTapped)
await store.send(.rainbowButtonTapped)

store.receive(.setColor(.red)) {
await store.receive(.setColor(.red)) {
$0.circleColor = .red
}

await mainQueue.advance(by: .seconds(1))
store.receive(.setColor(.blue)) {
await store.receive(.setColor(.blue)) {
$0.circleColor = .blue
}

await mainQueue.advance(by: .seconds(1))
store.receive(.setColor(.green)) {
await store.receive(.setColor(.green)) {
$0.circleColor = .green
}

await mainQueue.advance(by: .seconds(1))
store.receive(.setColor(.orange)) {
await store.receive(.setColor(.orange)) {
$0.circleColor = .orange
}

await mainQueue.advance(by: .seconds(1))
store.receive(.setColor(.pink)) {
await store.receive(.setColor(.pink)) {
$0.circleColor = .pink
}

await mainQueue.advance(by: .seconds(1))
store.receive(.setColor(.purple)) {
await store.receive(.setColor(.purple)) {
$0.circleColor = .purple
}

await mainQueue.advance(by: .seconds(1))
store.receive(.setColor(.yellow)) {
await store.receive(.setColor(.yellow)) {
$0.circleColor = .yellow
}

await mainQueue.advance(by: .seconds(1))
store.receive(.setColor(.black)) {
await store.receive(.setColor(.black)) {
$0.circleColor = .black
}

Expand All @@ -63,41 +63,41 @@ class AnimationTests: XCTestCase {
await mainQueue.advance(by: .seconds(10))
}

func testReset() async {
let mainQueue = TestScheduler()
func testReset() async {
let mainQueue = TestScheduler()

let store = TestStore(
initialState: AnimationsState(),
reducer: animationsReducer,
environment: AnimationsEnvironment(
mainQueue: mainQueue
)
let store = TestStore(
initialState: AnimationsState(),
reducer: animationsReducer,
environment: AnimationsEnvironment(
mainQueue: mainQueue
)
)

await store.send(.rainbowButtonTapped)

await store.send(.rainbowButtonTapped)

await store.receive(.setColor(.red)) {
$0.circleColor = .red
}

await mainQueue.advance(by: .seconds(1))
await store.receive(.setColor(.blue)) {
$0.circleColor = .blue
}

await store.send(.resetButtonTapped) {
$0.alert = AlertState(
title: TextState("Reset state?"),
primaryButton: .destructive(
TextState("Reset"),
action: .send(.resetConfirmationButtonTapped, animation: .default)
),
secondaryButton: .cancel(TextState("Cancel"))
)
}

await store.send(.resetConfirmationButtonTapped) {
$0 = AnimationsState()
}
await store.receive(.setColor(.red)) {
$0.circleColor = .red
}

await mainQueue.advance(by: .seconds(1))
await store.receive(.setColor(.blue)) {
$0.circleColor = .blue
}

await store.send(.resetButtonTapped) {
$0.alert = AlertState(
title: TextState("Reset state?"),
primaryButton: .destructive(
TextState("Reset"),
action: .send(.resetConfirmationButtonTapped, animation: .default)
),
secondaryButton: .cancel(TextState("Cancel"))
)
}

await store.send(.resetConfirmationButtonTapped) {
$0 = AnimationsState()
}
}
}
1 change: 1 addition & 0 deletions Examples/Search/Search.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
CA86E49924253C2500357AD9 /* Search */,
CA86E4B024253C2700357AD9 /* SearchTests */,
);
indentWidth = 2;
sourceTree = "<group>";
};
CA86E49824253C2500357AD9 /* Products */ = {
Expand Down
1 change: 0 additions & 1 deletion Examples/Search/Search/WeatherClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ extension WeatherClient {

let (data, _) = try await URLSession.shared.data(from: components.url!)
return try jsonDecoder.decode(Search.self, from: data)
}
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
CA23320C2447ACFA00B818EB /* SpeechRecognition */,
CA2332232447ACFC00B818EB /* SpeechRecognitionTests */,
);
indentWidth = 2;
sourceTree = "<group>";
};
CA23320B2447ACFA00B818EB /* Products */ = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Combine
import Speech

struct SpeechClient {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import ComposableArchitecture
import ReactiveSwift
import Speech

extension SpeechClient {
Expand Down Expand Up @@ -79,7 +78,6 @@ private actor Speech {
audioEngine.wrappedValue?.inputNode.removeTap(onBus: 0)
recognitionTask.wrappedValue?.finish()
}
lifetime += cancellable

self.audioEngine?.inputNode.installTap(
onBus: 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Combine
import ComposableArchitecture
import Speech
import XCTestDynamicOverlay
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import ComposableArchitecture
import ReactiveSwift
import Speech
@preconcurrency import SwiftUI

Expand Down Expand Up @@ -190,7 +189,7 @@ extension SpeechClient {
}
text += word + " "
c.yield(
value: .init(
.init(
bestTranscription: .init(
formattedString: text,
segments: []
Expand All @@ -200,8 +199,6 @@ extension SpeechClient {
)
)
}

lifetime += disposable
}
}
}
Expand Down
1 change: 1 addition & 0 deletions Examples/TicTacToe/TicTacToe.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
CA6AC25C2450FDB800C71CB3 /* App */,
DC9193F72420104100A5BE1F /* Products */,
);
indentWidth = 2;
sourceTree = "<group>";
};
DC9193F72420104100A5BE1F /* Products */ = {
Expand Down
1 change: 1 addition & 0 deletions Examples/Todos/Todos.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
DCBCB77224290F6C00DE1F59 /* Todos */,
DCBCB78924290F6D00DE1F59 /* TodosTests */,
);
indentWidth = 2;
sourceTree = "<group>";
};
DCBCB77124290F6C00DE1F59 /* Products */ = {
Expand Down
1 change: 1 addition & 0 deletions Examples/Todos/Todos/Todos.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ComposableArchitecture
import ReactiveSwift
import SwiftUI

enum Filter: LocalizedStringKey, CaseIterable, Hashable {
Expand Down
3 changes: 2 additions & 1 deletion Examples/Todos/Todos/TodosApp.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ComposableArchitecture
import ReactiveSwift
import SwiftUI

@main
Expand All @@ -10,7 +11,7 @@ struct TodosApp: App {
initialState: AppState(),
reducer: appReducer,
environment: AppEnvironment(
mainQueue: .main,
mainQueue: QueueScheduler.main,
uuid: { UUID() }
)
)
Expand Down
1 change: 1 addition & 0 deletions Examples/Todos/TodosTests/TodosTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class TodosTests: XCTestCase {
reducer: appReducer,
environment: AppEnvironment(
mainQueue: self.mainQueue,
uuid: { UUID.incrementing() }
)
)

Expand Down
3 changes: 2 additions & 1 deletion Examples/VoiceMemos/VoiceMemos.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

/* Begin PBXFileReference section */
23EDBE6B271CD8DD004F7430 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
CA93D05B249BF42500A6F65D /* VoiceMemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMemo.swift; sourceTree = "<group>"; };
CA93D05B249BF42500A6F65D /* VoiceMemo.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = VoiceMemo.swift; sourceTree = "<group>"; };
CA93D05D249BF46E00A6F65D /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
DC5BDCAA24589177009C65A3 /* VoiceMemos.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoiceMemos.app; sourceTree = BUILT_PRODUCTS_DIR; };
DC5BDCAF24589177009C65A3 /* VoiceMemosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMemosApp.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -103,6 +103,7 @@
DC5BDCAC24589177009C65A3 /* VoiceMemos */,
DC5BDCC324589179009C65A3 /* VoiceMemosTests */,
);
indentWidth = 2;
sourceTree = "<group>";
};
DC5BDCAB24589177009C65A3 /* Products */ = {
Expand Down
7 changes: 4 additions & 3 deletions Examples/VoiceMemos/VoiceMemos/VoiceMemo.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ComposableArchitecture
import Foundation
import ReactiveSwift
import SwiftUI

struct VoiceMemo: Equatable, Identifiable {
Expand Down Expand Up @@ -61,14 +62,14 @@ let voiceMemoReducer = Reducer<
memo.mode = .playing(progress: 0)

return .run { [url = memo.url] send in
let start = environment.mainRunLoop.now
let start = environment.mainRunLoop.currentDate

async let playAudio: Void = send(
.audioPlayerClient(TaskResult { try await environment.audioPlayerClient.play(url) })
)

for try await tick in environment.mainRunLoop.timer(interval: 0.5) {
await send(.timerUpdated(tick.date.timeIntervalSince(start.date)))
for try await tick in environment.mainRunLoop.timer(interval: .milliseconds(500)) {
await send(.timerUpdated(tick.timeIntervalSince(start)))
}
}
.cancellable(id: PlayID.self, cancelInFlight: true)
Expand Down
1 change: 1 addition & 0 deletions Examples/VoiceMemos/VoiceMemos/VoiceMemos.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import AVFoundation
import ComposableArchitecture
import Foundation
import ReactiveSwift
import SwiftUI

struct VoiceMemosState: Equatable {
Expand Down
11 changes: 5 additions & 6 deletions Examples/VoiceMemos/VoiceMemosTests/VoiceMemosTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class VoiceMemosTests: XCTestCase {
environment.audioRecorder.stopRecording = {
didFinish.continuation.yield(true)
didFinish.continuation.finish()
}
}
environment.mainRunLoop = mainRunLoop
environment.temporaryDirectory = { URL(fileURLWithPath: "/tmp") }
Expand Down Expand Up @@ -82,7 +81,7 @@ class VoiceMemosTests: XCTestCase {

var environment = VoiceMemosEnvironment.unimplemented
environment.audioRecorder.requestRecordPermission = { false }
environment.mainRunLoop = ImmediateScheduler()
environment.mainRunLoop = mainRunLoop
environment.openSettings = { await didOpenSettings.setValue(true) }

let store = TestStore(
Expand Down Expand Up @@ -113,7 +112,7 @@ class VoiceMemosTests: XCTestCase {
environment.audioRecorder.startRecording = { _ in
try await didFinish.stream.first { _ in true }!
}
environment.mainRunLoop = ImmediateScheduler()
environment.mainRunLoop = TestScheduler(startDate: Date(timeIntervalSince1970: 0))
environment.temporaryDirectory = { URL(fileURLWithPath: "/tmp") }
environment.uuid = { UUID(uuidString: "DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF")! }

Expand Down Expand Up @@ -145,7 +144,7 @@ class VoiceMemosTests: XCTestCase {
func testPlayMemoHappyPath() async {
var environment = VoiceMemosEnvironment.unimplemented
environment.audioPlayer.play = { _ in
try await self.mainRunLoop.sleep(for: 1.25)
try await self.mainRunLoop.sleep(for: .milliseconds(1250))
return true
}
environment.mainRunLoop = mainRunLoop
Expand Down Expand Up @@ -190,7 +189,7 @@ class VoiceMemosTests: XCTestCase {

var environment = VoiceMemosEnvironment.unimplemented
environment.audioPlayer.play = { _ in throw SomeError() }
environment.mainRunLoop = ImmediateScheduler()
environment.mainRunLoop = mainRunLoop

let url = URL(fileURLWithPath: "pointfreeco/functions.m4a")
let store = TestStore(
Expand Down Expand Up @@ -269,7 +268,7 @@ class VoiceMemosTests: XCTestCase {
let url = URL(fileURLWithPath: "pointfreeco/functions.m4a")
var environment = VoiceMemosEnvironment.unimplemented
environment.audioPlayer.play = { _ in try await Task.never() }
environment.mainRunLoop = ImmediateScheduler()
environment.mainRunLoop = mainRunLoop

let store = TestStore(
initialState: VoiceMemosState(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,10 @@ time-based asynchrony, but in a way that is controllable. One way to do this is
scheduler to the environment:

```swift
import CombineSchedulers
import ReactiveSwift

struct Environment {
var mainQueue: any SchedulerOf<DispatchQueue>
var mainQueue: DateScheduler
}
```

Expand Down
Loading

0 comments on commit 33ce925

Please sign in to comment.