Merge branch 'mkirk/orm-perf'

pull/1/head
Michael Kirk 6 years ago
commit 4a26952f51

@ -4,33 +4,62 @@ source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
def shared_pods
###
# OWS Pods
###
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', testspecs: ["Tests"]
# pod 'SignalCoreKit', path: '../SignalCoreKit', testspecs: ["Tests"]
# pod 'SQLCipher', path: '../sqlcipher'
pod 'SQLCipher', :git => 'https://github.com/sqlcipher/sqlcipher.git', :commit => 'd5c2bec'
# pod 'YapDatabase/SQLCipher', path: '../YapDatabase'
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release'
pod 'AxolotlKit', git: 'https://github.com/signalapp/SignalProtocolKit.git', branch: 'master', testspecs: ["Tests"]
# pod 'AxolotlKit', path: '../SignalProtocolKit', testspecs: ["Tests"]
pod 'HKDFKit', git: 'https://github.com/signalapp/HKDFKit.git', testspecs: ["Tests"]
# pod 'HKDFKit', path: '../HKDFKit', testspecs: ["Tests"]
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit', testspecs: ["Tests"]
# pod 'Curve25519Kit', path: '../Curve25519Kit', testspecs: ["Tests"]
pod 'SignalMetadataKit', git: 'https://github.com/signalapp/SignalMetadataKit', testspecs: ["Tests"]
# pod 'SignalMetadataKit', path: '../SignalMetadataKit', testspecs: ["Tests"]
pod 'SignalServiceKit', path: '.', testspecs: ["Tests"]
###
# forked third party pods
###
# Includes some soon to be released "unencrypted header" changes required for the Share Extension
pod 'SQLCipher', :git => 'https://github.com/sqlcipher/sqlcipher.git', :commit => 'd5c2bec'
# pod 'SQLCipher', path: '../sqlcipher'
# Forked for performance optimizations that are not likely to be upstreamed as they are specific
# to our limited use of Mantle
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master'
# pod 'Mantle', path: '../Mantle'
# SocketRocket has some critical crash fixes on Github, but have published an official release to cocoapods in ages, so
# we were following master
# Forked and have an open PR with our changes, but they have not been merged.
# pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git', inhibit_warnings: true
pod 'SocketRocket', :git => 'https://github.com/signalapp/SocketRocket.git', branch: 'mkirk/handle-sec-err', inhibit_warnings: true
# Forked for compatibily with the ShareExtension, changes have an open PR, but have not been merged.
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release'
# pod 'YapDatabase/SQLCipher', path: '../YapDatabase'
# Forked to incorporate our self-built binary artifact.
pod 'GRKOpenSSLFramework', git: 'https://github.com/signalapp/GRKOpenSSLFramework'
#pod 'GRKOpenSSLFramework', path: '../GRKOpenSSLFramework'
###
# third party pods
####
pod 'AFNetworking', inhibit_warnings: true
pod 'Mantle', :inhibit_warnings => true
# pod 'YapDatabase/SQLCipher', :inhibit_warnings => true
pod 'PureLayout', :inhibit_warnings => true
pod 'Reachability', :inhibit_warnings => true
# pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git', inhibit_warnings: true
pod 'SocketRocket', :git => 'https://github.com/signalapp/SocketRocket.git', branch: 'mkirk/handle-sec-err', inhibit_warnings: true
pod 'YYImage', :inhibit_warnings => true
end

