summaryrefslogtreecommitdiffstats
path: root/remoting/client/empty_cursor_filter_unittest.cc
blob: 3fa98acc64fe56819de3cf76424097effed5cc77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/client/empty_cursor_filter.h"

#include <ostream>

#include "remoting/proto/control.pb.h"
#include "remoting/protocol/cursor_shape_stub.h"
#include "remoting/protocol/protocol_mock_objects.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace remoting {

namespace {

// Chromoting cursors are always RGBA.
const int kBytesPerPixel = 4;

const int kTestCursorWidth = 100;
const int kTestCursorHeight = 64;
const int kTestCursorHotspotX = 10;
const int kTestCursorHotspotY = 30;
const int kTestCursorDataSize =
    kTestCursorWidth * kTestCursorHeight * kBytesPerPixel;

protocol::CursorShapeInfo CreateTransparentCursorShape() {
  protocol::CursorShapeInfo transparent_cursor;
  transparent_cursor.set_width(kTestCursorWidth);
  transparent_cursor.set_height(kTestCursorHeight);
  transparent_cursor.set_hotspot_x(kTestCursorHotspotX);
  transparent_cursor.set_hotspot_y(kTestCursorHotspotY);
  transparent_cursor.mutable_data()->resize(kTestCursorDataSize, 0);
  return transparent_cursor;
}

protocol::CursorShapeInfo CreateOpaqueCursorShape() {
  protocol::CursorShapeInfo cursor = CreateTransparentCursorShape();
  cursor.mutable_data()->assign(kTestCursorDataSize, 0x01);
  return cursor;
}

MATCHER_P(EqualsCursorShape, cursor_shape, "") {
  // TODO(wez): Should not assume that all fields were set.
  return arg.data() == cursor_shape.data() &&
         arg.width() == cursor_shape.width() &&
         arg.height() == cursor_shape.height() &&
         arg.hotspot_x() == cursor_shape.hotspot_x() &&
         arg.hotspot_y() == cursor_shape.hotspot_y();
}

}  // namespace

namespace protocol {

// This pretty-printer must be defined under remoting::protocol to be used.
::std::ostream& operator<<(::std::ostream& os, const CursorShapeInfo& cursor) {
  return os << "[w:" << cursor.width() << ", h:" << cursor.height()
            << ", h.x:" << cursor.hotspot_x() << ", h.y:" << cursor.hotspot_y()
            << ", data.size:" << cursor.data().size() << "]";
}

} // namespace protocol

// Verify that EmptyCursorShape() generates a normalized empty cursor.
TEST(EmptyCursorFilterTest, EmptyCursorShape) {
  const protocol::CursorShapeInfo& empty_cursor = EmptyCursorShape();

  // TODO(wez): Replace these individual asserts with IsCursorShapeValid()?
  ASSERT_TRUE(empty_cursor.has_data());
  ASSERT_TRUE(empty_cursor.has_width());
  ASSERT_TRUE(empty_cursor.has_height());
  ASSERT_TRUE(empty_cursor.has_hotspot_x());
  ASSERT_TRUE(empty_cursor.has_hotspot_y());

  EXPECT_EQ(0, empty_cursor.width());
  EXPECT_EQ(0, empty_cursor.height());
  EXPECT_EQ(0, empty_cursor.hotspot_x());
  EXPECT_EQ(0, empty_cursor.hotspot_y());
  EXPECT_TRUE(empty_cursor.data().empty());
}

// Verify that IsCursorShapeEmpty returns true only for normalized empty
// cursors, not for opaque or transparent non-empty cursors.
TEST(EmptyCursorFilterTest, IsCursorShapeEmpty) {
  const protocol::CursorShapeInfo& kEmptyCursor = EmptyCursorShape();
  EXPECT_TRUE(IsCursorShapeEmpty(kEmptyCursor));

  const protocol::CursorShapeInfo& kOpaqueCursor = CreateOpaqueCursorShape();
  EXPECT_FALSE(IsCursorShapeEmpty(kOpaqueCursor));

  const protocol::CursorShapeInfo& kTransparentCursor =
      CreateTransparentCursorShape();
  EXPECT_FALSE(IsCursorShapeEmpty(kTransparentCursor));
}

// Verify that EmptyCursorFilter behaves correctly for normalized empty cursors.
TEST(EmptyCursorFilterTest, EmptyCursor) {
  const protocol::CursorShapeInfo& kEmptyCursor = EmptyCursorShape();
  protocol::MockCursorShapeStub cursor_stub;
  EmptyCursorFilter cursor_filter(&cursor_stub);

  EXPECT_CALL(cursor_stub, SetCursorShape(EqualsCursorShape(kEmptyCursor)));

  cursor_filter.SetCursorShape(kEmptyCursor);
}

// Verify that EmptyCursorFilter turns transparent cursors into empty ones.
TEST(EmptyCursorFilterTest, TransparentCursor) {
  const protocol::CursorShapeInfo& kEmptyCursor = EmptyCursorShape();
  protocol::MockCursorShapeStub cursor_stub;
  EmptyCursorFilter cursor_filter(&cursor_stub);

  EXPECT_CALL(cursor_stub, SetCursorShape(EqualsCursorShape(kEmptyCursor)));

  cursor_filter.SetCursorShape(CreateTransparentCursorShape());
}

// Verify that EmptyCursorFilter leaves non-transparent cursors alone.
TEST(EmptyCursorFilterTest, NonTransparentCursor) {
  const protocol::CursorShapeInfo& kOpaqueCursor = CreateOpaqueCursorShape();
  protocol::MockCursorShapeStub cursor_stub;
  EmptyCursorFilter cursor_filter(&cursor_stub);

  EXPECT_CALL(cursor_stub, SetCursorShape(EqualsCursorShape(kOpaqueCursor)));

  cursor_filter.SetCursorShape(kOpaqueCursor);
}

}  // namespace remoting