test_estimate_pages.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #!/usr/bin/env python3
  2. """
  3. Tests for cli/estimate_pages.py functionality
  4. """
  5. import unittest
  6. import tempfile
  7. import json
  8. from pathlib import Path
  9. import sys
  10. from skill_seekers.cli.estimate_pages import estimate_pages
  11. class TestEstimatePages(unittest.TestCase):
  12. """Test estimate_pages function"""
  13. def test_estimate_pages_with_minimal_config(self):
  14. """Test estimation with minimal configuration"""
  15. config = {
  16. 'name': 'test',
  17. 'base_url': 'https://example.com/',
  18. 'rate_limit': 0.1
  19. }
  20. # This will make real HTTP request to example.com
  21. # We use low max_discovery to keep test fast
  22. result = estimate_pages(config, max_discovery=2, timeout=5)
  23. # Check result structure
  24. self.assertIsInstance(result, dict)
  25. self.assertIn('discovered', result)
  26. self.assertIn('estimated_total', result)
  27. # Actual key is elapsed_seconds, not time_elapsed
  28. self.assertIn('elapsed_seconds', result)
  29. def test_estimate_pages_returns_discovered_count(self):
  30. """Test that result contains discovered page count"""
  31. config = {
  32. 'name': 'test',
  33. 'base_url': 'https://example.com/',
  34. 'rate_limit': 0.1
  35. }
  36. result = estimate_pages(config, max_discovery=1, timeout=5)
  37. self.assertGreaterEqual(result['discovered'], 0)
  38. self.assertIsInstance(result['discovered'], int)
  39. def test_estimate_pages_respects_max_discovery(self):
  40. """Test that estimation respects max_discovery limit"""
  41. config = {
  42. 'name': 'test',
  43. 'base_url': 'https://example.com/',
  44. 'rate_limit': 0.1
  45. }
  46. result = estimate_pages(config, max_discovery=3, timeout=5)
  47. # Should not discover more than max_discovery
  48. self.assertLessEqual(result['discovered'], 3)
  49. def test_estimate_pages_with_start_urls(self):
  50. """Test estimation with custom start_urls"""
  51. config = {
  52. 'name': 'test',
  53. 'base_url': 'https://example.com/',
  54. 'start_urls': ['https://example.com/'],
  55. 'rate_limit': 0.1
  56. }
  57. result = estimate_pages(config, max_discovery=2, timeout=5)
  58. self.assertIsInstance(result, dict)
  59. self.assertIn('discovered', result)
  60. class TestEstimatePagesCLI(unittest.TestCase):
  61. """Test estimate_pages command-line interface (via entry point)"""
  62. def test_cli_help_output(self):
  63. """Test that skill-seekers estimate --help works"""
  64. import subprocess
  65. try:
  66. result = subprocess.run(
  67. ['skill-seekers', 'estimate', '--help'],
  68. capture_output=True,
  69. text=True,
  70. timeout=5
  71. )
  72. # Should return successfully (0 or 2 for argparse)
  73. self.assertIn(result.returncode, [0, 2])
  74. output = result.stdout + result.stderr
  75. self.assertTrue('usage:' in output.lower() or 'estimate' in output.lower())
  76. except FileNotFoundError:
  77. self.skipTest("skill-seekers command not installed")
  78. def test_cli_executes_with_help_flag(self):
  79. """Test that skill-seekers-estimate entry point works"""
  80. import subprocess
  81. try:
  82. result = subprocess.run(
  83. ['skill-seekers-estimate', '--help'],
  84. capture_output=True,
  85. text=True,
  86. timeout=5
  87. )
  88. # Should return successfully
  89. self.assertIn(result.returncode, [0, 2])
  90. except FileNotFoundError:
  91. self.skipTest("skill-seekers-estimate command not installed")
  92. def test_cli_requires_config_argument(self):
  93. """Test that CLI requires config file argument"""
  94. import subprocess
  95. try:
  96. # Run without config argument
  97. result = subprocess.run(
  98. ['skill-seekers', 'estimate'],
  99. capture_output=True,
  100. text=True,
  101. timeout=5
  102. )
  103. # Should fail (non-zero exit code) or show usage
  104. self.assertTrue(
  105. result.returncode != 0 or 'usage' in result.stderr.lower() or 'usage' in result.stdout.lower()
  106. )
  107. except FileNotFoundError:
  108. self.skipTest("skill-seekers command not installed")
  109. class TestEstimatePagesWithRealConfig(unittest.TestCase):
  110. """Test estimation with real config files (if available)"""
  111. def test_estimate_with_real_config_file(self):
  112. """Test estimation using a real config file (if exists)"""
  113. config_path = Path('configs/react.json')
  114. if not config_path.exists():
  115. self.skipTest("configs/react.json not found")
  116. with open(config_path, 'r') as f:
  117. config = json.load(f)
  118. # Use very low max_discovery to keep test fast
  119. result = estimate_pages(config, max_discovery=3, timeout=5)
  120. self.assertIsInstance(result, dict)
  121. self.assertIn('discovered', result)
  122. self.assertGreater(result['discovered'], 0)
  123. if __name__ == '__main__':
  124. unittest.main()