diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..274b90ff Binary files /dev/null and b/.DS_Store differ diff --git a/BankManager.swift b/BankManager.swift deleted file mode 100644 index 90347121..00000000 --- a/BankManager.swift +++ /dev/null @@ -1,7 +0,0 @@ -// -// BankManager.swift -// Created by yagom. -// Copyright © yagom academy. All rights reserved. -// - -import Foundation diff --git a/BankManagerConsoleApp/.DS_Store b/BankManagerConsoleApp/.DS_Store new file mode 100644 index 00000000..9c70a6bd Binary files /dev/null and b/BankManagerConsoleApp/.DS_Store differ diff --git a/BankManagerConsoleApp/BankManagerConsoleApp.xcodeproj/project.pbxproj b/BankManagerConsoleApp/BankManagerConsoleApp.xcodeproj/project.pbxproj index 6b40a668..63806f47 100644 --- a/BankManagerConsoleApp/BankManagerConsoleApp.xcodeproj/project.pbxproj +++ b/BankManagerConsoleApp/BankManagerConsoleApp.xcodeproj/project.pbxproj @@ -3,14 +3,43 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ + 9B26426B2B690DEE008FA05F /* CustomerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B26426A2B690DEE008FA05F /* CustomerManager.swift */; }; + 9B73730A2B61325300FDB082 /* BankManagerQueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B7373092B61325300FDB082 /* BankManagerQueueTests.swift */; }; + 9B7373102B6133C500FDB082 /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7E61A7E2B61239700D55D4A /* Node.swift */; }; + 9B7373112B6133C800FDB082 /* LinkedList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7E61A802B6123A600D55D4A /* LinkedList.swift */; }; + 9B7373122B6133CB00FDB082 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7E61A822B6123B600D55D4A /* Queue.swift */; }; + C735FB3D2B78AD750071555F /* CustomerNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = C735FB3C2B78AD750071555F /* CustomerNumber.swift */; }; + C74588442B709DD400F570DD /* ConsoleManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C74588432B709DD400F570DD /* ConsoleManager.swift */; }; + C74588462B70B7D100F570DD /* BankingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C74588452B70B7D100F570DD /* BankingService.swift */; }; + C75378492B68C32C0087F275 /* BankManagerLinkedListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75378482B68C32C0087F275 /* BankManagerLinkedListTests.swift */; }; C7694E7A259C3EC00053667F /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7694E79259C3EC00053667F /* main.swift */; }; + C76B75312B620123005B972D /* BankManagerConsoleApp in Sources */ = {isa = PBXBuildFile; fileRef = C7694E76259C3EC00053667F /* BankManagerConsoleApp */; }; + C76B75322B620127005B972D /* BankManagerConsoleTests.xctest in Sources */ = {isa = PBXBuildFile; fileRef = 9B7373072B61325300FDB082 /* BankManagerConsoleTests.xctest */; }; + C76B75332B62012C005B972D /* BankManagerConsoleApp in Sources */ = {isa = PBXBuildFile; fileRef = C7694E76259C3EC00053667F /* BankManagerConsoleApp */; }; + C76B75342B62012F005B972D /* BankManagerConsoleTests.xctest in Sources */ = {isa = PBXBuildFile; fileRef = 9B7373072B61325300FDB082 /* BankManagerConsoleTests.xctest */; }; + C78BD4D22B6909CE00682AE3 /* InputError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C78BD4D12B6909CE00682AE3 /* InputError.swift */; }; + C7A1FAEA2B68D85600050986 /* Customer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7A1FAE92B68D85600050986 /* Customer.swift */; }; + C7A1FAEC2B68DEC300050986 /* Employee.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7A1FAEB2B68DEC300050986 /* Employee.swift */; }; C7D65D1B259C8190005510E0 /* BankManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7D65D1A259C8190005510E0 /* BankManager.swift */; }; + C7E61A7F2B61239700D55D4A /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7E61A7E2B61239700D55D4A /* Node.swift */; }; + C7E61A812B6123A600D55D4A /* LinkedList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7E61A802B6123A600D55D4A /* LinkedList.swift */; }; + C7E61A832B6123B600D55D4A /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7E61A822B6123B600D55D4A /* Queue.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 9B4C3EB32B66101200420C0B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C7694E6E259C3EC00053667F /* Project object */; + proxyType = 1; + remoteGlobalIDString = C7694E75259C3EC00053667F; + remoteInfo = BankManagerConsoleApp; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ C7694E74259C3EC00053667F /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -24,12 +53,32 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 9B26426A2B690DEE008FA05F /* CustomerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomerManager.swift; sourceTree = ""; }; + 9B7373072B61325300FDB082 /* BankManagerConsoleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BankManagerConsoleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 9B7373092B61325300FDB082 /* BankManagerQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankManagerQueueTests.swift; sourceTree = ""; }; + C735FB3C2B78AD750071555F /* CustomerNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomerNumber.swift; sourceTree = ""; }; + C74588432B709DD400F570DD /* ConsoleManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleManager.swift; sourceTree = ""; }; + C74588452B70B7D100F570DD /* BankingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankingService.swift; sourceTree = ""; }; + C75378482B68C32C0087F275 /* BankManagerLinkedListTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankManagerLinkedListTests.swift; sourceTree = ""; }; C7694E76259C3EC00053667F /* BankManagerConsoleApp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = BankManagerConsoleApp; sourceTree = BUILT_PRODUCTS_DIR; }; C7694E79259C3EC00053667F /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; - C7D65D1A259C8190005510E0 /* BankManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BankManager.swift; path = ../../BankManager.swift; sourceTree = ""; }; + C78BD4D12B6909CE00682AE3 /* InputError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputError.swift; sourceTree = ""; }; + C7A1FAE92B68D85600050986 /* Customer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Customer.swift; sourceTree = ""; }; + C7A1FAEB2B68DEC300050986 /* Employee.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Employee.swift; sourceTree = ""; }; + C7D65D1A259C8190005510E0 /* BankManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BankManager.swift; sourceTree = ""; }; + C7E61A7E2B61239700D55D4A /* Node.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = ""; }; + C7E61A802B6123A600D55D4A /* LinkedList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedList.swift; sourceTree = ""; }; + C7E61A822B6123B600D55D4A /* Queue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 9B7373042B61325300FDB082 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; C7694E73259C3EC00053667F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -40,10 +89,54 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 9B2642652B68DAEA008FA05F /* Model */ = { + isa = PBXGroup; + children = ( + C7A1FAE92B68D85600050986 /* Customer.swift */, + C7A1FAEB2B68DEC300050986 /* Employee.swift */, + C735FB3C2B78AD750071555F /* CustomerNumber.swift */, + ); + path = Model; + sourceTree = ""; + }; + 9B2642662B68DAF0008FA05F /* Queue */ = { + isa = PBXGroup; + children = ( + C7E61A822B6123B600D55D4A /* Queue.swift */, + C7E61A802B6123A600D55D4A /* LinkedList.swift */, + C7E61A7E2B61239700D55D4A /* Node.swift */, + ); + path = Queue; + sourceTree = ""; + }; + 9B2642672B68DAF8008FA05F /* Controller */ = { + isa = PBXGroup; + children = ( + C74588432B709DD400F570DD /* ConsoleManager.swift */, + C7D65D1A259C8190005510E0 /* BankManager.swift */, + 9B26426A2B690DEE008FA05F /* CustomerManager.swift */, + ); + path = Controller; + sourceTree = ""; + }; + 9B7373082B61325300FDB082 /* BankManagerConsoleAppTests */ = { + isa = PBXGroup; + children = ( + 9B7373092B61325300FDB082 /* BankManagerQueueTests.swift */, + C75378482B68C32C0087F275 /* BankManagerLinkedListTests.swift */, + ); + path = BankManagerConsoleAppTests; + sourceTree = ""; + }; C7694E6D259C3EC00053667F = { isa = PBXGroup; children = ( C7694E78259C3EC00053667F /* BankManagerConsoleApp */, + 9B2642672B68DAF8008FA05F /* Controller */, + 9B2642652B68DAEA008FA05F /* Model */, + C78BD4D02B6909AB00682AE3 /* Enum */, + 9B2642662B68DAF0008FA05F /* Queue */, + 9B7373082B61325300FDB082 /* BankManagerConsoleAppTests */, C7694E77259C3EC00053667F /* Products */, ); sourceTree = ""; @@ -52,6 +145,7 @@ isa = PBXGroup; children = ( C7694E76259C3EC00053667F /* BankManagerConsoleApp */, + 9B7373072B61325300FDB082 /* BankManagerConsoleTests.xctest */, ); name = Products; sourceTree = ""; @@ -59,15 +153,41 @@ C7694E78259C3EC00053667F /* BankManagerConsoleApp */ = { isa = PBXGroup; children = ( - C7D65D1A259C8190005510E0 /* BankManager.swift */, C7694E79259C3EC00053667F /* main.swift */, ); path = BankManagerConsoleApp; sourceTree = ""; }; + C78BD4D02B6909AB00682AE3 /* Enum */ = { + isa = PBXGroup; + children = ( + C74588452B70B7D100F570DD /* BankingService.swift */, + C78BD4D12B6909CE00682AE3 /* InputError.swift */, + ); + path = Enum; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 9B7373062B61325300FDB082 /* BankManagerConsoleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9B73730D2B61325300FDB082 /* Build configuration list for PBXNativeTarget "BankManagerConsoleTests" */; + buildPhases = ( + 9B7373032B61325300FDB082 /* Sources */, + 9B7373042B61325300FDB082 /* Frameworks */, + 9B7373052B61325300FDB082 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9B4C3EB42B66101200420C0B /* PBXTargetDependency */, + ); + name = BankManagerConsoleTests; + productName = BankManagerConsoleAppTests; + productReference = 9B7373072B61325300FDB082 /* BankManagerConsoleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; C7694E75259C3EC00053667F /* BankManagerConsoleApp */ = { isa = PBXNativeTarget; buildConfigurationList = C7694E7D259C3EC00053667F /* Build configuration list for PBXNativeTarget "BankManagerConsoleApp" */; @@ -91,9 +211,13 @@ C7694E6E259C3EC00053667F /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1210; - LastUpgradeCheck = 1210; + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 1500; + LastUpgradeCheck = 1510; TargetAttributes = { + 9B7373062B61325300FDB082 = { + CreatedOnToolsVersion = 15.0.1; + }; C7694E75259C3EC00053667F = { CreatedOnToolsVersion = 12.1; }; @@ -113,23 +237,111 @@ projectRoot = ""; targets = ( C7694E75259C3EC00053667F /* BankManagerConsoleApp */, + 9B7373062B61325300FDB082 /* BankManagerConsoleTests */, ); }; /* End PBXProject section */ +/* Begin PBXResourcesBuildPhase section */ + 9B7373052B61325300FDB082 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ + 9B7373032B61325300FDB082 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C75378492B68C32C0087F275 /* BankManagerLinkedListTests.swift in Sources */, + C76B75322B620127005B972D /* BankManagerConsoleTests.xctest in Sources */, + C76B75312B620123005B972D /* BankManagerConsoleApp in Sources */, + 9B7373122B6133CB00FDB082 /* Queue.swift in Sources */, + 9B7373102B6133C500FDB082 /* Node.swift in Sources */, + 9B7373112B6133C800FDB082 /* LinkedList.swift in Sources */, + 9B73730A2B61325300FDB082 /* BankManagerQueueTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; C7694E72259C3EC00053667F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C76B75342B62012F005B972D /* BankManagerConsoleTests.xctest in Sources */, + C7A1FAEC2B68DEC300050986 /* Employee.swift in Sources */, + C76B75332B62012C005B972D /* BankManagerConsoleApp in Sources */, + C78BD4D22B6909CE00682AE3 /* InputError.swift in Sources */, + C7E61A832B6123B600D55D4A /* Queue.swift in Sources */, + C74588442B709DD400F570DD /* ConsoleManager.swift in Sources */, + C735FB3D2B78AD750071555F /* CustomerNumber.swift in Sources */, + C7A1FAEA2B68D85600050986 /* Customer.swift in Sources */, + 9B26426B2B690DEE008FA05F /* CustomerManager.swift in Sources */, + C74588462B70B7D100F570DD /* BankingService.swift in Sources */, + C7E61A7F2B61239700D55D4A /* Node.swift in Sources */, C7694E7A259C3EC00053667F /* main.swift in Sources */, + C7E61A812B6123A600D55D4A /* LinkedList.swift in Sources */, C7D65D1B259C8190005510E0 /* BankManager.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 9B4C3EB42B66101200420C0B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C7694E75259C3EC00053667F /* BankManagerConsoleApp */; + targetProxy = 9B4C3EB32B66101200420C0B /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ + 9B73730B2B61325300FDB082 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 13.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.swiftlec.BankManagerConsoleAppTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 9B73730C2B61325300FDB082 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 13.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.swiftlec.BankManagerConsoleAppTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; C7694E7B259C3EC00053667F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -164,6 +376,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -225,6 +438,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -249,6 +463,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + DEAD_CODE_STRIPPING = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; }; @@ -258,6 +473,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + DEAD_CODE_STRIPPING = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; }; @@ -266,6 +482,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 9B73730D2B61325300FDB082 /* Build configuration list for PBXNativeTarget "BankManagerConsoleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9B73730B2B61325300FDB082 /* Debug */, + 9B73730C2B61325300FDB082 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; C7694E71259C3EC00053667F /* Build configuration list for PBXProject "BankManagerConsoleApp" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/BankManagerConsoleApp/BankManagerConsoleApp.xcodeproj/xcshareddata/xcschemes/BankManagerConsoleAppTests.xcscheme b/BankManagerConsoleApp/BankManagerConsoleApp.xcodeproj/xcshareddata/xcschemes/BankManagerConsoleAppTests.xcscheme new file mode 100644 index 00000000..62988be4 --- /dev/null +++ b/BankManagerConsoleApp/BankManagerConsoleApp.xcodeproj/xcshareddata/xcschemes/BankManagerConsoleAppTests.xcscheme @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BankManagerConsoleApp/BankManagerConsoleApp/main.swift b/BankManagerConsoleApp/BankManagerConsoleApp/main.swift index 1aa9854c..8496ac3b 100644 --- a/BankManagerConsoleApp/BankManagerConsoleApp/main.swift +++ b/BankManagerConsoleApp/BankManagerConsoleApp/main.swift @@ -4,4 +4,5 @@ // Copyright © yagom academy. All rights reserved. // -import Foundation +var console: ConsoleManager = ConsoleManager() +console.operate() diff --git a/BankManagerConsoleApp/BankManagerConsoleAppTests/.DS_Store b/BankManagerConsoleApp/BankManagerConsoleAppTests/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/BankManagerConsoleApp/BankManagerConsoleAppTests/.DS_Store differ diff --git a/BankManagerConsoleApp/BankManagerConsoleAppTests/BankManagerLinkedListTests.swift b/BankManagerConsoleApp/BankManagerConsoleAppTests/BankManagerLinkedListTests.swift new file mode 100644 index 00000000..ce17647e --- /dev/null +++ b/BankManagerConsoleApp/BankManagerConsoleAppTests/BankManagerLinkedListTests.swift @@ -0,0 +1,51 @@ + +import XCTest +@testable import BankManagerConsoleApp + +final class BankMangerLinkedListTests: XCTestCase { + var sutLinkedTest: LinkedList! + + override func setUpWithError() throws { + sutLinkedTest = LinkedList() + } + + override func tearDownWithError() throws { + sutLinkedTest = nil + } + + func test_입력이1개일때_노드를1개추가하고삭제를1번하면_입력한노드가없을것이다() { + // given + let input = "A" + // when + sutLinkedTest.appendNodeAtRear(with: input) + let _ = sutLinkedTest.removeNodeFromFront() + let result = sutLinkedTest.searchNodeLocation(with: input) + // then + XCTAssertNil(result) + } + + func test_입력이1개일때_노드를1개추가하고그값을조회하면_1번위치가반환된다() { + // given + let input = "A" + let expectedResult = 1 + // when + sutLinkedTest.appendNodeAtRear(with: input) + let result = sutLinkedTest.searchNodeLocation(with: input) + // then + XCTAssertEqual(expectedResult, result) + } + + func test_입력이3개일때_노드를3개추가하고3번째값을조회하면_3번위치가반환된다() { + // given + let input = [ "A", "B", "C" ] + let expectedResult = 3 + // when + for data in input { + sutLinkedTest.appendNodeAtRear(with: data) + } + let result = sutLinkedTest.searchNodeLocation(with: input[2]) + // then + XCTAssertEqual(expectedResult, result) + } +} + diff --git a/BankManagerConsoleApp/BankManagerConsoleAppTests/BankManagerQueueTests.swift b/BankManagerConsoleApp/BankManagerConsoleAppTests/BankManagerQueueTests.swift new file mode 100644 index 00000000..5831cfb0 --- /dev/null +++ b/BankManagerConsoleApp/BankManagerConsoleAppTests/BankManagerQueueTests.swift @@ -0,0 +1,176 @@ + +import XCTest +@testable import BankManagerConsoleApp + +final class BankManagerQueueTests: XCTestCase { + var sut: Queue! + + override func setUpWithError() throws { + sut = Queue() + } + + override func tearDownWithError() throws { + sut = nil + } + + func test_초기상태일때_대기열을확인하면_대기열이없을것이다() { + // given + // when + let result = sut.isEmpty + // then + XCTAssertTrue(result) + } + + func test_입력이1개있을때_enqueue를수행하면_대기열이있을것이다() { + // given + let input = "test" + // when + sut.enqueue(with: input) + let result = sut.isEmpty + // then + XCTAssertFalse(result) + } + + func test_입력이5개있을때_queue의길이를확인하면_길이가5일것이다() { + // given + let data = [ "A", "B", "C", "D", "E" ] + let expectedLengthOfQueue = 5 + // when + for input in data { + sut.enqueue(with: input) + } + let result = sut.totalLength() + // then + XCTAssertEqual(expectedLengthOfQueue, result) + } + + func test_입력이5개일때_enqueue를5번dequeue를4번하면_queue의길이가1일것이다() { + // given + let data = [ "A", "B", "C", "D", "E" ] + let lengthOfQueue = 1 + let countOfDeque = 4 + // when + for input in data { + sut.enqueue(with: input) + } + for _ in 1...countOfDeque { + let _ = sut.dequeue() + } + let result = sut.totalLength() + // then + XCTAssertEqual(lengthOfQueue, result) + } + + func test_입력이5개일때_enqueue를5번dequeue3번하면_4번째데이터를정상적으로peek한다() { + // given + let data = [ "A", "B", "C", "D", "E" ] + let countOfDeque = 3 + let expectedResult = data[countOfDeque] + // when + for input in data { + sut.enqueue(with: input) + } + for _ in 1...countOfDeque { + let _ = sut.dequeue() + } + let result = sut.peek() + // then + XCTAssertEqual(expectedResult, result) + } + + func test_초기상태일때_dequeue를1번수행하면_길이가0을유지한다() { + // given + let expectedCount = 0 + // when + let _ = sut.dequeue() + let result = sut.totalLength() + // then + XCTAssertEqual(expectedCount, result) + } + + func test_초기상태일때_dequeue를1번수행하면_가져오는것이없을것이다() { + // given + // when + let result = sut.dequeue() + // then + XCTAssertNil(result) + } + + func test_입력이2개일때_enqueue를2번dequeue를1번수행하면_peek되는값이second일것이다() { + // given + let input = [ "First", "Second" ] + let expectedResult = "Second" + // when + for data in input { + sut.enqueue(with: data) + } + let _ = sut.dequeue() + let result = sut.peek() + // then + XCTAssertEqual(expectedResult, result) + } + + func test_입력이2개일때_enqueue를2번수행하면_dequeue한값이First일것이다() { + // given + let input = [ "First", "Second" ] + let expectedResult = "First" + //when + for data in input { + sut.enqueue(with: data) + } + let result = sut.dequeue() + // then + XCTAssertEqual(expectedResult, result) + } + + func test_입력이2개일때_enqueue를2번하고peek를하면_반환되는값이First일것이다() { + // given + let input = [ "First", "Second" ] + let expectedResult = "First" + // when + for data in input { + sut.enqueue(with: data) + } + let result = sut.peek() + // then + XCTAssertEqual(expectedResult, result) + } + + func test_입력이4개일때_enqueue를4번하고clean을하면_대기열이없을것이다() { + // given + let input = [ "A", "B", "C", "D" ] + // when + for data in input { + sut.enqueue(with: data) + } + let _ = sut.clean() + let result = sut.isEmpty + // then + XCTAssertTrue(result) + } + + func test_입력이3개일때_enque를3번하면_head의다음다음노드가정상연결되고데이터를불러온다() { + // given + let input = [ "A", "B", "C" ] + let expectedResult = "C" + // when + for data in input { + sut.enqueue(with: data) + } + let result = sut.linkedList.head?.next?.next?.data + // then + XCTAssertEqual(expectedResult, result) + } + + func test_입력이3개일때_enqueue를3번하면_tail의다음연결이nil이다() { + // given + let input = [ "A", "B", "C" ] + // when + for data in input { + sut.enqueue(with: data) + } + let result = sut.linkedList.tail?.next + // then + XCTAssertNil(result) + } +} diff --git a/BankManagerConsoleApp/Controller/.DS_Store b/BankManagerConsoleApp/Controller/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/BankManagerConsoleApp/Controller/.DS_Store differ diff --git a/BankManagerConsoleApp/Controller/BankManager.swift b/BankManagerConsoleApp/Controller/BankManager.swift new file mode 100644 index 00000000..a8ca8d2f --- /dev/null +++ b/BankManagerConsoleApp/Controller/BankManager.swift @@ -0,0 +1,21 @@ +// +// BankManager.swift +// Created by yagom. +// Copyright © yagom academy. All rights reserved. +// + +import Foundation + +struct BankManager { + private(set) var employees: [Employee] + + init(employees: [Employee]) { + self.employees = employees + } + + func reportDeadlineSummary(with customerNumber: Int, startTime bankingServiceStart: TimeInterval, endTime bankingServiceEnd: TimeInterval) { + let totalTime = bankingServiceEnd - bankingServiceStart + let convertedTotalTime = String(format: "%.2f", totalTime) + print("업무가 마감되었습니다. 오늘 업무를 처리한 고객은 총 \(customerNumber)명이며, 총 업무시간은 \(convertedTotalTime) 입니다.") + } +} diff --git a/BankManagerConsoleApp/Controller/ConsoleManager.swift b/BankManagerConsoleApp/Controller/ConsoleManager.swift new file mode 100644 index 00000000..37467292 --- /dev/null +++ b/BankManagerConsoleApp/Controller/ConsoleManager.swift @@ -0,0 +1,72 @@ + +import Foundation + +struct ConsoleManager { + private var isOpen: Bool = false + private var customerManager: CustomerManager = CustomerManager() + private var bankManager: BankManager = BankManager(employees:[ + Employee(loanTask: DispatchQueue(label: "대출1", attributes: .concurrent)), + Employee(depositTask: DispatchQueue(label: "예금1", attributes: .concurrent)), + Employee(depositTask: DispatchQueue(label: "예금2", attributes: .concurrent)) + ]) + + mutating func operate() { + isOpen = false + printMenuOfBank() + + do { + let input = try selectedByUser() + isOpen = shouldOpenBank(by: input) + } catch { + print(error.localizedDescription) + operate() + } + + while isOpen { + executeBankingOperation() + operate() + } + } + + private func shouldOpenBank(by input: String) -> Bool { + if input == "1" { + return true + } else { + print("종료되었습니다.") + return false + } + } + + private mutating func executeBankingOperation() { + customerManager.arrangeCustomers() + + let bankingServiceStart = Date.timeIntervalSinceReferenceDate + handleCustomersTasks() + let bankingServiceEnd = Date.timeIntervalSinceReferenceDate + + bankManager.reportDeadlineSummary(with: customerManager.totalCustomerNumber, startTime: bankingServiceStart, endTime: bankingServiceEnd) + customerManager.resetCustomer() + } + + private func selectedByUser() throws -> String { + guard let input = readLine(), input == "1" || input == "2" else { + throw InputError.wrongInput + } + return input + } + + private func handleCustomersTasks() { + let group = DispatchGroup() + let semaphore = DispatchSemaphore(value: 1) + bankManager.employees[0].handleLoanTasks(atTable: 0, with: customerManager.loanTicketMachine, bankManager: bankManager, group: group) + bankManager.employees[1].handleDepositTasks(atTable: 1, with: customerManager.depositTicketMachine, bankManager: bankManager, group: group, semaphore: semaphore) + bankManager.employees[2].handleDepositTasks(atTable: 2, with: customerManager.depositTicketMachine, bankManager: bankManager, group: group, semaphore: semaphore) + group.wait() + } + + private func printMenuOfBank() { + print("1 : 은행개점") + print("2 : 종료") + print("입력 : ", terminator: "") + } +} diff --git a/BankManagerConsoleApp/Controller/CustomerManager.swift b/BankManagerConsoleApp/Controller/CustomerManager.swift new file mode 100644 index 00000000..94a78215 --- /dev/null +++ b/BankManagerConsoleApp/Controller/CustomerManager.swift @@ -0,0 +1,39 @@ + +struct CustomerManager { + private(set) var loanTicketMachine: Queue = Queue() + private(set) var depositTicketMachine: Queue = Queue() + var customerNumber = CustomerNumber(loan: 0, deposit: 0) + + var totalCustomerNumber: Int { + return customerNumber.loan + customerNumber.deposit + } + + mutating func arrangeCustomers() { + createCustomers() + customerNumber.loan = loanTicketMachine.totalLength() + customerNumber.deposit = depositTicketMachine.totalLength() + } + + func createCustomers() { + let number = Int.random(in: 10...30) + for ticketNumber in 1...number { + guard let customerChoice = BankingService.allCases.randomElement() else { return } + customerChoice == BankingService.loan ? + loanTicketMachine.enqueue(with: Customer(ticketNumber: ticketNumber, bankingService: customerChoice)) : + depositTicketMachine.enqueue(with: Customer(ticketNumber: ticketNumber, bankingService: customerChoice)) + } + } + + func dequeueLoanCustomerFromQueue() -> Customer? { + return loanTicketMachine.dequeue() + } + + func dequeueDepositCustomerFromQueue() -> Customer? { + return depositTicketMachine.dequeue() + } + + func resetCustomer() { + loanTicketMachine.clean() + depositTicketMachine.clean() + } +} diff --git a/BankManagerConsoleApp/Enum/BankingService.swift b/BankManagerConsoleApp/Enum/BankingService.swift new file mode 100644 index 00000000..a55dcfc7 --- /dev/null +++ b/BankManagerConsoleApp/Enum/BankingService.swift @@ -0,0 +1,12 @@ + +enum BankingService: CaseIterable { + case loan + case deposit + + var name : String { + switch self { + case .loan: return "대출" + case .deposit: return "예금" + } + } +} diff --git a/BankManagerConsoleApp/Enum/InputError.swift b/BankManagerConsoleApp/Enum/InputError.swift new file mode 100644 index 00000000..a2075992 --- /dev/null +++ b/BankManagerConsoleApp/Enum/InputError.swift @@ -0,0 +1,13 @@ + +import Foundation + +enum InputError: LocalizedError { + case wrongInput + + var errorDescription: String? { + switch self { + case .wrongInput: + return "보여지는 메뉴의 숫자만 입력하세요!" + } + } +} diff --git a/BankManagerConsoleApp/Model/Customer.swift b/BankManagerConsoleApp/Model/Customer.swift new file mode 100644 index 00000000..28385a31 --- /dev/null +++ b/BankManagerConsoleApp/Model/Customer.swift @@ -0,0 +1,14 @@ + +struct Customer: Equatable { + private var ticketNumber: Int? + private var bankingService: BankingService? + + init(ticketNumber: Int? = nil, bankingService: BankingService? = nil) { + self.ticketNumber = ticketNumber + self.bankingService = bankingService + } + + func askEmployeeHandleTasks() -> (Int?, BankingService?)? { + return (ticketNumber, bankingService) + } +} diff --git a/BankManagerConsoleApp/Model/CustomerNumber.swift b/BankManagerConsoleApp/Model/CustomerNumber.swift new file mode 100644 index 00000000..0e316d6a --- /dev/null +++ b/BankManagerConsoleApp/Model/CustomerNumber.swift @@ -0,0 +1,5 @@ + +struct CustomerNumber { + var loan: Int + var deposit: Int +} diff --git a/BankManagerConsoleApp/Model/Employee.swift b/BankManagerConsoleApp/Model/Employee.swift new file mode 100644 index 00000000..da26e58c --- /dev/null +++ b/BankManagerConsoleApp/Model/Employee.swift @@ -0,0 +1,53 @@ + +import Foundation + +struct Employee { + var loanTask: DispatchQueue? + var depositTask: DispatchQueue? + + init(loanTask: DispatchQueue? = nil, depositTask: DispatchQueue? = nil) { + self.loanTask = loanTask + self.depositTask = depositTask + } + + func handleLoanTasks(atTable index: Int, with customerLoanQueue: Queue, bankManager: BankManager, group: DispatchGroup) { + bankManager.employees[index].loanTask?.async(group: group) { + while let customer = customerLoanQueue.dequeue() { + guard let (customerTicketNumber, customerBankingService) = customer.askEmployeeHandleTasks(), let definedCustomerTicketNumber = customerTicketNumber, let definedCustomerBankingService = customerBankingService else { return } + print("🌝 \(definedCustomerTicketNumber)번 고객 \(definedCustomerBankingService.name)업무 시작") + Thread.sleep(forTimeInterval: 1.1) + print("🌝 \(definedCustomerTicketNumber)번 고객 \(definedCustomerBankingService.name)업무 종료") + } + } + } + + func handleDepositTasks(atTable index: Int, with customerDepositQueue: Queue, bankManager: BankManager, group: DispatchGroup, semaphore: DispatchSemaphore) { + + if index == 1 { + bankManager.employees[index].depositTask?.async(group: group) { + semaphore.wait() + while let customer = customerDepositQueue.dequeue() { + + guard let (customerTicketNumber, customerBankingService) = customer.askEmployeeHandleTasks(), let definedCustomerTicketNumber = customerTicketNumber, let definedCustomerBankingService = customerBankingService else { return } + semaphore.signal() + + print("🥵 \(definedCustomerTicketNumber)번 고객 \(definedCustomerBankingService.name)업무 시작") + Thread.sleep(forTimeInterval: 0.7) + print("🥵 \(definedCustomerTicketNumber)번 고객 \(definedCustomerBankingService.name)업무 종료") + } + } + } else if index == 2 { + bankManager.employees[index].depositTask?.async(group: group) { + semaphore.wait() + while let customer = customerDepositQueue.dequeue() { + guard let (customerTicketNumber, customerBankingService) = customer.askEmployeeHandleTasks(), let definedCustomerTicketNumber = customerTicketNumber, let definedCustomerBankingService = customerBankingService else { return } + semaphore.signal() + + print("🥶 \(definedCustomerTicketNumber)번 고객 \(definedCustomerBankingService.name)업무 시작") + Thread.sleep(forTimeInterval: 0.7) + print("🥶 \(definedCustomerTicketNumber)번 고객 \(definedCustomerBankingService.name)업무 종료") + } + } + } + } +} diff --git a/BankManagerConsoleApp/Queue/LinkedList.swift b/BankManagerConsoleApp/Queue/LinkedList.swift new file mode 100644 index 00000000..4c142840 --- /dev/null +++ b/BankManagerConsoleApp/Queue/LinkedList.swift @@ -0,0 +1,64 @@ + +struct LinkedList { + private(set) var head: Node? + private(set) var tail: Node? + private(set) var count: Int = 0 + var isEmpty: Bool { head == nil } + + mutating func appendNodeAtRear(with data: T) { + if isEmpty { + tail = Node(data: data) + head = tail + count += 1 + return + } + tail?.updateNext(next: Node(data: data)) + tail = tail?.next + count += 1 + } + + mutating func removeNodeFromFront() -> T? { + let removedNode = head + if isEmpty { + tail = nil + count = 0 + return nil + } + head = head?.next + count -= 1 + return removedNode?.data + } + + mutating func clean() { + head = nil + tail = nil + count = 0 + } + + func peek() -> T? { + head?.data + } + + mutating func searchNodeLocation(with data: T?) -> Int? { + var foundLocation = 0 + + while head?.next != nil { + foundLocation += 1 + if head?.data == data { + return foundLocation + } + head = head?.next + } + + if isEmpty { + return nil + } else if head?.next == nil { + if head?.data == data { + foundLocation += 1 + return foundLocation + } + } + + return nil + } +} diff --git a/BankManagerConsoleApp/Queue/Node.swift b/BankManagerConsoleApp/Queue/Node.swift new file mode 100644 index 00000000..8b68817d --- /dev/null +++ b/BankManagerConsoleApp/Queue/Node.swift @@ -0,0 +1,18 @@ + +final class Node { + private(set) var data: T? + private(set) var next: Node? + + init(data: T? = nil, next: Node? = nil) { + self.data = data + self.next = next + } + + func updateData(data: T?) { + self.data = data + } + + func updateNext(next: Node?) { + self.next = next + } +} diff --git a/BankManagerConsoleApp/Queue/Queue.swift b/BankManagerConsoleApp/Queue/Queue.swift new file mode 100644 index 00000000..1fb11ada --- /dev/null +++ b/BankManagerConsoleApp/Queue/Queue.swift @@ -0,0 +1,25 @@ + +class Queue { + private(set) var linkedList: LinkedList = LinkedList() + var isEmpty: Bool { linkedList.isEmpty } + + func enqueue(with item: T) { + linkedList.appendNodeAtRear(with: item) + } + + func dequeue() -> T? { + return linkedList.removeNodeFromFront() + } + + func clean() { + linkedList.clean() + } + + func peek() -> T? { + return linkedList.peek() + } + + func totalLength() -> Int { + return linkedList.count + } +} diff --git a/BankManagerUIApp/.DS_Store b/BankManagerUIApp/.DS_Store new file mode 100644 index 00000000..f5ca2c4f Binary files /dev/null and b/BankManagerUIApp/.DS_Store differ diff --git a/BankManagerUIApp/BankManagerUIApp/.DS_Store b/BankManagerUIApp/BankManagerUIApp/.DS_Store new file mode 100644 index 00000000..d7095d50 Binary files /dev/null and b/BankManagerUIApp/BankManagerUIApp/.DS_Store differ diff --git a/BankManagerUIApp/BankManagerUIApp/BankManager.swift b/BankManagerUIApp/BankManagerUIApp/BankManager.swift new file mode 100644 index 00000000..9348c8bf --- /dev/null +++ b/BankManagerUIApp/BankManagerUIApp/BankManager.swift @@ -0,0 +1,8 @@ +// +// BankManager.swift +// BankManagerUIApp +// +// Created by Harry Ho on 2/7/24. +// + +import Foundation diff --git a/BankManagerUIApp/BankManagerUIApp/Base.lproj/Main.storyboard b/BankManagerUIApp/BankManagerUIApp/Base.lproj/Main.storyboard deleted file mode 100644 index ce80ec92..00000000 --- a/BankManagerUIApp/BankManagerUIApp/Base.lproj/Main.storyboard +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -