0

I'm trying to add a GHUnit test case to this SimpleHTTPServer example. The example include a Cocoa application that works fine for me. But I can't duplicate the behavior in a test case.

Here is the test class:

#import <GHUnit/GHUnit.h>
#import "SimpleHTTPServer.h"


@interface ServerTest : GHTestCase
{
    SimpleHTTPServer *server; 
}
@end


@implementation ServerTest

-(void)setUpClass
{
    [[NSRunLoop currentRunLoop] run]; 
}

- (NSString*)requestToURL:(NSString*)urlString error:(NSError**)error
{
    NSURL *url = [NSURL URLWithString:urlString]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:1]; 
    NSURLResponse *response = nil; 
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:error]; 
    NSString *page = nil; 
    if (error == nil)
    {
        NSStringEncoding responseEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)[response textEncodingName]));
        page = [[NSString alloc] initWithData:data encoding:responseEncoding]; 
        [page autorelease];
    }
    return page; 
}

- (void)testPortReuse
{
    unsigned int port = 50001; 
    NSError *error = nil; 
    NSString *path, *url; 

    server = [[SimpleHTTPServer alloc] initWithTCPPort:port delegate:self]; 
    sleep(10); 
    path = @"/x/y/z"; 
    url = [NSString stringWithFormat:@"http://localhost:%u%@", port, path]; 
    [self requestToURL:url error:&error]; 
    GHAssertNil(error, @"%@ : %@", url, error); 
    [server release]; 
}

- (void)processURL:(NSURL *)path connection:(SimpleHTTPConnection *)connection
{
    NSLog(@"processURL"); 
}

- (void)stopProcessing
{
    NSLog(@"stopProcessing"); 
}

@end

I've tried sending requests via NSURLRequest and also (during the sleep) via a web browser. The delegate methods -processURL and -stopProcessing are never called. The problem seems to be that [fileHandle acceptConnectionInBackgroundAndNotify] in SimpleHTTPServer -initWithTCPPort:delegate: is not causing any NSFileHandleConnectionAcceptedNotifications to reach the NSNotificationCenter -- so I suspect a problem involving run loops.

The problem seems to be with the NSFileHandle, not the NSNotificationCenter, because when [nc postNotificationName:NSFileHandleConnectionAcceptedNotification object:nil] is added to the end of initWithTCPPort:delegate:, the NSNotificationCenter does get the notification.

jlstrecker
  • 4,953
  • 3
  • 46
  • 60

1 Answers1

0
if (error == nil)

That should be:

if (data != nil)

error here is the passed-in pointer to an NSError* - it will only be nil if the caller passed nil instead of a reference to an NSError* object, which isn't what your -testPortReuse method does.

It would also be incorrect to dereference it (as in if (*error == nil)), because error arguments are not guaranteed to be set to nil upon error. The return value indicates an error condition, and the value returned in the error argument is only meaningful or reliable if there is an error. Always check the return value to determine if an error happened, then check the error parameter for details only if something did in fact go wrong.

In other words, as it's written above, your -requestToURL:error: method is incapable of handling success. Much like Charlie Sheen. :-)

Sherm Pendley
  • 13,556
  • 3
  • 45
  • 57
  • Thanks. I fixed this in my code but it doesn't help with the problem I asked about. Right now `data` is always nil, with error "The request timed out". – jlstrecker Apr 01 '11 at 03:11