40void ExpectTransform3DEqual(
const CATransform3D& t,
const CATransform3D& u) {
41 EXPECT_NEAR(t.m11, u.m11,
kMaxErr);
42 EXPECT_NEAR(t.m12, u.m12,
kMaxErr);
43 EXPECT_NEAR(t.m13, u.m13,
kMaxErr);
44 EXPECT_NEAR(t.m14, u.m14,
kMaxErr);
46 EXPECT_NEAR(t.m21, u.m21,
kMaxErr);
47 EXPECT_NEAR(t.m22, u.m22,
kMaxErr);
48 EXPECT_NEAR(t.m23, u.m23,
kMaxErr);
49 EXPECT_NEAR(t.m24, u.m24,
kMaxErr);
51 EXPECT_NEAR(t.m31, u.m31,
kMaxErr);
52 EXPECT_NEAR(t.m32, u.m32,
kMaxErr);
53 EXPECT_NEAR(t.m33, u.m33,
kMaxErr);
54 EXPECT_NEAR(t.m34, u.m34,
kMaxErr);
56 EXPECT_NEAR(t.m41, u.m41,
kMaxErr);
57 EXPECT_NEAR(t.m42, u.m42,
kMaxErr);
58 EXPECT_NEAR(t.m43, u.m43,
kMaxErr);
59 EXPECT_NEAR(t.m44, u.m44,
kMaxErr);
63TEST(FlutterMutatorViewTest, BasicFrameIsCorrect) {
64 NSView* platformView = [[NSView alloc] init];
69 std::vector<FlutterPlatformViewMutation> mutations{
82 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
84 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(100, 50, 30, 20)));
85 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
90TEST(FlutterMutatorViewTest, ClipsToBounds) {
91 NSView* platformView = [[NSView alloc] init];
96TEST(FlutterMutatorViewTest, TransformedFrameIsCorrect) {
97 NSView* platformView = [[NSView alloc] init];
99 NSView* mutatorViewParent = [[NSView alloc] init];
100 mutatorViewParent.wantsLayer = YES;
102 [mutatorViewParent addSubview:mutatorView];
104 std::vector<FlutterPlatformViewMutation> mutations{
136 ApplyFlutterLayer(mutatorView,
FlutterSize{30 * 2, 20 * 2}, mutations);
137 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(92.5, 45, 45, 30)));
138 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
141 CATransform3DMakeScale(1.5, 1.5, 1));
144TEST(FlutterMutatorViewTest, FrameWithLooseClipIsCorrect) {
145 NSView* platformView = [[NSView alloc] init];
150 std::vector<FlutterPlatformViewMutation> mutations{
167 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
169 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(100, 50, 30, 20)));
170 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
173TEST(FlutterMutatorViewTest, FrameWithTightClipIsCorrect) {
174 NSView* platformView = [[NSView alloc] init];
179 std::vector<FlutterPlatformViewMutation> mutations{
200 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
202 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 55, 10, 10)));
204 CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -5, 30, 20)));
205 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
208TEST(FlutterMutatorViewTest, FrameWithTightClipAndTransformIsCorrect) {
209 NSView* platformView = [[NSView alloc] init];
211 NSView* mutatorViewParent = [[NSView alloc] init];
212 mutatorViewParent.wantsLayer = YES;
214 [mutatorViewParent addSubview:mutatorView];
216 std::vector<FlutterPlatformViewMutation> mutations{
255 ApplyFlutterLayer(mutatorView,
FlutterSize{30 * 2, 20 * 2}, mutations);
257 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 55, 10, 10)));
259 CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-17.5, -10, 45, 30)));
260 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
264TEST(FlutterMutatorViewTest, RoundRectClipsToSimpleRectangle) {
265 NSView* platformView = [[NSView alloc] init];
268 std::vector<FlutterPlatformViewMutation> mutations{
292 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
294 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 50, 10, 20)));
296 CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, 0, 30, 20)));
297 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
304TEST(FlutterMutatorViewTest, ViewsSetIsFlipped) {
305 NSView* platformView = [[NSView alloc] init];
308 std::vector<FlutterPlatformViewMutation> mutations{
332 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
340TEST(FlutterMutatorViewTest, RectsClipsToPathWhenRotated) {
341 NSView* platformView = [[NSView alloc] init];
343 std::vector<FlutterPlatformViewMutation> mutations{
349 .
scaleX = 0.9238795325112867,
350 .skewX = -0.3826834323650898,
351 .skewY = 0.3826834323650898,
352 .scaleY = 0.9238795325112867,
370 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
376TEST(FlutterMutatorViewTest, RoundRectClipsToPath) {
377 NSView* platformView = [[NSView alloc] init];
380 std::vector<FlutterPlatformViewMutation> mutations{
404 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
406 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 60, 20, 10)));
408 CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -10, 30, 20)));
409 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
411 ExpectTransform3DEqual(mutatorView.
pathClipViews.firstObject.layer.mask.transform,
412 CATransform3DMakeTranslation(-100, -50, 0));
415TEST(FlutterMutatorViewTest, PathClipViewsAreAddedAndRemoved) {
416 NSView* platformView = [[NSView alloc] init];
419 std::vector<FlutterPlatformViewMutation> mutations{
432 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
434 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(100, 50, 30, 20)));
437 std::vector<FlutterPlatformViewMutation> mutations2{
461 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations2);
463 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 60, 20, 10)));
465 CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -10, 30, 20)));
466 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
471 EXPECT_EQ(mutatorView.
pathClipViews[0].superview, mutatorView);
473 std::vector<FlutterPlatformViewMutation> mutations3{
508 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations3);
510 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 55, 10, 10)));
512 CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -5, 30, 20)));
518 EXPECT_EQ(mutatorView.
pathClipViews[0].superview, mutatorView);
520 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations2);
522 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 60, 20, 10)));
524 CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -10, 30, 20)));
525 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
530 EXPECT_EQ(mutatorView.
pathClipViews[0].superview, mutatorView);
532 ApplyFlutterLayer(mutatorView,
FlutterSize{30, 20}, mutations);
534 EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(100, 50, 30, 20)));
538TEST(FlutterMutatorViewTest, HitTestIgnoreRegion) {
539 NSView* platformView = [[NSView alloc] init];
541 ApplyFlutterLayer(mutatorView,
FlutterSize{100, 100}, {});
542 EXPECT_EQ([mutatorView hitTest:NSMakePoint(10, 10)], platformView);
543 EXPECT_EQ([mutatorView hitTest:NSMakePoint(50, 10)], platformView);
549 EXPECT_EQ([mutatorView hitTest:NSMakePoint(10, 10)], nil);
550 EXPECT_EQ([mutatorView hitTest:NSMakePoint(49, 10)], nil);
551 EXPECT_EQ([mutatorView hitTest:NSMakePoint(10, 49)], nil);
552 EXPECT_EQ([mutatorView hitTest:NSMakePoint(50, 50)], nil);
553 EXPECT_EQ([mutatorView hitTest:NSMakePoint(50, 10)], platformView);
554 EXPECT_EQ([mutatorView hitTest:NSMakePoint(10, 50)], platformView);
557 EXPECT_EQ([mutatorView hitTest:NSMakePoint(10, 10)], platformView);
558 EXPECT_EQ([mutatorView hitTest:NSMakePoint(49, 10)], platformView);
559 EXPECT_EQ([mutatorView hitTest:NSMakePoint(10, 49)], platformView);
560 EXPECT_EQ([mutatorView hitTest:NSMakePoint(50, 50)], platformView);
561 EXPECT_EQ([mutatorView hitTest:NSMakePoint(50, 10)], platformView);
562 EXPECT_EQ([mutatorView hitTest:NSMakePoint(10, 50)], platformView);
565TEST(FlutterMutatorViewTest, ReparentingPlatformView) {
566 NSView* platformView = [[NSView alloc] init];
568 ApplyFlutterLayer(mutatorView,
FlutterSize{100, 100}, {});
570 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 100, 100)));
573 NSView* newParent = [[NSView alloc] init];
574 [newParent addSubview:platformView];
575 platformView.frame = CGRectMake(10, 10, 200, 200);
577 NSView* placeholderView = [[NSView alloc] init];
578 [mutatorView.platformViewContainer addSubview:placeholderView];
579 ApplyFlutterLayer(mutatorView,
FlutterSize{100, 100}, {});
583 EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(10, 10, 200, 200)));
584 EXPECT_TRUE(CGRectEqualToRect(placeholderView.frame, CGRectMake(0, 0, 100, 100)));
592- (void)testCoordinatorEventWithinFlutterContent {
593 id flutterView = OCMClassMock([
FlutterView class]);
597 id platformView = OCMClassMock([NSView
class]);
598 OCMStub([flutterView cursorUpdate:[OCMArg any]]);
600 OCMStub([mutatorView platformView]).andReturn(platformView);
601 CGPoint location = NSMakePoint(50, 50);
602 OCMStub([mutatorView convertPoint:location fromView:[OCMArg any]]).andReturn(location);
603 NSEvent*
event = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
615 OCMVerify([flutterView cursorUpdate:
event]);
618 id platformView = OCMClassMock([NSView
class]);
620 OCMReject([flutterView cursorUpdate:[OCMArg any]]);
622 OCMStub([mutatorView platformView]).andReturn(platformView);
623 CGPoint location = NSMakePoint(50, 50);
624 OCMStub([mutatorView convertPoint:location fromView:[OCMArg any]]).andReturn(location);
625 NSEvent*
event = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
639 [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
643- (void)testCoordinatorEventOutsideFlutterContent {
644 id flutterView = OCMClassMock([
FlutterView class]);
645 OCMReject([flutterView cursorUpdate:[OCMArg any]]);
648 id platformViewWindow = OCMClassMock([NSWindow
class]);
650 id platformView = OCMClassMock([NSView
class]);
651 OCMStub([platformViewWindow invalidateCursorRectsForView:platformView]);
652 OCMStub([platformView
window]).andReturn(platformViewWindow);
653 OCMStub([flutterView cursorUpdate:[OCMArg any]]);
655 OCMStub([mutatorView platformView]).andReturn(platformView);
656 CGPoint location = NSMakePoint(150, 150);
657 OCMStub([mutatorView convertPoint:location fromView:[OCMArg any]]).andReturn(location);
658 NSEvent*
event = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
667 [coordinator processMouseMoveEvent:event
668 forMutatorView:mutatorView
669 overlayRegion:{CGRectMake(0, 0, 100, 100)}];
670 OCMVerify([platformViewWindow invalidateCursorRectsForView:platformView]);
674 OCMReject([platformViewWindow invalidateCursorRectsForView:[OCMArg any]]);
676 id platformView = OCMClassMock([NSView
class]);
677 OCMStub([platformViewWindow invalidateCursorRectsForView:platformView]);
678 OCMStub([platformView
window]).andReturn(platformViewWindow);
679 OCMStub([flutterView cursorUpdate:[OCMArg any]]);
681 OCMStub([mutatorView platformView]).andReturn(platformView);
682 CGPoint location = NSMakePoint(150, 150);
683 OCMStub([mutatorView convertPoint:location fromView:[OCMArg any]]).andReturn(location);
684 NSEvent*
event = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
693 [coordinator processMouseMoveEvent:event
694 forMutatorView:mutatorView
695 overlayRegion:{CGRectMake(0, 0, 100, 100)}];
698 [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
699 EXPECT_FALSE(coordinator.cleanupScheduled);
702 platformViewWindow = OCMClassMock([NSWindow
class]);
704 id platformView = OCMClassMock([NSView
class]);
705 OCMStub([platformViewWindow invalidateCursorRectsForView:platformView]);
706 OCMStub([platformView
window]).andReturn(platformViewWindow);
707 OCMStub([flutterView cursorUpdate:[OCMArg any]]);
709 OCMStub([mutatorView platformView]).andReturn(platformView);
710 CGPoint location = NSMakePoint(150, 150);
711 OCMStub([mutatorView convertPoint:location fromView:[OCMArg any]]).andReturn(location);
712 NSEvent*
event = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
721 [coordinator processMouseMoveEvent:event
722 forMutatorView:mutatorView
723 overlayRegion:{CGRectMake(0, 0, 100, 100)}];
724 OCMVerify([platformViewWindow invalidateCursorRectsForView:platformView]);
726 [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];