Signal-iOS/Signal/test/util/StringAdditionsTest.swift

254 lines
16 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
//
import XCTest
class StringAdditionsTest: SignalBaseTest {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func test_truncated_ASCII() {
let originalString = "Hello World"
var truncatedString = originalString.truncated(toByteCount: 8)
XCTAssertEqual("Hello Wo", truncatedString)
truncatedString = originalString.truncated(toByteCount: 0)
XCTAssertEqual("", truncatedString)
truncatedString = originalString.truncated(toByteCount: 11)
XCTAssertEqual("Hello World", truncatedString)
truncatedString = originalString.truncated(toByteCount: 12)
XCTAssertEqual("Hello World", truncatedString)
truncatedString = originalString.truncated(toByteCount: 100)
XCTAssertEqual("Hello World", truncatedString)
}
func test_truncated_MultiByte() {
let originalString = "🇨🇦🇨🇦🇨🇦🇨🇦"
var truncatedString = originalString.truncated(toByteCount: 0)
XCTAssertEqual("", truncatedString)
truncatedString = originalString.truncated(toByteCount: 1)
XCTAssertEqual("", truncatedString)
truncatedString = originalString.truncated(toByteCount: 7)
XCTAssertEqual("", truncatedString)
truncatedString = originalString.truncated(toByteCount: 8)
XCTAssertEqual("🇨🇦", truncatedString)
truncatedString = originalString.truncated(toByteCount: 9)
XCTAssertEqual("🇨🇦", truncatedString)
truncatedString = originalString.truncated(toByteCount: 15)
XCTAssertEqual("🇨🇦", truncatedString)
truncatedString = originalString.truncated(toByteCount: 16)
XCTAssertEqual("🇨🇦🇨🇦", truncatedString)
truncatedString = originalString.truncated(toByteCount: 17)
XCTAssertEqual("🇨🇦🇨🇦", truncatedString)
}
func test_truncated_Mixed() {
let originalString = "Oh🇨🇦Canada🇨🇦"
var truncatedString = originalString.truncated(toByteCount: 0)
XCTAssertEqual("", truncatedString)
truncatedString = originalString.truncated(toByteCount: 1)
XCTAssertEqual("O", truncatedString)
truncatedString = originalString.truncated(toByteCount: 7)
XCTAssertEqual("Oh", truncatedString)
truncatedString = originalString.truncated(toByteCount: 9)
XCTAssertEqual("Oh", truncatedString)
truncatedString = originalString.truncated(toByteCount: 10)
XCTAssertEqual("Oh🇨🇦", truncatedString)
truncatedString = originalString.truncated(toByteCount: 11)
XCTAssertEqual("Oh🇨🇦C", truncatedString)
truncatedString = originalString.truncated(toByteCount: 23)
XCTAssertEqual("Oh🇨🇦Canada", truncatedString)
truncatedString = originalString.truncated(toByteCount: 24)
XCTAssertEqual("Oh🇨🇦Canada🇨🇦", truncatedString)
truncatedString = originalString.truncated(toByteCount: 25)
XCTAssertEqual("Oh🇨🇦Canada🇨🇦", truncatedString)
truncatedString = originalString.truncated(toByteCount: 100)
XCTAssertEqual("Oh🇨🇦Canada🇨🇦", truncatedString)
}
func test_caesar() {
XCTAssertEqual("abc", try! "abc".caesar(shift: 0))
XCTAssertEqual("abc", try! "abc".caesar(shift: 127))
XCTAssertEqual("bcd", try! "abc".caesar(shift: 1))
XCTAssertEqual("bcd", try! "abc".caesar(shift: 128))
XCTAssertEqual("z{b", try! "yza".caesar(shift: 1))
XCTAssertEqual("|}d", try! "yza".caesar(shift: 3))
XCTAssertEqual("ef=g", try! "bc:d".caesar(shift: 3))
let shifted = try! "abc".caesar(shift: 32)
let roundTrip = try! shifted.caesar(shift: 127 - 32)
XCTAssertEqual("abc", roundTrip)
}
func test_encodedForSelector() {
XCTAssertEqual("cnN0", "abc".encodedForSelector)
XCTAssertEqual("abc", "abc".encodedForSelector!.decodedForSelector)
XCTAssertNotEqual("abcWithFoo:bar:", "abcWithFoo:bar:".encodedForSelector)
XCTAssertEqual("abcWithFoo:bar:", "abcWithFoo:bar:".encodedForSelector!.decodedForSelector)
XCTAssertNotEqual("abcWithFoo:bar:zaz1:", "abcWithFoo:bar:zaz1:".encodedForSelector)
XCTAssertEqual("abcWithFoo:bar:zaz1:", "abcWithFoo:bar:zaz1:".encodedForSelector!.decodedForSelector)
}
func test_directionalAppend() {
// We used to have a rtlSafeAppend helper, but it didn't behave quite like expected
// because iOS tries to be smart about the language of the string you're appending to.
//
// Sanity check that the iOS methods are doing what we want.
// Basic tests, "a" + "b" = "ab", etc.
XCTAssertEqual("a" + "b", "ab")
XCTAssertEqual("hello" + " " + "world", "hello world")
XCTAssertEqual("a" + " " + "1" + " " + "b", "a 1 b")
XCTAssertEqual("ا" + "ب", "اب")
XCTAssertEqual("مرحبا" + " " + "بالعالم", "مرحبا بالعالم")
XCTAssertEqual("ا" + " " + "1" + " " + "ب", "ا 1 ب")
// Test a common usage, similar to `formatPastTimestampRelativeToNow` where we append a time to a date.
let testTime = "9:41"
let testStrings: [(day: String, expectedConcatentation: String)] = [
// LTR Tests
("Today", "Today 9:41"), // English
("Heute", "Heute 9:41"), // German
// RTL Tests
("اليوم", "اليوم 9:41"), // Arabic
("היום", "היום 9:41") // Hebrew
]
for (day, expectedConcatentation) in testStrings {
XCTAssertEqual(day + " " + testTime, expectedConcatentation)
XCTAssertEqual((day as NSString).appending(" ").appending(testTime), expectedConcatentation)
XCTAssertEqual(NSAttributedString(string: day) + " " + testTime, NSAttributedString(string: expectedConcatentation))
}
}
func test_formatDurationLossless() {
let secondsPerMinute: UInt32 = 60
let secondsPerHour: UInt32 = secondsPerMinute * 60
let secondsPerDay: UInt32 = secondsPerHour * 24
let secondsPerWeek: UInt32 = secondsPerDay * 7
let secondsPerYear: UInt32 = secondsPerDay * 365
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 0), "0 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1), "1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2), "2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerMinute - 1), "59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerMinute), "1 minute")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerMinute + 1), "1 minute, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerMinute + 2), "1 minute, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerMinute - 1), "1 minute, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerMinute), "2 minutes")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerMinute + 1), "2 minutes, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerMinute + 2), "2 minutes, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerHour - 1), "59 minutes, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerHour), "1 hour")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerHour + 1), "1 hour, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerHour + 2), "1 hour, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerHour + 1 * secondsPerMinute + 1), "1 hour, 1 minute, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerHour + 1 * secondsPerMinute + 2), "1 hour, 1 minute, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerHour + 2 * secondsPerMinute + 1), "1 hour, 2 minutes, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerHour + 2 * secondsPerMinute + 2), "1 hour, 2 minutes, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerHour - 1), "1 hour, 59 minutes, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerHour), "2 hours")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerHour + 1), "2 hours, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerHour + 2), "2 hours, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerHour + 1 * secondsPerMinute + 1), "2 hours, 1 minute, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerHour + 1 * secondsPerMinute + 2), "2 hours, 1 minute, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerHour + 2 * secondsPerMinute + 1), "2 hours, 2 minutes, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerHour + 2 * secondsPerMinute + 2), "2 hours, 2 minutes, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerDay - 1), "23 hours, 59 minutes, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerDay), "1 day")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerDay + 1), "1 day, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerDay + 2), "1 day, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerDay + 1 * secondsPerHour + 1), "1 day, 1 hour, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerDay + 1 * secondsPerHour + 2), "1 day, 1 hour, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerDay + 2 * secondsPerHour + 1), "1 day, 2 hours, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerDay + 2 * secondsPerHour + 2), "1 day, 2 hours, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerDay - 1), "1 day, 23 hours, 59 minutes, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerDay), "2 days")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerDay + 1), "2 days, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerDay + 2), "2 days, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerDay + 1 * secondsPerHour + 1), "2 days, 1 hour, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerDay + 1 * secondsPerHour + 2), "2 days, 1 hour, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerDay + 2 * secondsPerHour + 1), "2 days, 2 hours, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerDay + 2 * secondsPerHour + 2), "2 days, 2 hours, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerWeek - 1), "6 days, 23 hours, 59 minutes, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerWeek), "1 week")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerWeek + 1), "1 week, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerWeek + 2), "1 week, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerWeek + 1 * secondsPerDay + 1), "1 week, 1 day, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerWeek + 1 * secondsPerDay + 2), "1 week, 1 day, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerWeek + 2 * secondsPerDay + 1), "1 week, 2 days, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerWeek + 2 * secondsPerDay + 2), "1 week, 2 days, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerWeek - 1), "1 week, 6 days, 23 hours, 59 minutes, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerWeek), "2 weeks")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerWeek + 1), "2 weeks, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerWeek + 2), "2 weeks, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerWeek + 1 * secondsPerDay + 1), "2 weeks, 1 day, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerWeek + 1 * secondsPerDay + 2), "2 weeks, 1 day, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerWeek + 2 * secondsPerDay + 1), "2 weeks, 2 days, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerWeek + 2 * secondsPerDay + 2), "2 weeks, 2 days, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerYear - 1), "52 weeks, 23 hours, 59 minutes, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerYear), "1 year")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerYear + 1), "1 year, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerYear + 2), "1 year, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerYear + 1 * secondsPerWeek + 1), "1 year, 1 week, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerYear + 1 * secondsPerWeek + 2), "1 year, 1 week, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerYear + 2 * secondsPerWeek + 1), "1 year, 2 weeks, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 1 * secondsPerYear + 2 * secondsPerWeek + 2), "1 year, 2 weeks, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerYear - 1), "1 year, 52 weeks, 23 hours, 59 minutes, 59 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerYear), "2 years")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerYear + 1), "2 years, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerYear + 2), "2 years, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerYear + 1 * secondsPerWeek + 1), "2 years, 1 week, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerYear + 1 * secondsPerWeek + 2), "2 years, 1 week, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerYear + 2 * secondsPerWeek + 1), "2 years, 2 weeks, 1 second")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 2 * secondsPerYear + 2 * secondsPerWeek + 2), "2 years, 2 weeks, 2 seconds")
XCTAssertEqual(String.formatDurationLossless(durationSeconds: 88 * secondsPerYear + 7 * secondsPerWeek + 6 * secondsPerDay + 5 * secondsPerHour + 4 * secondsPerMinute + 3), "88 years, 7 weeks, 6 days, 5 hours, 4 minutes, 3 seconds")
}
}