{"id":21129512,"url":"https://github.com/guorg/gu.roslyn.asserts","last_synced_at":"2025-07-09T00:32:17.963Z","repository":{"id":30020514,"uuid":"90557092","full_name":"GuOrg/Gu.Roslyn.Asserts","owner":"GuOrg","description":"Asserts for testing Roslyn analyzers.","archived":false,"fork":false,"pushed_at":"2023-12-25T13:10:29.000Z","size":3196,"stargazers_count":21,"open_issues_count":33,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-05-28T08:57:47.622Z","etag":null,"topics":["codefix","diagnostics","testing-roslyn-analyzers"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GuOrg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-07T19:40:04.000Z","updated_at":"2024-06-19T02:23:35.085Z","dependencies_parsed_at":"2023-12-25T14:32:54.236Z","dependency_job_id":null,"html_url":"https://github.com/GuOrg/Gu.Roslyn.Asserts","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GuOrg%2FGu.Roslyn.Asserts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GuOrg%2FGu.Roslyn.Asserts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GuOrg%2FGu.Roslyn.Asserts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GuOrg%2FGu.Roslyn.Asserts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GuOrg","download_url":"https://codeload.github.com/GuOrg/Gu.Roslyn.Asserts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225473306,"owners_count":17479761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codefix","diagnostics","testing-roslyn-analyzers"],"created_at":"2024-11-20T05:24:26.497Z","updated_at":"2024-11-20T05:24:27.096Z","avatar_url":"https://github.com/GuOrg.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gu.Roslyn.Asserts\n\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![NuGet](https://img.shields.io/nuget/v/Gu.Roslyn.Asserts.svg)](https://www.nuget.org/packages/Gu.Roslyn.Asserts/)\n[![Build status](https://ci.appveyor.com/api/projects/status/a0976a1dmtcx387r/branch/master?svg=true)](https://ci.appveyor.com/project/JohanLarsson/gu-roslyn-asserts/branch/master)\n[![Build Status](https://dev.azure.com/guorg/Gu.Roslyn.Asserts/_apis/build/status/GuOrg.Gu.Roslyn.Asserts?branchName=master)](https://dev.azure.com/guorg/Gu.Roslyn.Asserts/_build/latest?definitionId=8\u0026branchName=master)\n[![Gitter](https://badges.gitter.im/GuOrg/Gu.Roslyn.Asserts.svg)](https://gitter.im/GuOrg/Gu.Roslyn.Asserts?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n\nMicrosoft are working on an official package for testing analyzers: [Microsoft.CodeAnalysis.CSharp.CodeFix.Testing](https://dotnet.myget.org/feed/roslyn-analyzers/package/nuget/Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit).\n\nHopefully this library will not be needed in the future.\n\n\u003c!--\n[![Build status](https://ci.appveyor.com/api/projects/status/a0976a1dmtcx387r/branch/master?svg=true)](https://ci.appveyor.com/project/JohanLarsson/gu-roslyn-asserts/branch/master)\n--\u003e\n\nAsserts for testing Roslyn analyzers.\n\nUse 1.x for Microsoft.CodeAnalysis 1.x\n\n- [RoslynAssert.Valid](#roslynassertvalid)\n- [RoslynAssert.Diagnostics](#roslynassertdiagnostics)\n- [CodeFix](#codefix)\n  - [Code fix only](#code-fix-only)\n- [FixAll](#fixall)\n- [NoFix](#nofix)\n- [Refactoring](#refactoring)\n- [AST](#ast)\n  - [SyntaxFactoryWriter](#syntaxfactorywriter)\n- [Settings](#settings)\n- [Analyze](#analyze)\n  - [GetDiagnosticsAsync](#getdiagnosticsasync)\n- [Fix](#fix)\n- [CodeFactory](#codefactory)\n  - [CreateSolution](#createsolution)\n    - [Create a Microsoft.CodeAnalysis.AdhocWorkspace, a Roslyn Solution from code.](#create-a-microsoftcodeanalysisadhocworkspace--a-roslyn-solution-from-code)\n    - [Create a Microsoft.CodeAnalysis.AdhocWorkspace, a Roslyn Solution from a file on disk.](#create-a-microsoftcodeanalysisadhocworkspace--a-roslyn-solution-from-a-file-on-disk)\n- [Benchmark](#benchmark)\n- [SyntaxNodeExt](#syntaxnodeext)\n- [AstView](#astview)\n- [Usage with different test project types](#usage-with-different-test-project-types)\n  - [Net472 new project type.](#net472-new-project-type)\n  - [NetCoreApp2.0](#netcoreapp20)\n\n\n# RoslynAssert.Valid\n\nUse `RoslynAssert.Valid\u003cNopAnalyzer\u003e(code)` to test that an analyzer does not report errors for valid code.\nThe code is checked so that it does not have any compiler errors either.\nA typical test fixture looks like:\n\n```c#\npublic class Valid\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new YourAnalyzer();\n\n    [Test]\n    public void M()\n    {\n        var code = @\"\nnamespace N\n{\n    class C\n    {\n    }\n}\";\n        RoslynAssert.Valid(Analyzer, code);\n    }\n    ...\n}\n```\n\nIf the analyzer produces many diagnostics you can pass in a descriptor so that only diagnostics matching it are checked.\n\n```c#\npublic class Valid\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new YourAnalyzer();\n    private static readonly DiagnosticDescriptor Descriptor = YourAnalyzer.SomeDescriptor;\n\n    [Test]\n    public void M()\n    {\n        var code = @\"\nnamespace N\n{\n    class C\n    {\n    }\n}\";\n        RoslynAssert.Valid(Analyzer, Descriptor, code);\n    }\n    ...\n}\n```\n\nWhen testing all analyzers something like this can be used:\n\n```c#\npublic class Valid\n{\n    private static readonly IReadOnlyList\u003cDiagnosticAnalyzer\u003e AllAnalyzers =\n        typeof(TypeInAnalyzerAssembly)\n        .Assembly.GetTypes()\n        .Where(typeof(DiagnosticAnalyzer).IsAssignableFrom)\n        .Select(t =\u003e (DiagnosticAnalyzer)Activator.CreateInstance(t))\n        .ToArray();\n\n\n    private static readonly Solution ValidProjectSln = CodeFactory.CreateSolution(\n        ProjectFile.Find(\"Valid.csproj\"),\n        AllAnalyzers);\n\n    [TestCaseSource(nameof(AllAnalyzers))]\n    public void Valid(DiagnosticAnalyzer analyzer)\n    {\n        RoslynAssert.Valid(analyzer, ValidProjectSln);\n    }\n}\n```\n\n# RoslynAssert.Diagnostics\n\nUse `RoslynAssert.Diagnostics\u003cFieldNameMustNotBeginWithUnderscore\u003e(code)` to test that the analyzer reports an error or warning at the position indicated by the character `↓`. To type this character, hold down \u003ckbd\u003eAlt\u003c/kbd\u003e and use the numpad to type the number \u003ckbd\u003e2\u003c/kbd\u003e\u003ckbd\u003e5\u003c/kbd\u003e.\n\nA typical test fixture looks like:\n\n```c#\npublic class Diagnostics\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new YourAnalyzer();\n    private static readonly ExpectedDiagnostic ExpectedDiagnostic = ExpectedDiagnostic.Create(YourAnalyzer.Descriptor);\n\n    [Test]\n    public void M()\n    {\n        var code = @\"\nnamespace N\n{\n    class ↓C\n    {\n    }\n}\";\n        RoslynAssert.Diagnostics(Analyzer, code);\n    }\n\n    [Test]\n    public void M()\n    {\n        var code = @\"\nnamespace N\n{\n    class ↓C\n    {\n    }\n}\";\n        RoslynAssert.Diagnostics(Analyzer, ExpectedDiagnostic.WithMessage(\"Don't name it C\"), code);\n    }\n    ...\n}\n```\n\nIf the analyzer produces many diagnostics you can pass in a descriptor so that only diagnostics matching it are checked.\n\n```c#\npublic class Diagnostics\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new YourAnalyzer();\n    private static readonly ExpectedDiagnostic ExpectedDiagnostic = ExpectedDiagnostic.Create(YourAnalyzer.Descriptor);\n\n    [Test]\n    public void M()\n    {\n        var code = @\"\nnamespace N\n{\n    class ↓Foo\n    {\n    }\n}\";\n        RoslynAssert.Diagnostics(Analyzer, ExpectedDiagnostic, code);\n    }\n    ...\n}\n```\n\nIf the analyzer supports many diagnostics the overload with `ExpectedDiagnostic` must be used. This suppresses all diagnstics other than the expected.\n\n# RoslynAssert.Suppressed\n\nUse `RoslynAssert.Suppressed(suppressor, code)` to test\nthat the suppressor suppresses an error or warning at the position\nindicated by the character `↓`. To type this character, hold down \u003ckbd\u003eAlt\u003c/kbd\u003e\nand use the numpad to type the number \u003ckbd\u003e2\u003c/kbd\u003e\u003ckbd\u003e5\u003c/kbd\u003e.\n\nA typical test fixture looks like:\n\n```c#\npublic class Suppression\n{\n    private static readonly DiagnosticSuppressor Suppressor = new YourSuppressor();\n\n    [Test]\n    public void M()\n    {\n        var code = @\"\nnamespace N\n{\n    class C\n    {\n        public string ↓F;\n    }\n}\";\n        RoslynAssert.NotSuppressed(Suppressor, code);\n    }\n\n    [Test]\n    public void M()\n    {\n        var code = @\"\nnamespace N\n{\n    class C\n    {\n        public string ↓Magic;\n    }\n}\";\n        RoslynAssert.Suppressed(Suppressor, code);\n\n    }\n    ...\n}\n```\n\nIf the suppressor can suppress many diagnostics you can pass in a descriptor so that only diagnostics matching it are checked.\n\n```c#\npublic class Diagnostics\n{\n    private static readonly DiagnosticSuppressor Suppressor = new YourSuppressor();\n    private static readonly ExpectedDiagnostic ExpectedDiagnostic = ExpectedDiagnostic.Create(YourSuppressor.Descriptor);\n\n    [Test]\n    public void M()\n    {\n        var code = @\"\nnamespace N\n{\n    class ↓Foo\n    {\n    }\n}\";\n        RoslynAssert.Suppressed(Analyzer, ExpectedDiagnostic, code);\n    }\n    ...\n}\n```\n\n# CodeFix\nTest that the analyzer reports an error or warning at the position indicated by the character `↓` and that the code fix fixes it and produces the expected code.\nTo type this character, hold down \u003ckbd\u003eAlt\u003c/kbd\u003e and use the numpad to type the number \u003ckbd\u003e2\u003c/kbd\u003e\u003ckbd\u003e5\u003c/kbd\u003e.\n\n```c#\npublic class CodeFix\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new FieldNameMustNotBeginWithUnderscore();\n    private static readonly CodeFixProvider Fix = new SA1309CodeFixProvider();\n\n\t[Test]\n\tpublic void M()\n\t{\n\t\tvar before = @\"\nnamespace N\n{\n\tclass C\n\t{\n\t\tprivate readonly int ↓_value;\n\t}\n}\";\n\n\t\tvar after = @\"\nnamespace N\n{\n\tclass C\n\t{\n\t\tprivate readonly int value;\n\t}\n}\";\n\t\tRoslynAssert.CodeFix(Analyzer, Fix, before, after);\n\t}\n}\n\n```\n\nA typical test fixture looks like:\n\n```c#\npublic class CodeFix\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new YourAnalyzer();\n    private static readonly CodeFixProvider Fix = new YorCodeFixProvider();\n    private static readonly ExpectedDiagnostic ExpectedDiagnostic = ExpectedDiagnostic.Create(YourAnalyzer.Descriptor);\n\n    [Test]\n    public void M1()\n    {\n        var before = @\"\nnamespace N\n{\n    class C\n    {\n        private readonly int ↓_value;\n    }\n}\";\n\n        var after = @\"\nnamespace N\n{\n    class C\n    {\n        private readonly int value;\n    }\n}\";\n        RoslynAssert.CodeFix(Analyzer, Fix, before, after);\n    }\n}\n```\n\nWith explicit title for the fix to apply. Useful when there are many candidate fixes.\n\n```cs\npublic class CodeFix\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new YourAnalyzer();\n    private static readonly CodeFixProvider Fix = new YorCodeFixProvider();\n    private static readonly ExpectedDiagnostic ExpectedDiagnostic = ExpectedDiagnostic.Create(YourAnalyzer.Descriptor);\n\n    [Test]\n    public void M1()\n    {\n        var before = @\"\nnamespace N\n{\n    class C\n    {\n        private readonly int ↓_value;\n    }\n}\";\n\n        var after = @\"\nnamespace N\n{\n    class C\n    {\n        private readonly int value;\n    }\n}\";\n        RoslynAssert.CodeFix(Analyzer, Fix, before, after, fixTitle: \"Don't use underscore prefix\");\n    }\n    ...\n}\n```\n\nIf the analyzer supports many diagnostics the overload with `ExpectedDiagnostic` must be used. This suppresses all diagnostics other than the expected.\n\n## Code fix only\n\nWhen the code fix is for a warning produced by an analyzer that you do not own, for example a built in analyzer in Visual Studio.\n```c#\npublic class CodeFix\n{\n    private static readonly CodeFixProvider Fix = new RemoveUnusedFixProvider();\n    private static readonly ExpectedDiagnostic ExpectedDiagnostic = ExpectedDiagnostic.Create(\"CS0067\");\n\n\t[Test]\n\tpublic void TestThatCodeFixProducesExpectedCode()\n\t{\n\t\tvar before = @\"\nnamespace N\n{\n\tusing System;\n\n\tpublic class C\n\t{\n\t\tpublic event EventHandler ↓Bar;\n\t}\n}\";\n\n\t\tvar after = @\"\nnamespace N\n{\n\tusing System;\n\n\tpublic class C\n\t{\n\t}\n}\";\n\t\tRoslynAssert.CodeFix(Fix, ExpectedDiagnostic, before, after);\n\t}\n}\n```\n\n# FixAll\n\nWhen there are many issues that will be fixed:\nRoslynAssert.FixAll does:\n- Fix all diagnostics one by one\n- Fix all diagnostics in all supported scopes.\n\n```c#\npublic class CodeFix\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new FieldNameMustNotBeginWithUnderscore();\n    private static readonly CodeFixProvider Fix = new SA1309CodeFixProvider();\n\n\t[Test]\n\tpublic void M()\n\t{\n\t\tvar before = @\"\nnamespace N\n{\n\tclass C\n\t{\n\t\tprivate readonly int ↓_value1;\n\t\tprivate readonly int ↓_value2;\n\t}\n}\";\n\n\t\tvar after = @\"\nnamespace N\n{\n\tclass C\n\t{\n\t\tprivate readonly int value1;\n\t\tprivate readonly int value2;\n\t}\n}\";\n\t\tRoslynAssert.FixAll(Analyzer, Fix, before, after);\n\t}\n}\n```\n\n# NoFix\n\nTest that the analyzer reports an error or warning at the position indicated by the character `↓` and that the code fix does not change the code.\nTo type this character, hold down \u003ckbd\u003eAlt\u003c/kbd\u003e and use the numpad to type the number \u003ckbd\u003e2\u003c/kbd\u003e\u003ckbd\u003e5\u003c/kbd\u003e.\nThis can happen if for example it is decided to not support rare edge cases with the code fix.\n\n```c#\npublic class CodeFix\n{\n    private static readonly DiagnosticAnalyzer Analyzer = new FieldNameMustNotBeginWithUnderscore();\n    private static readonly CodeFixProvider Fix = new SA1309CodeFixProvider();\n\n\t[Test]\n\tpublic void M()\n\t{\n\t\tvar code = @\"\nnamespace N\n{\n\tclass C\n\t{\n\t\tprivate readonly int ↓_value;\n\t}\n}\";\n\n\t\tRoslynAssert.NoFix(Analyzer, Fix, code);\n\t}\n}\n```\n\n# Refactoring\n```cs\npublic class CodeFix\n{\n\tprivate static readonly CodeRefactoringProvider Refactoring = new ClassNameToUpperCaseRefactoringProvider();\n\n    [Test]\n    public void M()\n    {\n        var before = @\"\nclass ↓c\n{\n}\";\n\n        var after = @\"\nclass C\n{\n}\";\n        RoslynAssert.Refactoring(Refactoring, before, after);\n\t\t// Or if you want to assert on title also\n\t\tRoslynAssert.Refactoring(Refactoring, before, after, title: \"Change to uppercase.\");\n    }\n}\n```\n\n# AST\n\nFor checking every node and token in the tree.\n\n```cs\n[Test]\npublic void CheckAst()\n{\n    var actual = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SyntaxFactory.IdentifierName(\"a\"), SyntaxFactory.IdentifierName(\"b\"));\n    var expected = CSharpSyntaxTree.ParseText(\"var c = a + b\").FindAssignmentExpression(\"a + b\");\n    RoslynAssert.Ast(expected, actual);\n}\n```\n\n## SyntaxFactoryWriter\n\nGet a string with a call to SyntaxFactory for generating the code passed in.\n\n```cs\nvar code = @\"namespace A.B\n{\n    public class C\n    {\n    }\n}\";\nvar call = SyntaxFactoryWriter.Serialize(code);\n```\n\n# Settings\n\nSettings.Default is meant to be set once and contains information used by asserts and code factory methods.\nIf specific settings are required for a test there are overloads acceping a settings intance.\n\n### Sample ModuleInitializer.cs (for the test project.)\n\n```c#\ninternal static class ModuleInitializer\n{\n    [ModuleInitializer]\n    internal static void Initialize()\n    {\n        Settings.Default = Settings.Default.WithMetadataReferences(\n            // This adds all transitive metadata references from containing project.\n            Asserts.MetadataReferences.Transitive(typeof(ModuleInitializer)));\n    }\n}\n```\n\n# Analyze\n\n## GetDiagnosticsAsync\n\nAnalyze a cs, csproj or sln file on disk.\n\n```c#\n[Test]\npublic async Task GetDiagnosticsFromProjectOnDisk()\n{\n    var dllFile = new Uri(Assembly.GetExecutingAssembly().CodeBase, UriKind.Absolute).LocalPath;\n    Assert.AreEqual(true, CodeFactory.TryFindProjectFile(new FileInfo(dllFile), out FileInfo projectFile));\n    var diagnostics = await Analyze.GetDiagnosticsAsync(new FieldNameMustNotBeginWithUnderscore(), projectFile)\n                                    .ConfigureAwait(false);\n    ...\n}\n```\n\n# Fix\n\nWhen dropping down to manual mode `Analyze` \u0026 `Fix` can be used like this:\n\n```cs\n[Test]\npublic void SingleClassOneErrorCorrectFix()\n{\n    var code = @\"\nnamespace N\n{\n    class Foo\n    {\n        private readonly int _value;\n    }\n}\";\n\n    var after = @\"\nnamespace N\n{\n    class Foo\n    {\n        private readonly int value;\n    }\n}\";\n    var analyzer = new FieldNameMustNotBeginWithUnderscore();\n    var settings = Settings.Default.WithCompilationOptions(CodeFactory.DefaultCompilationOptions(analyzer))\n                                   .WithMetadataReferences(MetadataReference.CreateFromFile(typeof(int).Assembly.Location))\n    var sln = CodeFactory.CreateSolution(code, settings: settings);\n    var diagnostics = Analyze.GetDiagnostics(sln, analyzer);\n    var fixedSln = Fix.Apply(sln, new DoNotUseUnderscoreFix(), diagnostics);\n    CodeAssert.AreEqual(after, fixedSln.Projects.Single().Documents.Single());\n}\n```\n\n# CodeFactory\n\n## CreateSolution\n\n### Create a Microsoft.CodeAnalysis.AdhocWorkspace, a Roslyn Solution from code.\n\n```c#\n[Test]\npublic void CreateSolutionFromSources()\n{\n    var code = @\"\nnamespace N\n{\n    class Foo\n    {\n        private readonly int _value;\n    }\n}\";\n    var sln = CodeFactory.CreateSolution(code, new[] { new FieldNameMustNotBeginWithUnderscore() });\n    Assert.AreEqual(\"N\", sln.Projects.Single().Name);\n    Assert.AreEqual(\"Foo.cs\", sln.Projects.Single().Documents.Single().Name);\n}\n\n[Test]\npublic void CreateSolutionFromSources()\n{\n    var code1 = @\"\nnamespace Project1\n{\n    class Foo1\n    {\n        private readonly int _value;\n    }\n}\";\n\n    var code2 = @\"\nnamespace Project2\n{\n    class Foo2\n    {\n        private readonly int _value;\n    }\n}\";\n    var sln = CodeFactory.CreateSolution(new[] { code1, code2 }, new[] { new FieldNameMustNotBeginWithUnderscore() });\n    CollectionAssert.AreEqual(new[] { \"Project1\", \"Project2\" }, sln.Projects.Select(x =\u003e x.Name));\n    Assert.AreEqual(new[] { \"Foo1.cs\", \"Foo2.cs\" }, sln.Projects.Select(x =\u003e x.Documents.Single().Name));\n}\n```\n\n### Create a Microsoft.CodeAnalysis.AdhocWorkspace, a Roslyn Solution from a file on disk.\n\n```c#\n[Test]\npublic void CreateSolutionFromProjectFile()\n{\n    Assert.AreEqual(\n        true,\n        CodeFactory.TryFindProjectFile(\n            new FileInfo(new Uri(Assembly.GetExecutingAssembly().CodeBase, UriKind.Absolute).LocalPath),\n            out FileInfo projectFile));\n    var solution = CodeFactory.CreateSolution(projectFile);\n}\n\n[Test]\npublic void CreateSolutionFromSolutionFile()\n{\n    Assert.AreEqual(\n        true,\n        CodeFactory.TryFindFileInParentDirectory(\n            new FileInfo(new Uri(Assembly.GetExecutingAssembly().CodeBase, UriKind.Absolute).LocalPath).Directory, \"Gu.Roslyn.Asserts.sln\",\n            out FileInfo solutionFile));\n    var solution = CodeFactory.CreateSolution(solutionFile);\n}\n```\n\n# Benchmark\n\nSample benchmark using BenchmarkDotNet.\n\n```cs\npublic class FieldNameMustNotBeginWithUnderscoreBenchmark\n{\n    private static readonly Solution Solution = CodeFactory.CreateSolution(\n        CodeFactory.FindSolutionFile(\"Gu.Roslyn.Asserts.sln\"));\n\n    private static readonly Benchmark Benchmark = Benchmark.Create(Solution, new FieldNameMustNotBeginWithUnderscore());\n\n    [BenchmarkDotNet.Attributes.Benchmark]\n    public void RunOnGuRoslynAssertsSln()\n    {\n        Benchmark.Run();\n    }\n}\n```\n\n# SyntaxNodeExt\n```cs\n[Test]\npublic void FindAssignmentExpressionDemo()\n{\n    var syntaxTree = CSharpSyntaxTree.ParseText(\n        @\"\nnamespace N\n{\n    internal class Foo\n    {\n        internal Foo()\n        {\n            var temp = 1;\n            temp = 2;\n        }\n    }\n}\");\n    var compilation = CSharpCompilation.Create(\"test\", new[] { syntaxTree });\n    var semanticModel = compilation.GetSemanticModel(syntaxTree);\n    var assignment = syntaxTree.FindAssignmentExpression(\"temp = 2\");\n    Assert.AreEqual(\"temp = 2\", assignment.ToString());\n    Assert.AreEqual(\"int\", semanticModel.GetTypeInfo(assignment.Right).Type.ToDisplayString());\n}\n```\n\n# AstView\n![Animation](https://user-images.githubusercontent.com/1640096/60766676-77ba5f80-a0ad-11e9-95c2-1b789d5490be.gif)\n\n# Usage with different test project types\n## Net472 new project type.\n```xml\n\u003cPropertyGroup\u003e\n  \u003cAutoGenerateBindingRedirects\u003etrue\u003c/AutoGenerateBindingRedirects\u003e\n  \u003cGenerateBindingRedirectsOutputType\u003etrue\u003c/GenerateBindingRedirectsOutputType\u003e\n\u003c/PropertyGroup\u003e\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguorg%2Fgu.roslyn.asserts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguorg%2Fgu.roslyn.asserts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguorg%2Fgu.roslyn.asserts/lists"}