import asyncio import time from unittest.mock import patch import asyncclick as click import pytest from click.testing import CliRunner from cli.utils.timer import timer from tests.cli.async_invoke import async_invoke @click.command() async def test_command(): with timer(): time.sleep(0.1) @pytest.mark.asyncio async def test_timer_measures_time(): runner = CliRunner() result = await async_invoke(runner, test_command) output = result.stdout_bytes.decode() assert "Time taken:" in output assert "seconds" in output measured_time = float(output.split(":")[1].split()[0]) assert 0.1 <= measured_time <= 0.2 @click.command() async def zero_duration_command(): with timer(): pass @pytest.mark.asyncio async def test_timer_zero_duration(): runner = CliRunner() result = await async_invoke(runner, zero_duration_command) output = result.stdout_bytes.decode() measured_time = float(output.split(":")[1].split()[0]) assert measured_time >= 0 assert measured_time < 0.1 @click.command() async def exception_command(): with timer(): raise ValueError("Test exception") @pytest.mark.asyncio async def test_timer_with_exception(): runner = CliRunner() result = await async_invoke(runner, exception_command) assert result.exit_code != 0 assert isinstance(result.exception, ValueError) @click.command() async def async_command(): with timer(): await asyncio.sleep(0.1) @pytest.mark.asyncio async def test_timer_with_async_code(): runner = CliRunner() result = await async_invoke(runner, async_command) output = result.stdout_bytes.decode() measured_time = float(output.split(":")[1].split()[0]) assert 0.1 <= measured_time <= 0.2 @click.command() async def nested_command(): with timer(): time.sleep(0.1) with timer(): time.sleep(0.1) @pytest.mark.asyncio async def test_timer_multiple_nested(): runner = CliRunner() result = await async_invoke(runner, nested_command) output = result.stdout_bytes.decode() assert output.count("Time taken:") == 2 @click.command() async def mock_time_command(): with timer(): pass @pytest.mark.asyncio @patch("time.time") async def test_timer_with_mock_time(mock_time): mock_time.side_effect = [0, 1] # Start and end times runner = CliRunner() result = await async_invoke(runner, mock_time_command) output = result.stdout_bytes.decode() assert "Time taken: 1.00 seconds" in output @click.command() async def precision_command(): with timer(): time.sleep(0.1) @pytest.mark.asyncio async def test_timer_precision(): runner = CliRunner() result = await async_invoke(runner, precision_command) output = result.stdout_bytes.decode() assert len(output.split(":")[1].split()[0].split(".")[1]) == 2