1#!/usr/bin/env python3
2#
3# Copyright 2019 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17
18"""Unittests for clion_project_file_gen."""
19
20import os
21import unittest
22from unittest import mock
23
24from io import StringIO
25
26from aidegen import constant
27from aidegen import templates
28from aidegen.lib import clion_project_file_gen
29from aidegen.lib import common_util
30from aidegen.lib import errors
31from aidegen.lib import native_module_info
32
33
34# pylint: disable=protected-access
35# pylint: disable=too-many-arguments
36class ClionProjectFileGenUnittests(unittest.TestCase):
37    """Unit tests for clion_project_file_gen.py."""
38
39    _FLAG_LIST = ['a', 'b']
40    _FLAG_DICT = {clion_project_file_gen._KEY_FLAG: _FLAG_LIST}
41    _MOD_INFO = {clion_project_file_gen._KEY_GLOBAL_COMMON_FLAGS: _FLAG_DICT}
42    _MOD_PATH = 'path_to_mod'
43    _PATH_DICT = {'path': [_MOD_PATH]}
44    _MOD_NAME = 'M'
45    _MOD_NAME_DICT = {'module_name': _MOD_NAME}
46    _ROOT_DIR = 'path_to_root'
47    _SRC_PATH = 'path_to_src'
48    _SRC_DICT = {constant.KEY_SRCS: [_SRC_PATH]}
49
50    def test_init_without_mod_info(self):
51        """Test __init__ without mod_info."""
52        with self.assertRaises(errors.ModuleInfoEmptyError):
53            clion_project_file_gen.CLionProjectFileGenerator({})
54
55    @mock.patch('os.path.exists')
56    def test_init_with_mod_info_without_mod_name(self, mock_exists):
57        """Test __init__ with mod_info but without the module name."""
58        mod_info = dict(self._MOD_INFO)
59        mod_info.update(self._PATH_DICT)
60        mock_exists.return_value = True
61        with self.assertRaises(errors.NoModuleNameDefinedInModuleInfoError):
62            clion_project_file_gen.CLionProjectFileGenerator(mod_info)
63
64    @mock.patch('os.path.exists')
65    def test_init_with_mod_info_without_mod_path(self, mock_exists):
66        """Test __init__ with mod_info but without the module path."""
67        mod_info = dict(self._MOD_INFO)
68        mod_info.update(self._MOD_NAME_DICT)
69        mock_exists.return_value = True
70        with self.assertRaises(errors.NoPathDefinedInModuleInfoError):
71            clion_project_file_gen.CLionProjectFileGenerator(mod_info)
72
73    @mock.patch.object(os, 'makedirs')
74    @mock.patch.object(os.path, 'exists')
75    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
76                       'get_cmakelists_file_dir')
77    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
78                       'get_module_path')
79    def test_init_with_mod_info_makedir(
80            self, mock_get_path, mock_get_cmake, mock_exists, mock_mkdirs):
81        """Test __init__ with mod_info and check if need to make dir."""
82        mod_info = dict(self._MOD_INFO)
83        mod_info.update(self._MOD_NAME_DICT)
84        mock_get_path.return_value = self._MOD_PATH
85        mock_get_cmake.return_value = self._SRC_PATH
86        mock_exists.return_value = True
87        clion_project_file_gen.CLionProjectFileGenerator(mod_info)
88        self.assertFalse(mock_mkdirs.called)
89        mock_mkdirs.mock_reset()
90        mock_exists.return_value = False
91        clion_project_file_gen.CLionProjectFileGenerator(mod_info)
92        self.assertTrue(mock_mkdirs.called)
93
94    @mock.patch('os.path.exists')
95    def test_write_header(self, mock_exists):
96        """Test _write_header function."""
97        hfile = StringIO()
98        mock_exists.return_value = True
99        mod_info = dict(self._MOD_INFO)
100        mod_info.update(self._PATH_DICT)
101        mod_info.update(self._MOD_NAME_DICT)
102        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
103        clion_gen._write_header(hfile)
104        hfile.seek(0)
105        content = hfile.read()
106        expected = templates.CMAKELISTS_HEADER.replace(
107            clion_project_file_gen._MIN_VERSION_TOKEN,
108            clion_project_file_gen._MINI_VERSION)
109        expected = expected.replace(
110            clion_project_file_gen._PROJECT_NAME_TOKEN, clion_gen.mod_name)
111        expected = expected.replace(
112            clion_project_file_gen._ANDOIR_ROOT_TOKEN,
113            common_util.get_android_root_dir())
114        self.assertEqual(content, expected)
115
116    @mock.patch('os.path.exists')
117    def test_write_c_compiler_paths(self, mock_exists):
118        """Test _write_c_compiler_paths function."""
119        hfile = StringIO()
120        c_lang_path = 'c_lang_path'
121        cpp_lang_path = 'cpp_lang_path'
122        native_module_info.NativeModuleInfo.c_lang_path = c_lang_path
123        native_module_info.NativeModuleInfo.cpp_lang_path = cpp_lang_path
124        mock_exists.return_value = True
125        mod_info = dict(self._MOD_INFO)
126        mod_info.update(self._PATH_DICT)
127        mod_info.update(self._MOD_NAME_DICT)
128        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
129        clion_gen._write_c_compiler_paths(hfile)
130        hfile.seek(0)
131        content = hfile.read()
132        expected = clion_project_file_gen._SET_C_COMPILER.format(
133            c_lang_path) + clion_project_file_gen._SET_CXX_COMPILER.format(
134                cpp_lang_path)
135        self.assertEqual(content, expected)
136
137    @mock.patch('os.path.exists')
138    def test_write_source_files_without_content(self, mock_exists):
139        """Test _write_source_files function without content."""
140        hfile = StringIO()
141        mock_exists.return_value = True
142        mod_info = dict(self._MOD_INFO)
143        mod_info.update(self._PATH_DICT)
144        mod_info.update(self._MOD_NAME_DICT)
145        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
146        clion_gen._write_source_files(hfile)
147        hfile.seek(0)
148        content = hfile.read()
149        expected = ''
150        self.assertEqual(content, expected)
151
152    @mock.patch('os.path.exists')
153    def test_write_source_files_with_content(self, mock_exists):
154        """Test _write_source_files function with content."""
155        hfile = StringIO()
156        mod_info = dict(self._MOD_INFO)
157        mod_info.update(self._PATH_DICT)
158        mod_info.update(self._MOD_NAME_DICT)
159        mod_info.update(self._SRC_DICT)
160        mock_exists.return_value = True
161        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
162        clion_gen._write_source_files(hfile)
163        hfile.seek(0)
164        content = hfile.read()
165        srcs = clion_project_file_gen._build_cmake_path(self._SRC_PATH, '    ')
166        header = clion_project_file_gen._LIST_APPEND_HEADER
167        src_heads = ['     ', clion_project_file_gen._SOURCE_FILES_HEADER, '\n']
168        tail = ')\n'
169        expected = header + ''.join(src_heads) + srcs + '\n' + tail
170        self.assertEqual(content, expected)
171
172    @mock.patch('os.path.exists')
173    def test_write_flags_without_content(self, mock_exists):
174        """Test _write_flags function without content."""
175        hfile = StringIO()
176        mod_info = dict(self._PATH_DICT)
177        mod_info.update(self._MOD_NAME_DICT)
178        key = clion_project_file_gen._KEY_GLOBAL_COMMON_FLAGS
179        mock_exists.return_value = True
180        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
181        clion_gen._write_flags(hfile, key, True, True)
182        hfile.seek(0)
183        content = hfile.read()
184        expected = clion_project_file_gen._FLAGS_DICT.get(key, '')
185        self.assertEqual(content, expected)
186
187    @mock.patch('os.path.exists')
188    def test_parse_compiler_parameters_without_flag(self, mock_exists):
189        """Test _parse_compiler_parameters function without flag."""
190        mod_info = dict(self._PATH_DICT)
191        mod_info.update(self._MOD_NAME_DICT)
192        mock_exists.return_value = True
193        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
194        result = clion_gen._parse_compiler_parameters(
195            clion_project_file_gen._KEY_GLOBAL_COMMON_FLAGS)
196        self.assertEqual(result, None)
197
198    @mock.patch('os.path.exists')
199    def test_parse_compiler_parameters_with_flag(self, mock_exists):
200        """Test _parse_compiler_parameters function with flag."""
201        mod_info = dict(self._MOD_INFO)
202        mod_info.update(self._PATH_DICT)
203        mod_info.update(self._MOD_NAME_DICT)
204        expected = {
205            constant.KEY_HEADER: [],
206            constant.KEY_SYSTEM: [],
207            clion_project_file_gen._KEY_FLAG: self._FLAG_LIST,
208            clion_project_file_gen._KEY_SYSTEM_ROOT: '',
209            clion_project_file_gen._KEY_RELATIVE: {}
210        }
211        mock_exists.return_value = True
212        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
213        flag = clion_project_file_gen._KEY_GLOBAL_COMMON_FLAGS
214        ret = clion_gen._parse_compiler_parameters(flag)
215        self.assertEqual(ret, expected)
216
217    @mock.patch.object(clion_project_file_gen, '_write_all_flags')
218    @mock.patch.object(clion_project_file_gen,
219                       '_write_all_relative_file_path_flags')
220    @mock.patch.object(clion_project_file_gen, '_write_all_include_directories')
221    def test_translate_to_cmake_with_empty_dict(
222            self, mock_write_all_inc, mock_write_rel, mock_write_all_flags):
223        """Test _translate_to_cmake function with empty dictionary."""
224        hfile = StringIO()
225        params_dict = {
226            constant.KEY_HEADER: [],
227            constant.KEY_SYSTEM: [],
228            clion_project_file_gen._KEY_FLAG: [],
229            clion_project_file_gen._KEY_SYSTEM_ROOT: '',
230            clion_project_file_gen._KEY_RELATIVE: {}
231        }
232        clion_project_file_gen._translate_to_cmake(hfile, params_dict, True,
233                                                   True)
234        hfile.seek(0)
235        content = hfile.read()
236        self.assertEqual(content, '')
237        self.assertTrue(mock_write_all_inc.call_count, 2)
238        self.assertTrue(mock_write_rel, 2)
239        self.assertTrue(mock_write_all_flags, 2)
240
241        mock_write_all_inc.mock_reset()
242        mock_write_rel.mock_reset()
243        mock_write_all_flags.mock_reset()
244        clion_project_file_gen._translate_to_cmake(hfile, params_dict, False,
245                                                   True)
246        hfile.seek(0)
247        content = hfile.read()
248        self.assertEqual(content, '')
249        self.assertTrue(mock_write_all_inc.call_count, 2)
250        self.assertTrue(mock_write_rel, 1)
251        self.assertTrue(mock_write_all_flags, 1)
252
253        mock_write_all_inc.mock_reset()
254        mock_write_rel.mock_reset()
255        mock_write_all_flags.mock_reset()
256        clion_project_file_gen._translate_to_cmake(hfile, params_dict, True,
257                                                   False)
258        hfile.seek(0)
259        content = hfile.read()
260        self.assertEqual(content, '')
261        self.assertTrue(mock_write_all_inc.call_count, 2)
262        self.assertTrue(mock_write_rel, 1)
263        self.assertTrue(mock_write_all_flags, 1)
264
265    @mock.patch.object(clion_project_file_gen, '_write_all_flags')
266    @mock.patch.object(clion_project_file_gen,
267                       '_write_all_relative_file_path_flags')
268    @mock.patch.object(clion_project_file_gen, '_write_all_include_directories')
269    def test_translate_to_cmake_with_system_root_info(
270            self, mock_write_all_inc, mock_write_rel, mock_write_all_flags):
271        """Test _translate_to_cmake function with empty dictionary."""
272        hfile = StringIO()
273        root = 'path_to_root'
274        params_dict = {
275            constant.KEY_HEADER: [],
276            constant.KEY_SYSTEM: [],
277            clion_project_file_gen._KEY_FLAG: [],
278            clion_project_file_gen._KEY_SYSTEM_ROOT: root,
279            clion_project_file_gen._KEY_RELATIVE: {}
280        }
281        clion_project_file_gen._translate_to_cmake(hfile, params_dict, True,
282                                                   False)
283        hfile.seek(0)
284        content = hfile.read()
285        path = os.path.join(
286            root, clion_project_file_gen._USR, clion_project_file_gen._INCLUDE)
287        expected = clion_project_file_gen._INCLUDE_SYSTEM.format(
288            clion_project_file_gen._build_cmake_path(path))
289        self.assertEqual(content, expected)
290        self.assertTrue(mock_write_all_inc.call_count, 2)
291        self.assertTrue(mock_write_rel, 1)
292        self.assertTrue(mock_write_all_flags, 1)
293
294    def test_write_all_relative_flags_without_content(self):
295        """Test _write_all_relative_file_path_flags function without content."""
296        hfile = StringIO()
297        clion_project_file_gen._write_all_relative_file_path_flags(
298            hfile, {}, '')
299        hfile.seek(0)
300        content = hfile.read()
301        self.assertEqual(content, '')
302
303    def test_write_all_relative_flags_with_content(self):
304        """Test _write_all_relative_file_path_flags function with content."""
305        hfile = StringIO()
306        flag = 'flag'
307        path = 'path_to_rel'
308        tag = '_CMAKE_C_FLAGS'
309        clion_project_file_gen._write_all_relative_file_path_flags(
310            hfile, {flag: path}, tag)
311        hfile.seek(0)
312        content = hfile.read()
313        expected = clion_project_file_gen._SET_RELATIVE_PATH.format(
314            tag, clion_project_file_gen._add_dollar_sign(tag), flag,
315            clion_project_file_gen._build_cmake_path(path))
316        self.assertEqual(content, expected)
317
318    def test_add_dollar_sign(self):
319        """Test _add_dollar_sign function."""
320        param = 'ANDROID'
321        expected = '${ANDROID}'
322        result = clion_project_file_gen._add_dollar_sign(param)
323        self.assertEqual(expected, result)
324
325    def test_write_all_flags_without_content(self):
326        """Test _write_all_flags function without content."""
327        hfile = StringIO()
328        clion_project_file_gen._write_all_flags(hfile, [], '')
329        hfile.seek(0)
330        content = hfile.read()
331        self.assertEqual(content, '')
332
333    def test_write_all_flags_with_content(self):
334        """Test _write_all_flags function with content."""
335        hfile = StringIO()
336        flag = 'flag'
337        tag = '_CMAKE_C_FLAGS'
338        clion_project_file_gen._write_all_flags(hfile, [flag], tag)
339        hfile.seek(0)
340        content = hfile.read()
341        expected = clion_project_file_gen._SET_ALL_FLAGS.format(
342            tag, clion_project_file_gen._add_dollar_sign(tag), flag)
343        self.assertEqual(content, expected)
344
345    def test_build_cmake_path_without_tag(self):
346        """Test _build_cmake_path function without tag."""
347        param = 'prebuilts/clang/host/linux-x86/clang-r370808/bin/clang'
348        expected = ('${ANDROID_ROOT}/prebuilts/clang/host/linux-x86/'
349                    'clang-r370808/bin/clang')
350        result = clion_project_file_gen._build_cmake_path(param)
351        self.assertEqual(expected, result)
352
353    def test_build_cmake_path_with_tag(self):
354        """Test _build_cmake_path function with tag."""
355        param = 'prebuilts/clang/host/linux-x86/clang-r370808/bin/clang'
356        tag = '    '
357        expected = ('    ${ANDROID_ROOT}/prebuilts/clang/host/linux-x86/'
358                    'clang-r370808/bin/clang')
359        result = clion_project_file_gen._build_cmake_path(param, tag)
360        self.assertEqual(expected, result)
361
362    def test_write_all_includes_without_content(self):
363        """Test _write_all_includes function without content."""
364        hfile = StringIO()
365        clion_project_file_gen._write_all_includes(hfile, [], True)
366        hfile.seek(0)
367        content = hfile.read()
368        self.assertEqual(content, '')
369        clion_project_file_gen._write_all_includes(hfile, [], False)
370        hfile.seek(0)
371        content = hfile.read()
372        self.assertEqual(content, '')
373
374    def test_write_all_includes_with_content(self):
375        """Test _write_all_includes function with content."""
376        hfile = StringIO()
377        include = 'path_to_include'
378        clion_project_file_gen._write_all_includes(hfile, [include], True)
379        hfile.seek(0)
380        content = hfile.read()
381        system = clion_project_file_gen._SYSTEM
382        head = clion_project_file_gen._INCLUDE_DIR.format(system)
383        middle = clion_project_file_gen._SET_INCLUDE_FORMAT.format(
384            clion_project_file_gen._build_cmake_path(include))
385        tail = clion_project_file_gen._END_WITH_TWO_BLANK_LINES
386        expected = head + middle + tail
387        self.assertEqual(content, expected)
388        hfile = StringIO()
389        clion_project_file_gen._write_all_includes(hfile, [include], False)
390        hfile.seek(0)
391        content = hfile.read()
392        head = clion_project_file_gen._INCLUDE_DIR.format('')
393        expected = head + middle + tail
394        self.assertEqual(content, expected)
395
396    @mock.patch('os.path.exists')
397    @mock.patch.object(clion_project_file_gen, '_translate_to_cmake')
398    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
399                       '_parse_compiler_parameters')
400    def test_write_flags_with_content(
401            self, mock_parse, mock_translate, mock_exists):
402        """Test _write_flags function with content."""
403        mock_exists.return_value = True
404        hfile = StringIO()
405        mod_info = dict(self._MOD_INFO)
406        mod_info.update(self._PATH_DICT)
407        mod_info.update(self._MOD_NAME_DICT)
408        mock_exists.return_value = True
409        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
410        key = clion_project_file_gen._KEY_GLOBAL_COMMON_FLAGS
411        clion_gen._write_flags(hfile, key, True, True)
412        self.assertTrue(mock_parse.called)
413        self.assertTrue(mock_translate.called)
414
415    @mock.patch('os.path.exists')
416    @mock.patch.object(clion_project_file_gen, '_translate_to_cmake')
417    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
418                       '_parse_compiler_parameters')
419    def test_write_flags_with_content_key_not_exists(
420            self, mock_parse, mock_translate, mock_exists):
421        """Test _write_flags function with content, key not in _FLAGS_DICT."""
422        mock_exists.return_value = True
423        hfile = StringIO()
424        mod_info = dict(self._MOD_INFO)
425        mod_info.update(self._PATH_DICT)
426        mod_info.update(self._MOD_NAME_DICT)
427        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
428        key = constant.KEY_PATH
429        clion_gen._write_flags(hfile, key, True, True)
430        self.assertFalse(mock_parse.called)
431        self.assertFalse(mock_translate.called)
432
433    def test_write_all_include_directories_without_content(self):
434        """Test _write_all_include_directories function without content."""
435        hfile = StringIO()
436        clion_project_file_gen._write_all_include_directories(hfile, [], True)
437        hfile.seek(0)
438        content = hfile.read()
439        self.assertEqual(content, '')
440        clion_project_file_gen._write_all_include_directories(hfile, [], False)
441        hfile.seek(0)
442        content = hfile.read()
443        self.assertEqual(content, '')
444
445    @mock.patch.object(clion_project_file_gen, '_write_all_headers')
446    @mock.patch.object(clion_project_file_gen, '_write_all_includes')
447    def test_write_all_include_directories_with_content(self, mock_includes,
448                                                        mock_headers):
449        """Test _write_all_include_directories function with content."""
450        hfile = StringIO()
451        includes = ['path_to_include']
452        clion_project_file_gen._write_all_include_directories(
453            hfile, includes, True)
454        self.assertTrue(mock_includes.called)
455        self.assertTrue(mock_headers.called)
456        clion_project_file_gen._write_all_include_directories(
457            hfile, includes, False)
458        self.assertTrue(mock_includes.called)
459        self.assertTrue(mock_headers.called)
460
461    def test_write_all_headers_without_content(self):
462        """Test _write_all_headers function without content."""
463        hfile = StringIO()
464        clion_project_file_gen._write_all_headers(hfile, [])
465        hfile.seek(0)
466        content = hfile.read()
467        self.assertEqual(content, '')
468
469    def test_write_all_headers_with_content(self):
470        """Test _write_all_headers function with content."""
471        hfile = StringIO()
472        include = 'path_to_include'
473        clion_project_file_gen._write_all_headers(hfile, [include])
474        hfile.seek(0)
475        content = hfile.read()
476        head = clion_project_file_gen._GLOB_RECURSE_TMP_HEADERS
477        middle = clion_project_file_gen._ALL_HEADER_FILES.format(
478            clion_project_file_gen._build_cmake_path(include))
479        tail1 = clion_project_file_gen._END_WITH_ONE_BLANK_LINE
480        tail2 = clion_project_file_gen._APPEND_SOURCE_FILES
481        expected = head + middle + tail1 + tail2
482        self.assertEqual(content, expected)
483
484    def test_cleanup_executable_name(self):
485        """Test _cleanup_executable_name function with conditions."""
486        mod_name = 'android.frameworks.bufferhub@1.0-service'
487        result = 'android.frameworks.bufferhub-1.0-service'
488        self.assertEqual(
489            result, clion_project_file_gen._cleanup_executable_name(mod_name))
490        mod_name = 'libui'
491        result = 'libui'
492        self.assertEqual(
493            result, clion_project_file_gen._cleanup_executable_name(mod_name))
494
495    @mock.patch('os.path.exists')
496    @mock.patch('builtins.open')
497    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
498                       '_write_cmakelists_file')
499    def test_generate_cmakelists_file(self, mock_write, mock_open, mock_exists):
500        """Test generate_cmakelists_file with handlings."""
501        mock_exists.return_value = True
502        mod_info = dict(self._MOD_INFO)
503        mod_info.update(self._PATH_DICT)
504        mod_info.update(self._MOD_NAME_DICT)
505        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
506        clion_gen.generate_cmakelists_file()
507        self.assertTrue(mock_open.called)
508        self.assertTrue(mock_write.called)
509
510    @mock.patch('os.path.exists')
511    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
512                       '_write_tail')
513    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
514                       '_write_cmakelists_flags')
515    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
516                       '_write_source_files')
517    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
518                       '_write_c_compiler_paths')
519    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
520                       '_write_header')
521    def test_write_cmakelists_file(self, mock_head, mock_comp, mock_src,
522                                   mock_flag, mock_tail, mock_exists):
523        """Test _write_cmakelists_file with handlings."""
524        mock_exists.return_value = True
525        mod_info = dict(self._MOD_INFO)
526        mod_info.update(self._PATH_DICT)
527        mod_info.update(self._MOD_NAME_DICT)
528        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
529        hfile = StringIO()
530        clion_gen._write_cmakelists_file(hfile)
531        self.assertTrue(mock_head.called)
532        self.assertTrue(mock_comp.called)
533        self.assertTrue(mock_src.called)
534        self.assertTrue(mock_flag.called)
535        self.assertTrue(mock_tail.called)
536
537    @mock.patch('os.path.exists')
538    @mock.patch.object(clion_project_file_gen.CLionProjectFileGenerator,
539                       '_write_flags')
540    def test_write_cmakelists_flags(self, mock_flags, mock_exists):
541        """Test _write_cmakelists_file with handlings."""
542        mock_exists.return_value = True
543        mod_info = dict(self._MOD_INFO)
544        mod_info.update(self._PATH_DICT)
545        mod_info.update(self._MOD_NAME_DICT)
546        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
547        hfile = StringIO()
548        clion_gen._write_cmakelists_flags(hfile)
549        self.assertEqual(mock_flags.call_count, 9)
550
551    @mock.patch('os.path.exists')
552    def test_write_tail(self, mock_exists):
553        """Test _write_tail with handlings."""
554        mock_exists.return_value = True
555        mod_info = dict(self._MOD_INFO)
556        mod_info.update(self._PATH_DICT)
557        mod_info.update(self._MOD_NAME_DICT)
558        clion_gen = clion_project_file_gen.CLionProjectFileGenerator(mod_info)
559        hfile = StringIO()
560        clion_gen._write_tail(hfile)
561        hfile.seek(0)
562        content = hfile.read()
563        expected = clion_project_file_gen._ADD_EXECUTABLE_HEADER.format(
564            clion_project_file_gen._cleanup_executable_name(clion_gen.mod_name),
565            clion_project_file_gen._add_dollar_sign(
566                clion_project_file_gen._SOURCE_FILES_HEADER))
567        self.assertEqual(content, expected)
568
569    def test_get_module_path(self):
570        """Test get_module_path function with conditions."""
571        path_b = 'a/b/path_a_to_A'
572        path_c = 'a/c/path_a_to_A'
573        path_d = 'a/d/path_a_to_A'
574        mod_info = {
575            'module_name': 'A_Mod',
576            'path': [
577                path_b,
578                path_c,
579                path_d,
580            ]
581        }
582        res = clion_project_file_gen.CLionProjectFileGenerator.get_module_path(
583            mod_info)
584        self.assertEqual(res, path_b)
585        res = clion_project_file_gen.CLionProjectFileGenerator.get_module_path(
586            mod_info, 'a/b')
587        self.assertEqual(res, path_b)
588        res = clion_project_file_gen.CLionProjectFileGenerator.get_module_path(
589            mod_info, 'a/c')
590        self.assertEqual(res, path_c)
591        res = clion_project_file_gen.CLionProjectFileGenerator.get_module_path(
592            mod_info, 'a/d')
593        self.assertEqual(res, path_d)
594
595if __name__ == '__main__':
596    unittest.main()
597