-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathPathValidationAttributeTests.cs
More file actions
437 lines (355 loc) · 11.5 KB
/
Copy pathPathValidationAttributeTests.cs
File metadata and controls
437 lines (355 loc) · 11.5 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
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
// Copyright (c) ktsu.dev
// All rights reserved.
// Licensed under the MIT license.
namespace ktsu.Semantics.Test;
using System;
using ktsu.Semantics.Paths;
using ktsu.Semantics.Strings;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class PathValidationAttributeTests
{
[TestMethod]
public void IsPathAttribute_ValidPath_ShouldPass()
{
// Arrange
TestPath validPath = TestPath.Create<TestPath>("C:\\valid\\path");
// Act & Assert
Assert.IsTrue(validPath.IsValid());
}
[TestMethod]
public void IsPathAttribute_EmptyPath_ShouldPass()
{
// Arrange
TestPath emptyPath = TestPath.Create<TestPath>("");
// Act & Assert
Assert.IsTrue(emptyPath.IsValid());
}
[TestMethod]
public void IsPathAttribute_PathWithInvalidChars_ShouldFail()
{
// Arrange & Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestPath.Create<TestPath>("C:\\invalid<>path"));
}
[TestMethod]
public void IsPathAttribute_ExcessivelyLongPath_ShouldFail()
{
// Arrange
string longPath = "C:\\" + new string('a', 300);
// Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestPath.Create<TestPath>(longPath));
}
[TestMethod]
public void IsAbsolutePathAttribute_WithAbsolutePath_ShouldPass()
{
// Arrange
TestAbsolutePath absolutePath = TestAbsolutePath.Create<TestAbsolutePath>("C:\\test\\path");
// Act & Assert
Assert.IsTrue(absolutePath.IsValid());
}
[TestMethod]
public void IsAbsolutePathAttribute_WithRelativePath_ShouldFail()
{
// Arrange & Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestAbsolutePath.Create<TestAbsolutePath>("relative\\path"));
}
[TestMethod]
public void IsAbsolutePathAttribute_WithUNCPath_ShouldPass()
{
// Arrange
TestAbsolutePath uncPath = TestAbsolutePath.Create<TestAbsolutePath>("\\\\server\\share\\file");
// Act & Assert
Assert.IsTrue(uncPath.IsValid());
}
[TestMethod]
public void IsAbsolutePathAttribute_EmptyPath_ShouldPass()
{
// Arrange
TestAbsolutePath emptyPath = TestAbsolutePath.Create<TestAbsolutePath>("");
// Act & Assert
Assert.IsTrue(emptyPath.IsValid());
}
[TestMethod]
public void IsRelativePathAttribute_WithRelativePath_ShouldPass()
{
// Arrange
TestRelativePath relativePath = TestRelativePath.Create<TestRelativePath>("relative\\path");
// Act & Assert
Assert.IsTrue(relativePath.IsValid());
}
[TestMethod]
public void IsRelativePathAttribute_WithAbsolutePath_ShouldFail()
{
// Arrange & Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestRelativePath.Create<TestRelativePath>("C:\\absolute\\path"));
}
[TestMethod]
public void IsRelativePathAttribute_WithDotPath_ShouldPass()
{
// Arrange
TestRelativePath dotPath = TestRelativePath.Create<TestRelativePath>("./relative/path");
// Act & Assert
Assert.IsTrue(dotPath.IsValid());
}
[TestMethod]
public void IsRelativePathAttribute_WithParentPath_ShouldPass()
{
// Arrange
TestRelativePath parentPath = TestRelativePath.Create<TestRelativePath>("../parent/path");
// Act & Assert
Assert.IsTrue(parentPath.IsValid());
}
[TestMethod]
public void IsRelativePathAttribute_EmptyPath_ShouldPass()
{
// Arrange
TestRelativePath emptyPath = TestRelativePath.Create<TestRelativePath>("");
// Act & Assert
Assert.IsTrue(emptyPath.IsValid());
}
[TestMethod]
public void IsFileNameAttribute_ValidFileName_ShouldPass()
{
// Arrange
TestFileName fileName = TestFileName.Create<TestFileName>("valid_file_name.txt");
// Act & Assert
Assert.IsTrue(fileName.IsValid());
}
[TestMethod]
public void IsFileNameAttribute_FileNameWithInvalidChars_ShouldFail()
{
// Arrange & Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestFileName.Create<TestFileName>("invalid<>file.txt"));
}
[TestMethod]
public void IsFileNameAttribute_EmptyFileName_ShouldPass()
{
// Arrange
TestFileName emptyFileName = TestFileName.Create<TestFileName>("");
// Act & Assert
Assert.IsTrue(emptyFileName.IsValid());
}
[TestMethod]
public void IsDirectoryPathAttribute_NonExistentPath_ShouldPass()
{
// Arrange
TestDirectoryPath directoryPath = TestDirectoryPath.Create<TestDirectoryPath>("C:\\nonexistent\\directory");
// Act & Assert
Assert.IsTrue(directoryPath.IsValid());
}
[TestMethod]
public void IsDirectoryPathAttribute_EmptyPath_ShouldPass()
{
// Arrange
TestDirectoryPath emptyPath = TestDirectoryPath.Create<TestDirectoryPath>("");
// Act & Assert
Assert.IsTrue(emptyPath.IsValid());
}
[TestMethod]
public void IsFilePathAttribute_NonExistentPath_ShouldPass()
{
// Arrange
TestFilePath filePath = TestFilePath.Create<TestFilePath>("C:\\nonexistent\\file.txt");
// Act & Assert
Assert.IsTrue(filePath.IsValid());
}
[TestMethod]
public void IsFilePathAttribute_EmptyPath_ShouldPass()
{
// Arrange
TestFilePath emptyPath = TestFilePath.Create<TestFilePath>("");
// Act & Assert
Assert.IsTrue(emptyPath.IsValid());
}
[TestMethod]
public void DoesExistAttribute_NonExistentPath_ShouldFail()
{
// Arrange & Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestExistingPath.Create<TestExistingPath>("C:\\definitely\\does\\not\\exist"));
}
[TestMethod]
public void DoesExistAttribute_EmptyPath_ShouldFail()
{
// Arrange & Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestExistingPath.Create<TestExistingPath>(""));
}
[TestMethod]
public void IsExtensionAttribute_ValidExtension_ShouldPass()
{
// Arrange
TestExtension extension = TestExtension.Create<TestExtension>(".txt");
// Act & Assert
Assert.IsTrue(extension.IsValid());
}
[TestMethod]
public void IsExtensionAttribute_ExtensionWithoutDot_ShouldFail()
{
// Arrange & Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestExtension.Create<TestExtension>("txt"));
}
[TestMethod]
public void IsExtensionAttribute_EmptyExtension_ShouldPass()
{
// Arrange
TestExtension emptyExtension = TestExtension.Create<TestExtension>("");
// Act & Assert
Assert.IsTrue(emptyExtension.IsValid());
}
[TestMethod]
public void IsExtensionAttribute_MultipleDotsExtension_ShouldPass()
{
// Arrange
TestExtension multiDotExtension = TestExtension.Create<TestExtension>(".tar.gz");
// Act & Assert
Assert.IsTrue(multiDotExtension.IsValid());
}
[TestMethod]
[TestCategory("OS-Specific")]
public void IsAbsolutePathAttribute_UnixStylePath_ShouldPassOnUnix()
{
// Only run this test on Unix-like systems
if (Environment.OSVersion.Platform is PlatformID.Unix or PlatformID.MacOSX)
{
// Arrange
TestAbsolutePath unixPath = TestAbsolutePath.Create<TestAbsolutePath>("/usr/bin/local");
// Act & Assert
Assert.IsTrue(unixPath.IsValid());
}
}
[TestMethod]
public void IsRelativePathAttribute_UnixStyleRelativePath_ShouldPass()
{
// Arrange
TestRelativePath unixStylePath = TestRelativePath.Create<TestRelativePath>("usr/bin/local");
// Act & Assert
Assert.IsTrue(unixStylePath.IsValid());
}
[TestMethod]
public void IsPathAttribute_PathAtExactLimit_ShouldPass()
{
// Most systems have a path limit around 260 chars (Windows) or 4096 (Unix)
// We'll use a limit that works on all systems for testing
int maxPathLength = 240; // Just under Windows limit
string exactLengthPath = "C:\\" + new string('a', maxPathLength - 3);
// Ensure we got the expected length
Assert.AreEqual(maxPathLength, exactLengthPath.Length);
// Arrange
TestPath pathAtLimit = TestPath.Create<TestPath>(exactLengthPath);
// Act & Assert
Assert.IsTrue(pathAtLimit.IsValid());
}
[TestMethod]
public void IsPathAttribute_PathOverLimit_ShouldFail()
{
// Using Windows path limit (260) + 100 chars to ensure it's over limit on all platforms
int tooLongLength = 360;
string tooLongPath = "C:\\" + new string('a', tooLongLength - 3);
// Ensure we got the expected length
Assert.AreEqual(tooLongLength, tooLongPath.Length);
// Arrange & Act & Assert
Assert.ThrowsExactly<ArgumentException>(() =>
TestPath.Create<TestPath>(tooLongPath));
}
[TestMethod]
public void IsFileNameAttribute_FileNameWithValidSpecialChars_ShouldPass()
{
// Arrange - using valid special chars
TestFileName specialCharsName = TestFileName.Create<TestFileName>("valid-file_name (1).txt");
// Act & Assert
Assert.IsTrue(specialCharsName.IsValid());
}
[TestMethod]
public void IsValidDirectoryNameAttribute_ValidDirectoryName_ShouldPass()
{
// Arrange
TestDirectoryName validName = TestDirectoryName.Create<TestDirectoryName>("MyFolder");
// Act & Assert
Assert.IsTrue(validName.IsValid());
}
[TestMethod]
public void IsValidDirectoryNameAttribute_DirectoryNameWithSpaces_ShouldPass()
{
// Arrange
TestDirectoryName nameWithSpaces = TestDirectoryName.Create<TestDirectoryName>("My Folder Name");
// Act & Assert
Assert.IsTrue(nameWithSpaces.IsValid());
}
[TestMethod]
public void IsValidDirectoryNameAttribute_DirectoryNameWithValidSpecialChars_ShouldPass()
{
// Arrange - using valid special chars
TestDirectoryName specialCharsName = TestDirectoryName.Create<TestDirectoryName>("valid-folder_name (1)");
// Act & Assert
Assert.IsTrue(specialCharsName.IsValid());
}
[TestMethod]
public void IsValidDirectoryNameAttribute_EmptyDirectoryName_ShouldPass()
{
// Arrange
TestDirectoryName emptyName = TestDirectoryName.Create<TestDirectoryName>("");
// Act & Assert
Assert.IsTrue(emptyName.IsValid());
}
[TestMethod]
public void IsValidDirectoryNameAttribute_DirectoryNameWithPathSeparator_ShouldFail()
{
// Arrange & Act & Assert - directory names shouldn't contain path separators
Assert.ThrowsExactly<ArgumentException>(() =>
TestDirectoryName.Create<TestDirectoryName>("folder\\subfolder"));
}
[TestMethod]
public void IsValidDirectoryNameAttribute_DirectoryNameWithForwardSlash_ShouldFail()
{
// Arrange & Act & Assert - directory names shouldn't contain forward slashes
Assert.ThrowsExactly<ArgumentException>(() =>
TestDirectoryName.Create<TestDirectoryName>("folder/subfolder"));
}
[TestMethod]
public void IsValidDirectoryNameAttribute_DirectoryNameWithInvalidChars_ShouldFail()
{
// Arrange & Act & Assert - test with invalid filename characters
Assert.ThrowsExactly<ArgumentException>(() =>
TestDirectoryName.Create<TestDirectoryName>("invalid<>name"));
}
[TestMethod]
public void IsValidDirectoryNameAttribute_DirectoryNameWithColon_ShouldFail()
{
// Arrange & Act & Assert - colon is invalid in directory names (except drive letters)
Assert.ThrowsExactly<ArgumentException>(() =>
TestDirectoryName.Create<TestDirectoryName>("invalid:name"));
}
[TestMethod]
public void IsValidDirectoryNameAttribute_DirectoryNameWithPipe_ShouldFail()
{
// Arrange & Act & Assert - pipe is an invalid character
Assert.ThrowsExactly<ArgumentException>(() =>
TestDirectoryName.Create<TestDirectoryName>("invalid|name"));
}
}
// Test record types for validation attribute testing
[IsPath]
public record TestPath : SemanticString<TestPath> { }
[IsAbsolutePath]
public record TestAbsolutePath : SemanticString<TestAbsolutePath> { }
[IsRelativePath]
public record TestRelativePath : SemanticString<TestRelativePath> { }
[IsValidFileName]
public record TestFileName : SemanticString<TestFileName> { }
[IsAbsoluteDirectoryPath]
public record TestDirectoryPath : SemanticString<TestDirectoryPath> { }
[IsFilePath]
public record TestFilePath : SemanticString<TestFilePath> { }
[DoesExist]
public record TestExistingPath : SemanticString<TestExistingPath> { }
[IsExtension]
public record TestExtension : SemanticString<TestExtension> { }
[IsValidDirectoryName]
public record TestDirectoryName : SemanticString<TestDirectoryName> { }