pivotal-legacy / PivotalCoreKit

Shared library and test code for iOS and macOS projects
http://pivotallabs.com
Other
168 stars 85 forks source link

popoverPresentationController is always nil in iOS 11 #204

Open evanhughes3 opened 6 years ago

evanhughes3 commented 6 years ago

Hello, and thanks for making an awesome tool! I'm running Cedar with PCK, and I'm trying to pin down an issue I had when running my specs on iOS 11. When running my specs on iOS 11, all the tests related a "presentedViewController's" "popoverPresentationController" started failing.

Here is a test that passes on iOS 10.3, and fails on iOS 11.

ViewControllerSpec.mm

#import <Cedar/Cedar.h>
#import "ViewController.h"

using namespace Cedar::Matchers;
using namespace Cedar::Doubles;

SPEC_BEGIN(ViewControllerSpec)

describe(@"ViewController", ^{
    __block ViewController *subject;

    beforeEach(^{
        subject = [[ViewController alloc] init];
    });

    describe(@"-viewDidLoad", ^{
        beforeEach(^{
            [subject loadViewIfNeeded];
        });

        it(@"should present a popover controller", ^{
            UIViewController *presentedViewController = subject.presentedViewController;
            presentedViewController.popoverPresentationController should_not be_nil;
        });
    });
});

SPEC_END

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@end

ViewController.m

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIViewController *popoverController = [[UIViewController alloc] init];
    popoverController.modalPresentationStyle = UIModalPresentationPopover;

    [self presentViewController:popoverController animated:YES completion:nil];
}

@end

Everything seems to work fine when running the actual app, meaning self.presentedViewController.popoverPresentationController is a real instance. This is only an issue in specs.

Any help would be much appreciated!

evanhughes3 commented 6 years ago

I found a workaround, though it seems strange - I noticed that the presentedViewController's presentationController property was actually a UIPopoverPresentationController instance.

Updating my spec to this got the test to pass.

#import <Cedar/Cedar.h>
#import "ViewController.h"

using namespace Cedar::Matchers;
using namespace Cedar::Doubles;

SPEC_BEGIN(ViewControllerSpec)

describe(@"ViewController", ^{
    __block ViewController *subject;

    beforeEach(^{
        subject = [[ViewController alloc] init];
    });

    describe(@"-viewDidLoad", ^{
        beforeEach(^{
            [subject loadViewIfNeeded];
        });

        it(@"should present a popover controller", ^{
            UIViewController *presentedViewController = subject.presentedViewController;
            UIPopoverPresentationController *popoverController = (UIPopoverPresentationController *)presentedViewController.presentationController;
            popoverController should_not be_nil;
        });
    });
});

SPEC_END

Inside the PCK method _pck_setPresentedViewController in UIViewController+Spec, modalViewController.popoverPresentationController is a real instance, but by the time we are asserting in the test above, subject.presentedViewController.popoverPresentationController is nil, but subject.presentedViewController.presentationController is the same instance as was in UIViewController+Spec.