diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_CompoundAssignment_ReportsError.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_CompoundAssignment_ReportsError.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_CompoundAssignment_ReportsError.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_CompoundAssignment_ReportsError.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_IfWithoutElse_ImplicitReturn.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_IfWithoutElse_ImplicitReturn.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_IfWithoutElse_ImplicitReturn.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_IfWithoutElse_ImplicitReturn.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_IfWithoutElse_UsesDefault.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_IfWithoutElse_UsesDefault.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_IfWithoutElse_UsesDefault.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_IfWithoutElse_UsesDefault.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_IncrementOperator_ReportsError.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_IncrementOperator_ReportsError.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_IncrementOperator_ReportsError.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_IncrementOperator_ReportsError.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_LocalInIfCondition.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_LocalInIfCondition.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_LocalInIfCondition.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_LocalInIfCondition.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_LocalInSwitchExpression.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_LocalInSwitchExpression.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_LocalInSwitchExpression.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_LocalInSwitchExpression.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_LocalsInNestedBlock_ProducesDiagnostic.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_LocalsInNestedBlock_ProducesDiagnostic.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_LocalsInNestedBlock_ProducesDiagnostic.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_LocalsInNestedBlock_ProducesDiagnostic.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_NonProjectableMethodCall_ReportsWarning.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_NonProjectableMethodCall_ReportsWarning.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_NonProjectableMethodCall_ReportsWarning.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_NonProjectableMethodCall_ReportsWarning.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_PropertyAssignment_ReportsError.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_PropertyAssignment_ReportsError.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_PropertyAssignment_ReportsError.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_PropertyAssignment_ReportsError.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SimpleReturn.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SimpleReturn.verified.txt
similarity index 94%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SimpleReturn.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SimpleReturn.verified.txt
index eeb0754..87a1cad 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SimpleReturn.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SimpleReturn.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using EntityFrameworkCore.Projectables;
@@ -14,4 +14,4 @@ namespace EntityFrameworkCore.Projectables.Generated
return (global::Foo.C @this) => 42;
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SwitchStatement_Simple.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SwitchStatement_Simple.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SwitchStatement_Simple.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SwitchStatement_Simple.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SwitchStatement_WithMultipleCases.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SwitchStatement_WithMultipleCases.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SwitchStatement_WithMultipleCases.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SwitchStatement_WithMultipleCases.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SwitchStatement_WithoutDefault.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SwitchStatement_WithoutDefault.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_SwitchStatement_WithoutDefault.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_SwitchStatement_WithoutDefault.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithAndPattern.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithAndPattern.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithAndPattern.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithAndPattern.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithConstantPattern.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithConstantPattern.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithConstantPattern.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithConstantPattern.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithIfElse.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithIfElse.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithIfElse.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithIfElse.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithIfElseAndCondition.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithIfElseAndCondition.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithIfElseAndCondition.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithIfElseAndCondition.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithLocalVariable.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithLocalVariable.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithLocalVariable.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithLocalVariable.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithMultipleParameters.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithMultipleParameters.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithMultipleParameters.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithMultipleParameters.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithNestedIfElse.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithNestedIfElse.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithNestedIfElse.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithNestedIfElse.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithNotPattern.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithNotPattern.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithNotPattern.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithNotPattern.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithOrPattern.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithOrPattern.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithOrPattern.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithOrPattern.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithPatternMatching.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithPatternMatching.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithPatternMatching.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithPatternMatching.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithPropertyAccess.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithPropertyAccess.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithPropertyAccess.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithPropertyAccess.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithRelationalPattern.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithRelationalPattern.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithRelationalPattern.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithRelationalPattern.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithTransitiveLocalVariables.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithTransitiveLocalVariables.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BlockBodiedMethod_WithTransitiveLocalVariables.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.BlockBodiedMethod_WithTransitiveLocalVariables.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.cs
new file mode 100644
index 0000000..d9caa24
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/BlockBodyTests.cs
@@ -0,0 +1,916 @@
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class BlockBodyTests : ProjectionExpressionGeneratorTestsBase
+{
+ public BlockBodyTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+ [Fact]
+ public void BlockBodiedMethod_NoLongerRaisesDiagnostics()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ return 1;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+ }
+
+ [Fact]
+ public void BlockBodiedMethod_WithoutAllowFlag_EmitsWarning()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class C {
+ public int Value { get; set; }
+
+ [Projectable]
+ public int GetDouble()
+ {
+ return Value * 2;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ var diagnostic = Assert.Single(result.Diagnostics);
+ Assert.Equal("EFP0001", diagnostic.Id);
+ Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity);
+ }
+
+ [Fact]
+ public void BlockBodiedMethod_WithAllowFlag_NoWarning()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class C {
+ public int Value { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int GetDouble()
+ {
+ return Value * 2;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_SimpleReturn()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ return 42;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithPropertyAccess()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ return Bar + 10;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithIfElse()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ if (Bar > 10)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithNestedIfElse()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public string Foo()
+ {
+ if (Bar > 10)
+ {
+ return ""High"";
+ }
+ else if (Bar > 5)
+ {
+ return ""Medium"";
+ }
+ else
+ {
+ return ""Low"";
+ }
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithLocalVariable()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ var temp = Bar * 2;
+ return temp + 5;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithTransitiveLocalVariables()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ var a = Bar * 2;
+ var b = a + 5;
+ return b + 10;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_LocalInIfCondition()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ var threshold = Bar * 2;
+ if (threshold > 10)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_LocalInSwitchExpression()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public string Foo()
+ {
+ var value = Bar * 2;
+ switch (value)
+ {
+ case 2:
+ return ""Two"";
+ case 4:
+ return ""Four"";
+ default:
+ return ""Other"";
+ }
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_LocalsInNestedBlock_ProducesDiagnostic()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ if (Bar > 10)
+ {
+ var temp = Bar * 2;
+ return temp;
+ }
+ return 0;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.NotEmpty(result.Diagnostics);
+ Assert.Contains(result.Diagnostics, d => d.Id == "EFP0003");
+
+ return Verifier.Verify(result.Diagnostics.Select(d => d.ToString()));
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithMultipleParameters()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable(AllowBlockBody = true)]
+ public int Add(int a, int b)
+ {
+ return a + b;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithIfElseAndCondition()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+ public bool IsActive { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ if (IsActive && Bar > 0)
+ {
+ return Bar * 2;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_IfWithoutElse_UsesDefault()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ if (Bar > 10)
+ {
+ return 1;
+ }
+ return 0;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_IfWithoutElse_ImplicitReturn()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int? Foo()
+ {
+ if (Bar > 10)
+ {
+ return 1;
+ }
+
+ return null;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_SwitchStatement_Simple()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public string Foo()
+ {
+ switch (Bar)
+ {
+ case 1:
+ return ""One"";
+ case 2:
+ return ""Two"";
+ default:
+ return ""Other"";
+ }
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_SwitchStatement_WithMultipleCases()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public string Foo()
+ {
+ switch (Bar)
+ {
+ case 1:
+ case 2:
+ return ""Low"";
+ case 3:
+ case 4:
+ case 5:
+ return ""Medium"";
+ default:
+ return ""High"";
+ }
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_SwitchStatement_WithoutDefault()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public string? Foo()
+ {
+ switch (Bar)
+ {
+ case 1:
+ return ""One"";
+ case 2:
+ return ""Two"";
+ }
+
+ return null;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_PropertyAssignment_ReportsError()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ Bar = 10;
+ return Bar;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.NotEmpty(result.Diagnostics);
+ Assert.Contains(result.Diagnostics, d => d.Id == "EFP0004");
+
+ return Verifier.Verify(result.Diagnostics.Select(d => d.ToString()));
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_CompoundAssignment_ReportsError()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ Bar += 10;
+ return Bar;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.NotEmpty(result.Diagnostics);
+ Assert.Contains(result.Diagnostics, d => d.Id == "EFP0004");
+
+ return Verifier.Verify(result.Diagnostics.Select(d => d.ToString()));
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_IncrementOperator_ReportsError()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ var x = 5;
+ x++;
+ return x;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.NotEmpty(result.Diagnostics);
+ Assert.Contains(result.Diagnostics, d => d.Id == "EFP0004");
+
+ return Verifier.Verify(result.Diagnostics.Select(d => d.ToString()));
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_NonProjectableMethodCall_ReportsWarning()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ public int Bar { get; set; }
+
+ [Projectable(AllowBlockBody = true)]
+ public int Foo()
+ {
+ Console.WriteLine(""test"");
+ return Bar;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.NotEmpty(result.Diagnostics);
+ Assert.Contains(result.Diagnostics, d => d.Id == "EFP0005");
+
+ return Verifier.Verify(result.Diagnostics.Select(d => d.ToString()));
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithPatternMatching()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class Entity {
+ public bool IsActive { get; set; }
+ public int Value { get; set; }
+ }
+
+ static class Extensions {
+ [Projectable(AllowBlockBody = true)]
+ public static string GetComplexCategory(this Entity entity)
+ {
+ if (entity is { IsActive: true, Value: > 100 })
+ {
+ return ""Active High"";
+ }
+ return ""Other"";
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithRelationalPattern()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class Entity {
+ public int Value { get; set; }
+ }
+
+ static class Extensions {
+ [Projectable(AllowBlockBody = true)]
+ public static string GetCategory(this Entity entity)
+ {
+ if (entity.Value is > 100)
+ {
+ return ""High"";
+ }
+ return ""Low"";
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithConstantPattern()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class Entity {
+ public string Status { get; set; }
+ }
+
+ static class Extensions {
+ [Projectable(AllowBlockBody = true)]
+ public static bool IsNull(this Entity entity)
+ {
+ if (entity is null)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithNotPattern()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class Entity {
+ public string Name { get; set; }
+ }
+
+ static class Extensions {
+ [Projectable(AllowBlockBody = true)]
+ public static bool IsNotNull(this Entity entity)
+ {
+ if (entity is not null)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithAndPattern()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public int Value { get; set; }
+ }
+
+ static class Extensions {
+ [Projectable(AllowBlockBody = true)]
+ public static bool IsInRange(this Entity entity)
+ {
+ if (entity.Value is >= 1 and <= 100)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BlockBodiedMethod_WithOrPattern()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public string Status { get; set; }
+ }
+
+ static class Extensions {
+ [Projectable(AllowBlockBody = true)]
+ public static bool IsTerminal(this Entity entity)
+ {
+ if (entity.Status is ""Cancelled"" or ""Completed"")
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_BodyAssignments.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_BodyAssignments.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_BodyAssignments.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_BodyAssignments.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_Overloads.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_Overloads.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_Overloads.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_Overloads.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingBasePropertyInDerivedBody.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingBasePropertyInDerivedBody.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingBasePropertyInDerivedBody.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingBasePropertyInDerivedBody.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingPreviouslyAssignedInBaseCtor.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingPreviouslyAssignedInBaseCtor.verified.txt
similarity index 93%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingPreviouslyAssignedInBaseCtor.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingPreviouslyAssignedInBaseCtor.verified.txt
index fc89a79..4570ef5 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingPreviouslyAssignedInBaseCtor.DotNet8_0.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingPreviouslyAssignedInBaseCtor.verified.txt
@@ -18,7 +18,7 @@ namespace EntityFrameworkCore.Projectables.Generated
/// public Base(int x, int y)
/// {
/// X = x;
- /// Y = x + y; // Y depends on X's assigned value (x)
+ /// Y = x + y;
/// }
///
///
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingPreviouslyAssignedProperty.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingPreviouslyAssignedProperty.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingPreviouslyAssignedProperty.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingPreviouslyAssignedProperty.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingStaticConstMember.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingStaticConstMember.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ReferencingStaticConstMember.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ReferencingStaticConstMember.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_ChainedThisAndBase.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_ChainedThisAndBase.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_ChainedThisAndBase.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_ChainedThisAndBase.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_RefPreviouslyAssignedProperty.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_RefPreviouslyAssignedProperty.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_RefPreviouslyAssignedProperty.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_RefPreviouslyAssignedProperty.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_SimpleOverload.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_SimpleOverload.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_SimpleOverload.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_SimpleOverload.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_WithBodyAfter.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_WithBodyAfter.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_WithBodyAfter.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_WithBodyAfter.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_WithIfElseInDelegated.DotNet8_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_WithIfElseInDelegated.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_ThisInitializer_WithIfElseInDelegated.DotNet8_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_ThisInitializer_WithIfElseInDelegated.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializer.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializer.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializer.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializer.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializerAndIfElse.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializerAndIfElse.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializerAndIfElse.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializerAndIfElse.verified.txt
index dad38a9..4ab74e1 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializerAndIfElse.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializerAndIfElse.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Foo;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializerExpression.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializerExpression.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializerExpression.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializerExpression.verified.txt
index d207be7..8856d78 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializerExpression.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializerExpression.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Foo;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializer_AndIfElse_InDerivedBody.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializer_AndIfElse_InDerivedBody.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithBaseInitializer_AndIfElse_InDerivedBody.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithBaseInitializer_AndIfElse_InDerivedBody.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithClassArgument.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithClassArgument.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithClassArgument.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithClassArgument.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithDeepNestedIf.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithDeepNestedIf.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithDeepNestedIf.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithDeepNestedIf.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithElseIfChain.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithElseIfChain.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithElseIfChain.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithElseIfChain.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithExplicitParameterlessConstructor_Succeeds.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithExplicitParameterlessConstructor_Succeeds.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithExplicitParameterlessConstructor_Succeeds.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithExplicitParameterlessConstructor_Succeeds.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithIfElseLogic.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithIfElseLogic.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithIfElseLogic.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithIfElseLogic.verified.txt
index 02c183c..5eeaf75 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithIfElseLogic.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithIfElseLogic.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Foo;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithIfInsideLocalScope_AndElse.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithIfInsideLocalScope_AndElse.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithIfInsideLocalScope_AndElse.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithIfInsideLocalScope_AndElse.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithIfNoElse.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithIfNoElse.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithIfNoElse.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithIfNoElse.verified.txt
index 24a3e55..3a469f0 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithIfNoElse.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithIfNoElse.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Foo;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithLocalVariable.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithLocalVariable.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithLocalVariable.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithLocalVariable.verified.txt
index bf93d90..d233058 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithLocalVariable.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithLocalVariable.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Foo;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithLocalVariableUsedInCondition.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithLocalVariableUsedInCondition.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithLocalVariableUsedInCondition.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithLocalVariableUsedInCondition.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithMultipleClassArguments.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithMultipleClassArguments.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithMultipleClassArguments.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithMultipleClassArguments.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithMultipleLocalVariables.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithMultipleLocalVariables.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithMultipleLocalVariables.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithMultipleLocalVariables.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithNestedIfElse.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithNestedIfElse.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithNestedIfElse.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithNestedIfElse.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithNullCoalescing.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithNullCoalescing.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithNullCoalescing.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithNullCoalescing.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithNullableParameter.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithNullableParameter.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithNullableParameter.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithNullableParameter.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithSequentialIfs.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithSequentialIfs.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithSequentialIfs.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithSequentialIfs.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithSwitchExpression.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithSwitchExpression.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithSwitchExpression.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithSwitchExpression.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithSwitchExpression_AndExtraProperty.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithSwitchExpression_AndExtraProperty.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithSwitchExpression_AndExtraProperty.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithSwitchExpression_AndExtraProperty.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithTernaryAssignment.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithTernaryAssignment.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithTernaryAssignment.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithTernaryAssignment.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithThisInitializer_AndElseIfInBody.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithThisInitializer_AndElseIfInBody.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableConstructor_WithThisInitializer_AndElseIfInBody.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.ProjectableConstructor_WithThisInitializer_AndElseIfInBody.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.cs
new file mode 100644
index 0000000..3f9648e
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ConstructorTests.cs
@@ -0,0 +1,1295 @@
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class ConstructorTests : ProjectionExpressionGeneratorTestsBase
+{
+ public ConstructorTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+ [Fact]
+ public Task ProjectableConstructor_BodyAssignments()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PointDto {
+ public int X { get; set; }
+ public int Y { get; set; }
+
+ public PointDto() { }
+
+ [Projectable]
+ public PointDto(int x, int y) {
+ X = x;
+ Y = y;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithBaseInitializer()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Base {
+ public int Id { get; set; }
+ public Base(int id) { Id = id; }
+
+ protected Base() { }
+ }
+
+ class Child : Base {
+ public string Name { get; set; }
+
+ public Child() { }
+
+ [Projectable]
+ public Child(int id, string name) : base(id) {
+ Name = name;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_Overloads()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(string firstName, string lastName) {
+ FirstName = firstName;
+ LastName = lastName;
+ }
+
+ [Projectable]
+ public PersonDto(string fullName) {
+ FirstName = fullName;
+ LastName = string.Empty;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Equal(2, result.GeneratedTrees.Length);
+
+ return Verifier.Verify(result.GeneratedTrees.OrderBy(t => t.FilePath).Select(t => t.ToString()));
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithClassArgument()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class SourceEntity {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ class PersonDto {
+ public int Id { get; set; }
+ public string Name { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(SourceEntity source) {
+ Id = source.Id;
+ Name = source.Name;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithMultipleClassArguments()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class NamePart {
+ public string Value { get; set; }
+ }
+
+ class PersonDto {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(NamePart first, NamePart last) {
+ FirstName = first.Value;
+ LastName = last.Value;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithIfElseLogic()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string Label { get; set; }
+ public int Score { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(int score) {
+ Score = score;
+ if (score >= 90) {
+ Label = ""A"";
+ } else {
+ Label = ""B"";
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithLocalVariable()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string FullName { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(string first, string last) {
+ var full = first + "" "" + last;
+ FullName = full;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithBaseInitializerExpression()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Base {
+ public string Code { get; set; }
+ public Base(string code) { Code = code; }
+
+ protected Base() { }
+ }
+
+ class Child : Base {
+ public string Name { get; set; }
+
+ public Child() { }
+
+ [Projectable]
+ public Child(string name, string rawCode) : base(rawCode.ToUpper()) {
+ Name = name;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithBaseInitializerAndIfElse()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Base {
+ public int Id { get; set; }
+ public Base(int id) {
+ if (id < 0) {
+ Id = 0;
+ } else {
+ Id = id;
+ }
+ }
+
+ protected Base() { }
+ }
+
+ class Child : Base {
+ public string Name { get; set; }
+
+ public Child() { }
+
+ [Projectable]
+ public Child(int id, string name) : base(id) {
+ Name = name;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithIfNoElse()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string Label { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(int score) {
+ Label = ""none"";
+ if (score >= 90) {
+ Label = ""A"";
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ReferencingPreviouslyAssignedProperty()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public string FullName { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(string firstName, string lastName) {
+ FirstName = firstName;
+ LastName = lastName;
+ FullName = FirstName + "" "" + LastName;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ReferencingBasePropertyInDerivedBody()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Base {
+ public string Code { get; set; }
+ public Base(string code) { Code = code; }
+
+ protected Base() { }
+ }
+
+ class Child : Base {
+ public string Label { get; set; }
+
+ public Child() { }
+
+ [Projectable]
+ public Child(string code) : base(code) {
+ Label = ""["" + Code + ""]"";
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ReferencingStaticConstMember()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ internal const string Separator = "" - "";
+ public string FullName { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(string first, string last) {
+ FullName = first + Separator + last;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ReferencingPreviouslyAssignedInBaseCtor()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Base {
+ public int X { get; set; }
+ public int Y { get; set; }
+ public Base(int x, int y) {
+ X = x;
+ Y = x + y;
+ }
+
+ protected Base() { }
+ }
+
+ class Child : Base {
+ public int Sum { get; set; }
+
+ public Child() { }
+
+ [Projectable]
+ public Child(int a, int b) : base(a, b) {
+ Sum = X + Y;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ThisInitializer_SimpleOverload()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+
+ public PersonDto() { }
+
+ public PersonDto(string firstName, string lastName) {
+ FirstName = firstName;
+ LastName = lastName;
+ }
+
+ [Projectable]
+ public PersonDto(string fullName) : this(fullName.Split(' ')[0], fullName.Split(' ')[1]) {
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ThisInitializer_WithBodyAfter()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public string FullName { get; set; }
+
+ public PersonDto() { }
+
+ public PersonDto(string firstName, string lastName) {
+ FirstName = firstName;
+ LastName = lastName;
+ }
+
+ [Projectable]
+ public PersonDto(string fn, string ln, bool upper) : this(fn, ln) {
+ FullName = upper ? (FirstName + "" "" + LastName).ToUpper() : FirstName + "" "" + LastName;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ThisInitializer_WithIfElseInDelegated()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string Label { get; set; }
+ public int Score { get; set; }
+
+ public PersonDto() { }
+
+ public PersonDto(int score) {
+ Score = score;
+ if (score >= 90) {
+ Label = ""A"";
+ } else {
+ Label = ""B"";
+ }
+ }
+
+ [Projectable]
+ public PersonDto(int score, string prefix) : this(score) {
+ Label = prefix + Label;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ThisInitializer_ChainedThisAndBase()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Base {
+ public int Id { get; set; }
+ public Base(int id) { Id = id; }
+ }
+
+ class Child : Base {
+ public string Name { get; set; }
+
+ public Child() : base(0) { }
+
+ public Child(int id, string name) : base(id) {
+ Name = name;
+ }
+
+ [Projectable]
+ public Child(int id, string name, string suffix) : this(id, name) {
+ Name = Name + suffix;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_ThisInitializer_RefPreviouslyAssignedProperty()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public string FullName { get; set; }
+
+ public PersonDto() { }
+
+ public PersonDto(string firstName, string lastName) {
+ FirstName = firstName;
+ LastName = lastName;
+ FullName = FirstName + "" "" + LastName;
+ }
+
+ [Projectable]
+ public PersonDto(string firstName) : this(firstName, ""Doe"") {
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public void ProjectableConstructor_WithoutParameterlessConstructor_EmitsDiagnostic()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string Name { get; set; }
+
+ [Projectable]
+ public PersonDto(string name) {
+ Name = name;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ var diagnostic = Assert.Single(result.Diagnostics);
+ Assert.Equal("EFP0008", diagnostic.Id);
+ Assert.Equal(DiagnosticSeverity.Error, diagnostic.Severity);
+ Assert.Empty(result.GeneratedTrees);
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithExplicitParameterlessConstructor_Succeeds()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PersonDto {
+ public string Name { get; set; }
+
+ public PersonDto() { }
+
+ [Projectable]
+ public PersonDto(string name) {
+ Name = name;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithElseIfChain()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class GradeDto {
+ public string Grade { get; set; }
+
+ public GradeDto() { }
+
+ [Projectable]
+ public GradeDto(int score) {
+ if (score >= 90) {
+ Grade = ""A"";
+ } else if (score >= 75) {
+ Grade = ""B"";
+ } else if (score >= 60) {
+ Grade = ""C"";
+ } else {
+ Grade = ""F"";
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithNestedIfElse()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class StatusDto {
+ public string Status { get; set; }
+
+ public StatusDto() { }
+
+ [Projectable]
+ public StatusDto(bool isActive, bool isPremium) {
+ if (isActive) {
+ if (isPremium) {
+ Status = ""Active Premium"";
+ } else {
+ Status = ""Active Free"";
+ }
+ } else {
+ Status = ""Inactive"";
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public void ProjectableConstructor_WithEarlyReturn_GuardClause_EmitsDiagnostic()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class ItemDto {
+ public string Name { get; set; }
+ public string Category { get; set; }
+
+ public ItemDto() { }
+
+ [Projectable]
+ public ItemDto(string name, string category) {
+ Name = name;
+ if (string.IsNullOrEmpty(category)) {
+ Category = ""Unknown"";
+ return;
+ }
+ Category = category;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ var diagnostic = Assert.Single(result.Diagnostics);
+ Assert.Equal("EFP0003", diagnostic.Id);
+ Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity);
+ }
+
+ [Fact]
+ public void ProjectableConstructor_WithMultipleEarlyReturns_EmitsDiagnostic()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class PriorityDto {
+ public string Level { get; set; }
+
+ public PriorityDto() { }
+
+ [Projectable]
+ public PriorityDto(int value) {
+ if (value < 0) {
+ Level = ""Invalid"";
+ return;
+ }
+ if (value == 0) {
+ Level = ""None"";
+ return;
+ }
+ if (value <= 5) {
+ Level = ""Low"";
+ return;
+ }
+ Level = ""High"";
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.NotEmpty(result.Diagnostics);
+ Assert.All(result.Diagnostics, d => Assert.Equal("EFP0003", d.Id));
+ Assert.All(result.Diagnostics, d => Assert.Equal(DiagnosticSeverity.Warning, d.Severity));
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithSequentialIfs()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class FlagDto {
+ public string Tag { get; set; }
+ public bool IsVerified { get; set; }
+ public bool IsAdmin { get; set; }
+
+ public FlagDto() { }
+
+ [Projectable]
+ public FlagDto(string role, bool verified) {
+ Tag = role;
+ if (verified) {
+ IsVerified = true;
+ }
+ if (role == ""admin"") {
+ IsAdmin = true;
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithTernaryAssignment()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class LabelDto {
+ public string Label { get; set; }
+ public string Display { get; set; }
+
+ public LabelDto() { }
+
+ [Projectable]
+ public LabelDto(string name, bool uppercase) {
+ Label = name;
+ Display = uppercase ? name.ToUpper() : name.ToLower();
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithNullCoalescing()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class ProductDto {
+ public string Name { get; set; }
+ public string Description { get; set; }
+
+ public ProductDto() { }
+
+ [Projectable]
+ public ProductDto(string name, string description) {
+ Name = name ?? ""Unnamed"";
+ Description = description ?? string.Empty;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithSwitchExpression()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class SeasonDto {
+ public string Name { get; set; }
+ public string Description { get; set; }
+
+ public SeasonDto() { }
+
+ [Projectable]
+ public SeasonDto(int month) {
+ Name = month switch {
+ 12 or 1 or 2 => ""Winter"",
+ 3 or 4 or 5 => ""Spring"",
+ 6 or 7 or 8 => ""Summer"",
+ _ => ""Autumn""
+ };
+ Description = ""Month: "" + month;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithMultipleLocalVariables()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class AddressDto {
+ public string Street { get; set; }
+ public string City { get; set; }
+ public string Full { get; set; }
+
+ public AddressDto() { }
+
+ [Projectable]
+ public AddressDto(string street, string city, string country) {
+ var trimmedStreet = street.Trim();
+ var trimmedCity = city.Trim();
+ Street = trimmedStreet;
+ City = trimmedCity;
+ Full = trimmedStreet + "", "" + trimmedCity + "", "" + country;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithNullableParameter()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class MeasurementDto {
+ public double Value { get; set; }
+ public string Unit { get; set; }
+
+ public MeasurementDto() { }
+
+ [Projectable]
+ public MeasurementDto(double? value, string unit) {
+ Value = value ?? 0.0;
+ Unit = unit ?? ""m"";
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithLocalVariableUsedInCondition()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class RangeDto {
+ public int Min { get; set; }
+ public int Max { get; set; }
+ public bool IsValid { get; set; }
+
+ public RangeDto() { }
+
+ [Projectable]
+ public RangeDto(int a, int b) {
+ var lo = a < b ? a : b;
+ var hi = a < b ? b : a;
+ Min = lo;
+ Max = hi;
+ if (hi - lo > 0) {
+ IsValid = true;
+ } else {
+ IsValid = false;
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithBaseInitializer_AndIfElse_InDerivedBody()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Animal {
+ public string Species { get; set; }
+ public Animal(string species) { Species = species; }
+ protected Animal() { }
+ }
+
+ class Pet : Animal {
+ public string Name { get; set; }
+ public string Nickname { get; set; }
+
+ public Pet() { }
+
+ [Projectable]
+ public Pet(string species, string name, bool useShortName) : base(species) {
+ Name = name;
+ if (useShortName) {
+ Nickname = name.Length > 3 ? name.Substring(0, 3) : name;
+ } else {
+ Nickname = name;
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public void ProjectableConstructor_WithBaseInitializer_AndEarlyReturn_EmitsDiagnostic()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Vehicle {
+ public string Type { get; set; }
+ public Vehicle(string type) { Type = type; }
+ protected Vehicle() { }
+ }
+
+ class Car : Vehicle {
+ public string Model { get; set; }
+ public int Year { get; set; }
+
+ public Car() { }
+
+ [Projectable]
+ public Car(string model, int year) : base(""Car"") {
+ Model = model;
+ if (year <= 0) {
+ Year = 2000;
+ return;
+ }
+ Year = year;
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ var diagnostic = Assert.Single(result.Diagnostics);
+ Assert.Equal("EFP0003", diagnostic.Id);
+ Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity);
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithDeepNestedIf()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class AccessDto {
+ public string Access { get; set; }
+
+ public AccessDto() { }
+
+ [Projectable]
+ public AccessDto(bool isLoggedIn, bool isVerified, bool isAdmin) {
+ if (isLoggedIn) {
+ if (isVerified) {
+ if (isAdmin) {
+ Access = ""Full"";
+ } else {
+ Access = ""Verified"";
+ }
+ } else {
+ Access = ""Unverified"";
+ }
+ } else {
+ Access = ""Guest"";
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithIfInsideLocalScope_AndElse()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class OrderDto {
+ public string Status { get; set; }
+ public string Note { get; set; }
+ public bool NeedsReview { get; set; }
+
+ public OrderDto() { }
+
+ [Projectable]
+ public OrderDto(int amount, bool flagged) {
+ if (flagged) {
+ Status = ""Flagged"";
+ Note = ""Requires manual review"";
+ NeedsReview = true;
+ } else {
+ Status = amount > 1000 ? ""Large"" : ""Normal"";
+ Note = string.Empty;
+ NeedsReview = false;
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithThisInitializer_AndElseIfInBody()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class EventDto {
+ public string Title { get; set; }
+ public string Tag { get; set; }
+ public string Priority { get; set; }
+
+ public EventDto() { }
+
+ public EventDto(string title, string tag) {
+ Title = title;
+ Tag = tag;
+ }
+
+ [Projectable]
+ public EventDto(string title, string tag, int urgency) : this(title, tag) {
+ if (urgency >= 10) {
+ Priority = ""Critical"";
+ } else if (urgency >= 5) {
+ Priority = ""High"";
+ } else {
+ Priority = ""Normal"";
+ }
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableConstructor_WithSwitchExpression_AndExtraProperty()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class ShapeDto {
+ public string ShapeType { get; set; }
+ public int Sides { get; set; }
+ public string Description { get; set; }
+
+ public ShapeDto() { }
+
+ [Projectable]
+ public ShapeDto(int sides) {
+ Sides = sides;
+ ShapeType = sides switch {
+ 3 => ""Triangle"",
+ 4 => ""Rectangle"",
+ 5 => ""Pentagon"",
+ _ => ""Polygon""
+ };
+ Description = ShapeType + "" with "" + sides + "" sides"";
+ }
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsOnNavigationProperty.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsOnNavigationProperty.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsOnNavigationProperty.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsOnNavigationProperty.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsReturningBoolean.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsReturningBoolean.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsReturningBoolean.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsReturningBoolean.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsReturningInteger.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsReturningInteger.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsReturningInteger.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsReturningInteger.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithDescriptionAttribute.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithDescriptionAttribute.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithDescriptionAttribute.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithDescriptionAttribute.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithDisplayAttribute.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithDisplayAttribute.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithDisplayAttribute.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithDisplayAttribute.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithMultipleParameters.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithMultipleParameters.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithMultipleParameters.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithMultipleParameters.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithNullableEnum.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithNullableEnum.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithNullableEnum.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithNullableEnum.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithParameter.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithParameter.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExpandEnumMethodsWithParameter.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.ExpandEnumMethodsWithParameter.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.cs
new file mode 100644
index 0000000..6046f45
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/EnumTests.cs
@@ -0,0 +1,369 @@
+using System.Threading.Tasks;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class EnumTests : ProjectionExpressionGeneratorTestsBase
+{
+ public EnumTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+ [Fact]
+ public Task ExpandEnumMethodsWithDisplayAttribute()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.ComponentModel.DataAnnotations;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public enum CustomEnum
+ {
+ [Display(Name = ""Value 1"")]
+ Value1,
+
+ [Display(Name = ""Value 2"")]
+ Value2,
+ }
+
+ public static class EnumExtensions
+ {
+ public static string GetDisplayName(this CustomEnum value)
+ {
+ return value.ToString();
+ }
+ }
+
+ public record Entity
+ {
+ public int Id { get; set; }
+ public CustomEnum MyValue { get; set; }
+
+ [Projectable(ExpandEnumMethods = true)]
+ public string MyEnumName => MyValue.GetDisplayName();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExpandEnumMethodsWithNullableEnum()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.ComponentModel.DataAnnotations;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public enum CustomEnum
+ {
+ [Display(Name = ""First Value"")]
+ First,
+
+ [Display(Name = ""Second Value"")]
+ Second,
+ }
+
+ public static class EnumExtensions
+ {
+ public static string GetDisplayName(this CustomEnum value)
+ {
+ return value.ToString();
+ }
+ }
+
+ public record Entity
+ {
+ public int Id { get; set; }
+ public CustomEnum? MyValue { get; set; }
+
+ [Projectable(ExpandEnumMethods = true)]
+ public string MyEnumName => MyValue.HasValue ? MyValue.Value.GetDisplayName() : null;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExpandEnumMethodsWithDescriptionAttribute()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.ComponentModel;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public enum Status
+ {
+ [Description(""The item is pending"")]
+ Pending,
+
+ [Description(""The item is approved"")]
+ Approved,
+
+ [Description(""The item is rejected"")]
+ Rejected,
+ }
+
+ public static class EnumExtensions
+ {
+ public static string GetDescription(this Status value)
+ {
+ return value.ToString();
+ }
+ }
+
+ public record Entity
+ {
+ public int Id { get; set; }
+ public Status Status { get; set; }
+
+ [Projectable(ExpandEnumMethods = true)]
+ public string StatusDescription => Status.GetDescription();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExpandEnumMethodsOnNavigationProperty()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.ComponentModel.DataAnnotations;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public enum OrderStatus
+ {
+ [Display(Name = ""Pending Review"")]
+ Pending,
+
+ [Display(Name = ""Approved"")]
+ Approved,
+ }
+
+ public static class EnumExtensions
+ {
+ public static string GetDisplayName(this OrderStatus value)
+ {
+ return value.ToString();
+ }
+ }
+
+ public record Order
+ {
+ public int Id { get; set; }
+ public OrderStatus Status { get; set; }
+ }
+
+ public record OrderItem
+ {
+ public int Id { get; set; }
+ public Order Order { get; set; }
+
+ [Projectable(ExpandEnumMethods = true)]
+ public string OrderStatusName => Order.Status.GetDisplayName();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExpandEnumMethodsReturningBoolean()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public enum Status
+ {
+ Pending,
+ Approved,
+ Rejected,
+ }
+
+ public static class EnumExtensions
+ {
+ public static bool IsApproved(this Status value)
+ {
+ return value == Status.Approved;
+ }
+ }
+
+ public record Entity
+ {
+ public int Id { get; set; }
+ public Status Status { get; set; }
+
+ [Projectable(ExpandEnumMethods = true)]
+ public bool IsStatusApproved => Status.IsApproved();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExpandEnumMethodsReturningInteger()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public enum Priority
+ {
+ Low,
+ Medium,
+ High,
+ }
+
+ public static class EnumExtensions
+ {
+ public static int GetSortOrder(this Priority value)
+ {
+ return (int)value;
+ }
+ }
+
+ public record Entity
+ {
+ public int Id { get; set; }
+ public Priority Priority { get; set; }
+
+ [Projectable(ExpandEnumMethods = true)]
+ public int PrioritySortOrder => Priority.GetSortOrder();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExpandEnumMethodsWithParameter()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public enum Status
+ {
+ Pending,
+ Approved,
+ Rejected,
+ }
+
+ public static class EnumExtensions
+ {
+ public static string GetDisplayNameWithPrefix(this Status value, string prefix)
+ {
+ return prefix + value.ToString();
+ }
+ }
+
+ public record Entity
+ {
+ public int Id { get; set; }
+ public Status Status { get; set; }
+
+ [Projectable(ExpandEnumMethods = true)]
+ public string StatusWithPrefix => Status.GetDisplayNameWithPrefix(""Status: "");
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExpandEnumMethodsWithMultipleParameters()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public enum Status
+ {
+ Pending,
+ Approved,
+ Rejected,
+ }
+
+ public static class EnumExtensions
+ {
+ public static string Format(this Status value, string prefix, string suffix)
+ {
+ return prefix + value.ToString() + suffix;
+ }
+ }
+
+ public record Entity
+ {
+ public int Id { get; set; }
+ public Status Status { get; set; }
+
+ [Projectable(ExpandEnumMethods = true)]
+ public string FormattedStatus => Status.Format(""["", ""]"");
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberMethod.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberMethod.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberMethod.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberMethod.verified.txt
index e0d8932..fe2e82e 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberMethod.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberMethod.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using EntityFrameworkCore.Projectables;
@@ -14,4 +14,4 @@ namespace EntityFrameworkCore.Projectables.Generated
return (global::Foo.Entity @this) => @this.Id * 3;
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberMethodWithParameters.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberMethodWithParameters.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberMethodWithParameters.DotNet10_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberMethodWithParameters.verified.txt
index 837945b..0b278df 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberMethodWithParameters.DotNet10_0.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberMethodWithParameters.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using EntityFrameworkCore.Projectables;
@@ -14,4 +14,4 @@ namespace EntityFrameworkCore.Projectables.Generated
return (global::Foo.Entity @this, int factor) => @this.Id * factor;
}
}
-}
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberOnInterface.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberOnInterface.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberOnInterface.DotNet10_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberOnInterface.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberOnPrimitive.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberOnPrimitive.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberOnPrimitive.DotNet10_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberOnPrimitive.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberProperty.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberProperty.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberProperty.DotNet10_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberProperty.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberWithBlockBody.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberWithBlockBody.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberWithBlockBody.DotNet10_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberWithBlockBody.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberWithIsPatternExpression.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberWithIsPatternExpression.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberWithIsPatternExpression.DotNet10_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberWithIsPatternExpression.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberWithMemberAccess.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberWithMemberAccess.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberWithMemberAccess.DotNet10_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberWithMemberAccess.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberWithSwitchExpression.DotNet10_0.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberWithSwitchExpression.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExtensionMemberWithSwitchExpression.DotNet10_0.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.ExtensionMemberWithSwitchExpression.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.cs
new file mode 100644
index 0000000..e8552be
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMemberTests.cs
@@ -0,0 +1,285 @@
+using System.Threading.Tasks;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class ExtensionMemberTests : ProjectionExpressionGeneratorTestsBase
+{
+ public ExtensionMemberTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+#if NET10_0_OR_GREATER
+ [Fact]
+ public Task ExtensionMemberProperty()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public int Id { get; set; }
+ }
+
+ static class EntityExtensions {
+ extension(Entity e) {
+ [Projectable]
+ public int DoubleId => e.Id * 2;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExtensionMemberMethod()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public int Id { get; set; }
+ }
+
+ static class EntityExtensions {
+ extension(Entity e) {
+ [Projectable]
+ public int TripleId() => e.Id * 3;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExtensionMemberMethodWithParameters()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public int Id { get; set; }
+ }
+
+ static class EntityExtensions {
+ extension(Entity e) {
+ [Projectable]
+ public int Multiply(int factor) => e.Id * factor;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExtensionMemberOnPrimitive()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+static class IntExtensions {
+ extension(int i) {
+ [Projectable]
+ public int Squared => i * i;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExtensionMemberWithMemberAccess()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ static class EntityExtensions {
+ extension(Entity e) {
+ [Projectable]
+ public string IdAndName => e.Id + "": "" + e.Name;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExtensionMemberWithBlockBody()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public int Value { get; set; }
+ public bool IsActive { get; set; }
+ }
+
+ static class EntityExtensions {
+ extension(Entity e) {
+ [Projectable(AllowBlockBody = true)]
+ public string GetStatus()
+ {
+ if (e.IsActive && e.Value > 0)
+ {
+ return ""Active"";
+ }
+ return ""Inactive"";
+ }
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExtensionMemberWithSwitchExpression()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public int Score { get; set; }
+ }
+
+ static class EntityExtensions {
+ extension(Entity e) {
+ [Projectable]
+ public string GetGrade() => e.Score switch
+ {
+ >= 90 => ""A"",
+ >= 80 => ""B"",
+ >= 70 => ""C"",
+ _ => ""F"",
+ };
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExtensionMemberOnInterface()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ interface IEntity {
+ int Id { get; }
+ string Name { get; }
+ }
+
+ static class IEntityExtensions {
+ extension(IEntity e) {
+ [Projectable]
+ public string Label => e.Id + "": "" + e.Name;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExtensionMemberWithIsPatternExpression()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ class Entity {
+ public int Value { get; set; }
+ }
+
+ static class EntityExtensions {
+ extension(Entity e) {
+ [Projectable]
+ public bool IsHighValue => e.Value is > 100;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+#endif
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod.verified.txt
index 8e8012f..f473738 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod2.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod2.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod2.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod2.verified.txt
index b17f73b..c6d1a9d 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod2.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod2.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod3.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod3.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod3.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod3.verified.txt
index bf3ca9c..25e7d8a 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod3.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod3.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod4.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod4.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod4.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod4.verified.txt
index 03de978..3ea7b53 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod4.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.ProjectableExtensionMethod4.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.cs
new file mode 100644
index 0000000..54e36af
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ExtensionMethodTests.cs
@@ -0,0 +1,109 @@
+using System.Threading.Tasks;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class ExtensionMethodTests : ProjectionExpressionGeneratorTestsBase
+{
+ public ExtensionMethodTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+ [Fact]
+ public Task ProjectableExtensionMethod()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class D { }
+
+ static class C {
+ [Projectable]
+ public static int Foo(this D d) => 1;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableExtensionMethod2()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ static class C {
+ [Projectable]
+ public static int Foo(this int i) => i;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableExtensionMethod3()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ static class C {
+ [Projectable]
+ public static int Foo1(this int i) => i;
+
+ [Projectable]
+ public static int Foo2(this int i) => i.Foo1();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Equal(2, result.GeneratedTrees.Length);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableExtensionMethod4()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ static class C {
+ [Projectable]
+ public static object Foo1(this object i) => i.Foo1();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericClassesWithContraints_AreRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericClassesWithContraints_AreRewritten.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericClassesWithContraints_AreRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericClassesWithContraints_AreRewritten.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericClassesWithTypeContraints_AreRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericClassesWithTypeContraints_AreRewritten.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericClassesWithTypeContraints_AreRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericClassesWithTypeContraints_AreRewritten.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericMethods_AreRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericMethods_AreRewritten.verified.txt
similarity index 96%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericMethods_AreRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericMethods_AreRewritten.verified.txt
index 973cde3..aa77e0e 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericMethods_AreRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericMethods_AreRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericTypes.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericTypes.verified.txt
similarity index 94%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericTypes.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericTypes.verified.txt
index 4c06e39..e496376 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericTypes.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericTypes.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericTypesWithConstraints.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericTypesWithConstraints.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericTypesWithConstraints.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericTypesWithConstraints.verified.txt
index 8fd234b..bf57240 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericTypesWithConstraints.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.GenericTypesWithConstraints.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.cs
new file mode 100644
index 0000000..3bc651b
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/GenericTests.cs
@@ -0,0 +1,151 @@
+using System.Threading.Tasks;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class GenericTests : ProjectionExpressionGeneratorTestsBase
+{
+ public GenericTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+ [Fact]
+ public Task GenericMethods_AreRewritten()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public static class EntityExtensions
+ {
+ public record Entity
+ {
+ public int Id { get; set; }
+ public string? FullName { get; set; }
+ }
+
+ [Projectable]
+ public static string EnforceString(T value) where T : unmanaged
+ => value.ToString();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task GenericClassesWithContraints_AreRewritten()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public class TypedObject where TEnum : struct, System.Enum
+ {
+ public TEnum SomeProp { get; set; }
+ }
+
+ public abstract class Entitywhere T : TypedObject where TEnum : struct, System.Enum
+ {
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public T SomeSubobject { get; set; }
+
+ [Projectable]
+ public string FullName => $""{FirstName} {LastName} {SomeSubobject.SomeProp}"";
+ }
+}
+");
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task GenericClassesWithTypeContraints_AreRewritten()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public abstract class Entity where T : notnull
+ {
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public T SomeSubobject { get; set; }
+
+ [Projectable]
+ public string FullName => $""{FirstName} {LastName} {SomeSubobject}"";
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task GenericTypes()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+class EntiyBase {
+ [Projectable]
+ public static TId GetId() => default;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task GenericTypesWithConstraints()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+class EntityBase where TId : ICloneable, new() {
+ [Projectable]
+ public static TId GetId() => default;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DefaultExplicitInterfaceMember.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.DefaultExplicitInterfaceMember.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DefaultExplicitInterfaceMember.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.DefaultExplicitInterfaceMember.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DefaultInterfaceMember.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.DefaultInterfaceMember.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DefaultInterfaceMember.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.DefaultInterfaceMember.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExplicitInterfaceImplementation.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.ExplicitInterfaceImplementation.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExplicitInterfaceImplementation.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.ExplicitInterfaceImplementation.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExplicitInterfaceMember.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.ExplicitInterfaceMember.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ExplicitInterfaceMember.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.ExplicitInterfaceMember.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.cs
new file mode 100644
index 0000000..5e46b48
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/InterfaceTests.cs
@@ -0,0 +1,141 @@
+using System.Threading.Tasks;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class InterfaceTests : ProjectionExpressionGeneratorTestsBase
+{
+ public InterfaceTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+ [Fact]
+ public Task ExplicitInterfaceMember()
+ {
+ var compilation = CreateCompilation(
+ """
+ using System;
+ using EntityFrameworkCore.Projectables;
+
+ public interface IBase
+ {
+ int ComputedProperty { get; }
+ }
+
+ public class Concrete : IBase
+ {
+ public int Id { get; }
+
+ [Projectable]
+ int IBase.ComputedProperty => Id + 1;
+ }
+ """);
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task DefaultInterfaceMember()
+ {
+ var compilation = CreateCompilation(
+ """
+ using System;
+ using EntityFrameworkCore.Projectables;
+
+ public interface IBase
+ {
+ int Id { get; }
+ int ComputedProperty { get; }
+ int ComputedMethod();
+ }
+
+ public interface IDefaultBase : IBase
+ {
+ [Projectable]
+ int Default => ComputedProperty * 2;
+ }
+ """);
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task DefaultExplicitInterfaceMember()
+ {
+ var compilation = CreateCompilation(
+ """
+ using System;
+ using EntityFrameworkCore.Projectables;
+
+ public interface IBase
+ {
+ int Id { get; }
+ int ComputedProperty { get; }
+ int ComputedMethod();
+ }
+
+ public interface IDefaultBase
+ {
+ int Default { get; }
+ }
+
+ public interface IDefaultBaseImplementation : IDefaultBase, IBase
+ {
+ [Projectable]
+ int IDefaultBase.Default => ComputedProperty * 2;
+ }
+ """);
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ExplicitInterfaceImplementation()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public interface IStringId
+ {
+ string Id { get; }
+ }
+
+ public class Item : IStringId
+ {
+ public int Id { get; set; }
+
+ // Explicit interface implementation without [Projectable]
+ string IStringId.Id => Id.ToString();
+
+ [Projectable]
+ public string FormattedId => ((IStringId)this).Id;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ArgumentlessProjectableComputedMethod.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ArgumentlessProjectableComputedMethod.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ArgumentlessProjectableComputedMethod.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ArgumentlessProjectableComputedMethod.verified.txt
index fa2d4ec..2d48bd4 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ArgumentlessProjectableComputedMethod.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ArgumentlessProjectableComputedMethod.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMemberExplicitReference.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMemberExplicitReference.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMemberExplicitReference.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMemberExplicitReference.verified.txt
index 682df68..6544cf9 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMemberExplicitReference.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMemberExplicitReference.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Projectables.Repro;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMemberImplicitReference.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMemberImplicitReference.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMemberImplicitReference.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMemberImplicitReference.verified.txt
index 682df68..6544cf9 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMemberImplicitReference.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMemberImplicitReference.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Projectables.Repro;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMethorImplicitReference.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMethodExplicitReference.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMethorImplicitReference.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMethodExplicitReference.verified.txt
index fe999c7..56ee353 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMethorImplicitReference.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMethodExplicitReference.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Projectables.Repro;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMethodExplicitReference.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMethorImplicitReference.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMethodExplicitReference.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMethorImplicitReference.verified.txt
index fe999c7..56ee353 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BaseMethodExplicitReference.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.BaseMethorImplicitReference.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Projectables.Repro;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.Cast.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.Cast.verified.txt
similarity index 96%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.Cast.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.Cast.verified.txt
index cf931bf..525720b 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.Cast.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.Cast.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using Projectables.Repro;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember3.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember3.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember.verified.txt
index d467476..191ae28 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember3.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMembers2.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember2.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMembers2.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember2.verified.txt
index 5c768e9..e2d943d 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMembers2.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember2.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMembers.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember3.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMembers.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember3.verified.txt
index d467476..191ae28 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMembers.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ConstMember3.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DeclarationTypeNamesAreGettingFullyQualified.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.DeclarationTypeNamesAreGettingFullyQualified.verified.txt
similarity index 96%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DeclarationTypeNamesAreGettingFullyQualified.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.DeclarationTypeNamesAreGettingFullyQualified.verified.txt
index cec10d1..153a1f1 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DeclarationTypeNamesAreGettingFullyQualified.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.DeclarationTypeNamesAreGettingFullyQualified.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DefaultValuesGetRemoved.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.DefaultValuesGetRemoved.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DefaultValuesGetRemoved.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.DefaultValuesGetRemoved.verified.txt
index b0c3e64..57bce24 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.DefaultValuesGetRemoved.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.DefaultValuesGetRemoved.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.EnumAccessor.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.EnumAccessor.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.EnumAccessor.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.EnumAccessor.verified.txt
index d108871..1dc6812 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.EnumAccessor.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.EnumAccessor.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.InheritedMembers.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.InheritedMembers.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.InheritedMembers.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.InheritedMembers.verified.txt
index f2157d2..dbe94a4 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.InheritedMembers.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.InheritedMembers.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.IsOperator.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.IsOperator.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.IsOperator.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.IsOperator.verified.txt
index 55a8bc3..382a881 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.IsOperator.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.IsOperator.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.MethodOverloads_WithDifferentParameterCounts.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.MethodOverloads_WithDifferentParameterCounts.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.MethodOverloads_WithDifferentParameterCounts.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.MethodOverloads_WithDifferentParameterCounts.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.MethodOverloads_WithDifferentParameterTypes.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.MethodOverloads_WithDifferentParameterTypes.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.MethodOverloads_WithDifferentParameterTypes.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.MethodOverloads_WithDifferentParameterTypes.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.MixPrimaryConstructorAndProperties.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.MixPrimaryConstructorAndProperties.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.MixPrimaryConstructorAndProperties.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.MixPrimaryConstructorAndProperties.verified.txt
index 84bf825..eb39b4b 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.MixPrimaryConstructorAndProperties.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.MixPrimaryConstructorAndProperties.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ParamsModifiedGetsRemoved.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ParamsModifiedGetsRemoved.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ParamsModifiedGetsRemoved.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ParamsModifiedGetsRemoved.verified.txt
index 4231778..c9bfda4 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ParamsModifiedGetsRemoved.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ParamsModifiedGetsRemoved.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithMultipleArguments.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ProjectableComputedMethodWithMultipleArguments.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithMultipleArguments.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ProjectableComputedMethodWithMultipleArguments.verified.txt
index 6a50a32..cc9ef2b 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithMultipleArguments.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ProjectableComputedMethodWithMultipleArguments.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithSingleArgument.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ProjectableComputedMethodWithSingleArgument.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithSingleArgument.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ProjectableComputedMethodWithSingleArgument.verified.txt
index 864fb95..c6344cb 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithSingleArgument.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.ProjectableComputedMethodWithSingleArgument.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.RequiredNamespace.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.RequiredNamespace.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.RequiredNamespace.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.RequiredNamespace.verified.txt
index 08e611e..a2fab55 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.RequiredNamespace.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.RequiredNamespace.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
using One.Two;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyWithExplicitBlockGetter.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.SimpleProjectableMethod.verified.txt
similarity index 100%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyWithExplicitBlockGetter.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.SimpleProjectableMethod.verified.txt
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMembers.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMembers.verified.txt
index d467476..191ae28 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMembers.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember2.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMembers2.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember2.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMembers2.verified.txt
index 5c768e9..e2d943d 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ConstMember2.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMembers2.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMethodWithNoParameters.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMethodWithNoParameters.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMethodWithNoParameters.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMethodWithNoParameters.verified.txt
index e170859..4e25fd2 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMethodWithNoParameters.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMethodWithNoParameters.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMethodWithParameters.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMethodWithParameters.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMethodWithParameters.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMethodWithParameters.verified.txt
index f5a9570..e1745ef 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StaticMethodWithParameters.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StaticMethodWithParameters.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StringInterpolationWithParenthesis_NoParenthesisAdded.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StringInterpolationWithParenthesis_NoParenthesisAdded.verified.txt
similarity index 96%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StringInterpolationWithParenthesis_NoParenthesisAdded.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StringInterpolationWithParenthesis_NoParenthesisAdded.verified.txt
index 6e33afa..caf66f8 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StringInterpolationWithParenthesis_NoParenthesisAdded.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StringInterpolationWithParenthesis_NoParenthesisAdded.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StringInterpolationWithStaticCall_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StringInterpolationWithStaticCall_IsBeingRewritten.verified.txt
similarity index 96%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StringInterpolationWithStaticCall_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StringInterpolationWithStaticCall_IsBeingRewritten.verified.txt
index 6e33afa..caf66f8 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.StringInterpolationWithStaticCall_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.StringInterpolationWithStaticCall_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.TypesInBodyGetsFullyQualified.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.TypesInBodyGetsFullyQualified.verified.txt
similarity index 96%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.TypesInBodyGetsFullyQualified.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.TypesInBodyGetsFullyQualified.verified.txt
index 06f2ded..6b3e666 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.TypesInBodyGetsFullyQualified.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.TypesInBodyGetsFullyQualified.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.cs
new file mode 100644
index 0000000..ef3da1a
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/MethodTests.cs
@@ -0,0 +1,804 @@
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class MethodTests : ProjectionExpressionGeneratorTestsBase
+{
+ public MethodTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+ [Fact]
+ public Task SimpleProjectableMethod()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable]
+ public int Foo() => 1;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ArgumentlessProjectableComputedMethod()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable]
+ public int Foo() => 0;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableComputedMethodWithSingleArgument()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable]
+ public int Foo(int i) => i;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ProjectableComputedMethodWithMultipleArguments()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable]
+ public int Foo(int a, string b, object d) => a;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task StaticMethodWithNoParameters()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+public static class Foo {
+ [Projectable]
+ public static int Zero() => 0;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task StaticMethodWithParameters()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+public static class Foo {
+ [Projectable]
+ public static int Zero(int x) => 0;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task StaticMembers()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public class Foo {
+ public static int Bar { get; set; }
+
+ public int Id { get; set; }
+
+ [Projectable]
+ public int IdWithBar() => Id + Bar;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task StaticMembers2()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public static class Constants {
+ public static readonly int Bar = 1;
+ }
+
+ public class Foo {
+ public int Id { get; set; }
+
+ [Projectable]
+ public int IdWithBar() => Id + Constants.Bar;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ConstMember()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public class Foo {
+ public const int Bar = 1;
+
+ public int Id { get; set; }
+
+ [Projectable]
+ public int IdWithBar() => Id + Bar;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ConstMember2()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public static class Constants {
+ public const int Bar = 1;
+ }
+
+ public class Foo {
+ public int Id { get; set; }
+
+ [Projectable]
+ public int IdWithBar() => Id + Constants.Bar;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ConstMember3()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public class Foo {
+ public const int Bar = 1;
+
+ public int Id { get; set; }
+
+ [Projectable]
+ public int IdWithBar() => Id + Foo.Bar;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task DefaultValuesGetRemoved()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+class Foo {
+ [Projectable]
+ public int Calculate(int i = 0) => i;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task ParamsModifiedGetsRemoved()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+class Foo {
+ [Projectable]
+ public int First(params int[] all) => all[0];
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task MethodOverloads_WithDifferentParameterTypes()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable]
+ public int Method(int x) => x;
+
+ [Projectable]
+ public int Method(string s) => s.Length;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Equal(2, result.GeneratedTrees.Length);
+
+ var generatedFiles = result.GeneratedTrees.Select(t => t.FilePath).ToList();
+ Assert.Contains(generatedFiles, f => f.Contains("Method_P0_int.g.cs"));
+ Assert.Contains(generatedFiles, f => f.Contains("Method_P0_string.g.cs"));
+
+ return Verifier.Verify(result.GeneratedTrees.Select(t => t.ToString()));
+ }
+
+ [Fact]
+ public Task MethodOverloads_WithDifferentParameterCounts()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class C {
+ [Projectable]
+ public int Method(int x) => x;
+
+ [Projectable]
+ public int Method(int x, int y) => x + y;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Equal(2, result.GeneratedTrees.Length);
+
+ var generatedFiles = result.GeneratedTrees.Select(t => t.FilePath).ToList();
+ Assert.Contains(generatedFiles, f => f.Contains("Method_P0_int.g.cs"));
+ Assert.Contains(generatedFiles, f => f.Contains("Method_P0_int_P1_int.g.cs"));
+
+ return Verifier.Verify(result.GeneratedTrees.Select(t => t.ToString()));
+ }
+
+ [Fact]
+ public Task InheritedMembers()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public class Foo {
+ public int Id { get; set; }
+ }
+
+ public class Bar : Foo {
+ [Projectable]
+ public int ProjectedId => Id;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BaseMemberExplicitReference()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Projectables.Repro;
+
+class Base
+{
+ public string Foo { get; set; }
+}
+
+class Derived : Base
+{
+ [Projectable]
+ public string Bar => base.Foo;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BaseMemberImplicitReference()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Projectables.Repro;
+
+class Base
+{
+ public string Foo { get; set; }
+}
+
+class Derived : Base
+{
+ [Projectable]
+ public string Bar => Foo;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BaseMethodExplicitReference()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Projectables.Repro;
+
+class Base
+{
+ public string Foo() => """";
+}
+
+class Derived : Base
+{
+ [Projectable]
+ public string Bar => base.Foo();
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task BaseMethorImplicitReference()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Projectables.Repro;
+
+class Base
+{
+ public string Foo() => """";
+}
+
+class Derived : Base
+{
+ [Projectable]
+ public string Bar => Foo();
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task IsOperator()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class A {
+ [Projectable]
+ public bool IsB => this is B;
+ }
+
+ class B : A {
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task Cast()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace Projectables.Repro;
+
+public class SuperEntity : SomeEntity
+{
+ public string Superpower { get; set; }
+}
+
+public class SomeEntity
+{
+ public int Id { get; set; }
+}
+
+public static class SomeExtensions
+{
+ [Projectable]
+ public static string AsSomeResult(this SomeEntity e) => ((SuperEntity)e).Superpower;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task EnumAccessor()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+public enum SomeFlag
+{
+ Foo
+}
+
+public static class SomeExtensions
+{
+ [Projectable]
+ public static bool Test(this SomeFlag f) => f == SomeFlag.Foo;
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task StringInterpolationWithStaticCall_IsBeingRewritten()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ static class MyExtensions {
+ public static string ToDateString(this DateTime date) => date.ToString(""dd/MM/yyyy"");
+ }
+
+ class C {
+ public DateTime? ValidationDate { get; set; }
+
+ [Projectable]
+ public string Status => ValidationDate != null ? $""Validation date : ({ValidationDate.Value.ToDateString()})"" : """";
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task StringInterpolationWithParenthesis_NoParenthesisAdded()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ static class MyExtensions {
+ public static string ToDateString(this DateTime date) => date.ToString(""dd/MM/yyyy"");
+ }
+
+ class C {
+ public DateTime? ValidationDate { get; set; }
+
+ [Projectable]
+ public string Status => ValidationDate != null ? $""Validation date : ({(ValidationDate.Value.ToDateString())})"" : """";
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task TypesInBodyGetsFullyQualified()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+namespace Foo {
+ class D { }
+
+ class C {
+ public System.Collections.Generic.List Dees { get; set; }
+
+ [Projectable]
+ public int Foo => Dees.OfType().Count();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task DeclarationTypeNamesAreGettingFullyQualified()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public static class EntityExtensions
+ {
+ public record Entity
+ {
+ public int Id { get; set; }
+ public string? FullName { get; set; }
+
+ [Projectable]
+ public static Entity Something(Entity entity)
+ => entity;
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task MixPrimaryConstructorAndProperties()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using EntityFrameworkCore.Projectables;
+
+namespace Foo {
+ public static class EntityExtensions
+ {
+ public record Entity(int Id)
+ {
+ public int Id { get; set; }
+ public string? FullName { get; set; }
+
+ [Projectable]
+ public static Entity Something(Entity entity)
+ => new Entity(entity.Id) {
+ FullName = entity.FullName
+ };
+ }
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task RequiredNamespace()
+ {
+ var compilation = CreateCompilation(@"
+using EntityFrameworkCore.Projectables;
+
+namespace One {
+ static class IntExtensions {
+ public static int AddOne(this int i) => i + 1;
+ }
+}
+
+namespace One.Two {
+ class Bar {
+ [Projectable]
+ public int Method() => 1.AddOne();
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+}
\ No newline at end of file
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BooleanSimpleTernary_WithRewriteSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.BooleanSimpleTernary_WithRewriteSupport_IsBeingRewritten.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BooleanSimpleTernary_WithRewriteSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.BooleanSimpleTernary_WithRewriteSupport_IsBeingRewritten.verified.txt
index 8fb3344..e64abfa 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.BooleanSimpleTernary_WithRewriteSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.BooleanSimpleTernary_WithRewriteSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericNullableReferenceTypesAreBeingEliminated.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.GenericNullableReferenceTypesAreBeingEliminated.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericNullableReferenceTypesAreBeingEliminated.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.GenericNullableReferenceTypesAreBeingEliminated.verified.txt
index 0993caa..490c579 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.GenericNullableReferenceTypesAreBeingEliminated.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.GenericNullableReferenceTypesAreBeingEliminated.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Collections.Generic;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullConditionalNullCoalesceTypeConversion.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullConditionalNullCoalesceTypeConversion.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullConditionalNullCoalesceTypeConversion.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullConditionalNullCoalesceTypeConversion.verified.txt
index f366397..fe04612 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullConditionalNullCoalesceTypeConversion.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullConditionalNullCoalesceTypeConversion.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using EntityFrameworkCore.Projectables;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementAndMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementAndMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
similarity index 96%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementAndMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementAndMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
index 0153a0f..c51a3f1 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementAndMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementAndMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementAndMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementAndMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementAndMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementAndMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
index 010f995..1f2af4d 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementAndMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementAndMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
index aff9e8b..ceb60d4 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
index c881b5d..55ac25a 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
index 97ef48d..4fa8aa7 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableMemberBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
index 4b30f5d..a93f089 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableMemberBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableParameters_WithRewriteSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableParameters_WithRewriteSupport_IsBeingRewritten.verified.txt
similarity index 97%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableParameters_WithRewriteSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableParameters_WithRewriteSupport_IsBeingRewritten.verified.txt
index fc9af02..734be49 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableParameters_WithRewriteSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableParameters_WithRewriteSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableReferenceTypeCastOperatorGetsEliminated.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableReferenceTypeCastOperatorGetsEliminated.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableReferenceTypeCastOperatorGetsEliminated.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableReferenceTypeCastOperatorGetsEliminated.verified.txt
index 48f6a5f..88fa434 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableReferenceTypeCastOperatorGetsEliminated.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableReferenceTypeCastOperatorGetsEliminated.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Collections.Generic;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableReferenceTypesAreBeingEliminated.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableReferenceTypesAreBeingEliminated.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableReferenceTypesAreBeingEliminated.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableReferenceTypesAreBeingEliminated.verified.txt
index f880d94..24ac2e2 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableReferenceTypesAreBeingEliminated.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableReferenceTypesAreBeingEliminated.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableSimpleElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableSimpleElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableSimpleElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableSimpleElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
index fe0230a..f44e605 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableSimpleElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableSimpleElementBinding_WithIgnoreSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableSimpleElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableSimpleElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableSimpleElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableSimpleElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
index d34d367..a9ec933 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableSimpleElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableSimpleElementBinding_WithRewriteSupport_IsBeingRewritten.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Linq;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableValueCastOperatorsPersist.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableValueCastOperatorsPersist.verified.txt
similarity index 95%
rename from tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableValueCastOperatorsPersist.verified.txt
rename to tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableValueCastOperatorsPersist.verified.txt
index 8cfc5e5..b464304 100644
--- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.NullableValueCastOperatorsPersist.verified.txt
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.NullableValueCastOperatorsPersist.verified.txt
@@ -1,4 +1,4 @@
-//
+//
#nullable disable
using System;
using System.Collections.Generic;
diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.cs
new file mode 100644
index 0000000..1f533f8
--- /dev/null
+++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/NullableTests.cs
@@ -0,0 +1,492 @@
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis;
+using VerifyXunit;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace EntityFrameworkCore.Projectables.Generator.Tests;
+
+[UsesVerify]
+public class NullableTests : ProjectionExpressionGeneratorTestsBase
+{
+ public NullableTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { }
+
+ [Fact]
+ public Task NullableReferenceTypesAreBeingEliminated()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+
+#nullable enable
+
+namespace Foo {
+ static class C {
+ [Projectable]
+ public static object? NextFoo(this object? unusedArgument, int? nullablePrimitiveArgument) => null;
+ }
+}
+");
+
+ var result = RunGenerator(compilation);
+
+ Assert.Empty(result.Diagnostics);
+ Assert.Single(result.GeneratedTrees);
+
+ return Verifier.Verify(result.GeneratedTrees[0].ToString());
+ }
+
+ [Fact]
+ public Task GenericNullableReferenceTypesAreBeingEliminated()
+ {
+ var compilation = CreateCompilation(@"
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using EntityFrameworkCore.Projectables;
+
+#nullable enable
+
+namespace Foo {
+ static class C {
+ [Projectable]
+ public static List