1
+ // Licensed to the .NET Foundation under one or more agreements.
2
+ // The .NET Foundation licenses this file to you under the MIT license.
3
+
4
+ using Aspire . Cli . Commands ;
5
+
6
+ namespace Aspire . Cli . Tests . Commands ;
7
+
8
+ public class ProjectNameValidatorTests
9
+ {
10
+ [ Theory ]
11
+ [ InlineData ( "项目1" , true ) ] // Chinese
12
+ [ InlineData ( "Проект1" , true ) ] // Cyrillic
13
+ [ InlineData ( "プロジェクト1" , true ) ] // Japanese
14
+ [ InlineData ( "مشروع1" , true ) ] // Arabic
15
+ [ InlineData ( "Project_1" , true ) ] // Latin with underscore
16
+ [ InlineData ( "Project-1" , true ) ] // Latin with dash
17
+ [ InlineData ( "Project.1" , true ) ] // Latin with dot
18
+ [ InlineData ( "MyApp" , true ) ] // Simple ASCII
19
+ [ InlineData ( "A" , true ) ] // Single character
20
+ [ InlineData ( "1" , true ) ] // Single number
21
+ [ InlineData ( "プ" , true ) ] // Single Unicode character
22
+ [ InlineData ( "Test123" , true ) ] // Mixed letters and numbers
23
+ [ InlineData ( "My_Cool-Project.v2" , true ) ] // Complex valid name
24
+ [ InlineData ( "Project:1" , true ) ] // Colon (now allowed)
25
+ [ InlineData ( "Project*1" , true ) ] // Asterisk (now allowed)
26
+ [ InlineData ( "Project?1" , true ) ] // Question mark (now allowed)
27
+ [ InlineData ( "Project\" 1" , true ) ] // Quote (now allowed)
28
+ [ InlineData ( "Project<1" , true ) ] // Less than (now allowed)
29
+ [ InlineData ( "Project>1" , true ) ] // Greater than (now allowed)
30
+ [ InlineData ( "Project|1" , true ) ] // Pipe (now allowed)
31
+ [ InlineData ( "Project " , true ) ] // Ends with space (now allowed)
32
+ [ InlineData ( " Project" , true ) ] // Starts with space (now allowed)
33
+ [ InlineData ( "Pro ject" , true ) ] // Space in middle (now allowed)
34
+ [ InlineData ( "-Project" , true ) ] // Starts with dash (now allowed)
35
+ [ InlineData ( "Project-" , true ) ] // Ends with dash (now allowed)
36
+ [ InlineData ( ".Project" , true ) ] // Starts with dot (now allowed)
37
+ [ InlineData ( "Project." , true ) ] // Ends with dot (now allowed)
38
+ [ InlineData ( "_Project" , true ) ] // Starts with underscore (now allowed)
39
+ [ InlineData ( "Project_" , true ) ] // Ends with underscore (now allowed)
40
+ public void IsProjectNameValid_ValidNames_ReturnsTrue ( string projectName , bool expected )
41
+ {
42
+ // Act
43
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
44
+
45
+ // Assert
46
+ Assert . Equal ( expected , result ) ;
47
+ }
48
+
49
+ [ Theory ]
50
+ [ InlineData ( "Project/1" , false ) ] // Forward slash (path separator)
51
+ [ InlineData ( "Project\\ 1" , false ) ] // Backslash (path separator)
52
+ [ InlineData ( "" , false ) ] // Empty string
53
+ [ InlineData ( " " , false ) ] // Space only
54
+ [ InlineData ( " " , false ) ] // Multiple spaces only
55
+ [ InlineData ( "\t " , false ) ] // Tab only
56
+ [ InlineData ( "\n " , false ) ] // Newline only
57
+ public void IsProjectNameValid_InvalidNames_ReturnsFalse ( string projectName , bool expected )
58
+ {
59
+ // Act
60
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
61
+
62
+ // Assert
63
+ Assert . Equal ( expected , result ) ;
64
+ }
65
+
66
+ [ Fact ]
67
+ public void IsProjectNameValid_MaxLength254_ReturnsTrue ( )
68
+ {
69
+ // Arrange
70
+ var projectName = new string ( 'A' , 254 ) ;
71
+
72
+ // Act
73
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
74
+
75
+ // Assert
76
+ Assert . True ( result ) ;
77
+ }
78
+
79
+ [ Fact ]
80
+ public void IsProjectNameValid_Length255_ReturnsFalse ( )
81
+ {
82
+ // Arrange
83
+ var projectName = new string ( 'A' , 255 ) ;
84
+
85
+ // Act
86
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
87
+
88
+ // Assert
89
+ Assert . False ( result ) ;
90
+ }
91
+
92
+ [ Theory ]
93
+ [ InlineData ( "项目测试名称很长的中文项目名称" ) ] // Long Chinese name
94
+ [ InlineData ( "очень_длинное_русское_имя_проекта" ) ] // Long Russian name
95
+ [ InlineData ( "とても長い日本語のプロジェクト名" ) ] // Long Japanese name
96
+ [ InlineData ( "اسم_مشروع_طويل_جدا_بالعربية" ) ] // Long Arabic name
97
+ public void IsProjectNameValid_LongUnicodeNames_ReturnsTrue ( string projectName )
98
+ {
99
+ // Act
100
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
101
+
102
+ // Assert
103
+ Assert . True ( result , $ "Unicode project name should be valid: { projectName } ") ;
104
+ }
105
+
106
+ [ Theory ]
107
+ [ InlineData ( "Ελληνικά" , true ) ] // Greek
108
+ [ InlineData ( "עברית" , true ) ] // Hebrew
109
+ [ InlineData ( "हिन्दी" , true ) ] // Hindi
110
+ [ InlineData ( "ไทย" , true ) ] // Thai
111
+ [ InlineData ( "한국어" , true ) ] // Korean
112
+ [ InlineData ( "Türkçe" , true ) ] // Turkish
113
+ [ InlineData ( "Português" , true ) ] // Portuguese with accent
114
+ [ InlineData ( "Français" , true ) ] // French with accent
115
+ [ InlineData ( "Español" , true ) ] // Spanish with accent
116
+ [ InlineData ( "Deutsch" , true ) ] // German
117
+ public void IsProjectNameValid_VariousLanguages_ReturnsTrue ( string projectName , bool expected )
118
+ {
119
+ // Act
120
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
121
+
122
+ // Assert
123
+ Assert . Equal ( expected , result ) ;
124
+ }
125
+
126
+ [ Theory ]
127
+ [ InlineData ( "Test123-Project_Name.v2" ) ] // Complex valid with all allowed characters
128
+ [ InlineData ( "A1-B2_C3.D4" ) ] // Mixed with separators
129
+ [ InlineData ( "项目-测试_版本.1" ) ] // Unicode with separators
130
+ public void IsProjectNameValid_ComplexValidNames_ReturnsTrue ( string projectName )
131
+ {
132
+ // Act
133
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
134
+
135
+ // Assert
136
+ Assert . True ( result , $ "Complex valid project name should be valid: { projectName } ") ;
137
+ }
138
+
139
+ [ Theory ]
140
+ [ InlineData ( "Test..Name" ) ] // Double dot
141
+ [ InlineData ( "Test--Name" ) ] // Double dash
142
+ [ InlineData ( "Test__Name" ) ] // Double underscore
143
+ public void IsProjectNameValid_ConsecutiveSpecialChars_ReturnsTrue ( string projectName )
144
+ {
145
+ // These should be valid as the spec doesn't prohibit consecutive allowed characters
146
+ // Act
147
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
148
+
149
+ // Assert
150
+ Assert . True ( result , $ "Consecutive allowed characters should be valid: { projectName } ") ;
151
+ }
152
+
153
+ [ Theory ]
154
+ [ InlineData ( "My/Project" ) ] // Forward slash in middle
155
+ [ InlineData ( "/MyProject" ) ] // Forward slash at start
156
+ [ InlineData ( "MyProject/" ) ] // Forward slash at end
157
+ [ InlineData ( "My\\ Project" ) ] // Backslash in middle
158
+ [ InlineData ( "\\ MyProject" ) ] // Backslash at start
159
+ [ InlineData ( "MyProject\\ " ) ] // Backslash at end
160
+ [ InlineData ( "My/Project/Name" ) ] // Multiple forward slashes
161
+ [ InlineData ( "My\\ Project\\ Name" ) ] // Multiple backslashes
162
+ [ InlineData ( "My/Project\\ Name" ) ] // Mixed path separators
163
+ public void IsProjectNameValid_PathSeparators_ReturnsFalse ( string projectName )
164
+ {
165
+ // Act
166
+ var result = ProjectNameValidator . IsProjectNameValid ( projectName ) ;
167
+
168
+ // Assert
169
+ Assert . False ( result , $ "Project name with path separators should be invalid: { projectName } ") ;
170
+ }
171
+ }
0 commit comments