11cb0ef41Sopenharmony_ci#!/usr/bin/env python3
21cb0ef41Sopenharmony_ci#
31cb0ef41Sopenharmony_ci# Copyright 2020 the V8 project authors. All rights reserved.
41cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
51cb0ef41Sopenharmony_ci# found in the LICENSE file.
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cifrom gen_cmake import CMakeBuilder, V8GNTransformer, ParseGN, V8_TARGET_TYPES
81cb0ef41Sopenharmony_ciimport unittest
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciclass CMakeMockBuilder(CMakeBuilder):
121cb0ef41Sopenharmony_ci    """
131cb0ef41Sopenharmony_ci    Similar to CMakeBuilder but doesn't produce prologues/epilogues.
141cb0ef41Sopenharmony_ci    """
151cb0ef41Sopenharmony_ci    def BuildPrologue(self):
161cb0ef41Sopenharmony_ci        pass
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci    def BuildEpilogue(self):
191cb0ef41Sopenharmony_ci        pass
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ciclass CMakeGenerationTest(unittest.TestCase):
231cb0ef41Sopenharmony_ci    TARGET = 'cppgc_base'
241cb0ef41Sopenharmony_ci    CMAKE_TARGET_SOURCES = TARGET.upper() + '_SOURCES'
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci    def test_source_assignment(self):
271cb0ef41Sopenharmony_ci        self._CompileAndCheck(
281cb0ef41Sopenharmony_ci            f'set({self.CMAKE_TARGET_SOURCES} "source1.h" "source1.cc")',
291cb0ef41Sopenharmony_ci            'sources = [ "source1.h", "source1.cc", ]')
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci    def test_source_append(self):
321cb0ef41Sopenharmony_ci        self._CompileAndCheck(
331cb0ef41Sopenharmony_ci            f'list(APPEND {self.CMAKE_TARGET_SOURCES} "source1.h" "source1.cc")',
341cb0ef41Sopenharmony_ci            'sources += [ "source1.h", "source1.cc", ]')
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci    def test_source_remove(self):
371cb0ef41Sopenharmony_ci        self._CompileAndCheck(
381cb0ef41Sopenharmony_ci            f'list(REMOVE_ITEM {self.CMAKE_TARGET_SOURCES} "source1.h" "source1.cc")',
391cb0ef41Sopenharmony_ci            'sources -= [ "source1.h", "source1.cc", ]')
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci    def test_equal(self):
421cb0ef41Sopenharmony_ci        self._CompileExpressionAndCheck('"${CURRENT_CPU}" STREQUAL "x64"',
431cb0ef41Sopenharmony_ci                                        'current_cpu == "x64"')
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci    def test_not_equal(self):
461cb0ef41Sopenharmony_ci        self._CompileExpressionAndCheck('NOT "${CURRENT_CPU}" STREQUAL "x86"',
471cb0ef41Sopenharmony_ci                                        'current_cpu != "x86"')
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci    def test_comparison_ops(self):
501cb0ef41Sopenharmony_ci        OPS = {
511cb0ef41Sopenharmony_ci            '<': 'LESS',
521cb0ef41Sopenharmony_ci            '<=': 'LESS_EQUAL',
531cb0ef41Sopenharmony_ci            '>': 'GREATER',
541cb0ef41Sopenharmony_ci            '>=': 'GREATER_EQUAL',
551cb0ef41Sopenharmony_ci        }
561cb0ef41Sopenharmony_ci        for gn_op, cmake_op in OPS.items():
571cb0ef41Sopenharmony_ci            self._CompileExpressionAndCheck(
581cb0ef41Sopenharmony_ci                f'"${{GCC_VERSION}}" {cmake_op} 40802',
591cb0ef41Sopenharmony_ci                f'gcc_version {gn_op} 40802')
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci    def test_parenthesized_expressions(self):
621cb0ef41Sopenharmony_ci        self._CompileExpressionAndCheck(
631cb0ef41Sopenharmony_ci            '(("${IS_POSIX}" AND NOT "${IS_ANDROID}") OR "${IS_FUCHSIA}") AND NOT "${USING_SANITIZER}"',
641cb0ef41Sopenharmony_ci            '((is_posix && !is_android) || is_fuchsia) && !using_sanitizer')
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci    def test_conditional_statements(self):
671cb0ef41Sopenharmony_ci        self._CompileAndCheck(
681cb0ef41Sopenharmony_ci            f"""
691cb0ef41Sopenharmony_ciif("${{IS_POSIX}}")
701cb0ef41Sopenharmony_ci  list(APPEND {self.CMAKE_TARGET_SOURCES} "unistd.h")
711cb0ef41Sopenharmony_cielse()
721cb0ef41Sopenharmony_ci  list(REMOVE_ITEM {self.CMAKE_TARGET_SOURCES} "unistd.h")
731cb0ef41Sopenharmony_ciendif()
741cb0ef41Sopenharmony_ci            """, """
751cb0ef41Sopenharmony_ciif (is_posix) {
761cb0ef41Sopenharmony_ci  sources += ["unistd.h"]
771cb0ef41Sopenharmony_ci} else {
781cb0ef41Sopenharmony_ci  sources -= ["unistd.h"]
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci            """)
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci    def test_conditional_statements_elseif(self):
831cb0ef41Sopenharmony_ci        self._CompileAndCheck(
841cb0ef41Sopenharmony_ci            f"""
851cb0ef41Sopenharmony_ciif("${{IS_POSIX}}")
861cb0ef41Sopenharmony_ci  list(APPEND {self.CMAKE_TARGET_SOURCES} "unistd.h")
871cb0ef41Sopenharmony_cielseif("${{IS_WIN}}")
881cb0ef41Sopenharmony_ci  list(REMOVE_ITEM {self.CMAKE_TARGET_SOURCES} "unistd.h")
891cb0ef41Sopenharmony_ciendif()
901cb0ef41Sopenharmony_ci            """, """
911cb0ef41Sopenharmony_ciif (is_posix) {
921cb0ef41Sopenharmony_ci  sources += ["unistd.h"]
931cb0ef41Sopenharmony_ci} else if (is_win) {
941cb0ef41Sopenharmony_ci  sources -= ["unistd.h"]
951cb0ef41Sopenharmony_ci}
961cb0ef41Sopenharmony_ci            """)
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci    def _Compile(self, gn_string):
991cb0ef41Sopenharmony_ci        gn_code = f'v8_component({self.TARGET}) {{ {gn_string} }}'
1001cb0ef41Sopenharmony_ci        tree = ParseGN(gn_code)
1011cb0ef41Sopenharmony_ci        builder = CMakeMockBuilder()
1021cb0ef41Sopenharmony_ci        V8GNTransformer(builder, [self.TARGET]).Traverse(tree)
1031cb0ef41Sopenharmony_ci        return builder.GetResult()
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci    def _CompileAndCheck(self, expected_cmake, gn_string):
1061cb0ef41Sopenharmony_ci        actual_cmake = self._Compile(gn_string)
1071cb0ef41Sopenharmony_ci        self.assertIn(self._Canonicalize(expected_cmake),
1081cb0ef41Sopenharmony_ci                      self._Canonicalize(actual_cmake))
1091cb0ef41Sopenharmony_ci        pass
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci    def _CompileExpressionAndCheck(self, expected_cmake, gn_string):
1121cb0ef41Sopenharmony_ci        gn_string = f'if ({gn_string}) {{ sources = [ "source.cc" ] }}'
1131cb0ef41Sopenharmony_ci        expected_cmake = f'if({expected_cmake})'
1141cb0ef41Sopenharmony_ci        actual_cmake = self._Compile(gn_string)
1151cb0ef41Sopenharmony_ci        self.assertIn(self._Canonicalize(expected_cmake),
1161cb0ef41Sopenharmony_ci                      self._Canonicalize(actual_cmake))
1171cb0ef41Sopenharmony_ci        pass
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci    @staticmethod
1201cb0ef41Sopenharmony_ci    def _Canonicalize(str):
1211cb0ef41Sopenharmony_ci        return ' '.join(str.split()).strip()
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ciif __name__ == '__main__':
1251cb0ef41Sopenharmony_ci    unittest.main()
126