1# Copyright 2022 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Tests for pw_build.project_builder_prefs""" 15 16import argparse 17import copy 18from pathlib import Path 19import tempfile 20from typing import Any, Dict 21import unittest 22from unittest.mock import MagicMock 23 24from pw_build.project_builder_argparse import add_project_builder_arguments 25from pw_build.project_builder_prefs import ( 26 ProjectBuilderPrefs, 27 _DEFAULT_CONFIG, 28 load_defaults_from_argparse, 29) 30 31 32def _create_tempfile(content: str) -> Path: 33 with tempfile.NamedTemporaryFile( 34 prefix=f'{__package__}', delete=False 35 ) as output_file: 36 output_file.write(content.encode('UTF-8')) 37 return Path(output_file.name) 38 39 40class TestProjectBuilderPrefs(unittest.TestCase): 41 """Tests for ProjectBuilderPrefs.""" 42 43 def setUp(self): 44 self.maxDiff = None # pylint: disable=invalid-name 45 46 def test_load_no_existing_files(self) -> None: 47 # Create a prefs instance with no loaded config. 48 prefs = ProjectBuilderPrefs( 49 load_argparse_arguments=add_project_builder_arguments, 50 project_file=False, 51 project_user_file=False, 52 user_file=False, 53 ) 54 # Construct an expected result config. 55 expected_config: Dict[Any, Any] = {} 56 expected_config.update(_DEFAULT_CONFIG) 57 expected_config.update( 58 load_defaults_from_argparse(add_project_builder_arguments) 59 ) 60 61 self.assertEqual( 62 prefs._config, expected_config # pylint: disable=protected-access 63 ) 64 65 def test_apply_command_line_args(self) -> None: 66 """Check command line args are applied to watch preferences.""" 67 # Load default command line arg values. 68 defaults_from_argparse = load_defaults_from_argparse( 69 add_project_builder_arguments 70 ) 71 72 # Create a prefs instance with the test config file. 73 prefs = ProjectBuilderPrefs( 74 load_argparse_arguments=add_project_builder_arguments, 75 project_file=False, 76 project_user_file=False, 77 user_file=False, 78 ) 79 80 # Construct an expected result config. 81 expected_config: Dict[Any, Any] = copy.copy(_DEFAULT_CONFIG) 82 expected_config.update(defaults_from_argparse) 83 84 # pylint: disable=protected-access 85 prefs._update_config = MagicMock( # type: ignore 86 wraps=prefs._update_config 87 ) 88 # pylint: enable=protected-access 89 90 args_dict = copy.deepcopy(defaults_from_argparse) 91 changed_args = { 92 'jobs': 8, 93 'colors': False, 94 'build_system_commands': [ 95 ['out', 'bazel build'], 96 ['out', 'bazel test'], 97 ], 98 } 99 args_dict.update(changed_args) 100 101 prefs.apply_command_line_args(argparse.Namespace(**args_dict)) 102 103 # apply_command_line_args modifies build_system_commands to match the 104 # prefs dict format. 105 changed_args['build_system_commands'] = { 106 'default': {'commands': [{'command': 'ninja', 'extra_args': []}]}, 107 'out': { 108 'commands': [ 109 {'command': 'bazel', 'extra_args': ['build']}, 110 {'command': 'bazel', 'extra_args': ['test']}, 111 ], 112 }, 113 } 114 115 # Check that only args changed from their defaults are applied. 116 # pylint: disable=protected-access 117 prefs._update_config.assert_called_once_with(changed_args) 118 # pylint: enable=protected-access 119 120 # Check the result includes the project_config settings and the 121 # changed_args. 122 expected_config.update(changed_args) 123 # pylint: disable=protected-access 124 self.assertEqual(prefs._config, expected_config) 125 # pylint: enable=protected-access 126 127 128if __name__ == '__main__': 129 unittest.main() 130