|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.AddImport;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.ExtractInterface;
using Microsoft.CodeAnalysis.Editor.UnitTests;
using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions;
using Microsoft.CodeAnalysis.Editor.UnitTests.ExtractInterface;
using Microsoft.CodeAnalysis.ExtractInterface;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
using Roslyn.Test.Utilities;
using Xunit;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ExtractInterface;
public class ExtractInterfaceTests : AbstractExtractInterfaceTests
{
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_CaretInMethod()
{
var markup = """
using System;
class MyClass
{
public void Goo()
{
$$
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_CaretAfterClassClosingBrace()
{
var markup = """
using System;
class MyClass
{
public void Goo()
{
}
}$$
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_CaretBeforeClassKeyword()
{
var markup = """
using System;
$$class MyClass
{
public void Goo()
{
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_FromInnerClass1()
{
var markup = """
using System;
class MyClass
{
public void Goo()
{
}
class AnotherClass
{
$$public void Bar()
{
}
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Bar");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_FromInnerClass2()
{
var markup = """
using System;
class MyClass
{
public void Goo()
{
}
$$class AnotherClass
{
public async Task Bar()
{
}
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Bar");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_FromOuterClass()
{
var markup = """
using System;
class MyClass
{
public void Goo()
{
}$$
class AnotherClass
{
public async Task Bar()
{
}
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Goo");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_FromInterface_01()
{
var markup = """
using System;
interface IMyInterface
{
$$void Goo();
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Goo", expectedInterfaceName: "IMyInterface1");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_FromInterface_02()
{
var markup = """
using System;
interface IMyInterface()
{
$$void Goo();
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Goo", expectedInterfaceName: "IMyInterface1");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_FromStruct()
{
var markup = """
using System;
struct SomeStruct
{
$$public void Goo() { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Goo", expectedInterfaceName: "ISomeStruct");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_Invocation_FromNamespace()
{
var markup = """
using System;
namespace Ns$$
{
class MyClass
{
public async Task Goo() { }
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_DoesNotIncludeFields()
{
var markup = """
using System;
class MyClass
{
$$public int x;
public void Goo()
{
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Goo");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_IncludesPublicProperty_WithGetAndSet()
{
var markup = """
using System;
class MyClass
{
$$public int Prop { get; set; }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Prop");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterfaceAction_ExtractableMembers_IncludesPublicProperty_WithGetAndSet()
{
var markup = """
class MyClass$$
{
public int Prop { get; set; }
}
""";
var expectedMarkup = """
interface IMyClass
{
int Prop { get; set; }
}
class MyClass : IMyClass
{
public int Prop { get; set; }
}
""";
await TestExtractInterfaceCodeActionCSharpAsync(markup, expectedMarkup);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_IncludesPublicProperty_WithGetAndPrivateSet()
{
var markup = """
using System;
class MyClass
{
$$public int Prop { get; private set; }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Prop");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_IncludesPublicProperty_WithGet()
{
var markup = """
using System;
class MyClass
{
$$public int Prop { get; }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "Prop");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_ExcludesPublicProperty_WithPrivateGetAndPrivateSet()
{
var markup = """
using System;
class MyClass
{
$$public int Prop { private get; private set; }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_IncludesPublicIndexer()
{
var markup = """
using System;
class MyClass
{
$$public int this[int x] { get { return 5; } set { } }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "this[]");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_ExcludesInternalIndexer()
{
var markup = """
using System;
class MyClass
{
$$internal int this[int x] { get { return 5; } set { } }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_IncludesPublicMethod()
{
var markup = """
using System;
class MyClass
{
$$public void M()
{
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "M");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_ExcludesInternalMethod()
{
var markup = """
using System;
class MyClass
{
$$internal void M()
{
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_IncludesAbstractMethod()
{
var markup = """
using System;
abstract class MyClass
{
$$public abstract void M();
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "M");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_IncludesPublicEvent()
{
var markup = """
using System;
class MyClass
{
$$public event Action MyEvent;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedMemberName: "MyEvent");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_ExtractableMembers_ExcludesPrivateEvent()
{
var markup = """
using System;
class MyClass
{
$$private event Action MyEvent;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_DefaultInterfaceName_DoesNotConflictWithOtherTypeNames()
{
var markup = """
using System;
class MyClass
{
$$public void Goo() { }
}
interface IMyClass { }
struct IMyClass1 { }
class IMyClass2 { }
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceName: "IMyClass3");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_NamespaceName_NoNamespace()
{
var markup = """
using System;
class MyClass
{
$$public void Goo() { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedNamespaceName: "");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_NamespaceName_SingleNamespace()
{
var markup = """
using System;
namespace MyNamespace
{
class MyClass
{
$$public void Goo() { }
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedNamespaceName: "MyNamespace");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_NamespaceName_NestedNamespaces()
{
var markup = """
using System;
namespace OuterNamespace
{
namespace InnerNamespace
{
class MyClass
{
$$public void Goo() { }
}
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedNamespaceName: "OuterNamespace.InnerNamespace");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_NamespaceName_NestedNamespaces_FileScopedNamespace1()
{
var markup = """
using System;
namespace OuterNamespace
{
namespace InnerNamespace
{
class MyClass
{
$$public void Goo() { }
}
}
}
""";
using var testState = ExtractInterfaceTestState.Create(
markup, LanguageNames.CSharp,
parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10),
options: new OptionsCollection(LanguageNames.CSharp)
{
{ CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped, NotificationOption2.Silent }
});
var result = await testState.ExtractViaCommandAsync();
var interfaceDocument = result.UpdatedSolution.GetRequiredDocument(result.NavigationDocumentId);
var interfaceCode = (await interfaceDocument.GetTextAsync()).ToString();
Assert.Equal("""
namespace OuterNamespace.InnerNamespace;
internal interface IMyClass
{
void Goo();
}
""", interfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_NamespaceName_NestedNamespaces_FileScopedNamespace2()
{
var markup = """
using System;
namespace OuterNamespace
{
namespace InnerNamespace
{
class MyClass
{
$$public void Goo() { }
}
}
}
""";
using var testState = ExtractInterfaceTestState.Create(
markup, LanguageNames.CSharp,
parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9),
options: new OptionsCollection(LanguageNames.CSharp)
{
{ CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped, NotificationOption2.Silent }
});
var result = await testState.ExtractViaCommandAsync();
var interfaceDocument = result.UpdatedSolution.GetRequiredDocument(result.NavigationDocumentId);
var interfaceCode = (await interfaceDocument.GetTextAsync()).ToString();
Assert.Equal("""
namespace OuterNamespace.InnerNamespace
{
internal interface IMyClass
{
void Goo();
}
}
""", interfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_NamespaceName_NestedNamespaces_FileScopedNamespace3()
{
var markup = """
using System;
namespace OuterNamespace
{
namespace InnerNamespace
{
class MyClass
{
$$public void Goo() { }
}
}
}
""";
using var testState = ExtractInterfaceTestState.Create(
markup, LanguageNames.CSharp,
parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10),
options: new OptionsCollection(LanguageNames.CSharp)
{
{ CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped, NotificationOption2.Silent }
});
var result = await testState.ExtractViaCommandAsync();
var interfaceDocument = result.UpdatedSolution.GetRequiredDocument(result.NavigationDocumentId);
var interfaceCode = (await interfaceDocument.GetTextAsync()).ToString();
Assert.Equal("""
namespace OuterNamespace.InnerNamespace
{
internal interface IMyClass
{
void Goo();
}
}
""", interfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_ClassesImplementExtractedInterface()
{
var markup = """
using System;
class MyClass
{
$$public void Goo() { }
}
""";
var expectedCode = """
using System;
class MyClass : IMyClass
{
public void Goo() { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_StructsImplementExtractedInterface()
{
var markup = """
using System;
struct MyStruct
{
$$public void Goo() { }
}
""";
var expectedCode = """
using System;
struct MyStruct : IMyStruct
{
public void Goo() { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_InterfacesDoNotImplementExtractedInterface()
{
var markup = """
using System;
interface MyInterface
{
$$void Goo();
}
""";
var expectedCode = """
using System;
interface MyInterface
{
void Goo();
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_Methods()
{
var markup = """
using System;
abstract class MyClass$$
{
public required int RequiredProperty { get; set; }
public void ExtractableMethod_Normal() { }
public void ExtractableMethod_ParameterTypes(System.Diagnostics.CorrelationManager x, Nullable<Int32> y = 7, string z = "42") { }
public abstract void ExtractableMethod_Abstract();
unsafe public void NotActuallyUnsafeMethod(int p) { }
unsafe public void UnsafeMethod(int *p) { }
}
""";
var expectedInterfaceCode = """
using System.Diagnostics;
interface IMyClass
{
int RequiredProperty { get; set; }
void ExtractableMethod_Abstract();
void ExtractableMethod_Normal();
void ExtractableMethod_ParameterTypes(CorrelationManager x, int? y = 7, string z = "42");
void NotActuallyUnsafeMethod(int p);
unsafe void UnsafeMethod(int* p);
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_MethodsInRecord()
{
var markup = """
abstract record R$$
{
public void M() { }
}
""";
var expectedInterfaceCode = """
interface IR
{
bool Equals(object obj);
bool Equals(R other);
int GetHashCode();
void M();
string ToString();
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_Events()
{
var markup = """
using System;
abstract internal class MyClass$$
{
public event Action ExtractableEvent1;
public event Action<Nullable<Int32>> ExtractableEvent2;
}
""";
var expectedInterfaceCode = """
using System;
internal interface IMyClass
{
event Action ExtractableEvent1;
event Action<int?> ExtractableEvent2;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_Properties()
{
var markup = """
using System;
abstract class MyClass$$
{
public int ExtractableProp { get; set; }
public int ExtractableProp_GetOnly { get { return 1; } }
public int ExtractableProp_SetOnly { set { } }
public int ExtractableProp_SetPrivate { get; private set; }
public int ExtractableProp_GetPrivate { private get; set; }
public int ExtractableProp_SetInternal { get; internal set; }
public int ExtractableProp_GetInternal { internal get; set; }
unsafe public int NotActuallyUnsafeProp { get; set; }
unsafe public int* UnsafeProp { get; set; }
}
""";
var expectedInterfaceCode = """
interface IMyClass
{
int ExtractableProp { get; set; }
int ExtractableProp_GetOnly { get; }
int ExtractableProp_SetOnly { set; }
int ExtractableProp_SetPrivate { get; }
int ExtractableProp_GetPrivate { set; }
int ExtractableProp_SetInternal { get; }
int ExtractableProp_GetInternal { set; }
int NotActuallyUnsafeProp { get; set; }
unsafe int* UnsafeProp { get; set; }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_Indexers()
{
var markup = """
using System;
abstract class MyClass$$
{
public int this[int x] { set { } }
public int this[string x] { get { return 1; } }
public int this[double x] { get { return 1; } set { } }
public int this[Nullable<Int32> x, string y = "42"] { get { return 1; } set { } }
}
""";
var expectedInterfaceCode = """
interface IMyClass
{
int this[int x] { set; }
int this[string x] { get; }
int this[double x] { get; set; }
int this[int? x, string y = "42"] { get; set; }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_Imports()
{
var markup = """
public class Class
{
$$public System.Diagnostics.BooleanSwitch M1(System.Globalization.Calendar x) { return null; }
public void M2(System.Collections.Generic.List<System.IO.BinaryWriter> x) { }
public void M3<T>() where T : System.Net.WebProxy { }
}
""";
var expectedInterfaceCode = """
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
public interface IClass
{
BooleanSwitch M1(Calendar x);
void M2(List<BinaryWriter> x);
void M3<T>() where T : WebProxy;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_ImportsInsideNamespace()
{
var markup = """
namespace N
{
public class Class
{
$$public System.Diagnostics.BooleanSwitch M1(System.Globalization.Calendar x) { return null; }
public void M2(System.Collections.Generic.List<System.IO.BinaryWriter> x) { }
public void M3<T>() where T : System.Net.WebProxy { }
}
}
""";
var expectedInterfaceCode = """
namespace N
{
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
public interface IClass
{
BooleanSwitch M1(Calendar x);
void M2(List<BinaryWriter> x);
void M3<T>() where T : WebProxy;
}
}
""";
using var testState = ExtractInterfaceTestState.Create(
markup, LanguageNames.CSharp,
parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10),
options: new OptionsCollection(LanguageNames.CSharp)
{
{ CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, AddImportPlacement.InsideNamespace }
});
var result = await testState.ExtractViaCommandAsync();
var interfaceDocument = result.UpdatedSolution.GetRequiredDocument(result.NavigationDocumentId);
var interfaceCode = (await interfaceDocument.GetTextAsync()).ToString();
Assert.Equal(expectedInterfaceCode, interfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_TypeParameters1()
{
var markup = """
public class Class<A, B, C, D, E, F, G, H, NO1> where E : F
{
$$public void Goo1(A a) { }
public B Goo2() { return default(B); }
public void Goo3(List<C> list) { }
public event Func<D> Goo4;
public List<E> Prop { set { } }
public List<G> this[List<List<H>> list] { set { } }
public void Bar1() { var x = default(NO1); }
}
""";
var expectedInterfaceCode = """
public interface IClass<A, B, C, D, E, F, G, H> where E : F
{
List<G> this[List<List<H>> list] { set; }
List<E> Prop { set; }
event Func<D> Goo4;
void Bar1();
void Goo1(A a);
B Goo2();
void Goo3(List<C> list);
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/706894")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_TypeParameters2()
{
var markup = """
using System.Collections.Generic;
class Program<A, B, C, D, E> where A : List<B> where B : Dictionary<List<D>, List<E>>
{
$$public void Goo<T>(T t) where T : List<A> { }
}
""";
var expectedInterfaceCode = """
using System.Collections.Generic;
interface IProgram<A, B, D, E>
where A : List<B>
where B : Dictionary<List<D>, List<E>>
{
void Goo<T>(T t) where T : List<A>;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_TypeParameters3()
{
var markup = """
class $$Class1<A, B>
{
public void method(A P1, Class2 P2)
{
}
public class Class2
{
}
}
""";
var expectedInterfaceCode = """
interface IClass1<A, B>
{
void method(A P1, Class1<A, B>.Class2 P2);
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/706894")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_TypeParameters4()
{
var markup = """
class C1<A>
{
public class C2<B> where B : new()
{
public class C3<C> where C : System.Collections.ICollection
{
public class C4
{$$
public A method() { return default(A); }
public B property { set { } }
public C this[int i] { get { return default(C); } }
}
}
}
}
""";
var expectedInterfaceCode = """
using System.Collections;
public interface IC4<A, B, C>
where B : new()
where C : ICollection
{
C this[int i] { get; }
B property { set; }
A method();
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_AccessibilityModifiers()
{
var markup = """
using System;
abstract class MyClass$$
{
public void Goo() { }
}
""";
using var testState = ExtractInterfaceTestState.Create(
markup, LanguageNames.CSharp,
options: new OptionsCollection(LanguageNames.CSharp)
{
{ CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.Always, NotificationOption2.Silent }
});
var result = await testState.ExtractViaCommandAsync();
var interfaceDocument = result.UpdatedSolution.GetRequiredDocument(result.NavigationDocumentId);
var interfaceCode = (await interfaceDocument.GetTextAsync()).ToString();
Assert.Equal("""
internal interface IMyClass
{
void Goo();
}
""", interfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_BaseList_NewBaseListNonGeneric()
{
var markup = """
class Program
{
$$public void Goo() { }
}
""";
var expectedCode = """
class Program : IProgram
{
public void Goo() { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_BaseList_NewBaseListGeneric()
{
var markup = """
class Program<T>
{
$$public void Goo(T t) { }
}
""";
var expectedCode = """
class Program<T> : IProgram<T>
{
public void Goo(T t) { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_BaseList_NewBaseListWithWhereClause()
{
var markup = """
class Program<T, U> where T : U
{
$$public void Goo(T t, U u) { }
}
""";
var expectedCode = """
class Program<T, U> : IProgram<T, U> where T : U
{
public void Goo(T t, U u) { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_BaseList_LargerBaseList1()
{
var markup = """
class Program : ISomeInterface
{
$$public void Goo() { }
}
interface ISomeInterface {}
""";
var expectedCode = """
class Program : ISomeInterface, IProgram
{
public void Goo() { }
}
interface ISomeInterface {}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_BaseList_LargerBaseList2()
{
var markup = """
class Program<T, U> : ISomeInterface<T>
{
$$public void Goo(T t, U u) { }
}
interface ISomeInterface<T> {}
""";
var expectedCode = """
class Program<T, U> : ISomeInterface<T>, IProgram<T, U>
{
public void Goo(T t, U u) { }
}
interface ISomeInterface<T> {}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_BaseList_LargerBaseList3()
{
var markup = """
class Program<T, U> : ISomeInterface<T>, ISomeInterface2<T, U>
{
$$public void Goo(T t, U u) { }
}
interface ISomeInterface<T> {}
interface ISomeInterface2<T, U> {}
""";
var expectedCode = """
class Program<T, U> : ISomeInterface<T>, ISomeInterface2<T, U>, IProgram<T, U>
{
public void Goo(T t, U u) { }
}
interface ISomeInterface<T> {}
interface ISomeInterface2<T, U> {}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_CodeGen_BaseList_LargerBaseList4()
{
var markup = """
class Program<T, U> : ISomeInterface<T>, ISomeInterface2<T, U> where T : U
{
$$public void Goo(T t, U u) { }
}
interface ISomeInterface<T> {}
interface ISomeInterface2<T, U> {}
""";
var expectedCode = """
class Program<T, U> : ISomeInterface<T>, ISomeInterface2<T, U>, IProgram<T, U> where T : U
{
public void Goo(T t, U u) { }
}
interface ISomeInterface<T> {}
interface ISomeInterface2<T, U> {}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedUpdatedOriginalDocumentCode: expectedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly1()
{
var markup = """
interface ISomeInterface<T> {}
class Program<T, U> : ISomeInterface<T> where T : U
{
$$public void Goo(T t, U u) { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly2()
{
var markup = """
interface ISomeInterface<T> {}
class Program<T, U> $$: ISomeInterface<T> where T : U
{
public void Goo(T t, U u) { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly3()
{
var markup = """
interface ISomeInterface<T> {}
class$$ Program<T, U> : ISomeInterface<T> where T : U
{
public void Goo(T t, U u) { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly4()
{
var markup = """
interface ISomeInterface<T> {}
class Program<T, U>$$ : ISomeInterface<T> where T : U
{
public void Goo(T t, U u) { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly5()
{
var markup = """
interface ISomeInterface<T> {}
class Program $$ <T, U> : ISomeInterface<T> where T : U
{
public void Goo(T t, U u) { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly6()
{
var markup = """
interface ISomeInterface<T> {}
class $$Program <T, U> : ISomeInterface<T> where T : U
{
public void Goo(T t, U u) { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly7()
{
var markup = """
interface ISomeInterface<T> {}
class $$Program : ISomeInterface<object>
{
public void Goo() { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly8()
{
var markup = """
interface ISomeInterface<T> {}
class Program$$ : ISomeInterface<object>
{
public void Goo() { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly9()
{
var markup = """
interface ISomeInterface<T> {}
class$$ Program : ISomeInterface<object>
{
public void Goo() { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly10()
{
var markup = """
interface ISomeInterface<T> {}
class Program $$: ISomeInterface<object>
{
public void Goo() { }
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_TypeDiscovery_NameOnly11()
{
var markup = """
namespace N
{
$$ class Program
{
public void Goo() { }
}
}
""";
await TestTypeDiscoveryAsync(markup, TypeDiscoveryRule.TypeNameOnly, expectedExtractable: true);
}
private static async Task TestTypeDiscoveryAsync(
string markup,
TypeDiscoveryRule typeDiscoveryRule,
bool expectedExtractable)
{
using var testState = ExtractInterfaceTestState.Create(markup, LanguageNames.CSharp, compilationOptions: null);
var result = await testState.GetTypeAnalysisResultAsync(typeDiscoveryRule);
Assert.Equal(expectedExtractable, result.CanExtractInterface);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_GeneratedNameTypeParameterSuffix1()
{
var markup = """
class $$Test<T>
{
public void M(T a) { }
}
""";
var expectedTypeParameterSuffix = @"<T>";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedTypeParameterSuffix: expectedTypeParameterSuffix);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_GeneratedNameTypeParameterSuffix2()
{
var markup = """
class $$Test<T, U>
{
public void M(T a) { }
}
""";
var expectedTypeParameterSuffix = @"<T>";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedTypeParameterSuffix: expectedTypeParameterSuffix);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task ExtractInterface_GeneratedNameTypeParameterSuffix3()
{
var markup = """
class $$Test<T, U>
{
public void M(T a, U b) { }
}
""";
var expectedTypeParameterSuffix = @"<T, U>";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedTypeParameterSuffix: expectedTypeParameterSuffix);
}
[WpfFact]
[Trait(Traits.Feature, Traits.Features.ExtractInterface)]
[Trait(Traits.Feature, Traits.Features.Interactive)]
public void ExtractInterfaceCommandDisabledInSubmission()
{
using var workspace = EditorTestWorkspace.Create(XElement.Parse("""
<Workspace>
<Submission Language="C#" CommonReferences="true">
public class $$C
{
public void M() { }
}
</Submission>
</Workspace>
"""),
workspaceKind: WorkspaceKind.Interactive,
composition: EditorTestCompositions.EditorFeaturesWpf);
// Force initialization.
workspace.GetOpenDocumentIds().Select(id => workspace.GetTestDocument(id)!.GetTextView()).ToList();
var textView = workspace.Documents.Single().GetTextView();
var handler = workspace.ExportProvider.GetCommandHandler<ExtractInterfaceCommandHandler>(PredefinedCommandHandlerNames.ExtractInterface, ContentTypeNames.CSharpContentType);
var state = handler.GetCommandState(new ExtractInterfaceCommandArgs(textView, textView.TextBuffer));
Assert.True(state.IsUnspecified);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestInWithMethod_Parameters()
{
var markup = """
using System;
class $$TestClass
{
public void Method(in int p1)
{
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass
{
void Method(in int p1);
}
""");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestRefReadOnlyWithMethod_ReturnType()
{
var markup = """
using System;
class $$TestClass
{
public ref readonly int Method() => throw null;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass
{
ref readonly int Method();
}
""");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestRefReadOnlyWithProperty()
{
var markup = """
using System;
class $$TestClass
{
public ref readonly int Property => throw null;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass
{
ref readonly int Property { get; }
}
""");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestInWithIndexer_Parameters()
{
var markup = """
using System;
class $$TestClass
{
public int this[in int p1] { set { } }
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass
{
int this[in int p1] { set; }
}
""");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestRefReadOnlyWithIndexer_ReturnType()
{
var markup = """
using System;
class $$TestClass
{
public ref readonly int this[int p1] => throw null;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass
{
ref readonly int this[int p1] { get; }
}
""");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestUnmanagedConstraint_Type()
{
var markup = """
class $$TestClass<T> where T : unmanaged
{
public void M(T arg) => throw null;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass<T> where T : unmanaged
{
void M(T arg);
}
""");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestUnmanagedConstraint_Method()
{
var markup = """
class $$TestClass
{
public void M<T>() where T : unmanaged => throw null;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass
{
void M<T>() where T : unmanaged;
}
""");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestNotNullConstraint_Type()
{
var markup = """
class $$TestClass<T> where T : notnull
{
public void M(T arg) => throw null;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass<T> where T : notnull
{
void M(T arg);
}
""");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestNotNullConstraint_Method()
{
var markup = """
class $$TestClass
{
public void M<T>() where T : notnull => throw null;
}
""";
await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode:
"""
interface ITestClass
{
void M<T>() where T : notnull;
}
""");
}
[WorkItem("https://github.com/dotnet/roslyn/issues/23855")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestExtractInterface_WithCopyright1()
{
var markup =
"""
// Copyright
public class $$Goo
{
public void Test()
{
}
}
""";
var updatedMarkup =
"""
// Copyright
public class Goo : IGoo
{
public void Test()
{
}
}
""";
var expectedInterfaceCode =
"""
// Copyright
public interface IGoo
{
void Test();
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: true,
expectedUpdatedOriginalDocumentCode: updatedMarkup,
expectedInterfaceCode: expectedInterfaceCode);
}
[WorkItem("https://github.com/dotnet/roslyn/issues/23855")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestExtractInterface_WithCopyright2()
{
var markup =
"""
// Copyright
public class Goo
{
public class $$A
{
public void Test()
{
}
}
}
""";
var updatedMarkup =
"""
// Copyright
public class Goo
{
public class A : IA
{
public void Test()
{
}
}
}
""";
var expectedInterfaceCode =
"""
// Copyright
public interface IA
{
void Test();
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: true,
expectedUpdatedOriginalDocumentCode: updatedMarkup,
expectedInterfaceCode: expectedInterfaceCode);
}
[WorkItem("https://github.com/dotnet/roslyn/issues/49739")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestRecord1()
{
var markup =
"""
namespace Test
{
record $$Whatever(int X, string Y);
}
""";
var updatedMarkup =
"""
namespace Test
{
record Whatever(int X, string Y) : IWhatever;
}
""";
var expectedInterfaceCode =
"""
namespace Test
{
interface IWhatever
{
int X { get; init; }
string Y { get; init; }
void Deconstruct(out int X, out string Y);
bool Equals(object obj);
bool Equals(Whatever other);
int GetHashCode();
string ToString();
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: true,
expectedUpdatedOriginalDocumentCode: updatedMarkup,
expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestClass1()
{
var markup =
"""
namespace Test
{
class $$Whatever(int X, string Y);
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestStruct1()
{
var markup =
"""
namespace Test
{
struct $$Whatever(int X, string Y);
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: false);
}
[WorkItem("https://github.com/dotnet/roslyn/issues/49739")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestRecord2()
{
var markup =
"""
namespace Test
{
record $$Whatever(int X, string Y) { }
}
""";
var updatedMarkup =
"""
namespace Test
{
record Whatever(int X, string Y) : IWhatever { }
}
""";
var expectedInterfaceCode =
"""
namespace Test
{
interface IWhatever
{
int X { get; init; }
string Y { get; init; }
void Deconstruct(out int X, out string Y);
bool Equals(object obj);
bool Equals(Whatever other);
int GetHashCode();
string ToString();
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: true,
expectedUpdatedOriginalDocumentCode: updatedMarkup,
expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestClass2()
{
var markup =
"""
namespace Test
{
class $$Whatever(int X, string Y) { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestStruct2()
{
var markup =
"""
namespace Test
{
struct $$Whatever(int X, string Y) { }
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: false);
}
[WorkItem("https://github.com/dotnet/roslyn/issues/49739")]
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestRecord3()
{
var markup =
"""
namespace Test
{
/// <summary></summary>
record $$Whatever(int X, string Y);
}
""";
var updatedMarkup =
"""
namespace Test
{
/// <summary></summary>
record Whatever(int X, string Y) : IWhatever;
}
""";
var expectedInterfaceCode =
"""
namespace Test
{
interface IWhatever
{
int X { get; init; }
string Y { get; init; }
void Deconstruct(out int X, out string Y);
bool Equals(object obj);
bool Equals(Whatever other);
int GetHashCode();
string ToString();
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: true,
expectedUpdatedOriginalDocumentCode: updatedMarkup,
expectedInterfaceCode: expectedInterfaceCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestClass3()
{
var markup =
"""
namespace Test
{
/// <summary></summary>
class $$Whatever(int X, string Y);
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestStruct3()
{
var markup =
"""
namespace Test
{
/// <summary></summary>
struct $$Whatever(int X, string Y);
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: false);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)]
public async Task TestStruct4()
{
var markup =
"""
namespace Test
{
struct $$Whatever
{
public int I { get; set; }
}
}
""";
var expectedInterfaceCode =
"""
namespace Test
{
interface IWhatever
{
int I { get; set; }
}
}
""";
await TestExtractInterfaceCommandCSharpAsync(
markup,
expectedSuccess: true,
expectedInterfaceCode: expectedInterfaceCode);
}
}
|