• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
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
31from pw_config_loader import yaml_config_loader_mixin
32
33
34def _create_tempfile(content: str) -> Path:
35    with tempfile.NamedTemporaryFile(
36        prefix=f'{__package__}', delete=False
37    ) as output_file:
38        output_file.write(content.encode('UTF-8'))
39        return Path(output_file.name)
40
41
42class TestProjectBuilderPrefs(unittest.TestCase):
43    """Tests for ProjectBuilderPrefs."""
44
45    maxDiff = None
46
47    def test_load_no_existing_files(self) -> None:
48        # Create a prefs instance with no loaded config.
49        prefs = ProjectBuilderPrefs(
50            load_argparse_arguments=add_project_builder_arguments,
51            project_file=False,
52            project_user_file=False,
53            user_file=False,
54        )
55        # Construct an expected result config.
56        expected_config: dict[Any, Any] = {}
57        expected_config.update(_DEFAULT_CONFIG)
58        expected_config.update(
59            load_defaults_from_argparse(add_project_builder_arguments)
60        )
61
62        self.assertEqual(
63            prefs._config, expected_config  # pylint: disable=protected-access
64        )
65
66    def test_apply_command_line_args(self) -> None:
67        """Check command line args are applied to watch preferences."""
68        # Load default command line arg values.
69        defaults_from_argparse = load_defaults_from_argparse(
70            add_project_builder_arguments
71        )
72
73        # Create a prefs instance with the test config file.
74        prefs = ProjectBuilderPrefs(
75            load_argparse_arguments=add_project_builder_arguments,
76            project_file=False,
77            project_user_file=False,
78            user_file=False,
79        )
80
81        # Construct an expected result config.
82        expected_config: dict[Any, Any] = copy.copy(_DEFAULT_CONFIG)
83        expected_config.update(defaults_from_argparse)
84
85        # pylint: disable=protected-access
86        prefs._update_config = MagicMock(  # type: ignore
87            wraps=prefs._update_config
88        )
89        # pylint: enable=protected-access
90
91        args_dict = copy.deepcopy(defaults_from_argparse)
92        changed_args = {
93            'jobs': 8,
94            'colors': False,
95            'build_system_commands': [
96                ['out', 'bazel build'],
97                ['out', 'bazel test'],
98            ],
99        }
100        args_dict.update(changed_args)
101
102        prefs.apply_command_line_args(argparse.Namespace(**args_dict))
103
104        # apply_command_line_args modifies build_system_commands to match the
105        # prefs dict format.
106        changed_args['build_system_commands'] = {
107            'default': {'commands': [{'command': 'ninja', 'extra_args': []}]},
108            'out': {
109                'commands': [
110                    {'command': 'bazel', 'extra_args': ['build']},
111                    {'command': 'bazel', 'extra_args': ['test']},
112                ],
113            },
114        }
115
116        # Check that only args changed from their defaults are applied.
117        # pylint: disable=protected-access
118        prefs._update_config.assert_called_once_with(
119            changed_args,
120            yaml_config_loader_mixin.Stage.DEFAULT,
121        )
122        # pylint: enable=protected-access
123
124        # Check the result includes the project_config settings and the
125        # changed_args.
126        expected_config.update(changed_args)
127        # pylint: disable=protected-access
128        self.assertEqual(prefs._config, expected_config)
129        # pylint: enable=protected-access
130
131
132if __name__ == '__main__':
133    unittest.main()
134