Skip to content

Commit 669059a

Browse files
committed
Return stats delta as formatted percentage and direction of change
1 parent 3cd945e commit 669059a

File tree

2 files changed

+48
-20
lines changed

2 files changed

+48
-20
lines changed

WooCommerce/Classes/ViewRelated/Dashboard/Factories/StatsDataTextFormatter.swift

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,11 @@ extension StatsDataTextFormatter {
124124
///
125125
static func createDeltaPercentage(from previousValue: Decimal?, to currentValue: Decimal?) -> DeltaPercentage {
126126
guard let previousValue, let currentValue else {
127-
return DeltaPercentage(value: 0) // Placeholder for missing data: `+0%`
127+
return DeltaPercentage(value: 0) // Missing data: 0% change
128128
}
129129

130130
guard previousValue > 0 else {
131-
return DeltaPercentage(value: 1) // When previous value was 0: `+100%`
131+
return DeltaPercentage(value: 1) // Previous value was 0: 100% change
132132
}
133133

134134
return DeltaPercentage(value: (currentValue - previousValue) / previousValue)
@@ -138,23 +138,38 @@ extension StatsDataTextFormatter {
138138
///
139139
static func createDeltaPercentage(from previousValue: Double?, to currentValue: Double?) -> DeltaPercentage {
140140
guard let previousValue, let currentValue else {
141-
return DeltaPercentage(value: 0) // Placeholder for missing data: `+0%`
141+
return DeltaPercentage(value: 0) // Missing data: 0% change
142142
}
143143

144144
return createDeltaPercentage(from: Decimal(previousValue), to: Decimal(currentValue))
145145
}
146146

147-
/// Represents a delta percentage value and its formatted string
147+
/// Represents a formatted delta percentage string and its direction of change
148148
struct DeltaPercentage {
149-
/// The delta percentage value
150-
let value: Decimal
151-
152149
/// The delta percentage formatted as a localized string (e.g. `+100%`)
153150
let string: String
154151

152+
/// The direction of change
153+
let direction: Direction
154+
155155
init(value: Decimal) {
156-
self.value = value
157156
self.string = deltaNumberFormatter.string(from: value as NSNumber) ?? Constants.placeholderText
157+
self.direction = {
158+
if value > 0 {
159+
return .positive
160+
} else if value < 0 {
161+
return .negative
162+
} else {
163+
return .zero
164+
}
165+
}()
166+
}
167+
168+
/// Represents the direction of change for a delta value
169+
enum Direction {
170+
case positive
171+
case negative
172+
case zero
158173
}
159174
}
160175

WooCommerce/WooCommerceTests/ViewRelated/Dashboard/StatsDataTextFormatterTests.swift

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ final class StatsDataTextFormatterTests: XCTestCase {
7171
let totalRevenueDelta = StatsDataTextFormatter.createTotalRevenueDelta(from: previousOrderStats, to: currentOrderStats)
7272

7373
// Then
74-
XCTAssertEqual(totalRevenueDelta.value, 0.5)
7574
XCTAssertEqual(totalRevenueDelta.string, "+50%")
75+
XCTAssertEqual(totalRevenueDelta.direction, .positive)
7676
}
7777

7878
// MARK: Orders Stats
@@ -116,8 +116,8 @@ final class StatsDataTextFormatterTests: XCTestCase {
116116
let orderCountDelta = StatsDataTextFormatter.createOrderCountDelta(from: previousOrderStats, to: currentOrderStats)
117117

118118
// Then
119-
XCTAssertEqual(orderCountDelta.value, 0.5)
120119
XCTAssertEqual(orderCountDelta.string, "+50%")
120+
XCTAssertEqual(orderCountDelta.direction, .positive)
121121
}
122122

123123
func test_createAverageOrderValueText_does_not_return_decimal_points_for_integer_value() {
@@ -155,8 +155,8 @@ final class StatsDataTextFormatterTests: XCTestCase {
155155
let averageOrderValueDelta = StatsDataTextFormatter.createAverageOrderValueDelta(from: previousOrderStats, to: currentOrderStats)
156156

157157
// Then
158-
XCTAssertEqual(averageOrderValueDelta.value, 0.5)
159158
XCTAssertEqual(averageOrderValueDelta.string, "+50%")
159+
XCTAssertEqual(averageOrderValueDelta.direction, .positive)
160160
}
161161

162162
// MARK: Views and Visitors Stats
@@ -198,8 +198,8 @@ final class StatsDataTextFormatterTests: XCTestCase {
198198
let visitorCountDelta = StatsDataTextFormatter.createVisitorCountDelta(from: previousSiteStats, to: currentSiteStats)
199199

200200
// Then
201-
XCTAssertEqual(visitorCountDelta.value, 0.5)
202201
XCTAssertEqual(visitorCountDelta.string, "+50%")
202+
XCTAssertEqual(visitorCountDelta.direction, .positive)
203203
}
204204

205205
// MARK: Conversion Stats
@@ -255,7 +255,7 @@ final class StatsDataTextFormatterTests: XCTestCase {
255255

256256
// MARK: Delta Calculations
257257

258-
func test_createDeltaText_returns_expected_positive_text() {
258+
func test_createDeltaPercentage_returns_expected_positive_delta() {
259259
// Given
260260
let previousValue: Double = 100
261261
let currentValue: Double = 150
@@ -264,11 +264,11 @@ final class StatsDataTextFormatterTests: XCTestCase {
264264
let delta = StatsDataTextFormatter.createDeltaPercentage(from: previousValue, to: currentValue)
265265

266266
// Then
267-
XCTAssertEqual(delta.value, 0.5)
268267
XCTAssertEqual(delta.string, "+50%")
268+
XCTAssertEqual(delta.direction, .positive)
269269
}
270270

271-
func test_createDeltaText_returns_expected_negative_text() {
271+
func test_createDeltaPercentage_returns_expected_negative_delta() {
272272
// Given
273273
let previousValue: Double = 100
274274
let currentValue: Double = 50
@@ -277,11 +277,24 @@ final class StatsDataTextFormatterTests: XCTestCase {
277277
let delta = StatsDataTextFormatter.createDeltaPercentage(from: previousValue, to: currentValue)
278278

279279
// Then
280-
XCTAssertEqual(delta.value, -0.5)
281280
XCTAssertEqual(delta.string, "-50%")
281+
XCTAssertEqual(delta.direction, .negative)
282282
}
283283

284-
func test_createDeltaText_returns_100_percent_change_when_previous_value_is_zero() {
284+
func test_createDeltaPercentage_returns_expected_zero_delta() {
285+
// Given
286+
let previousValue: Double = 100
287+
let currentValue: Double = 100
288+
289+
// When
290+
let delta = StatsDataTextFormatter.createDeltaPercentage(from: previousValue, to: currentValue)
291+
292+
// Then
293+
XCTAssertEqual(delta.string, "+0%")
294+
XCTAssertEqual(delta.direction, .zero)
295+
}
296+
297+
func test_createDeltaPercentage_returns_100_percent_change_when_previous_value_is_zero() {
285298
// Given
286299
let previousValue: Double = 0
287300
let currentValue: Double = 10
@@ -290,11 +303,11 @@ final class StatsDataTextFormatterTests: XCTestCase {
290303
let delta = StatsDataTextFormatter.createDeltaPercentage(from: previousValue, to: currentValue)
291304

292305
// Then
293-
XCTAssertEqual(delta.value, 1)
294306
XCTAssertEqual(delta.string, "+100%")
307+
XCTAssertEqual(delta.direction, .positive)
295308
}
296309

297-
func test_createDeltaText_returns_negative_100_percent_change_when_current_value_is_zero() {
310+
func test_createDeltaPercentage_returns_negative_100_percent_change_when_current_value_is_zero() {
298311
// Given
299312
let previousValue: Double = 10
300313
let currentValue: Double = 0
@@ -303,7 +316,7 @@ final class StatsDataTextFormatterTests: XCTestCase {
303316
let delta = StatsDataTextFormatter.createDeltaPercentage(from: previousValue, to: currentValue)
304317

305318
// Then
306-
XCTAssertEqual(delta.value, -1)
307319
XCTAssertEqual(delta.string, "-100%")
320+
XCTAssertEqual(delta.direction, .negative)
308321
}
309322
}

0 commit comments

Comments
 (0)