YapDatabase/Testing/UnitTesting/TestYapDatabaseSearchResultsView.m
2014-05-16 18:04:00 -07:00

457 lines
17 KiB
Objective-C

#import <XCTest/XCTest.h>
#import "YapDatabase.h"
#import "YapDatabaseView.h"
#import "YapDatabaseFullTextSearch.h"
#import "YapDatabaseSearchResultsView.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
@interface TestYapDatabaseSearchResultsView : XCTestCase
@end
@implementation TestYapDatabaseSearchResultsView
- (NSString *)databasePath:(NSString *)suffix
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *baseDir = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
NSString *databaseName = [NSString stringWithFormat:@"%@-%@.sqlite", THIS_FILE, suffix];
return [baseDir stringByAppendingPathComponent:databaseName];
}
- (void)setUp
{
[super setUp];
[DDLog removeAllLoggers];
[DDLog addLogger:[DDTTYLogger sharedInstance]];
}
- (void)tearDown
{
[DDLog flushLog];
[super tearDown];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark With ParentView
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)test1_parentView_memory_withoutSnippets
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
YapDatabaseSearchResultsViewOptions *searchViewOptions = [[YapDatabaseSearchResultsViewOptions alloc] init];
searchViewOptions.isPersistent = NO;
[self _test1_parentView_withPath:databasePath options:searchViewOptions];
}
- (void)test1_parentView_memory_withSnippets
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
YapDatabaseFullTextSearchSnippetOptions *snippetOptions = [[YapDatabaseFullTextSearchSnippetOptions alloc] init];
snippetOptions.numberOfTokens = 5;
YapDatabaseSearchResultsViewOptions *searchViewOptions = [[YapDatabaseSearchResultsViewOptions alloc] init];
searchViewOptions.isPersistent = NO;
searchViewOptions.snippetOptions = snippetOptions;
[self _test1_parentView_withPath:databasePath options:searchViewOptions];
}
- (void)test1_parentView_persistent_withoutSnippets
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
YapDatabaseSearchResultsViewOptions *searchViewOptions = [[YapDatabaseSearchResultsViewOptions alloc] init];
searchViewOptions.isPersistent = YES;
[self _test1_parentView_withPath:databasePath options:searchViewOptions];
}
- (void)test1_parentView_persistent_withSnippets
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
YapDatabaseFullTextSearchSnippetOptions *snippetOptions = [[YapDatabaseFullTextSearchSnippetOptions alloc] init];
snippetOptions.numberOfTokens = 5;
YapDatabaseSearchResultsViewOptions *searchViewOptions = [[YapDatabaseSearchResultsViewOptions alloc] init];
searchViewOptions.isPersistent = YES;
searchViewOptions.snippetOptions = snippetOptions;
[self _test1_parentView_withPath:databasePath options:searchViewOptions];
}
- (void)_test1_parentView_withPath:(NSString *)databasePath
options:(YapDatabaseSearchResultsViewOptions *)searchViewOptions
{
[[NSFileManager defaultManager] removeItemAtPath:databasePath error:NULL];
YapDatabase *database = [[YapDatabase alloc] initWithPath:databasePath];
XCTAssertNotNil(database, @"Oops");
// Setup ParentView
YapDatabaseViewBlockType groupingBlockType;
YapDatabaseViewGroupingWithKeyBlock groupingBlock;
YapDatabaseViewBlockType sortingBlockType;
YapDatabaseViewSortingWithObjectBlock sortingBlock;
groupingBlockType = YapDatabaseViewBlockTypeWithKey;
groupingBlock = ^NSString *(NSString *collection, NSString *key)
{
return @"";
};
sortingBlockType = YapDatabaseViewBlockTypeWithObject;
sortingBlock = ^(NSString *group, NSString *collection1, NSString *key1, id obj1,
NSString *collection2, NSString *key2, id obj2)
{
__unsafe_unretained NSString *str1 = (NSString *)obj1;
__unsafe_unretained NSString *str2 = (NSString *)obj2;
return [str1 compare:str2 options:NSLiteralSearch];
};
YapDatabaseViewOptions *viewOptions = [[YapDatabaseViewOptions alloc] init];
viewOptions.isPersistent = NO;
YapDatabaseView *view =
[[YapDatabaseView alloc] initWithGroupingBlock:groupingBlock
groupingBlockType:groupingBlockType
sortingBlock:sortingBlock
sortingBlockType:sortingBlockType
versionTag:@"1"
options:viewOptions];
BOOL registerResult1 = [database registerExtension:view withName:@"order"];
XCTAssertTrue(registerResult1, @"Failure registering view extension");
// Setup FTS
YapDatabaseFullTextSearchBlockType blockType = YapDatabaseFullTextSearchBlockTypeWithObject;
YapDatabaseFullTextSearchWithObjectBlock block =
^(NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
[dict setObject:object forKey:@"content"];
};
YapDatabaseFullTextSearch *fts =
[[YapDatabaseFullTextSearch alloc] initWithColumnNames:@[@"content"]
block:block
blockType:blockType
versionTag:@"1"];
BOOL registerResult2 = [database registerExtension:fts withName:@"fts"];
XCTAssertTrue(registerResult2, @"Failure registering fts extension");
// Setup SearchResultsView
YapDatabaseSearchResultsView *searchResultsView =
[[YapDatabaseSearchResultsView alloc] initWithFullTextSearchName:@"fts"
parentViewName:@"order"
versionTag:@"1"
options:searchViewOptions];
BOOL registerResult3 = [database registerExtension:searchResultsView withName:@"searchResults"];
XCTAssertTrue(registerResult3, @"Failure registering searchResults extension");
// Add a bunch of values to the database
YapDatabaseConnection *connection1 = [database newConnection];
YapDatabaseConnection *connection2 = [database newConnection];
connection1.name = @"connection1";
connection2.name = @"connection2";
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
NSArray *phrases = @[
@"The duck quacks at midnight",
@"You take the red pill, you stay in Wonderland, and I show you how deep the rabbit hole goes.",
@"I am a fire gasoline. Come pour yourself all over me.",
@"I am enjoying my coffee.",
@"Are you gonna stay the night?",
@"What it is hoe? What's up?",
@"If Jimmy cracks corn and no one cares, then why does he keep doing it?"
];
NSUInteger i = 0;
for (NSString *phrase in phrases)
{
NSString *key = [NSString stringWithFormat:@"%lu", (unsigned long)i];
[transaction setObject:phrase forKey:key inCollection:nil];
i++;
}
// [[transaction ext:@"order"] enumerateKeysAndObjectsInGroup:@""
// usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop)
// {
// NSLog(@"Normal view: %lu : %@", (unsigned long)index, object);
// }];
// [[transaction ext:@"searchResults"] enumerateKeysAndObjectsInGroup:@""
// usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop)
// {
// NSLog(@"Search view: %lu : %@", (unsigned long)index, object);
// }];
NSUInteger count = 0;
count = [[transaction ext:@"order"] numberOfItemsInGroup:@""];
XCTAssertTrue(count == 7, @"Bad count: %lu", (unsigned long)count);
count = [[transaction ext:@"searchResults"] numberOfItemsInGroup:@""];
XCTAssertTrue(count == 0, @"Bad count: %lu", (unsigned long)count);
}];
NSString *query = @"the";
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[[transaction ext:@"searchResults"] performSearchFor:query];
[[transaction ext:@"searchResults"] enumerateKeysAndObjectsInGroup:@""
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop)
{
// NSLog(@"Search view: %lu : %@", (unsigned long)index, object);
if (searchViewOptions.snippetOptions)
{
NSString *snippet = [[transaction ext:@"searchResults"] snippetForKey:key inCollection:collection];
// NSLog(@" snippet: %lu : %@", (unsigned long)index, snippet);
XCTAssertNotNil(snippet, @"Expected a snippet");
}
}];
NSUInteger count = 0;
count = [[transaction ext:@"searchResults"] numberOfItemsInGroup:@""];
XCTAssertTrue(count == 3, @"Bad count: %lu", (unsigned long)count);
}];
[connection1 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
NSString *connectionQuery = [[transaction ext:@"searchResults"] query];
XCTAssertTrue([connectionQuery isEqualToString:query], @"Oops");
}];
[connection2 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
NSString *connectionQuery = [[transaction ext:@"searchResults"] query];
XCTAssertTrue([connectionQuery isEqualToString:query], @"Oops");
}];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark With Blocks
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)test1_blocks_memory_withoutSnippets
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
YapDatabaseSearchResultsViewOptions *searchViewOptions = [[YapDatabaseSearchResultsViewOptions alloc] init];
searchViewOptions.isPersistent = NO;
[self _test1_blocks_withPath:databasePath options:searchViewOptions];
}
- (void)test1_blocks_memory_withSnippets
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
YapDatabaseFullTextSearchSnippetOptions *snippetOptions = [[YapDatabaseFullTextSearchSnippetOptions alloc] init];
snippetOptions.numberOfTokens = 5;
YapDatabaseSearchResultsViewOptions *searchViewOptions = [[YapDatabaseSearchResultsViewOptions alloc] init];
searchViewOptions.isPersistent = NO;
searchViewOptions.snippetOptions = snippetOptions;
[self _test1_blocks_withPath:databasePath options:searchViewOptions];
}
- (void)test1_blocks_persistent_withoutSnippets
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
YapDatabaseSearchResultsViewOptions *searchViewOptions = [[YapDatabaseSearchResultsViewOptions alloc] init];
searchViewOptions.isPersistent = YES;
[self _test1_blocks_withPath:databasePath options:searchViewOptions];
}
- (void)test1_blocks_persistent_withSnippets
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
YapDatabaseFullTextSearchSnippetOptions *snippetOptions = [[YapDatabaseFullTextSearchSnippetOptions alloc] init];
snippetOptions.numberOfTokens = 5;
YapDatabaseSearchResultsViewOptions *searchViewOptions = [[YapDatabaseSearchResultsViewOptions alloc] init];
searchViewOptions.isPersistent = YES;
searchViewOptions.snippetOptions = snippetOptions;
[self _test1_blocks_withPath:databasePath options:searchViewOptions];
}
- (void)_test1_blocks_withPath:(NSString *)databasePath
options:(YapDatabaseSearchResultsViewOptions *)searchViewOptions
{
[[NSFileManager defaultManager] removeItemAtPath:databasePath error:NULL];
YapDatabase *database = [[YapDatabase alloc] initWithPath:databasePath];
XCTAssertNotNil(database, @"Oops");
// Setup FTS
YapDatabaseFullTextSearchBlockType blockType = YapDatabaseFullTextSearchBlockTypeWithObject;
YapDatabaseFullTextSearchWithObjectBlock block =
^(NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
[dict setObject:object forKey:@"content"];
};
YapDatabaseFullTextSearch *fts =
[[YapDatabaseFullTextSearch alloc] initWithColumnNames:@[@"content"]
block:block
blockType:blockType
versionTag:@"1"];
BOOL registerResult1 = [database registerExtension:fts withName:@"fts"];
XCTAssertTrue(registerResult1, @"Failure registering fts extension");
// Setup SearchResultsView
YapDatabaseViewBlockType groupingBlockType;
YapDatabaseViewGroupingWithKeyBlock groupingBlock;
YapDatabaseViewBlockType sortingBlockType;
YapDatabaseViewSortingWithObjectBlock sortingBlock;
groupingBlockType = YapDatabaseViewBlockTypeWithKey;
groupingBlock = ^NSString *(NSString *collection, NSString *key)
{
return @"";
};
sortingBlockType = YapDatabaseViewBlockTypeWithObject;
sortingBlock = ^(NSString *group, NSString *collection1, NSString *key1, id obj1,
NSString *collection2, NSString *key2, id obj2)
{
__unsafe_unretained NSString *str1 = (NSString *)obj1;
__unsafe_unretained NSString *str2 = (NSString *)obj2;
return [str1 compare:str2 options:NSLiteralSearch];
};
YapDatabaseSearchResultsView *searchResultsView =
[[YapDatabaseSearchResultsView alloc] initWithFullTextSearchName:@"fts"
groupingBlock:groupingBlock
groupingBlockType:groupingBlockType
sortingBlock:sortingBlock
sortingBlockType:sortingBlockType
versionTag:@"1"
options:searchViewOptions];
BOOL registerResult2 = [database registerExtension:searchResultsView withName:@"searchResults"];
XCTAssertTrue(registerResult2, @"Failure registering searchResults extension");
// Add a bunch of values to the database
YapDatabaseConnection *connection1 = [database newConnection];
YapDatabaseConnection *connection2 = [database newConnection];
connection1.name = @"connection1";
connection2.name = @"connection2";
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
NSArray *phrases = @[
@"The duck quacks at midnight",
@"You take the red pill, you stay in Wonderland, and I show you how deep the rabbit hole goes.",
@"I am a fire gasoline. Come pour yourself all over me.",
@"I am enjoying my coffee.",
@"Are you gonna stay the night?",
@"What it is hoe? What's up?",
@"If Jimmy cracks corn and no one cares, then why does he keep doing it?"
];
NSUInteger i = 0;
for (NSString *phrase in phrases)
{
NSString *key = [NSString stringWithFormat:@"%lu", (unsigned long)i];
[transaction setObject:phrase forKey:key inCollection:nil];
i++;
}
// [[transaction ext:@"order"] enumerateKeysAndObjectsInGroup:@""
// usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop)
// {
// NSLog(@"Normal view: %lu : %@", (unsigned long)index, object);
// }];
// [[transaction ext:@"searchResults"] enumerateKeysAndObjectsInGroup:@""
// usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop)
// {
// NSLog(@"Search view: %lu : %@", (unsigned long)index, object);
// }];
NSUInteger count = 0;
count = [[transaction ext:@"searchResults"] numberOfItemsInGroup:@""];
XCTAssertTrue(count == 0, @"Bad count: %lu", (unsigned long)count);
}];
NSString *query = @"the";
[connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[[transaction ext:@"searchResults"] performSearchFor:query];
[[transaction ext:@"searchResults"] enumerateKeysAndObjectsInGroup:@""
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop)
{
// NSLog(@"Search view: %lu : %@", (unsigned long)index, object);
if (searchViewOptions.snippetOptions)
{
NSString *snippet = [[transaction ext:@"searchResults"] snippetForKey:key inCollection:collection];
// NSLog(@" snippet: %lu : %@", (unsigned long)index, snippet);
XCTAssertNotNil(snippet, @"Expected a snippet");
}
}];
NSUInteger count = 0;
count = [[transaction ext:@"searchResults"] numberOfItemsInGroup:@""];
XCTAssertTrue(count == 3, @"Bad count: %lu", (unsigned long)count);
}];
[connection1 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
NSString *connectionQuery = [[transaction ext:@"searchResults"] query];
XCTAssertTrue([connectionQuery isEqualToString:query], @"Oops");
}];
[connection2 readWithBlock:^(YapDatabaseReadTransaction *transaction) {
NSString *connectionQuery = [[transaction ext:@"searchResults"] query];
XCTAssertTrue([connectionQuery isEqualToString:query], @"Oops");
}];
}
@end