mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-03-11 04:23:38 +00:00
Compare commits
1 Commits
master
...
feature/pk
| Author | SHA1 | Date | |
|---|---|---|---|
| 17e4807fcf |
@@ -92,14 +92,6 @@ ahriman.application.handlers.patch module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.application.handlers.pkgbuild module
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.application.handlers.pkgbuild
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.application.handlers.rebuild module
|
ahriman.application.handlers.rebuild module
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -140,14 +140,6 @@ ahriman.core.database.migrations.m016\_archive module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.core.database.migrations.m017\_pkgbuild module
|
|
||||||
------------------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.core.database.migrations.m017_pkgbuild
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
Module contents
|
Module contents
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|||||||
@@ -76,14 +76,6 @@ ahriman.core.formatters.patch\_printer module
|
|||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
ahriman.core.formatters.pkgbuild\_printer module
|
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
.. automodule:: ahriman.core.formatters.pkgbuild_printer
|
|
||||||
:members:
|
|
||||||
:no-undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
ahriman.core.formatters.printer module
|
ahriman.core.formatters.printer module
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class Change(Handler):
|
|||||||
case Action.List:
|
case Action.List:
|
||||||
changes = client.package_changes_get(args.package)
|
changes = client.package_changes_get(args.package)
|
||||||
ChangesPrinter(changes)(verbose=True, separator="")
|
ChangesPrinter(changes)(verbose=True, separator="")
|
||||||
Change.check_status(args.exit_code, changes.changes is not None)
|
Change.check_status(args.exit_code, not changes.is_empty)
|
||||||
case Action.Remove:
|
case Action.Remove:
|
||||||
client.package_changes_update(args.package, Changes())
|
client.package_changes_update(args.package, Changes())
|
||||||
|
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (c) 2021-2026 ahriman team.
|
|
||||||
#
|
|
||||||
# This file is part of ahriman
|
|
||||||
# (see https://github.com/arcan1s/ahriman).
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
from dataclasses import replace
|
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
|
||||||
from ahriman.application.handlers.handler import Handler, SubParserAction
|
|
||||||
from ahriman.core.configuration import Configuration
|
|
||||||
from ahriman.core.formatters import PkgbuildPrinter
|
|
||||||
from ahriman.models.action import Action
|
|
||||||
from ahriman.models.repository_id import RepositoryId
|
|
||||||
|
|
||||||
|
|
||||||
class Pkgbuild(Handler):
|
|
||||||
"""
|
|
||||||
package pkgbuild handler
|
|
||||||
"""
|
|
||||||
|
|
||||||
ALLOW_MULTI_ARCHITECTURE_RUN = False # conflicting io
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *,
|
|
||||||
report: bool) -> None:
|
|
||||||
"""
|
|
||||||
callback for command line
|
|
||||||
|
|
||||||
Args:
|
|
||||||
args(argparse.Namespace): command line args
|
|
||||||
repository_id(RepositoryId): repository unique identifier
|
|
||||||
configuration(Configuration): configuration instance
|
|
||||||
report(bool): force enable or disable reporting
|
|
||||||
"""
|
|
||||||
application = Application(repository_id, configuration, report=True)
|
|
||||||
client = application.repository.reporter
|
|
||||||
|
|
||||||
match args.action:
|
|
||||||
case Action.List:
|
|
||||||
changes = client.package_changes_get(args.package)
|
|
||||||
PkgbuildPrinter(changes)(verbose=True, separator="")
|
|
||||||
Pkgbuild.check_status(args.exit_code, changes.pkgbuild is not None)
|
|
||||||
case Action.Remove:
|
|
||||||
changes = client.package_changes_get(args.package)
|
|
||||||
client.package_changes_update(args.package, replace(changes, pkgbuild=None))
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _set_package_pkgbuild_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|
||||||
"""
|
|
||||||
add parser for package pkgbuild subcommand
|
|
||||||
|
|
||||||
Args:
|
|
||||||
root(SubParserAction): subparsers for the commands
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
argparse.ArgumentParser: created argument parser
|
|
||||||
"""
|
|
||||||
parser = root.add_parser("package-pkgbuild", help="get package pkgbuild",
|
|
||||||
description="retrieve package PKGBUILD stored in database",
|
|
||||||
epilog="This command requests package status from the web interface "
|
|
||||||
"if it is available.")
|
|
||||||
parser.add_argument("package", help="package base")
|
|
||||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty",
|
|
||||||
action="store_true")
|
|
||||||
parser.set_defaults(action=Action.List, lock=None, quiet=True, report=False, unsafe=True)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _set_package_pkgbuild_remove_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
|
||||||
"""
|
|
||||||
add parser for package pkgbuild remove subcommand
|
|
||||||
|
|
||||||
Args:
|
|
||||||
root(SubParserAction): subparsers for the commands
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
argparse.ArgumentParser: created argument parser
|
|
||||||
"""
|
|
||||||
parser = root.add_parser("package-pkgbuild-remove", help="remove package pkgbuild",
|
|
||||||
description="remove the package PKGBUILD stored remotely")
|
|
||||||
parser.add_argument("package", help="package base")
|
|
||||||
parser.set_defaults(action=Action.Remove, exit_code=False, lock=None, quiet=True, report=False, unsafe=True)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
arguments = [_set_package_pkgbuild_parser, _set_package_pkgbuild_remove_parser]
|
|
||||||
@@ -26,7 +26,6 @@ from ahriman.core.formatters.event_stats_printer import EventStatsPrinter
|
|||||||
from ahriman.core.formatters.package_printer import PackagePrinter
|
from ahriman.core.formatters.package_printer import PackagePrinter
|
||||||
from ahriman.core.formatters.package_stats_printer import PackageStatsPrinter
|
from ahriman.core.formatters.package_stats_printer import PackageStatsPrinter
|
||||||
from ahriman.core.formatters.patch_printer import PatchPrinter
|
from ahriman.core.formatters.patch_printer import PatchPrinter
|
||||||
from ahriman.core.formatters.pkgbuild_printer import PkgbuildPrinter
|
|
||||||
from ahriman.core.formatters.printer import Printer
|
from ahriman.core.formatters.printer import Printer
|
||||||
from ahriman.core.formatters.repository_printer import RepositoryPrinter
|
from ahriman.core.formatters.repository_printer import RepositoryPrinter
|
||||||
from ahriman.core.formatters.repository_stats_printer import RepositoryStatsPrinter
|
from ahriman.core.formatters.repository_stats_printer import RepositoryStatsPrinter
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class ChangesPrinter(Printer):
|
|||||||
Returns:
|
Returns:
|
||||||
list[Property]: list of content properties
|
list[Property]: list of content properties
|
||||||
"""
|
"""
|
||||||
if self.changes.changes is None:
|
if self.changes.is_empty:
|
||||||
return []
|
return []
|
||||||
return [Property("", self.changes.changes, is_required=True, indent=0)]
|
return [Property("", self.changes.changes, is_required=True, indent=0)]
|
||||||
|
|
||||||
@@ -57,6 +57,6 @@ class ChangesPrinter(Printer):
|
|||||||
Returns:
|
Returns:
|
||||||
str | None: content title if it can be generated and ``None`` otherwise
|
str | None: content title if it can be generated and ``None`` otherwise
|
||||||
"""
|
"""
|
||||||
if self.changes.changes is None:
|
if self.changes.is_empty:
|
||||||
return None
|
return None
|
||||||
return self.changes.last_commit_sha
|
return self.changes.last_commit_sha
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (c) 2021-2026 ahriman team.
|
|
||||||
#
|
|
||||||
# This file is part of ahriman
|
|
||||||
# (see https://github.com/arcan1s/ahriman).
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
from ahriman.core.formatters.printer import Printer
|
|
||||||
from ahriman.models.changes import Changes
|
|
||||||
from ahriman.models.property import Property
|
|
||||||
|
|
||||||
|
|
||||||
class PkgbuildPrinter(Printer):
|
|
||||||
"""
|
|
||||||
print content of the pkgbuild stored in changes
|
|
||||||
|
|
||||||
Attributes:
|
|
||||||
changes(Changes): package changes
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, changes: Changes) -> None:
|
|
||||||
"""
|
|
||||||
Args:
|
|
||||||
changes(Changes): package changes
|
|
||||||
"""
|
|
||||||
Printer.__init__(self)
|
|
||||||
self.changes = changes
|
|
||||||
|
|
||||||
def properties(self) -> list[Property]:
|
|
||||||
"""
|
|
||||||
convert content into printable data
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[Property]: list of content properties
|
|
||||||
"""
|
|
||||||
if self.changes.pkgbuild is None:
|
|
||||||
return []
|
|
||||||
return [Property("", self.changes.pkgbuild, is_required=True, indent=0)]
|
|
||||||
|
|
||||||
# pylint: disable=redundant-returns-doc
|
|
||||||
def title(self) -> str | None:
|
|
||||||
"""
|
|
||||||
generate entry title from content
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str | None: content title if it can be generated and ``None`` otherwise
|
|
||||||
"""
|
|
||||||
if self.changes.pkgbuild is None:
|
|
||||||
return None
|
|
||||||
return self.changes.last_commit_sha
|
|
||||||
@@ -38,6 +38,16 @@ class Changes:
|
|||||||
changes: str | None = None
|
changes: str | None = None
|
||||||
pkgbuild: str | None = None
|
pkgbuild: str | None = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_empty(self) -> bool:
|
||||||
|
"""
|
||||||
|
validate that changes are not empty
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: ``True`` in case if changes are not set and ``False`` otherwise
|
||||||
|
"""
|
||||||
|
return self.changes is None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, dump: dict[str, Any]) -> Self:
|
def from_json(cls, dump: dict[str, Any]) -> Self:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
import argparse
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from pytest_mock import MockerFixture
|
|
||||||
|
|
||||||
from ahriman.application.handlers.pkgbuild import Pkgbuild
|
|
||||||
from ahriman.core.configuration import Configuration
|
|
||||||
from ahriman.core.database import SQLite
|
|
||||||
from ahriman.core.repository import Repository
|
|
||||||
from ahriman.models.action import Action
|
|
||||||
from ahriman.models.changes import Changes
|
|
||||||
|
|
||||||
|
|
||||||
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
|
|
||||||
"""
|
|
||||||
default arguments for these test cases
|
|
||||||
|
|
||||||
Args:
|
|
||||||
args(argparse.Namespace): command line arguments fixture
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
argparse.Namespace: generated arguments for these test cases
|
|
||||||
"""
|
|
||||||
args.action = Action.List
|
|
||||||
args.exit_code = False
|
|
||||||
args.package = "package"
|
|
||||||
return args
|
|
||||||
|
|
||||||
|
|
||||||
def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
|
||||||
mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must run command
|
|
||||||
"""
|
|
||||||
args = _default_args(args)
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
|
||||||
application_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get",
|
|
||||||
return_value=Changes("sha", "change", "pkgbuild content"))
|
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
|
||||||
print_mock = mocker.patch("ahriman.core.formatters.Printer.print")
|
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
|
||||||
Pkgbuild.run(args, repository_id, configuration, report=False)
|
|
||||||
application_mock.assert_called_once_with(args.package)
|
|
||||||
check_mock.assert_called_once_with(False, True)
|
|
||||||
print_mock.assert_called_once_with(verbose=True, log_fn=pytest.helpers.anyvar(int), separator="")
|
|
||||||
|
|
||||||
|
|
||||||
def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
|
||||||
mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must raise ExitCode exception on empty pkgbuild result
|
|
||||||
"""
|
|
||||||
args = _default_args(args)
|
|
||||||
args.exit_code = True
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
|
||||||
mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get", return_value=Changes())
|
|
||||||
check_mock = mocker.patch("ahriman.application.handlers.handler.Handler.check_status")
|
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
|
||||||
Pkgbuild.run(args, repository_id, configuration, report=False)
|
|
||||||
check_mock.assert_called_once_with(True, False)
|
|
||||||
|
|
||||||
|
|
||||||
def test_run_remove(args: argparse.Namespace, configuration: Configuration, repository: Repository,
|
|
||||||
mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must remove package pkgbuild
|
|
||||||
"""
|
|
||||||
args = _default_args(args)
|
|
||||||
args.action = Action.Remove
|
|
||||||
mocker.patch("ahriman.core.repository.Repository.load", return_value=repository)
|
|
||||||
changes = Changes("sha", "change", "pkgbuild content")
|
|
||||||
mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_get", return_value=changes)
|
|
||||||
update_mock = mocker.patch("ahriman.core.status.local_client.LocalClient.package_changes_update")
|
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
|
||||||
Pkgbuild.run(args, repository_id, configuration, report=False)
|
|
||||||
update_mock.assert_called_once_with(args.package, Changes("sha", "change", None))
|
|
||||||
|
|
||||||
|
|
||||||
def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, database: SQLite,
|
|
||||||
mocker: MockerFixture) -> None:
|
|
||||||
"""
|
|
||||||
must create application object with native reporting
|
|
||||||
"""
|
|
||||||
args = _default_args(args)
|
|
||||||
mocker.patch("ahriman.core.database.SQLite.load", return_value=database)
|
|
||||||
load_mock = mocker.patch("ahriman.core.repository.Repository.load")
|
|
||||||
|
|
||||||
_, repository_id = configuration.check_loaded()
|
|
||||||
Pkgbuild.run(args, repository_id, configuration, report=False)
|
|
||||||
load_mock.assert_called_once_with(repository_id, configuration, database, report=True, refresh_pacman_database=0)
|
|
||||||
|
|
||||||
|
|
||||||
def test_disallow_multi_architecture_run() -> None:
|
|
||||||
"""
|
|
||||||
must not allow multi architecture run
|
|
||||||
"""
|
|
||||||
assert not Pkgbuild.ALLOW_MULTI_ARCHITECTURE_RUN
|
|
||||||
@@ -2,26 +2,24 @@ import pytest
|
|||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from ahriman.core.formatters import (
|
from ahriman.core.formatters import \
|
||||||
AurPrinter,
|
AurPrinter, \
|
||||||
ChangesPrinter,
|
ChangesPrinter, \
|
||||||
ConfigurationPathsPrinter,
|
ConfigurationPathsPrinter, \
|
||||||
ConfigurationPrinter,
|
ConfigurationPrinter, \
|
||||||
EventStatsPrinter,
|
EventStatsPrinter, \
|
||||||
PackagePrinter,
|
PackagePrinter, \
|
||||||
PackageStatsPrinter,
|
PackageStatsPrinter, \
|
||||||
PatchPrinter,
|
PatchPrinter, \
|
||||||
PkgbuildPrinter,
|
RepositoryPrinter, \
|
||||||
RepositoryPrinter,
|
RepositoryStatsPrinter, \
|
||||||
RepositoryStatsPrinter,
|
StatusPrinter, \
|
||||||
StatusPrinter,
|
StringPrinter, \
|
||||||
StringPrinter,
|
TreePrinter, \
|
||||||
TreePrinter,
|
UpdatePrinter, \
|
||||||
UpdatePrinter,
|
UserPrinter, \
|
||||||
UserPrinter,
|
ValidationPrinter, \
|
||||||
ValidationPrinter,
|
|
||||||
VersionPrinter
|
VersionPrinter
|
||||||
)
|
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
from ahriman.models.build_status import BuildStatus
|
from ahriman.models.build_status import BuildStatus
|
||||||
from ahriman.models.changes import Changes
|
from ahriman.models.changes import Changes
|
||||||
@@ -57,17 +55,6 @@ def changes_printer() -> ChangesPrinter:
|
|||||||
return ChangesPrinter(Changes("sha", "changes"))
|
return ChangesPrinter(Changes("sha", "changes"))
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def pkgbuild_printer() -> PkgbuildPrinter:
|
|
||||||
"""
|
|
||||||
fixture for pkgbuild printer
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
PkgbuildPrinter: pkgbuild printer test instance
|
|
||||||
"""
|
|
||||||
return PkgbuildPrinter(Changes("sha", "changes", "pkgbuild content"))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def configuration_paths_printer() -> ConfigurationPathsPrinter:
|
def configuration_paths_printer() -> ConfigurationPathsPrinter:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
from ahriman.core.formatters import PkgbuildPrinter
|
|
||||||
from ahriman.models.changes import Changes
|
|
||||||
|
|
||||||
|
|
||||||
def test_properties(pkgbuild_printer: PkgbuildPrinter) -> None:
|
|
||||||
"""
|
|
||||||
must return non-empty properties list
|
|
||||||
"""
|
|
||||||
assert pkgbuild_printer.properties()
|
|
||||||
|
|
||||||
|
|
||||||
def test_properties_empty() -> None:
|
|
||||||
"""
|
|
||||||
must return empty properties list if pkgbuild is empty
|
|
||||||
"""
|
|
||||||
assert not PkgbuildPrinter(Changes()).properties()
|
|
||||||
assert not PkgbuildPrinter(Changes("sha", "changes")).properties()
|
|
||||||
|
|
||||||
|
|
||||||
def test_title(pkgbuild_printer: PkgbuildPrinter) -> None:
|
|
||||||
"""
|
|
||||||
must return non-empty title
|
|
||||||
"""
|
|
||||||
assert pkgbuild_printer.title()
|
|
||||||
|
|
||||||
|
|
||||||
def test_title_empty() -> None:
|
|
||||||
"""
|
|
||||||
must return empty title if change is empty
|
|
||||||
"""
|
|
||||||
assert not PkgbuildPrinter(Changes()).title()
|
|
||||||
assert not PkgbuildPrinter(Changes("sha")).title()
|
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
from ahriman.models.changes import Changes
|
from ahriman.models.changes import Changes
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_empty() -> None:
|
||||||
|
"""
|
||||||
|
must check if changes are empty
|
||||||
|
"""
|
||||||
|
assert Changes().is_empty
|
||||||
|
assert Changes("sha").is_empty
|
||||||
|
|
||||||
|
assert not Changes("sha", "change").is_empty
|
||||||
|
assert not Changes(None, "change").is_empty # well, ok
|
||||||
|
|
||||||
|
|
||||||
def test_changes_from_json_view() -> None:
|
def test_changes_from_json_view() -> None:
|
||||||
"""
|
"""
|
||||||
must construct same object from json
|
must construct same object from json
|
||||||
|
|||||||
Reference in New Issue
Block a user