Merge lp:~elopio/ubuntu-ui-toolkit/fake_app_fixture into lp:ubuntu-ui-toolkit

Proposed by Leo Arias
Status: Merged
Approved by: Cris Dywan
Approved revision: 938
Merged at revision: 940
Proposed branch: lp:~elopio/ubuntu-ui-toolkit/fake_app_fixture
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 340 lines (+271/-15)
4 files modified
debian/control (+3/-2)
tests/autopilot/ubuntuuitoolkit/fixture_setup.py (+97/-0)
tests/autopilot/ubuntuuitoolkit/tests/__init__.py (+8/-13)
tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py (+163/-0)
To merge this branch: bzr merge lp:~elopio/ubuntu-ui-toolkit/fake_app_fixture
Reviewer Review Type Date Requested Status
Cris Dywan Approve
PS Jenkins bot continuous-integration Approve
Richard Huddie (community) Approve
VĂ­ctor R. Ruiz Pending
Javier Collado Pending
Review via email: mp+205916@code.launchpad.net

Commit message

Refactor the fake application used by the autopilot emulator tests to make a fixture that can be reused by other projects.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Richard Huddie (rhuddie) wrote :

I ran the tests on desktop and touch OK. Clean for pep8 and pyflakes. New code looks good to me.

review: Approve
Revision history for this message
Cris Dywan (kalikiana) wrote :

Would it make sense to verify the fields in the .desktop file? The shell isn't typically very talkative in case something's wrong.

Revision history for this message
Javier Collado (javier.collado) wrote :

I've looked into the code and run it in a desktop and works fine.

My only comment, is that I don't like the "assert_desktop_file_contents"
method. Instead of generating a long regular expression for the desktop file
and check that there's a match for every key value pair in the expected
contents dictionary, I'd parse the desktop file as a dictionary and run an
assertion on both the dictionaries:

        contents_dict = dict(
            [line.split('=')
             for line in desktop_file_contents.splitlines()[1:]])

        self.assertDictEqual(expected_contents_dict, contents_dict)

937. By Leo Arias

Cleaned the assert_desktop_file_contents as suggested by javier.

Revision history for this message
Leo Arias (elopio) wrote :

> My only comment, is that I don't like the "assert_desktop_file_contents"
> method. Instead of generating a long regular expression for the desktop file
> and check that there's a match for every key value pair in the expected
> contents dictionary, I'd parse the desktop file as a dictionary and run an
> assertion on both the dictionaries:

Right you are! It looks much better now.

Revision history for this message
Leo Arias (elopio) wrote :

> Would it make sense to verify the fields in the .desktop file? The shell isn't
> typically very talkative in case something's wrong.

kalikiana, I had reported a bug about that. I see now that it's a duplicate of:
https://bugs.launchpad.net/ubuntu/+source/qtubuntu/+bug/1204595
And it seems to have some work. I'll ask tomorrow.

It wouldn't hurt to add an extra check here. What are the fields that we should require?

If that's ok to you, I'll do it in a separate branch.

938. By Leo Arias

Removed extra line.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Leo Arias (elopio) wrote :

<greyback> elopio: required entries are Name, Comment, Icon, Exec, Path, StageHint, others are optional

Revision history for this message
Cris Dywan (kalikiana) wrote :

> It wouldn't hurt to add an extra check here. What are the fields that we
> should require?
>
> If that's ok to you, I'll do it in a separate branch.

Ack.

Nice stuff.

review: Approve
Revision history for this message
Leo Arias (elopio) wrote :