@ -196,7 +196,7 @@ DEPENDENCIES:
- GRKOpenSSLFramework (from `https://github.com/signalapp/GRKOpenSSLFramework`)
- HKDFKit (from `https://github.com/signalapp/HKDFKit.git`)
- HKDFKit/Tests (from `https://github.com/signalapp/HKDFKit.git`)
- Mantle
- Mantle (from `https://github.com/signalapp/Mantle`, branch `signal-master`)
- PureLayout
- Reachability
- SignalCoreKit (from `https://github.com/signalapp/SignalCoreKit.git`)
@ -216,7 +216,6 @@ SPEC REPOS:
- AFNetworking
- CocoaLumberjack
- libPhoneNumber-iOS
- Mantle
- PromiseKit
- PureLayout
- Reachability
@ -235,6 +234,9 @@ EXTERNAL SOURCES:
:git: https://github.com/signalapp/GRKOpenSSLFramework
HKDFKit:
:git: https://github.com/signalapp/HKDFKit.git
Mantle:
:branch: signal-master
:git: https://github.com/signalapp/Mantle
SignalCoreKit:
:git: https://github.com/signalapp/SignalCoreKit.git
SignalMetadataKit:
@ -264,8 +266,11 @@ CHECKOUT OPTIONS:
HKDFKit:
:commit: 3e0c2371d125f2d3db26daa498d5d436961b1795
:git: https://github.com/signalapp/HKDFKit.git
Mantle:
:commit: 86be6280908291114bfacca7b765fe89bd5ca6e2
:git: https://github.com/signalapp/Mantle
SignalCoreKit:
:commit: a84ec7ed6c13b079a7e03cb09c79b5452086d1e7
:commit: b575b9ce6a670964e1624f596dbf0aebcae82046
:git: https://github.com/signalapp/SignalCoreKit.git
SignalMetadataKit:
:commit: 56f28fc3a6e35d548d034ef7d0009f233ca0aa62
@ -303,6 +308,6 @@ SPEC CHECKSUMS:
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
PODFILE CHECKSUM: 0f765be42c3a325b23c9a59b52d35289bb6b067d
PODFILE CHECKSUM: 1d3c7b17e2ff7bab54e3551c74559c26d95d9b06
COCOAPODS: 1.5.3

@ -1 +1 @@
Subproject commit 96cc3c16eb56a8bf416d91d6f06b47b06b02b9f0
Subproject commit 80ecd88615e75d270f1aa5f5a0e8d6060cec334f

