aboutsummaryrefslogtreecommitdiffstats
path: root/UnitTests
diff options
context:
space:
mode:
authorMax <post@wickenrode.com>2015-03-07 20:48:55 +0100
committerMax <post@wickenrode.com>2015-03-07 20:48:55 +0100
commit96b765ffbcb6c7fda058fbe8028b2e128007134a (patch)
treea4ac6c9fb75b5b810f7c42f1d159937caa6c2dda /UnitTests
parented38f229a052a678d3a5022afd3806b1c3b434cf (diff)
downloadsequelpro-96b765ffbcb6c7fda058fbe8028b2e128007134a.tar.gz
sequelpro-96b765ffbcb6c7fda058fbe8028b2e128007134a.tar.bz2
sequelpro-96b765ffbcb6c7fda058fbe8028b2e128007134a.zip
Added an internal algorithm for fuzzy string matching
* This works similar to a regex matching "abc" as /a.*b.*c/ (ie. all characters of $needle need to be contained in $haystack in the correct order but not neccesarily consecutive). Additionaly some unicode equivalencies are handled. * Changed a tiny helper function from ObjC to plain C
Diffstat (limited to 'UnitTests')
-rw-r--r--UnitTests/SPStringAdditionsTests.h1
-rw-r--r--UnitTests/SPStringAdditionsTests.m69
2 files changed, 70 insertions, 0 deletions
diff --git a/UnitTests/SPStringAdditionsTests.h b/UnitTests/SPStringAdditionsTests.h
index d6854dbe..56b5c6f9 100644
--- a/UnitTests/SPStringAdditionsTests.h
+++ b/UnitTests/SPStringAdditionsTests.h
@@ -35,5 +35,6 @@
- (void)testStringByRemovingCharactersInSet;
- (void)testStringWithNewUUID;
- (void)testCreateViewSyntaxPrettifier;
+- (void)testNonConsecutivelySearchStringMatchingRanges;
@end
diff --git a/UnitTests/SPStringAdditionsTests.m b/UnitTests/SPStringAdditionsTests.m
index af22df77..f455066f 100644
--- a/UnitTests/SPStringAdditionsTests.m
+++ b/UnitTests/SPStringAdditionsTests.m
@@ -86,4 +86,73 @@
STAssertEqualObjects([actualSyntax description], [expectedSyntax description], @"Actual view syntax '%@' does not equal expected syntax '%@'", actualSyntax, expectedSyntax);
}
+- (void)testNonConsecutivelySearchStringMatchingRanges
+{
+ //basic tests
+ {
+ NSArray *matches = nil;
+ STAssertTrue([@"" nonConsecutivelySearchString:@"" matchingRanges:&matches], @"Equality of empty strings");
+ STAssertTrue(([matches count] == 1) && NSEqualRanges(NSMakeRange(0, 0), [(NSValue *)[matches objectAtIndex:0] rangeValue]), @"Returned matches in empty string");
+ }
+
+ {
+ NSArray *matches = (void *)0xdeadbeef;
+ STAssertFalse([@"" nonConsecutivelySearchString:@"R" matchingRanges:&matches], @"Inequality with empty left side");
+ STAssertTrue((matches == (void *)0xdeadbeef), @"out variable not touched by mismatch");
+ }
+
+ STAssertFalse([@"L" nonConsecutivelySearchString:@"" matchingRanges:NULL], @"Inequality with empty right side");
+
+ {
+ NSArray *matches = nil;
+ STAssertTrue([@"left" nonConsecutivelySearchString:@"le" matchingRanges:&matches], @"Anchored match left");
+ STAssertTrue(([matches count] == 1) && NSEqualRanges(NSMakeRange(0, 2), [(NSValue *)[matches objectAtIndex:0] rangeValue]), @"Returned matches in anchored left match");
+ }
+
+ {
+ NSArray *matches = nil;
+ STAssertTrue([@"right" nonConsecutivelySearchString:@"ht" matchingRanges:&matches], @"Anchored match right");
+ STAssertTrue(([matches count] == 1) && NSEqualRanges(NSMakeRange(3, 2), [(NSValue *)[matches objectAtIndex:0] rangeValue]), @"Returned matches in anchroed right match");
+ }
+
+ STAssertFalse([@"ht" nonConsecutivelySearchString:@"right" matchingRanges:NULL], @"Left and Right are not commutative");
+
+ //real tests
+ {
+ NSArray *matches = nil;
+ STAssertTrue([@"... is not secure anymore!" nonConsecutivelySearchString:@"NSA" matchingRanges:&matches], @"Non-consecutive match, ignoring case");
+ STAssertTrue(([matches count] == 3) &&
+ (NSEqualRanges(NSMakeRange(7, 1), [(NSValue *)[matches objectAtIndex:0] rangeValue])) &&
+ (NSEqualRanges(NSMakeRange(11, 1), [(NSValue *)[matches objectAtIndex:1] rangeValue])) &&
+ (NSEqualRanges(NSMakeRange(18, 1), [(NSValue *)[matches objectAtIndex:2] rangeValue])), @"Returned matches in non-consecutive string");
+ }
+
+ STAssertFalse([@"Deoxyribonucleic Acid" nonConsecutivelySearchString:@"DNS" matchingRanges:NULL], @"Non-consecutive mismatch");
+
+ {
+ NSArray *matches = nil;
+ STAssertTrue([@"Turn left, then right at the corner" nonConsecutivelySearchString:@"left right" matchingRanges:&matches], @"Partly consecutive match");
+ STAssertTrue(([matches count] == 3) &&
+ (NSEqualRanges(NSMakeRange(5, 4), [(NSValue *)[matches objectAtIndex:0] rangeValue])) &&
+ (NSEqualRanges(NSMakeRange(10, 1), [(NSValue *)[matches objectAtIndex:1] rangeValue])) &&
+ (NSEqualRanges(NSMakeRange(16, 5), [(NSValue *)[matches objectAtIndex:2] rangeValue])), @"Returned matches in partly-consecutive string");
+ }
+
+ //advanced tests
+
+ // LATIN CAPITAL LETTER A == LATIN SMALL LETTER A
+ // LATIN SMALL LETTER O WITH DIAERESIS == LATIN SMALL LETTER O
+ // FULLWIDTH LATIN SMALL LETTER b == LATIN SMALL LETTER B
+ STAssertTrue([@"A:\xC3\xB6:\xEF\xBD\x82" nonConsecutivelySearchString:@"aob" matchingRanges:NULL], @"Fuzzy matching of defined characters");
+
+ //all bytes on the right are contained on the left, but on a character level "ä" is not contained in "Hütte Ф"
+ STAssertFalse([@"H\xC3\xBCtte \xD0\xA4" nonConsecutivelySearchString:@"\xC3\xA4" matchingRanges:NULL], @"Mismatch of composed characters with same prefix");
+
+ // ":😥:𠘄:" vs "😄" (according to wikipedia "𠘄" is the arachic variant of "印")
+ // TECHNICALLY THIS SHOULD NOT MATCH!
+ // However Apple doesn't correctly handle characters in the 4-Byte UTF range, so let's use this test to check for changes in Apples behaviour :)
+ STAssertTrue([@":\xF0\x9F\x98\x84:\xF0\xA0\x98\x84:" nonConsecutivelySearchString:@"\xF0\x9F\x98\x84" matchingRanges:NULL], @"Mismatch of composed characters (4-byte) with same prefix");
+
+}
+
@end