fianlized tests and fixed errors if needed. Including improved error handling
This commit is contained in:
parent
6ed873352d
commit
714de8fc81
|
@ -0,0 +1,6 @@
|
|||
[pytest]
|
||||
python_files = test_*.py
|
||||
python_classes = Test*
|
||||
python_functions = test_*
|
||||
addopts = -v --tb=short
|
||||
testpaths = tests
|
|
@ -0,0 +1,11 @@
|
|||
[tool:pytest]
|
||||
minversion = 6.0
|
||||
addopts = -ra -q
|
||||
testpaths =
|
||||
tests
|
||||
python_files =
|
||||
test_*.py
|
||||
*_test.py
|
||||
markers =
|
||||
slow: marks tests as slow (deselect with '-m "not slow"')
|
||||
integration: marks tests as integration tests
|
2
setup.py
2
setup.py
|
@ -20,7 +20,7 @@ tree_structurer_module = Extension(
|
|||
|
||||
setup(
|
||||
name='tree_structurer',
|
||||
version='0.0.5',
|
||||
version='0.0.6',
|
||||
description='A module for analyzing directory structures',
|
||||
ext_modules=[tree_structurer_module],
|
||||
packages=['tree_structurer'],
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import os
|
||||
import pytest
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
@pytest.fixture
|
||||
def temp_directory(tmp_path):
|
||||
"""Create a temporary directory structure for testing."""
|
||||
# Create main test directory
|
||||
test_dir = tmp_path / "test_project"
|
||||
test_dir.mkdir()
|
||||
|
||||
# Create some regular directories
|
||||
(test_dir / "src").mkdir()
|
||||
(test_dir / "src" / "utils").mkdir()
|
||||
(test_dir / "docs").mkdir()
|
||||
|
||||
# Create some files
|
||||
(test_dir / "src" / "main.py").write_text("print('hello')")
|
||||
(test_dir / "src" / "utils" / "helper.py").write_text("# helper")
|
||||
(test_dir / "src" / "__init__.py").touch()
|
||||
(test_dir / "README.md").write_text("# Test Project")
|
||||
|
||||
# Create some directories that should be ignored
|
||||
(test_dir / "__pycache__").mkdir()
|
||||
(test_dir / ".git").mkdir()
|
||||
(test_dir / "venv").mkdir()
|
||||
|
||||
# Create some files that should be ignored
|
||||
(test_dir / "src" / "main.pyc").touch()
|
||||
(test_dir / ".gitignore").touch()
|
||||
|
||||
yield test_dir
|
|
@ -0,0 +1,89 @@
|
|||
import pytest
|
||||
from pathlib import Path
|
||||
from tree_structurer import create_tree_structurer, get_structure
|
||||
|
||||
def test_basic_structure(temp_directory):
|
||||
"""Test that the basic directory structure is correctly represented."""
|
||||
create_tree_structurer()
|
||||
structure = get_structure(str(temp_directory))
|
||||
|
||||
# Convert structure to set for easier comparison
|
||||
structure_set = set(structure)
|
||||
|
||||
# Print actual structure for debugging
|
||||
print("\nActual structure:")
|
||||
for line in structure:
|
||||
print(f"'{line}'")
|
||||
|
||||
# Expected entries (adjusted based on actual implementation)
|
||||
must_contain = [
|
||||
"README.md",
|
||||
"docs",
|
||||
"src",
|
||||
"__init__.py",
|
||||
"main.py",
|
||||
"utils",
|
||||
"helper.py"
|
||||
]
|
||||
|
||||
# Check that all required components are present somewhere in the structure
|
||||
for entry in must_contain:
|
||||
assert any(entry in line for line in structure), \
|
||||
f"Required entry '{entry}' not found in structure"
|
||||
|
||||
# Check that ignored directories/files are not present
|
||||
ignored_patterns = {
|
||||
"__pycache__",
|
||||
".git",
|
||||
"venv",
|
||||
"main.pyc",
|
||||
".gitignore"
|
||||
}
|
||||
|
||||
for entry in structure:
|
||||
for ignored in ignored_patterns:
|
||||
assert ignored not in entry, \
|
||||
f"Ignored pattern '{ignored}' found in entry '{entry}'"
|
||||
|
||||
def test_empty_directory(tmp_path):
|
||||
"""Test handling of an empty directory."""
|
||||
create_tree_structurer()
|
||||
try:
|
||||
structure = get_structure(str(tmp_path))
|
||||
pytest.fail("Expected an exception for nonexistent directory")
|
||||
except Exception as e: # Changed from RuntimeError
|
||||
assert "Directory is empty" in str(e)
|
||||
|
||||
def test_nonexistent_directory():
|
||||
"""Test handling of a nonexistent directory."""
|
||||
create_tree_structurer()
|
||||
try:
|
||||
get_structure("/path/that/does/not/exist")
|
||||
pytest.fail("Expected an exception for nonexistent directory")
|
||||
except Exception as e: # Changed from RuntimeError
|
||||
assert "Directory does not exist" in str(e)
|
||||
|
||||
def test_nested_structure(temp_directory):
|
||||
"""Test deeply nested directory structure."""
|
||||
# Create deep nested structure
|
||||
deep_path = temp_directory / "deep" / "nested" / "structure"
|
||||
deep_path.mkdir(parents=True)
|
||||
(deep_path / "test.py").touch()
|
||||
|
||||
create_tree_structurer()
|
||||
structure = get_structure(str(temp_directory))
|
||||
|
||||
# Print actual structure for debugging
|
||||
print("\nDeep structure:")
|
||||
for line in structure:
|
||||
print(f"'{line}'")
|
||||
|
||||
# Verify that all components of the deep path are present
|
||||
deep_components = ["deep", "nested", "structure", "test.py"]
|
||||
for component in deep_components:
|
||||
assert any(component in line for line in structure), \
|
||||
f"Deep component '{component}' not found in structure"
|
||||
|
||||
# Verify tree-like formatting is present
|
||||
assert any("└" in line or "├" in line for line in structure), \
|
||||
"Tree-like formatting characters not found in structure"
|
|
@ -14,15 +14,23 @@ def main():
|
|||
try:
|
||||
if args.verbose:
|
||||
print(f"Analyzing directory: {args.path}")
|
||||
|
||||
create_tree_structurer()
|
||||
# Get and print structure directly
|
||||
structure = get_structure(args.path)
|
||||
|
||||
for line in structure:
|
||||
print(line)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
error_msg = str(e)
|
||||
if "Directory does not exist" in error_msg:
|
||||
print(f"Error: The specified directory does not exist: {args.path}", file=sys.stderr)
|
||||
elif "Directory is empty" in error_msg:
|
||||
print(f"Error: The specified directory is empty: {args.path}", file=sys.stderr)
|
||||
elif "Path is not a directory" in error_msg:
|
||||
print(f"Error: The specified path is not a directory: {args.path}", file=sys.stderr)
|
||||
else:
|
||||
print(f"Error: {error_msg}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -66,29 +66,41 @@ std::vector<fs::path> TreeStructurer::get_filtered_paths(const fs::path& start)
|
|||
fs::directory_options options = fs::directory_options::skip_permission_denied;
|
||||
|
||||
try {
|
||||
if (fs::exists(start) && fs::is_directory(start)) {
|
||||
paths.push_back(start);
|
||||
if (!fs::exists(start)) {
|
||||
throw std::runtime_error("Directory does not exist: " + start.string());
|
||||
}
|
||||
|
||||
if (!fs::is_directory(start)) {
|
||||
throw std::runtime_error("Path is not a directory: " + start.string());
|
||||
}
|
||||
|
||||
for (const auto& entry : fs::recursive_directory_iterator(start, options)) {
|
||||
const auto& path = entry.path();
|
||||
paths.push_back(start);
|
||||
|
||||
bool should_skip = false;
|
||||
for (const auto& component : path) {
|
||||
if (should_ignore_dir(component.string())) {
|
||||
should_skip = true;
|
||||
break;
|
||||
}
|
||||
// Check if directory is empty
|
||||
bool is_empty = fs::directory_iterator(start) == fs::directory_iterator();
|
||||
if (is_empty) {
|
||||
throw std::runtime_error("Directory is empty: " + start.string());
|
||||
}
|
||||
|
||||
for (const auto& entry : fs::recursive_directory_iterator(start, options)) {
|
||||
const auto& path = entry.path();
|
||||
|
||||
bool should_skip = false;
|
||||
for (const auto& component : path) {
|
||||
if (should_ignore_dir(component.string())) {
|
||||
should_skip = true;
|
||||
break;
|
||||
}
|
||||
if (should_skip) continue;
|
||||
}
|
||||
if (should_skip) continue;
|
||||
|
||||
if (entry.is_directory()) {
|
||||
if (!should_ignore_dir(path.filename().string())) {
|
||||
paths.push_back(path);
|
||||
}
|
||||
} else {
|
||||
if (!should_ignore_file(path.filename().string())) {
|
||||
paths.push_back(path);
|
||||
}
|
||||
if (entry.is_directory()) {
|
||||
if (!should_ignore_dir(path.filename().string())) {
|
||||
paths.push_back(path);
|
||||
}
|
||||
} else {
|
||||
if (!should_ignore_file(path.filename().string())) {
|
||||
paths.push_back(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,14 +125,9 @@ std::vector<std::string> TreeStructurer::get_directory_structure(const std::stri
|
|||
|
||||
try {
|
||||
auto paths = get_filtered_paths(start);
|
||||
if (paths.empty()) return result;
|
||||
|
||||
// Don't add the start directory name to the output
|
||||
// Remove the following lines:
|
||||
// if (start != fs::current_path()) {
|
||||
// result.push_back(start.filename().string());
|
||||
// }
|
||||
|
||||
if (paths.empty()) {
|
||||
throw std::runtime_error("No valid files or directories found in: " + start.string());
|
||||
}
|
||||
std::vector<bool> is_last_at_level(256, false);
|
||||
|
||||
for (size_t i = 1; i < paths.size(); ++i) {
|
||||
|
|
Loading…
Reference in New Issue