diff --git a/CalculatorProject/CalculatorProject.xcodeproj/project.pbxproj b/CalculatorProject/CalculatorProject.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c116716 --- /dev/null +++ b/CalculatorProject/CalculatorProject.xcodeproj/project.pbxproj @@ -0,0 +1,583 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXContainerItemProxy section */ + 1ECDD4DC2EFD7FC9005A9325 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1ECDD4C62EFD7FC8005A9325 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1ECDD4CD2EFD7FC8005A9325; + remoteInfo = CalculatorProject; + }; + 1ECDD4E62EFD7FC9005A9325 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1ECDD4C62EFD7FC8005A9325 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1ECDD4CD2EFD7FC8005A9325; + remoteInfo = CalculatorProject; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1ECDD4CE2EFD7FC8005A9325 /* CalculatorProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CalculatorProject.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1ECDD4DB2EFD7FC9005A9325 /* CalculatorProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CalculatorProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1ECDD4E52EFD7FC9005A9325 /* CalculatorProjectUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CalculatorProjectUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 1ECDD4D02EFD7FC8005A9325 /* CalculatorProject */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = CalculatorProject; + sourceTree = ""; + }; + 1ECDD4DE2EFD7FC9005A9325 /* CalculatorProjectTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = CalculatorProjectTests; + sourceTree = ""; + }; + 1ECDD4E82EFD7FC9005A9325 /* CalculatorProjectUITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = CalculatorProjectUITests; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1ECDD4CB2EFD7FC8005A9325 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1ECDD4D82EFD7FC9005A9325 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1ECDD4E22EFD7FC9005A9325 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1ECDD4C52EFD7FC8005A9325 = { + isa = PBXGroup; + children = ( + 1ECDD4D02EFD7FC8005A9325 /* CalculatorProject */, + 1ECDD4DE2EFD7FC9005A9325 /* CalculatorProjectTests */, + 1ECDD4E82EFD7FC9005A9325 /* CalculatorProjectUITests */, + 1ECDD4CF2EFD7FC8005A9325 /* Products */, + ); + sourceTree = ""; + }; + 1ECDD4CF2EFD7FC8005A9325 /* Products */ = { + isa = PBXGroup; + children = ( + 1ECDD4CE2EFD7FC8005A9325 /* CalculatorProject.app */, + 1ECDD4DB2EFD7FC9005A9325 /* CalculatorProjectTests.xctest */, + 1ECDD4E52EFD7FC9005A9325 /* CalculatorProjectUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1ECDD4CD2EFD7FC8005A9325 /* CalculatorProject */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1ECDD4EF2EFD7FC9005A9325 /* Build configuration list for PBXNativeTarget "CalculatorProject" */; + buildPhases = ( + 1ECDD4CA2EFD7FC8005A9325 /* Sources */, + 1ECDD4CB2EFD7FC8005A9325 /* Frameworks */, + 1ECDD4CC2EFD7FC8005A9325 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 1ECDD4D02EFD7FC8005A9325 /* CalculatorProject */, + ); + name = CalculatorProject; + packageProductDependencies = ( + ); + productName = CalculatorProject; + productReference = 1ECDD4CE2EFD7FC8005A9325 /* CalculatorProject.app */; + productType = "com.apple.product-type.application"; + }; + 1ECDD4DA2EFD7FC9005A9325 /* CalculatorProjectTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1ECDD4F22EFD7FC9005A9325 /* Build configuration list for PBXNativeTarget "CalculatorProjectTests" */; + buildPhases = ( + 1ECDD4D72EFD7FC9005A9325 /* Sources */, + 1ECDD4D82EFD7FC9005A9325 /* Frameworks */, + 1ECDD4D92EFD7FC9005A9325 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1ECDD4DD2EFD7FC9005A9325 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 1ECDD4DE2EFD7FC9005A9325 /* CalculatorProjectTests */, + ); + name = CalculatorProjectTests; + packageProductDependencies = ( + ); + productName = CalculatorProjectTests; + productReference = 1ECDD4DB2EFD7FC9005A9325 /* CalculatorProjectTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 1ECDD4E42EFD7FC9005A9325 /* CalculatorProjectUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1ECDD4F52EFD7FC9005A9325 /* Build configuration list for PBXNativeTarget "CalculatorProjectUITests" */; + buildPhases = ( + 1ECDD4E12EFD7FC9005A9325 /* Sources */, + 1ECDD4E22EFD7FC9005A9325 /* Frameworks */, + 1ECDD4E32EFD7FC9005A9325 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1ECDD4E72EFD7FC9005A9325 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 1ECDD4E82EFD7FC9005A9325 /* CalculatorProjectUITests */, + ); + name = CalculatorProjectUITests; + packageProductDependencies = ( + ); + productName = CalculatorProjectUITests; + productReference = 1ECDD4E52EFD7FC9005A9325 /* CalculatorProjectUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 1ECDD4C62EFD7FC8005A9325 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 2600; + LastUpgradeCheck = 2600; + TargetAttributes = { + 1ECDD4CD2EFD7FC8005A9325 = { + CreatedOnToolsVersion = 26.0.1; + }; + 1ECDD4DA2EFD7FC9005A9325 = { + CreatedOnToolsVersion = 26.0.1; + TestTargetID = 1ECDD4CD2EFD7FC8005A9325; + }; + 1ECDD4E42EFD7FC9005A9325 = { + CreatedOnToolsVersion = 26.0.1; + TestTargetID = 1ECDD4CD2EFD7FC8005A9325; + }; + }; + }; + buildConfigurationList = 1ECDD4C92EFD7FC8005A9325 /* Build configuration list for PBXProject "CalculatorProject" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 1ECDD4C52EFD7FC8005A9325; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 1ECDD4CF2EFD7FC8005A9325 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1ECDD4CD2EFD7FC8005A9325 /* CalculatorProject */, + 1ECDD4DA2EFD7FC9005A9325 /* CalculatorProjectTests */, + 1ECDD4E42EFD7FC9005A9325 /* CalculatorProjectUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1ECDD4CC2EFD7FC8005A9325 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1ECDD4D92EFD7FC9005A9325 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1ECDD4E32EFD7FC9005A9325 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1ECDD4CA2EFD7FC8005A9325 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1ECDD4D72EFD7FC9005A9325 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1ECDD4E12EFD7FC9005A9325 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 1ECDD4DD2EFD7FC9005A9325 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1ECDD4CD2EFD7FC8005A9325 /* CalculatorProject */; + targetProxy = 1ECDD4DC2EFD7FC9005A9325 /* PBXContainerItemProxy */; + }; + 1ECDD4E72EFD7FC9005A9325 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1ECDD4CD2EFD7FC8005A9325 /* CalculatorProject */; + targetProxy = 1ECDD4E62EFD7FC9005A9325 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1ECDD4ED2EFD7FC9005A9325 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 5RA2A76S4S; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 1ECDD4EE2EFD7FC9005A9325 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 5RA2A76S4S; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 1ECDD4F02EFD7FC9005A9325 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5RA2A76S4S; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + 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"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = come.Jin.CalculatorProject; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 1ECDD4F12EFD7FC9005A9325 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5RA2A76S4S; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + 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"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = come.Jin.CalculatorProject; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 1ECDD4F32EFD7FC9005A9325 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5RA2A76S4S; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = come.Jin.CalculatorProjectTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CalculatorProject.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/CalculatorProject"; + }; + name = Debug; + }; + 1ECDD4F42EFD7FC9005A9325 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5RA2A76S4S; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 26.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = come.Jin.CalculatorProjectTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CalculatorProject.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/CalculatorProject"; + }; + name = Release; + }; + 1ECDD4F62EFD7FC9005A9325 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5RA2A76S4S; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = come.Jin.CalculatorProjectUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = CalculatorProject; + }; + name = Debug; + }; + 1ECDD4F72EFD7FC9005A9325 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5RA2A76S4S; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = come.Jin.CalculatorProjectUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = CalculatorProject; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1ECDD4C92EFD7FC8005A9325 /* Build configuration list for PBXProject "CalculatorProject" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1ECDD4ED2EFD7FC9005A9325 /* Debug */, + 1ECDD4EE2EFD7FC9005A9325 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1ECDD4EF2EFD7FC9005A9325 /* Build configuration list for PBXNativeTarget "CalculatorProject" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1ECDD4F02EFD7FC9005A9325 /* Debug */, + 1ECDD4F12EFD7FC9005A9325 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1ECDD4F22EFD7FC9005A9325 /* Build configuration list for PBXNativeTarget "CalculatorProjectTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1ECDD4F32EFD7FC9005A9325 /* Debug */, + 1ECDD4F42EFD7FC9005A9325 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1ECDD4F52EFD7FC9005A9325 /* Build configuration list for PBXNativeTarget "CalculatorProjectUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1ECDD4F62EFD7FC9005A9325 /* Debug */, + 1ECDD4F72EFD7FC9005A9325 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 1ECDD4C62EFD7FC8005A9325 /* Project object */; +} diff --git a/CalculatorProject/CalculatorProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/CalculatorProject/CalculatorProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/CalculatorProject/CalculatorProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/CalculatorProject/CalculatorProject/Assets.xcassets/AccentColor.colorset/Contents.json b/CalculatorProject/CalculatorProject/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/CalculatorProject/CalculatorProject/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CalculatorProject/CalculatorProject/Assets.xcassets/AppIcon.appiconset/Contents.json b/CalculatorProject/CalculatorProject/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/CalculatorProject/CalculatorProject/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CalculatorProject/CalculatorProject/Assets.xcassets/Contents.json b/CalculatorProject/CalculatorProject/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/CalculatorProject/CalculatorProject/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CalculatorProject/CalculatorProject/CalculatorProjectApp.swift b/CalculatorProject/CalculatorProject/CalculatorProjectApp.swift new file mode 100644 index 0000000..f8e2621 --- /dev/null +++ b/CalculatorProject/CalculatorProject/CalculatorProjectApp.swift @@ -0,0 +1,17 @@ +// +// CalculatorProjectApp.swift +// CalculatorProject +// +// Created by JIN on 12/25/25. +// + +import SwiftUI + +@main +struct CalculatorProjectApp: App { + var body: some Scene { + WindowGroup { + CalculatorView() + } + } +} diff --git a/CalculatorProject/CalculatorProject/ContentView.swift b/CalculatorProject/CalculatorProject/ContentView.swift new file mode 100644 index 0000000..c7a8c10 --- /dev/null +++ b/CalculatorProject/CalculatorProject/ContentView.swift @@ -0,0 +1,24 @@ +// +// ContentView.swift +// CalculatorProject +// +// Created by JIN on 12/25/25. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { + VStack { + Image(systemName: "globe") + .imageScale(.large) + .foregroundStyle(.tint) + Text("Hello, world!") + } + .padding() + } +} + +#Preview { + ContentView() +} diff --git a/CalculatorProject/CalculatorProject/DIContainer/AppDIContainer.swift b/CalculatorProject/CalculatorProject/DIContainer/AppDIContainer.swift new file mode 100644 index 0000000..f697609 --- /dev/null +++ b/CalculatorProject/CalculatorProject/DIContainer/AppDIContainer.swift @@ -0,0 +1,19 @@ +// +// AppDIContainer.swift +// CalculatorProject +// +// Created by JIN on 12/26/25. +// + +import Foundation + +final class AppDIContainer { + static let shared = AppDIContainer() + + private init() {} + + func makeCalculatorViewModel() -> CalculatorViewModel { + let calculator = Calculator() + return CalculatorViewModel(calculator: calculator) + } +} diff --git a/CalculatorProject/CalculatorProject/Models/Calculator.swift b/CalculatorProject/CalculatorProject/Models/Calculator.swift new file mode 100644 index 0000000..2374d58 --- /dev/null +++ b/CalculatorProject/CalculatorProject/Models/Calculator.swift @@ -0,0 +1,29 @@ +// +// Calculator.swift +// CalculatorProject +// +// Created by JIN on 12/25/25. +// + +import SwiftUI + +// MARK: - Protocol +protocol CalculatorProtocol { + func calculate(lhs: Double, rhs: Double, operation: Operation) -> Double +} + +// MARK: - Implementation +final class Calculator: CalculatorProtocol { + func calculate(lhs: Double, rhs: Double, operation: Operation) -> Double { + switch operation { + case .add: + return lhs + rhs + case .subtract: + return lhs - rhs + case .multiply: + return lhs * rhs + case .divide: + return rhs != 0 ? lhs / rhs : 0 + } + } +} diff --git a/CalculatorProject/CalculatorProject/Models/CalculatorButton.swift b/CalculatorProject/CalculatorProject/Models/CalculatorButton.swift new file mode 100644 index 0000000..6f52d95 --- /dev/null +++ b/CalculatorProject/CalculatorProject/Models/CalculatorButton.swift @@ -0,0 +1,68 @@ +// +// Button.swift +// CalculatorProject +// +// Created by JIN on 12/25/25. +// + +import SwiftUI + +enum CalculatorButton: Hashable { + case zero, one, two, three, four + case five, six, seven, eight, nine + + case add + case subtract + case multiply + case divide + + case equal + case clear + + var title: String { + switch self { + case .zero: return "0" + case .one: return "1" + case .two: return "2" + case .three: return "3" + case .four: return "4" + case .five: return "5" + case .six: return "6" + case .seven: return "7" + case .eight: return "8" + case .nine: return "9" + case .add: return "+" + case .subtract: return "-" + case .multiply: return "×" + case .divide: return "÷" + case .equal: return "=" + case .clear: return "AC" + } + } + + var number: Int? { + switch self { + case .zero: return 0 + case .one: return 1 + case .two: return 2 + case .three: return 3 + case .four: return 4 + case .five: return 5 + case .six: return 6 + case .seven: return 7 + case .eight: return 8 + case .nine: return 9 + default: return nil + } + } + + var operation: Operation? { + switch self { + case .add: return .add + case .subtract: return .subtract + case .multiply: return .multiply + case .divide: return .divide + default: return nil + } + } +} diff --git a/CalculatorProject/CalculatorProject/Models/CalculatorSate.swift b/CalculatorProject/CalculatorProject/Models/CalculatorSate.swift new file mode 100644 index 0000000..21f5a21 --- /dev/null +++ b/CalculatorProject/CalculatorProject/Models/CalculatorSate.swift @@ -0,0 +1,22 @@ +// +// CalculatorSate.swift +// CalculatorProject +// +// Created by JIN on 12/25/25. +// + +import SwiftUI + +struct CalculatorState { + var currentValue: Double = 0 + var storedValue: Double? + var currentOperation: Operation? + var isNewInput: Bool = true + + mutating func reset() { + currentValue = 0 + storedValue = nil + currentOperation = nil + isNewInput = true + } +} diff --git a/CalculatorProject/CalculatorProject/Models/Operation.swift b/CalculatorProject/CalculatorProject/Models/Operation.swift new file mode 100644 index 0000000..12c11c3 --- /dev/null +++ b/CalculatorProject/CalculatorProject/Models/Operation.swift @@ -0,0 +1,24 @@ +// +// Operation.swift +// CalculatorProject +// +// Created by JIN on 12/25/25. +// + +import SwiftUI + +enum Operation { + case add + case subtract + case multiply + case divide + + var symbol: String { + switch self { + case .add: return "+" + case .subtract: return "-" + case .multiply: return "×" + case .divide: return "÷" + } + } +} diff --git a/CalculatorProject/CalculatorProject/ViewModels/CalculatorViewModel.swift b/CalculatorProject/CalculatorProject/ViewModels/CalculatorViewModel.swift new file mode 100644 index 0000000..fc1303d --- /dev/null +++ b/CalculatorProject/CalculatorProject/ViewModels/CalculatorViewModel.swift @@ -0,0 +1,99 @@ +// +// CalculatorViewModel.swift +// CalculatorProject +// +// Created by JIN on 12/26/25. +// + +import Foundation +import Combine + +final class CalculatorViewModel: ObservableObject { + @Published private(set) var state: CalculatorState + private let calculator: CalculatorProtocol + + var displayValue: String { + formatNumber(state.currentValue) + } + + init(calculator: CalculatorProtocol) { + self.calculator = calculator + self.state = CalculatorState() + } + + func buttonPressed(_ button: CalculatorButton) { + switch button { + case .zero, .one, .two, .three, .four, .five, .six, .seven, .eight, .nine: + handleNumberInput(button) + case .add, .subtract, .multiply, .divide: + handleOperation(button) + case .equal: + handleEqual() + case .clear: + handleClear() + } + } + + // MARK: - Private Methods + + private func handleNumberInput(_ button: CalculatorButton) { + guard let number = button.number else { return } + + if state.isNewInput { + state.currentValue = Double(number) + state.isNewInput = false + } else { + let currentString = String(Int(state.currentValue)) + let newString = currentString + String(number) + state.currentValue = Double(newString) ?? state.currentValue + } + } + + private func handleOperation(_ button: CalculatorButton) { + guard let operation = button.operation else { return } + + if let storedValue = state.storedValue, + let currentOperation = state.currentOperation, + !state.isNewInput { + let result = calculator.calculate( + lhs: storedValue, + rhs: state.currentValue, + operation: currentOperation + ) + state.currentValue = result + } + state.storedValue = state.currentValue + state.currentOperation = operation + state.isNewInput = true + } + + private func handleEqual() { + guard let storedValue = state.storedValue, + let operation = state.currentOperation else { + return + } + + let result = calculator.calculate( + lhs: storedValue, + rhs: state.currentValue, + operation: operation + ) + + state.currentValue = result + state.storedValue = nil + state.currentOperation = nil + state.isNewInput = true + } + + private func handleClear() { + state.reset() + } + + private func formatNumber(_ value: Double) -> String { + if value.truncatingRemainder(dividingBy: 1) == 0 { + return String(Int(value)) + } else { + return String(value) + } + } +} diff --git a/CalculatorProject/CalculatorProject/Views/CalculatorView.swift b/CalculatorProject/CalculatorProject/Views/CalculatorView.swift new file mode 100644 index 0000000..72229b3 --- /dev/null +++ b/CalculatorProject/CalculatorProject/Views/CalculatorView.swift @@ -0,0 +1,45 @@ +// +// CalculatorView.swift +// CalculatorProject +// +// Created by JIN on 12/26/25. +// + +import SwiftUI + +struct CalculatorView: View { + + @StateObject private var viewModel = AppDIContainer.shared.makeCalculatorViewModel() + + private let buttonRows: [[CalculatorButton]] = [ + [.clear, .add, .subtract, .multiply], + [.seven, .eight, .nine, .divide], + [.four, .five, .six, .equal], + [.one, .two, .three, .zero] + ] + + var body: some View { + ZStack { + Color.white.ignoresSafeArea() + VStack(spacing: 12) { + DisplayView(text: viewModel.displayValue) + .padding(.top, 30) + Spacer() + ForEach(buttonRows, id: \.self) { row in + HStack(spacing: 12) { + ForEach(row, id: \.self) { button in + CalculatorButtonView(button: button) { + viewModel.buttonPressed(button) + } + } + } + } + } + .padding() + } + } +} + +#Preview { + CalculatorView() +} diff --git a/CalculatorProject/CalculatorProject/Views/Components/CalculatorButtonView.swift b/CalculatorProject/CalculatorProject/Views/Components/CalculatorButtonView.swift new file mode 100644 index 0000000..b63df7d --- /dev/null +++ b/CalculatorProject/CalculatorProject/Views/Components/CalculatorButtonView.swift @@ -0,0 +1,38 @@ +// +// CalculatorButtonView.swift +// CalculatorProject +// +// Created by JIN on 12/26/25. +// + +import SwiftUI + +struct CalculatorButtonView: View { + let button: CalculatorButton + let action: () -> Void + + private var backgroundColor: Color { + switch button { + case .add, .subtract, .multiply, .divide, .equal, .clear: + return Color.blue + default: + return Color.gray + } + } + + private var foregroundColor: Color { + return .white + } + + var body: some View { + Button(action: action) { + Text(button.title) + .font(.system(size: 32, weight: .medium)) + .foregroundColor(foregroundColor) + .frame(width: 80, height: 80) + .background(backgroundColor) + .clipShape(Circle()) + } + } +} + diff --git a/CalculatorProject/CalculatorProject/Views/Components/DisplayView.swift b/CalculatorProject/CalculatorProject/Views/Components/DisplayView.swift new file mode 100644 index 0000000..5d345bb --- /dev/null +++ b/CalculatorProject/CalculatorProject/Views/Components/DisplayView.swift @@ -0,0 +1,26 @@ +// +// DisplayView.swift +// CalculatorProject +// +// Created by JIN on 12/26/25. +// + +import SwiftUI + +struct DisplayView: View { + let text: String + + var body: some View { + HStack { + Spacer() + Text(text) + .font(.system(size: 64, weight: .light)) + .foregroundColor(.black) + .lineLimit(1) + .minimumScaleFactor(0.5) + .padding(.horizontal, 24) + } + .frame(maxWidth: .infinity, alignment: .trailing) + .frame(height: 100) + } +} diff --git a/CalculatorProject/CalculatorProjectTests/Models/CalculatorProjectTests.swift b/CalculatorProject/CalculatorProjectTests/Models/CalculatorProjectTests.swift new file mode 100644 index 0000000..db9a57e --- /dev/null +++ b/CalculatorProject/CalculatorProjectTests/Models/CalculatorProjectTests.swift @@ -0,0 +1,100 @@ +// +// CalculatorProjectTests.swift +// CalculatorProjectTests +// +// Created by JIN on 12/25/25. +// + +import XCTest +@testable import CalculatorProject + +final class CalculatorProjectTests: XCTestCase { + + var sut: Calculator! + + override func setUp() { + super.setUp() + sut = Calculator() + } + + override func tearDown() { + sut = nil + super.tearDown() + } + + // MARK: - Addition Tests + func test_calculate_whenAddingTwoAndThree_returnsFive() { + let lhs = 2.0 + let rhs = 3.0 + + let result = sut.calculate(lhs: lhs, rhs: rhs, operation: .add) + + XCTAssertEqual(result, 5.0) + } + + func test_calculate_whenAddingNegativeAndPositive_returnsCorrectSum() { + let lhs = -5.0 + let rhs = 3.0 + + let result = sut.calculate(lhs: lhs, rhs: rhs, operation: .add) + + XCTAssertEqual(result, -2.0) + } + + // MARK: - Subtraction Tests + func test_calculate_whenSubtractingThreeFromFive_returnsTwo() { + let lhs = 5.0 + let rhs = 3.0 + + let result = sut.calculate(lhs: lhs, rhs: rhs, operation: .subtract) + + XCTAssertEqual(result, 2.0) + } + + func test_calculate_whenSubtractingLargerFromSmaller_returnsNegativeResult() { + let lhs = 3.0 + let rhs = 5.0 + + let result = sut.calculate(lhs: lhs, rhs: rhs, operation: .subtract) + + XCTAssertEqual(result, -2.0) + } + + // MARK: - Multiplication Tests + + func test_calculate_whenMultiplyingFourAndThree_returnsTwelve() { + let lhs = 4.0 + let rhs = 3.0 + + let result = sut.calculate(lhs: lhs, rhs: rhs, operation: .multiply) + + XCTAssertEqual(result, 12.0) + } + + func test_calculate_whenMultiplyingByZero_returnsZero() { + let lhs = 0.0 + let rhs = 5.0 + + let result = sut.calculate(lhs: lhs, rhs: rhs, operation: .multiply) + + XCTAssertEqual(result, 0.0) + } + + func test_calculate_whenDividingTenByTwo_returnsFive() { + let lhs = 10.0 + let rhs = 2.0 + + let result = sut.calculate(lhs: lhs, rhs: rhs, operation: .divide) + + XCTAssertEqual(result, 5.0) + } + + func test_calculate_whenDividingByZero_returnsZero() { + let lhs = 10.0 + let rhs = 0.0 + + let result = sut.calculate(lhs: lhs, rhs: rhs, operation: .divide) + + XCTAssertEqual(result, 0.0) + } +} diff --git a/CalculatorProject/CalculatorProjectTests/ViewModels/CalculatroViewModelTest.swift b/CalculatorProject/CalculatorProjectTests/ViewModels/CalculatroViewModelTest.swift new file mode 100644 index 0000000..5a482f5 --- /dev/null +++ b/CalculatorProject/CalculatorProjectTests/ViewModels/CalculatroViewModelTest.swift @@ -0,0 +1,141 @@ +// +// CalculatroViewModelTest.swift +// CalculatorProjectTests +// +// Created by JIN on 12/26/25. +// + +import XCTest +@testable import CalculatorProject + +final class CalculatorViewModelTests: XCTestCase { + var sut: CalculatorViewModel! + var mockCalculator: Calculator! + + override func setUp() { + super.setUp() + mockCalculator = Calculator() + sut = CalculatorViewModel(calculator: mockCalculator) + } + + override func tearDown() { + sut = nil + mockCalculator = nil + super.tearDown() + } + + // MARK: - Initial State Tests + + func test_initialState_shouldDisplayZero() { + XCTAssertEqual(sut.displayValue, "0") + } + + // MARK: - Number Input Tests + + func test_pressNumberButton_shouldUpdateDisplay() { + sut.buttonPressed(.two) + XCTAssertEqual(sut.displayValue, "2") + } + + func test_pressMultipleNumbers_shouldConcatenate() { + sut.buttonPressed(.two) + sut.buttonPressed(.four) + XCTAssertEqual(sut.displayValue, "24") + } + + // MARK: - Operation Tests + + func test_pressAddOperation_shouldStoreValueAndOperation() { + sut.buttonPressed(.two) + sut.buttonPressed(.four) + sut.buttonPressed(.add) + XCTAssertEqual(sut.displayValue, "24") + } + + func test_afterOperation_newNumberShouldReplaceDisplay() { + sut.buttonPressed(.two) + sut.buttonPressed(.four) + sut.buttonPressed(.add) + sut.buttonPressed(.three) + XCTAssertEqual(sut.displayValue, "3") + } + + // MARK: - Continuous Calculation Tests + + func test_continuousCalculation_24plus36plus20_shouldEqual80() { + sut.buttonPressed(.two) + sut.buttonPressed(.four) + XCTAssertEqual(sut.displayValue, "24") + sut.buttonPressed(.add) + XCTAssertEqual(sut.displayValue, "24") + sut.buttonPressed(.three) + sut.buttonPressed(.six) + XCTAssertEqual(sut.displayValue, "36") + sut.buttonPressed(.add) + XCTAssertEqual(sut.displayValue, "60") + sut.buttonPressed(.two) + sut.buttonPressed(.zero) + XCTAssertEqual(sut.displayValue, "20") + sut.buttonPressed(.equal) + XCTAssertEqual(sut.displayValue, "80") + } + + // MARK: - Equal Operation Tests + + func test_simpleAddition_shouldCalculateCorrectly() { + sut.buttonPressed(.two) + sut.buttonPressed(.four) + sut.buttonPressed(.add) + sut.buttonPressed(.three) + sut.buttonPressed(.six) + sut.buttonPressed(.equal) + XCTAssertEqual(sut.displayValue, "60") + } + + func test_simpleSubtraction_shouldCalculateCorrectly() { + sut.buttonPressed(.five) + sut.buttonPressed(.zero) + sut.buttonPressed(.subtract) + sut.buttonPressed(.three) + sut.buttonPressed(.zero) + sut.buttonPressed(.equal) + XCTAssertEqual(sut.displayValue, "20") + } + + func test_simpleMultiplication_shouldCalculateCorrectly() { + sut.buttonPressed(.one) + sut.buttonPressed(.two) + sut.buttonPressed(.multiply) + sut.buttonPressed(.five) + sut.buttonPressed(.equal) + XCTAssertEqual(sut.displayValue, "60") + } + + func test_simpleDivision_shouldCalculateCorrectly() { + sut.buttonPressed(.eight) + sut.buttonPressed(.zero) + sut.buttonPressed(.divide) + sut.buttonPressed(.four) + sut.buttonPressed(.equal) + XCTAssertEqual(sut.displayValue, "20") + } + + // MARK: - Clear Operation Tests + + func test_clearButton_shouldResetToInitialState() { + sut.buttonPressed(.two) + sut.buttonPressed(.four) + sut.buttonPressed(.add) + sut.buttonPressed(.three) + sut.buttonPressed(.six) + sut.buttonPressed(.clear) + XCTAssertEqual(sut.displayValue, "0") + } + + func test_clearButton_afterClear_canStartNewCalculation() { + sut.buttonPressed(.five) + sut.buttonPressed(.clear) + sut.buttonPressed(.three) + XCTAssertEqual(sut.displayValue, "3") + } +} diff --git a/CalculatorProject/CalculatorProjectUITests/CalculatorProjectUITests.swift b/CalculatorProject/CalculatorProjectUITests/CalculatorProjectUITests.swift new file mode 100644 index 0000000..bba74c6 --- /dev/null +++ b/CalculatorProject/CalculatorProjectUITests/CalculatorProjectUITests.swift @@ -0,0 +1,32 @@ +// +// CalculatorProjectUITests.swift +// CalculatorProjectUITests +// +// Created by JIN on 12/25/25. +// + +import XCTest + +final class CalculatorProjectUITests: XCTestCase { + + override func setUpWithError() throws { + continueAfterFailure = false + } + + override func tearDownWithError() throws { + + } + + @MainActor + func testExample() throws { + let app = XCUIApplication() + app.launch() + } + + @MainActor + func testLaunchPerformance() throws { + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/CalculatorProject/CalculatorProjectUITests/CalculatorProjectUITestsLaunchTests.swift b/CalculatorProject/CalculatorProjectUITests/CalculatorProjectUITestsLaunchTests.swift new file mode 100644 index 0000000..163ce4e --- /dev/null +++ b/CalculatorProject/CalculatorProjectUITests/CalculatorProjectUITestsLaunchTests.swift @@ -0,0 +1,29 @@ +// +// CalculatorProjectUITestsLaunchTests.swift +// CalculatorProjectUITests +// +// Created by JIN on 12/25/25. +// + +import XCTest + +final class CalculatorProjectUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +}