Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/pr_status.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
- 'Projects/DependencyInjection/**'
design_system:
- 'Projects/DesignSystem/**'
home:
- 'Projects/Home/**'
- name: Generate matrix
id: matrix
run: |
Expand All @@ -39,6 +41,10 @@ jobs:
if [ "${{ steps.filter.outputs.design_system }}" == "true" ]; then
targets+=("DesignSystem")
fi

if [ "${{ steps.filter.outputs.home }}" == "true" ]; then
targets+=("Home")
fi

if [ ${#targets[@]} -gt 0 ]; then
matrix="{\"target\": [$(printf '"%s",' "${targets[@]}" | sed 's/,$//')]}"
Expand Down
20 changes: 17 additions & 3 deletions Projects/App/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,25 @@ let dependecies: [TargetDependency] = [
.project(target: "DependencyInjection",
path: "../DependencyInjection"),
.project(target: "DependencyInjectionInterfaces",
path: "../DependencyInjection")
path: "../DependencyInjection"),
.project(target: "Home",
path: "../Home"),
.project(target: "HomeInterfaces",
path: "../Home"),
.project(target: "NavigationInterfaces",
path: "../Navigation"),
.external(name: "Networking"),
.external(name: "NetworkingInterfaces"),
]

let testDependencies: [TargetDependency] = [
.target(name: moduleName),
.project(target: "DependencyInjectionTesting",
path: "../DependencyInjection"),
.project(target: "HomeTesting",
path: "../Home"),
.project(target: "NavigationTesting",
path: "../Navigation"),
]

let project = Project(
Expand Down Expand Up @@ -59,8 +73,8 @@ let project = Project(
"\(moduleName)Tests",
// Disabled UITests for now, as they are not yet implemented
// "\(moduleName)UITests"
]
),
],
arguments: .arguments(environmentVariables: ["IS_TESTING": "true"])),
runAction: .runAction(configuration: .debug,
executable: .project(path: ".", target: moduleName),
arguments: .arguments(environmentVariables: developmentEnv)))
Expand Down
5 changes: 4 additions & 1 deletion Projects/App/Sources/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {}

@MainActor
private func setupDependencies() {
func setupDependencies() {
let injector = Injector()
SharedContainer.shared.setInjector(injector)

NetworkAssembly(injector: injector).register()
CoordinatorAssembly(injector: injector).register()
}
}
30 changes: 19 additions & 11 deletions Projects/App/Sources/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,38 @@
//

import UIKit
import DependencyInjectionInterfaces

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?
var appCoordinator: AppCoordinating?

#if DEBUG
var isTesting: Bool {
return ProcessInfo.processInfo.environment["IS_TESTING"] == "true"
}
#endif

func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }

#if DEBUG
if isTesting { return }
#endif

let window = UIWindow(windowScene: windowScene)
let nav = UINavigationController(rootViewController: ViewController())
let nav = UINavigationController()
let resolver = SharedContainer.shared.resolver()

appCoordinator = resolver.resolve(AppCoordinating.self, argument: nav)
appCoordinator?.start()

window.rootViewController = nav
window.makeKeyAndVisible()

self.window = window
}

func sceneDidDisconnect(_ scene: UIScene) {}

func sceneDidBecomeActive(_ scene: UIScene) {}

func sceneWillResignActive(_ scene: UIScene) {}

func sceneWillEnterForeground(_ scene: UIScene) {}

func sceneDidEnterBackground(_ scene: UIScene) {}
}
35 changes: 35 additions & 0 deletions Projects/App/Sources/Assemblies/CoordinatorAssembly.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
//
// Created by Vitor Conceicao.
//
// github.com/vitor-rc1
//
//
import DependencyInjectionInterfaces
import HomeInterfaces
import Home
import NavigationInterfaces

import UIKit

public struct CoordinatorAssembly {
private let injector: DependencyInjector

public init(injector: DependencyInjector) {
self.injector = injector
}

@MainActor
public func register() {
injector.register(AppCoordinating.self) { (_, arg: UINavigationController) in
AppCoordinator(navigationController: arg)
}

injector.register(HomeCoordinating.self) { (_, arg: (UINavigationController, Coordinator?)) in
let (navigationController, parentCoordinator) = arg

return HomeCoordinator(parentCoordinator: parentCoordinator,
navigationController: navigationController)
}
}
}
27 changes: 27 additions & 0 deletions Projects/App/Sources/Assemblies/NetworkAssembly.swift.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
//
// Created by Vitor Conceicao.
//
// github.com/vitor-rc1
//
//

import DependencyInjectionInterfaces
import NetworkingInterfaces
import Networking

import Foundation

