Skip to content

Commit 14b80c0

Browse files
author
Reed Es
committed
init?() now fails on nonsense input
1 parent 8262b47 commit 14b80c0

File tree

3 files changed

+26
-20
lines changed

3 files changed

+26
-20
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Generate 'nice' numbers for label ticks over a range, such as for y-axis on a chart.
44

5-
Adapted from pseudo-code in *Graphics Gems, Volume 1* by Andrew S. Glassner (1995).
5+
Adapted from pseudo-code in *Graphics Gems, Volume 1* by Andrew S. Glassner (1995). See also Tufte (1983) for a discussion of topic.
66

77
Available as an open source Swift library to be incorporated in other apps.
88

@@ -16,12 +16,15 @@ _SwiftNiceScale_ is part of the [OpenAlloc](https://github.com/openalloc) family
1616
let ns = NiceScale(105...543, desiredTicks: 5)
1717

1818
print("nice range=\(ns.range)")
19+
1920
=> "nice range=100.0...600.0"
2021

2122
print("tick interval=\(ns.tickInterval)")
23+
2224
=> "tick interval=100.0"
2325

2426
print("labels=\(ns.tickValues)")
27+
2528
=> "labels=[100.0, 200.0, 300.0, 400.0, 500.0, 600.0]"
2629
```
2730

@@ -37,7 +40,9 @@ typealias ValueRange = ClosedRange<T>
3740

3841
#### Initializer
3942

40-
- `init(_ rawRange: NiceScale<T>.ValueRange, desiredTicks: Int)` - create a new `NiceScale` instance
43+
- `init?(_ rawRange: NiceScale<T>.ValueRange, desiredTicks: Int)` - create a new `NiceScale` instance
44+
45+
Initialization will fail and return `nil` if provided nonsense parameters, such as a range with zero extent, or a desired tick count less than 2.
4146

4247
The initialization values are also available as properties:
4348

Sources/NiceScale.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public final class NiceScale<T: BinaryFloatingPoint & Real> {
2626
public let rawRange: ValueRange
2727
public let desiredTicks: Int
2828

29-
public init(_ rawRange: ValueRange, desiredTicks: Int = 10) {
29+
public init?(_ rawRange: ValueRange, desiredTicks: Int = 10) {
30+
guard rawRange.lowerBound < rawRange.upperBound, desiredTicks > 1 else { return nil }
3031
self.rawRange = rawRange
3132
self.desiredTicks = desiredTicks
3233
}

Tests/NiceScaleTests.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class NiceScaleTests: XCTestCase {
2727
typealias NS = NiceScale<Double>
2828

2929
func testExample() {
30-
let ns = NiceScale(105...543, desiredTicks: 5)
30+
let ns = NiceScale(105...543, desiredTicks: 5)!
3131
XCTAssertEqual(0, ns.tickFractionDigits)
3232
XCTAssertEqual(100, ns.tickInterval)
3333
XCTAssertEqual(100.0...600.0, ns.range)
@@ -37,29 +37,29 @@ class NiceScaleTests: XCTestCase {
3737
}
3838

3939
func testFractionDigits() {
40-
let ns20 = NS(1...4, desiredTicks: 20)
40+
let ns20 = NS(1...4, desiredTicks: 20)!
4141
XCTAssertEqual(1, ns20.tickFractionDigits)
4242

43-
let ns200 = NS(1...4, desiredTicks: 200)
43+
let ns200 = NS(1...4, desiredTicks: 200)!
4444
XCTAssertEqual(2, ns200.tickFractionDigits)
4545
}
4646

47-
func testNoRange() {
48-
let ns = NS(0...0)
49-
XCTAssertFalse(ns.hasPositiveRange)
50-
XCTAssertFalse(ns.hasNegativeRange)
51-
XCTAssertEqual(0...0, ns.positiveRange)
52-
XCTAssertEqual(0...0, ns.negativeRange)
53-
XCTAssertEqual(0, ns.positiveExtent)
54-
XCTAssertEqual(0, ns.negativeExtent)
47+
func testBadInit() {
48+
let ns0 = NS(0...0)
49+
XCTAssertNil(ns0)
50+
51+
let ns1 = NS(1...1)
52+
XCTAssertNil(ns1)
53+
54+
let ns2 = NS(0...1, desiredTicks: 0)
55+
XCTAssertNil(ns2)
5556

56-
XCTAssertEqual(Double.infinity, ns.scaleToUnit(1000))
57-
XCTAssertEqual(Double.infinity, ns.scaleToUnitPositive(1000))
58-
XCTAssertEqual(-Double.infinity, ns.scaleToUnitNegative(1000))
57+
let ns3 = NS(0...1, desiredTicks: 1)
58+
XCTAssertNil(ns3)
5959
}
6060

6161
func testPositiveRange() {
62-
let ns = NS(10...100)
62+
let ns = NS(10...100)!
6363
XCTAssertTrue(ns.hasPositiveRange)
6464
XCTAssertFalse(ns.hasNegativeRange)
6565
XCTAssertEqual(10...100, ns.positiveRange)
@@ -73,7 +73,7 @@ class NiceScaleTests: XCTestCase {
7373
}
7474

7575
func testNegativeRange() {
76-
let ns = NS(-100...(-10))
76+
let ns = NS(-100...(-10))!
7777
XCTAssertFalse(ns.hasPositiveRange)
7878
XCTAssertTrue(ns.hasNegativeRange)
7979
XCTAssertEqual(0...0, ns.positiveRange)
@@ -87,7 +87,7 @@ class NiceScaleTests: XCTestCase {
8787
}
8888

8989
func testBothRange() {
90-
let ns = NS(-100...100)
90+
let ns = NS(-100...100)!
9191
XCTAssertTrue(ns.hasPositiveRange)
9292
XCTAssertTrue(ns.hasNegativeRange)
9393
XCTAssertEqual(0...100, ns.positiveRange)

0 commit comments

Comments
 (0)