Skip to content

Commit

Permalink
Accomodate Swift 4.1 changes. (#7)
Browse files Browse the repository at this point in the history
* Accomodate Swift 4.1 changes.

* Add a Travis CI task for Xcode 9.3 beta.
  • Loading branch information
andersio authored Mar 31, 2018
1 parent a05eb62 commit d1b23e4
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 45 deletions.
29 changes: 24 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
language: objective-c
osx_image: xcode9
before_install:
- brew uninstall carthage
- HOMEBREW_NO_AUTO_UPDATE=1 brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/6ae4f69a652fb0ecb102b0c9216378679a4f1b92/Formula/carthage.rb # 0.22.0
install: true
branches:
only:
Expand Down Expand Up @@ -32,12 +29,34 @@ jobs:
- XCODE_SCHEME=FlexibleDiff
XCODE_SDK=appletvsimulator
XCODE_ACTION="build-for-testing test-without-building"
XCODE_DESTINATION="platform=tvOS Simulator,name=Apple TV 1080p"
XCODE_DESTINATION="platform=tvOS Simulator,name=Apple TV"
script/build
- XCODE_SCHEME=FlexibleDiff
XCODE_SDK=watchsimulator
XCODE_ACTION=build
XCODE_DESTINATION="platform=watchOS Simulator,name=Apple Watch - 38mm,OS=2.2"
XCODE_DESTINATION="platform=watchOS Simulator,name=Apple Watch Series 3 - 38mm"
script/build
- osx_image: xcode9.3beta
script:
- XCODE_SCHEME=FlexibleDiff
XCODE_SDK=macosx
XCODE_ACTION="build test"
XCODE_DESTINATION="arch=x86_64"
script/build
- XCODE_SCHEME=FlexibleDiff
XCODE_SDK=iphonesimulator
XCODE_ACTION="build-for-testing test-without-building"
XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 6s"
script/build
- XCODE_SCHEME=FlexibleDiff
XCODE_SDK=appletvsimulator
XCODE_ACTION="build-for-testing test-without-building"
XCODE_DESTINATION="platform=tvOS Simulator,name=Apple TV"
script/build
- XCODE_SCHEME=FlexibleDiff
XCODE_SDK=watchsimulator
XCODE_ACTION=build
XCODE_DESTINATION="platform=watchOS Simulator,name=Apple Watch Series 3 - 38mm"
script/build
- script:
- pod repo update --silent
Expand Down
26 changes: 16 additions & 10 deletions FlexibleDiff/Changeset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ public struct Changeset {
public init<C: Collection, Identifier: Hashable>(
previous: C?,
current: C,
identifier: (C.Iterator.Element) -> Identifier,
areEqual: (C.Iterator.Element, C.Iterator.Element) -> Bool
identifier: (C.Element) -> Identifier,
areEqual: (C.Element, C.Element) -> Bool
) {
guard let previous = previous else {
self.init(initial: current)
Expand Down Expand Up @@ -257,8 +257,14 @@ public struct Changeset {
continue
}

let previousIndex = previous.index(previous.startIndex, offsetBy: C.IndexDistance(oldPosition))
let currentIndex = current.index(current.startIndex, offsetBy: C.IndexDistance(newPosition))
#if swift(>=4.1)
let previousIndex = previous.index(previous.startIndex, offsetBy: oldPosition)
let currentIndex = current.index(current.startIndex, offsetBy: newPosition)
#else
let previousIndex = previous.index(previous.startIndex, offsetBy: C.IndexDistance(oldPosition))
let currentIndex = current.index(current.startIndex, offsetBy: C.IndexDistance(newPosition))
#endif

let isMutated = !areEqual(previous[previousIndex], current[currentIndex])

if newPosition - oldPosition != 0 {
Expand Down Expand Up @@ -315,8 +321,8 @@ public struct Changeset {
public init<C: Collection, Identifier: Hashable>(
previous: C?,
current: C,
identifier: (C.Iterator.Element) -> Identifier
) where C.Iterator.Element: Equatable {
identifier: (C.Element) -> Identifier
) where C.Element: Equatable {
self.init(previous: previous, current: current, identifier: identifier, areEqual: ==)
}

Expand All @@ -334,7 +340,7 @@ public struct Changeset {
public init<C: Collection>(
previous: C?,
current: C
) where C.Iterator.Element: Hashable {
) where C.Element: Hashable {
self.init(previous: previous, current: current, identifier: { $0 }, areEqual: ==)
}

Expand All @@ -350,7 +356,7 @@ public struct Changeset {
public init<C: Collection>(
previous: C?,
current: C
) where C.Iterator.Element: AnyObject {
) where C.Element: AnyObject {
self.init(previous: previous, current: current, identifier: ObjectIdentifier.init, areEqual: ===)
}

Expand All @@ -371,7 +377,7 @@ public struct Changeset {
previous: C?,
current: C,
comparingBy strategy: ObjectDiffStrategy = .value
) where C.Iterator.Element: AnyObject & Equatable {
) where C.Element: AnyObject & Equatable {
switch strategy.kind {
case .value:
self.init(previous: previous, current: current, identifier: ObjectIdentifier.init, areEqual: ==)
Expand Down Expand Up @@ -399,7 +405,7 @@ public struct Changeset {
current: C,
identifyingBy identifyingStrategy: ObjectDiffStrategy = .identity,
comparingBy comparingStrategy: ObjectDiffStrategy = .value
) where C.Iterator.Element: AnyObject & Hashable {
) where C.Element: AnyObject & Hashable {
switch (identifyingStrategy.kind, comparingStrategy.kind) {
case (.value, .value):
self.init(previous: previous, current: current, identifier: { $0 }, areEqual: ==)
Expand Down
61 changes: 31 additions & 30 deletions FlexibleDiffTests/ChangesetSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ class ChangesetSpec: QuickSpec {
moves: [.init(source: 2, destination: 6, isMutated: true),
.init(source: 3, destination: 8, isMutated: false),
.init(source: 5, destination: 2, isMutated: false)]),
to: "abcdefgh".characters,
expecting: "YBfeZgChd".characters)
to: "abcdefgh",
expecting: "YBfeZgChd")
}

it("should reproduce all the operations") {
Expand All @@ -278,8 +278,8 @@ class ChangesetSpec: QuickSpec {
moves: [Changeset.Move(source: 1, destination: 0, isMutated: false),
Changeset.Move(source: 2, destination: 1, isMutated: false),
Changeset.Move(source: 0, destination: 4, isMutated: false)]),
to: "EABDFGHIJ".characters,
expecting: "ABCDEFGHIJ".characters)
to: "EABDFGHIJ",
expecting: "ABCDEFGHIJ")
}
}

Expand Down Expand Up @@ -353,17 +353,17 @@ class ChangesetSpec: QuickSpec {
}

it("should detect inserted repeated values") {
diffTest(previous: "AAA".characters,
current: "AAAAA".characters,
diffTest(previous: "AAA",
current: "AAAAA",
computed: { Changeset(previous: $0, current: $1) },
expected: Changeset(inserts: [3, 4]),
areEqual: ==)
}

it("should detect inserted, scattered repeated values") {
// NOTE: This is not the most ideal changeset.
diffTest(previous: "WAXAYAZ".characters,
current: "AWAXAAYAZA".characters,
diffTest(previous: "WAXAYAZ",
current: "AWAXAAYAZA",
computed: { Changeset(previous: $0, current: $1) },
expected: Changeset(inserts: [5, 7, 9],
moves: [.init(source: 6, destination: 8, isMutated: false),
Expand Down Expand Up @@ -445,8 +445,8 @@ class ChangesetSpec: QuickSpec {
}

it("should detect removed repeated values") {
diffTest(previous: "AAAAA".characters,
current: "AAA".characters,
diffTest(previous: "AAAAA",
current: "AAA",
computed: { Changeset(previous: $0, current: $1) },
expected: Changeset(removals: [3, 4]),
areEqual: ==)
Expand Down Expand Up @@ -685,8 +685,8 @@ class ChangesetSpec: QuickSpec {

describe("insertions and moves") {
it("should reflect a move and an insertion") {
diffTest(previous: "EABDFGHIJ".characters,
current: "ABCDEFGHIJ".characters,
diffTest(previous: "EABDFGHIJ",
current: "ABCDEFGHIJ",
computed: { Changeset(previous: $0, current: $1) },
expected: Changeset(inserts: [2],
removals: [],
Expand Down Expand Up @@ -732,9 +732,9 @@ class ChangesetSpec: QuickSpec {

it("should produce a snapshot that can be reproduced from the previous snapshot by applying the changeset, even if the collection is bidirectional") {
_measureAndStart(times: 256) {
let oldCharacters = "abcdefghijkl12345~!@%^&*()_-+=".characters.shuffled()
var newCharacters = oldCharacters.dropLast(8)
newCharacters.append(contentsOf: "mnopqrstuvwxyz67890#".characters)
let oldCharacters = "abcdefghijkl12345~!@%^&*()_-+=".shuffled()
var newCharacters = String(oldCharacters.dropLast(8))
newCharacters.append(contentsOf: "mnopqrstuvwxyz67890#")
newCharacters = newCharacters.shuffled()

reproducibilityTest(applying: Changeset(previous: oldCharacters,
Expand All @@ -746,9 +746,9 @@ class ChangesetSpec: QuickSpec {

it("should produce a snapshot that can be reproduced from the previous snapshot by applying the changeset, even if the collection is bidirectional and is a multiset") {
_measureAndStart(times: 256) {
let oldCharacters = "abcdefghijkl12345~!@%^&*()_-+=abcdefghijkl12345~!@%^&*()_-+=".characters.shuffled()
var newCharacters = oldCharacters.dropLast(8)
newCharacters.append(contentsOf: "mnopqrstuvwxyz67890#".characters)
let oldCharacters = "abcdefghijkl12345~!@%^&*()_-+=abcdefghijkl12345~!@%^&*()_-+=".shuffled()
var newCharacters = String(oldCharacters.dropLast(8))
newCharacters.append(contentsOf: "mnopqrstuvwxyz67890#")
newCharacters = newCharacters.shuffled()

reproducibilityTest(applying: Changeset(previous: oldCharacters,
Expand Down Expand Up @@ -849,8 +849,8 @@ private func reproducibilityTest<C: RangeReplaceableCollection>(

// (1) Perform removals (including move sources).
for range in removals.rangeView.reversed() {
let lowerBound = values.index(values.startIndex, offsetBy: C.IndexDistance(range.lowerBound))
let upperBound = values.index(lowerBound, offsetBy: C.IndexDistance(range.count))
let lowerBound = values.index(values.startIndex, offsetBy: numericCast(range.lowerBound))
let upperBound = values.index(lowerBound, offsetBy: numericCast(range.count))
values.removeSubrange(lowerBound ..< upperBound)
}

Expand All @@ -859,20 +859,21 @@ private func reproducibilityTest<C: RangeReplaceableCollection>(
let removalOffset = removals.count(in: 0 ..< range.lowerBound)
let insertOffset = inserts.count(in: 0 ... range.lowerBound)

let lowerBound = values.index(values.startIndex, offsetBy: C.IndexDistance(range.lowerBound - removalOffset))
let upperBound = values.index(lowerBound, offsetBy: C.IndexDistance(range.count))
let copyLowerBound = current.index(current.startIndex, offsetBy: C.IndexDistance(range.lowerBound - removalOffset + insertOffset))
let copyUpperBound = current.index(copyLowerBound, offsetBy: C.IndexDistance(range.count))
let lowerBound = values.index(values.startIndex, offsetBy: numericCast(range.lowerBound - removalOffset))
let upperBound = values.index(lowerBound, offsetBy: numericCast(range.count))
let copyLowerBound = current.index(current.startIndex, offsetBy: numericCast(range.lowerBound - removalOffset + insertOffset))
let copyUpperBound = current.index(copyLowerBound, offsetBy: numericCast(range.count))
values.replaceSubrange(lowerBound ..< upperBound,
with: current[copyLowerBound ..< copyUpperBound])
}

// (3) Perform insertions (including move destinations).
for range in inserts.rangeView {
let lowerBound = values.index(values.startIndex, offsetBy: C.IndexDistance(range.lowerBound))
let copyLowerBound = current.index(current.startIndex, offsetBy: C.IndexDistance(range.lowerBound))
let copyUpperBound = current.index(copyLowerBound, offsetBy: C.IndexDistance(range.count))
values.insert(contentsOf: current[copyLowerBound ..< copyUpperBound], at: lowerBound)
let lowerBound = values.index(values.startIndex, offsetBy: numericCast(range.lowerBound))
let copyLowerBound = current.index(current.startIndex, offsetBy: numericCast(range.lowerBound))
let copyUpperBound = current.index(copyLowerBound, offsetBy: numericCast(range.count))
values.insert(contentsOf: current[copyLowerBound ..< copyUpperBound],
at: lowerBound)
}

expect(values, file: file, line: line).to(equal(current, original: previous, changeset: changeset, by: areEqual))
Expand Down Expand Up @@ -903,8 +904,8 @@ private extension RangeReplaceableCollection {

for i in 0 ..< Int(elements.count) {
let distance = randomInteger() % Int(elements.count)
let random = elements.index(elements.startIndex, offsetBy: IndexDistance(distance))
let index = elements.index(elements.startIndex, offsetBy: IndexDistance(i))
let random = elements.index(elements.startIndex, offsetBy: numericCast(distance))
let index = elements.index(elements.startIndex, offsetBy: numericCast(i))
guard random != index else { continue }

let temp = elements[index]
Expand Down

0 comments on commit d1b23e4

Please sign in to comment.