~mir-team/mir/development-branch

« back to all changes in this revision

Viewing changes to tests/unit-tests/scene/test_default_shell.cpp

merge trunk and resolve conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2015 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License version 3 as
 
6
 * published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authored by: ALan Griffiths <alan.griffiths@canonical.com>
 
17
 */
 
18
 
 
19
#include "src/server/shell/default_shell.h"
 
20
 
 
21
#include "mir/scene/session.h"
 
22
#include "mir/scene/null_session_listener.h"
 
23
#include "mir/scene/placement_strategy.h"
 
24
#include "mir/scene/prompt_session.h"
 
25
#include "mir/scene/prompt_session_creation_parameters.h"
 
26
#include "mir/scene/surface_creation_parameters.h"
 
27
 
 
28
#include "src/server/scene/default_session_container.h"
 
29
#include "src/server/scene/session_event_sink.h"
 
30
#include "src/server/scene/session_manager.h"
 
31
 
 
32
#include "mir_test_doubles/mock_surface_coordinator.h"
 
33
#include "mir_test_doubles/mock_session_listener.h"
 
34
#include "mir_test_doubles/mock_surface.h"
 
35
#include "mir_test_doubles/null_snapshot_strategy.h"
 
36
#include "mir_test_doubles/null_prompt_session_manager.h"
 
37
#include "mir_test_doubles/stub_input_targeter.h"
 
38
 
 
39
#include "mir_test/fake_shared.h"
 
40
 
 
41
#include <gmock/gmock.h>
 
42
#include <gtest/gtest.h>
 
43
 
 
44
namespace mc = mir::compositor;
 
45
namespace mf = mir::frontend;
 
46
namespace mi = mir::input;
 
47
namespace ms = mir::scene;
 
48
namespace mg = mir::graphics;
 
49
namespace geom = mir::geometry;
 
50
namespace mt = mir::test;
 
51
namespace mtd = mir::test::doubles;
 
52
namespace msh = mir::shell;
 
53
using namespace ::testing;
 
54
 
 
55
namespace
 
56
{
 
57
struct MockSessionContainer : public ms::SessionContainer
 
58
{
 
59
    MOCK_METHOD1(insert_session, void(std::shared_ptr<ms::Session> const&));
 
60
    MOCK_METHOD1(remove_session, void(std::shared_ptr<ms::Session> const&));
 
61
    MOCK_CONST_METHOD1(successor_of, std::shared_ptr<ms::Session>(std::shared_ptr<ms::Session> const&));
 
62
    MOCK_CONST_METHOD1(for_each, void(std::function<void(std::shared_ptr<ms::Session> const&)>));
 
63
    MOCK_METHOD0(lock, void());
 
64
    MOCK_METHOD0(unlock, void());
 
65
    ~MockSessionContainer() noexcept {}
 
66
};
 
67
 
 
68
struct MockSessionEventSink : public ms::SessionEventSink
 
69
{
 
70
    MOCK_METHOD1(handle_focus_change, void(std::shared_ptr<ms::Session> const& session));
 
71
    MOCK_METHOD0(handle_no_focus, void());
 
72
    MOCK_METHOD1(handle_session_stopping, void(std::shared_ptr<ms::Session> const& session));
 
73
};
 
74
}
 
75
 
 
76
 
 
77
namespace
 
78
{
 
79
struct MockPlacementStrategy : public ms::PlacementStrategy
 
80
{
 
81
    MockPlacementStrategy()
 
82
    {
 
83
        ON_CALL(*this, place(_, _)).WillByDefault(ReturnArg<1>());
 
84
    }
 
85
 
 
86
    MOCK_METHOD2(place, ms::SurfaceCreationParameters(ms::Session const&, ms::SurfaceCreationParameters const&));
 
87
};
 
88
 
 
89
struct MockSessionManager : ms::SessionManager
 
90
{
 
91
    using ms::SessionManager::SessionManager;
 
92
 
 
93
    MOCK_METHOD1(set_focus_to, void (std::shared_ptr<ms::Session> const& focus));
 
94
 
 
95
    void unmocked_set_focus_to(std::shared_ptr<ms::Session> const& focus)
 
96
    { ms::SessionManager::set_focus_to(focus); }
 
97
};
 
98
 
 
99
struct DefaultShell : Test
 
100
{
 
101
    NiceMock<mtd::MockSurface> mock_surface;
 
102
    MockPlacementStrategy placement_strategy;
 
103
    NiceMock<mtd::MockSurfaceCoordinator> surface_coordinator;
 
104
    NiceMock<MockSessionContainer> container;
 
105
    NiceMock<MockSessionEventSink> session_event_sink;
 
106
    NiceMock<mtd::MockSessionListener> session_listener;
 
107
 
 
108
    NiceMock<MockSessionManager> session_manager{
 
109
        mt::fake_shared(surface_coordinator),
 
110
        mt::fake_shared(container),
 
111
        std::make_shared<mtd::NullSnapshotStrategy>(),
 
112
        mt::fake_shared(session_event_sink),
 
113
        mt::fake_shared(session_listener)};
 
114
 
 
115
    mtd::StubInputTargeter input_targeter;
 
116
    msh::DefaultShell shell{
 
117
        mt::fake_shared(input_targeter),
 
118
        mt::fake_shared(surface_coordinator),
 
119
        mt::fake_shared(session_manager),
 
120
        std::make_shared<mtd::NullPromptSessionManager>(),
 
121
        mt::fake_shared(placement_strategy)};
 
122
 
 
123
    void SetUp() override
 
124
    {
 
125
        ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));
 
126
        ON_CALL(session_manager, set_focus_to(_)).
 
127
            WillByDefault(Invoke(&session_manager, &MockSessionManager::unmocked_set_focus_to));
 
128
        ON_CALL(surface_coordinator, add_surface(_,_))
 
129
            .WillByDefault(Return(mt::fake_shared(mock_surface)));
 
130
    }
 
