Skip to content

Commit

Permalink
Improve preview API (#1)
Browse files Browse the repository at this point in the history
* Improve preview API

* Add workflow folder

* Update docc.yml

* Create ubuntu.yml

* Delete .github/workflows/.github/workflows directory

* Create ubunutu.yml

* Create windows.yml

* Rename ubunutu.yml to ubuntu.yml

* Create macOS.yml

* Create FUNDING.yml

* Delete Package.resolved

* Create ApplicationLogger.swift

* Add tests

* Remove mirror comments

* Update gitignore

* Remove .resolved
  • Loading branch information
0xLeif authored Mar 8, 2024
1 parent 7a290be commit 84b73f2
Show file tree
Hide file tree
Showing 14 changed files with 404 additions and 29 deletions.
13 changes: 13 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# These are supported funding model platforms

github: [0xLeif]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
40 changes: 40 additions & 0 deletions .github/workflows/docc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: docc
on:
release:
types: [released]
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: true
jobs:
pages:
environment:
name: github-pages
url: '${{ steps.deployment.outputs.page_url }}'
runs-on: macos-13
steps:
- uses: swift-actions/setup-swift@v1
- name: git checkout
uses: actions/checkout@v3
- name: docbuild
run: >
sudo xcode-select -s /Applications/Xcode_15.0.app;
xcodebuild docbuild -scheme AppDependency \
-derivedDataPath /tmp/docbuild \
-destination 'generic/platform=iOS';
$(xcrun --find docc) process-archive \
transform-for-static-hosting /tmp/docbuild/Build/Products/Debug-iphoneos/AppDependency.doccarchive \
--output-path docs \
--hosting-base-path 'AppDependency';
echo "<script>window.location.href +=
\"/documentation/appdependency\"</script>" > docs/index.html;
- name: artifacts
uses: actions/upload-pages-artifact@v1
with:
path: docs
- name: deploy
id: deployment
uses: actions/deploy-pages@v1
23 changes: 23 additions & 0 deletions .github/workflows/macOS.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This workflow will build a Swift project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift

name: macOS

on:
push:
branches: ["**"]

jobs:
build:
runs-on: macos-13

steps:
- uses: swift-actions/setup-swift@v1
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v3
- name: Build for release
run: swift build -v -c release
- name: Test
run: swift test -v
20 changes: 20 additions & 0 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This workflow will build a Swift project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift

name: Ubuntu

on:
push:
branches: ["**"]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: swift-actions/setup-swift@v1
- uses: actions/checkout@v3
- name: Build for release
run: swift build -v -c release
- name: Test
run: swift test -v
18 changes: 18 additions & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Windows

on:
push:
branches: ["**"]

jobs:
build:
runs-on: windows-latest
steps:
- uses: compnerd/gha-setup-swift@main
with:
branch: swift-5.9.2-release
tag: 5.9.2-RELEASE

- uses: actions/checkout@v2
- run: swift build
- run: swift test
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.swiftpm/
xcworkspacedata
.netrc
Package.resolved

This file was deleted.

14 changes: 0 additions & 14 deletions Package.resolved

This file was deleted.

27 changes: 27 additions & 0 deletions Sources/AppDependency/Application/Application+public.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import Foundation
#if !os(Linux) && !os(Windows)
import SwiftUI
#endif

// MARK: Application Functions

Expand Down Expand Up @@ -259,6 +262,30 @@ public extension Application {
}
}

#if !os(Linux) && !os(Windows)
// MARK: - SwiftUI Preview Dependency Functions

public extension Application {
/**
Use in SwiftUI previews to inject mock dependencies into the content view.
- Parameters:
- dependencyOverrides: An array of `Application.override(_, with:)` outputs that you want to use for the preview.
- content: A closure that returns the View you want to preview.
- Returns: A View with the overridden dependencies applied.
*/
@ViewBuilder
static func preview<Content: View>(
_ dependencyOverrides: DependencyOverride...,
content: @escaping () -> Content
) -> some View {
ApplicationPreview(
dependencyOverrides: dependencyOverrides,
content: content
)
}
}
#endif

// MARK: - DependencySlice Functions

extension Application {
Expand Down
34 changes: 34 additions & 0 deletions Sources/AppDependency/Application/Helper/ApplicationLogger.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#if os(Linux) || os(Windows)
/// `ApplicationLogger` is a class that provides logging functionalities for Linux and Windows operating systems.
open class ApplicationLogger {
/// Prints a debug message.
/// - Parameter message: The message to be logged.
open func debug(_ message: String) {
debug { message }
}

/// Prints a debug message.
/// - Parameter message: A closure that returns the message to be logged.
open func debug(_ message: () -> String) {
print(message())
}

/// Logs an error message.
/// - Parameters:
/// - error: The error that occurred.
/// - message: An optional custom message to accompany the error.
open func error(_ error: Error, message: String? = nil) {
guard let message else {
return print("Error: \(error.localizedDescription)")
}

print("\(message) (Error: \(error.localizedDescription))")
}

/// Logs an error message.
/// - Parameter message: The error message to be logged.
open func error(_ message: String) {
print("Error: \(message)")
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#if !os(Linux) && !os(Windows)
import SwiftUI

extension Application {
struct ApplicationPreview<Content: View>: View {
let dependencyOverrides: [DependencyOverride]
let content: () -> Content

init(
dependencyOverrides: [DependencyOverride],
content: @escaping () -> Content
) {
self.dependencyOverrides = dependencyOverrides
self.content = content
}

var body: some View {
content()
}
}
}
#endif
79 changes: 74 additions & 5 deletions Tests/AppDependencyTests/AppDependencyTests.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,81 @@
import XCTest
@testable import AppDependency

fileprivate protocol Networking {
func fetch()
}

fileprivate class NetworkService: Networking {
func fetch() {
fatalError()
}
}

fileprivate class MockNetworking: Networking {
func fetch() { /* no-op */ }
}

fileprivate class ComposableService {
let networking: Networking

init(networking: Networking) {
self.networking = networking
}
}

fileprivate extension Application {
var networking: Dependency<Networking> {
dependency(NetworkService())
}

var composableService: Dependency<ComposableService> {
dependency(ComposableService(networking: Application.dependency(\.networking)))
}
}

fileprivate struct ExampleDependencyWrapper {
@AppDependency(\.networking) private var networking

func fetch() {
networking.fetch()
}
}

final class AppDependencyTests: XCTestCase {
func testExample() throws {
// XCTest Documentation
// https://developer.apple.com/documentation/xctest
override class func setUp() {
Application.logging(isEnabled: true)
}

override class func tearDown() {
Application.logger.debug("AppDependencyTests \(Application.description)")
}

func testComposableDependencies() {
let dependencyOverride = Application.override(\.networking, with: MockNetworking())

let composableService = Application.dependency(\.composableService)
composableService.networking.fetch()

dependencyOverride.cancel()
}

func testDependency() async throws {
let networkingOverride = Application.override(\.networking, with: MockNetworking())

let mockNetworking = Application.dependency(\.networking)

XCTAssertNotNil(mockNetworking as? MockNetworking)

mockNetworking.fetch()

let example = ExampleDependencyWrapper()

example.fetch()

networkingOverride.cancel()

let networkingService = Application.dependency(\.networking)

// Defining Test Cases and Test Methods
// https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods
XCTAssertNotNil(networkingService as? NetworkService)
}
}
Loading

0 comments on commit 84b73f2

Please sign in to comment.