Skip to content

Commit

Permalink
Merge pull request #29 from wieslawsoltes/InheritedReactive
Browse files Browse the repository at this point in the history
Support inherited Reactive attribute
  • Loading branch information
wieslawsoltes authored Dec 19, 2024
2 parents a752b53 + 943ee8e commit e3baf32
Show file tree
Hide file tree
Showing 24 changed files with 1,154 additions and 808 deletions.
216 changes: 208 additions & 8 deletions ReactiveGenerator.Tests/ReactiveGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ public class ReactiveGeneratorTests
private Task TestAndVerify(string source, Dictionary<string, string>? analyzerConfigOptions = null)
{
return SourceGeneratorTestHelper.TestAndVerify(
source,
analyzerConfigOptions,
source,
analyzerConfigOptions,
generators: new ReactiveGenerator());
}

Expand Down Expand Up @@ -186,10 +186,7 @@ public partial class TestClass
public partial string Name { get; set; }
}";

var analyzerConfigOptions = new Dictionary<string, string>
{
["build_property.UseBackingFields"] = "true"
};
var analyzerConfigOptions = new Dictionary<string, string> { ["build_property.UseBackingFields"] = "true" };

return TestAndVerify(source, analyzerConfigOptions);
}
Expand All @@ -206,7 +203,7 @@ public partial class GlobalClass

return TestAndVerify(source);
}

[Fact]
public Task ClassWithMultipleReactiveAttributes()
{
Expand Down Expand Up @@ -483,7 +480,7 @@ public partial class TestClass

return TestAndVerify(source);
}

[Fact]
public Task PropertyLevelReactiveWithMixedProperties()
{
Expand Down Expand Up @@ -1069,4 +1066,207 @@ internal partial class GenericViewModel<T>

return TestAndVerify(source);
}

[Fact]
public Task InheritedReactiveAttribute()
{
var source = @"
[Reactive]
public abstract partial class BaseViewModel
{
public partial string BaseProp { get; set; }
}
public partial class ViewModel : BaseViewModel
{
public partial string ViewModelProp { get; set; }
}
[IgnoreReactive]
public partial class NonReactiveViewModel : BaseViewModel
{
public partial string IgnoredProp { get; set; }
}
public partial class DerivedViewModel : ViewModel
{
public partial string DerivedProp { get; set; }
}";

return TestAndVerify(source);
}

[Fact]
public Task MultiLevelInheritanceWithMixedReactiveAttributes()
{
var source = @"
[Reactive]
public abstract partial class BaseViewModel
{
public partial string BaseProp { get; set; }
}
public partial class MiddleViewModel : BaseViewModel
{
public partial string MiddleProp { get; set; }
[IgnoreReactive]
public partial string IgnoredMiddleProp { get; set; }
}
[IgnoreReactive]
public partial class NonReactiveViewModel : MiddleViewModel
{
public partial string NonReactiveProp { get; set; }
}
[Reactive]
public partial class ReactiveDerivedViewModel : NonReactiveViewModel
{
public partial string ReactiveProp { get; set; }
}";

return TestAndVerify(source);
}

[Fact]
public Task ReactiveObjectWithSingleReactiveProperty()
{
var source = @"
using ReactiveUI;
public partial class Car : ReactiveObject
{
[Reactive]
public partial string? Make { get; set; }
public partial string Model { get; set; } // Should not be processed
}";

return TestAndVerify(source);
}

[Fact]
public Task ReactiveObjectWithClassLevelReactive()
{
var source = @"
using ReactiveUI;
[Reactive]
internal partial class ReactiveViewModel : ReactiveObject
{
public partial string FirstName { get; set; }
public partial string LastName { get; set; }
}";

return TestAndVerify(source);
}

[Fact]
public Task ReactiveObjectWithoutAnyReactiveAttribute()
{
var source = @"
using ReactiveUI;
public partial class OaphViewModel<T> : ReactiveObject
{
public partial string ComputedValue { get; } // Should not be processed
public partial string NormalProperty { get; set; } // Should not be processed
}";

return TestAndVerify(source);
}

