Skip to content

Commit b902703

Browse files
committed
Merge pull request #133 from ws233/master
More unit tests and improved return value for `moveTessdataToCachesDirectoryIfNecessary`.
2 parents 551238a + 30c2e87 commit b902703

File tree

2 files changed

+117
-48
lines changed

2 files changed

+117
-48
lines changed

TesseractOCR/G8Tesseract.mm

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ @interface G8Tesseract () {
3131
ETEXT_DESC *_monitor;
3232
}
3333

34-
@property (nonatomic, copy) NSString *absoluteDataPath;
3534
@property (nonatomic, strong) NSDictionary *configDictionary;
3635
@property (nonatomic, strong) NSArray *configFileNames;
3736
@property (nonatomic, strong) NSMutableDictionary *variables;
@@ -50,6 +49,8 @@ @interface G8Tesseract () {
5049

5150
@implementation G8Tesseract
5251

52+
@synthesize absoluteDataPath=_absoluteDataPath;
53+
5354
+ (NSString *)version
5455
{
5556
const char *version = tesseract::TessBaseAPI::Version();
@@ -112,7 +113,10 @@ - (id)initWithLanguage:(NSString *)language
112113

113114
_absoluteDataPath = [cachesPath stringByAppendingPathComponent:_absoluteDataPath].copy;
114115

115-
[self moveTessdataToCachesDirectoryIfNecessary];
116+
BOOL success = [self moveTessdataToCachesDirectoryIfNecessary];
117+
if (success == NO) {
118+
return nil;
119+
}
116120
}
117121
else {
118122
// config Tesseract to search trainedData in tessdata folder of the application bundle];
@@ -206,8 +210,8 @@ - (BOOL)moveTessdataToCachesDirectoryIfNecessary
206210

207211
if ([fileManager fileExistsAtPath:destinationPath] == NO) {
208212
NSError *error = nil;
209-
[fileManager createDirectoryAtPath:destinationPath withIntermediateDirectories:YES attributes:nil error:&error];
210-
if (error != nil) {
213+
BOOL res = [fileManager createDirectoryAtPath:destinationPath withIntermediateDirectories:YES attributes:nil error:&error];
214+
if (res == NO) {
211215
NSLog(@"Error creating folder %@: %@", destinationPath, error);
212216
return NO;
213217
}
@@ -216,30 +220,31 @@ - (BOOL)moveTessdataToCachesDirectoryIfNecessary
216220
BOOL result = YES;
217221
NSError *error = nil;
218222
NSArray *files = [fileManager contentsOfDirectoryAtPath:tessdataPath error:&error];
219-
if (error != nil) {
223+
if (files == nil) {
220224
NSLog(@"ERROR! %@", error.description);
221225
result = NO;
222-
}
223-
for (NSString *filename in files) {
224-
225-
NSString *destinationFileName = [destinationPath stringByAppendingPathComponent:filename];
226-
if (![fileManager fileExistsAtPath:destinationFileName]) {
226+
} else {
227+
for (NSString *filename in files) {
227228

228-
NSString *filePath = [tessdataPath stringByAppendingPathComponent:filename];
229-
//NSLog(@"found %@", filePath);
230-
//NSLog(@"symlink in %@", destinationFileName);
231-
232-
// delete broken symlinks first
233-
[fileManager removeItemAtPath:destinationFileName error:&error];
234-
235-
// than recreate it
236-
error = nil; // don't care about previous error, that can happens if we tried to remove an symlink, which doesn't exist
237-
[fileManager createSymbolicLinkAtPath:destinationFileName
238-
withDestinationPath:filePath
239-
error:&error];
240-
if (error != nil) {
241-
NSLog(@"Error creating symlink %@: %@", destinationPath, error);
242-
result = NO;
229+
NSString *destinationFileName = [destinationPath stringByAppendingPathComponent:filename];
230+
if (![fileManager fileExistsAtPath:destinationFileName]) {
231+
232+
NSString *filePath = [tessdataPath stringByAppendingPathComponent:filename];
233+
//NSLog(@"found %@", filePath);
234+
//NSLog(@"symlink in %@", destinationFileName);
235+
236+
// delete broken symlinks first
237+
[fileManager removeItemAtPath:destinationFileName error:&error];
238+
239+
// than recreate it
240+
error = nil; // don't care about previous error, that can happens if we tried to remove a symlink, which doesn't exist
241+
BOOL res = [fileManager createSymbolicLinkAtPath:destinationFileName
242+
withDestinationPath:filePath
243+
error:&error];
244+
if (res == NO) {
245+
NSLog(@"Error creating symlink %@: %@", destinationPath, error);
246+
result = NO;
247+
}
243248
}
244249
}
245250
}

TestsProject/TestsProjectTests/InitializationTests.m

Lines changed: 87 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#import <Kiwi/Kiwi.h>
1313
#import "Defaults.h"
1414

15+
@interface G8Tesseract (Tests)
16+
- (BOOL)configEngine;
17+
- (BOOL)resetEngine;
18+
@end
19+
1520
SPEC_BEGIN(TesseractInitialization)
1621

1722
describe(@"Tesseract initialization", ^{
@@ -43,6 +48,13 @@
4348
[[recognizedText should] equal:@"1234567890\n\n"];
4449
};
4550

51+
context(@"Should check common function", ^{
52+
53+
it(@"Should check version", ^{
54+
[[[G8Tesseract version] should] equal:@"3.03"];
55+
});
56+
});
57+
4658
context(@"nil cachesRelatedDataPath", ^{
4759

4860
it(@"Should initialize simple", ^{
@@ -51,6 +63,27 @@
5163
[[tesseract shouldNot] beNil];
5264

5365
[[tesseract.absoluteDataPath should] equal:resourcePath];
66+
67+
tesseract = [G8Tesseract alloc];
68+
[[tesseract shouldNot] beNil];
69+
NSAssert([tesseract respondsToSelector:@selector(configEngine)] == YES, @"Error! G8Tesseract instance does not contain configEngine selector");
70+
[[tesseract should] receive:@selector(configEngine) andReturn:theValue(NO)];
71+
tesseract = [tesseract init];
72+
73+
[[tesseract should] beNil];
74+
75+
tesseract = [[G8Tesseract alloc] init];
76+
NSAssert([tesseract respondsToSelector:@selector(resetEngine)] == YES, @"Error! G8Tesseract instance does not contain resetEngine selector");
77+
[[tesseract should] receive:@selector(configEngine) andReturn:theValue(NO)];
78+
[[theValue([tesseract resetEngine]) should] beNo];
79+
});
80+
81+
it(@"Should initialize simple with engine mode", ^{
82+
[[fileManager shouldNot] receive:@selector(createSymbolicLinkAtPath:withDestinationPath:error:)];
83+
G8Tesseract *tesseract = [[G8Tesseract alloc] initWithLanguage:kG8Languages engineMode:G8OCREngineModeTesseractOnly];
84+
[[tesseract shouldNot] beNil];
85+
86+
[[tesseract.absoluteDataPath should] equal:resourcePath];
5487
});
5588

5689
NSString *debugConfigsFilePathFromTheBundle = [[tessdataFolderPathFromTheBundle stringByAppendingPathComponent:tessConfigsFolderName] stringByAppendingPathComponent:debugConfigsFileName];
@@ -114,22 +147,66 @@
114147
checkVariablesAreSetForTesseract(tesseract);
115148
});
116149
});
117-
150+
118151
NSArray *cachesPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
119152
NSString *cachesPath = cachesPaths.firstObject;
120153
NSString *tessdataPath = @"foo/bar";
121154
NSString *cachesTessDataPath = [cachesPath stringByAppendingPathComponent:tessdataPath];
155+
156+
void(^cleanTessdataFolder)() = ^{
157+
//NSLog(@"Removing previous tessdata folder from Caches folder");
158+
NSError *error = nil;
159+
BOOL fileIsRemoved = [fileManager removeItemAtPath:cachesTessDataPath error:&error];
160+
if (error != nil) {
161+
NSLog(@"Error deleting tessdata folder from the Caches folder: %@", error);
162+
}
163+
NSAssert(fileIsRemoved == YES, @"Error cleaning tessdata from the Caches folder");
164+
165+
// check tessdata folder was deleted
166+
NSArray *cachesContent = [fileManager contentsOfDirectoryAtPath:cachesPath error:&error];
167+
if (error != nil) {
168+
NSLog(@"Error getting the contents of the Caches folder: %@", error);
169+
}
170+
NSAssert([cachesContent containsObject:tessdataPath] == NO, @"Assert! Tessdata path was not removed from the Caches folder");
171+
};
172+
173+
context(@"moveTessdataToCachesDirectoryIfNecessary", ^{
174+
175+
void (^checkInitializationWithFailedSelectorReturnValueAndCount)(SEL selector, id returnValue, int count) = ^(SEL selector, id returnValue, int count){
176+
G8Tesseract *wrongTesseract = [G8Tesseract alloc];
177+
[[wrongTesseract shouldNot] beNil];
178+
[[[NSFileManager defaultManager] should] receive:selector andReturn:returnValue withCount:count];
179+
wrongTesseract = [wrongTesseract initWithLanguage:kG8Languages configDictionary:nil configFileNames:nil cachesRelatedDataPath:tessdataPath engineMode:G8OCREngineModeTesseractOnly];
180+
[[wrongTesseract should] beNil];
181+
};
182+
183+
it(@"Should return nil if createDirectoryAtPath fails", ^{
184+
checkInitializationWithFailedSelectorReturnValueAndCount(@selector(createDirectoryAtPath:withIntermediateDirectories:attributes:error:), theValue(NO), 1);
185+
});
186+
187+
it(@"Should return nil if createSymbolicLinkAtPath fails", ^{
188+
NSError *error = nil;
189+
NSArray *contentsOfTessdataFromTheBundle = [fileManager contentsOfDirectoryAtPath:tessdataFolderPathFromTheBundle error:&error];
190+
NSAssert (error == nil, @"Error getting the content of the Tessdata folder from the app bundle: %@", error);
122191

192+
checkInitializationWithFailedSelectorReturnValueAndCount(@selector(createSymbolicLinkAtPath:withDestinationPath:error:), theValue(NO), contentsOfTessdataFromTheBundle.count);
193+
cleanTessdataFolder();
194+
});
195+
196+
it(@"Should return nil if contentsOfDirectoryAtPath fails", ^{
197+
checkInitializationWithFailedSelectorReturnValueAndCount(@selector(contentsOfDirectoryAtPath:error:), nil, 2);
198+
cleanTessdataFolder();
199+
});
200+
});
201+
123202
context(@"not nil cachesRelatedDataPath", ^{
124203

125204
// helper
126205
BOOL (^doFoldersContainTheSameElements)(void) = ^(void){
127206
NSError *error = nil;
128207
NSArray *contentsOfTessdataFromTheBundle = [fileManager contentsOfDirectoryAtPath:tessdataFolderPathFromTheBundle error:&error];
129-
[[contentsOfTessdataFromTheBundle should] haveCountOfAtLeast:1];
130-
if (error != nil) {
131-
NSLog(@"Error getting the content of the Tessdata folder from the app bundle: %@", error);
132-
}
208+
NSAssert(contentsOfTessdataFromTheBundle.count >= 1, @"Error! Tessdata folder is empty");
209+
NSAssert(error == nil, @"Error getting the content of the Tessdata folder from the app bundle: %@", error);
133210

134211
NSArray *contentsOfTheTessdataPathFolder = [fileManager contentsOfDirectoryAtPath:[cachesTessDataPath stringByAppendingPathComponent:tessdataFolderName] error:&error];
135212
[[contentsOfTheTessdataPathFolder should] haveCountOfAtLeast:1];
@@ -148,7 +225,7 @@
148225
it(@"Should simple init, download rus language files and reinitialize tess with them", ^{
149226
// proof Caches folder is empty
150227
BOOL folderExists = [fileManager fileExistsAtPath:cachesTessDataPath];
151-
[[theValue(folderExists) should] beNo];
228+
NSAssert(folderExists == NO, @"Error! Tessdata folder is already here: %@", cachesTessDataPath);
152229

153230
G8Tesseract *tesseract = [[G8Tesseract alloc] initWithLanguage:kG8Languages
154231
configDictionary:nil
@@ -196,7 +273,7 @@
196273
});
197274

198275
it(@"Should initialize with config dictionary", ^{
199-
276+
200277
G8Tesseract *tesseract = [[G8Tesseract alloc] initWithLanguage:kG8Languages
201278
configDictionary:@{
202279
kG8ParamTessdataManagerDebugLevel : @"1",
@@ -235,8 +312,8 @@
235312

236313
it(@"Should initialize with 2 config files", ^{
237314

238-
[[[fileManager attributesOfItemAtPath:debugConfigsFilePathFromTheCaches error:nil] should] beNil];
239-
[[[fileManager attributesOfItemAtPath:recognitionConfigsFilePathFromTheCaches error:nil] should] beNil];
315+
NSAssert([fileManager attributesOfItemAtPath:debugConfigsFilePathFromTheCaches error:nil] == nil, @"Error! %@ is already here!", debugConfigsFilePathFromTheCaches);
316+
NSAssert([fileManager attributesOfItemAtPath:recognitionConfigsFilePathFromTheCaches error:nil] == nil, @"Error! %@ cannot is already here!", recognitionConfigsFilePathFromTheCaches);
240317

241318
G8Tesseract *tesseract = [[G8Tesseract alloc] initWithLanguage:kG8Languages
242319
configDictionary:nil
@@ -380,20 +457,7 @@
380457
});
381458

382459
afterEach(^{
383-
//NSLog(@"Removing previous tessdata folder from Caches folder");
384-
NSError *error = nil;
385-
BOOL fileIsRemoved = [fileManager removeItemAtPath:cachesTessDataPath error:&error];
386-
if (error != nil) {
387-
NSLog(@"Error deleting tessdata folder from the Caches folder: %@", error);
388-
}
389-
NSAssert(fileIsRemoved == YES, @"Error cleaning tessdata from the Caches folder");
390-
391-
// check tessdata folder was deleted
392-
NSArray *cachesContent = [fileManager contentsOfDirectoryAtPath:cachesPath error:&error];
393-
if (error != nil) {
394-
NSLog(@"Error getting the contents of the Caches folder: %@", error);
395-
}
396-
NSAssert([cachesContent containsObject:tessdataPath] == NO, @"Assert! Tessdata path was not removed from the Caches folder");
460+
cleanTessdataFolder();
397461
});
398462
});
399463
});

0 commit comments

Comments
 (0)