├── Assets
├── AppXNumber.png
├── AppXPattern.png
├── ViewXNumber.gif
└── ViewXPattern.gif
├── .gitignore
├── Apps
└── DiffableTextAppXUIKit
│ ├── App
│ ├── Assets
│ │ ├── Assets.xcassets
│ │ │ ├── Contents.json
│ │ │ ├── AccentColor.colorset
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ └── Preview Content
│ │ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── App.swift
│ ├── Helpers
│ │ ├── Random.swift
│ │ ├── Range.swift
│ │ ├── Twins.swift
│ │ └── Bounds.swift
│ ├── Models
│ │ └── Constants.swift
│ ├── Views
│ │ ├── Scroller.swift
│ │ ├── Action.swift
│ │ ├── Screen.swift
│ │ └── Interval.swift
│ ├── Utilities
│ │ ├── Observer.swift
│ │ └── Observable.swift
│ └── Screens
│ │ ├── Number
│ │ └── NumberScreenContext.swift
│ │ └── Pattern
│ │ ├── PatternScreenExample.swift
│ │ └── PatternScreenContext.swift
│ ├── Modules
│ └── IntervalSliderViews
│ │ ├── .gitignore
│ │ ├── Package.swift
│ │ └── Sources
│ │ └── IntervalSliderViews
│ │ └── Models
│ │ ├── Values.swift
│ │ ├── Layout.swift
│ │ └── Context.swift
│ ├── DiffableTextAppXUIKit.xcodeproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── Entitlements.entitlements
├── Sources
├── DiffableTextKitXNumber
│ ├── Exports.swift
│ ├── Models
│ │ ├── Parser.swift
│ │ ├── Count.swift
│ │ ├── Attributes.swift
│ │ ├── Preferences.swift
│ │ ├── Clamp.swift
│ │ └── Label.swift
│ ├── Aliases.swift
│ ├── Traits.swift
│ ├── Tokens
│ │ ├── Separator.swift
│ │ ├── Digit.swift
│ │ └── Sign.swift
│ ├── Value.swift
│ ├── Graphs
│ │ └── Graph+Decimal.swift
│ └── Graph.swift
├── DiffableTextKitXPattern
│ └── Exports.swift
├── DiffableTextKitXUIKit
│ ├── Exports.swift
│ ├── Streams
│ │ ├── Sidestream.swift
│ │ └── Upstream.swift
│ ├── Models
│ │ ├── Intent.swift
│ │ └── Alignment.swift
│ ├── Environment+OnSubmit.swift
│ ├── Environment+Tint.swift
│ ├── Environment+SubmitLabel.swift
│ ├── Environment+KeyboardType.swift
│ ├── Environment+ForegroundColor.swift
│ ├── Environment+MultilineTextAlignment.swift
│ ├── Environment+AutocorrectionDisabled.swift
│ ├── Environment+TextFieldStyle.swift
│ ├── Environment+TextInputAutocapitalization.swift
│ ├── Environment+TextContentType.swift
│ ├── Environment+ToolbarDoneButton.swift
│ └── Environment+Font.swift
├── DiffableTextKit
│ ├── Utilities
│ │ ├── Void.swift
│ │ ├── Locale.swift
│ │ ├── Count.swift
│ │ ├── Slice.swift
│ │ ├── Options.swift
│ │ ├── Brrr.swift
│ │ ├── Trigger.swift
│ │ └── Lock.swift
│ ├── Models
│ │ ├── Focus.swift
│ │ ├── Synchronize.swift
│ │ ├── Changes.swift
│ │ ├── Resolve.swift
│ │ ├── Update.swift
│ │ ├── Direction.swift
│ │ ├── Index.swift
│ │ └── Caret.swift
│ └── Styles
│ │ ├── Normal.swift
│ │ └── Constant.swift
└── DiffableTextViews
│ └── Exports.swift
└── Tests
├── DiffableTextKitTests
├── Aliases.swift
├── Constants.swift
├── Utilities
│ ├── Slice.swift
│ ├── Void.swift
│ ├── Count.swift
│ ├── Options.swift
│ └── Info.swift
├── Models
│ ├── Focus.swift
│ ├── Proposal.swift
│ ├── Resolve.swift
│ ├── Update.swift
│ ├── Changes.swift
│ ├── Synchronize.swift
│ ├── Index.swift
│ ├── Attribute.swift
│ ├── Direction.swift
│ ├── Symbol.swift
│ └── Commit.swift
└── Styles
│ ├── Constant.swift
│ ├── Equals.swift
│ ├── Normal.swift
│ ├── Suffix.swift
│ └── Prefix.swift
├── DiffableTextKitXNumberTests
├── Constants.swift
├── Models
│ └── Links.swift
├── Comments+Percent.swift
├── Tokens
│ ├── Sign.swift
│ ├── Separator.swift
│ └── Digit.swift
├── Graphs
│ ├── Graph.swift
│ ├── Graph+Floats.swift
│ └── Graph+Integers.swift
├── Comments+Inaccurate.swift
├── Styles
│ ├── Style.swift
│ └── Style+Percent.swift
├── Comments+Currency.swift
└── Comments.swift
├── DiffableTextKitXUIKitTests
├── Field.swift
└── Font.swift
└── DiffableTextKitXPatternTests
├── Style.swift
├── Style+Hidden.swift
└── Style+Visible.swift
/Assets/AppXNumber.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oscbyspro/DiffableTextViews/HEAD/Assets/AppXNumber.png
--------------------------------------------------------------------------------
/Assets/AppXPattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oscbyspro/DiffableTextViews/HEAD/Assets/AppXPattern.png
--------------------------------------------------------------------------------
/Assets/ViewXNumber.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oscbyspro/DiffableTextViews/HEAD/Assets/ViewXNumber.gif
--------------------------------------------------------------------------------
/Assets/ViewXPattern.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oscbyspro/DiffableTextViews/HEAD/Assets/ViewXPattern.gif
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | /*.xcodeproj
5 | xcuserdata/
6 | DerivedData/
7 | .swiftpm/xcode/
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/Assets/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/Assets/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/Modules/IntervalSliderViews/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | /*.xcodeproj
5 | xcuserdata/
6 | DerivedData/
7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/DiffableTextAppXUIKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/DiffableTextAppXUIKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/Entitlements.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.network.client
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/Assets/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "display-p3",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0.708",
9 | "green" : "0.389",
10 | "red" : "0.206"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXNumber/Exports.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Exports
12 | //*============================================================================*
13 |
14 | @_exported import protocol DiffableTextKit.DiffableTextStyle
15 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXPattern/Exports.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Exports
12 | //*============================================================================*
13 |
14 | @_exported import protocol DiffableTextKit.DiffableTextStyle
15 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXUIKit/Exports.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Exports
12 | //*============================================================================*
13 |
14 | @_exported import protocol DiffableTextKit.DiffableTextStyle
15 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Aliases.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import DiffableTextKit
11 |
12 | //*============================================================================*
13 | // MARK: * Aliases
14 | //*============================================================================*
15 |
16 | typealias C = Offset
17 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Utilities/Void.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Void [...]
12 | //*============================================================================*
13 |
14 | public struct _Void: Hashable { @inlinable @inline(__always) public init() { } }
15 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Constants.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import Foundation
11 |
12 | //*============================================================================*
13 | // MARK: * Constants
14 | //*============================================================================*
15 |
16 | let en_US = Locale(identifier: "en_US")
17 | let sv_SE = Locale(identifier: "sv_SE")
18 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Utilities/Locale.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import struct Foundation.Locale
11 |
12 | //*============================================================================*
13 | // MARK: * Locale [...]
14 | //*============================================================================*
15 |
16 | public extension Locale { static let en_US_POSIX = Locale(identifier: "en_US_POSIX") }
17 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/App.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import SwiftUI
11 |
12 | //*============================================================================*
13 | // MARK: * App
14 | //*============================================================================*
15 |
16 | @main struct App: SwiftUI.App {
17 |
18 | //=------------------------------------------------------------------------=
19 | // MARK: Body
20 | //=------------------------------------------------------------------------=
21 |
22 | var body: some Scene {
23 | WindowGroup {
24 | Tabs().preferredColorScheme(.dark)
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Models/Focus.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Focus [...]
12 | //*============================================================================*
13 |
14 | @frozen public struct Focus: Equatable, ExpressibleByBooleanLiteral {
15 |
16 | //=------------------------------------------------------------------------=
17 |
18 | public let value: Bool
19 |
20 | //=------------------------------------------------------------------------=
21 |
22 | @inlinable public init(_ value: Bool) { self.value = value }
23 |
24 | @inlinable public init(booleanLiteral value: Bool) { self.value = value }
25 | }
26 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Utilities/Slice.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Slice x Tests
18 | //*============================================================================*
19 |
20 | final class SliceTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests x Suffix
24 | //=------------------------------------------------------------------------=
25 |
26 | func testSuffixWhile() {
27 | XCTAssert("0123456789".suffix(while: { "4" < $0 }).elementsEqual("56789"))
28 | }
29 | }
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Constants.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import DiffableTextKitXNumber
11 |
12 | import Foundation
13 |
14 | //*============================================================================*
15 | // MARK: * Constants
16 | //*============================================================================*
17 |
18 | let USD: String = "USD"
19 |
20 | let en_US: Locale = Locale(identifier: "en_US")
21 |
22 | let currencyCodes: [String] = Locale
23 | .isoCurrencyCodes
24 |
25 | let locales: [Locale] = Locale
26 | .availableIdentifiers.lazy.map(Locale.init)
27 | .sorted(by: { $0.identifier < $1.identifier })
28 |
29 | let numbers: [NumberTextStyle.Cache] = locales.lazy
30 | .map(NumberTextStyle.init).map({ $0.cache() })
31 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/Helpers/Random.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Random
12 | //*============================================================================*
13 |
14 | extension Character {
15 |
16 | //=------------------------------------------------------------------------=
17 | // MARK: Utilitis
18 | //=------------------------------------------------------------------------=
19 |
20 | static func random(in bounds: ClosedRange) -> Character? {
21 | let bounds = ClosedRange(uncheckedBounds:
22 | (bounds.lowerBound.value, bounds.upperBound.value))
23 | return UnicodeScalar(UInt32.random(in: bounds)).map(Character.init)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/Helpers/Range.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Range
12 | //*============================================================================*
13 |
14 | extension ClosedRange where Bound: Comparable {
15 |
16 | //=------------------------------------------------------------------------=
17 | // MARK: Initializers
18 | //=------------------------------------------------------------------------=
19 |
20 | init(_ unordered: (Bound, Bound)) {
21 | switch unordered.0 <= unordered.1 {
22 | case true: self.init(uncheckedBounds: (unordered.0, unordered.1))
23 | case false: self.init(uncheckedBounds: (unordered.1, unordered.0))
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Models/Synchronize.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Synchronize [...]
12 | //*============================================================================*
13 |
14 | /// A message describing synchronization behavior.
15 | @frozen public struct Synchronize: OptionSet {
16 |
17 | /// Requires that input and output values are equal.
18 | public static let acyclical = Self(rawValue: 1 << 0)
19 |
20 | //=------------------------------------------------------------------------=
21 |
22 | public let rawValue: UInt8
23 |
24 | //=------------------------------------------------------------------------=
25 |
26 | @inlinable public init(rawValue: UInt8) { self.rawValue = rawValue }
27 | }
28 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Models/Links.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKitXNumber
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Links x Tests
18 | //*============================================================================*
19 |
20 | final class LinksTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests
24 | //=------------------------------------------------------------------------=
25 |
26 | func testIsBidirectional() {
27 | let links = Links.ascii()
28 | for token in Digit.allCases {
29 | XCTAssertEqual(token, links[links[token]])
30 | }
31 | }
32 | }
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXUIKit/Streams/Sidestream.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if canImport(UIKit)
11 |
12 | import DiffableTextKit
13 | import SwiftUI
14 |
15 | //*============================================================================*
16 | // MARK: * Sidestream [...]
17 | //*============================================================================*
18 |
19 | @usableFromInline struct Sidestream {
20 |
21 | //=------------------------------------------------------------------------=
22 |
23 | @usableFromInline var onSubmit: Trigger?
24 |
25 | //=------------------------------------------------------------------------=
26 |
27 | @inlinable init() { }
28 |
29 | @inlinable init(_ environment: EnvironmentValues) {
30 | self.onSubmit = environment.diffableTextViews_onSubmit
31 | }
32 | }
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Models/Changes.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Changes [...]
12 | //*============================================================================*
13 |
14 | /// A model used to capture comparison results.
15 | @frozen @usableFromInline struct Changes: OptionSet {
16 |
17 | public static let style = Self(rawValue: 1 << 0)
18 | public static let value = Self(rawValue: 1 << 1)
19 | public static let focus = Self(rawValue: 1 << 2)
20 |
21 | //=------------------------------------------------------------------------=
22 |
23 | public var rawValue: UInt8
24 |
25 | //=------------------------------------------------------------------------=
26 |
27 | @inlinable init(rawValue: UInt8) { self.rawValue = rawValue }
28 | }
29 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/Models/Constants.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import Foundation
11 |
12 | //*============================================================================*
13 | // MARK: * Constants
14 | //*============================================================================*
15 |
16 | enum Constants {
17 |
18 | //=------------------------------------------------------------------------=
19 | // MARK: State
20 | //=------------------------------------------------------------------------=
21 |
22 | static let currencies: [String] = Locale.Currency
23 | .isoCurrencies
24 | .map(\.identifier)
25 |
26 | static let locales: [Locale] = Locale
27 | .availableIdentifiers
28 | .lazy.map(Locale.init)
29 | .reduce(into: Set()) { $0.insert($1) }
30 | .sorted(by: { $0.identifier < $1.identifier })
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Models/Resolve.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*========================================================================*
11 | // MARK: * Resolve [...]
12 | //*========================================================================*
13 |
14 | /// A message describing selection behavior.
15 | @frozen public struct Resolve: OptionSet {
16 |
17 | /// Resolve max selection.
18 | public static let max = Self(rawValue: 1 << 0)
19 |
20 | /// Resolve selection by using caret momentums.
21 | public static let momentums = Self(rawValue: 1 << 1)
22 |
23 | //=--------------------------------------------------------------------=
24 |
25 | public var rawValue: UInt8
26 |
27 | //=--------------------------------------------------------------------=
28 |
29 | @inlinable public init(rawValue: UInt8) { self.rawValue = rawValue }
30 | }
31 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXNumber/Models/Parser.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Parser [...]
12 | //*============================================================================*
13 |
14 | @usableFromInline struct Parser {
15 |
16 | //=------------------------------------------------------------------------=
17 |
18 | @usableFromInline let base: Format.Strategy
19 |
20 | //=------------------------------------------------------------------------=
21 |
22 | @inlinable init(initial: Format) {
23 | self.base = initial.locale(.en_US_POSIX).parseStrategy
24 | }
25 |
26 | @inlinable func parse(_ number: Number) throws -> Format.FormatInput {
27 | try base.parse(String.init(bytes: number.ascii, encoding: .ascii)!)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Utilities/Count.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Count
12 | //*============================================================================*
13 |
14 | public extension Sequence {
15 |
16 | //=------------------------------------------------------------------------=
17 | // MARK: Predicate
18 | //=------------------------------------------------------------------------=
19 |
20 | @inlinable func count(where predicate: (Element) throws -> Bool) rethrows -> Int {
21 | var S0 = 0; for S1 in self { if try predicate(S1) { S0 += 1 } }; return S0
22 | }
23 |
24 | @inlinable func count(while predicate: (Element) throws -> Bool) rethrows -> Int {
25 | var S0 = 0; for S1 in self { if try predicate(S1) { S0 += 1 } else { break } }; return S0
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Utilities/Void.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Void x Tests
18 | //*============================================================================*
19 |
20 | final class _VoidTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests
24 | //=------------------------------------------------------------------------=
25 |
26 | func testIsSimilarToVoid() {
27 | XCTAssertEqual(MemoryLayout<_Void>.size, MemoryLayout.size)
28 | XCTAssertEqual(MemoryLayout<_Void>.stride, MemoryLayout.stride)
29 | XCTAssertEqual(MemoryLayout<_Void>.alignment, MemoryLayout.alignment)
30 | }
31 | }
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Models/Focus.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Focus x Tests
18 | //*============================================================================*
19 |
20 | final class FocusTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests x Initializers
24 | //=------------------------------------------------------------------------=
25 |
26 | func testInit() {
27 | XCTAssertEqual(Focus( true).value, true)
28 | XCTAssertEqual(Focus(false).value, false)
29 | }
30 |
31 | func testInitAsBooleanLiteral() {
32 | XCTAssertEqual(Focus( true), true)
33 | XCTAssertEqual(Focus(false), false)
34 | }
35 | }
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/Views/Scroller.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import SwiftUI
11 |
12 | //*============================================================================*
13 | // MARK: * Scroller
14 | //*============================================================================*
15 |
16 | struct Scroller: View {
17 |
18 | //=------------------------------------------------------------------------=
19 | // MARK: State
20 | //=------------------------------------------------------------------------=
21 |
22 | @ViewBuilder let content: () -> Content
23 |
24 | //=------------------------------------------------------------------------=
25 | // MARK: Body
26 | //=------------------------------------------------------------------------=
27 |
28 | var body: some View {
29 | ScrollView(showsIndicators: false) {
30 | content().padding()
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Models/Proposal.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Proposal x Tests
18 | //*============================================================================*
19 |
20 | final class ProposalTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests
24 | //=------------------------------------------------------------------------=
25 |
26 | func testMerged() {
27 | let proposal = Proposal("AxE", with: "BCD", in: C(1) ..< 2)
28 | XCTAssertEqual(proposal.merged(), "ABCDE")
29 | }
30 |
31 | func testLazyMerged() {
32 | let proposal = Proposal("AxE", with: "BCD", in: C(1) ..< 2)
33 | XCTAssertEqual(Snapshot(proposal.lazy.merged()), "ABCDE")
34 | }
35 | }
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/Modules/IntervalSliderViews/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.5
2 | //=----------------------------------------------------------------------------=
3 | // This source file is part of the DiffableTextViews open source project.
4 | //
5 | // Copyright (c) 2022 Oscar Byström Ericsson
6 | // Licensed under Apache License, Version 2.0
7 | //
8 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
9 | //=----------------------------------------------------------------------------=
10 |
11 | import PackageDescription
12 |
13 | //*============================================================================*
14 | // MARK: IntervalSliderViews
15 | //*============================================================================*
16 |
17 | let package = Package(
18 | name: "IntervalSliderViews",
19 | platforms: [
20 | .iOS(.v15),
21 | ],
22 | products: [
23 | //=--------------------------------------=
24 | // IntervalSliderViews
25 | //=--------------------------------------=
26 | .library(
27 | name: "IntervalSliderViews",
28 | targets: ["IntervalSliderViews"])
29 | ],
30 | targets: [
31 | //=--------------------------------------=
32 | // IntervalSliderViews
33 | //=--------------------------------------=
34 | .target(name: "IntervalSliderViews"),
35 | ]
36 | )
37 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Comments+Percent.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKitXNumber
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Comments x Percent
18 | //*============================================================================*
19 |
20 | final class CommentsOnPercent: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests
24 | //=------------------------------------------------------------------------=
25 |
26 | func testPercentLabelsAreAlwaysVirtual() {
27 | for cache in numbers {
28 | let components = cache.interpreter.components
29 | let percent = IntegerFormatStyle.Percent(locale:cache.style.locale)
30 | XCTAssertEqual(1, percent.format(0).filter(components.nonvirtual).count)
31 | }
32 | }
33 | }
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Models/Resolve.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Resolve x Tests
18 | //*============================================================================*
19 |
20 | final class ResolveTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: State
24 | //=------------------------------------------------------------------------=
25 |
26 | let all: [Resolve] = [.max, .momentums]
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Tests x Instances
30 | //=------------------------------------------------------------------------=
31 |
32 | func testInstancesAreUnique() {
33 | XCTAssertEqual(Set(all.map(\.rawValue)).count, all.count)
34 | }
35 | }
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Models/Update.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Update x Tests
18 | //*============================================================================*
19 |
20 | final class UpdateTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: State
24 | //=------------------------------------------------------------------------=
25 |
26 | let all: [Update] = [.value, .text, .selection]
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Tests x Instances
30 | //=------------------------------------------------------------------------=
31 |
32 | func testInstancesAreUnique() {
33 | XCTAssertEqual(Set(all.map(\.rawValue)).count, all.count)
34 | }
35 | }
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/Modules/IntervalSliderViews/Sources/IntervalSliderViews/Models/Values.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import SwiftUI
11 |
12 | //*============================================================================*
13 | // MARK: Declaration
14 | //*============================================================================*
15 |
16 | struct Values {
17 |
18 | //=------------------------------------------------------------------------=
19 | // MARK: State
20 | //=------------------------------------------------------------------------=
21 |
22 | let limits: ClosedRange
23 | @Binding var remote: (CGFloat, CGFloat)
24 |
25 | //=------------------------------------------------------------------------=
26 | // MARK: Initializers
27 | //=------------------------------------------------------------------------=
28 |
29 | init(_ remote: Binding<(CGFloat, CGFloat)>, in limits: ClosedRange) {
30 | self.limits = limits; self._remote = remote
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Models/Changes.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Changes x Tests
18 | //*============================================================================*
19 |
20 | final class ChangesTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: State
24 | //=------------------------------------------------------------------------=
25 |
26 | let all: [Changes] = [.style, .value, .focus]
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Tests x Instances
30 | //=------------------------------------------------------------------------=
31 |
32 | func testInstancesAreUnique() {
33 | XCTAssertEqual(Set(all.map(\.rawValue)).count, all.count)
34 | }
35 | }
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Models/Synchronize.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Synchronize x Tests
18 | //*============================================================================*
19 |
20 | final class SynchronizeTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: State
24 | //=------------------------------------------------------------------------=
25 |
26 | let all: [Synchronize] = [.acyclical]
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Tests x Instances
30 | //=------------------------------------------------------------------------=
31 |
32 | func testInstancesAreUnique() {
33 | XCTAssertEqual(Set(all.map(\.rawValue)).count, all.count)
34 | }
35 | }
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Models/Update.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Update [...]
12 | //*============================================================================*
13 |
14 | /// A message describing which properties should be updated.
15 | ///
16 | /// It is recommended to update the value first, then the text before selection.
17 | ///
18 | /// - Implement reentrant updates by only updating the value until it stabilizes.
19 | ///
20 | @frozen public struct Update: OptionSet {
21 |
22 | public static let value = Self(rawValue: 1 << 0)
23 | public static let text = Self(rawValue: 1 << 1)
24 | public static let selection = Self(rawValue: 1 << 2)
25 |
26 | //=------------------------------------------------------------------------=
27 |
28 | public let rawValue: UInt8
29 |
30 | //=------------------------------------------------------------------------=
31 |
32 | @inlinable public init(rawValue: UInt8) { self.rawValue = rawValue }
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Styles/Constant.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Constant x Tests
18 | //*============================================================================*
19 |
20 | final class ConstantTextStyleTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests
24 | //=------------------------------------------------------------------------=
25 |
26 | func test() {
27 | //=--------------------------------------=
28 | // Setup
29 | //=--------------------------------------=
30 | let mock0 = Mock(locale: en_US).constant()
31 | let mock1 = mock0.locale(sv_SE)
32 | //=--------------------------------------=
33 | // Assert
34 | //=--------------------------------------=
35 | XCTAssertEqual(mock0, mock1)
36 | }
37 | }
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Utilities/Slice.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Slice
12 | //*============================================================================*
13 |
14 | extension BidirectionalCollection {
15 |
16 | //=------------------------------------------------------------------------=
17 | // MARK: Suffix
18 | //=------------------------------------------------------------------------=
19 |
20 | @inlinable public func suffix(while predicate: (Element) throws -> Bool) rethrows -> SubSequence {
21 | try self[startOfSuffix(while: predicate)...]
22 | }
23 |
24 | @inlinable func startOfSuffix(while predicate: (Element) throws -> Bool) rethrows -> Index {
25 | var position = endIndex
26 |
27 | backwards: while position != startIndex {
28 | let after = position; formIndex(before: &position)
29 | if try !predicate(self[position]) { return after }
30 | }
31 |
32 | return position
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Tokens/Sign.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKitXNumber
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Sign x Tests
18 | //*============================================================================*
19 |
20 | final class SignTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Assertions
24 | //=------------------------------------------------------------------------=
25 |
26 | func XCTAssertASCII(_ sign: Sign, _ character: Character) {
27 | XCTAssertEqual(sign.character, character)
28 | }
29 |
30 | //=------------------------------------------------------------------------=
31 | // MARK: Tests
32 | //=------------------------------------------------------------------------=
33 |
34 | func testASCII() {
35 | XCTAssertASCII(.positive, "+")
36 | XCTAssertASCII(.negative, "-")
37 | }
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Tokens/Separator.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKitXNumber
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Separator x Tests
18 | //*============================================================================*
19 |
20 | final class SeparatorTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Assertions
24 | //=------------------------------------------------------------------------=
25 |
26 | func XCTAssertASCII(_ separator: Separator, _ character: Character) {
27 | XCTAssertEqual(separator.character, character)
28 | }
29 |
30 | //=------------------------------------------------------------------------=
31 | // MARK: Tests
32 | //=------------------------------------------------------------------------=
33 |
34 | func testASCII() {
35 | XCTAssertASCII(.fraction, ".")
36 | XCTAssertASCII(.grouping, ",")
37 | }
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Models/Index.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Index x Tests
18 | //*============================================================================*
19 |
20 | final class IndexTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: State
24 | //=------------------------------------------------------------------------=
25 |
26 | let characters = "ABC"
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Tests x Utilities
30 | //=------------------------------------------------------------------------=
31 |
32 | func testComparableUsesOnlyAttribute() {
33 | XCTAssertEqual(
34 | Index(characters .endIndex, as: 0),
35 | Index(characters.startIndex, as: 0))
36 |
37 | XCTAssertLessThan(
38 | Index(characters .endIndex, as: 0),
39 | Index(characters.startIndex, as: 1))
40 | }
41 | }
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Styles/Equals.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Equals x Tests
18 | //*============================================================================*
19 |
20 | final class EqualsTextStyleTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests
24 | //=------------------------------------------------------------------------=
25 |
26 | func test() {
27 | //=--------------------------------------=
28 | // Setup
29 | //=--------------------------------------=
30 | let mock0 = Mock(locale: en_US).equals(0)
31 | let mock1 = Mock(locale: sv_SE).equals(0)
32 | let mock2 = Mock(locale: en_US).equals(1)
33 | //=--------------------------------------=
34 | // Assert
35 | //=--------------------------------------=
36 | XCTAssertEqual( mock0, mock1)
37 | XCTAssertNotEqual(mock0, mock2)
38 | XCTAssertNotEqual(mock1, mock2)
39 | }
40 | }
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXUIKit/Models/Intent.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if canImport(UIKit)
11 |
12 | import UIKit
13 |
14 | //*============================================================================*
15 | // MARK: * Intent [...]
16 | //*============================================================================*
17 |
18 | @usableFromInline struct Intent {
19 |
20 | @usableFromInline typealias Key = UIKeyboardHIDUsage
21 |
22 | //=------------------------------------------------------------------------=
23 |
24 | @usableFromInline private(set) var latest: Key?
25 |
26 | //=------------------------------------------------------------------------=
27 |
28 | @inlinable mutating func insert(_ presses: Set) {
29 | parse(presses).map({ latest = $0 })
30 | }
31 |
32 | @inlinable mutating func remove(_ presses: Set) {
33 | parse(presses).map({ latest == $0 ? latest = nil : () })
34 | }
35 |
36 | @inlinable func parse(_ presses: Set) -> Key? {
37 | if let key = presses.first?.key?.keyCode,
38 | key == .keyboardLeftArrow ||
39 | key == .keyboardRightArrow { return key }; return nil
40 | }
41 | }
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXNumber/Aliases.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import Foundation
11 |
12 | //*============================================================================*
13 | // MARK: * Aliases
14 | //*============================================================================*
15 |
16 | public typealias NumberTextStyle =
17 | Value.NumberTextGraph.Number where
18 | Value.NumberTextGraph: _Numberable
19 |
20 | public typealias NumberTextBounds = _Bounds
21 | public typealias NumberTextPrecision = _Precision
22 |
23 | //*============================================================================*
24 | // MARK: * Aliases x Internal
25 | //*============================================================================*
26 |
27 | public typealias _FPRR = FloatingPointRoundingRule
28 |
29 | public typealias _NFSC = NumberFormatStyleConfiguration
30 | public typealias _CFSC = CurrencyFormatStyleConfiguration
31 |
32 | public typealias _NFSC_SignDS = _NFSC.SignDisplayStrategy
33 | public typealias _CFSC_SignDS = _CFSC.SignDisplayStrategy
34 |
35 | public typealias _NFSC_SeparatorDS = _NFSC.DecimalSeparatorDisplayStrategy
36 | public typealias _CFSC_SeparatorDS = _CFSC.DecimalSeparatorDisplayStrategy
37 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXUIKit/Models/Alignment.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if canImport(UIKit)
11 |
12 | import SwiftUI
13 | import UIKit
14 |
15 | //*============================================================================*
16 | // MARK: * Alignment x UIKit
17 | //*============================================================================*
18 |
19 | extension NSTextAlignment {
20 |
21 | //=------------------------------------------------------------------------=
22 | // MARK: Initializers
23 | //=------------------------------------------------------------------------=
24 |
25 | @inlinable init(_ alignment: TextAlignment, relativeTo layout: LayoutDirection) {
26 | switch alignment {
27 | case .leading: self.init(layout, leftToRight: .left, rightToLeft: .right)
28 | case .trailing: self.init(layout, leftToRight: .right, rightToLeft: .left)
29 | case .center: self = .center }
30 | }
31 |
32 | @inlinable init(_ layout: LayoutDirection, leftToRight: Self, rightToLeft: Self) {
33 | switch layout {
34 | case .rightToLeft: self = rightToLeft
35 | case .leftToRight: self = leftToRight
36 | @unknown default: self = leftToRight }
37 | }
38 | }
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Utilities/Count.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Count x Tests
18 | //*============================================================================*
19 |
20 | final class CountTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests x Where
24 | //=------------------------------------------------------------------------=
25 |
26 | func testCountWhere() {
27 | let numbers = "22122"
28 | XCTAssertEqual(numbers.count(where: { $0 == "1" }), 1)
29 | XCTAssertEqual(numbers.count(where: { $0 == "2" }), 4)
30 | }
31 |
32 | //=------------------------------------------------------------------------=
33 | // MARK: Tests x While
34 | //=------------------------------------------------------------------------=
35 |
36 | func testCountWhile() {
37 | let numbers = "22122"
38 | XCTAssertEqual(numbers.count(while: { $0 == "1" }), 0)
39 | XCTAssertEqual(numbers.count(while: { $0 == "2" }), 2)
40 | }
41 | }
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Graphs/Graph.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKitXNumber
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Graph x Tests
18 | //*============================================================================*
19 |
20 | final class GraphTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Tests
24 | //=------------------------------------------------------------------------=
25 |
26 | func testBounds_Decimal_Double_Int64() {
27 | XCTAssertEqual(Decimal._NumberTextGraph.max, Decimal(string: String(repeating: "9", count: 38))!)
28 | XCTAssertEqual(Double ._NumberTextGraph.max, Double .init(String(repeating: "9", count: 15))!)
29 | XCTAssertEqual(Int64 ._NumberTextGraph.max, Int64 .init(String(repeating: "9", count: 18))!)
30 | }
31 |
32 | func testPrecision_Decimal_Double_Int64() {
33 | XCTAssertEqual(Decimal._NumberTextGraph.precision, 38)
34 | XCTAssertEqual(Double ._NumberTextGraph.precision, 15)
35 | XCTAssertEqual(Int64 ._NumberTextGraph.precision, 18)
36 | }
37 | }
38 |
39 | #endif
40 |
41 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Utilities/Options.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Options
12 | //*============================================================================*
13 |
14 | public extension OptionSet {
15 |
16 | //=------------------------------------------------------------------------=
17 | // MARK: Transformations
18 | //=------------------------------------------------------------------------=
19 |
20 | @inlinable @inline(__always) func callAsFunction(_ mask: Bool) -> Self {
21 | mask ? self : Self()
22 | }
23 |
24 | @inlinable @inline(__always) static prefix func !(options: Self) -> Bool {
25 | options.isEmpty
26 | }
27 |
28 | @inlinable @inline(__always) static func + (lhs: Self, rhs: Self) -> Self {
29 | lhs.union(rhs)
30 | }
31 |
32 | @inlinable @inline(__always) static func += (lhs: inout Self, rhs: Self) {
33 | lhs.formUnion(rhs)
34 | }
35 |
36 | @inlinable @inline(__always) static func - (lhs: Self, rhs: Self) -> Self {
37 | lhs.subtracting(rhs)
38 | }
39 |
40 | @inlinable @inline(__always) static func -= (lhs: inout Self, rhs: Self) {
41 | lhs.subtract(rhs)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXNumber/Models/Count.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Count [...]
12 | //*============================================================================*
13 |
14 | /// A count of a number's components.
15 | ///
16 | /// - It SHOULD NOT include leading integer zeros.
17 | ///
18 | @usableFromInline struct Count: CustomStringConvertible, Equatable {
19 |
20 | //=------------------------------------------------------------------------=
21 |
22 | @usableFromInline let digits: Int
23 | @usableFromInline let integer: Int
24 | @usableFromInline let fraction: Int
25 |
26 | //=------------------------------------------------------------------------=
27 |
28 | @inlinable init(digits: Int, integer: Int, fraction: Int) {
29 | self.digits = digits; self.integer = integer; self.fraction = fraction
30 | }
31 |
32 | @inlinable init( _ number: Number) {
33 | self.integer = number.integer .count - number.integer.count(prefix:{$0 == .zero})
34 | self.fraction = number.fraction.count; self.digits = self.integer + self.fraction
35 | }
36 |
37 | public var description: String {
38 | "\((digits, integer, fraction))"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXUIKitTests/Field.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG && canImport(UIKit)
11 |
12 | @testable import DiffableTextKitXUIKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Field x Tests
18 | //*============================================================================*
19 |
20 | final class FieldTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: State
24 | //=------------------------------------------------------------------------=
25 |
26 | lazy var field = Field()
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Tests
30 | //=------------------------------------------------------------------------=
31 |
32 | func testForceUnwrappingTextIsOK() {
33 | field.text = nil
34 | XCTAssertNotNil(field.text)
35 | }
36 |
37 | func testForceUnwrappingSelectedTextRangeIsOK() {
38 | field.selectedTextRange = nil
39 | XCTAssertNotNil(field.selectedTextRange)
40 | }
41 |
42 | func testForceUnwrappingMarkedTextRangeIsBad() {
43 | XCTAssertNil(field.markedTextRange)
44 | }
45 | }
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Models/Attribute.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Attribute x Tests
18 | //*============================================================================*
19 |
20 | final class AttributeTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: State
24 | //=------------------------------------------------------------------------=
25 |
26 | let all: [Attribute] = [.virtual, .insertable, .removable, .passthrough]
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Tests x Instances
30 | //=------------------------------------------------------------------------=
31 |
32 | func testContentIsEmpty() {
33 | XCTAssert(Attribute.content.isEmpty)
34 | XCTAssertEqual(Attribute.content,[])
35 | }
36 |
37 | func testPhantomIsFull() {
38 | XCTAssertEqual(Attribute.phantom, Attribute(all))
39 | }
40 |
41 | func testInstancesAreUnique() {
42 | XCTAssertEqual(Set(all.map(\.rawValue)).count, all.count)
43 | }
44 | }
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Comments+Inaccurate.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | import XCTest
13 |
14 | //*============================================================================*
15 | // MARK: * Comments x Tests x Inaccurate
16 | //*============================================================================*
17 |
18 | final class CommentsOnInaccurate: XCTestCase {
19 |
20 | //=------------------------------------------------------------------------=
21 | // MARK: Assertions
22 | //=------------------------------------------------------------------------=
23 |
24 | func XCTAssert(_ value: T, result: String) {
25 | let style = FloatingPointFormatStyle(locale: en_US)
26 | XCTAssertEqual(style.precision(.fractionLength(0...)).format(value), result)
27 | }
28 |
29 | //=------------------------------------------------------------------------=
30 | // MARK: Tests
31 | //=------------------------------------------------------------------------=
32 |
33 | func testFloat16IsInaccurate() {
34 | XCTAssert(-1.23 as Float16, result: "-1.23046875")
35 | }
36 |
37 | func testFloat32IsInaccurate() {
38 | XCTAssert(-1.23 as Float32, result: "-1.2300000190734863")
39 | }
40 | }
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Utilities/Brrr.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Brrr [...]
12 | //*============================================================================*
13 |
14 | /// A model that prints messages in DEBUG mode.
15 | ///
16 | /// It uses conditional compilation such that it has no size or cost in RELEASE mode.
17 | ///
18 | public struct Brrr: Equatable {
19 |
20 | public static let cancellation = Self("cancellation")
21 | public static let autocorrection = Self("autocorrection")
22 | public static let unsynchronizable = Self("unsynchronizable")
23 |
24 | //=------------------------------------------------------------------------=
25 |
26 | #if DEBUG
27 | @usableFromInline let context: String
28 | #endif
29 |
30 | //=------------------------------------------------------------------------=
31 |
32 | @inlinable @inline(__always) public init(_ context: @autoclosure () -> String) {
33 | #if DEBUG
34 | self.context = context()
35 | #endif
36 | }
37 |
38 | @inlinable @inline(__always) public static func << (brrr: Self, message: @autoclosure () -> Any) {
39 | #if DEBUG
40 | Swift.print("[DiffableTextViews] \(brrr.context): \(message())")
41 | #endif
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Styles/Style.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | import DiffableTextKitXNumber
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Style
18 | //*============================================================================*
19 |
20 | class StyleTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Overrides
24 | //=------------------------------------------------------------------------=
25 |
26 | override func setUp() {
27 | super.setUp(); self.continueAfterFailure = false
28 | }
29 |
30 | //=------------------------------------------------------------------------=
31 | // MARK: Assertions
32 | //=------------------------------------------------------------------------=
33 |
34 | func XCTAssert(_ value: S.Value, with style: S) {
35 | let style = style.precision(fraction: 0...)
36 | var cache = style.cache()
37 |
38 | let commit = style.interpret(value, with: &cache)
39 | XCTAssertEqual(commit.value, value, "\(style) x \(value)")
40 |
41 | let characters = style.format(value, with: &cache)
42 | XCTAssertEqual(commit.snapshot.characters, characters, "\(style) x \(value)")
43 | }
44 | }
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitXNumberTests/Tokens/Digit.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKitXNumber
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Digit x Tests
18 | //*============================================================================*
19 |
20 | final class DigitTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: Assertions
24 | //=------------------------------------------------------------------------=
25 |
26 | func XCTAssertASCII(_ digit: Digit, _ value: UInt8) {
27 | XCTAssertEqual(digit.character, Character(String(value)))
28 | }
29 |
30 | //=------------------------------------------------------------------------=
31 | // MARK: Tests
32 | //=------------------------------------------------------------------------=
33 |
34 | func testASCII() {
35 | XCTAssertASCII(.zero, 0)
36 | XCTAssertASCII(.one, 1)
37 | XCTAssertASCII(.two, 2)
38 | XCTAssertASCII(.three, 3)
39 | XCTAssertASCII(.four, 4)
40 | XCTAssertASCII(.five, 5)
41 | XCTAssertASCII(.six, 6)
42 | XCTAssertASCII(.seven, 7)
43 | XCTAssertASCII(.eight, 8)
44 | XCTAssertASCII(.nine, 9)
45 | }
46 | }
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/Apps/DiffableTextAppXUIKit/App/Views/Action.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import SwiftUI
11 |
12 | //*============================================================================*
13 | // MARK: * Action
14 | //*============================================================================*
15 |
16 | struct Action: View {
17 |
18 | //=------------------------------------------------------------------------=
19 | // MARK: State
20 | //=------------------------------------------------------------------------=
21 |
22 | let title: String
23 | let action: () -> Void
24 |
25 | //=------------------------------------------------------------------------=
26 | // MARK: Initializers
27 | //=------------------------------------------------------------------------=
28 |
29 | init(_ title: String, action: @escaping () -> Void) {
30 | self.title = title
31 | self.action = action
32 | }
33 |
34 | //=------------------------------------------------------------------------=
35 | // MARK: Body
36 | //=------------------------------------------------------------------------=
37 |
38 | var body: some View {
39 | Button(action: action) {
40 | Text(title)
41 | .font(.subheadline)
42 | .frame(height: 16)
43 | .frame(maxWidth: .infinity)
44 | }
45 | .tint(Color.gray.opacity(2/3))
46 | .buttonStyle(.borderedProminent)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXNumber/Models/Attributes.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | import DiffableTextKit
11 |
12 | //*============================================================================*
13 | // MARK: * Attributes
14 | //*============================================================================*
15 |
16 | @usableFromInline struct Attributes {
17 |
18 | //=------------------------------------------------------------------------=
19 | // MARK: State
20 | //=------------------------------------------------------------------------=
21 |
22 | @usableFromInline private(set) var map = [Character: Attribute]()
23 |
24 | //=------------------------------------------------------------------------=
25 | // MARK: Initializers
26 | //=------------------------------------------------------------------------=
27 |
28 | @inlinable init(_ components: Components) {
29 | self.map[components.separators[.fraction/*------*/]] = .removable
30 | components.digits.tokens.keys.forEach { self.map[$0] = .content }
31 | components.signs .tokens.keys.forEach { self.map[$0] = .phantom - .virtual }
32 | }
33 |
34 | //=------------------------------------------------------------------------=
35 | // MARK: Accessors
36 | //=------------------------------------------------------------------------=
37 |
38 | @inlinable subscript(character: Character) -> Attribute {
39 | map[character] ?? .phantom
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Models/Direction.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Direction
12 | //*============================================================================*
13 |
14 | /// A forwards/backwards model.
15 | @frozen public enum Direction {
16 |
17 | //=------------------------------------------------------------------------=
18 | // MARK: Instances
19 | //=------------------------------------------------------------------------=
20 |
21 | case forwards
22 | case backwards
23 |
24 | //=------------------------------------------------------------------------=
25 | // MARK: Initializers
26 | //=------------------------------------------------------------------------=
27 |
28 | @inlinable public init?(from start: T, to end: T) where T: Comparable {
29 | if start < end { self = .forwards }
30 | else if start > end { self = .backwards }
31 | else { return nil }
32 | }
33 |
34 | //=------------------------------------------------------------------------=
35 | // MARK: Transformations
36 | //=------------------------------------------------------------------------=
37 |
38 | @inlinable mutating public func reverse() {
39 | self = reversed()
40 | }
41 |
42 | @inlinable public func reversed() -> Self {
43 | self == .forwards ? .backwards : .forwards
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Tests/DiffableTextKitTests/Styles/Normal.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if DEBUG
11 |
12 | @testable import DiffableTextKit
13 |
14 | import XCTest
15 |
16 | //*============================================================================*
17 | // MARK: * Normal x Tests
18 | //*============================================================================*
19 |
20 | final class NormalTextStyleTests: XCTestCase {
21 |
22 | //=------------------------------------------------------------------------=
23 | // MARK: State
24 | //=------------------------------------------------------------------------=
25 |
26 | let normal = NormalTextStyle()
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Tests
30 | //=------------------------------------------------------------------------=
31 |
32 | func testFormat() {
33 | XCTAssertEqual(normal.format("2"), "2")
34 | }
35 |
36 | func testInterpret() {
37 | XCTAssertEqual(normal.interpret("3"), Commit("3", "3"))
38 | }
39 |
40 | func testResolve() {
41 | let snapshot = Snapshot("13") + Snapshot("o(><)o", as: .phantom)
42 | let proposal = Proposal(snapshot, with: "2", in: C(1) ..< C(1))
43 |
44 | let resolved = try! normal.resolve(proposal)
45 |
46 | XCTAssertEqual(resolved.value, "123")
47 | XCTAssertEqual(resolved.snapshot, "123")
48 | }
49 | }
50 |
51 | #endif
52 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKit/Models/Index.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | //*============================================================================*
11 | // MARK: * Index [...]
12 | //*============================================================================*
13 |
14 | /// A character encoded index and offset.
15 | public struct Index: Comparable, CustomStringConvertible {
16 |
17 | //=------------------------------------------------------------------------=
18 |
19 | @usableFromInline let character: String.Index
20 | @usableFromInline let attribute: Int
21 |
22 | //=------------------------------------------------------------------------=
23 |
24 | /// Creates an instance describing a character's position.
25 | ///
26 | /// - Parameters:
27 | /// - character: The character encoded index.
28 | /// - attribute: The character encoded offset.
29 | ///
30 | @inlinable @inline(__always) init(_ character: String.Index, as attribute: Int) {
31 | self.character = character
32 | self.attribute = attribute
33 | }
34 |
35 | public var description: String {
36 | String(describing: attribute)
37 | }
38 |
39 | @inlinable @inline(__always) public static func == (lhs: Self, rhs: Self) -> Bool {
40 | lhs.attribute == rhs.attribute
41 | }
42 |
43 | @inlinable @inline(__always) public static func < (lhs: Self, rhs: Self) -> Bool {
44 | lhs.attribute < rhs.attribute
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Sources/DiffableTextKitXUIKit/Streams/Upstream.swift:
--------------------------------------------------------------------------------
1 | //=----------------------------------------------------------------------------=
2 | // This source file is part of the DiffableTextViews open source project.
3 | //
4 | // Copyright (c) 2022 Oscar Byström Ericsson
5 | // Licensed under Apache License, Version 2.0
6 | //
7 | // See http://www.apache.org/licenses/LICENSE-2.0 for license information.
8 | //=----------------------------------------------------------------------------=
9 |
10 | #if canImport(UIKit)
11 |
12 | import DiffableTextKit
13 | import SwiftUI
14 |
15 | //*============================================================================*
16 | // MARK: * Upstream
17 | //*============================================================================*
18 |
19 | @usableFromInline struct Upstream {
20 |
21 | //=------------------------------------------------------------------------=
22 | // MARK: State
23 | //=------------------------------------------------------------------------=
24 |
25 | @usableFromInline let style: Style
26 | @usableFromInline let proxy: Binding
27 |
28 | //=------------------------------------------------------------------------=
29 | // MARK: Initializers
30 | //=------------------------------------------------------------------------=
31 |
32 | @inlinable init(_ view: DiffableTextField