1515#import " Miscellaneous.h"
1616#import " MMAppController.h"
1717#import " MMApplication.h"
18+ #import " MMFullScreenWindow.h"
19+ #import " MMWindow.h"
1820#import " MMTextView.h"
1921#import " MMWindowController.h"
2022#import " MMVimController.h"
@@ -30,10 +32,6 @@ - (void)handleMessage:(int)msgid data:(NSData *)data;
3032@end
3133
3234// Test harness
33- @interface MMAppController (Tests)
34- - (NSMutableArray *)vimControllers ;
35- @end
36-
3735@implementation MMAppController (Tests)
3836- (NSMutableArray *)vimControllers {
3937 return vimControllers;
@@ -50,6 +48,12 @@ - (BOOL)inLiveResize {
5048}
5149@end
5250
51+ @implementation MMWindowController (Tests)
52+ - (BOOL )fullScreenEnabled {
53+ return fullScreenEnabled;
54+ }
55+ @end
56+
5357@interface MacVimTests : XCTestCase
5458
5559@end
@@ -733,4 +737,129 @@ - (void) testWindowResize {
733737 [self waitForVimClose ];
734738}
735739
740+ - (void )waitForNativeFullscreenEnter {
741+ XCTestExpectation *expectation = [self expectationWithDescription: @" NativeFullscreenEnter" ];
742+
743+ SEL sel = @selector (windowDidEnterFullScreen: );
744+ Method method = class_getInstanceMethod ([MMWindowController class ], sel);
745+
746+ IMP origIMP = method_getImplementation (method);
747+ IMP newIMP = imp_implementationWithBlock (^(id self, id notification) {
748+ typedef void (*fn)(id ,SEL ,NSNotification *);
749+ ((fn)origIMP)(self, sel, notification);
750+ [expectation fulfill ];
751+ });
752+
753+ method_setImplementation (method, newIMP);
754+ [self waitForExpectations: @[expectation] timeout: 10 ];
755+ method_setImplementation (method, origIMP);
756+ }
757+
758+ - (void )waitForNativeFullscreenExit {
759+ XCTestExpectation *expectation = [self expectationWithDescription: @" NativeFullscreenExit" ];
760+
761+ SEL sel = @selector (windowDidExitFullScreen: );
762+ Method method = class_getInstanceMethod ([MMWindowController class ], sel);
763+
764+ IMP origIMP = method_getImplementation (method);
765+ IMP newIMP = imp_implementationWithBlock (^(id self, id notification) {
766+ typedef void (*fn)(id ,SEL ,NSNotification *);
767+ ((fn)origIMP)(self, sel, notification);
768+ [expectation fulfill ];
769+ });
770+
771+ method_setImplementation (method, newIMP);
772+ [self waitForExpectations: @[expectation] timeout: 10 ];
773+ method_setImplementation (method, origIMP);
774+ }
775+
776+ // / Utility to test full screen functionality in both non-native/native full
777+ // / screen.
778+ - (void ) fullScreenTestWithNative : (BOOL )native {
779+ MMAppController *app = MMAppController.sharedInstance ;
780+
781+ // Cache test defaults
782+ NSUserDefaults *ud = NSUserDefaults .standardUserDefaults ;
783+ NSDictionary <NSString *, id > *defaults = [ud volatileDomainForName: NSArgumentDomain ];
784+ NSMutableDictionary <NSString *, id > *newDefaults = [defaults mutableCopy ];
785+
786+ // Change native full screen setting
787+ newDefaults[MMNativeFullScreenKey] = [NSNumber numberWithBool: native];
788+ [ud setVolatileDomain: newDefaults forName: NSArgumentDomain ];
789+
790+ [app openNewWindow: NewWindowClean activate: YES ];
791+ [self waitForVimOpenAndMessages ];
792+
793+ MMWindowController *winController = app.keyVimController .windowController ;
794+
795+ // Enter full screen and check that the states are properly changed.
796+ [self sendStringToVim: @" :set fu\n " withMods: 0 ];
797+ if (native) {
798+ [self waitForNativeFullscreenEnter ];
799+ } else {
800+ [self waitForEventHandlingAndVimProcess ];
801+ [self waitForEventHandlingAndVimProcess ]; // wait one more cycle to make sure we finished the transition
802+ }
803+
804+ XCTAssertTrue ([winController fullScreenEnabled ]);
805+ if (native) {
806+ XCTAssertTrue ([winController.window isKindOfClass: [MMWindow class ]]);
807+ } else {
808+ XCTAssertTrue ([winController.window isKindOfClass: [MMFullScreenWindow class ]]);
809+ }
810+
811+ // Exit full screen
812+ [self sendStringToVim: @" :set nofu\n " withMods: 0 ];
813+ if (native) {
814+ [self waitForNativeFullscreenExit ];
815+ } else {
816+ [self waitForEventHandlingAndVimProcess ];
817+ [self waitForEventHandlingAndVimProcess ]; // wait one more cycle to make sure we finished the transition
818+ }
819+
820+ XCTAssertFalse ([winController fullScreenEnabled ]);
821+ XCTAssertTrue ([winController.window isKindOfClass: [MMWindow class ]]);
822+
823+ // Enter full screen again
824+ [self sendStringToVim: @" :set fu\n " withMods: 0 ];
825+ if (native) {
826+ [self waitForNativeFullscreenEnter ];
827+ } else {
828+ [self waitForEventHandlingAndVimProcess ];
829+ [self waitForEventHandlingAndVimProcess ]; // wait one more cycle to make sure we finished the transition
830+ }
831+
832+ XCTAssertTrue ([winController fullScreenEnabled ]);
833+
834+ // Test that resizing the vim view does not work when in full screen as we fix the window size instead
835+ MMTextView *textView = [[[[app keyVimController ] windowController ] vimView ] textView ];
836+ const int fuRows = textView.maxRows ;
837+ const int fuCols = textView.maxColumns ;
838+ XCTAssertNotEqual (10 , fuRows); // just some basic assumptions as full screen should have more rows/cols than this
839+ XCTAssertNotEqual (30 , fuCols);
840+ [self sendStringToVim: @" :set lines=10\n " withMods: 0 ];
841+ [self sendStringToVim: @" :set columns=30\n " withMods: 0 ];
842+ [self waitForEventHandlingAndVimProcess ];
843+ [self waitForEventHandlingAndVimProcess ]; // need to wait twice to allow full screen to force it back
844+ XCTAssertEqual (fuRows, textView.maxRows );
845+ XCTAssertEqual (fuCols, textView.maxColumns );
846+
847+ // Clean up
848+ [[app keyVimController ] sendMessage: VimShouldCloseMsgID data: nil ];
849+ [self waitForVimClose ];
850+
851+ XCTAssertEqual (0 , [app vimControllers ].count );
852+
853+ // Restore settings to test defaults
854+ [ud setVolatileDomain: defaults forName: NSArgumentDomain ];
855+ }
856+
857+ - (void ) testFullScreenNonNative {
858+ [self fullScreenTestWithNative: NO ];
859+ }
860+
861+ - (void ) testFullScreenNative {
862+ [self fullScreenTestWithNative: YES ];
863+ }
864+
736865@end
0 commit comments