Files
CurvyText/PathText/Tests/PathTextTests/PathTextTests.swift
2020-01-02 17:12:35 -05:00

228 lines
8.3 KiB
Swift

import XCTest
import SwiftUI
@testable import PathText
func AssertPathTangentsEqual(_ expression1: [PathTangent], _ expression2: [PathTangent]) {
for (tangent1, tangent2) in zip(expression1, expression2) {
XCTAssertEqual(tangent1.t, tangent2.t, accuracy: 0.01)
XCTAssertEqual(tangent1.angle, tangent2.angle, accuracy: 0.01)
XCTAssertEqual(tangent1.point.x, tangent2.point.x, accuracy: 1.0)
XCTAssertEqual(tangent1.point.y, tangent2.point.y, accuracy: 1.0)
}
}
@available(iOS 13.0, *)
final class PathTextTests: XCTestCase {
static let text: NSAttributedString = {
let string = NSString("You can display text along a curve, with bold, color, and big text.")
let s = NSMutableAttributedString(string: string as String,
attributes: [.font: UIFont.systemFont(ofSize: 16)])
s.addAttributes([.font: UIFont.boldSystemFont(ofSize: 16)], range: string.range(of: "bold"))
s.addAttributes([.foregroundColor: UIColor.red], range: string.range(of: "color"))
s.addAttributes([.font: UIFont.systemFont(ofSize: 32)], range: string.range(of: "big text"))
return s
}()
func testCurve() {
let P0 = CGPoint(x: 50, y: 500)
let P1 = CGPoint(x: 300, y: 300)
let P2 = CGPoint(x: 400, y: 700)
let P3 = CGPoint(x: 650, y: 500)
let path = Path() {
$0.move(to: P0)
$0.addCurve(to: P3, control1: P1, control2: P2)
}.cgPath
let sections = path.sections()
XCTAssertEqual(sections.count, 1)
guard let section = sections.first as? PathCurveSection else {
XCTFail()
return
}
XCTAssertEqual(section.p0, P0)
XCTAssertEqual(section.p1, P1)
XCTAssertEqual(section.p2, P2)
XCTAssertEqual(section.p3, P3)
var generator = TangentGenerator(path: path)
let tangents = [0, 100, 200, 300, 400, 500, 600].compactMap{ generator.getTangent(at: $0) }
AssertPathTangentsEqual(tangents, [
PathTangent(t: 0, point: P0, angle: -0.674),
PathTangent(t: 0.124, point: CGPoint(x: 137, y: 451), angle: -0.310),
PathTangent(t: 0.288, point: CGPoint(x: 236, y: 448), angle: 0.234),
PathTangent(t: 0.461, point: CGPoint(x: 328, y: 488), angle: 0.510),
PathTangent(t: 0.628, point: CGPoint(x: 416, y: 536), angle: 0.420),
PathTangent(t: 0.800, point: CGPoint(x: 513, y: 558), angle: -0.026),
PathTangent(t: 0.947, point: CGPoint(x: 607, y: 528), angle: -0.522),
])
}
func testFlatLine() {
let P0 = CGPoint(x: 0, y: 0)
let P1 = CGPoint(x: 800, y: 0)
let path = Path() {
$0.move(to: P0)
$0.addLine(to: P1)
}.cgPath
let sections = path.sections()
XCTAssertEqual(sections.count, 1)
guard let section = sections.first as? PathLineSection else {
XCTFail()
return
}
XCTAssertEqual(section.start, P0)
XCTAssertEqual(section.end, P1)
var generator = TangentGenerator(path: path)
let tangents = [0, 100, 200, 300, 400, 500, 600, 700].compactMap{ generator.getTangent(at: $0) }
AssertPathTangentsEqual(tangents, [
PathTangent(t: 0, point: CGPoint(x: 0, y: 0), angle: 0),
PathTangent(t: 0.125, point: CGPoint(x: 100, y: 0), angle: 0),
PathTangent(t: 0.250, point: CGPoint(x: 200, y: 0), angle: 0),
PathTangent(t: 0.375, point: CGPoint(x: 300, y: 0), angle: 0),
PathTangent(t: 0.500, point: CGPoint(x: 400, y: 0), angle: 0),
PathTangent(t: 0.625, point: CGPoint(x: 500, y: 0), angle: 0),
PathTangent(t: 0.750, point: CGPoint(x: 600, y: 0), angle: 0),
PathTangent(t: 0.875, point: CGPoint(x: 700, y: 0), angle: 0),
])
}
func testLine() {
let P0 = CGPoint(x: 0, y: 0)
let P1 = CGPoint(x: 800, y: 800)
let path = Path() {
$0.move(to: P0)
$0.addLine(to: P1)
}.cgPath
let sections = path.sections()
XCTAssertEqual(sections.count, 1)
guard let section = sections.first as? PathLineSection else {
XCTFail()
return
}
XCTAssertEqual(section.start, P0)
XCTAssertEqual(section.end, P1)
var generator = TangentGenerator(path: path)
let tangents = [0, 100, 200, 300, 400, 500, 600, 700].compactMap{ generator.getTangent(at: $0) }
let angle: CGFloat = atan(1)
AssertPathTangentsEqual(tangents, [
PathTangent(t: 0.000, point: CGPoint(x: 0.0, y: 0.0), angle: angle),
PathTangent(t: 0.089, point: CGPoint(x: 71, y: 71), angle: angle),
PathTangent(t: 0.178, point: CGPoint(x: 142, y: 142), angle: angle),
PathTangent(t: 0.267, point: CGPoint(x: 214, y: 214), angle: angle),
PathTangent(t: 0.356, point: CGPoint(x: 285, y: 285), angle: angle),
PathTangent(t: 0.445, point: CGPoint(x: 356, y: 356), angle: angle),
PathTangent(t: 0.534, point: CGPoint(x: 427, y: 427), angle: angle),
PathTangent(t: 0.623, point: CGPoint(x: 498, y: 498), angle: angle),
])
}
func testTwoLines() {
let P0 = CGPoint(x: 0, y: 0)
let P1 = CGPoint(x: 400, y: 400)
let P2 = CGPoint(x: 800, y: 0)
let path = Path() {
$0.move(to: P0)
$0.addLine(to: P1)
$0.addLine(to: P2)
}.cgPath
let sections = path.sections()
XCTAssertEqual(sections.count, 2)
guard let section1 = sections.first as? PathLineSection else {
XCTFail()
return
}
XCTAssertEqual(section1.start, P0)
XCTAssertEqual(section1.end, P1)
guard let section2 = sections.dropFirst().first as? PathLineSection else {
XCTFail()
return
}
XCTAssertEqual(section2.start, P1)
XCTAssertEqual(section2.end, P2)
var generator = TangentGenerator(path: path)
let tangents = [0, 100, 200, 300, 400, 500, 600, 700].compactMap{ generator.getTangent(at: $0) }
AssertPathTangentsEqual(tangents, [
PathTangent(t: 0.000, point: CGPoint(x: 0, y: 0), angle: 0.785),
PathTangent(t: 0.177, point: CGPoint(x: 70, y: 71), angle: 0.785),
PathTangent(t: 0.354, point: CGPoint(x: 141, y: 142), angle: 0.785),
PathTangent(t: 0.531, point: CGPoint(x: 212, y: 212), angle: 0.785),
PathTangent(t: 0.708, point: CGPoint(x: 283, y: 283), angle: 0.785),
PathTangent(t: 0.885, point: CGPoint(x: 354, y: 354), angle: 0.785),
PathTangent(t: 0.062, point: CGPoint(x: 425, y: 375), angle: -0.785),
PathTangent(t: 0.239, point: CGPoint(x: 496, y: 304), angle: -0.785),
])
}
func testQuadCurve() {
let P0 = CGPoint(x: 50, y: 500)
let P1 = CGPoint(x: 300, y: 300)
let P2 = CGPoint(x: 650, y: 500)
let path = Path() {
$0.move(to: P0)
$0.addQuadCurve(to: P2, control: P1)
}.cgPath
let sections = path.sections()
XCTAssertEqual(sections.count, 1)
guard let section1 = sections.first as? PathQuadCurveSection else {
XCTFail()
return
}
XCTAssertEqual(section1.p0, P0)
XCTAssertEqual(section1.p1, P1)
XCTAssertEqual(section1.p2, P2)
var generator = TangentGenerator(path: path)
let tangents = [0, 100, 200, 300, 400, 500, 600, 700].compactMap{ generator.getTangent(at: $0) }
AssertPathTangentsEqual(tangents, [
PathTangent(t: 0.000, point: CGPoint(x: 50, y: 500), angle: -0.675),
PathTangent(t: 0.163, point: CGPoint(x: 134, y: 445), angle: -0.469),
PathTangent(t: 0.334, point: CGPoint(x: 228, y: 411), angle: -0.230),
PathTangent(t: 0.505, point: CGPoint(x: 328, y: 400), angle: 0.007),
PathTangent(t: 0.667, point: CGPoint(x: 427, y: 411), angle: 0.208),
PathTangent(t: 0.815, point: CGPoint(x: 523, y: 440), angle: 0.363),
PathTangent(t: 0.950, point: CGPoint(x: 614, y: 481), angle: 0.481),
])
}
}