blob: e49ca87ef58f1932fafb582d7defd29f52829267 [file] [log] [blame]
# Copyright 2024 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.
"""Tests for GN's built-in formatter."""
import importlib.resources
from pathlib import Path
from tempfile import TemporaryDirectory
import unittest
from format_testing_utils import CapturingToolRunner
from pw_presubmit.format.gn import GnFormatter
_TEST_DATA_FILES = importlib.resources.files('pw_presubmit.format.test_data')
_TEST_SRC_FILE = _TEST_DATA_FILES / 'gn_test_data.gn'
_TEST_GOLDEN = _TEST_DATA_FILES / 'gn_test_data_golden.gn'
_TEST_MALFORMED = _TEST_DATA_FILES / 'malformed_file.txt'
class TestGnFormatter(unittest.TestCase):
"""Tests for the GnFormatter."""
def test_check_file(self):
tool_runner = CapturingToolRunner()
formatter = GnFormatter()
formatter.run_tool = tool_runner
result = formatter.format_file_in_memory(
_TEST_SRC_FILE, _TEST_SRC_FILE.read_bytes()
)
self.assertTrue(result.ok)
self.assertEqual(result.error_message, None)
self.assertMultiLineEqual(
result.formatted_file_contents.decode(), _TEST_GOLDEN.read_text()
)
self.assertEqual(
tool_runner.command_history.pop(0),
' '.join(
(
'gn',
'format',
'--stdin',
)
),
)
def test_check_file_error(self):
tool_runner = CapturingToolRunner()
formatter = GnFormatter()
formatter.run_tool = tool_runner
result = formatter.format_file_in_memory(
_TEST_MALFORMED, _TEST_MALFORMED.read_bytes()
)
self.assertFalse(result.ok)
self.assertTrue(result.error_message.startswith('ERROR at'))
self.assertTrue('Invalid token' in result.error_message)
self.assertEqual(result.formatted_file_contents, b'')
self.assertEqual(
tool_runner.command_history.pop(0),
' '.join(
(
'gn',
'format',
'--stdin',
)
),
)
def test_fix_file(self):
"""Tests that formatting is properly applied to files."""
tool_runner = CapturingToolRunner()
formatter = GnFormatter()
formatter.run_tool = tool_runner
with TemporaryDirectory() as temp_dir:
file_to_fix = Path(temp_dir) / _TEST_SRC_FILE.name
file_to_fix.write_bytes(_TEST_SRC_FILE.read_bytes())
malformed_file = Path(temp_dir) / _TEST_MALFORMED.name
malformed_file.write_bytes(_TEST_MALFORMED.read_bytes())
errors = list(formatter.format_files([file_to_fix, malformed_file]))
# Should see three separate commands, one where we try to format
# both files together, and then the fallback logic that formats
# them individually to isolate errors.
self.assertEqual(
tool_runner.command_history.pop(0),
' '.join(
(
'gn',
'format',
str(file_to_fix),
str(malformed_file),
)
),
)
self.assertEqual(
tool_runner.command_history.pop(0),
' '.join(
(
'gn',
'format',
str(file_to_fix),
)
),
)
self.assertEqual(
tool_runner.command_history.pop(0),
' '.join(
(
'gn',
'format',
str(malformed_file),
)
),
)
# Check good build file.
self.assertMultiLineEqual(
file_to_fix.read_text(), _TEST_GOLDEN.read_text()
)
# Check malformed file.
self.assertEqual(len(errors), 1)
malformed_files = [malformed_file]
for file_path, error in errors:
self.assertIn(file_path, malformed_files)
self.assertFalse(error.ok)
self.assertTrue(error.error_message.startswith('ERROR at'))
if __name__ == '__main__':
unittest.main()