Skip to content

Commit 3d0cd55

Browse files
Add Rust AppHost scaffold regression coverage (#17283)
* Add Rust AppHost scaffold regression coverage Centralize the Rust AppHost marker filename and add language support tests that assert Rust scaffolding emits apphost.rs without apphost.ts, detection requires the Rust marker plus Cargo.toml, and the runtime spec remains cargo run. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Test Rust detection requires Cargo manifest Add a negative Rust language-support test covering apphost.rs without Cargo.toml so detection keeps requiring the Cargo manifest. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use collection assertion for Rust scaffold files Replace individual scaffold file key assertions with Assert.Collection so the test verifies the exact Rust scaffold file set. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent adc48ab commit 3d0cd55

3 files changed

Lines changed: 90 additions & 5 deletions

File tree

src/Aspire.Hosting.CodeGeneration.Rust/RustLanguageSupport.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ internal sealed class RustLanguageSupport : ILanguageSupport
1515
/// The language/runtime identifier for Rust.
1616
/// </summary>
1717
private const string LanguageId = "rust";
18+
private const string AppHostFileName = "apphost.rs";
1819

1920
/// <summary>
2021
/// The code generation target language. This maps to the ICodeGenerator.Language property.
2122
/// </summary>
2223
private const string CodeGenTarget = "Rust";
2324

2425
private const string LanguageDisplayName = "Rust";
25-
private static readonly string[] s_detectionPatterns = ["apphost.rs"];
26+
private static readonly string[] s_detectionPatterns = [AppHostFileName];
2627

2728
/// <inheritdoc />
2829
public string Language => LanguageId;
@@ -68,8 +69,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
6869
lazy_static = "1.4"
6970
""";
7071

71-
// Create apphost.rs marker file for detection
72-
files["apphost.rs"] = """
72+
// Create the marker file the CLI uses to recognize Rust AppHosts.
73+
files[AppHostFileName] = """
7374
// Aspire Rust AppHost marker file
7475
// This file is used to detect the project type.
7576
// The actual entry point is in src/main.rs.
@@ -105,7 +106,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
105106
/// <inheritdoc />
106107
public DetectionResult Detect(string directoryPath)
107108
{
108-
var appHostPath = Path.Combine(directoryPath, "apphost.rs");
109+
var appHostPath = Path.Combine(directoryPath, AppHostFileName);
109110
if (!File.Exists(appHostPath))
110111
{
111112
return DetectionResult.NotFound;
@@ -117,7 +118,7 @@ public DetectionResult Detect(string directoryPath)
117118
return DetectionResult.NotFound;
118119
}
119120

120-
return DetectionResult.Found(LanguageId, "apphost.rs");
121+
return DetectionResult.Found(LanguageId, AppHostFileName);
121122
}
122123

123124
/// <inheritdoc />

tests/Aspire.Hosting.CodeGeneration.Rust.Tests/Aspire.Hosting.CodeGeneration.Rust.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
<ItemGroup>
1919
<Compile Include="$(TestsSharedDir)TestModuleInitializer.cs" Link="shared/TestModuleInitializer.cs" />
20+
<Compile Include="$(TestsSharedDir)TempDirectory.cs" Link="shared/TempDirectory.cs" />
2021
<!-- Share test types with TypeScript tests -->
2122
<Compile Include="..\Aspire.Hosting.CodeGeneration.TypeScript.Tests\TestTypes\*.cs" Link="TestTypes\%(Filename)%(Extension)" />
2223
</ItemGroup>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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.TypeSystem;
5+
6+
namespace Aspire.Hosting.CodeGeneration.Rust.Tests;
7+
8+
public class RustLanguageSupportTests
9+
{
10+
private readonly RustLanguageSupport _languageSupport = new();
11+
12+
[Fact]
13+
public void Scaffold_CreatesRustAppHostFilesOnly()
14+
{
15+
using var testDir = new TestTempDirectory();
16+
17+
var files = _languageSupport.Scaffold(new ScaffoldRequest
18+
{
19+
TargetPath = testDir.Path,
20+
ProjectName = "RustApp"
21+
});
22+
23+
Assert.Collection(
24+
files.Keys.Order(StringComparer.Ordinal),
25+
key => Assert.Equal("Cargo.toml", key),
26+
key => Assert.Equal("apphost.rs", key),
27+
key => Assert.Equal("apphost.run.json", key),
28+
key => Assert.Equal("src/main.rs", key));
29+
}
30+
31+
[Fact]
32+
public void Detect_ReturnsRustAppHostWhenMarkerAndCargoExist()
33+
{
34+
using var testDir = new TestTempDirectory();
35+
36+
File.WriteAllText(Path.Combine(testDir.Path, "apphost.rs"), "// marker");
37+
File.WriteAllText(Path.Combine(testDir.Path, "Cargo.toml"), "[package]");
38+
39+
var result = _languageSupport.Detect(testDir.Path);
40+
41+
Assert.True(result.IsValid);
42+
Assert.Equal("rust", result.Language);
43+
Assert.Equal("apphost.rs", result.AppHostFile);
44+
}
45+
46+
[Fact]
47+
public void Detect_DoesNotTreatTypeScriptAppHostAsRust()
48+
{
49+
using var testDir = new TestTempDirectory();
50+
51+
File.WriteAllText(Path.Combine(testDir.Path, "apphost.ts"), "// typescript");
52+
File.WriteAllText(Path.Combine(testDir.Path, "Cargo.toml"), "[package]");
53+
54+
var result = _languageSupport.Detect(testDir.Path);
55+
56+
Assert.False(result.IsValid);
57+
}
58+
59+
[Fact]
60+
public void Detect_RequiresCargoManifest()
61+
{
62+
using var testDir = new TestTempDirectory();
63+
64+
File.WriteAllText(Path.Combine(testDir.Path, "apphost.rs"), "// marker");
65+
66+
var result = _languageSupport.Detect(testDir.Path);
67+
68+
Assert.False(result.IsValid);
69+
}
70+
71+
[Fact]
72+
public void GetRuntimeSpec_UsesCargoRun()
73+
{
74+
var runtimeSpec = _languageSupport.GetRuntimeSpec();
75+
76+
Assert.Equal("rust", runtimeSpec.Language);
77+
Assert.Equal("Rust", runtimeSpec.DisplayName);
78+
Assert.Equal("Rust", runtimeSpec.CodeGenLanguage);
79+
Assert.Equal(["apphost.rs"], runtimeSpec.DetectionPatterns);
80+
Assert.Equal("cargo", runtimeSpec.Execute.Command);
81+
Assert.Equal(["run"], runtimeSpec.Execute.Args);
82+
}
83+
}

0 commit comments

Comments
 (0)