|  | 
|  | 1 | +package cli | 
|  | 2 | + | 
|  | 3 | +import ( | 
|  | 4 | +	"os" | 
|  | 5 | +	"path/filepath" | 
|  | 6 | +	"testing" | 
|  | 7 | +	"time" | 
|  | 8 | +) | 
|  | 9 | + | 
|  | 10 | +func TestCalculateDirectorySize(t *testing.T) { | 
|  | 11 | +	tests := []struct { | 
|  | 12 | +		name     string | 
|  | 13 | +		setup    func(t *testing.T) string | 
|  | 14 | +		expected int64 | 
|  | 15 | +	}{ | 
|  | 16 | +		{ | 
|  | 17 | +			name: "empty directory", | 
|  | 18 | +			setup: func(t *testing.T) string { | 
|  | 19 | +				dir := t.TempDir() | 
|  | 20 | +				return dir | 
|  | 21 | +			}, | 
|  | 22 | +			expected: 0, | 
|  | 23 | +		}, | 
|  | 24 | +		{ | 
|  | 25 | +			name: "single file", | 
|  | 26 | +			setup: func(t *testing.T) string { | 
|  | 27 | +				dir := t.TempDir() | 
|  | 28 | +				err := os.WriteFile(filepath.Join(dir, "test.txt"), []byte("hello"), 0644) | 
|  | 29 | +				if err != nil { | 
|  | 30 | +					t.Fatal(err) | 
|  | 31 | +				} | 
|  | 32 | +				return dir | 
|  | 33 | +			}, | 
|  | 34 | +			expected: 5, | 
|  | 35 | +		}, | 
|  | 36 | +		{ | 
|  | 37 | +			name: "multiple files in nested directories", | 
|  | 38 | +			setup: func(t *testing.T) string { | 
|  | 39 | +				dir := t.TempDir() | 
|  | 40 | +				// File 1: 10 bytes | 
|  | 41 | +				err := os.WriteFile(filepath.Join(dir, "file1.txt"), []byte("0123456789"), 0644) | 
|  | 42 | +				if err != nil { | 
|  | 43 | +					t.Fatal(err) | 
|  | 44 | +				} | 
|  | 45 | +				// Create subdirectory | 
|  | 46 | +				subdir := filepath.Join(dir, "subdir") | 
|  | 47 | +				err = os.Mkdir(subdir, 0755) | 
|  | 48 | +				if err != nil { | 
|  | 49 | +					t.Fatal(err) | 
|  | 50 | +				} | 
|  | 51 | +				// File 2: 5 bytes | 
|  | 52 | +				err = os.WriteFile(filepath.Join(subdir, "file2.txt"), []byte("hello"), 0644) | 
|  | 53 | +				if err != nil { | 
|  | 54 | +					t.Fatal(err) | 
|  | 55 | +				} | 
|  | 56 | +				return dir | 
|  | 57 | +			}, | 
|  | 58 | +			expected: 15, | 
|  | 59 | +		}, | 
|  | 60 | +		{ | 
|  | 61 | +			name: "nonexistent directory", | 
|  | 62 | +			setup: func(t *testing.T) string { | 
|  | 63 | +				return "/nonexistent/path/that/does/not/exist" | 
|  | 64 | +			}, | 
|  | 65 | +			expected: 0, | 
|  | 66 | +		}, | 
|  | 67 | +	} | 
|  | 68 | + | 
|  | 69 | +	for _, tt := range tests { | 
|  | 70 | +		t.Run(tt.name, func(t *testing.T) { | 
|  | 71 | +			dir := tt.setup(t) | 
|  | 72 | +			got := calculateDirectorySize(dir) | 
|  | 73 | +			if got != tt.expected { | 
|  | 74 | +				t.Errorf("calculateDirectorySize() = %d, want %d", got, tt.expected) | 
|  | 75 | +			} | 
|  | 76 | +		}) | 
|  | 77 | +	} | 
|  | 78 | +} | 
|  | 79 | + | 
|  | 80 | +func TestParseDurationString(t *testing.T) { | 
|  | 81 | +	tests := []struct { | 
|  | 82 | +		name     string | 
|  | 83 | +		input    string | 
|  | 84 | +		expected time.Duration | 
|  | 85 | +	}{ | 
|  | 86 | +		{ | 
|  | 87 | +			name:     "valid duration - seconds", | 
|  | 88 | +			input:    "5s", | 
|  | 89 | +			expected: 5 * time.Second, | 
|  | 90 | +		}, | 
|  | 91 | +		{ | 
|  | 92 | +			name:     "valid duration - minutes", | 
|  | 93 | +			input:    "2m", | 
|  | 94 | +			expected: 2 * time.Minute, | 
|  | 95 | +		}, | 
|  | 96 | +		{ | 
|  | 97 | +			name:     "valid duration - hours", | 
|  | 98 | +			input:    "1h", | 
|  | 99 | +			expected: 1 * time.Hour, | 
|  | 100 | +		}, | 
|  | 101 | +		{ | 
|  | 102 | +			name:     "valid duration - complex", | 
|  | 103 | +			input:    "1h30m45s", | 
|  | 104 | +			expected: 1*time.Hour + 30*time.Minute + 45*time.Second, | 
|  | 105 | +		}, | 
|  | 106 | +		{ | 
|  | 107 | +			name:     "invalid duration", | 
|  | 108 | +			input:    "not a duration", | 
|  | 109 | +			expected: 0, | 
|  | 110 | +		}, | 
|  | 111 | +		{ | 
|  | 112 | +			name:     "empty string", | 
|  | 113 | +			input:    "", | 
|  | 114 | +			expected: 0, | 
|  | 115 | +		}, | 
|  | 116 | +		{ | 
|  | 117 | +			name:     "zero duration", | 
|  | 118 | +			input:    "0s", | 
|  | 119 | +			expected: 0, | 
|  | 120 | +		}, | 
|  | 121 | +	} | 
|  | 122 | + | 
|  | 123 | +	for _, tt := range tests { | 
|  | 124 | +		t.Run(tt.name, func(t *testing.T) { | 
|  | 125 | +			got := parseDurationString(tt.input) | 
|  | 126 | +			if got != tt.expected { | 
|  | 127 | +				t.Errorf("parseDurationString(%q) = %v, want %v", tt.input, got, tt.expected) | 
|  | 128 | +			} | 
|  | 129 | +		}) | 
|  | 130 | +	} | 
|  | 131 | +} | 
|  | 132 | + | 
|  | 133 | +func TestTruncateString(t *testing.T) { | 
|  | 134 | +	tests := []struct { | 
|  | 135 | +		name     string | 
|  | 136 | +		input    string | 
|  | 137 | +		maxLen   int | 
|  | 138 | +		expected string | 
|  | 139 | +	}{ | 
|  | 140 | +		{ | 
|  | 141 | +			name:     "string shorter than max length", | 
|  | 142 | +			input:    "hello", | 
|  | 143 | +			maxLen:   10, | 
|  | 144 | +			expected: "hello", | 
|  | 145 | +		}, | 
|  | 146 | +		{ | 
|  | 147 | +			name:     "string equal to max length", | 
|  | 148 | +			input:    "hello", | 
|  | 149 | +			maxLen:   5, | 
|  | 150 | +			expected: "hello", | 
|  | 151 | +		}, | 
|  | 152 | +		{ | 
|  | 153 | +			name:     "string longer than max length", | 
|  | 154 | +			input:    "hello world", | 
|  | 155 | +			maxLen:   8, | 
|  | 156 | +			expected: "hello...", | 
|  | 157 | +		}, | 
|  | 158 | +		{ | 
|  | 159 | +			name:     "max length 3 or less", | 
|  | 160 | +			input:    "hello", | 
|  | 161 | +			maxLen:   3, | 
|  | 162 | +			expected: "hel", | 
|  | 163 | +		}, | 
|  | 164 | +		{ | 
|  | 165 | +			name:     "max length 2", | 
|  | 166 | +			input:    "hello", | 
|  | 167 | +			maxLen:   2, | 
|  | 168 | +			expected: "he", | 
|  | 169 | +		}, | 
|  | 170 | +		{ | 
|  | 171 | +			name:     "max length 1", | 
|  | 172 | +			input:    "hello", | 
|  | 173 | +			maxLen:   1, | 
|  | 174 | +			expected: "h", | 
|  | 175 | +		}, | 
|  | 176 | +		{ | 
|  | 177 | +			name:     "empty string", | 
|  | 178 | +			input:    "", | 
|  | 179 | +			maxLen:   10, | 
|  | 180 | +			expected: "", | 
|  | 181 | +		}, | 
|  | 182 | +		{ | 
|  | 183 | +			name:     "unicode string", | 
|  | 184 | +			input:    "Hello 世界", | 
|  | 185 | +			maxLen:   9, | 
|  | 186 | +			expected: "Hello ...", | 
|  | 187 | +		}, | 
|  | 188 | +	} | 
|  | 189 | + | 
|  | 190 | +	for _, tt := range tests { | 
|  | 191 | +		t.Run(tt.name, func(t *testing.T) { | 
|  | 192 | +			got := truncateString(tt.input, tt.maxLen) | 
|  | 193 | +			if got != tt.expected { | 
|  | 194 | +				t.Errorf("truncateString(%q, %d) = %q, want %q", tt.input, tt.maxLen, got, tt.expected) | 
|  | 195 | +			} | 
|  | 196 | +		}) | 
|  | 197 | +	} | 
|  | 198 | +} | 
0 commit comments