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