blob: 06b1192dc9f5f12e6a3f0fd1192c3fd352c8ff47 [file] [log] [blame]
# Copyright 2026 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import os
import sys
import unittest
_SCRIPT_DIR = os.path.dirname(__file__)
sys.path.insert(0, _SCRIPT_DIR)
from script_commands import ScriptCommandBase, ScriptCommandList
class ExitCodeCommand(ScriptCommandBase):
"""A command only used during unit-testing."""
@staticmethod
def add_arguments(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"--exit_code",
type=int,
default=0,
help="Exit code for the test command, default is 0",
)
@staticmethod
def run(args: argparse.Namespace) -> int:
return args.exit_code
class StatusCodeTestCommand(ScriptCommandBase):
PARSER_KWARGS = {
"name": "status_code",
"help": "another command only used during unit-testing.",
}
def __init__(self, status_code: int) -> None:
self._status_code = status_code
# This is a regular, i.e. non-static, method.
def run(self, args: argparse.Namespace) -> int:
return self._status_code
class NoNameAndInvalidCommandSuffix(ScriptCommandBase):
"""Ignored help."""
def run(self, args: argparse.Namespace) -> int:
return 1
class NoHelpAndDocstringCommand(ScriptCommandBase):
# This class must not have a docstring, and no "help" field in PARSER_KWARGS
def run(self, args: argparse.Namespace) -> int:
return 1
class SimpleDescriptionCommand(ScriptCommandBase):
"""Simple command"""
DESCRIPTION = "Simple description"
class MultiLineDescriptionCommand(ScriptCommandBase):
"""Multi-line command"""
DESCRIPTION = """A multi-line
description test
that can be reformatted.
"""
class RawDescriptionCommand(ScriptCommandBase):
"""Raw command"""
DESCRIPTION_RAW = """
A raw help description
that should not be reformatted
in any way
"""
class ScriptCommandListTest(unittest.TestCase):
@staticmethod
def init() -> tuple[argparse.ArgumentParser, ScriptCommandList]:
parser = argparse.ArgumentParser(description="parser for tests")
commands = ScriptCommandList(parser)
return parser, commands
def test_commands(self) -> None:
parser, commands = self.init()
commands.add_command(ExitCodeCommand())
commands.add_command(StatusCodeTestCommand(31))
args = parser.parse_args(args=["exit_code"])
self.assertEqual(commands.run(args), 0)
args = parser.parse_args(args=["exit_code", "--exit_code", "42"])
self.assertEqual(commands.run(args), 42)
args = parser.parse_args(args=["status_code"])
self.assertEqual(commands.run(args), 31)
def test_bad_command_class_name(self) -> None:
parser, commands = self.init()
with self.assertRaises(AssertionError) as cm:
commands.add_command(NoNameAndInvalidCommandSuffix())
self.assertEqual(
str(cm.exception),
"ScriptCommandBase derived class name (NoNameAndInvalidCommandSuffix) "
+ 'does not end with Command suffix. Please ensure its PARSER_KWARGS value provides a "name" value.',
)
def test_missing_docstring_in_command_class(self) -> None:
parser, commands = self.init()
with self.assertRaises(AssertionError) as cm:
commands.add_command(NoHelpAndDocstringCommand())
self.assertEqual(
str(cm.exception),
"ScriptCommandBase derived class (NoHelpAndDocstringCommand) "
+ 'has no docstring. Please ensure its PARSER_KWARGS value provides a "help" value.',
)
def test_description_in_command_class(self) -> None:
parser, commands = self.init()
commands.add_command(SimpleDescriptionCommand())
desc_command = commands.parsers[0]
self.assertEqual(
desc_command.format_help(),
"""usage: script_commands_test.py simple_description [-h]
Simple description
options:
-h, --help show this help message and exit
""",
)
def test_multiline_description_in_command_class(self) -> None:
parser, commands = self.init()
commands.add_command(MultiLineDescriptionCommand())
desc_command = commands.parsers[0]
self.assertEqual(
desc_command.format_help(),
"""usage: script_commands_test.py multi_line_description [-h]
A multi-line description test that can be reformatted.
options:
-h, --help show this help message and exit
""",
)
def test_raw_description_in_command_class(self) -> None:
parser, commands = self.init()
commands.add_command(RawDescriptionCommand())
desc_command = commands.parsers[0]
self.assertEqual(
desc_command.format_help(),
"""usage: script_commands_test.py raw_description [-h]
A raw help description
that should not be reformatted
in any way
options:
-h, --help show this help message and exit
""",
)
if __name__ == "__main__":
unittest.main()