Skip to content

Commit

Permalink
Add accessibility settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ltrzesniewski committed Dec 22, 2024
1 parent 3ecf952 commit b9c066e
Show file tree
Hide file tree
Showing 18 changed files with 423 additions and 32 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,16 @@ The source generator will process `RazorBlade` MSBuild items which have the `.cs

By default, all `.cshtml` files are included, unless one of the `EnableDefaultRazorBladeItems` or `EnableDefaultItems` properties are set to `false`. You can also manually customize this set.

**Available property settings:**

- `EnableDefaultRazorBladeItems`: Whether to automatically include all `.cshtml` files in the project. Default is `true`.
- `RazorBladeDefaultAccessibility`: The default accessibility of the generated classes (`internal` or `public`). Default is `internal`.
- `RazorBladeEmbeddedLibrary`: Whether to embed the RazorBlade library in the target project (see below). Default is `false`.

**Available item metadata settings:**

- `Accessibility`: The accessibility of the generated class (`internal` or `public`). Default is `$(RazorBladeDefaultAccessibility)`.

### Removing the dependency on RazorBlade

RazorBlade makes it possible to remove the dependency on its runtime assembly. This could be useful for library projects which should be self-contained, with no dependencies on external packages.
Expand Down
138 changes: 117 additions & 21 deletions src/RazorBlade.Analyzers.Tests/RazorBladeSourceGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ public Task should_forward_constructor_from_embedded_library()
"""
@inherits RazorBlade.HtmlTemplate<string>
""",
embeddedLibrary: true
config: new()
{
EmbeddedLibrary = true
}
);
}

Expand All @@ -229,7 +232,10 @@ public Task should_reject_model_directive()
"""
@model FooBar
""",
expectErrors: true
config: new()
{
ExpectErrors = true
}
);
}

Expand All @@ -252,7 +258,10 @@ public Task should_mark_sync_methods_as_obsolete_on_async_templates_netstandard(
@using System.Threading.Tasks
@await Task.FromResult(42)
""",
netstandard: true
config: new()
{
NetStandard = true
}
);
}

Expand Down Expand Up @@ -319,7 +328,10 @@ public Task should_reject_tag_helper_directives()
"""
@addTagHelper *, Foo
""",
expectErrors: true
config: new()
{
ExpectErrors = true
}
);
}

Expand Down Expand Up @@ -361,15 +373,89 @@ @using System
);
}

[Test]
public Task should_set_accessibility()
{
return Verify(
"""
Hello
""",
config: new()
{
ConfigOptions = { [Constants.FileOptions.Accessibility] = "public" }
}
);
}

[Test]
public Task should_report_invalid_accessibility()
{
return Verify(
"""
Hello
""",
config: new()
{
ConfigOptions = { [Constants.FileOptions.Accessibility] = "foo" },
ExpectErrors = true
}
);
}

[Test]
public Task should_set_default_accessibility()
{
return Verify(
"""
Hello
""",
config: new()
{
ConfigOptions = { [Constants.GlobalOptions.DefaultAccessibility] = "public" }
}
);
}

[Test]
public Task should_report_invalid_default_accessibility()
{
return Verify(
"""
Hello
""",
config: new()
{
ConfigOptions = { [Constants.GlobalOptions.DefaultAccessibility] = "foo" },
ExpectErrors = true
}
);
}

[Test]
public Task should_prioritize_accessibility_over_default_accessibility()
{
return Verify(
"""
Hello
""",
config: new()
{
ConfigOptions =
{
[Constants.FileOptions.Accessibility] = "public",
[Constants.GlobalOptions.DefaultAccessibility] = "internal"
}
}
);
}

private static GeneratorDriverRunResult Generate(string input,
string? csharpCode,
bool embeddedLibrary,
bool netstandard,
bool expectErrors)
TestConfig config)
{
var metadataReferences = new List<MetadataReference>();

if (netstandard)
if (config.NetStandard)
{
metadataReferences.Add(
MetadataReference.CreateFromFile(
Expand All @@ -392,19 +478,18 @@ private static GeneratorDriverRunResult Generate(string input,
]);
}

var analyzerConfigOptionsProvider = new AnalyzerConfigOptionsProviderMock
{
{ Constants.FileOptions.IsRazorBlade, "True" },
{ Constants.FileOptions.HintNamespace, "TestNamespace" }
};
var analyzerConfigOptionsProvider = new AnalyzerConfigOptionsProviderMock();

if (embeddedLibrary)
foreach (var (key, value) in config.ConfigOptions)
analyzerConfigOptionsProvider.Add(key, value);

if (config.EmbeddedLibrary)
{
analyzerConfigOptionsProvider.Add(Constants.GlobalOptions.EmbeddedLibrary, "true");
}
else
{
if (netstandard)
if (config.NetStandard)
{
metadataReferences.Add(
MetadataReference.CreateFromFile(
Expand Down Expand Up @@ -435,15 +520,15 @@ private static GeneratorDriverRunResult Generate(string input,

var diagnostics = updatedCompilation.GetDiagnostics();

if (expectErrors)
if (config.ExpectErrors)
{
result.Diagnostics.ShouldContain(i => i.Severity == DiagnosticSeverity.Error);
}
else
{
result.Diagnostics.ShouldBeEmpty();

if (!embeddedLibrary) // Don't validate the embedded library generator here, assume the final output will compile.
if (!config.EmbeddedLibrary) // Don't validate the embedded library generator here, assume the final output will compile.
{
if (!diagnostics.IsEmpty)
Console.WriteLine(result.GeneratedTrees.FirstOrDefault());
Expand All @@ -457,11 +542,22 @@ private static GeneratorDriverRunResult Generate(string input,

private static Task Verify([StringSyntax("razor")] string input,
[StringSyntax("csharp")] string? csharpCode = null,
bool embeddedLibrary = false,
bool netstandard = false,
bool expectErrors = false)
TestConfig? config = null)
{
var result = Generate(input, csharpCode, embeddedLibrary, netstandard, expectErrors);
var result = Generate(input, csharpCode, config ?? new());
return Verifier.Verify(result);
}

private class TestConfig
{
public Dictionary<string, string> ConfigOptions { get; } = new()
{
{ Constants.FileOptions.IsRazorBlade, "True" },
{ Constants.FileOptions.HintNamespace, "TestNamespace" }
};

public bool EmbeddedLibrary { get; init; }
public bool NetStandard { get; init; }
public bool ExpectErrors { get; init; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//HintName: TestNamespace.TestFile.Razor.g.cs
#pragma checksum "./TestFile.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0"
// <auto-generated/>
#pragma warning disable 1591
namespace TestNamespace
{
#line hidden
#nullable restore
public partial class TestFile : global::RazorBlade.HtmlTemplate
#nullable disable
{
#pragma warning disable 1998
protected async override global::System.Threading.Tasks.Task ExecuteAsync()
{
WriteLiteral("Hello");
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//HintName: TestNamespace.TestFile.Razor.g.cs
#pragma checksum "./TestFile.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0"
// <auto-generated/>
#pragma warning disable 1591
namespace TestNamespace
{
#line hidden
#nullable restore
internal partial class TestFile : global::RazorBlade.HtmlTemplate
#nullable disable
{
#pragma warning disable 1998
protected async override global::System.Threading.Tasks.Task ExecuteAsync()
{
WriteLiteral("Hello");
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
Diagnostics: [
{
Message: Invalid accessibility modifier: 'foo'. Valid values are 'internal' and 'public'.,
Severity: Error,
Descriptor: {
Id: RB0007,
Title: Invalid accessibility,
MessageFormat: Invalid accessibility modifier: '{0}'. Valid values are 'internal' and 'public'.,
Category: RazorBlade,
DefaultSeverity: Error,
IsEnabledByDefault: true
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//HintName: TestNamespace.TestFile.Razor.g.cs
#pragma checksum "./TestFile.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0"
// <auto-generated/>
#pragma warning disable 1591
namespace TestNamespace
{
#line hidden
#nullable restore
internal partial class TestFile : global::RazorBlade.HtmlTemplate
#nullable disable
{
#pragma warning disable 1998
protected async override global::System.Threading.Tasks.Task ExecuteAsync()
{
WriteLiteral("Hello");
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
Diagnostics: [
{
Message: Invalid accessibility modifier: 'foo'. Valid values are 'internal' and 'public'.,
Severity: Error,
Descriptor: {
Id: RB0007,
Title: Invalid accessibility,
MessageFormat: Invalid accessibility modifier: '{0}'. Valid values are 'internal' and 'public'.,
Category: RazorBlade,
DefaultSeverity: Error,
IsEnabledByDefault: true
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//HintName: TestNamespace.TestFile.Razor.g.cs
#pragma checksum "./TestFile.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0"
// <auto-generated/>
#pragma warning disable 1591
namespace TestNamespace
{
#line hidden
#nullable restore
public partial class TestFile : global::RazorBlade.HtmlTemplate
#nullable disable
{
#pragma warning disable 1998
protected async override global::System.Threading.Tasks.Task ExecuteAsync()
{
WriteLiteral("Hello");
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//HintName: TestNamespace.TestFile.Razor.g.cs
#pragma checksum "./TestFile.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0"
// <auto-generated/>
#pragma warning disable 1591
namespace TestNamespace
{
#line hidden
#nullable restore
public partial class TestFile : global::RazorBlade.HtmlTemplate
#nullable disable
{
#pragma warning disable 1998
protected async override global::System.Threading.Tasks.Task ExecuteAsync()
{
WriteLiteral("Hello");
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591
2 changes: 2 additions & 0 deletions src/RazorBlade.Analyzers/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public static class GlobalOptions
{
private const string _prefix = "build_property";

public const string DefaultAccessibility = $"{_prefix}.RazorBladeDefaultAccessibility";
public const string EmbeddedLibrary = $"{_prefix}.RazorBladeEmbeddedLibrary";
}

Expand All @@ -15,5 +16,6 @@ public static class FileOptions

public const string IsRazorBlade = $"{_prefix}.IsRazorBlade";
public const string HintNamespace = $"{_prefix}.HintNamespace";
public const string Accessibility = $"{_prefix}.Accessibility";
}
}
Loading

0 comments on commit b9c066e

Please sign in to comment.