Fix, remove, improve cli tests.

This commit is contained in:
Andrej Milicevic 2025-08-25 16:21:02 +02:00
parent fe6c9000fa
commit a805c640ec
4 changed files with 47 additions and 212 deletions

View file

@ -2,7 +2,6 @@
Integration tests for CLI commands that test end-to-end functionality.
"""
import pytest
import tempfile
import os
import sys

View file

@ -4,9 +4,7 @@ Tests for CLI edge cases and error scenarios with proper mocking.
import pytest
import argparse
import tempfile
import os
import asyncio
import types
from unittest.mock import patch, MagicMock, AsyncMock
from cognee.cli.commands.add_command import AddCommand
from cognee.cli.commands.search_command import SearchCommand
@ -35,21 +33,8 @@ class TestAddCommandEdgeCases:
command.execute(args)
mock_asyncio_run.assert_called_once()
@patch("builtins.__import__")
@patch("cognee.cli.commands.add_command.asyncio.run")
def test_add_very_long_dataset_name(self, mock_asyncio_run, mock_import):
"""Test add command with very long dataset name"""
# Mock the cognee module
mock_cognee = MagicMock()
mock_cognee.add = AsyncMock()
mock_import.return_value = mock_cognee
command = AddCommand()
long_name = "a" * 1000 # Very long dataset name
args = argparse.Namespace(data=["test.txt"], dataset_name=long_name)
command.execute(args)
mock_asyncio_run.assert_called_once()
coro = mock_asyncio_run.call_args[0][0]
assert isinstance(coro, types.CoroutineType)
@patch("cognee.cli.commands.add_command.asyncio.run")
def test_add_asyncio_run_exception(self, mock_asyncio_run):
@ -337,16 +322,37 @@ class TestCognifyCommandEdgeCases:
command.execute(args)
mock_asyncio_run.assert_called_once()
def test_cognify_empty_datasets_list(self):
"""Test cognify command with empty datasets list"""
@patch("builtins.__import__")
@patch("cognee.cli.commands.cognify_command.asyncio.run")
def test_cognify_empty_datasets_list(self, mock_asyncio_run, mock_import):
"""Test cognify command with nonexistent ontology file"""
# Mock the cognee module
mock_cognee = MagicMock()
mock_cognee.cognify = AsyncMock()
def mock_import_func(name, fromlist=None, *args, **kwargs):
if name == "cognee":
return mock_cognee
elif name == "cognee.modules.chunking":
module = MagicMock()
module.TextChunker = MagicMock()
return module
return MagicMock()
mock_import.side_effect = mock_import_func
command = CognifyCommand()
parser = argparse.ArgumentParser()
command.configure_parser(parser)
# Empty datasets list should be handled
args = parser.parse_args(["--datasets"])
assert args.datasets == []
args = argparse.Namespace(
datasets=[],
chunk_size=None,
ontology_file=None,
chunker="TextChunker",
background=False,
verbose=False,
)
command.execute(args)
mock_asyncio_run.assert_called_once()
class TestDeleteCommandEdgeCases:
"""Test edge cases for DeleteCommand"""
@ -439,6 +445,7 @@ class TestConfigCommandEdgeCases:
# Should handle the exception gracefully
command.execute(args)
mock_cognee.config.get.assert_called_once_with("nonexistent_key")
@patch("builtins.__import__")
def test_config_set_complex_json_value(self, mock_import):
@ -450,9 +457,11 @@ class TestConfigCommandEdgeCases:
command = ConfigCommand()
complex_json = '{"nested": {"key": "value"}, "array": [1, 2, 3]}'
complex_json_expected_value = {"nested": {"key": "value"}, "array": [1, 2, 3]}
args = argparse.Namespace(config_action="set", key="complex_config", value=complex_json)
command.execute(args)
mock_cognee.config.set.assert_called_once_with("complex_config", complex_json_expected_value)
@patch("builtins.__import__")
def test_config_set_invalid_json_value(self, mock_import):
@ -467,6 +476,7 @@ class TestConfigCommandEdgeCases:
args = argparse.Namespace(config_action="set", key="test_key", value=invalid_json)
command.execute(args)
mock_cognee.config.set.assert_called_once_with("test_key", invalid_json)
@patch("cognee.cli.commands.config_command.fmt.confirm")
@patch("builtins.__import__")
@ -499,6 +509,7 @@ class TestConfigCommandEdgeCases:
# Should handle AttributeError gracefully
command.execute(args)
mock_cognee.config.unset.assert_not_called()
def test_config_invalid_subcommand(self):
"""Test config command with invalid subcommand"""

View file

@ -4,7 +4,6 @@ Test runner and utilities for CLI tests.
import pytest
import sys
import os
from pathlib import Path

View file

@ -2,11 +2,6 @@
Tests for CLI utility functions and helper modules.
"""
import pytest
from unittest.mock import patch, MagicMock
import click
from cognee.cli import echo as fmt
from cognee.cli.exceptions import CliCommandException, CliCommandInnerException
from cognee.cli import debug
from cognee.cli.config import (
CLI_DESCRIPTION,
@ -16,155 +11,7 @@ from cognee.cli.config import (
CHUNKER_CHOICES,
OUTPUT_FORMAT_CHOICES,
)
class TestEchoModule:
"""Test the CLI echo/formatting module"""
@patch("click.secho")
def test_echo_basic(self, mock_secho):
"""Test basic echo functionality"""
fmt.echo("test message")
mock_secho.assert_called_once_with("test message", fg=None, err=False)
@patch("click.secho")
def test_echo_with_color(self, mock_secho):
"""Test echo with color"""
fmt.echo("test message", color="red")
mock_secho.assert_called_once_with("test message", fg="red", err=False)
@patch("click.secho")
def test_echo_to_stderr(self, mock_secho):
"""Test echo to stderr"""
fmt.echo("test message", err=True)
mock_secho.assert_called_once_with("test message", fg=None, err=True)
@patch("cognee.cli.echo.echo")
def test_note(self, mock_echo):
"""Test note formatting"""
fmt.note("test note")
mock_echo.assert_called_once_with("Note: test note", color="blue")
@patch("cognee.cli.echo.echo")
def test_warning(self, mock_echo):
"""Test warning formatting"""
fmt.warning("test warning")
mock_echo.assert_called_once_with("Warning: test warning", color="yellow")
@patch("cognee.cli.echo.echo")
def test_error(self, mock_echo):
"""Test error formatting"""
fmt.error("test error")
mock_echo.assert_called_once_with("Error: test error", color="red", err=True)
@patch("cognee.cli.echo.echo")
def test_success(self, mock_echo):
"""Test success formatting"""
fmt.success("test success")
mock_echo.assert_called_once_with("Success: test success", color="green")
@patch("click.style")
def test_bold(self, mock_style):
"""Test bold text formatting"""
mock_style.return_value = "bold text"
result = fmt.bold("test text")
mock_style.assert_called_once_with("test text", bold=True)
assert result == "bold text"
@patch("click.confirm")
def test_confirm(self, mock_confirm):
"""Test confirmation prompt"""
mock_confirm.return_value = True
result = fmt.confirm("Are you sure?")
mock_confirm.assert_called_once_with("Are you sure?", default=False)
assert result is True
@patch("click.confirm")
def test_confirm_with_default(self, mock_confirm):
"""Test confirmation prompt with default"""
mock_confirm.return_value = False
result = fmt.confirm("Are you sure?", default=True)
mock_confirm.assert_called_once_with("Are you sure?", default=True)
assert result is False
@patch("click.prompt")
def test_prompt(self, mock_prompt):
"""Test user input prompt"""
mock_prompt.return_value = "user input"
result = fmt.prompt("Enter value:")
mock_prompt.assert_called_once_with("Enter value:", default=None)
assert result == "user input"
@patch("click.prompt")
def test_prompt_with_default(self, mock_prompt):
"""Test user input prompt with default"""
mock_prompt.return_value = "default value"
result = fmt.prompt("Enter value:", default="default value")
mock_prompt.assert_called_once_with("Enter value:", default="default value")
assert result == "default value"
class TestCliExceptions:
"""Test CLI exception classes"""
def test_cli_command_exception_basic(self):
"""Test basic CliCommandException"""
exc = CliCommandException("Test error")
assert str(exc) == "Test error"
assert exc.error_code == -1
assert exc.docs_url is None
assert exc.raiseable_exception is None
def test_cli_command_exception_full(self):
"""Test CliCommandException with all parameters"""
inner_exc = ValueError("Inner error")
exc = CliCommandException(
"Test error",
error_code=2,
docs_url="https://docs.test.com",
raiseable_exception=inner_exc,
)
assert str(exc) == "Test error"
assert exc.error_code == 2
assert exc.docs_url == "https://docs.test.com"
assert exc.raiseable_exception is inner_exc
def test_cli_command_inner_exception(self):
"""Test CliCommandInnerException"""
exc = CliCommandInnerException("Inner error")
assert str(exc) == "Inner error"
assert isinstance(exc, Exception)
class TestDebugModule:
"""Test CLI debug functionality"""
def test_debug_initially_disabled(self):
"""Test that debug is initially disabled"""
# Reset debug state
debug._debug_enabled = False
assert not debug.is_debug_enabled()
def test_enable_debug(self):
"""Test enabling debug mode"""
debug.enable_debug()
assert debug.is_debug_enabled()
# Reset for other tests
debug._debug_enabled = False
def test_debug_state_persistence(self):
"""Test that debug state persists"""
debug.enable_debug()
assert debug.is_debug_enabled()
# Should still be enabled
assert debug.is_debug_enabled()
# Reset for other tests
debug._debug_enabled = False
from cognee.cli._cognee import _discover_commands
class TestCliConfig:
"""Test CLI configuration constants"""
@ -180,10 +27,17 @@ class TestCliConfig:
assert DEFAULT_DOCS_URL
assert isinstance(DEFAULT_DOCS_URL, str)
assert DEFAULT_DOCS_URL.startswith("https://")
assert "cognee.ai" in DEFAULT_DOCS_URL
def test_command_descriptions_complete(self):
"""Test that all expected commands have descriptions"""
expected_commands = ["add", "search", "cognify", "delete", "config"]
commands = _discover_commands()
assert len(commands) > 0
expected_commands = []
for command_class in commands:
command = command_class()
expected_commands.append(command.command_string)
for command in expected_commands:
assert command in COMMAND_DESCRIPTIONS
@ -224,7 +78,6 @@ class TestCliConfig:
for expected_format in expected_formats:
assert expected_format in OUTPUT_FORMAT_CHOICES
class TestCliReference:
"""Test CLI reference protocol"""
@ -262,38 +115,11 @@ class TestCliReference:
class TestCliUtilityFunctions:
"""Test utility functions and edge cases"""
def test_echo_empty_message(self):
"""Test echo with empty message"""
with patch("click.secho") as mock_secho:
fmt.echo()
mock_secho.assert_called_once_with("", fg=None, err=False)
def test_echo_none_message(self):
"""Test echo with None message (should not crash)"""
with patch("click.secho") as mock_secho:
# This might raise an exception, which is expected behavior
try:
fmt.echo(None)
except TypeError:
# Expected for None message
pass
def test_multiple_debug_enable_calls(self):
"""Test multiple calls to enable_debug"""
debug.enable_debug()
debug.enable_debug() # Should not cause issues
assert debug.is_debug_enabled()
assert debug.is_debug_enabled() is True
# Reset for other tests
debug._debug_enabled = False
def test_config_constants_immutability(self):
"""Test that config constants are not accidentally modified"""
original_description = CLI_DESCRIPTION
original_url = DEFAULT_DOCS_URL
original_commands = COMMAND_DESCRIPTIONS.copy()
# These should be the same after any test
assert CLI_DESCRIPTION == original_description
assert DEFAULT_DOCS_URL == original_url
assert COMMAND_DESCRIPTIONS == original_commands