Skip to content

Commit

Permalink
[test] Add tests for Rope.join’s copy-on-write behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
lorentey committed May 31, 2024
1 parent e166904 commit 6c31865
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
23 changes: 22 additions & 1 deletion Tests/RopeModuleTests/TestBigString.swift
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,28 @@ class TestBigString: CollectionTestCase {
}
return pieces
}


func test_append_copy_on_write() {
let flat = String(repeating: sampleString, count: 10)
withEvery("stride", in: [32, 64, 128, 250, 1_000, 10_000, 20_000]) { stride in
let pieces = self.pieces(of: flat, by: stride).map {
BigString($0.str)
}

var big: BigString = ""
withEvery("i", in: 0 ..< pieces.count) { i in
let copy = big
let expected = String(copy)

big.append(contentsOf: pieces[i])

let actual = String(copy)
expectTrue(actual == expected)
copy._invariantCheck()
}
}
}

func test_insert_string() {
let flat = sampleString
let ref = BigString(flat)
Expand Down
32 changes: 32 additions & 0 deletions Tests/RopeModuleTests/TestRope.swift
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,38 @@ class TestRope: CollectionTestCase {
expectEqual(ranges, [0 ..< c])
}

func test_join_copy_on_write() {
let c = 10_000
var trees = (0 ..< c).map {
let chunk = Chunk(length: ($0 % 4) + 1, value: $0)
return Rope(CollectionOfOne(chunk))
}
var ranges = (0 ..< c).map { $0 ..< $0 + 1 }

var rng = RepeatableRandomNumberGenerator(seed: 0)
while trees.count >= 2 {
let i = (0 ..< trees.count - 1).randomElement(using: &rng)!
let expectedRange = ranges[i].lowerBound ..< ranges[i + 1].upperBound

let a = trees[i]
let b = trees.remove(at: i + 1)
trees[i] = Rope()

let joined = Rope.join(a, b)

expectEqualElements(a.map { $0.value }, Array(ranges[i]), "Copy-on-write violation")
expectEqualElements(b.map { $0.value }, Array(ranges[i + 1]), "Copy-on-write violation")

a._invariantCheck()
b._invariantCheck()
joined._invariantCheck()

trees[i] = joined
ranges.replaceSubrange(i ... i + 1, with: CollectionOfOne(expectedRange))
}
expectEqual(ranges, [0 ..< c])
}

func chunkify(_ values: [Int]) -> [Chunk] {
var result: [Chunk] = []
var last = Int.min
Expand Down

0 comments on commit 6c31865

Please sign in to comment.