131
};
 
132
}
 
133
 
 
134
TEST_F(DefaultShell, new_applications_receive_focus)
 
135
{
 
136
    std::shared_ptr<ms::Session> new_session;
 
137
 
 
138
    EXPECT_CALL(container, insert_session(_)).Times(1);
 
139
    EXPECT_CALL(session_manager, set_focus_to(_)).WillOnce(SaveArg<0>(&new_session));
 
140
 
 
141
    auto session = shell.open_session(__LINE__, "Visual Basic Studio", std::shared_ptr<mf::EventSink>());
 
142
    EXPECT_EQ(session, new_session);
 
143
}
 
144
 
 
145
TEST_F(DefaultShell, session_listener_is_notified_of_focus)
 
146
{
 
147
    EXPECT_CALL(session_listener, focused(_)).Times(1);
 
148
    EXPECT_CALL(session_listener, unfocused()).Times(1);
 
149
 
 
150
    auto session = shell.open_session(__LINE__, "XPlane", std::shared_ptr<mf::EventSink>());
 
151
    shell.close_session(session);
 
152
}
 
153
 
 
154
TEST_F(DefaultShell, session_event_sink_is_notified_of_focus)
 
155
{
 
156
    EXPECT_CALL(session_event_sink, handle_focus_change(_)).Times(2);
 
157
 
 
158
    auto session = shell.open_session(__LINE__, "XPlane", std::shared_ptr<mf::EventSink>());
 
159
    auto session1 = shell.open_session(__LINE__, "Bla", std::shared_ptr<mf::EventSink>());
 
160
 
 
161
    Mock::VerifyAndClearExpectations(&session_event_sink);
 
162
 
 
163
    InSequence s;
 
164
    EXPECT_CALL(session_event_sink, handle_session_stopping(_)).Times(1);
 
165
    EXPECT_CALL(container, successor_of(_)).
 
166
        WillOnce(Return(std::dynamic_pointer_cast<ms::Session>(session)));
 
167
    EXPECT_CALL(session_event_sink, handle_focus_change(_)).Times(1);
 
168
    EXPECT_CALL(session_event_sink, handle_session_stopping(_)).Times(1);
 
169
    EXPECT_CALL(container, successor_of(_)).
 
170
        WillOnce(Return(std::shared_ptr<ms::Session>()));
 
171
    EXPECT_CALL(session_event_sink, handle_no_focus()).Times(1);
 
172
 
 
173
    shell.close_session(session1);
 
174
    shell.close_session(session);
 
175
}
 
176
 
 
177
TEST_F(DefaultShell, offers_create_surface_parameters_to_placement_strategy)
 
178
{
 
179
    std::shared_ptr<ms::Session> session;
 
180
    EXPECT_CALL(session_manager, set_focus_to(_)).WillOnce(SaveArg<0>(&session));
 
181
    shell.open_session(__LINE__, "XPlane", std::shared_ptr<mf::EventSink>());
 
182
 
 
183
    auto params = ms::a_surface();
 
184
    EXPECT_CALL(placement_strategy, place(Ref(*session), Ref(params)));
 
185
 
 
186
    shell.create_surface(session, params);
 
187
}
 
188
 
 
189
TEST_F(DefaultShell, forwards_create_surface_parameters_from_placement_strategy_to_model)
 
190
{
 
191
    std::shared_ptr<ms::Session> session;
 
192
    EXPECT_CALL(session_manager, set_focus_to(_)).WillOnce(SaveArg<0>(&session));
 
193
    shell.open_session(__LINE__, "XPlane", std::shared_ptr<mf::EventSink>());
 
194
 
 
195
    auto params = ms::a_surface();
 
196
    auto placed_params = params;
 
197
    placed_params.size.width = geom::Width{100};
 
198
 
 
199
    EXPECT_CALL(placement_strategy, place(_, Ref(params))).Times(1)
 
200
        .WillOnce(Return(placed_params));
 
201
    EXPECT_CALL(surface_coordinator, add_surface(placed_params, _));
 
202
 
 
203
    shell.create_surface(session, params);
 
204
}