mirror of
https://github.com/pointfreeco/swift-composable-architecture.git
synced 2025-12-20 09:11:33 +01:00
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Silence test warnings * wip * wip * wip * wip * wip * wip * wip * Revert "wip" This reverts commited6cc24adb. * Revert "Revert "wip"" This reverts commit8358990b1a. * wip * wip * wip * wip * wip * update a bunch of docs * wip * wip * wip * fix * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Kill integration tests for now * wip * wip * wip * wip * updating docs for @Reducer macro * replaced more Reducer protocols with @Reducer * Fixed some broken docc references * wip * Some @Reducer docs * more docs * convert some old styles to new style * wip * wip * wip * wip * wip * wip * wip * bump * update tutorials to use body * update tutorials to use DML on destination state enum * Add diagnostic * wip * updated a few more tests * wip * wip * Add another gotcha * wip * wip * wip * Add dynamic lookup to presentation state/action * wip * wip * Better lookup * wip * wip * wip * IdentifiedAction * wip * wip * wip * wip * wip * wip * wip * wip * wip * fixes * wip * wip * added migration guide for new scope operation * migration guide for new navigation view modifiers * wip * fix * wip * wip * wip * wip * wip * wip * wip * wip * wip * fix * fix * wip * wip * remove for now * wip * wip * simplify scope * wip * updated some docs * migration guides * more migration guide * fix ci * fix * soft deprecate all apis using AnyCasePath * wip * Fix * fix tests * updated tests * swift-format 509 compatibility * wip * wip * Update Sources/ComposableArchitecture/Macros.swift Co-authored-by: Mateusz Bąk <bakmatthew@icloud.com> * wip * wip * update optional state case study * remove initializer * Don't use @State for BasicsView integration demo * fix tests * remove reduce diagnostics for now * diagnose error not warning * Update Sources/ComposableArchitecture/Macros.swift Co-authored-by: Jesse Tipton <jesse@jessetipton.com> * wip * move integration tests to cron * Revert "move integration tests to cron" This reverts commitf9bdf2f04b. * disable flakey tests on CI * wip * wip * fix migration guide * fix docs * fix deprecation messages * wip * wip * missing deprecation * soft * wip * update migration guide * Fix resolved * update migration guide * fix test * format * wip * fix * wip * wip * wip * wip * wip * wip * wip * wip * fix * wip * wip --------- Co-authored-by: Brandon Williams <mbrandonw@hey.com> Co-authored-by: Mateusz Bąk <bakmatthew@icloud.com> Co-authored-by: Brandon Williams <135203+mbrandonw@users.noreply.github.com> Co-authored-by: Jesse Tipton <jesse@jessetipton.com>
144 lines
3.9 KiB
Swift
144 lines
3.9 KiB
Swift
import Accessibility
|
|
import CustomDump
|
|
import InlineSnapshotTesting
|
|
import XCTest
|
|
|
|
@MainActor
|
|
class BaseIntegrationTests: XCTestCase {
|
|
var app: XCUIApplication!
|
|
var logs: XCUIElement!
|
|
private var _expectRuntimeWarnings: (file: StaticString, line: UInt)?
|
|
|
|
func expectRuntimeWarnings(file: StaticString = #file, line: UInt = #line) {
|
|
self._expectRuntimeWarnings = (file, line)
|
|
}
|
|
|
|
override func setUp() async throws {
|
|
//SnapshotTesting.isRecording = true
|
|
// self.continueAfterFailure = false
|
|
self.app = XCUIApplication()
|
|
self.app.launchEnvironment["UI_TEST"] = "true"
|
|
self.app.launch()
|
|
self.app.activate()
|
|
self.logs = self.app.staticTexts["composable-architecture.debug.logs"]
|
|
}
|
|
|
|
override func tearDown() {
|
|
super.tearDown()
|
|
if let (file, line) = self._expectRuntimeWarnings {
|
|
XCTAssert(
|
|
self.app.staticTexts["Runtime warning"].waitForExistence(timeout: 1),
|
|
"Expected runtime warning(s)",
|
|
file: file,
|
|
line: line
|
|
)
|
|
} else {
|
|
XCTAssertFalse(self.app.staticTexts["Runtime warning"].exists)
|
|
}
|
|
SnapshotTesting.isRecording = false
|
|
}
|
|
|
|
func clearLogs() {
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
|
let alert = XCUIApplication(bundleIdentifier: "com.apple.springboard").alerts
|
|
let open = alert.buttons["Open"]
|
|
if alert.firstMatch.waitForExistence(timeout: 0.3),
|
|
open.waitForExistence(timeout: 0.3)
|
|
{
|
|
alert.buttons["Open"].tap()
|
|
}
|
|
}
|
|
XCUIDevice.shared.system.open(URL(string: "integration:///clear-logs")!)
|
|
}
|
|
|
|
func assertLogs(
|
|
_ logConfiguration: LogConfiguration = .unordered,
|
|
matches expectedLogs: (() -> String)? = nil,
|
|
file: StaticString = #file,
|
|
function: StaticString = #function,
|
|
line: UInt = #line,
|
|
column: UInt = #column
|
|
) {
|
|
defer { self.clearLogs() }
|
|
let logs: String
|
|
switch logConfiguration {
|
|
case .exact:
|
|
logs = self.logs.label
|
|
case .unordered:
|
|
logs = self.logs.label.split(separator: "\n").sorted().joined(separator: "\n")
|
|
}
|
|
assertInlineSnapshot(
|
|
of: logs,
|
|
as: ._lines,
|
|
matches: expectedLogs,
|
|
file: file,
|
|
function: function,
|
|
line: line,
|
|
column: column
|
|
)
|
|
}
|
|
}
|
|
|
|
enum LogConfiguration {
|
|
case exact
|
|
case unordered
|
|
}
|
|
|
|
extension Snapshotting where Value == String, Format == String {
|
|
fileprivate static let _lines = Snapshotting(
|
|
pathExtension: "txt",
|
|
diffing: Diffing(
|
|
toData: { Data($0.utf8) },
|
|
fromData: { String(decoding: $0, as: UTF8.self) }
|
|
) { old, new in
|
|
guard old != new else { return nil }
|
|
|
|
let newLines = new.split(separator: "\n", omittingEmptySubsequences: false)
|
|
|
|
let oldLines = old.split(separator: "\n", omittingEmptySubsequences: false)
|
|
let difference = newLines.difference(from: oldLines)
|
|
|
|
var result = ""
|
|
|
|
var insertions = [Int: Substring]()
|
|
var removals = [Int: Substring]()
|
|
|
|
for change in difference {
|
|
switch change {
|
|
case let .insert(offset, element, _):
|
|
insertions[offset] = element
|
|
case let .remove(offset, element, _):
|
|
removals[offset] = element
|
|
}
|
|
}
|
|
|
|
var oldLine = 0
|
|
var newLine = 0
|
|
|
|
while oldLine < oldLines.count || newLine < newLines.count {
|
|
if let removal = removals[oldLine] {
|
|
result += "\(oldPrefix) \(removal)\n"
|
|
oldLine += 1
|
|
} else if let insertion = insertions[newLine] {
|
|
result += "\(newPrefix) \(insertion)\n"
|
|
newLine += 1
|
|
} else {
|
|
result += "\(prefix) \(oldLines[oldLine])\n"
|
|
oldLine += 1
|
|
newLine += 1
|
|
}
|
|
}
|
|
|
|
let attachment = XCTAttachment(
|
|
data: Data(result.utf8),
|
|
uniformTypeIdentifier: "public.patch-file"
|
|
)
|
|
return (result, [attachment])
|
|
}
|
|
)
|
|
}
|
|
|
|
private let oldPrefix = "\u{2212}"
|
|
private let newPrefix = "+"
|
|
private let prefix = "\u{2007}"
|