-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_cli.py
More file actions
282 lines (241 loc) · 12 KB
/
Copy pathtest_cli.py
File metadata and controls
282 lines (241 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
"""Tests for CLI module."""
import tempfile
from pathlib import Path
from cedarmapper.cli.main import run_cli
class TestCLI:
"""Test command-line interface."""
def test_cli_basic_run(self):
"""Test basic CLI invocation returns code 0 and content contains root dir."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
(tmppath / "test.txt").write_text("hello world")
code, out = run_cli([str(tmppath)])
assert code == 0
assert tmppath.name + "/" in out or "test.txt" in out
def test_cli_nonexistent_path(self):
"""Test CLI with nonexistent path."""
code, out = run_cli(["/nonexistent/path"])
assert code == 2
assert "Path not found" in out
def test_cli_max_depth_flag(self):
"""Test CLI with --max-depth flag."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
subdir = tmppath / "subdir"
subdir.mkdir()
(tmppath / "file1.txt").write_text("hello")
(subdir / "file2.txt").write_text("world")
code_flat, out_flat = run_cli([str(tmppath), "--max-depth", "1"])
code_tree, out_tree = run_cli([str(tmppath), "--max-depth", "1", "--tree"])
assert code_flat == 0 and code_tree == 0
# The outputs should be meaningfully different:
assert out_flat != out_tree
# tree output should include indentation or directory slash
assert "/" in out_tree
# flat output should show paths like "rootname/subdir/..." (no indentation)
assert tmppath.name + "/" in out_flat
def test_cli_skip_word_count_flag(self):
"""Test CLI with --skip-word-count flag."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
(tmppath / "test.txt").write_text("hello world")
# Test with header - Words column should be missing
code, out = run_cli([str(tmppath), "--skip-word-count"])
assert code == 0
lines = out.splitlines()
header = lines[0]
# Words column should not be in header
assert "Words" not in header
# Size column should be present
assert "Size" in header
# First data line should start with size, not "-"
data_line = lines[1]
assert not data_line.startswith("-")
assert data_line[0].isdigit() or data_line[0].isspace()
# Test with --skip-header - should start directly with size
code, out_no_header = run_cli([str(tmppath), "--skip-word-count", "--skip-header"])
assert code == 0
# Should not contain "- " (space after dash) which would indicate Words column
first_line = out_no_header.splitlines()[0]
assert "- " not in first_line # No "- " pattern (Words column would show this)
# Should start with digits (size) or spaces (alignment)
assert first_line[0].isdigit() or first_line[0].isspace()
def test_cli_default_path(self):
"""Test CLI with default path (current directory)."""
code, out = run_cli([])
assert code == 0
def test_skip_word_count_column_combinations(self):
"""Test --skip-word-count with different flag combinations."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
(tmppath / "test.txt").write_text("hello world test")
(tmppath / "subdir").mkdir()
(tmppath / "subdir" / "file2.txt").write_text("more content")
# Test 1: --skip-word-count + --skip-date (Size + Path only)
code, out = run_cli([str(tmppath), "--skip-word-count", "--skip-date"])
assert code == 0
lines = out.splitlines()
header = lines[0]
# Should contain Size and Path but not Words or Modified
assert "Words" not in header
assert "Modified" not in header
assert "Size" in header
assert "Path" in header
# Test 2: --skip-word-count + --date-format day (Size + Modified + Path)
code, out = run_cli([str(tmppath), "--skip-word-count", "--date-format", "day"])
assert code == 0
lines = out.splitlines()
header = lines[0]
# Should contain Size, Modified, and Path but not Words
assert "Words" not in header
assert "Size" in header
assert "Modified" in header
assert "Path" in header
# Test 3: --skip-word-count + --tree mode
code, out = run_cli([str(tmppath), "--skip-word-count", "--tree"])
assert code == 0
lines = out.splitlines()
header = lines[0]
assert "Words" not in header
assert "Size" in header
# Test 4: --skip-word-count + --skip-header + --skip-totals
code, out = run_cli(
[str(tmppath), "--skip-word-count", "--skip-header", "--skip-totals"]
)
assert code == 0
lines = out.splitlines()
# Should have only data lines, no headers or totals
for line in lines:
assert not line.startswith("Words")
assert not line.startswith("TOTAL")
assert "- " not in line # No "- " pattern since Words column is hidden
# Test 5: Normal mode (without --skip-word-count) should show Words column
code, out_normal = run_cli([str(tmppath)])
assert code == 0
lines_normal = out_normal.splitlines()
header_normal = lines_normal[0]
assert "Words" in header_normal
assert "Size" in header_normal
def test_skip_word_count_tree_mode_structure(self):
"""Test that tree structure is preserved with --skip-word-count."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
(tmppath / "root.txt").write_text("root content")
subdir = tmppath / "subdir"
subdir.mkdir()
(subdir / "child.txt").write_text("child content")
subsub = subdir / "subsub"
subsub.mkdir()
(subsub / "deep.txt").write_text("deep content")
# Test tree mode with --skip-word-count
code, out_tree = run_cli(
[str(tmppath), "--tree", "--skip-word-count", "--max-depth", "2"]
)
assert code == 0
lines = out_tree.splitlines()
# Should have header and tree structure
header = lines[0]
assert "Words" not in header
assert "Size" in header
# Should have tree characters in data lines
data_lines = lines[1:]
has_tree_chars = any(
"├── " in line or "└── " in line or "│ " in line for line in data_lines
)
assert has_tree_chars
# No "- " pattern in data lines since Words column is hidden
for line in data_lines:
# Skip separator and totals lines (contain only dashes and spaces)
if set(line) <= {"-", " "}:
continue
if line.strip() == "TOTAL":
continue
# Data lines should not have "- " pattern from Words column
assert "- " not in line
def test_cli_click_line_limit_option(self):
"""Test Click integration with --line-limit option."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
# Create many files to test limiting
for i in range(10):
(tmppath / f"file{i}.txt").write_text(f"content {i}")
code, out = run_cli([str(tmppath), "--max-depth", "1", "--line-limit", "3"])
assert code == 0
# Basic check that line limiting is working
assert "Words" in out or "Size" in out
def test_cli_negative_n_format_click_integration(self):
"""Test -N format for line limiting through Click integration."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
for i in range(5):
(tmppath / f"test{i}.txt").write_text(f"test {i}")
code, out = run_cli([str(tmppath), "-2"])
assert code == 0
# Verify output is reasonable
assert "Words" in out or "test" in out
def test_cli_original_failing_case_click_integration(self):
"""Test the exact case that was failing: -t -d 1 -3."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
# Create nested structure similar to what was failing
for i in range(5):
(tmppath / f"file{i}.txt").write_text(f"content {i}")
subdir = tmppath / "subdir"
subdir.mkdir()
for i in range(3):
(subdir / f"subfile{i}.txt").write_text(f"subcontent {i}")
# Test the exact command that was failing before Click integration
code, out = run_cli([str(tmppath), "-t", "-d", "1", "-3"])
assert code == 0
# Should have some tree structure output
assert "├── " in out or "└── " in out or "/" in out
def test_cli_line_limit_with_other_click_options(self):
"""Test line limiting combined with other Click options."""
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
# Create files with different sizes for sorting
(tmppath / "small.txt").write_text("small")
(tmppath / "large.txt").write_text("x" * 1000)
(tmppath / "medium.txt").write_text("x" * 100)
# Test combination of Click options
code, out = run_cli(
[str(tmppath), "--tree", "--max-depth", "1", "--sort", "-s", "--line-limit", "2"]
)
assert code == 0
# Should have basic structure
assert "Words" in out or "Size" in out
def test_cli_invalid_line_limit_values(self):
"""Test error handling for invalid line limit values through Click."""
# Test zero value
code, out = run_cli(["--line-limit", "0"])
assert code == 2
assert "positive integer" in out.lower()
# Test negative value
code, out = run_cli(["--line-limit", "-5"])
assert code == 2
assert "positive integer" in out.lower()
def test_cli_help_shows_git_log_style_documentation(self):
"""Test that help shows git log-style line limiting documentation."""
# Test using the actual CLI command (since --help is handled by Click)
import subprocess
result = subprocess.run(["cedarmapper", "ls", "--help"], capture_output=True, text=True)
assert result.returncode == 0
# Should show tree-only functionality but not --line-limit (we use -N git log style)
assert "--tree-only" in result.stdout
# Verify we have the basic expected structure without duplicate aliases
def test_cli_short_aliases_documented(self):
"""Test that short option aliases are documented in help."""
# Test using the actual CLI command (since --help is handled by Click)
import subprocess
result = subprocess.run(["cedarmapper", "ls", "--help"], capture_output=True, text=True)
assert result.returncode == 0
# Check that -t and -n aliases are properly formatted with their long options
lines = result.stdout.splitlines()
help_text = "\n".join(lines)
# Should have -t and --tree on the same line (proper Click formatting)
assert "-t, --tree" in help_text
# Should have -n and --numbered-indent on the same line (proper Click formatting)
assert "-n, --numbered-indent" in help_text
# Should NOT have duplicate "also:" references since we cleaned those up
assert "also: -t" not in help_text
assert "also: -n" not in help_text