From ef40940821251cf18643c267f9e4a613c4c01434 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:01:36 +0000 Subject: [PATCH 1/5] Initial plan From 4305df7633bed83a5c1bbd8ccac123613c7768f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:20:30 +0000 Subject: [PATCH 2/5] Make WrapperElementsGenerator cacheable with collect-and-execute pattern Co-authored-by: linkdotnet <26365461+linkdotnet@users.noreply.github.com> --- .../WrapperElementsGenerator.cs | 63 ++++++++++++++----- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs b/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs index facb2e810..2d379655e 100644 --- a/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs +++ b/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs @@ -1,7 +1,9 @@ +#nullable enable using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using System.Text; @@ -14,26 +16,37 @@ public class WrapperElementsGenerator : IIncrementalGenerator public void Initialize(IncrementalGeneratorInitializationContext context) { // Finds the AngleSharp assembly referenced by the target project - // This should prevent the source generator from running unless a - // new symbol is returned. - var angleSharpAssemblyReference = context + // and collects element interface type names into cacheable records. + var elementInterfaces = context .CompilationProvider .Select((compilation, cancellationToken) => { var meta = compilation.References.FirstOrDefault(x => x.Display?.EndsWith($"{Path.DirectorySeparatorChar}AngleSharp.dll", StringComparison.Ordinal) ?? false); - return compilation.GetAssemblyOrModuleSymbol(meta); + var assembly = compilation.GetAssemblyOrModuleSymbol(meta); + + if (assembly is not IAssemblySymbol angleSharpAssembly) + return null; + + var elementInterfaceTypes = FindElementInterfaces(angleSharpAssembly); + // Create cacheable records with just the essential info needed for generation + return new ElementInterfacesData( + angleSharpAssembly, + elementInterfaceTypes.Select(t => new ElementTypeInfo( + t.Name, + t.ToDisplayString(GeneratorConfig.SymbolFormat) + )).ToImmutableArray()); }); // Output the hardcoded source files - context.RegisterSourceOutput(angleSharpAssemblyReference, GenerateStaticContent); + context.RegisterSourceOutput(elementInterfaces, GenerateStaticContent); // Output the generated wrapper types - context.RegisterSourceOutput(angleSharpAssemblyReference, GenerateWrapperTypes); + context.RegisterSourceOutput(elementInterfaces, GenerateWrapperTypes); } - private static void GenerateStaticContent(SourceProductionContext context, ISymbol assembly) + private static void GenerateStaticContent(SourceProductionContext context, ElementInterfacesData? data) { - if (assembly is not IAssemblySymbol) + if (data is null) return; context.AddSource("IElementWrapperFactory.g.cs", ReadEmbeddedResource("Bunit.Web.AngleSharp.IElementWrapperFactory.cs")); @@ -41,15 +54,20 @@ private static void GenerateStaticContent(SourceProductionContext context, ISymb context.AddSource("WrapperBase.g.cs", ReadEmbeddedResource("Bunit.Web.AngleSharp.WrapperBase.cs")); } - private static void GenerateWrapperTypes(SourceProductionContext context, ISymbol assembly) + private static void GenerateWrapperTypes(SourceProductionContext context, ElementInterfacesData? data) { - if (assembly is not IAssemblySymbol angleSharpAssembly) + if (data is null) return; - var elementInterfacetypes = FindElementInterfaces(angleSharpAssembly); + // Retrieve the actual symbols from the assembly for code generation + var elementSymbols = data.ElementTypes + .Select(t => data.Assembly.GetTypeByMetadataName(t.FullyQualifiedName.Replace("global::", ""))) + .Where(s => s is not null) + .Cast() + .ToList(); var source = new StringBuilder(); - foreach (var elm in elementInterfacetypes) + foreach (var elm in elementSymbols) { source.Clear(); var name = WrapperElementGenerator.GenerateWrapperTypeSource(source, elm); @@ -57,11 +75,11 @@ private static void GenerateWrapperTypes(SourceProductionContext context, ISymbo } source.Clear(); - GenerateWrapperFactory(source, elementInterfacetypes); + GenerateWrapperFactory(source, data.ElementTypes); context.AddSource($"WrapperExtensions.g.cs", SourceText.From(source.ToString(), Encoding.UTF8)); } - private static void GenerateWrapperFactory(StringBuilder source, IEnumerable elementInterfacetypes) + private static void GenerateWrapperFactory(StringBuilder source, ImmutableArray elementTypes) { source.AppendLine("""namespace Bunit.Web.AngleSharp;"""); source.AppendLine(); @@ -78,10 +96,10 @@ private static void GenerateWrapperFactory(StringBuilder source, IEnumerable(this global::AngleSharp.Dom.IElement element, TElementFactory elementFactory) where TElementFactory : Bunit.Web.AngleSharp.IElementWrapperFactory => element switch"); source.AppendLine("\t{"); - foreach (var elm in elementInterfacetypes) + foreach (var elm in elementTypes) { var wrapperName = $"{elm.Name.Substring(1)}Wrapper"; - source.AppendLine($"\t\t{elm.ToDisplayString(GeneratorConfig.SymbolFormat)} e => new {wrapperName}(e, elementFactory),"); + source.AppendLine($"\t\t{elm.FullyQualifiedName} e => new {wrapperName}(e, elementFactory),"); } source.AppendLine($"\t\t_ => new ElementWrapper(element, elementFactory),"); @@ -104,6 +122,9 @@ private static IReadOnlyList FindElementInterfaces(IAssemblySy var elementInterfaceSymbol = angleSharpAssembly .GetTypeByMetadataName("AngleSharp.Dom.IElement"); + if (elementInterfaceSymbol is null) + return Array.Empty(); + var result = htmlDomNamespace .GetTypeMembers() .Where(typeSymbol => typeSymbol.TypeKind == TypeKind.Interface && typeSymbol.AllInterfaces.Contains(elementInterfaceSymbol)) @@ -139,3 +160,13 @@ private static string ReadEmbeddedResource(string resourceName) return reader.ReadToEnd(); } } + +// Cacheable data structure that stores minimal information about element interfaces +// This allows the incremental generator to cache and reuse results across builds +internal sealed record ElementInterfacesData( + IAssemblySymbol Assembly, + ImmutableArray ElementTypes); + +internal sealed record ElementTypeInfo( + string Name, + string FullyQualifiedName); From 0e8ad246906308c9bc727bb34cf3084267b23517 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:24:55 +0000 Subject: [PATCH 3/5] Fix cacheability by removing IAssemblySymbol from record and using Combine Co-authored-by: linkdotnet <26365461+linkdotnet@users.noreply.github.com> --- .../WrapperElementsGenerator.cs | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs b/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs index 2d379655e..2d99652df 100644 --- a/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs +++ b/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs @@ -29,19 +29,23 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var elementInterfaceTypes = FindElementInterfaces(angleSharpAssembly); // Create cacheable records with just the essential info needed for generation + // Store metadata names instead of symbols for cacheability return new ElementInterfacesData( - angleSharpAssembly, elementInterfaceTypes.Select(t => new ElementTypeInfo( t.Name, - t.ToDisplayString(GeneratorConfig.SymbolFormat) + t.ToDisplayString(GeneratorConfig.SymbolFormat), + GetMetadataName(t) )).ToImmutableArray()); }); + // Combine with compilation to retrieve symbols during execution + var elementInterfacesWithCompilation = elementInterfaces.Combine(context.CompilationProvider); + // Output the hardcoded source files context.RegisterSourceOutput(elementInterfaces, GenerateStaticContent); // Output the generated wrapper types - context.RegisterSourceOutput(elementInterfaces, GenerateWrapperTypes); + context.RegisterSourceOutput(elementInterfacesWithCompilation, GenerateWrapperTypes); } private static void GenerateStaticContent(SourceProductionContext context, ElementInterfacesData? data) @@ -54,14 +58,22 @@ private static void GenerateStaticContent(SourceProductionContext context, Eleme context.AddSource("WrapperBase.g.cs", ReadEmbeddedResource("Bunit.Web.AngleSharp.WrapperBase.cs")); } - private static void GenerateWrapperTypes(SourceProductionContext context, ElementInterfacesData? data) + private static void GenerateWrapperTypes(SourceProductionContext context, (ElementInterfacesData? data, Compilation compilation) input) { + var (data, compilation) = input; if (data is null) return; + // Find the AngleSharp assembly in the compilation + var meta = compilation.References.FirstOrDefault(x => x.Display?.EndsWith($"{Path.DirectorySeparatorChar}AngleSharp.dll", StringComparison.Ordinal) ?? false); + var assembly = compilation.GetAssemblyOrModuleSymbol(meta); + + if (assembly is not IAssemblySymbol angleSharpAssembly) + return; + // Retrieve the actual symbols from the assembly for code generation var elementSymbols = data.ElementTypes - .Select(t => data.Assembly.GetTypeByMetadataName(t.FullyQualifiedName.Replace("global::", ""))) + .Select(t => angleSharpAssembly.GetTypeByMetadataName(t.MetadataName)) .Where(s => s is not null) .Cast() .ToList(); @@ -108,6 +120,17 @@ private static void GenerateWrapperFactory(StringBuilder source, ImmutableArray< source.AppendLine("}"); } + private static string GetMetadataName(INamedTypeSymbol typeSymbol) + { + // Get the full metadata name that can be used with GetTypeByMetadataName + // This is the fully qualified name without the "global::" prefix + var containingNamespace = typeSymbol.ContainingNamespace; + var namespacePrefix = containingNamespace?.IsGlobalNamespace == false + ? containingNamespace.ToDisplayString() + "." + : ""; + return namespacePrefix + typeSymbol.Name; + } + private static IReadOnlyList FindElementInterfaces(IAssemblySymbol angleSharpAssembly) { var htmlDomNamespace = angleSharpAssembly @@ -164,9 +187,9 @@ private static string ReadEmbeddedResource(string resourceName) // Cacheable data structure that stores minimal information about element interfaces // This allows the incremental generator to cache and reuse results across builds internal sealed record ElementInterfacesData( - IAssemblySymbol Assembly, ImmutableArray ElementTypes); internal sealed record ElementTypeInfo( string Name, - string FullyQualifiedName); + string FullyQualifiedName, + string MetadataName); From b5dc6613403388ee86c1c8f56cc555776ae37f47 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:28:49 +0000 Subject: [PATCH 4/5] Add defensive checks for interface name processing Co-authored-by: linkdotnet <26365461+linkdotnet@users.noreply.github.com> --- .../Web.AngleSharp/WrapperElementGenerator.cs | 6 +++++- .../Web.AngleSharp/WrapperElementsGenerator.cs | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/bunit.generators.internal/Web.AngleSharp/WrapperElementGenerator.cs b/src/bunit.generators.internal/Web.AngleSharp/WrapperElementGenerator.cs index 81d0039e7..be5968ea6 100644 --- a/src/bunit.generators.internal/Web.AngleSharp/WrapperElementGenerator.cs +++ b/src/bunit.generators.internal/Web.AngleSharp/WrapperElementGenerator.cs @@ -1,4 +1,5 @@ using Microsoft.CodeAnalysis; +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -10,7 +11,10 @@ internal static class WrapperElementGenerator { internal static string GenerateWrapperTypeSource(StringBuilder source, INamedTypeSymbol elm) { - var name = $"{elm.Name.Substring(1)}Wrapper"; + // Element interface names start with 'I' (e.g., IElement -> ElementWrapper) + var name = elm.Name.Length > 1 && elm.Name.StartsWith("I", StringComparison.Ordinal) + ? $"{elm.Name[1..]}Wrapper" + : $"{elm.Name}Wrapper"; var wrappedTypeName = elm.ToDisplayString(GeneratorConfig.SymbolFormat); source.AppendLine("#nullable enable"); diff --git a/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs b/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs index 2d99652df..be0950b2a 100644 --- a/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs +++ b/src/bunit.generators.internal/Web.AngleSharp/WrapperElementsGenerator.cs @@ -110,7 +110,10 @@ private static void GenerateWrapperFactory(StringBuilder source, ImmutableArray< foreach (var elm in elementTypes) { - var wrapperName = $"{elm.Name.Substring(1)}Wrapper"; + // Element interface names start with 'I' (e.g., IElement -> ElementWrapper) + var wrapperName = elm.Name.Length > 1 && elm.Name.StartsWith("I", StringComparison.Ordinal) + ? $"{elm.Name[1..]}Wrapper" + : $"{elm.Name}Wrapper"; source.AppendLine($"\t\t{elm.FullyQualifiedName} e => new {wrapperName}(e, elementFactory),"); } From 9d75bfe9d5657d1416fe1070abc1e05864d7c5db Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Dec 2025 08:28:53 +0000 Subject: [PATCH 5/5] Make WrapperElementsGenerator cacheable and move generated code to bunit.anglesharp package Co-authored-by: linkdotnet <26365461+linkdotnet@users.noreply.github.com> --- bunit.sln | 93 ++++++++++++++++++- src/bunit.anglesharp/Directory.Build.props | 7 ++ .../AngleSharpWrapperExtensions.cs | 3 +- src/bunit.anglesharp/Placeholder.cs | 7 ++ src/bunit.anglesharp/bunit.anglesharp.csproj | 18 ++++ src/bunit/bunit.csproj | 3 +- 6 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 src/bunit.anglesharp/Directory.Build.props rename src/{bunit/Extensions/Internal => bunit.anglesharp/Extensions}/AngleSharpWrapperExtensions.cs (91%) create mode 100644 src/bunit.anglesharp/Placeholder.cs create mode 100644 src/bunit.anglesharp/bunit.anglesharp.csproj diff --git a/bunit.sln b/bunit.sln index e5b5294d4..f782ca9f9 100644 --- a/bunit.sln +++ b/bunit.sln @@ -62,46 +62,136 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bunit.tests", "tests\bunit. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bunit.generators.tests", "tests\bunit.generators.tests\bunit.generators.tests.csproj", "{D08F7F1D-74B1-4A76-86A2-94918863740C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bunit.anglesharp", "src\bunit.anglesharp\bunit.anglesharp.csproj", "{4591042C-410C-4BA1-A075-653F77891EDA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|x64.ActiveCfg = Debug|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|x64.Build.0 = Debug|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|x86.ActiveCfg = Debug|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|x86.Build.0 = Debug|Any CPU {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|Any CPU.ActiveCfg = Release|Any CPU {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|Any CPU.Build.0 = Release|Any CPU - {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|x64.ActiveCfg = Release|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|x64.Build.0 = Release|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|x86.ActiveCfg = Release|Any CPU + {1DA6EFDE-81A1-4324-A56C-40BEE14A75BA}.Release|x86.Build.0 = Release|Any CPU {6127D121-9387-451B-B15D-8350A32D3001}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6127D121-9387-451B-B15D-8350A32D3001}.Debug|x64.ActiveCfg = Debug|Any CPU + {6127D121-9387-451B-B15D-8350A32D3001}.Debug|x64.Build.0 = Debug|Any CPU + {6127D121-9387-451B-B15D-8350A32D3001}.Debug|x86.ActiveCfg = Debug|Any CPU + {6127D121-9387-451B-B15D-8350A32D3001}.Debug|x86.Build.0 = Debug|Any CPU {6127D121-9387-451B-B15D-8350A32D3001}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6127D121-9387-451B-B15D-8350A32D3001}.Release|x64.ActiveCfg = Release|Any CPU + {6127D121-9387-451B-B15D-8350A32D3001}.Release|x64.Build.0 = Release|Any CPU + {6127D121-9387-451B-B15D-8350A32D3001}.Release|x86.ActiveCfg = Release|Any CPU + {6127D121-9387-451B-B15D-8350A32D3001}.Release|x86.Build.0 = Release|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|x64.ActiveCfg = Debug|Any CPU + {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|x64.Build.0 = Debug|Any CPU + {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|x86.ActiveCfg = Debug|Any CPU + {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Debug|x86.Build.0 = Debug|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Release|Any CPU.ActiveCfg = Release|Any CPU {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Release|Any CPU.Build.0 = Release|Any CPU + {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Release|x64.ActiveCfg = Release|Any CPU + {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Release|x64.Build.0 = Release|Any CPU + {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Release|x86.ActiveCfg = Release|Any CPU + {7972A80F-30DC-4EF4-9294-7D4DD2965882}.Release|x86.Build.0 = Release|Any CPU {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Debug|x64.ActiveCfg = Debug|Any CPU + {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Debug|x64.Build.0 = Debug|Any CPU + {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Debug|x86.ActiveCfg = Debug|Any CPU + {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Debug|x86.Build.0 = Debug|Any CPU {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Release|Any CPU.ActiveCfg = Release|Any CPU {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Release|Any CPU.Build.0 = Release|Any CPU + {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Release|x64.ActiveCfg = Release|Any CPU + {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Release|x64.Build.0 = Release|Any CPU + {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Release|x86.ActiveCfg = Release|Any CPU + {0FF92169-7D8F-46A2-8327-A2F028CB426F}.Release|x86.Build.0 = Release|Any CPU {DE975A0C-0672-4248-913E-D267C1001801}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DE975A0C-0672-4248-913E-D267C1001801}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE975A0C-0672-4248-913E-D267C1001801}.Debug|x64.ActiveCfg = Debug|Any CPU + {DE975A0C-0672-4248-913E-D267C1001801}.Debug|x64.Build.0 = Debug|Any CPU + {DE975A0C-0672-4248-913E-D267C1001801}.Debug|x86.ActiveCfg = Debug|Any CPU + {DE975A0C-0672-4248-913E-D267C1001801}.Debug|x86.Build.0 = Debug|Any CPU {DE975A0C-0672-4248-913E-D267C1001801}.Release|Any CPU.ActiveCfg = Release|Any CPU {DE975A0C-0672-4248-913E-D267C1001801}.Release|Any CPU.Build.0 = Release|Any CPU + {DE975A0C-0672-4248-913E-D267C1001801}.Release|x64.ActiveCfg = Release|Any CPU + {DE975A0C-0672-4248-913E-D267C1001801}.Release|x64.Build.0 = Release|Any CPU + {DE975A0C-0672-4248-913E-D267C1001801}.Release|x86.ActiveCfg = Release|Any CPU + {DE975A0C-0672-4248-913E-D267C1001801}.Release|x86.Build.0 = Release|Any CPU {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Debug|x64.ActiveCfg = Debug|Any CPU + {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Debug|x64.Build.0 = Debug|Any CPU + {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Debug|x86.ActiveCfg = Debug|Any CPU + {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Debug|x86.Build.0 = Debug|Any CPU {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Release|Any CPU.ActiveCfg = Release|Any CPU {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Release|Any CPU.Build.0 = Release|Any CPU + {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Release|x64.ActiveCfg = Release|Any CPU + {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Release|x64.Build.0 = Release|Any CPU + {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Release|x86.ActiveCfg = Release|Any CPU + {AE3DFB52-2BF4-4806-AD82-7FB7B38AC17F}.Release|x86.Build.0 = Release|Any CPU {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Debug|x64.ActiveCfg = Debug|Any CPU + {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Debug|x64.Build.0 = Debug|Any CPU + {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Debug|x86.ActiveCfg = Debug|Any CPU + {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Debug|x86.Build.0 = Debug|Any CPU {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Release|Any CPU.ActiveCfg = Release|Any CPU {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Release|Any CPU.Build.0 = Release|Any CPU + {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Release|x64.ActiveCfg = Release|Any CPU + {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Release|x64.Build.0 = Release|Any CPU + {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Release|x86.ActiveCfg = Release|Any CPU + {A7C6A2AA-FF8F-4ED1-8590-5324FC566059}.Release|x86.Build.0 = Release|Any CPU {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Debug|x64.ActiveCfg = Debug|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Debug|x64.Build.0 = Debug|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Debug|x86.ActiveCfg = Debug|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Debug|x86.Build.0 = Debug|Any CPU {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Release|Any CPU.ActiveCfg = Release|Any CPU {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Release|Any CPU.Build.0 = Release|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Release|x64.ActiveCfg = Release|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Release|x64.Build.0 = Release|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Release|x86.ActiveCfg = Release|Any CPU + {56889DE7-5E66-4E9C-815B-CBCFC9961612}.Release|x86.Build.0 = Release|Any CPU {D08F7F1D-74B1-4A76-86A2-94918863740C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D08F7F1D-74B1-4A76-86A2-94918863740C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D08F7F1D-74B1-4A76-86A2-94918863740C}.Debug|x64.ActiveCfg = Debug|Any CPU + {D08F7F1D-74B1-4A76-86A2-94918863740C}.Debug|x64.Build.0 = Debug|Any CPU + {D08F7F1D-74B1-4A76-86A2-94918863740C}.Debug|x86.ActiveCfg = Debug|Any CPU + {D08F7F1D-74B1-4A76-86A2-94918863740C}.Debug|x86.Build.0 = Debug|Any CPU {D08F7F1D-74B1-4A76-86A2-94918863740C}.Release|Any CPU.ActiveCfg = Release|Any CPU {D08F7F1D-74B1-4A76-86A2-94918863740C}.Release|Any CPU.Build.0 = Release|Any CPU + {D08F7F1D-74B1-4A76-86A2-94918863740C}.Release|x64.ActiveCfg = Release|Any CPU + {D08F7F1D-74B1-4A76-86A2-94918863740C}.Release|x64.Build.0 = Release|Any CPU + {D08F7F1D-74B1-4A76-86A2-94918863740C}.Release|x86.ActiveCfg = Release|Any CPU + {D08F7F1D-74B1-4A76-86A2-94918863740C}.Release|x86.Build.0 = Release|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Debug|x64.ActiveCfg = Debug|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Debug|x64.Build.0 = Debug|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Debug|x86.ActiveCfg = Debug|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Debug|x86.Build.0 = Debug|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Release|Any CPU.Build.0 = Release|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Release|x64.ActiveCfg = Release|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Release|x64.Build.0 = Release|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Release|x86.ActiveCfg = Release|Any CPU + {4591042C-410C-4BA1-A075-653F77891EDA}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -116,6 +206,7 @@ Global {A7C6A2AA-FF8F-4ED1-8590-5324FC566059} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} {56889DE7-5E66-4E9C-815B-CBCFC9961612} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520} {D08F7F1D-74B1-4A76-86A2-94918863740C} = {6EA09ED4-B714-4E6F-B0E1-4D987F8AE520} + {4591042C-410C-4BA1-A075-653F77891EDA} = {9A2B3B34-D41C-43E8-BC7D-246BEBE48D59} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {24106918-1C86-4769-BDA6-9C80E64CD260} diff --git a/src/bunit.anglesharp/Directory.Build.props b/src/bunit.anglesharp/Directory.Build.props new file mode 100644 index 000000000..6c80b1779 --- /dev/null +++ b/src/bunit.anglesharp/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + true + + diff --git a/src/bunit/Extensions/Internal/AngleSharpWrapperExtensions.cs b/src/bunit.anglesharp/Extensions/AngleSharpWrapperExtensions.cs similarity index 91% rename from src/bunit/Extensions/Internal/AngleSharpWrapperExtensions.cs rename to src/bunit.anglesharp/Extensions/AngleSharpWrapperExtensions.cs index ffb6f391d..77a019de5 100644 --- a/src/bunit/Extensions/Internal/AngleSharpWrapperExtensions.cs +++ b/src/bunit.anglesharp/Extensions/AngleSharpWrapperExtensions.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using AngleSharp.Dom; namespace Bunit.Web.AngleSharp; @@ -5,7 +6,7 @@ namespace Bunit.Web.AngleSharp; /// /// Extensions for wrapped inside types. /// -internal static class AngleSharpWrapperExtensions +public static class AngleSharpWrapperExtensions { /// /// Unwraps a wrapped AngleSharp object, if it has been wrapped. diff --git a/src/bunit.anglesharp/Placeholder.cs b/src/bunit.anglesharp/Placeholder.cs new file mode 100644 index 000000000..2b88fcebe --- /dev/null +++ b/src/bunit.anglesharp/Placeholder.cs @@ -0,0 +1,7 @@ +// This file is a placeholder to ensure the project compiles +namespace Bunit.Web.AngleSharp +{ + internal static class Placeholder + { + } +} diff --git a/src/bunit.anglesharp/bunit.anglesharp.csproj b/src/bunit.anglesharp/bunit.anglesharp.csproj new file mode 100644 index 000000000..9ffaebade --- /dev/null +++ b/src/bunit.anglesharp/bunit.anglesharp.csproj @@ -0,0 +1,18 @@ + + + net8.0;net9.0;net10.0 + Bunit.Web.AngleSharp + false + disable + + + + + + + + + + + diff --git a/src/bunit/bunit.csproj b/src/bunit/bunit.csproj index 3a5511a05..0f2da07d1 100644 --- a/src/bunit/bunit.csproj +++ b/src/bunit/bunit.csproj @@ -44,8 +44,7 @@ - +