blob: a95768ba3a5b77d537809f986f2b3238358003d1 [file] [log] [blame]
# Copyright 2022 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""pw_ide test classes."""
from contextlib import contextmanager
from io import TextIOWrapper
from pathlib import Path
import tempfile
from typing import Generator, List, Optional, Tuple, Union
import unittest
from pw_ide.settings import IdeSettings
class TempDirTestCase(unittest.TestCase):
"""Run tests that need access to a temporary directory."""
def setUp(self) -> None:
self.temp_dir = tempfile.TemporaryDirectory()
self.temp_dir_path = Path(self.temp_dir.name)
def tearDown(self) -> None:
self.temp_dir.cleanup()
return super().tearDown()
@contextmanager
def make_temp_file(
self,
filename: Union[Path, str],
content: str = ''
) -> Generator[Tuple[TextIOWrapper, Path], None, None]:
"""Create a temp file in the test case's temp dir.
Returns a tuple containing the file reference and the file's path.
The file can be read immediately.
"""
path = self.temp_dir_path / filename
with open(path, 'a+', encoding='utf-8') as file:
file.write(content)
file.flush()
file.seek(0)
yield (file, path)
@contextmanager
def open_temp_file(
self,
filename: Union[Path, str],
) -> Generator[Tuple[TextIOWrapper, Path], None, None]:
"""Open an existing temp file in the test case's temp dir.
Returns a tuple containing the file reference and the file's path.
"""
path = self.temp_dir_path / filename
with open(path, 'r', encoding='utf-8') as file:
yield (file, path)
@contextmanager
def make_temp_files(
self, files_data: List[Tuple[Union[Path, str], str]]
) -> Generator[List[TextIOWrapper], None, None]:
"""Create several temp files in the test case's temp dir.
Provide a list of file name and content tuples. Saves you the trouble
of excessive `with self.make_temp_file, self.make_temp_file...`
nesting, and allows programmatic definition of multiple temp file
contexts. Files can be read immediately.
"""
files: List[TextIOWrapper] = []
for filename, content in files_data:
file = open(self.path_in_temp_dir(filename),
'a+',
encoding='utf-8')
file.write(content)
file.flush()
file.seek(0)
files.append(file)
yield files
for file in files:
file.close()
@contextmanager
def open_temp_files(
self, files_data: List[Union[Path, str]]
) -> Generator[List[TextIOWrapper], None, None]:
"""Open several existing temp files in the test case's temp dir.
Provide a list of file names. Saves you the trouble of excessive
`with self.open_temp_file, self.open_temp_file...` nesting, and allows
programmatic definition of multiple temp file contexts.
"""
files: List[TextIOWrapper] = []
for filename in files_data:
file = open(self.path_in_temp_dir(filename), 'r', encoding='utf-8')
files.append(file)
yield files
for file in files:
file.close()
def path_in_temp_dir(self, path: Union[Path, str]) -> Path:
"""Place a path into the test case's temp dir.
This only works with a relative path; with an absolute path, this is a
no-op.
"""
return self.temp_dir_path / path
def paths_in_temp_dir(self, *paths: Union[Path, str]) -> List[Path]:
"""Place several paths into the test case's temp dir.
This only works with relative paths; with absolute paths, this is a
no-op.
"""
return [self.path_in_temp_dir(path) for path in paths]
class PwIdeTestCase(TempDirTestCase):
"""A test case for testing `pw_ide`.
Provides a temp dir for testing file system actions and access to IDE
settings that wrap the temp dir.
"""
def make_ide_settings(self,
working_dir: Optional[Union[str, Path]] = None,
targets: Optional[List[str]] = None) -> IdeSettings:
"""Make settings that wrap provided paths in the temp path."""
if working_dir is not None:
working_dir_path = self.path_in_temp_dir(working_dir)
else:
working_dir_path = self.temp_dir_path
if targets is None:
targets = []
return IdeSettings(False,
False,
False,
default_config={
'working_dir': str(working_dir_path),
'targets': targets,
})