[Fact]
public Task ReactiveObjectWithNullableGenerics()
{
var source = @"
using System;
using ReactiveUI;
public partial class NullableGenericsTest<T>
{
[Reactive]
public partial DateTime? StartDate { get; set; }
[Reactive]
public partial DateTime? EndDate { get; set; }
}";

return TestAndVerify(source);
}

[Fact]
public Task ReactiveObjectWithMixedReactiveProperties()
{
var source = @"
using ReactiveUI;
public partial class MixedViewModel : ReactiveObject
{
[Reactive]
public partial string ReactiveProperty { get; set; }
public partial string NonReactiveProperty { get; set; }
[Reactive]
public partial int? NullableReactiveProperty { get; set; }
[ObservableAsProperty]
public partial string ComputedProperty { get; }
}";

return TestAndVerify(source);
}

[Fact]
public Task ReactiveObjectWithClassLevelReactiveAndIgnoreOverride()
{
var source = @"
using ReactiveUI;
[Reactive]
public partial class AllReactiveViewModel : ReactiveObject
{
public partial string Property1 { get; set; }
[IgnoreReactive]
public partial string IgnoredProperty { get; set; }
public partial string Property2 { get; set; }
}";

return TestAndVerify(source);
}

[Fact]
public Task ReactiveObjectWithPropertyInitializer()
{
var source = @"
using ReactiveUI;
[Reactive]
public partial class InitializedViewModel : ReactiveObject
{
public partial string Name { get; set; } = string.Empty;
public partial int Count { get; set; } = 42;
}";

return TestAndVerify(source);
}

[Fact]
public Task NonReactiveObjectWithMixedProperties()
{
var source = @"
public partial class RegularClass
{
[Reactive]
public partial string ReactiveProperty { get; set; }
public partial string NonReactiveProperty { get; set; }
}";

return TestAndVerify(source);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,59 +21,24 @@ sealed class ReactiveAttribute : Attribute
{
public ReactiveAttribute() { }
}
},
{
FileName: TestClass.INPC.g.cs,
Source:
// <auto-generated/>
#nullable enable

using System.ComponentModel;
using System.Runtime.CompilerServices;

public partial class TestClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
PropertyChanged?.Invoke(this, args);
}
}

},
{
FileName: TestClass.ReactiveProperties.g.cs,
Source:
// <auto-generated/>
#nullable enable

using System.ComponentModel;
using System.Runtime.CompilerServices;
using ReactiveUI;

/// <summary>
/// A partial class implementation for TestClass.
/// </summary>
public partial class TestClass
{
private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name));

public partial string Name
{
get => field;
set
{
if (!Equals(field, value))
{
field = value;
OnPropertyChanged(_nameChangedEventArgs);
}
}
set => this.RaiseAndSetIfChanged(ref field, value);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,19 @@
{
Sources: [
{
FileName: GenericViewModel.INPC.g.cs,
Source:
// <auto-generated/>
#nullable enable

using System.ComponentModel;
using System.Runtime.CompilerServices;

internal partial class GenericViewModel<T> : INotifyPropertyChanged where T : class
{
public event PropertyChangedEventHandler? PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
PropertyChanged?.Invoke(this, args);
}
}

},
{
FileName: GenericViewModel.ReactiveProperties.g.cs,
Source:
// <auto-generated/>
#nullable enable

using System.ComponentModel;
using System.Runtime.CompilerServices;
using ReactiveUI;

internal partial class GenericViewModel<T> where T : class
{
private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value));

public partial T? Value
{
get => field;
set
{
if (!Equals(field, value))
{
field = value;
OnPropertyChanged(_valueChangedEventArgs);
}
}
set => this.RaiseAndSetIfChanged(ref field, value);
}
}

Expand Down
Loading

0 comments on commit e3baf32

Please sign in to comment.