Skip to content

Commit 2b136db

Browse files
committed
Add tests for full screen code
Basic tests to validate different full screen functionalities. Help prevents regressions such as #1515 where full screen simply stops working. Not an exhaustive test for now. Some functionalities (e.g. multi-monitor, MacBook notch) are hard to mock up and validate in tests. Some other functionalities like restoring window size, delayed full screen on startup (when setting it from gvimrc) will be added later.
1 parent ea84370 commit 2b136db

File tree

1 file changed

+133
-4
lines changed

1 file changed

+133
-4
lines changed

src/MacVim/MacVimTests/MacVimTests.m

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
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

Comments
 (0)