@@ -126,6 +126,73 @@ struct HeatmapWidgetSnapshotFactoryTests {
126126 #expect( targetDay. deletedCount == 3 )
127127 }
128128
129+ @Test ( " Heatmap 위젯 스냅샷은 분기 시작일은 포함하고 다음 분기 시작일은 제외한다 " )
130+ func heatmap_위젯_스냅샷은_분기_시작일은_포함하고_다음_분기_시작일은_제외한다( ) throws {
131+ let calendar = Calendar ( identifier: . gregorian)
132+ let quarterStart = try #require( calendar. date ( from: DateComponents ( year: 2026 , month: 4 , day: 1 ) ) )
133+ let nextQuarterStart = try #require( calendar. date ( from: DateComponents ( year: 2026 , month: 7 , day: 1 ) ) )
134+ let quarterLastDate = try #require( calendar. date ( byAdding: . second, value: - 1 , to: nextQuarterStart) )
135+ let factory = HeatmapWidgetSnapshotFactory ( calendar: calendar)
136+
137+ let snapshot = factory. makeSnapshot (
138+ createdTodos: [
139+ makeTodo ( id: " created-quarter-start " , createdAt: quarterStart) ,
140+ makeTodo ( id: " created-next-quarter-start " , createdAt: nextQuarterStart)
141+ ] ,
142+ completedTodos: [
143+ makeTodo (
144+ id: " completed-quarter-last-date " ,
145+ createdAt: quarterStart,
146+ completedAt: quarterLastDate
147+ )
148+ ] ,
149+ deletedTodos: [ ] ,
150+ selectedActivityKinds: [ . created, . completed] ,
151+ quarterStart: quarterStart,
152+ now: quarterStart
153+ )
154+
155+ let aprilFirst = try #require( day ( for: DateComponents ( year: 2026 , month: 4 , day: 1 ) , in: snapshot, calendar: calendar) )
156+ let juneThirtieth = try #require( day ( for: DateComponents ( year: 2026 , month: 6 , day: 30 ) , in: snapshot, calendar: calendar) )
157+
158+ #expect( aprilFirst. createdCount == 1 )
159+ #expect( juneThirtieth. completedCount == 1 )
160+ #expect( day ( for: DateComponents ( year: 2026 , month: 7 , day: 1 ) , in: snapshot, calendar: calendar) == nil )
161+ #expect( snapshot. maxCount == 1 )
162+ }
163+
164+ @Test ( " Heatmap 위젯 스냅샷은 Q4 분기를 다음 해 1월 전까지 만든다 " )
165+ func heatmap_위젯_스냅샷은_q4_분기를_다음_해_1월_전까지_만든다( ) throws {
166+ let calendar = Calendar ( identifier: . gregorian)
167+ let q4Date = try #require( calendar. date ( from: DateComponents ( year: 2026 , month: 11 , day: 10 ) ) )
168+ let octoberStart = try #require( calendar. date ( from: DateComponents ( year: 2026 , month: 10 , day: 1 ) ) )
169+ let novemberStart = try #require( calendar. date ( from: DateComponents ( year: 2026 , month: 11 , day: 1 ) ) )
170+ let decemberStart = try #require( calendar. date ( from: DateComponents ( year: 2026 , month: 12 , day: 1 ) ) )
171+ let decemberLastDate = try #require( calendar. date ( from: DateComponents ( year: 2026 , month: 12 , day: 31 ) ) )
172+ let nextYearStart = try #require( calendar. date ( from: DateComponents ( year: 2027 , month: 1 , day: 1 ) ) )
173+ let factory = HeatmapWidgetSnapshotFactory ( calendar: calendar)
174+
175+ let snapshot = factory. makeSnapshot (
176+ createdTodos: [
177+ makeTodo ( id: " created-december-last-date " , createdAt: decemberLastDate) ,
178+ makeTodo ( id: " created-next-year-start " , createdAt: nextYearStart)
179+ ] ,
180+ completedTodos: [ ] ,
181+ deletedTodos: [ ] ,
182+ selectedActivityKinds: [ . created] ,
183+ quarterStart: q4Date,
184+ now: q4Date
185+ )
186+
187+ let decemberLastDay = try #require( day ( for: DateComponents ( year: 2026 , month: 12 , day: 31 ) , in: snapshot, calendar: calendar) )
188+
189+ #expect( snapshot. quarterStart == octoberStart)
190+ #expect( snapshot. months. map ( \. monthStart) == [ octoberStart, novemberStart, decemberStart] )
191+ #expect( decemberLastDay. createdCount == 1 )
192+ #expect( day ( for: DateComponents ( year: 2027 , month: 1 , day: 1 ) , in: snapshot, calendar: calendar) == nil )
193+ #expect( snapshot. maxCount == 1 )
194+ }
195+
129196 private func day(
130197 for components: DateComponents ,
131198 in snapshot: HeatmapWidgetSnapshot ,
0 commit comments