public static void WhenAssigningLocalInLambda() { var before = @" namespace N { using System; public class C { public C() { Console.CancelKeyPress += (_, __) => { Disposable disposable; ↓disposable = new Disposable(); }; } } }"; var after = @" namespace N { using System; public class C { public C() { Console.CancelKeyPress += (_, __) => { Disposable disposable; using (disposable = new Disposable()) { } }; } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, new[] { Disposable, before }, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, new[] { Disposable, before }, after); }
public static void AddToExistingCompositeDisposableInitializerWithTrivia() { var before = @" namespace N { using System.IO; using System.Reactive.Disposables; internal sealed class C { private readonly CompositeDisposable disposable; internal C() { this.disposable = new CompositeDisposable(); // trivia1 ↓File.OpenRead(string.Empty); // trivia2 } } }"; var after = @" namespace N { using System.IO; using System.Reactive.Disposables; internal sealed class C { private readonly CompositeDisposable disposable; internal C() { this.disposable = new CompositeDisposable { File.OpenRead(string.Empty), // trivia2 }; // trivia1 } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void CreateNewCompositeDisposable() { var before = @" namespace N { using System; using System.IO; using System.Reactive.Disposables; internal sealed class C { internal C() { ↓File.OpenRead(string.Empty); } } }"; var after = @" namespace N { using System; using System.IO; using System.Reactive.Disposables; internal sealed class C { private readonly CompositeDisposable disposable; internal C() { this.disposable = new CompositeDisposable { File.OpenRead(string.Empty), }; } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void WhenNotCallingBaseDisposeWithoutBaseCode() { var before = @" namespace N { using System.IO; public class C : StreamReader { public C(Stream stream) : base(stream) { } protected override void ↓Dispose(bool disposing) { } } }"; var after = @" namespace N { using System.IO; public class C : StreamReader { public C(Stream stream) : base(stream) { } protected override void Dispose(bool disposing) { base.Dispose(disposing); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, new[] { DisposableCode, before }, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, new[] { DisposableCode, before }, after); }
public static void WhenNotNotifyingWithBackingFieldExpressionBodies() { var before = @" namespace N { public class ↓C { private int value; public int Value { get => this.value; private set => this.value = value; } } }"; var after = @" namespace N { public class C : System.ComponentModel.INotifyPropertyChanged { private int value; public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; public int Value { get => this.value; private set => this.value = value; } protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null) { this.PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "Implement INotifyPropertyChanged fully qualified."); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "Implement INotifyPropertyChanged fully qualified."); }
public static void LocalInLambdaClosure() { var before = @" namespace N { using System; public class C { public C() { Disposable disposable = null; Console.CancelKeyPress += (_, __) => { ↓disposable = new Disposable(); }; } } }"; var after = @" namespace N { using System; public class C { public C() { Disposable disposable = null; Console.CancelKeyPress += (_, __) => { disposable?.Dispose(); disposable = new Disposable(); }; } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, new[] { Disposable, before }, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, new[] { Disposable, before }, after); }
public static void WhenAlreadyDisposingOther() { var before = @" namespace N { using System; using System.IO; public sealed class C : IDisposable { private readonly Stream stream1 = File.OpenRead(string.Empty); ↓private readonly Stream stream2 = File.OpenRead(string.Empty); public void Dispose() { stream1.Dispose(); } } }"; var after = @" namespace N { using System; using System.IO; public sealed class C : IDisposable { private readonly Stream stream1 = File.OpenRead(string.Empty); private readonly Stream stream2 = File.OpenRead(string.Empty); public void Dispose() { stream1.Dispose(); this.stream2?.Dispose(); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public void VerifyPartlyIndependent() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void Test() { var configuration = new Configuration(); Assert.That(configuration, Is.Not.Null); ↓Assert.That(configuration.Value1, Is.EqualTo(0)); ↓Assert.That(configuration.Value2, Is.EqualTo(0.0)); Assert.That(configuration.Value11, Is.EqualTo(string.Empty)); configuration = null; } private sealed class Configuration { public int Value1 { get; set; } public double Value2 { get; set; } public string Value11 { get; set; } = string.Empty; }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void Test() { var configuration = new Configuration(); Assert.That(configuration, Is.Not.Null); Assert.Multiple(() => { Assert.That(configuration.Value1, Is.EqualTo(0)); Assert.That(configuration.Value2, Is.EqualTo(0.0)); Assert.That(configuration.Value11, Is.EqualTo(string.Empty)); }); configuration = null; } private sealed class Configuration { public int Value1 { get; set; } public double Value2 { get; set; } public string Value11 { get; set; } = string.Empty; }"); RoslynAssert.FixAll(analyzer, fix, expectedDiagnostic, code, fixedCode); }
public static void EventHandler() { var before = @" namespace N { using System; [Serializable] public class Foo { ↓private EventHandler someEvent; public event EventHandler SomeEvent { add { this.someEvent += value; } remove { this.someEvent -= value; } } } }"; var after = @" namespace N { using System; [Serializable] public class Foo { [NonSerialized] private EventHandler someEvent; public event EventHandler SomeEvent { add { this.someEvent += value; } remove { this.someEvent -= value; } } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void SingleDocumentExplicitTitle() { var before = @" namespace N { class C { private readonly int ↓_value; } }"; var analyzer = new FieldNameMustNotBeginWithUnderscore(); var fix = new DoNotUseUnderscoreFix(); var expected = "Did not find a code fix with title WRONG.\r\n" + "Found:\r\n" + "Rename to: 'value'\r\n"; var exception = Assert.Throws <AssertException>(() => RoslynAssert.FixAll(analyzer, fix, before, string.Empty, "WRONG")); Assert.AreEqual(expected, exception.Message); }
public static void AddIgnoredReturnValueToExistingCompositeDisposableCtorUnderscore() { var before = @" namespace N { using System; using System.IO; using System.Reactive.Disposables; internal sealed class C { private readonly CompositeDisposable _disposable = new CompositeDisposable(); internal C() { ↓File.OpenRead(string.Empty); } } }"; var after = @" namespace N { using System; using System.IO; using System.Reactive.Disposables; internal sealed class C { private readonly CompositeDisposable _disposable = new CompositeDisposable(); internal C() { _disposable.Add(File.OpenRead(string.Empty)); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void TwoDocumentsTwoFixes(string title, string expected) { var before1 = @" namespace N { class C1 { private readonly int ↓_value; } }"; var before2 = @" namespace N { class C2 { private readonly int ↓_value; } }"; var after1 = @" namespace N { class C1 { private readonly int value; } }".AssertReplace("value", expected); var after2 = @" namespace N { class C2 { private readonly int value; } }".AssertReplace("value", expected); var analyzer = new FieldNameMustNotBeginWithUnderscore(); var fix = new DontUseUnderscoreManyFix(); RoslynAssert.FixAll(analyzer, fix, new[] { before1, before2 }, new[] { after1, after2 }, title); }
public static void InNullableContext(string member) { var before = @" #nullable enable namespace N { using System.ComponentModel; public class C : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(↓string propertyName) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }".AssertReplace("this.PropertyChanged", member); var after = @" #nullable enable namespace N { using System.ComponentModel; public class C : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string? propertyName = null) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }".AssertReplace("this.PropertyChanged", member); RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void LocalInLambdaToUsingDeclaration() { var before = @" namespace N { using System; using System.IO; public class C { public C() { Console.CancelKeyPress += (_, __) => { ↓var stream = File.OpenRead(string.Empty); }; } } }"; var after = @" namespace N { using System; using System.IO; public class C { public C() { Console.CancelKeyPress += (_, __) => { using var stream = File.OpenRead(string.Empty); }; } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "using"); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "using"); }
public static void FieldAssignedInPublicMethodReturnExpression() { var before = @" namespace N { using System; using System.IO; public class C { private Stream stream; public IDisposable M() { return ↓this.stream = File.OpenRead(string.Empty); } } }"; var after = @" namespace N { using System; using System.IO; public class C { private Stream stream; public IDisposable M() { this.stream?.Dispose(); return this.stream = File.OpenRead(string.Empty); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void AssignedInExpressionBody() { var before = @" namespace N { using System; class C : IDisposable { ↓IDisposable _disposable; public void M() => _disposable = new Disposable(); public void Dispose() { } } }"; var after = @" namespace N { using System; class C : IDisposable { IDisposable _disposable; public void M() => _disposable = new Disposable(); public void Dispose() { _disposable?.Dispose(); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, new[] { Disposable, before }, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, new[] { Disposable, before }, after); }
public static void NotDisposingVariables() { var before = @" namespace N { using System.IO; public class C { public void M() { var stream1 = File.OpenRead(string.Empty); var stream2 = File.OpenRead(string.Empty); ↓stream1 = File.OpenRead(string.Empty); ↓stream2 = File.OpenRead(string.Empty); } } }"; var after = @" namespace N { using System.IO; public class C { public void M() { var stream1 = File.OpenRead(string.Empty); var stream2 = File.OpenRead(string.Empty); stream1?.Dispose(); stream1 = File.OpenRead(string.Empty); stream2?.Dispose(); stream2 = File.OpenRead(string.Empty); } } }"; RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void DependencyPropertyRegisterBackingField(string modifiersBefore, string modifiersAfter) { var before = @" namespace N { using System.Windows; using System.Windows.Controls; public class FooControl : Control { public static DependencyProperty ↓BarProperty = DependencyProperty.Register(nameof(Bar), typeof(int), typeof(FooControl), new PropertyMetadata(default(int))); public int Bar { get { return (int)GetValue(BarProperty); } set { SetValue(BarProperty, value); } } } }".AssertReplace("public static DependencyProperty", modifiersBefore + " DependencyProperty"); var after = @" namespace N { using System.Windows; using System.Windows.Controls; public class FooControl : Control { public static readonly DependencyProperty BarProperty = DependencyProperty.Register(nameof(Bar), typeof(int), typeof(FooControl), new PropertyMetadata(default(int))); public int Bar { get { return (int)GetValue(BarProperty); } set { SetValue(BarProperty, value); } } } }".AssertReplace("public static readonly DependencyProperty", modifiersAfter + " DependencyProperty"); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void PropertyInitializedAndAssignedInConstructor() { var before = @" namespace N { using System; using System.IO; public class C { public C() { ↓this.Stream = File.OpenRead(string.Empty); } public Stream Stream { get; } = File.OpenRead(string.Empty); } }"; var after = @" namespace N { using System; using System.IO; public class C { public C() { this.Stream?.Dispose(); this.Stream = File.OpenRead(string.Empty); } public Stream Stream { get; } = File.OpenRead(string.Empty); } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void FieldOfTypeObjectInitializedThenAssignedInConstructor() { var before = @" namespace N { using System; using System.IO; public class C { private readonly object stream = File.OpenRead(string.Empty); public C() { ↓this.stream = File.OpenRead(string.Empty); } } }"; var after = @" namespace N { using System; using System.IO; public class C { private readonly object stream = File.OpenRead(string.Empty); public C() { (this.stream as IDisposable)?.Dispose(); this.stream = File.OpenRead(string.Empty); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void NoCheckToUseTrySet() { var before = @" namespace N { public class C : MvvmCross.ViewModels.MvxNotifyPropertyChanged { private string name; public string Name { get => this.name; set { this.name = value; ↓this.RaisePropertyChanged(); } } } }"; var after = @" namespace N { public class C : MvvmCross.ViewModels.MvxNotifyPropertyChanged { private string name; public string Name { get => this.name; set => this.SetProperty(ref this.name, value); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "SetProperty(ref storage, value)", metadataReferences: MetadataReferences); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "SetProperty(ref storage, value)", metadataReferences: MetadataReferences); }
public static void NoCheckToUseTrySet() { var before = @" namespace N { public class C : Stylet.PropertyChangedBase { private string name; public string Name { get => this.name; set { this.name = value; ↓this.NotifyOfPropertyChange(); } } } }"; var after = @" namespace N { public class C : Stylet.PropertyChangedBase { private string name; public string Name { get => this.name; set => this.SetAndNotify(ref this.name, value); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "SetAndNotify(ref field, value)", metadataReferences: MetadataReferences); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "SetAndNotify(ref field, value)", metadataReferences: MetadataReferences); }
public static void LocalOneStatementAfter() { var before = @" namespace N { using System; using System.IO; public sealed class C { public void M() { ↓var stream = File.OpenRead(string.Empty); var i = 1; } } }"; var after = @" namespace N { using System; using System.IO; public sealed class C { public void M() { using (var stream = File.OpenRead(string.Empty)) { var i = 1; } } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "Add using to end of block."); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "Add using to end of block."); }
public static void AddUsingForIgnoredFileOpenRead() { var before = @" namespace N { using System; using System.IO; public sealed class C { public void M() { ↓File.OpenRead(string.Empty); var i = 1; } } }"; var after = @" namespace N { using System; using System.IO; public sealed class C { public void M() { using (File.OpenRead(string.Empty)) { var i = 1; } } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }
public static void NoCheckToUseTrySet() { var before = @" namespace N { public class C : Microsoft.Practices.Prism.Mvvm.BindableBase { private string name; public string Name { get => this.name; set { this.name = value; ↓this.OnPropertyChanged(nameof(this.Name)); } } } }"; var after = @" namespace N { public class C : Microsoft.Practices.Prism.Mvvm.BindableBase { private string name; public string Name { get => this.name; set => this.SetProperty(ref this.name, value); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "SetProperty(ref storage, value)", metadataReferences: MetadataReferences); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "SetProperty(ref storage, value)", metadataReferences: MetadataReferences); }
public static void TwoClassOneError() { var barCode = @" namespace N { class Bar { private readonly int value; } }"; var before = @" namespace N { class C { private readonly int ↓_value; } }"; var after = @" namespace N { class C { private readonly int value; } }"; var expectedDiagnostic = ExpectedDiagnostic.Create(FieldNameMustNotBeginWithUnderscore.DiagnosticId); var analyzer = new FieldNameMustNotBeginWithUnderscore(); var fix = new DoNotUseUnderscoreFix(); RoslynAssert.FixAll(analyzer, fix, new[] { barCode, before }, new[] { barCode, after }); RoslynAssert.FixAll(analyzer, fix, new[] { barCode, before }, after); RoslynAssert.FixAll(analyzer, fix, new[] { barCode, before }, after); RoslynAssert.FixAll(analyzer, fix, new[] { barCode, before }, new[] { barCode, after }); RoslynAssert.FixAll(analyzer, fix, expectedDiagnostic, new[] { barCode, before }, after); RoslynAssert.FixAll(analyzer, fix, expectedDiagnostic, new[] { barCode, before }, new[] { barCode, after }); }
public static void NoCheckToUseTrySet() { var before = @" namespace N.Client { public class C : N.Core.ViewModelBase { private string name; public string Name { get => this.name; set { this.name = value; ↓this.OnPropertyChanged(); } } } }"; var after = @" namespace N.Client { public class C : N.Core.ViewModelBase { private string name; public string Name { get => this.name; set => this.TrySet(ref this.name, value); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, new[] { ViewModelBaseCode, before }, after, fixTitle: "TrySet(ref field, value)"); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, new[] { ViewModelBaseCode, before }, after, fixTitle: "TrySet(ref field, value)"); }
public static void NoCheckExpressionToUseTrySet() { var before = @" namespace N { public class C : Caliburn.Micro.PropertyChangedBase { private string name; public string Name { get => this.name; set { this.name = value; ↓this.NotifyOfPropertyChange(() => this.Name); } } } }"; var after = @" namespace N { public class C : Caliburn.Micro.PropertyChangedBase { private string name; public string Name { get => this.name; set => this.Set(ref this.name, value); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "Set(ref oldValue, newValue)", metadataReferences: MetadataReferences); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "Set(ref oldValue, newValue)", metadataReferences: MetadataReferences); }
public static void NoCheckToUseTrySet() { var before = @" namespace N { public class C : GalaSoft.MvvmLight.ViewModelBase { private string name; public string Name { get => this.name; set { this.name = value; ↓this.RaisePropertyChanged(); } } } }"; var after = @" namespace N { public class C : GalaSoft.MvvmLight.ViewModelBase { private string name; public string Name { get => this.name; set => this.Set(ref this.name, value); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "Set(ref field, newValue)", metadataReferences: MetadataReferences); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after, fixTitle: "Set(ref field, newValue)", metadataReferences: MetadataReferences); }
public static void OfTypeObject() { var before = @" namespace N { using System; using System.IO; public sealed class C : IDisposable { ↓private readonly object stream = File.OpenRead(string.Empty); public void Dispose() { } } }"; var after = @" namespace N { using System; using System.IO; public sealed class C : IDisposable { private readonly object stream = File.OpenRead(string.Empty); public void Dispose() { (this.stream as IDisposable)?.Dispose(); } } }"; RoslynAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, before, after); RoslynAssert.FixAll(Analyzer, Fix, ExpectedDiagnostic, before, after); }