Runtime warn instead of breakpoint in `Switch` (#26)

* Runtime warn instead of breakpoint in `Switch`

* Bump swift tools version

* update CI

* wip
This commit is contained in:
Stephen Celis 2022-10-18 17:16:18 -07:00 committed by GitHub
parent 51c7b145a7
commit 128f264790
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 127 additions and 58 deletions

View File

@ -10,19 +10,14 @@ on:
jobs:
library:
runs-on: macos-11.0
runs-on: macos-12
strategy:
matrix:
xcode:
- '12.4'
- '12.5.1'
- '13.1'
xcode: ['14.0.1']
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Select Xcode ${{ matrix.xcode }}
run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app
- name: Run tests
run: make test
- name: Compile documentation
if: ${{ matrix.xcode == '13.1' }}
run: make test-docs

View File

@ -1,7 +1,7 @@
PLATFORM_IOS = iOS Simulator,name=iPhone 11 Pro Max
PLATFORM_IOS = iOS Simulator,name=iPhone 13 Pro Max
PLATFORM_MACOS = macOS
PLATFORM_TVOS = tvOS Simulator,name=Apple TV 4K (at 1080p)
PLATFORM_WATCHOS = watchOS Simulator,name=Apple Watch Series 4 - 44mm
PLATFORM_TVOS = tvOS Simulator,name=Apple TV
PLATFORM_WATCHOS = watchOS Simulator,name=Apple Watch Series 7 (45mm)
default: test

View File

@ -6,8 +6,17 @@
"repositoryURL": "https://github.com/pointfreeco/swift-case-paths",
"state": {
"branch": null,
"revision": "d226d167bd4a68b51e352af5655c92bce8ee0463",
"version": "0.7.0"
"revision": "15bba50ebf3a2065388c8d12210debe4f6ada202",
"version": "0.10.0"
}
},
{
"package": "xctest-dynamic-overlay",
"repositoryURL": "https://github.com/pointfreeco/xctest-dynamic-overlay",
"state": {
"branch": null,
"revision": "16e6409ee82e1b81390bdffbf217b9c08ab32784",
"version": "0.5.0"
}
}
]

View File

@ -1,4 +1,4 @@
// swift-tools-version:5.3
// swift-tools-version:5.5
import PackageDescription
@ -17,13 +17,15 @@ let package = Package(
)
],
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-case-paths", from: "0.7.0")
.package(url: "https://github.com/pointfreeco/swift-case-paths", from: "0.10.0"),
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "0.5.0"),
],
targets: [
.target(
name: "SwiftUINavigation",
dependencies: [
.product(name: "CasePaths", package: "swift-case-paths")
.product(name: "CasePaths", package: "swift-case-paths"),
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
]
),
.testTarget(

View File

@ -1,30 +0,0 @@
/// Raises a debug breakpoint if a debugger is attached.
@inline(__always) func breakpoint(_ message: @autoclosure () -> String = "") {
#if DEBUG
// https://github.com/bitstadium/HockeySDK-iOS/blob/c6e8d1e940299bec0c0585b1f7b86baf3b17fc82/Classes/BITHockeyHelper.m#L346-L370
var name: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
var info: kinfo_proc = kinfo_proc()
var info_size = MemoryLayout<kinfo_proc>.size
let isDebuggerAttached = name.withUnsafeMutableBytes {
$0.bindMemory(to: Int32.self).baseAddress
.map {
sysctl($0, 4, &info, &info_size, nil, 0) != -1 && info.kp_proc.p_flag & P_TRACED != 0
}
?? false
}
if isDebuggerAttached {
fputs(
"""
\(message())
Caught debug breakpoint. Type "continue" ("c") to resume execution.
""",
stderr
)
raise(SIGTRAP)
}
#endif
}

View File

@ -0,0 +1,71 @@
@_transparent
@inline(__always)
@usableFromInline
func runtimeWarn(
_ message: @autoclosure () -> String,
category: String? = "SwiftUINavigation",
file: StaticString? = nil,
line: UInt? = nil
) {
#if DEBUG
let message = message()
let category = category ?? "Runtime Warning"
if _XCTIsTesting {
if let file = file, let line = line {
XCTFail(message, file: file, line: line)
} else {
XCTFail(message)
}
} else {
#if canImport(os)
os_log(
.fault,
dso: dso,
log: OSLog(subsystem: "com.apple.runtime-issues", category: category),
"%@",
message
)
#else
fputs("\(formatter.string(from: Date())) [\(category)] \(message)\n", stderr)
#endif
}
#endif
}
#if DEBUG
import XCTestDynamicOverlay
#if canImport(os)
import os
// NB: Xcode runtime warnings offer a much better experience than traditional assertions and
// breakpoints, but Apple provides no means of creating custom runtime warnings ourselves.
// To work around this, we hook into SwiftUI's runtime issue delivery mechanism, instead.
//
// Feedback filed: https://gist.github.com/stephencelis/a8d06383ed6ccde3e5ef5d1b3ad52bbc
@usableFromInline
let dso = { () -> UnsafeMutableRawPointer in
let count = _dyld_image_count()
for i in 0..<count {
if let name = _dyld_get_image_name(i) {
let swiftString = String(cString: name)
if swiftString.hasSuffix("/SwiftUI") {
if let header = _dyld_get_image_header(i) {
return UnsafeMutableRawPointer(mutating: UnsafeRawPointer(header))
}
}
}
}
return UnsafeMutableRawPointer(mutating: #dsohandle)
}()
#else
import Foundation
@usableFromInline
let formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:MM:SS.sssZ"
return formatter
}()
#endif
#endif

View File

@ -1065,15 +1065,7 @@ public struct _ExhaustivityCheckView<Enum>: View {
.foregroundColor(.white)
.padding()
.background(Color.red.edgesIgnoringSafeArea(.all))
.onAppear {
breakpoint(
"""
---
\(message)
---
"""
)
}
.onAppear { runtimeWarn(message, file: self.file, line: self.line) }
#else
EmptyView()
#endif

View File

@ -4,4 +4,7 @@
<FileRef
location = "group:">
</FileRef>
<FileRef
location = "group:Examples/Examples.xcodeproj">
</FileRef>
</Workspace>

View File

@ -6,8 +6,35 @@
"repositoryURL": "https://github.com/pointfreeco/swift-case-paths",
"state": {
"branch": null,
"revision": "7346701ea29da0a85d4403cf3d7a589a58ae3dee",
"version": "0.9.2"
"revision": "15bba50ebf3a2065388c8d12210debe4f6ada202",
"version": "0.10.0"
}
},
{
"package": "swift-collections",
"repositoryURL": "https://github.com/apple/swift-collections",
"state": {
"branch": null,
"revision": "f504716c27d2e5d4144fa4794b12129301d17729",
"version": "1.0.3"
}
},
{
"package": "swift-identified-collections",
"repositoryURL": "https://github.com/pointfreeco/swift-identified-collections.git",
"state": {
"branch": null,
"revision": "bfb0d43e75a15b6dfac770bf33479e8393884a36",
"version": "0.4.1"
}
},
{
"package": "xctest-dynamic-overlay",
"repositoryURL": "https://github.com/pointfreeco/xctest-dynamic-overlay",
"state": {
"branch": null,
"revision": "16e6409ee82e1b81390bdffbf217b9c08ab32784",
"version": "0.5.0"
}
}
]