@ -443,6 +443,7 @@
45FBC5C81DF8575700E9B410 /* CallKitCallManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45FBC59A1DF8575700E9B410 /* CallKitCallManager.swift */; };
45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45FBC5D01DF8592E00E9B410 /* SignalCall.swift */; };
4AC4EA13C8A444455DAB351F /* Pods_SignalMessaging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 264242150E87D10A357DB07B /* Pods_SignalMessaging.framework */; };
4C04F58421C860C50090D0BB /* MantlePerfTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C04F58321C860C50090D0BB /* MantlePerfTest.swift */; };
4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */; };
4C11AA5020FD59C700351FBD /* MessageStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C11AA4F20FD59C700351FBD /* MessageStatusView.swift */; };
4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */; };
@ -1159,6 +1160,7 @@
45F659811E1BE77000444429 /* NonCallKitCallUIAdaptee.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NonCallKitCallUIAdaptee.swift; sourceTree = "<group>"; };
45FBC59A1DF8575700E9B410 /* CallKitCallManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallKitCallManager.swift; sourceTree = "<group>"; };
45FBC5D01DF8592E00E9B410 /* SignalCall.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalCall.swift; sourceTree = "<group>"; };
4C04F58321C860C50090D0BB /* MantlePerfTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MantlePerfTest.swift; path = Models/MantlePerfTest.swift; sourceTree = "<group>"; };
4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HapticFeedback.swift; path = UserInterface/HapticFeedback.swift; sourceTree = "<group>"; };
4C11AA4F20FD59C700351FBD /* MessageStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageStatusView.swift; sourceTree = "<group>"; };
4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = "<group>"; };
@ -2192,6 +2194,7 @@
458E38381D6699110094BD24 /* Models */ = {
isa = PBXGroup;
children = (
4C04F58321C860C50090D0BB /* MantlePerfTest.swift */,
4C4BC6C22102D697004040C9 /* ContactDiscoveryOperationTest.swift */,
458E38391D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m */,
458967101DC117CC00E9DD21 /* AccountManagerTest.swift */,
@ -3626,6 +3629,7 @@
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */,
3421981C21061D2E00C57195 /* ByteParserTest.swift in Sources */,
34843B26214327C9004DED45 /* OWSOrphanDataCleanerTest.m in Sources */,
4C04F58421C860C50090D0BB /* MantlePerfTest.swift in Sources */,
45360B901F9527DA00FA666C /* SearcherTest.swift in Sources */,
34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */,
34843B2C214FE296004DED45 /* MockEnvironment.m in Sources */,

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>classNames</key>
<dict>
<key>MantlePerfTest</key>
<dict>
<key>testPerformanceExample()</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>3.19</real>
<key>baselineIntegrationDisplayName</key>
<string>Local Baseline</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</plist>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>classNames</key>
<dict>
<key>MantlePerfTest</key>
<dict>
<key>testPerformanceExample()</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>0.62862</real>
<key>baselineIntegrationDisplayName</key>
<string>Local Baseline</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</plist>

@ -35,6 +35,68 @@
<string>com.apple.platform.iphonesimulator</string>
</dict>
</dict>
<key>F29A0D38-3F89-44CA-8BDC-C99EE6C1AB81</key>
<dict>
<key>localComputer</key>
<dict>
<key>busSpeedInMHz</key>
<integer>100</integer>
<key>cpuCount</key>
<integer>1</integer>
<key>cpuKind</key>
<string>Intel Core i7</string>
<key>cpuSpeedInMHz</key>
<integer>2900</integer>
<key>logicalCPUCoresPerPackage</key>
<integer>8</integer>
<key>modelCode</key>
<string>MacBookPro14,3</string>
<key>physicalCPUCoresPerPackage</key>
<integer>4</integer>
<key>platformIdentifier</key>
<string>com.apple.platform.macosx</string>
</dict>
<key>targetArchitecture</key>
<string>x86_64</string>
<key>targetDevice</key>
<dict>
<key>modelCode</key>
<string>iPhone10,6</string>
<key>platformIdentifier</key>
<string>com.apple.platform.iphonesimulator</string>
</dict>
</dict>
<key>F934A594-2E7D-49A5-9B1B-63A05DABCE3C</key>
<dict>
<key>localComputer</key>
<dict>
<key>busSpeedInMHz</key>
<integer>100</integer>
<key>cpuCount</key>
<integer>1</integer>
<key>cpuKind</key>
<string>Intel Core i7</string>
<key>cpuSpeedInMHz</key>
<integer>2900</integer>
<key>logicalCPUCoresPerPackage</key>
<integer>8</integer>
<key>modelCode</key>
<string>MacBookPro14,3</string>
<key>physicalCPUCoresPerPackage</key>
<integer>4</integer>
<key>platformIdentifier</key>
<string>com.apple.platform.macosx</string>
</dict>
<key>targetArchitecture</key>
<string>x86_64</string>
<key>targetDevice</key>
<dict>
<key>modelCode</key>
<string>iPhone7,2</string>
<key>platformIdentifier</key>
<string>com.apple.platform.iphonesimulator</string>
</dict>
</dict>
</dict>
</dict>
</plist>

@ -77,6 +77,9 @@ public class BackupLazyRestore: NSObject {
public func runIfNecessary() {
AssertIsOnMainThread()
guard !CurrentAppContext().isRunningTests else {
return
}
guard AppReadiness.isAppReady() else {
return
}

@ -47,6 +47,10 @@ class VerifyingTSAccountManager: FailingTSAccountManager {
success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
success()
}
override func performUpdateAccountAttributes() -> AnyPromise {
return AnyPromise(Promise.value(()))
}
}
class TokenObtainingTSAccountManager: VerifyingTSAccountManager {

@ -0,0 +1,42 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import XCTest
@testable import SignalMessaging
@testable import SignalServiceKit
class MantlePerfTest: SignalBaseTest {
var primaryStorage: OWSPrimaryStorage {
return SSKEnvironment.shared.primaryStorage
}
override func 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.
}
func testPerformanceExample() {
let migration = OWS110SortIdMigration()
self.measureMetrics(XCTestCase.defaultPerformanceMetrics, automaticallyStartMeasuring: false) {
_ = OutgoingMessageFactory().create(count: 100)
startMeasuring()
let migrationCompleted = expectation(description: "migrationCompleted")
migration.runUp(completion: migrationCompleted.fulfill)
self.wait(for: [migrationCompleted], timeout: 10)
stopMeasuring()
TSInteraction.removeAllObjectsInCollection()
}
}
}

@ -294,7 +294,9 @@ class ConversationSearcherTest: SignalBaseTest {
XCTAssertEqual(["My fax is: 222-333-4444"], bodies(forMessageResults: resultSet.messages))
}
func bodies(forMessageResults messageResults: [ConversationSearchResult]) -> [String] {
// MARK: Helpers
func bodies<T>(forMessageResults messageResults: [ConversationSearchResult<T>]) -> [String] {
var result = [String]()
self.dbConnection.read { transaction in
@ -322,8 +324,6 @@ class ConversationSearcherTest: SignalBaseTest {
return result.sorted()
}
// MARK: Helpers
private func searchConversations(searchText: String) -> [ThreadViewModel] {
let results = getResultSet(searchText: searchText)
return results.conversations.map { $0.thread }

@ -4,7 +4,7 @@
import Foundation
class OWS110SortIdMigration: OWSDatabaseMigration {
public class OWS110SortIdMigration: OWSDatabaseMigration {
// increment a similar constant for each migration.
@objc
class func migrationId() -> String {

@ -81,10 +81,14 @@ NS_ASSUME_NONNULL_BEGIN
+ (uint32_t)maxDurationSeconds
{
uint32_t max = [[self.validDurationsSeconds valueForKeyPath:@"@max.intValue"] unsignedIntValue];
// It's safe to update this assert if we add a larger duration
OWSAssertDebug(max == 1 * kWeekInterval);
static uint32_t max;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
max = [[self.validDurationsSeconds valueForKeyPath:@"@max.intValue"] unsignedIntValue];
// It's safe to update this assert if we add a larger duration
OWSAssertDebug(max == 1 * kWeekInterval);
});
return max;
}

@ -129,26 +129,20 @@ public class FullTextSearchFinder: NSObject {
return charactersToFilter
}()
// This is a hot method, especially while running large migrations.
// Changes to it should go through a profiler to make sure large migrations
// aren't adversely affected.
public class func normalize(text: String) -> String {
// 1. Filter out invalid characters.
let filtered = text.unicodeScalars.lazy.filter({
!charactersToRemove.contains($0)
})
let filtered = text.removeCharacters(characterSet: charactersToRemove)
// 2. Simplify whitespace.
let simplifyingFunction: (UnicodeScalar) -> UnicodeScalar = {
if CharacterSet.whitespacesAndNewlines.contains($0) {
return UnicodeScalar(" ")
} else {
return $0
}
}
let simplified = filtered.map(simplifyingFunction)
let simplified = filtered.replaceCharacters(characterSet: .whitespacesAndNewlines,
replacement: " ")
// 3. Strip leading & trailing whitespace last, since we may replace
// filtered characters with whitespace.
let result = String(String.UnicodeScalarView(simplified))
return result.trimmingCharacters(in: .whitespacesAndNewlines)
return simplified.trimmingCharacters(in: .whitespacesAndNewlines)
}
// MARK: - Index Building
@ -248,9 +242,7 @@ public class FullTextSearchFinder: NSObject {
let contentColumnName = "content"
let handler = YapDatabaseFullTextSearchHandler.withObjectBlock { (transaction: YapDatabaseReadTransaction, dict: NSMutableDictionary, _: String, _: String, object: Any) in
if let content: String = indexContent(object: object, transaction: transaction) {
dict[contentColumnName] = content
}
dict[contentColumnName] = indexContent(object: object, transaction: transaction)
}
// update search index on contact name changes?
@ -262,3 +254,15 @@ public class FullTextSearchFinder: NSObject {
versionTag: "1")
}
}
extension String {
func replaceCharacters(characterSet: CharacterSet, replacement: String) -> String {
let components = self.components(separatedBy: characterSet)
return components.joined(separator: replacement)
}
func removeCharacters(characterSet: CharacterSet) -> String {
let components = self.components(separatedBy: characterSet)
return components.joined()
}
}

@ -7,7 +7,7 @@ import Foundation
/// Factories for creating some default TSYapDatabaseObjects.
///
/// To customize properties applied by the factory (e.g. `someProperty`)
/// the factory needs a `var somePropertyBuilder: () -> (SomePropertyType)`
/// the factory needs a `public var somePropertyBuilder: () -> (SomePropertyType)`
/// which is then used in the `create` method.
///
/// Examples:
@ -29,7 +29,7 @@ import Foundation
/// messageFactory.threadCreator = { _ in return existingThread }
/// messageFactory.create(count: 100)
///
protocol Factory {
public protocol Factory {
associatedtype ObjectType: TSYapDatabaseObject
var dbConnection: YapDatabaseConnection { get }
@ -44,27 +44,27 @@ protocol Factory {
func create(count: UInt, transaction: YapDatabaseReadWriteTransaction) -> [ObjectType]
}
extension Factory {
public extension Factory {
static var dbConnection: YapDatabaseConnection {
static public var dbConnection: YapDatabaseConnection {
return OWSPrimaryStorage.shared().dbReadWriteConnection
}
var dbConnection: YapDatabaseConnection {
public var dbConnection: YapDatabaseConnection {
return OWSPrimaryStorage.shared().dbReadWriteConnection
}
static func readWrite(block: @escaping (YapDatabaseReadWriteTransaction) -> Void) {
static public func readWrite(block: @escaping (YapDatabaseReadWriteTransaction) -> Void) {
dbConnection.readWrite(block)
}
func readWrite(block: @escaping (YapDatabaseReadWriteTransaction) -> Void) {
public func readWrite(block: @escaping (YapDatabaseReadWriteTransaction) -> Void) {
dbConnection.readWrite(block)
}
// MARK: Factory Methods
func create() -> ObjectType {
public func create() -> ObjectType {
var item: ObjectType!
self.readWrite { transaction in
item = self.create(transaction: transaction)
@ -72,7 +72,7 @@ extension Factory {
return item
}
func create(count: UInt) -> [ObjectType] {
public func create(count: UInt) -> [ObjectType] {
var items: [ObjectType] = []
self.readWrite { transaction in
items = self.create(count: count, transaction: transaction)
@ -80,20 +80,20 @@ extension Factory {
return items
}
func create(count: UInt, transaction: YapDatabaseReadWriteTransaction) -> [ObjectType] {
public func create(count: UInt, transaction: YapDatabaseReadWriteTransaction) -> [ObjectType] {
return (0..<count).map { _ in return create(transaction: transaction) }
}
}
@objc
class ContactThreadFactory: NSObject, Factory {
public class ContactThreadFactory: NSObject, Factory {
var messageCount: UInt = 0
// MARK: Factory
@objc
func create(transaction: YapDatabaseReadWriteTransaction) -> TSContactThread {
public func create(transaction: YapDatabaseReadWriteTransaction) -> TSContactThread {
let threadId = generateContactThreadId()
let thread = TSContactThread.getOrCreateThread(withContactId: threadId, transaction: transaction)
@ -116,18 +116,18 @@ class ContactThreadFactory: NSObject, Factory {
// MARK: Generators
func generateContactThreadId() -> String {
public func generateContactThreadId() -> String {
return CommonGenerator.contactId
}
}
@objc
class OutgoingMessageFactory: NSObject, Factory {
public class OutgoingMessageFactory: NSObject, Factory {
// MARK: Factory
@objc
func build(transaction: YapDatabaseReadWriteTransaction) -> TSOutgoingMessage {
public func build(transaction: YapDatabaseReadWriteTransaction) -> TSOutgoingMessage {
let item = TSOutgoingMessage(outgoingMessageWithTimestamp: timestampBuilder(),
in: threadCreator(transaction),
messageBody: messageBodyBuilder(),
@ -143,7 +143,7 @@ class OutgoingMessageFactory: NSObject, Factory {
}
@objc
func create(transaction: YapDatabaseReadWriteTransaction) -> TSOutgoingMessage {
public func create(transaction: YapDatabaseReadWriteTransaction) -> TSOutgoingMessage {
let item = self.build(transaction: transaction)
item.save(with: transaction)
@ -153,19 +153,19 @@ class OutgoingMessageFactory: NSObject, Factory {
// MARK: Dependent Factories
@objc
var threadCreator: (YapDatabaseReadWriteTransaction) -> TSThread = { transaction in
public var threadCreator: (YapDatabaseReadWriteTransaction) -> TSThread = { transaction in
ContactThreadFactory().create(transaction: transaction)
}
// MARK: Generators
@objc
var timestampBuilder: () -> UInt64 = {
public var timestampBuilder: () -> UInt64 = {
return NSDate.ows_millisecondTimeStamp()
}
@objc
var messageBodyBuilder: () -> String = {
public var messageBodyBuilder: () -> String = {
return CommonGenerator.paragraph
}
@ -175,39 +175,39 @@ class OutgoingMessageFactory: NSObject, Factory {
}
@objc
var expiresInSecondsBuilder: () -> UInt32 = {
public var expiresInSecondsBuilder: () -> UInt32 = {
return 0
}
@objc
var expireStartedAtBuilder: () -> UInt64 = {
public var expireStartedAtBuilder: () -> UInt64 = {
return 0
}
@objc
var isVoiceMessageBuilder: () -> Bool = {
public var isVoiceMessageBuilder: () -> Bool = {
return false
}
@objc
var groupMetaMessageBuilder: () -> TSGroupMetaMessage = {
public var groupMetaMessageBuilder: () -> TSGroupMetaMessage = {
return .unspecified
}
@objc
var quotedMessageBuilder: () -> TSQuotedMessage? = {
public var quotedMessageBuilder: () -> TSQuotedMessage? = {
return nil
}
@objc
var contactShareBuilder: () -> OWSContact? = {
public var contactShareBuilder: () -> OWSContact? = {
return nil
}
// MARK: Delivery Receipts
@objc
func buildDeliveryReceipt() -> OWSReceiptsForSenderMessage {
public func buildDeliveryReceipt() -> OWSReceiptsForSenderMessage {
var item: OWSReceiptsForSenderMessage!
self.readWrite { transaction in
item = self.buildDeliveryReceipt(transaction: transaction)
@ -216,14 +216,14 @@ class OutgoingMessageFactory: NSObject, Factory {
}
@objc
func buildDeliveryReceipt(transaction: YapDatabaseReadWriteTransaction) -> OWSReceiptsForSenderMessage {
public func buildDeliveryReceipt(transaction: YapDatabaseReadWriteTransaction) -> OWSReceiptsForSenderMessage {
let item = OWSReceiptsForSenderMessage.deliveryReceiptsForSenderMessage(with: threadCreator(transaction),
messageTimestamps: messageTimestampsBuilder())
return item
}
@objc
var messageTimestampsBuilder: () -> [NSNumber] = {
public var messageTimestampsBuilder: () -> [NSNumber] = {
return [1]
}
}
@ -234,7 +234,7 @@ class IncomingMessageFactory: NSObject, Factory {
// MARK: Factory
@objc
func create(transaction: YapDatabaseReadWriteTransaction) -> TSIncomingMessage {
public func create(transaction: YapDatabaseReadWriteTransaction) -> TSIncomingMessage {
let item = TSIncomingMessage(incomingMessageWithTimestamp: timestampBuilder(),
in: threadCreator(transaction),
authorId: authorIdBuilder(),
@ -255,59 +255,59 @@ class IncomingMessageFactory: NSObject, Factory {
// MARK: Dependent Factories
@objc
var threadCreator: (YapDatabaseReadWriteTransaction) -> TSThread = { transaction in
public var threadCreator: (YapDatabaseReadWriteTransaction) -> TSThread = { transaction in
ContactThreadFactory().create(transaction: transaction)
}
// MARK: Generators
@objc
var timestampBuilder: () -> UInt64 = {
public var timestampBuilder: () -> UInt64 = {
return NSDate.ows_millisecondTimeStamp()
}
@objc
var messageBodyBuilder: () -> String = {
public var messageBodyBuilder: () -> String = {
return CommonGenerator.paragraph
}
@objc
var authorIdBuilder: () -> String = {
public var authorIdBuilder: () -> String = {
return CommonGenerator.contactId
}
@objc
var sourceDeviceIdBuilder: () -> UInt32 = {
public var sourceDeviceIdBuilder: () -> UInt32 = {
return 1
}
@objc
var attachmentIdsBuilder: () -> [String] = {
public var attachmentIdsBuilder: () -> [String] = {
return []
}
@objc
var expiresInSecondsBuilder: () -> UInt32 = {
public var expiresInSecondsBuilder: () -> UInt32 = {
return 0
}
@objc
var quotedMessageBuilder: () -> TSQuotedMessage? = {
public var quotedMessageBuilder: () -> TSQuotedMessage? = {
return nil
}
@objc
var contactShareBuilder: () -> OWSContact? = {
public var contactShareBuilder: () -> OWSContact? = {
return nil
}
@objc
var serverTimestampBuilder: () -> NSNumber? = {
public var serverTimestampBuilder: () -> NSNumber? = {
return nil
}
@objc
var wasReceivedByUDBuilder: () -> Bool = {
public var wasReceivedByUDBuilder: () -> Bool = {
return false
}
}
@ -316,10 +316,10 @@ class IncomingMessageFactory: NSObject, Factory {
class GroupThreadFactory: NSObject, Factory {
@objc
var messageCount: UInt = 0
public var messageCount: UInt = 0
@objc
func create(transaction: YapDatabaseReadWriteTransaction) -> TSGroupThread {
public func create(transaction: YapDatabaseReadWriteTransaction) -> TSGroupThread {
let thread = TSGroupThread.getOrCreateThread(with: groupModelBuilder(self),
transaction: transaction)
thread.save(with: transaction)
@ -345,7 +345,7 @@ class GroupThreadFactory: NSObject, Factory {
// MARK: Generators
@objc
var groupModelBuilder: (GroupThreadFactory) -> TSGroupModel = { groupThreadFactory in
public var groupModelBuilder: (GroupThreadFactory) -> TSGroupModel = { groupThreadFactory in
return TSGroupModel(title: groupThreadFactory.titleBuilder(),
memberIds: groupThreadFactory.memberIdsBuilder(),
image: groupThreadFactory.imageBuilder(),
@ -353,22 +353,22 @@ class GroupThreadFactory: NSObject, Factory {
}
@objc
var titleBuilder: () -> String? = {
public var titleBuilder: () -> String? = {
return CommonGenerator.words(count: 3)
}
@objc
var groupIdBuilder: () -> Data = {
public var groupIdBuilder: () -> Data = {
return Randomness.generateRandomBytes(Int32(kGroupIdLength))!
}
@objc
var imageBuilder: () -> UIImage? = {
public var imageBuilder: () -> UIImage? = {
return nil
}
@objc
var memberIdsBuilder: () -> [RecipientIdentifier] = {
public var memberIdsBuilder: () -> [RecipientIdentifier] = {
let groupSize = arc4random_uniform(10)
return (0..<groupSize).map { _ in CommonGenerator.contactId }
}
@ -378,7 +378,7 @@ class GroupThreadFactory: NSObject, Factory {
class AttachmentStreamFactory: NSObject, Factory {
@objc
class func create(contentType: String, dataSource: DataSource) -> TSAttachmentStream {
class public func create(contentType: String, dataSource: DataSource) -> TSAttachmentStream {
var item: TSAttachmentStream!
readWrite { transaction in
item = create(contentType: contentType, dataSource: dataSource, transaction: transaction)
@ -387,7 +387,7 @@ class AttachmentStreamFactory: NSObject, Factory {
}
@objc
class func create(contentType: String, dataSource: DataSource, transaction: YapDatabaseReadWriteTransaction) -> TSAttachmentStream {
class public func create(contentType: String, dataSource: DataSource, transaction: YapDatabaseReadWriteTransaction) -> TSAttachmentStream {
let factory = AttachmentStreamFactory()
factory.contentTypeBuilder = { return contentType }
factory.byteCountBuilder = { return UInt32(dataSource.dataLength()) }
@ -403,7 +403,7 @@ class AttachmentStreamFactory: NSObject, Factory {
// MARK: Factory
@objc
func create(transaction: YapDatabaseReadWriteTransaction) -> TSAttachmentStream {
public func create(transaction: YapDatabaseReadWriteTransaction) -> TSAttachmentStream {
let attachmentStream = build(transaction: transaction)
attachmentStream.save(with: transaction)
@ -411,12 +411,12 @@ class AttachmentStreamFactory: NSObject, Factory {
}
@objc
func build(transaction: YapDatabaseReadTransaction) -> TSAttachmentStream {
public func build(transaction: YapDatabaseReadTransaction) -> TSAttachmentStream {
return build()
}
@objc
func build() -> TSAttachmentStream {
public func build() -> TSAttachmentStream {
let attachmentStream = TSAttachmentStream(contentType: contentTypeBuilder(),
byteCount: byteCountBuilder(),
sourceFilename: sourceFilenameBuilder(),
@ -429,33 +429,33 @@ class AttachmentStreamFactory: NSObject, Factory {
// MARK: Properties
@objc
var contentTypeBuilder: () -> String = {
public var contentTypeBuilder: () -> String = {
return OWSMimeTypeApplicationOctetStream
}
@objc
var byteCountBuilder: () -> UInt32 = {
public var byteCountBuilder: () -> UInt32 = {
return 0
}
@objc
var sourceFilenameBuilder: () -> String? = {
public var sourceFilenameBuilder: () -> String? = {
return "fake_file.dat"
}
@objc
var captionBuilder: () -> String? = {
public var captionBuilder: () -> String? = {
return nil
}
@objc
var albumMessageIdBuilder: () -> String? = {
public var albumMessageIdBuilder: () -> String? = {
return nil
}
}
extension Array {
func ows_randomElement() -> Element? {
public func ows_randomElement() -> Element? {
guard self.count > 0 else {
return nil
}
@ -466,7 +466,7 @@ extension Array {
struct CommonGenerator {
static var contactId: String {
static public var contactId: String {
let digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
let randomDigits = (0..<10).map { _ in return digits.ows_randomElement()! }
@ -499,11 +499,11 @@ struct CommonGenerator {
"At one time in the world there were woods that no one owned."
]
static var word: String {
static public var word: String {
return String(sentence.split(separator: " ").first!)
}
static func words(count: Int) -> String {
static public func words(count: Int) -> String {
var result: [String] = []
while result.count < count {
@ -514,20 +514,20 @@ struct CommonGenerator {
return result.joined(separator: " ")
}
static var sentence: String {
static public var sentence: String {
return sentences.ows_randomElement()!
}
static func sentences(count: UInt) -> [String] {
static public func sentences(count: UInt) -> [String] {
return (0..<count).map { _ in sentence }
}
static var paragraph: String {
static public var paragraph: String {
let sentenceCount = UInt(arc4random_uniform(7) + 2)
return paragraph(sentenceCount: sentenceCount)
}
static func paragraph(sentenceCount: UInt) -> String {
static public func paragraph(sentenceCount: UInt) -> String {
return sentences(count: sentenceCount).joined(separator: " ")
}
}

Loading…
Cancel
Save