File: general.m

package info (click to toggle)
gnustep-base 1.31.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 26,580 kB
  • sloc: objc: 239,446; ansic: 36,519; cpp: 122; sh: 112; makefile: 100; xml: 32
file content (452 lines) | stat: -rw-r--r-- 17,563 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
#import "Testing.h"
#import "ObjectTesting.h"
#import <Foundation/Foundation.h>

#ifdef  EQ
#undef  EQ
#endif
#define EPSILON (DBL_EPSILON*100)
#define EQ(x,y) ((x >= y - EPSILON) && (x <= y + EPSILON))

@interface      MyHandler : NSObject
{
  @public
  NSString      *path;
  NSError       *error;
}
- (BOOL) fileManager: (NSFileManager*)m shouldProceedAfterError: (NSError*)e;
- (void) fileManager: (NSFileManager*)m willProcessPath: (NSString*)p;
- (void) reset;
@end

@implementation MyHandler
- (void) dealloc
{
  [self reset];
  [super dealloc];
}

- (BOOL) fileManager: (NSFileManager*)m shouldProceedAfterError: (NSError*)e
{
  ASSIGN(error, e);
  return NO;
}

- (void) fileManager: (NSFileManager*)m willProcessPath: (NSString*)p
{
  ASSIGN(path, p);
}

- (void) reset
{
  DESTROY(path);
  DESTROY(error);
}
@end

int main()
{
  NSAutoreleasePool   	*arp = [NSAutoreleasePool new];
  NSFileManager		*mgr = [NSFileManager defaultManager];
  NSString 		*dir = @"NSFileManagerTestDir"; 
  MyHandler 		*handler = AUTORELEASE([MyHandler new]);
  NSDictionary 		*attr;
  NSString 		*dirInDir;
  NSString 		*str1;
  NSString 		*str2;
  NSMutableString	*mstr;
  NSString 		*tmp;
  NSError 		*err;
  NSDictionary 		*errInfo;
  BOOL 			exists;
  BOOL 			isDir;

  dirInDir = [dir stringByAppendingPathComponent: @"WithinDirectory"];

  PASS(mgr != nil && [mgr isKindOfClass: [NSFileManager class]],
       "NSFileManager understands +defaultManager");

  /* remove test directory if it exists */
  exists = [mgr fileExistsAtPath: dir isDirectory: &isDir];
  if (exists)
    {
      [mgr removeFileAtPath: dir handler: handler];
    }
  PASS([mgr fileAttributesAtPath: dir traverseLink: NO] == nil,
    "NSFileManager returns nil for attributes of non-existent file");

  PASS([mgr createDirectoryAtPath: dir attributes: nil],
       "NSFileManager can create a directory");
  PASS([mgr fileExistsAtPath: dir isDirectory: &isDir] &&
       isDir == YES,
       "exists and is a directory");
  PASS(NO == [mgr createDirectoryAtPath: dir attributes: nil],
       "-createDirectoryAtPath:attributes: fails for existing directory");
  PASS(NO == [mgr createDirectoryAtPath: dir withIntermediateDirectories: NO
    attributes: nil error: 0],
   "-createDirectoryAtPath:withIntermediateDirectories:attributes:error:"
    " fails for existing directory if flag is NO");

  PASS(YES == [mgr createDirectoryAtPath: dir withIntermediateDirectories: YES
    attributes: nil error: 0],
   "-createDirectoryAtPath:withIntermediateDirectories:attributes:error:"
    " succeeds for existing directory if flag is YES");

  PASS([mgr fileAttributesAtPath: dir traverseLink: NO] != nil,
    "NSFileManager returns non-nil for attributes of existing file");
  attr = [mgr fileAttributesAtPath: dir traverseLink: NO];
  PASS(attr != nil,
    "NSFileManager returns non-nil for attributes of existing file");
  PASS([NSUserName() isEqual: [attr fileOwnerAccountName]],
    "newly created file is owned by current user");
//NSLog(@"'%@', '%@'", NSUserName(), [attr fileOwnerAccountName]);
  err = (id)(void*)42;
  attr = [mgr attributesOfItemAtPath: dir error: &err]; 
  PASS(attr != nil && err == (id)(void*)42, 
    "[NSFileManager attributesOfItemAtPath:error:] returns non-nil for "
    "attributes and leaves error unchanged in the case of existing file"); 
  attr = [mgr attributesOfItemAtPath:
    [dir stringByAppendingPathComponent:
      @"thispathMUSTNOTexistatyoursystem"] error: &err]; 
  PASS(attr == nil && err != nil, 
    "[NSFileManager attributesOfItemAtPath:error:] returns nil for "
    "attributes and non-nil for error in the case of non-existent file"); 
  
  PASS([mgr changeCurrentDirectoryPath: dir],
       "NSFileManager can change directories");
  
  
  {
    NSString *dir1 = [mgr currentDirectoryPath];
    PASS(dir1 != nil && [[dir1 lastPathComponent] isEqualToString: dir],
         "NSFileManager can get current dir");
  }
  
  PASS([mgr createFileAtPath: @"NSFMFile" 
                    contents: [NSData data]
		  attributes: nil],
       "NSFileManager creates an empty file")
  PASS([mgr fileExistsAtPath: @"NSFMFile"],"-fileExistsAtPath: agrees")
  str1 = [NSString stringWithContentsOfFile: @"NSFMFile"];
  PASS_EQUAL(str1, @"", "empty file produces empty string")
  mstr = [NSMutableString stringWithContentsOfFile: @"NSFMFile"];
  PASS([mstr isKindOfClass: [NSMutableString class]] && [mstr isEqual: @""],
    "empty file produces empty mutable string")
  PASS([mgr removeFileAtPath: @"NSFMFile" handler: handler], 
    "NSFileManager removes an empty file")

  str1 = @"A string";
  PASS([mgr createFileAtPath: @"NSFMFile" 
                    contents: [str1 dataUsingEncoding: 1]
		  attributes: nil],
       "NSFileManager creates a file");
  PASS([mgr fileExistsAtPath: @"NSFMFile"],"-fileExistsAtPath: agrees");
  
  {
    NSArray	*a;

    a = [mgr contentsOfDirectoryAtPath: @"." error: 0];
    PASS(1 == [a count] && [[a lastObject] isEqual: @"NSFMFile"],
      "-contentsOfDirectoryAtPath: agrees");
  }

  {
    NSArray	*a;
    NSString *dir1 = [mgr currentDirectoryPath];

    [mgr changeCurrentDirectoryPath: [dir1 stringByDeletingLastPathComponent]];
    a = [mgr contentsOfDirectoryAtPath: dir error: 0];
    PASS(1 == [a count] && [[a lastObject] isEqual: @"NSFMFile"],
      "-contentsOfDirectoryAtPath: agrees with different current directory");
    [mgr changeCurrentDirectoryPath: dir1];
  }

  {
    NSArray	*a;
    NSString *dir1 = [mgr currentDirectoryPath];
    NSURL *dirURL = [NSURL fileURLWithPath: dir1];
    NSURL *fileURL = [dirURL URLByAppendingPathComponent: @"NSFMFile"];

    [mgr changeCurrentDirectoryPath: [dir1 stringByDeletingLastPathComponent]];
    a = [mgr contentsOfDirectoryAtURL: dirURL includingPropertiesForKeys: nil
                              options: 0 error: NULL];
    PASS(1 == [a count] && [[a lastObject] isEqual: fileURL],
      "-contentsOfDirectoryAtURL: agrees with different current directory");
    [mgr changeCurrentDirectoryPath: dir];
  }

  {
    NSData *dat1 = [mgr contentsAtPath: @"NSFMFile"];
    str2 = [[NSString alloc] initWithData: dat1 encoding: 1];
    PASS([str1 isEqualToString: str2], "NSFileManager file contents match");
    DESTROY(str2);
  }
  [NSThread sleepForTimeInterval: 1.0]; // So date of file is clearly in past
  [handler reset];
  PASS([mgr copyPath: @"NSFMFile"
              toPath: @"NSFMCopy"
	     handler: handler], 
       "NSFileManager copies a file");
  PASS([mgr fileExistsAtPath: @"NSFMCopy"],"-fileExistsAtPath: agrees");
  {
    NSData *dat1 = [mgr contentsAtPath: @"NSFMCopy"];
    str2 = [[NSString alloc] initWithData: dat1 encoding: 1];
    PASS([str1 isEqual: str2],"NSFileManager copied file contents match");
    DESTROY(str2);
  }
  NSDictionary *oa = [mgr fileAttributesAtPath: @"NSFMFile" traverseLink: NO];
  NSDictionary *na = [mgr fileAttributesAtPath: @"NSFMCopy" traverseLink: NO];
  NSTimeInterval        ot, nt;
  ot = [[oa fileCreationDate] timeIntervalSinceReferenceDate];
  nt = [[na fileCreationDate] timeIntervalSinceReferenceDate];
  NSLog(@"ot = %f, nt = %f", ot, nt);
  PASS(EQ(ot, nt), "copy creation date equals original")
  ot = [[oa fileModificationDate] timeIntervalSinceReferenceDate];
  nt = [[na fileModificationDate] timeIntervalSinceReferenceDate];
  PASS(EQ(ot, nt), "copy modification date equals original")
  {
    NSData *dat1 = [mgr contentsAtPath: @"NSFMFile"];
    NSError *err;
    BOOL ok;

    ok = [dat1 writeToFile: @"NSFMFile"
                   options: NSDataWritingAtomic
                     error: &err];
    PASS(ok, "can rewrite data file")
    if (NO == ok) NSLog(@"Problem: %@ with %@", err, dat1);
    na = [mgr fileAttributesAtPath: @"NSFMFile" traverseLink: NO];
#if !defined(_WIN32)
    /* Atomic copy to an existing file on windows retains the file
     * creation date, but on unix a rename produces a new timestamp.
     */
    ot = [[oa fileCreationDate] timeIntervalSinceReferenceDate];
    nt = [[na fileCreationDate] timeIntervalSinceReferenceDate];
    PASS(!EQ(ot, nt), "rewritten file creation date changed")
#endif
    ot = [[oa fileModificationDate] timeIntervalSinceReferenceDate];
    nt = [[na fileModificationDate] timeIntervalSinceReferenceDate];
    PASS(!EQ(ot, nt), "rewritten file modification date changed")
  }

  PASS([mgr movePath: @"NSFMFile"
              toPath: @"NSFMMove"
	     handler: handler],
       "NSFileManager moves a file");
  PASS([mgr fileExistsAtPath: @"NSFMMove"], 
       "NSFileManager move destination exists");
  PASS(![mgr fileExistsAtPath: @"NSFMFile"], 
       "NSFileManager move source doesn't exist"); 
  {
    NSData *dat1 = [mgr contentsAtPath: @"NSFMMove"];
    str2 = [[NSString alloc] initWithData: dat1 encoding: 1];
    PASS([str1 isEqualToString: str2],"NSFileManager moved file contents match")
    DESTROY(str2);
  }

  PASS(![mgr copyPath: @"NSFMFile"
               toPath: @"NSFMDestination"
              handler: handler],
         "NSFileManager does not copy nonexistent file")

  if ([[NSProcessInfo processInfo] operatingSystem]
    != NSWindowsNTOperatingSystem)
    {
      PASS([mgr createSymbolicLinkAtPath: @"NSFMLink" pathContent: @"NSFMMove"],
       "NSFileManager creates a symbolic link");
  
      PASS([mgr fileExistsAtPath: @"NSFMLink"], "link exists");
  
      PASS([mgr removeFileAtPath: @"NSFMLink" handler: handler], 
       "NSFileManager removes a symbolic link");
  
      PASS(![mgr fileExistsAtPath: @"NSFMLink"],
       "NSFileManager removed link doesn't exist");
  
      PASS([mgr fileExistsAtPath: @"NSFMMove"],
       "NSFileManager removed link's target still exists");
    }
  
  PASS([mgr removeFileAtPath: @"NSFMMove" handler: handler], 
       "NSFileManager removes a file"); 
 
  PASS(![mgr fileExistsAtPath: @"NSFMMove"],
       "NSFileManager removed file doesn't exist");
  
  PASS([mgr isReadableFileAtPath: @"NSFMCopy"], 
       "NSFileManager isReadableFileAtPath: works");
  PASS([mgr isWritableFileAtPath: @"NSFMCopy"],
       "NSFileManager isWritableFileAtPath: works");
  PASS([mgr isDeletableFileAtPath: @"NSFMCopy"],
       "NSFileManager isDeletableFileAtPath: works");
  PASS(![mgr isExecutableFileAtPath: @"NSFMCopy"],
       "NSFileManager isExecutableFileAtPath: works");
  
  PASS_EXCEPTION([mgr removeFileAtPath: @"." handler: handler];, 
                 NSInvalidArgumentException,
		 "NSFileManager -removeFileAtPath: @\".\" throws exception");

  PASS([mgr createDirectoryAtPath: @"subdir" attributes: nil],
       "NSFileManager can create a subdirectory");
  
  {
    NSURL			*u;
    NSDirectoryEnumerator	*e;
    unsigned			found = 0;

    e = [mgr enumeratorAtURL: [NSURL fileURLWithPath: @"."]
  includingPropertiesForKeys: nil
		     options: 0
		errorHandler: nil]; 

    while (nil != (u = [e nextObject]))
      {
	NSString	*c = [[u path] lastPathComponent];

	if ([c isEqualToString: @"NSFMCopy"])
	  found++;
	if ([c isEqualToString: @"subdir"])
	  found++;
      }
    PASS(2 == found, "URL enumerator finds expected file and subdirectory")
  }

  PASS([mgr changeCurrentDirectoryPath: @"subdir"], 
       "NSFileManager can move into subdir");

  [mgr createDirectoryAtPath: @"sub1" attributes: nil];
  [mgr createFileAtPath: @"sub1/x" 
               contents: [@"hello" dataUsingEncoding: NSASCIIStringEncoding]
             attributes: nil],
  [mgr createDirectoryAtPath: @"sub2" attributes: nil];
  [mgr createFileAtPath: @"sub2/x" 
               contents: [@"hello" dataUsingEncoding: NSASCIIStringEncoding]
             attributes: nil];
  PASS(YES == [mgr contentsEqualAtPath: @"sub1/x" andPath: @"sub2/x"],
    "directories containing identical files are equal");
  [mgr removeFileAtPath: @"sub2/x" handler: handler],
  [mgr createFileAtPath: @"sub2/x" 
               contents: [@"goodbye" dataUsingEncoding: NSASCIIStringEncoding]
             attributes: nil];
  PASS(NO == [mgr contentsEqualAtPath: @"sub1/x" andPath: @"sub2/x"],
    "directories containing files with different content are not equal");
  PASS(YES == [mgr removeFileAtPath: @"sub1" handler: handler],
    "sub1 removed");
  PASS(YES == [mgr removeFileAtPath: @"sub2" handler: handler],
    "sub2 removed");

  err = nil;
  PASS([mgr createDirectoryAtPath: dirInDir
      withIntermediateDirectories: NO  
                       attributes: nil
                            error: &err] == NO,
       "NSFileManager refuses to create intermediate directories"); 
  PASS(err != nil, "error value is set"); 
  PASS_EQUAL([err domain], NSCocoaErrorDomain, "cocoa error domain");
  PASS((errInfo = [err userInfo]) != nil, "error user info is set"); 
  PASS([errInfo objectForKey: NSFilePathErrorKey] != nil,
    "error info has a path");

  err = nil;
  PASS([mgr createDirectoryAtPath: dirInDir
      withIntermediateDirectories: YES
                       attributes: nil
                            error: &err] && err == nil,
   "NSFileManager can create intermediate directories"); 
  PASS([mgr fileExistsAtPath: dirInDir isDirectory: &isDir] && isDir == YES,
    "NSFileManager create directory and intermediate directory");

  tmp = [mgr currentDirectoryPath];
  exists = [mgr fileExistsAtPath: tmp isDirectory: &isDir];
  PASS(YES == exists && YES == isDir, "current directory exists");
  tmp = [tmp stringByDeletingLastPathComponent];
  exists = [mgr fileExistsAtPath: tmp isDirectory: &isDir];
  PASS(YES == exists && YES == isDir, "parent directory exists");
  tmp = [tmp stringByDeletingLastPathComponent];
  exists = [mgr fileExistsAtPath: tmp isDirectory: &isDir];
  PASS(YES == exists && YES == isDir, "parent of parent directory exists");
  [mgr changeCurrentDirectoryPath: tmp];
  exists = [mgr fileExistsAtPath: dir isDirectory: &isDir];
  PASS(YES == exists && YES == isDir, "directory exists");
  if (exists && isDir)
    {
      dir = [dir stringByStandardizingPath];
      PASS([mgr removeFileAtPath: dir handler: handler], "removed directory");
      PASS(![mgr fileExistsAtPath: dir], "directory no longer exists");
    }
  
  err = nil;
  PASS([mgr createDirectoryAtURL: [NSURL fileURLWithPath:dirInDir]
      withIntermediateDirectories: NO  
                       attributes: nil
                            error: &err] == NO
    && err != nil && [[err domain] isEqual: NSCocoaErrorDomain]
    && (errInfo = [err userInfo]) != nil
    && [errInfo objectForKey: NSFilePathErrorKey] != nil,
       "NSFileManager refuses to create intermediate directories on URL"); 

  err = nil;
  PASS([mgr createDirectoryAtURL: [NSURL fileURLWithPath:dirInDir]
      withIntermediateDirectories: YES
                       attributes: nil
                            error: &err] && err == nil,
   "NSFileManager can create intermediate directories on URL"); 
  PASS([mgr fileExistsAtPath: dirInDir isDirectory: &isDir] && isDir == YES,
    "NSFileManager create directory and intermediate directory on URL");

  [mgr createDirectoryAtPath: @"sub1"
	withIntermediateDirectories: YES
			 attributes: nil
	    		      error: &err];
  [mgr createDirectoryAtPath: @"sub2"
	withIntermediateDirectories: YES
			 attributes: nil
	    		      error: &err];
  [mgr copyItemAtURL: [NSURL fileURLWithPath: @"sub1"] 
               toURL: [NSURL fileURLWithPath: @"sub2/sub1"] 
               error: &err];
  PASS([mgr fileExistsAtPath: @"sub2/sub1" isDirectory: &isDir]
    && isDir == YES, "NSFileManager copy item at URL");
  PASS([mgr copyItemAtPath: @"sub2" toPath: @"sub1/sub2" error: &err] == YES
    && nil == err, "NSFileManager copy item at Path returns expected values")
  PASS([mgr fileExistsAtPath: @"sub1/sub2/sub1" isDirectory: &isDir]
    && isDir == YES, "NSFileManager copy item at Path actually works");
  PASS([mgr copyItemAtPath: @"sub2" toPath: @"sub1/sub2" error: &err] == NO
    && nil != err, "NSFileManager copy item at Path fails when dest exists")
  PASS([err code] == NSFileWriteFileExistsError, "expected error code")

  [mgr moveItemAtURL: [NSURL fileURLWithPath: @"sub2/sub1"]
	       toURL: [NSURL fileURLWithPath: @"sub1/moved"]
	       error: &err];
  PASS([mgr fileExistsAtPath: @"sub1/moved" isDirectory: &isDir]
    && isDir == YES, "NSFileManager move item at URL");
  [mgr moveItemAtPath:@"sub1/sub2" toPath:@"sub2/moved" error: &err];
  PASS([mgr fileExistsAtPath: @"sub2/moved" isDirectory: &isDir]
    && isDir == YES, "NSFileManager move item at Path");
  [mgr removeItemAtURL: [NSURL fileURLWithPath: @"sub1"]
	         error: &err];
  PASS([mgr fileExistsAtPath: @"sub1" isDirectory: &isDir] == NO,
    "NSFileManager remove item at URL");
  [mgr removeItemAtPath: @"sub2" error: &err];
  PASS([mgr fileExistsAtPath: @"sub2" isDirectory: &isDir] == NO,
    "NSFileManager remove item at Path");
  
  PASS_EXCEPTION([mgr removeFileAtPath: @"." handler: handler];, 
    NSInvalidArgumentException,
    "NSFileManager -removeFileAtPath: @\".\" throws exception");
       
  PASS_EXCEPTION([mgr removeFileAtPath: @".." handler: handler];, 
    NSInvalidArgumentException,
    "NSFileManager -removeFileAtPath: @\"..\" throws exception");
/* clean up */ 
  [mgr changeCurrentDirectoryPath: [[[mgr currentDirectoryPath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent]];
  exists = [mgr fileExistsAtPath: dir isDirectory: &isDir];
  if (exists && isDir)
    {
      PASS([mgr removeFileAtPath: dir handler: handler],
           "NSFileManager removes a directory");
      PASS(![mgr fileExistsAtPath: dir],"directory no longer exists");
    }
  
  [arp release]; arp = nil;
  return 0;
}