public struct NetworkAssembly {
private let injector: DependencyInjector

public init(injector: DependencyInjector) {
self.injector = injector
}

public func register() {
injector.register(NetworkServiceProtocol.self) { _ in
NetworkService()
}
}
}
35 changes: 35 additions & 0 deletions Projects/App/Sources/Coordinator/AppCoordinator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
//
// Created by Vitor Conceicao.
//
// github.com/vitor-rc1
//
//

import DependencyInjectionInterfaces
import HomeInterfaces
import NavigationInterfaces
import UIKit

protocol AppCoordinating: Coordinator {}

@MainActor
final class AppCoordinator: AppCoordinating {
var parentCoordinator: Coordinator?
var children: [Coordinator] = []
var navigationController: UINavigationController

init(navigationController: UINavigationController) {
self.navigationController = navigationController
}

func start() {
let resolver = SharedContainer.shared.resolver()
let arg: (UINavigationController, Coordinator?) = (navigationController, self)

let homeCoordinator = resolver.resolve(HomeCoordinating.self,
argument: arg)

homeCoordinator.start()
}
}
16 changes: 0 additions & 16 deletions Projects/App/Sources/ViewController.swift

This file was deleted.

56 changes: 55 additions & 1 deletion Projects/App/Tests/Application/AppDelegateTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,69 @@

import Testing
import DependencyInjectionInterfaces
import NetworkingInterfaces
import HomeInterfaces
import NavigationInterfaces
import UIKit

@testable import App

@Suite
@MainActor
struct AppDelegateTests {
init() {
_ = AppDelegate()
}

@Test("GIVEN AppDelegate initialize THEN it should set injector")
func example() async throws {
func setInjectot() async throws {
#expect(throws: Never.self) {
_ = SharedContainer.shared.resolver()
}
}

@Test("GIVEN AppDelegate initialize THEN it SHOULD register DI Network")
func networkRegister() async throws {
#expect(throws: Never.self) {
let _: NetworkServiceProtocol = SharedContainer.shared.resolver().resolve()
}
}

@Test("GIVEN AppDelegate initialize THEN it SHOULD register DI Network")
func appCoordinatorRegister() async throws {
#expect(throws: Never.self) {
let navigation = UINavigationController()
_ = SharedContainer
.shared
.resolver()
.resolve(AppCoordinating.self, argument: navigation)
}
}

@Test("GIVEN AppDelegate initialize THEN it SHOULD register DI AppCoordinating")
func appCoordinatingRegister() async throws {
#expect(throws: Never.self) {
let navigation = UINavigationController()
_ = SharedContainer
.shared
.resolver()
.resolve(AppCoordinating.self, argument: navigation)
}
}

@Test("GIVEN AppDelegate initialize THEN it SHOULD register DI HomeCoordinating")
func homeCoordinatorRegister() async throws {
#expect(throws: Never.self) {
let navigation = UINavigationController()
let parentCoordinator: Coordinator? = SharedContainer
.shared
.resolver()
.resolve(AppCoordinating.self, argument: navigation)

_ = SharedContainer
.shared
.resolver()
.resolve(HomeCoordinating.self, argument: (navigation, parentCoordinator))
}
}
}
50 changes: 50 additions & 0 deletions Projects/App/Tests/Coordinator/AppCoordinatorTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
//
// Created by Vitor Conceicao.
//
// github.com/vitor-rc1
//
//
//
import DependencyInjectionInterfaces
import DependencyInjectionTesting
import HomeInterfaces
import HomeTesting
import NavigationInterfaces
import NavigationTesting
import Testing
import UIKit

@testable import App

@MainActor
@Suite("AppCoordinator Tests")
struct AppCoordinatorTests {

// MARK: - Start Tests

@Test("Start resolves HomeCoordinating from container")
func startResolvesHomeCoordinator() {
// Given
let navigationController = UINavigationController()
let sut = AppCoordinator(navigationController: navigationController)

let injectorSpy = DependencyInjectorSpy()
let homeCoordinatorSpy = HomeCoordinatingSpy(
children: [],
navigationController: navigationController
)

injectorSpy
.register(HomeCoordinating.self) { (_, arg: (UINavigationController, Coordinator?)) in
homeCoordinatorSpy
}

SharedContainer.shared.setInjector(injectorSpy)

sut.start()

#expect(injectorSpy.calledMethods.contains(.resolveWithArgument))
#expect(homeCoordinatorSpy.calledMethods.contains(.start))
}
}
2 changes: 1 addition & 1 deletion Projects/DependencyInjection/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ let dependecies: [TargetDependency] = [
]

let project = Project.templateModule(named: moduleName,
targets: [.source,. interfaces, .test],
targets: [.source,. interfaces, .test, .testing],
dependencies: dependecies)
Loading
Loading