Reported bug https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1279901 to do the desktop fields check.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2014-01-30 13:37:10 +0000
3+++ debian/control 2014-02-12 18:41:59 +0000
4@@ -40,8 +40,8 @@
5 locales,
6 Standards-Version: 3.9.4
7 Homepage: https://launchpad.net/ubuntu-ui-toolkit
8-# If you aren't a member of ~ubuntu-sdk-team but need to upload packaging
9-# changes, just go ahead. ~ubuntu-sdk-team will notice and sync up the code
10+# If you aren't a member of ~ubuntu-sdk-team but need to upload packaging
11+# changes, just go ahead. ~ubuntu-sdk-team will notice and sync up the code
12 # again.
13 Vcs-Bzr: https://code.launchpad.net/~ubuntu-sdk-team/ubuntu-ui-toolkit/trunk
14
15@@ -131,6 +131,7 @@
16 libqt5test5,
17 libqt5widgets5,
18 python-autopilot (>= 1.4),
19+ python-fixtures,
20 python-mock,
21 ubuntu-ui-toolkit-examples (>= ${source:Version}),
22 Description: Test package for Ubuntu UI Toolkit
23
24=== added file 'tests/autopilot/ubuntuuitoolkit/fixture_setup.py'
25--- tests/autopilot/ubuntuuitoolkit/fixture_setup.py 1970-01-01 00:00:00 +0000
26+++ tests/autopilot/ubuntuuitoolkit/fixture_setup.py 2014-02-12 18:41:59 +0000
27@@ -0,0 +1,97 @@
28+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
29+#
30+# Copyright (C) 2014 Canonical Ltd.
31+#
32+# This program is free software; you can redistribute it and/or modify
33+# it under the terms of the GNU Lesser General Public License as published by
34+# the Free Software Foundation; version 3.
35+#
36+# This program is distributed in the hope that it will be useful,
37+# but WITHOUT ANY WARRANTY; without even the implied warranty of
38+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39+# GNU Lesser General Public License for more details.
40+#
41+# You should have received a copy of the GNU Lesser General Public License
42+# along with this program. If not, see <http://www.gnu.org/licenses/>.
43+
44+import copy
45+import os
46+import tempfile
47+
48+import fixtures
49+
50+from ubuntuuitoolkit import base
51+
52+
53+DEFAULT_QML_FILE_CONTENTS = ("""
54+import QtQuick 2.0
55+import Ubuntu.Components 0.1
56+
57+MainView {
58+ width: units.gu(48)
59+ height: units.gu(60)
60+
61+ Label {
62+ objectName: 'testLabel'
63+ text: 'Test application.'
64+ }
65+}
66+""")
67+DEFAULT_DESKTOP_FILE_DICT = {
68+ 'Type': 'Application',
69+ 'Name': 'test',
70+ 'Exec': '{qmlscene} {qml_file_path}',
71+ 'Icon': 'Not important'
72+}
73+
74+
75+class FakeApplication(fixtures.Fixture):
76+
77+ def __init__(
78+ self, qml_file_contents=DEFAULT_QML_FILE_CONTENTS,
79+ desktop_file_dict=None):
80+ super(FakeApplication, self).__init__()
81+ self._qml_file_contents = qml_file_contents
82+ if desktop_file_dict is None:
83+ self._desktop_file_dict = copy.deepcopy(DEFAULT_DESKTOP_FILE_DICT)
84+ else:
85+ self._desktop_file_dict = copy.deepcopy(desktop_file_dict)
86+
87+ def setUp(self):
88+ super(FakeApplication, self).setUp()
89+ self.qml_file_path, self.desktop_file_path = (
90+ self._create_test_application())
91+
92+ def _create_test_application(self):
93+ qml_file_path = self._write_test_qml_file()
94+ self.addCleanup(os.remove, qml_file_path)
95+ desktop_file_path = self._write_test_desktop_file(qml_file_path)
96+ self.addCleanup(os.remove, desktop_file_path)
97+ return qml_file_path, desktop_file_path
98+
99+ def _write_test_qml_file(self):
100+ qml_file = tempfile.NamedTemporaryFile(
101+ mode='w+t', suffix='.qml', delete=False)
102+ qml_file.write(self._qml_file_contents)
103+ qml_file.close()
104+ return qml_file.name
105+
106+ def _write_test_desktop_file(self, qml_file_path):
107+ desktop_file_dir = self._get_local_desktop_file_directory()
108+ if not os.path.exists(desktop_file_dir):
109+ os.makedirs(desktop_file_dir)
110+ desktop_file = tempfile.NamedTemporaryFile(
111+ mode='w+t', suffix='.desktop', dir=desktop_file_dir, delete=False)
112+ self._desktop_file_dict['Exec'] = (
113+ self._desktop_file_dict['Exec'].format(
114+ qmlscene=base.get_qmlscene_launch_command(),
115+ qml_file_path=qml_file_path))
116+ desktop_file.write('[Desktop Entry]\n')
117+ for key, value in self._desktop_file_dict.iteritems():
118+ desktop_file.write('{key}={value}\n'.format(key=key, value=value))
119+ desktop_file.close()
120+ return desktop_file.name
121+
122+ def _get_local_desktop_file_directory(self):
123+ return os.path.join(
124+ os.environ.get('HOME'), '.local', 'share', 'applications')
125
126=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/__init__.py'
127--- tests/autopilot/ubuntuuitoolkit/tests/__init__.py 2014-01-09 15:10:25 +0000
128+++ tests/autopilot/ubuntuuitoolkit/tests/__init__.py 2014-02-12 18:41:59 +0000
129@@ -23,7 +23,7 @@
130 from autopilot.matchers import Eventually
131 from testtools.matchers import Is, Not, Equals
132
133-from ubuntuuitoolkit import base, emulators
134+from ubuntuuitoolkit import base, emulators, fixture_setup
135
136
137 _DESKTOP_FILE_CONTENTS = ("""[Desktop Entry]
138@@ -79,27 +79,22 @@
139 self.launch_application()
140
141 def launch_application(self):
142- qml_file_path = self._write_test_qml_file()
143- self.addCleanup(os.remove, qml_file_path)
144- desktop_file_path = _write_test_desktop_file()
145- self.addCleanup(os.remove, desktop_file_path)
146+ fake_application = fixture_setup.FakeApplication(
147+ qml_file_contents=self.test_qml)
148+ self.useFixture(fake_application)
149+
150 self.app = self.launch_test_application(
151 base.get_qmlscene_launch_command(),
152 '-I' + _get_module_include_path(),
153- qml_file_path,
154- '--desktop_file_hint={0}'.format(desktop_file_path),
155+ fake_application.qml_file_path,
156+ '--desktop_file_hint={0}'.format(
157+ fake_application.desktop_file_path),
158 emulator_base=emulators.UbuntuUIToolkitEmulatorBase,
159 app_type='qt')
160
161 self.assertThat(
162 self.main_view.visible, Eventually(Equals(True)))
163
164- def _write_test_qml_file(self):
165- qml_file = tempfile.NamedTemporaryFile(suffix='.qml', delete=False)
166- qml_file.write(self.test_qml.encode('utf-8'))
167- qml_file.close()
168- return qml_file.name
169-
170 @property
171 def main_view(self):
172 return self.app.select_single(emulators.MainView)
173
174=== added file 'tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py'
175--- tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py 1970-01-01 00:00:00 +0000
176+++ tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py 2014-02-12 18:41:59 +0000
177@@ -0,0 +1,163 @@
178+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
179+#
180+# Copyright (C) 2014 Canonical Ltd.
181+#
182+# This program is free software; you can redistribute it and/or modify
183+# it under the terms of the GNU Lesser General Public License as published by
184+# the Free Software Foundation; version 3.
185+#
186+# This program is distributed in the hope that it will be useful,
187+# but WITHOUT ANY WARRANTY; without even the implied warranty of
188+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
189+# GNU Lesser General Public License for more details.
190+#
191+# You should have received a copy of the GNU Lesser General Public License
192+# along with this program. If not, see <http://www.gnu.org/licenses/>.
193+
194+import os
195+
196+import mock
197+import testtools
198+from autopilot import testcase as autopilot_testcase
199+from testtools.matchers import Contains, Not, FileExists
200+
201+from ubuntuuitoolkit import base, fixture_setup
202+
203+
204+class FakeApplicationTestCase(testtools.TestCase):
205+
206+ def assert_desktop_file_contents(
207+ self, desktop_file_contents, expected_contents_dict):
208+ desktop_file_lines = desktop_file_contents.splitlines()
209+ self.assertEqual('[Desktop Entry]', desktop_file_lines[0])
210+
211+ contents_dict = dict(
212+ [line.split('=') for line in desktop_file_lines[1:]])
213+ self.assertDictEqual(expected_contents_dict, contents_dict)
214+
215+ def test_qml_file_must_be_created_with_specified_contents(self):
216+ fake_application = fixture_setup.FakeApplication(
217+ qml_file_contents='Test')
218+ self.useFixture(fake_application)
219+
220+ with open(fake_application.qml_file_path, 'r+t') as qml_file:
221+ qml_file_contents = qml_file.read()
222+
223+ self.assertEqual('Test', qml_file_contents)
224+
225+ def test_qml_file_with_default_contents(self):
226+ fake_application = fixture_setup.FakeApplication()
227+ self.useFixture(fake_application)
228+
229+ with open(fake_application.qml_file_path, 'r+t') as qml_file:
230+ qml_file_contents = qml_file.read()
231+
232+ self.assertEqual(
233+ fixture_setup.DEFAULT_QML_FILE_CONTENTS, qml_file_contents)
234+
235+ def test_desktop_file_must_be_created_with_specified_values(self):
236+ test_desktop_file_dict = {
237+ 'test key 1': 'test value 1',
238+ 'test key 2': 'test value 2',
239+ 'Exec': 'test',
240+ }
241+ fake_application = fixture_setup.FakeApplication(
242+ desktop_file_dict=test_desktop_file_dict)
243+ self.useFixture(fake_application)
244+
245+ with open(fake_application.desktop_file_path, 'r+t') as desktop_file:
246+ desktop_file_contents = desktop_file.read()
247+
248+ self.assert_desktop_file_contents(
249+ desktop_file_contents, test_desktop_file_dict)
250+
251+ def test_desktop_file_with_qmlscene_launch_command(self):
252+ test_desktop_file_dict = {'Exec': '{qmlscene} application'}
253+
254+ qmlscene = 'ubuntuuitoolkit.base.get_qmlscene_launch_command'
255+ with mock.patch(qmlscene) as mock_qmlscene:
256+ mock_qmlscene.return_value = 'test_qmlscene_command'
257+ fake_application = fixture_setup.FakeApplication(
258+ desktop_file_dict=test_desktop_file_dict)
259+ self.useFixture(fake_application)
260+
261+ with open(fake_application.desktop_file_path, 'r+t') as desktop_file:
262+ desktop_file_contents = desktop_file.read()
263+
264+ self.assertThat(
265+ desktop_file_contents,
266+ Contains('Exec=test_qmlscene_command application'))
267+
268+ def test_desktop_file_with_qml_file_path(self):
269+ test_desktop_file_dict = {'Exec': 'qmlscene {qml_file_path}'}
270+
271+ fake_application = fixture_setup.FakeApplication(
272+ desktop_file_dict=test_desktop_file_dict)
273+ self.useFixture(fake_application)
274+
275+ with open(fake_application.desktop_file_path, 'r+t') as desktop_file:
276+ desktop_file_contents = desktop_file.read()
277+
278+ self.assertThat(
279+ desktop_file_contents,
280+ Contains(
281+ 'Exec=qmlscene {}'.format(fake_application.qml_file_path)))
282+
283+ def test_desktop_file_with_default_contents(self):
284+ qmlscene = 'ubuntuuitoolkit.base.get_qmlscene_launch_command'
285+ with mock.patch(qmlscene) as mock_qmlscene:
286+ mock_qmlscene.return_value = 'qmlscene'
287+ fake_application = fixture_setup.FakeApplication()
288+ self.useFixture(fake_application)
289+
290+ with open(fake_application.desktop_file_path, 'r+t') as desktop_file:
291+ desktop_file_contents = desktop_file.read()
292+
293+ expected_desktop_file_dict = {
294+ 'Type': 'Application',
295+ 'Name': 'test',
296+ 'Icon': 'Not important',
297+ 'Exec': 'qmlscene {}'.format(fake_application.qml_file_path),
298+ }
299+ self.assert_desktop_file_contents(
300+ desktop_file_contents, expected_desktop_file_dict)
301+
302+ def test_desktop_file_must_be_created_in_local_directory(self):
303+ fake_application = fixture_setup.FakeApplication()
304+ self.useFixture(fake_application)
305+
306+ expected_desktop_file_directory = os.path.join(
307+ os.environ.get('HOME'), '.local', 'share', 'applications')
308+ self.assertEqual(
309+ expected_desktop_file_directory,
310+ os.path.dirname(fake_application.desktop_file_path))
311+
312+ def test_fake_application_files_must_be_removed_after_test(self):
313+ fake_application = fixture_setup.FakeApplication()
314+
315+ def inner_test():
316+ class TestWithFakeApplication(testtools.TestCase):
317+ def test_it(self):
318+ self.useFixture(fake_application)
319+ return TestWithFakeApplication('test_it')
320+
321+ inner_test().run()
322+ self.assertThat(fake_application.qml_file_path, Not(FileExists()))
323+ self.assertThat(fake_application.desktop_file_path, Not(FileExists()))
324+
325+
326+class LaunchFakeApplicationTestCase(autopilot_testcase.AutopilotTestCase):
327+
328+ def test_launch_fake_application_with_qmlscene(self):
329+ fake_application = fixture_setup.FakeApplication()
330+ self.useFixture(fake_application)
331+
332+ self.application = self.launch_test_application(
333+ base.get_qmlscene_launch_command(),
334+ fake_application.qml_file_path,
335+ '--desktop_file_hint={0}'.format(
336+ fake_application.desktop_file_path),
337+ app_type='qt')
338+
339+ # We can select a component from the application.
340+ self.application.select_single('Label', objectName='testLabel')

Subscribers

People subscribed via source and target branches

to status/vote changes: