Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions SOPT-Test-Code-Study.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
/* End PBXFileReference section */

/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
63AA094E2EFAC30A0096D8DB /* Exceptions for "SOPT-Test-Code-StudyTests" folder in "SOPT-Test-Code-Study" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
CalculatorServiceTests.swift,
);
target = 63D7DF292EC2EE2700F7C4D0 /* SOPT-Test-Code-Study */;
};
63D7DF3C2EC2EE2900F7C4D0 /* Exceptions for "SOPT-Test-Code-Study" folder in "SOPT-Test-Code-Study" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Expand All @@ -39,6 +46,9 @@
/* Begin PBXFileSystemSynchronizedRootGroup section */
63C525922EC591D1002440C5 /* SOPT-Test-Code-StudyTests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
63AA094E2EFAC30A0096D8DB /* Exceptions for "SOPT-Test-Code-StudyTests" folder in "SOPT-Test-Code-Study" target */,
);
path = "SOPT-Test-Code-StudyTests";
sourceTree = "<group>";
};
Expand Down
10 changes: 10 additions & 0 deletions SOPT-Test-Code-Study/CalcOperator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// CalcOperator.swift
// SOPT-Test-Code-Study
//
// Created by 이승준 on 12/23/25.
//

enum CalcOperator {
case add, subtract, multiply, divide
}
19 changes: 19 additions & 0 deletions SOPT-Test-Code-Study/CalculatorService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// CalculatorService.swift
// SOPT-Test-Code-Study
//
// Created by 이승준 on 12/23/25.
//

import Foundation

protocol CalculatorServiceType {
func calculate(lhs: Double, rhs: Double, operator: CalcOperator) -> Double
}

class CalculatorService: CalculatorServiceType {
func calculate(lhs: Double, rhs: Double, operator: CalcOperator) -> Double {
// 실제 사칙연산 로직 구현
return 0
}
}
16 changes: 16 additions & 0 deletions SOPT-Test-Code-Study/CalculatorViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// CalculatorViewController.swift
// SOPT-Test-Code-Study
//
// Created by 이승준 on 12/23/25.
//

import Combine
import UIKit

import Then
import SnapKit

class CalculatorViewController: UIViewController {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뷰는 안구현 하신건가요..?


}
34 changes: 34 additions & 0 deletions SOPT-Test-Code-Study/CalculatorViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// CalculatorViewModel.swift
// SOPT-Test-Code-Study
//
// Created by 이승준 on 12/23/25.
//

import Combine

class CalculatorViewModel {
struct Input {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

갠취지만 인풋 아웃풋 패턴 프로토콜로 만들고 뷰모델에서 채택해주면 더 좋을 것 같습니당

let tapNumber = PassthroughSubject<Double, Never>()
let tapOperator = PassthroughSubject<CalcOperator, Never>()
let tapEqual = PassthroughSubject<Void, Never>()
}

struct Output {
let displayText = CurrentValueSubject<String, Never>("0")
}

private let service: CalculatorServiceType // DI 적용
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

과제의 의도를 명확하게 파악하셨군요 좋습니다

private var cancellables = Set<AnyCancellable>()

init(service: CalculatorServiceType = CalculatorService()) {
self.service = service
// Input을 받아 로직 처리 후 Output으로 전달하는 바인딩 구현
}

func transform(input: Input) -> Output {
let output = Output()
// Combine 연산자(combineLatest 등)를 활용한 로직
return output
}
}
35 changes: 35 additions & 0 deletions SOPT-Test-Code-StudyTests/CalculatorServiceTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// CalculatorServiceTests.swift
// SOPT-Test-Code-StudyTests
//
// Created by 이승준 on 12/23/25.
//

import XCTest

final class CalculatorServiceTests: XCTestCase {

override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
// Any test you write for XCTest can be annotated as throws and async.
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
}

func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}

}
35 changes: 35 additions & 0 deletions SOPT-Test-Code-StudyTests/CalculatorViewModelTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// CalculatorViewModelTests.swift
// SOPT-Test-Code-StudyTests
//
// Created by 이승준 on 12/23/25.
//

import XCTest

final class CalculatorViewModelTests: XCTestCase {

override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
// Any test you write for XCTest can be annotated as throws and async.
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
}

func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}

}