public async Task NoDiagnostics_ChainOf3() { var hostPropertyTypeInfo = new EmptyClassBuilder() .WithClassName("ClassName") .WithNamespace("Namespace1") .WithClassAccess(Accessibility.Public); var hostTypeInfo = WhenChangedHostBuilder.Changing() .WithClassName("ClassName") .WithNamespace("Namespace2") .WithInvocation(InvocationKind.MemberAccess, x => x.Child.Child.Value) .WithClassAccess(Accessibility.Public) .WithPropertyType(hostPropertyTypeInfo) .WithPropertyAccess(Accessibility.Public); var fixture = await WhenChangedFixture.Create(hostTypeInfo, x => TestContext.WriteLine(x), ("HostProperty.cs", hostPropertyTypeInfo.BuildRoot())).ConfigureAwait(false); fixture.RunGenerator(out var compilationDiagnostics, out var generatorDiagnostics); generatorDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); compilationDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); var host = fixture.NewHostInstance(); host.Child = fixture.NewHostInstance(); host.Child.Child = fixture.NewHostInstance(); host.Child.Child.Value = fixture.NewValuePropertyInstance(); var observable = host.GetWhenChangedObservable(_ => TestContext.WriteLine(fixture.Sources)); object emittedValue = null; observable.Subscribe(x => emittedValue = x); var initialValue = host.Child.Child.Value; emittedValue.Should().Be(initialValue); var previousValue = emittedValue; // According to the current design, no emission should occur when the chain is "broken". host.Child = null; emittedValue.Should().Be(previousValue); previousValue = emittedValue; host.Child = fixture.NewHostInstance(); host.Child.Child = fixture.NewHostInstance(); emittedValue.Should().Be(previousValue); previousValue = emittedValue; host.Child.Child.Value = fixture.NewValuePropertyInstance(); emittedValue.Should().Be(previousValue); previousValue = emittedValue; host.Child.Child.Value = null; emittedValue.Should().Be(previousValue); }
public Task NoDiagnostics_ExplicitInvocation_MultiExpression(Accessibility hostTypeAccess, Accessibility propertyTypeAccess, Accessibility propertyAccess) { var hostPropertyTypeInfo = new EmptyClassBuilder() .WithClassAccess(propertyTypeAccess); var hostTypeInfo = new WhenChangedHostBuilder() .WithClassName("HostClass") .WithClassAccess(hostTypeAccess) .WithPropertyType(hostPropertyTypeInfo) .WithPropertyAccess(propertyAccess); return(AssertTestCase_MultiExpression(hostTypeInfo, InvocationKind.Explicit, ("HostPropertyTypeInfo.cs", hostPropertyTypeInfo.BuildRoot()))); }
public async Task NoDiagnostics_TwoWayBind(Accessibility hostContainerTypeAccess, Accessibility hostTypeAccess, Accessibility hostPropertiesAccess, Accessibility vmTypeAccess, Accessibility vmPropertiesAccess) { var viewModelHostDetails = new WhenChangedHostBuilder() .WithClassAccess(vmTypeAccess) .WithInvocation(InvocationKind.MemberAccess, x => x.Value) .WithPropertyType("string") .WithPropertyAccess(vmPropertiesAccess) .WithClassName("ViewModelHost"); var hostTypeInfo = new BindHostBuilder() .WithClassName("Host") .WithTwoWayInvocation(InvocationKind.MemberAccess, ReceiverKind.This, x => x.Value, x => x.Value) .WithClassAccess(hostTypeAccess) .WithPropertyType("string") .WithPropertyAccess(hostPropertiesAccess) .WithViewModelPropertyAccess(hostPropertiesAccess) .WithViewModelPropertyType(viewModelHostDetails) .AddNestedClass(viewModelHostDetails); var hostContainerTypeInfo = new EmptyClassBuilder() .WithClassName("HostContainer") .WithClassAccess(hostContainerTypeAccess) .AddNestedClass(hostTypeInfo); var fixture = await BindFixture.Create(hostTypeInfo, x => TestContext.WriteLine(x)).ConfigureAwait(false); fixture.RunGenerator(hostTypeInfo, out var compilationDiagnostics, out var generatorDiagnostics); generatorDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); compilationDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); var host = fixture.NewHostInstance(); host.ViewModel = fixture.NewViewModelPropertyInstance(); var disposable = host.GetTwoWayBindSubscription(_ => TestContext.WriteLine(fixture.Sources)); var viewModelObservable = host.GetViewModelWhenChangedObservable(_ => TestContext.WriteLine(fixture.Sources)); var viewObservable = host.GetWhenChangedObservable(_ => TestContext.WriteLine(fixture.Sources)); object viewModelValue = null; object viewValue = null; viewModelObservable.Subscribe(x => viewModelValue = x); viewObservable.Subscribe(x => viewValue = x); host.Value = "test"; host.ViewModel.Value.Should().Be("test"); host.Value = "Test2"; host.ViewModel.Value.Should().Be("Test2"); host.ViewModel.Value = "Test3"; host.Value.Should().Be("Test3"); }
public Task NoDiagnostics_Namespaces(string hostTypeNamespace, string hostPropertyTypeNamespace) { var hostPropertyTypeInfo = new EmptyClassBuilder() .WithClassAccess(Accessibility.Public) .WithNamespace(hostPropertyTypeNamespace); var hostTypeInfo = new WhenChangedHostBuilder() .WithClassName("HostClass") .WithClassAccess(Accessibility.Public) .WithPropertyType(hostPropertyTypeInfo) .WithPropertyAccess(Accessibility.Public) .WithNamespace(hostTypeNamespace); return(AssertTestCase_MultiExpression(hostTypeInfo, InvocationKind.MemberAccess, ("HostPropertyTypeInfo.cs", hostPropertyTypeInfo.BuildRoot()))); }
public void RXM006_ExplicitInvocationInvolvingNonAccessibleProperty(Accessibility propertyAccess) { var hostPropertyTypeInfo = new EmptyClassBuilder() .WithClassAccess(Accessibility.Public); var source = new WhenChangedHostBuilder() .WithClassName("HostClass") .WithInvocation(InvocationKind.Explicit, x => x.Value) .WithClassAccess(Accessibility.Public) .WithPropertyType(hostPropertyTypeInfo) .WithPropertyAccess(propertyAccess) .BuildRoot(); source += hostPropertyTypeInfo.BuildRoot(); AssertDiagnostic(source, DiagnosticWarnings.UnableToGenerateExtension); }
public Task NoDiagnostics_AccessModifierCombinations(Accessibility hostContainerTypeAccess, Accessibility hostTypeAccess, Accessibility propertyTypeAccess, Accessibility propertyAccess) { var hostPropertyTypeInfo = new EmptyClassBuilder() .WithClassAccess(propertyTypeAccess); var hostTypeInfo = new WhenChangedHostBuilder() .WithClassName("HostClass") .WithClassAccess(hostTypeAccess) .AddNestedClass(hostPropertyTypeInfo) .WithPropertyType(hostPropertyTypeInfo) .WithPropertyAccess(propertyAccess); var hostContainerTypeInfo = new EmptyClassBuilder() .WithClassName("HostContainer") .WithClassAccess(hostContainerTypeAccess) .AddNestedClass(hostTypeInfo); return(AssertTestCase_MultiExpression(hostTypeInfo, InvocationKind.MemberAccess)); }
public async Task NoDiagnostics_PrivateHostPropertyTypeAndInternalOutputType() { var hostPropertyTypeInfo = new EmptyClassBuilder() .WithClassAccess(Accessibility.Private); var customType = new EmptyClassBuilder() .WithClassName("Output") .WithClassAccess(Accessibility.Internal); var hostTypeInfo = WhenChangedHostBuilder.Changing() .WithClassName("HostClass") .WithInvocation(InvocationKind.MemberAccess, x => x.Child, x => x.Value, "(a, b) => b != null ? new HostContainer.Output() : null") .WithClassAccess(Accessibility.Protected) .AddNestedClass(hostPropertyTypeInfo) .WithPropertyType(hostPropertyTypeInfo) .WithPropertyAccess(Accessibility.Private); var hostContainerTypeInfo = new EmptyClassBuilder() .WithClassName("HostContainer") .WithClassAccess(Accessibility.Public) .AddNestedClass(hostTypeInfo) .AddNestedClass(customType); var fixture = await WhenChangedFixture.Create(hostTypeInfo, x => TestContext.WriteLine(x)).ConfigureAwait(false); fixture.RunGenerator(out var compilationDiagnostics, out var generatorDiagnostics); generatorDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); compilationDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); var host = fixture.NewHostInstance(); host.Value = fixture.NewValuePropertyInstance(); var observable = host.GetWhenChangedObservable(_ => TestContext.WriteLine(fixture.Sources)); object emittedValue = null; observable.Subscribe(x => emittedValue = x); // TODO: Better series of checks. Currently can't compare values because of reference // equality and we don't have access to the instance that the conversionFunc creates. emittedValue.Should().NotBeNull(); host.Value = null; emittedValue.Should().NotBeNull(); host.Value = fixture.NewValuePropertyInstance(); emittedValue.Should().BeNull(); }
public async Task NoDiagnostics_InstanceReceiverKind(InvocationKind invocationKind) { var receiverPropertyTypeInfo = new EmptyClassBuilder() .WithClassAccess(Accessibility.Public); var externalReceiverTypeInfo = new WhenChangedHostBuilder() .WithClassName("ReactiveType") .WithClassAccess(Accessibility.Public) .WithPropertyType(receiverPropertyTypeInfo) .WithPropertyAccess(Accessibility.Public) .WithInvocation("null"); var hostTypeInfo = new WhenChangedHostBuilder() .WithClassName("HostClass") .WithClassAccess(Accessibility.Public) .WithInvocation(invocationKind, x => x.Value, externalReceiverTypeInfo); var fixture = await WhenChangedFixture.Create(hostTypeInfo, externalReceiverTypeInfo, x => TestContext.WriteLine(x), ("ReceiverPropertyTypeInfo.cs", receiverPropertyTypeInfo.BuildRoot())).ConfigureAwait(false); fixture.RunGenerator(out var compilationDiagnostics, out var generatorDiagnostics); generatorDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); compilationDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); var host = fixture.NewHostInstance(); var receiver = fixture.NewReceiverInstance(); host.Receiver = receiver; receiver.Value = fixture.NewValuePropertyInstance(); var observable = host.GetWhenChangedObservable(_ => TestContext.WriteLine(fixture.Sources)); object value = null; observable.Subscribe(x => value = x); receiver.Value.Should().Equals(value); receiver.Value = fixture.NewValuePropertyInstance(); receiver.Value.Should().Equals(value); receiver.Value = null; receiver.Value.Should().Equals(value); }
private async Task AssertTestCase_SingleExpression(WhenChangedHostBuilder hostTypeInfo, BaseUserSourceBuilder hostPropertyTypeInfo, bool typesHaveSameRoot) { hostTypeInfo.WithInvocation(InvocationKind.MemberAccess, x => x.Value); var propertyTypeSource = typesHaveSameRoot ? string.Empty : hostPropertyTypeInfo.BuildRoot(); var fixture = await WhenChangedFixture.Create(hostTypeInfo, x => TestContext.WriteLine(x), ("PropertyTypeSource.cs", propertyTypeSource)).ConfigureAwait(false); fixture.RunGenerator(out var compilationDiagnostics, out var generatorDiagnostics); generatorDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); compilationDiagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Should().BeEmpty(); var host = fixture.NewHostInstance(); host.Value = fixture.NewValuePropertyInstance(); var observable = host.GetWhenChangedObservable(_ => TestContext.WriteLine(fixture.Sources)); object value = null; observable.Subscribe(x => value = x); host.Value.Should().Be(value); host.Value = fixture.NewValuePropertyInstance(); host.Value.Should().Be(value); host.Value = null; host.Value.Should().Be(value); }
private async Task AssertTestCase_MultiExpression(WhenChangedHostBuilder hostTypeInfo, InvocationKind invocationKind, params (string FileName, string Source)[] extraSources)