Skip to content

Instantly share code, notes, and snippets.

@msanders
Last active March 3, 2017 19:09
Show Gist options
  • Save msanders/f8db1a931e65b7d989e997ce7b0337e4 to your computer and use it in GitHub Desktop.
Save msanders/f8db1a931e65b7d989e997ce7b0337e4 to your computer and use it in GitHub Desktop.
import Nimble
import Quick
import SwiftCheck
final class StringTransformSpec: QuickSpec {
override func spec() {
describe("chopPrefix<Int>") {
it("should remove prefix of given length") {
property("result is of expected length") <- forAll { (string: String) in
let stringLength = string.characters.count
return !(0..<stringLength).contains { idx in
let chopped = string.chopPrefix(idx)
return chopped.characters.count != stringLength - idx
}
}
property("result has prefix removed") <- forAll { (string: String) in
return !(0..<string.characters.count).contains { idx in
let chopped = string.chopPrefix(idx)
let expected = string.substringWithRange(
string.startIndex.advancedBy(idx)..<string.endIndex
)
return chopped != expected
}
}
}
}
describe("chopSuffix<Int>") {
it("should remove suffix of given length") {
property("result is of expected length") <- forAll { (string: String) in
let stringLength = string.characters.count
return !(0..<stringLength).contains { idx in
let chopped = string.chopSuffix(idx)
return chopped.characters.count != stringLength - idx
}
}
property("result has suffix removed") <- forAll { (string: String) in
return !(0..<string.characters.count).contains { idx in
let chopped = string.chopSuffix(idx)
let expected = string.substringWithRange(
string.startIndex..<string.endIndex.advancedBy(-idx)
)
return chopped != expected
}
}
}
}
describe("chopPrefix<String>") {
it("should remove the given prefix") {
property("result is of expected length") <- forAll { (string: String) in
let stringLength = string.characters.count
return !(0..<stringLength).contains { idx in
let prefix = string.substringToIndex(string.startIndex.advancedBy(idx))
let chopped = string.chopPrefix(prefix)
return chopped.characters.count != stringLength - prefix.characters.count
}
}
property("result has prefix removed") <- forAll { (string: String) in
return !(0..<string.characters.count).contains { idx in
let prefix = string.substringToIndex(string.startIndex.advancedBy(idx))
let expected = string.substringWithRange(
string.startIndex.advancedBy(prefix.characters.count)..<string.endIndex
)
let chopped = string.chopPrefix(prefix)
return chopped != expected
}
}
property("is no-op if prefix isn't present") <- forAll { (string: String) in
let mutantString = string.obfuscate()
return !(0..<mutantString.characters.count).contains { idx in
let prefix = mutantString.substringToIndex(
mutantString.startIndex.advancedBy(idx)
)
let chopped = string.chopPrefix(prefix)
return chopped != string
}
}
}
}
describe("chopSuffix<String>") {
it("should remove the given suffix") {
property("result is of expected length") <- forAll { (string: String) in
let stringLength = string.characters.count
return !(0..<stringLength).contains { idx in
let suffix = string.substringFromIndex(string.endIndex.advancedBy(-idx))
let chopped = string.chopSuffix(suffix)
return chopped.characters.count != stringLength - suffix.characters.count
}
}
property("result has suffix removed") <- forAll { (string: String) in
return !(0..<string.characters.count).contains { idx in
let suffix = string.substringFromIndex(string.endIndex.advancedBy(-idx))
let expected = string.substringWithRange(
string.startIndex..<string.endIndex.advancedBy(-suffix.characters.count)
)
let chopped = string.chopSuffix(suffix)
return chopped != expected
}
}
property("is no-op if suffix isn't present") <- forAll { (string: String) in
let mutantString = string.obfuscate()
return !(0..<mutantString.characters.count).contains { idx in
let suffix = mutantString.substringFromIndex(
mutantString.endIndex.advancedBy(-idx)
)
let chopped = string.chopSuffix(suffix)
return chopped != string
}
}
}
}
}
}
private extension String {
// From https://stackoverflow.com/a/26761822
func obfuscate() -> String {
return String(characters.map { c in
let scalars = String(c).unicodeScalars
let val = scalars[scalars.startIndex].value
return Character(UnicodeScalar(val + 1))
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment