ashfurrow / Forgeries

Helper methods for testing iOS code
MIT License
83 stars 6 forks source link

Add fake NSFileManager #12

Closed orta closed 8 years ago

orta commented 8 years ago

I think we could do something around the file manager, it's one of the other big non-DI'd singleton in the Foundation space. Eigen could definitely do with this, there's some ugly thing going on in ARFileUtilTests.

orta commented 8 years ago

Idea: It could setup a fake version of the user support dir etc in /tmp

alloy commented 8 years ago

Real FS access is slow, though, and as this is about forging the NSFileManager API being used, and not necessarily all other FS APIs, I think it can all be done in memory, akin to https://github.com/defunkt/fakefs.

E.g.

describe(@"NSFileManager", ^{
  __block NSFileManager *fileManager = nil;

  before(@"", ^{
    fileManager = [ForgeriesFileManager new];
    [fileManager createDirectoryAtPath:@"/what/a/beautiful/directory" withIntermediateDirectories:YES attributes:nil error:nil];
    [fileManager createFileAtPath:@"/what/a/beautiful/directory/file" contents:@"zomg" attributes:nil];
  });

  it(@"reads from the in-memory FS", ^{
    expect([fileManager contentsAtPath:@"/what/a/beautiful/directory/file"]).to.equal(@"zomg");
  });
});

For clarity sake I wrote this as if the APIs take/return strings, where in fact they work with data.

alloy commented 8 years ago

I have to add, having written this example, I think it would be quite an undertaking, and so

orta commented 8 years ago

I have a small use case right now ( https://github.com/artsy/Aerodramus/pull/1 ) - I can start with it in-memory and see how it goes from there if/when we start integrating it into ours apps.

alloy commented 8 years ago

👍

orta commented 8 years ago

This is hard to cover a lot of use cases, a key API for file writing functions exists on NSData:

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)atomically; // the atomically flag is ignored if the url is not of a type the supports atomic writes
- (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)writeOptionsMask error:(NSError **)errorPtr;
- (BOOL)writeToURL:(NSURL *)url options:(NSDataWritingOptions)writeOptionsMask error:(NSError **)errorPtr;
alloy commented 8 years ago

Yeah, that’s the thing, you have to then do all the FS access through that API. Although I don’t think that it’s that much of a problem to use -[NSFileManager createFileAtPath:contents:attributes:] if you’re already DI'ing a NSFileManager, no?

If the point is to stub any and all FS access, than this ticket is not related to NSFileManager per se.

orta commented 8 years ago

It's possible however createFileAtPath:contents:attributes has different behaviour ( won't overwrite unlike the NSData ones )

alloy commented 8 years ago

Highly unlikely, the NSFileManager API will be lower-level than such convenience methods.

ashfurrow commented 8 years ago

Fixed in https://github.com/ashfurrow/Forgeries/pull/14