Skip to content

Commit

Permalink
Merge pull request #11 from Haitec/feature/demo-presentation
Browse files Browse the repository at this point in the history
Add presentation and composition demo
  • Loading branch information
Haitec authored Oct 9, 2022
2 parents 35164bd + 9d41b6d commit ef343fb
Show file tree
Hide file tree
Showing 32 changed files with 632 additions and 71 deletions.
26 changes: 18 additions & 8 deletions CleanApp/CleanApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
4902E3C128F1DB24003AB55D /* DataLayer in Frameworks */ = {isa = PBXBuildFile; productRef = 4902E3C028F1DB24003AB55D /* DataLayer */; };
4902E3C328F1DB24003AB55D /* DomainLayer in Frameworks */ = {isa = PBXBuildFile; productRef = 4902E3C228F1DB24003AB55D /* DomainLayer */; };
4902E3C528F1DB24003AB55D /* PresentationLayer in Frameworks */ = {isa = PBXBuildFile; productRef = 4902E3C428F1DB24003AB55D /* PresentationLayer */; };
4937EC5328F3358500810F76 /* DIContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4937EC5228F3358500810F76 /* DIContainer.swift */; };
493CDDD62723258300499858 /* CleanApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493CDDD52723258300499858 /* CleanApp.swift */; };
493CDDE72723258400499858 /* iOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493CDDE62723258400499858 /* iOSTests.swift */; };
493CDDF12723258400499858 /* iOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493CDDF02723258400499858 /* iOSUITests.swift */; };
Expand Down Expand Up @@ -37,6 +38,7 @@
4902E3BE28F1DB07003AB55D /* DataLayer */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DataLayer; path = Modules/DataLayer; sourceTree = "<group>"; };
4902E3BF28F1DB0D003AB55D /* PresentationLayer */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = PresentationLayer; path = Modules/PresentationLayer; sourceTree = "<group>"; };
49204DE3272346EF00891C5E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
4937EC5228F3358500810F76 /* DIContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DIContainer.swift; sourceTree = "<group>"; };
493CDDD22723258300499858 /* CleanApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CleanApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
493CDDD52723258300499858 /* CleanApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CleanApp.swift; sourceTree = "<group>"; };
493CDDE22723258400499858 /* iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -117,8 +119,9 @@
493CDDD42723258300499858 /* iOS */ = {
isa = PBXGroup;
children = (
493CDDD52723258300499858 /* CleanApp.swift */,
49204DE3272346EF00891C5E /* Assets.xcassets */,
493CDDD52723258300499858 /* CleanApp.swift */,
4937EC5228F3358500810F76 /* DIContainer.swift */,
);
path = iOS;
sourceTree = "<group>";
Expand Down Expand Up @@ -208,7 +211,7 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1300;
LastSwiftUpdateCheck = 1400;
LastUpgradeCheck = 1300;
TargetAttributes = {
493CDDD12723258300499858 = {
Expand Down Expand Up @@ -273,6 +276,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4937EC5328F3358500810F76 /* DIContainer.swift in Sources */,
493CDDD62723258300499858 /* CleanApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -438,8 +442,8 @@
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -448,9 +452,12 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = io.doenicke.CleanApp;
PRODUCT_NAME = CleanApp;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = 1;
};
name = Debug;
};
Expand All @@ -466,8 +473,8 @@
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -476,9 +483,12 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = io.doenicke.CleanApp;
PRODUCT_NAME = CleanApp;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = 1;
};
name = Release;
};
Expand Down
8 changes: 0 additions & 8 deletions CleanApp/Modules/DataLayer/Sources/Data.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,11 @@ public class LocalTodoRepository: TodoRepository {
self.todos = []
}

public func add(todo: Todo) {
todos.append(todo)
}

public func todos() async -> Result<[Todo], Swift.Error> {
.success(todos)
}

@discardableResult
public func complete(id: Int) async -> Result<Todo, Swift.Error> {
if var todo = todos.first(where: { $0.id == id }) {
todo.completed = true
Expand All @@ -35,4 +32,12 @@ public class LocalTodoRepository: TodoRepository {
return .failure(Error.notFound)
}
}

@discardableResult
public func add(todo: Todo) async -> Result<Todo, Swift.Error> {
var newTodo = todo
newTodo.id = todos.count + 1
todos.append(newTodo)
return .success(newTodo)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ final class LocalTodoRepositoryTests: XCTestCase {
// Arrange
let expected = Todo(id: 1, title: "Mock")
let sut = LocalTodoRepository()
sut.add(todo: expected)
await sut.add(todo: expected)

// Act
let result = try await sut.todos().get()
Expand All @@ -27,7 +27,7 @@ final class LocalTodoRepositoryTests: XCTestCase {
// Arrange
let expected = Todo(id: 1, title: "Mock", completed: true)
let sut = LocalTodoRepository()
sut.add(todo: expected)
await sut.add(todo: expected)

// Act
let result = try await sut.complete(id: 1).get()
Expand All @@ -49,4 +49,17 @@ final class LocalTodoRepositoryTests: XCTestCase {
XCTFail()
}
}

func testAdd() async throws {
// Arrange
let expected = Todo(id: 1, title: "Mock")
let sut = LocalTodoRepository()
await sut.add(todo: Todo(title: "Mock"))

// Act
let result = try await sut.todos().get()

// Assert
XCTAssertEqual(result, [expected])
}
}
6 changes: 0 additions & 6 deletions CleanApp/Modules/DomainLayer/Sources/Domain.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ import Foundation
public protocol TodoRepository {
func todos() async -> Result<[Todo], Error>
func complete(id: Int) async -> Result<Todo, Error>
func add(todo: Todo) async -> Result<Todo, Error>
}
24 changes: 24 additions & 0 deletions CleanApp/Modules/DomainLayer/Sources/UseCases/AddTodoUseCase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// AddTodoUseCase.swift
// DomainLayer
//
// Created by Miguel Dönicke on 09.10.22.
//

import Foundation

public protocol AddTodoUseCase {
func execute(todo: Todo) async -> Result<Todo, Error>
}

public class DefaultAddTodoUseCase: AddTodoUseCase {
private let repository: TodoRepository

public init(repository: TodoRepository) {
self.repository = repository
}

public func execute(todo: Todo) async -> Result<Todo, Error> {
await repository.add(todo: todo)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

import Foundation

public class CompleteTodoUseCase {
public protocol CompleteTodoUseCase {
func execute(id: Int) async -> Result<Todo, Error>
}

public class DefaultCompleteTodoUseCase: CompleteTodoUseCase {
private let repository: TodoRepository

public init(repository: TodoRepository) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

import Foundation

public class GetAllTodosUseCase {
public protocol GetAllTodosUseCase {
func execute() async -> Result<[Todo], Error>
}

public class DefaultGetAllTodosUseCase: GetAllTodosUseCase {
private let repository: TodoRepository

public init(repository: TodoRepository) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import DomainLayer
struct MockTodoRepository: TodoRepository {
var todosResult: Result<[Todo], Error>!
var completeResult: Result<Todo, Error>!
var addResult: Result<Todo, Error>!

func todos() async -> Result<[Todo], Error> {
todosResult
Expand All @@ -19,4 +20,8 @@ struct MockTodoRepository: TodoRepository {
func complete(id: Int) async -> Result<Todo, Error> {
completeResult
}

func add(todo: Todo) async -> Result<Todo, Error> {
addResult
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// DefaultAddTodoUseCaseTests.swift
// DomainLayerTests
//
// Created by Miguel Dönicke on 09.10.22.
//

import DomainLayer
import XCTest

final class DefaultAddTodoUseCaseTests: XCTestCase {
func testExecute() async throws {
// Arrange
let expected = Todo.mock()
let repository = MockTodoRepository(addResult: .success(expected))
let sut = DefaultAddTodoUseCase(repository: repository)

// Act
let result = try await sut.execute(todo: expected).get()

// Assert
XCTAssertEqual(result, expected)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// CompleteTodoUseCaseTests.swift
// DefaultCompleteTodoUseCaseTests.swift
// DomainLayerTests
//
// Created by Miguel Dönicke on 08.10.22.
Expand All @@ -8,12 +8,12 @@
import DomainLayer
import XCTest

final class CompleteTodoUseCaseTests: XCTestCase {
final class DefaultCompleteTodoUseCaseTests: XCTestCase {
func testExecute() async throws {
// Arrange
let expected = Todo.mock()
let repository = MockTodoRepository(completeResult: .success(expected))
let sut = CompleteTodoUseCase(repository: repository)
let sut = DefaultCompleteTodoUseCase(repository: repository)

// Act
let result = try await sut.execute(id: expected.id!).get()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// GetAllTodosUseCaseTests.swift
// DefaultGetAllTodosUseCaseTests.swift
// DomainLayerTests
//
// Created by Miguel Dönicke on 08.10.22.
Expand All @@ -8,12 +8,12 @@
import DomainLayer
import XCTest

final class GetAllTodosUseCaseTests: XCTestCase {
final class DefaultGetAllTodosUseCaseTests: XCTestCase {
func testExecute() async throws {
// Arrange
let expected = [Todo.mock()]
let repository = MockTodoRepository(todosResult: .success(expected))
let sut = GetAllTodosUseCase(repository: repository)
let sut = DefaultGetAllTodosUseCase(repository: repository)

// Act
let result = try await sut.execute().get()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1400"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "PresentationLayer"
BuildableName = "PresentationLayer"
BlueprintName = "PresentationLayer"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "PresentationLayerTests"
BuildableName = "PresentationLayerTests"
BlueprintName = "PresentationLayerTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "PresentationLayer"
BuildableName = "PresentationLayer"
BlueprintName = "PresentationLayer"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Loading

0 comments on commit ef343fb

Please sign in to comment.