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