Skip to content

Commit 09b5009

Browse files
committed
refactor: now 시점을 최대한 상위 위치로 옮겨 시간을 일차화
1 parent 3b15203 commit 09b5009

3 files changed

Lines changed: 100 additions & 12 deletions

File tree

Application/DevLogPresentation/Sources/Today/TodayFeature+State.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ extension TodayFeature {
1212
static func summaryValue(
1313
for scope: SectionScope,
1414
todos: [TodayTodoItem],
15-
displayOptions: TodayDisplayOptions
15+
displayOptions: TodayDisplayOptions,
16+
now: Date
1617
) -> Int {
1718
let displayedTodos = displayedTodos(
1819
todos: todos,
@@ -25,9 +26,9 @@ extension TodayFeature {
2526
case .focused:
2627
return displayedTodos.filter(\.isPinned).count
2728
case .overdue:
28-
return displayedTodos.filter(isOverdue).count
29+
return displayedTodos.filter { isOverdue($0, now: now) }.count
2930
case .dueSoon:
30-
return displayedTodos.filter(isDueSoon).count
31+
return displayedTodos.filter { isDueSoon($0, now: now) }.count
3132
}
3233
}
3334

@@ -54,10 +55,11 @@ extension TodayFeature {
5455
}
5556

5657
static func groupedSectionItems(
57-
from items: [TodayTodoItem]
58+
from items: [TodayTodoItem],
59+
now: Date
5860
) -> TodayFeature.SectionCollection {
5961
let calendar = Calendar.current
60-
let startOfToday = calendar.startOfDay(for: Date())
62+
let startOfToday = calendar.startOfDay(for: now)
6163
guard let windowEnd = calendar.date(
6264
byAdding: .day,
6365
value: TodayFeature.upcomingWindowDays,
@@ -95,16 +97,16 @@ extension TodayFeature {
9597
return collection
9698
}
9799

98-
static func isOverdue(_ item: TodayTodoItem) -> Bool {
100+
static func isOverdue(_ item: TodayTodoItem, now: Date) -> Bool {
99101
guard let dueDate = item.dueDate else { return false }
100102
let calendar = Calendar.current
101-
return calendar.startOfDay(for: dueDate) < calendar.startOfDay(for: Date())
103+
return calendar.startOfDay(for: dueDate) < calendar.startOfDay(for: now)
102104
}
103105

104-
static func isDueSoon(_ item: TodayTodoItem) -> Bool {
106+
static func isDueSoon(_ item: TodayTodoItem, now: Date) -> Bool {
105107
guard let dueDate = item.dueDate else { return false }
106108
let calendar = Calendar.current
107-
let startOfToday = calendar.startOfDay(for: Date())
109+
let startOfToday = calendar.startOfDay(for: now)
108110
guard let windowEnd = calendar.date(
109111
byAdding: .day,
110112
value: TodayFeature.upcomingWindowDays,

Application/DevLogPresentation/Sources/Today/TodayFeature.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ struct TodayFeature {
5959
}
6060

6161
var sections: [SectionContent] {
62+
let now = Date()
6263
let items = TodayFeature.groupedSectionItems(
6364
from: TodayFeature.displayedTodos(
6465
todos: todos,
6566
displayOptions: displayOptions
66-
)
67+
),
68+
now: now
6769
)
6870

6971
switch selectedSectionScope {
@@ -122,14 +124,16 @@ struct TodayFeature {
122124
}
123125

124126
var summaryCounts: [SectionScope: Int] {
125-
Dictionary(
127+
let now = Date()
128+
return Dictionary(
126129
uniqueKeysWithValues: SectionScope.allCases.map { scope in
127130
(
128131
scope,
129132
TodayFeature.summaryValue(
130133
for: scope,
131134
todos: todos,
132-
displayOptions: displayOptions
135+
displayOptions: displayOptions,
136+
now: now
133137
)
134138
)
135139
}

Application/DevLogPresentation/Tests/Today/TodayFeatureTests.swift

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,65 @@
66
//
77

88
import Testing
9+
import Foundation
10+
import DevLogCore
911
@testable import DevLogPresentation
1012

1113
@MainActor
1214
struct TodayFeatureTests {
15+
@Test("TodayFeature groupedSectionItems는 주입된 now 기준으로 섹션을 분류한다")
16+
func TodayFeature_groupedSectionItems는_주입된_now_기준으로_섹션을_분류한다() throws {
17+
let now = try #require(makeFixedTodayNow())
18+
let items = makeFixedTodayTodoItems(now: now)
19+
20+
let sections = TodayFeature.groupedSectionItems(from: items, now: now)
21+
22+
#expect(sections.focused.map(\.id) == ["focused"])
23+
#expect(sections.overdue.map(\.id) == ["overdue"])
24+
#expect(sections.dueSoon.map(\.id) == ["due-soon"])
25+
#expect(sections.later.map(\.id) == ["later"])
26+
#expect(sections.unscheduled.map(\.id) == ["unscheduled"])
27+
}
28+
29+
@Test("TodayFeature summaryValue는 주입된 now 기준으로 요약 값을 계산한다")
30+
func TodayFeature_summaryValue는_주입된_now_기준으로_요약_값을_계산한다() throws {
31+
let now = try #require(makeFixedTodayNow())
32+
let todos = makeFixedTodayTodoItems(now: now)
33+
34+
#expect(
35+
TodayFeature.summaryValue(
36+
for: .all,
37+
todos: todos,
38+
displayOptions: .default,
39+
now: now
40+
) == 5
41+
)
42+
#expect(
43+
TodayFeature.summaryValue(
44+
for: .focused,
45+
todos: todos,
46+
displayOptions: .default,
47+
now: now
48+
) == 1
49+
)
50+
#expect(
51+
TodayFeature.summaryValue(
52+
for: .overdue,
53+
todos: todos,
54+
displayOptions: .default,
55+
now: now
56+
) == 1
57+
)
58+
#expect(
59+
TodayFeature.summaryValue(
60+
for: .dueSoon,
61+
todos: todos,
62+
displayOptions: .default,
63+
now: now
64+
) == 2
65+
)
66+
}
67+
1368
@Test("현재 TodayViewModel fetchData는 요약과 섹션 상태를 갱신한다")
1469
func 현재_TodayViewModel_fetchData는_요약과_섹션_상태를_갱신한다() async throws {
1570
let todos = makeTodaySectionTodos()
@@ -234,3 +289,30 @@ struct TodayFeatureTests {
234289
await verifyTodayFetchFailureShowsAlert(adapter: adapter)
235290
}
236291
}
292+
293+
private func makeFixedTodayNow() -> Date? {
294+
Calendar.current.date(
295+
from: DateComponents(
296+
year: 2026,
297+
month: 6,
298+
day: 14,
299+
hour: 12
300+
)
301+
)
302+
}
303+
304+
private func makeFixedTodayTodoItems(now: Date) -> [TodayTodoItem] {
305+
let calendar = Calendar.current
306+
307+
func dueDate(_ dayOffset: Int) -> Date {
308+
calendar.date(byAdding: .day, value: dayOffset, to: now) ?? now
309+
}
310+
311+
return [
312+
TodayTodoItem(from: makeTodayTodo(id: "focused", isPinned: true, dueDate: dueDate(1)))!,
313+
TodayTodoItem(from: makeTodayTodo(id: "overdue", dueDate: dueDate(-1)))!,
314+
TodayTodoItem(from: makeTodayTodo(id: "due-soon", dueDate: dueDate(2)))!,
315+
TodayTodoItem(from: makeTodayTodo(id: "later", dueDate: dueDate(10)))!,
316+
TodayTodoItem(from: makeTodayTodo(id: "unscheduled", dueDate: nil))!
317+
]
318+
}

0 commit comments

Comments
 (0)