• 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, 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