• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3# Copyright 2020 the V8 project authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7from gen_cmake import CMakeBuilder, V8GNTransformer, ParseGN, V8_TARGET_TYPES
8import unittest
9
10
11class CMakeMockBuilder(CMakeBuilder):
12    """
13    Similar to CMakeBuilder but doesn't produce prologues/epilogues.
14    """
15    def BuildPrologue(self):
16        pass
17
18    def BuildEpilogue(self):
19        pass
20
21
22class CMakeGenerationTest(unittest.TestCase):
23    TARGET = 'cppgc_base'
24    CMAKE_TARGET_SOURCES = TARGET.upper() + '_SOURCES'
25
26    def test_source_assignment(self):
27        self._CompileAndCheck(
28            f'set({self.CMAKE_TARGET_SOURCES} "source1.h" "source1.cc")',
29            'sources = [ "source1.h", "source1.cc", ]')
30
31    def test_source_append(self):
32        self._CompileAndCheck(
33            f'list(APPEND {self.CMAKE_TARGET_SOURCES} "source1.h" "source1.cc")',
34            'sources += [ "source1.h", "source1.cc", ]')
35
36    def test_source_remove(self):
37        self._CompileAndCheck(
38            f'list(REMOVE_ITEM {self.CMAKE_TARGET_SOURCES} "source1.h" "source1.cc")',
39            'sources -= [ "source1.h", "source1.cc", ]')
40
41    def test_equal(self):
42        self._CompileExpressionAndCheck('"${CURRENT_CPU}" STREQUAL "x64"',
43                                        'current_cpu == "x64"')
44
45    def test_not_equal(self):
46        self._CompileExpressionAndCheck('NOT "${CURRENT_CPU}" STREQUAL "x86"',
47                                        'current_cpu != "x86"')
48
49    def test_comparison_ops(self):
50        OPS = {
51            '<': 'LESS',
52            '<=': 'LESS_EQUAL',
53            '>': 'GREATER',
54            '>=': 'GREATER_EQUAL',
55        }
56        for gn_op, cmake_op in OPS.items():
57            self._CompileExpressionAndCheck(
58                f'"${{GCC_VERSION}}" {cmake_op} 40802',
59                f'gcc_version {gn_op} 40802')
60
61    def test_parenthesized_expressions(self):
62        self._CompileExpressionAndCheck(
63            '(("${IS_POSIX}" AND NOT "${IS_ANDROID}") OR "${IS_FUCHSIA}") AND NOT "${USING_SANITIZER}"',
64            '((is_posix && !is_android) || is_fuchsia) && !using_sanitizer')
65
66    def test_conditional_statements(self):
67        self._CompileAndCheck(
68            f"""
69if("${{IS_POSIX}}")
70  list(APPEND {self.CMAKE_TARGET_SOURCES} "unistd.h")
71else()
72  list(REMOVE_ITEM {self.CMAKE_TARGET_SOURCES} "unistd.h")
73endif()
74            """, """
75if (is_posix) {
76  sources += ["unistd.h"]
77} else {
78  sources -= ["unistd.h"]
79}
80            """)
81
82    def test_conditional_statements_elseif(self):
83        self._CompileAndCheck(
84            f"""
85if("${{IS_POSIX}}")
86  list(APPEND {self.CMAKE_TARGET_SOURCES} "unistd.h")
87elseif("${{IS_WIN}}")
88  list(REMOVE_ITEM {self.CMAKE_TARGET_SOURCES} "unistd.h")
89endif()
90            """, """
91if (is_posix) {
92  sources += ["unistd.h"]
93} else if (is_win) {
94  sources -= ["unistd.h"]
95}
96            """)
97
98    def _Compile(self, gn_string):
99        gn_code = f'v8_component({self.TARGET}) {{ {gn_string} }}'
100        tree = ParseGN(gn_code)
101        builder = CMakeMockBuilder()
102        V8GNTransformer(builder, [self.TARGET]).Traverse(tree)
103        return builder.GetResult()
104
105    def _CompileAndCheck(self, expected_cmake, gn_string):
106        actual_cmake = self._Compile(gn_string)
107        self.assertIn(self._Canonicalize(expected_cmake),
108                      self._Canonicalize(actual_cmake))
109        pass
110
111    def _CompileExpressionAndCheck(self, expected_cmake, gn_string):
112        gn_string = f'if ({gn_string}) {{ sources = [ "source.cc" ] }}'
113        expected_cmake = f'if({expected_cmake})'
114        actual_cmake = self._Compile(gn_string)
115        self.assertIn(self._Canonicalize(expected_cmake),
116                      self._Canonicalize(actual_cmake))
117        pass
118
119    @staticmethod
120    def _Canonicalize(str):
121        return ' '.join(str.split()).strip()
122
123
124if __name__ == '__main__':
125    unittest.main()
126