Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Fix binding validation (#41)
Browse files Browse the repository at this point in the history
* Fixed binding validation
  • Loading branch information
klemmchr authored Dec 5, 2020
1 parent 49d9c7f commit fa9616a
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 45 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
on: [push, pull_request]
on:
push:
branches:
- master
pull_request:
branches:
- master

name: Build

Expand All @@ -14,7 +20,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@master
with:
dotnet-version: '3.1.300'
dotnet-version: '5.0.x'

- name: Build
run: dotnet build --configuration Release src
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@master
with:
dotnet-version: '3.1.300'
dotnet-version: '5.0.x'

- name: Build
run: dotnet build --configuration Release src
Expand Down
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,3 @@ This sample tries to incorporate a ports and adapters architectural approach and

As an example the weather forecast view model just references the interface of the service that is responsible to gather data. For Blazor serverside, it directly populates it, for Blazor serverside it gathers them from an api. The advantages of such patterns will especially get interesting when Blazor Native and Blazor Embedded will be available.

## Known projects
These projects are know to use `MvvmBlazor`. They can be used as a reference for different implementation scenarios that go beyond the samples.

- [BlazorPlanningPoker](https://github.com/brandon-james105/BlazorPlanningPoker)

If you want to see your project here, just create an issue.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>7.3</LangVersion>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
27 changes: 8 additions & 19 deletions src/MvvmBlazor.Tests/Components/MvvmComponentBaseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,24 +112,21 @@ public void AddBinding_Throws_WhenBindingMemberIsAField()
var wemf = new Mock<IWeakEventManagerFactory>();
var wem = new Mock<IWeakEventManager>();
var bindingFactory = new Mock<IBindingFactory>();
var binding = new Mock<IBinding>();
serviceProvider.Setup(x => x.GetService(typeof(IWeakEventManagerFactory))).Returns(wemf.Object)
.Verifiable();
serviceProvider.Setup(x => x.GetService(typeof(IBindingFactory))).Returns(bindingFactory.Object)
.Verifiable();
wemf.Setup(x => x.Create()).Returns(wem.Object).Verifiable();
bindingFactory.Setup(x => x.Create(It.IsAny<INotifyPropertyChanged>(), It.IsAny<PropertyInfo>(),
It.IsAny<IWeakEventManager>())).Returns(binding.Object).Verifiable();

var component = new TestComponent(serviceProvider.Object);
Should.Throw<BindingException>(() => component.AddBinding(viewModel, x => x._testProperty));

serviceProvider.Verify();
wemf.Verify();
serviceProvider.VerifyNoOtherCalls();

wemf.VerifyNoOtherCalls();
serviceProvider.VerifyNoOtherCalls();
bindingFactory.VerifyNoOtherCalls();
binding.VerifyNoOtherCalls();
wem.VerifyNoOtherCalls();
}

Expand All @@ -141,24 +138,21 @@ public void AddBinding_Throws_WhenBindingMemberIsAMethod()
var wemf = new Mock<IWeakEventManagerFactory>();
var wem = new Mock<IWeakEventManager>();
var bindingFactory = new Mock<IBindingFactory>();
var binding = new Mock<IBinding>();
serviceProvider.Setup(x => x.GetService(typeof(IWeakEventManagerFactory))).Returns(wemf.Object)
.Verifiable();
serviceProvider.Setup(x => x.GetService(typeof(IBindingFactory))).Returns(bindingFactory.Object)
.Verifiable();
wemf.Setup(x => x.Create()).Returns(wem.Object).Verifiable();
bindingFactory.Setup(x => x.Create(It.IsAny<INotifyPropertyChanged>(), It.IsAny<PropertyInfo>(),
It.IsAny<IWeakEventManager>())).Returns(binding.Object).Verifiable();

var component = new TestComponent(serviceProvider.Object);
Should.Throw<BindingException>(() => component.AddBinding(viewModel, x => x.ShouldRender()));

serviceProvider.Verify();
wemf.Verify();

serviceProvider.VerifyNoOtherCalls();
wemf.VerifyNoOtherCalls();
bindingFactory.VerifyNoOtherCalls();
binding.VerifyNoOtherCalls();
wem.VerifyNoOtherCalls();
}

Expand All @@ -170,54 +164,47 @@ public void AddBinding_Throws_WhenPropertyExpressionIsNull()
var wemf = new Mock<IWeakEventManagerFactory>();
var wem = new Mock<IWeakEventManager>();
var bindingFactory = new Mock<IBindingFactory>();
var binding = new Mock<IBinding>();
serviceProvider.Setup(x => x.GetService(typeof(IWeakEventManagerFactory))).Returns(wemf.Object)
.Verifiable();
serviceProvider.Setup(x => x.GetService(typeof(IBindingFactory))).Returns(bindingFactory.Object)
.Verifiable();
wemf.Setup(x => x.Create()).Returns(wem.Object).Verifiable();
bindingFactory.Setup(x => x.Create(It.IsAny<INotifyPropertyChanged>(), It.IsAny<PropertyInfo>(),
It.IsAny<IWeakEventManager>())).Returns(binding.Object).Verifiable();

var component = new TestComponent(serviceProvider.Object);
Should.Throw<BindingException>(() => component.AddBinding<TestViewModel, string>(viewModel, null));

serviceProvider.Verify();
wemf.Verify();

serviceProvider.VerifyNoOtherCalls();
wemf.VerifyNoOtherCalls();
bindingFactory.VerifyNoOtherCalls();
binding.VerifyNoOtherCalls();
wem.VerifyNoOtherCalls();
}

[Fact]
public void AddBinding_Throws_WhenViewModelIsNull()
{
var viewModel = new TestViewModel();
var serviceProvider = new Mock<IServiceProvider>();
var wemf = new Mock<IWeakEventManagerFactory>();
var wem = new Mock<IWeakEventManager>();
var bindingFactory = new Mock<IBindingFactory>();
var binding = new Mock<IBinding>();
serviceProvider.Setup(x => x.GetService(typeof(IWeakEventManagerFactory))).Returns(wemf.Object)
.Verifiable();
serviceProvider.Setup(x => x.GetService(typeof(IBindingFactory))).Returns(bindingFactory.Object)
.Verifiable();
wemf.Setup(x => x.Create()).Returns(wem.Object).Verifiable();
bindingFactory.Setup(x => x.Create(It.IsAny<INotifyPropertyChanged>(), It.IsAny<PropertyInfo>(),
It.IsAny<IWeakEventManager>())).Returns(binding.Object).Verifiable();

var component = new TestComponent(serviceProvider.Object);
Should.Throw<BindingException>(() =>
component.AddBinding<TestViewModel, string>(null, x => x.TestProperty));
component.AddBinding<TestViewModel, string>(null!, x => x.TestProperty));

serviceProvider.Verify();
wemf.Verify();

serviceProvider.VerifyNoOtherCalls();
wemf.VerifyNoOtherCalls();
bindingFactory.VerifyNoOtherCalls();
binding.VerifyNoOtherCalls();
wem.VerifyNoOtherCalls();
}

Expand Down Expand Up @@ -264,6 +251,8 @@ public void Binding_BindingValueChanged_GetsInvoked()
It.IsAny<IWeakEventManager>())).Returns(binding.Object).Verifiable();
binding.Setup(x => x.GetValue()).Returns("Test").Verifiable();
binding.Setup(x => x.Initialize()).Verifiable();
binding.SetupAdd(m => m.BindingValueChanged += It.IsAny<EventHandler>()).Verifiable();


var bindingChangedInvoked = false;
var component = new TestComponent(serviceProvider.Object)
Expand Down
12 changes: 6 additions & 6 deletions src/MvvmBlazor.Tests/MvvmBlazor.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Moq" Version="4.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="Moq" Version="4.15.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="Shouldly" Version="4.0.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
10 changes: 5 additions & 5 deletions src/MvvmBlazor/Components/MvvmComponentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ protected MvvmComponentBase()

private void InitializeDependencies()
{
_weakEventManagerFactory ??= ServiceProvider.GetRequiredService<IWeakEventManagerFactory>();
_bindingFactory ??= ServiceProvider.GetRequiredService<IBindingFactory>();
_weakEventManager ??= _weakEventManagerFactory.Create();
_weakEventManagerFactory = ServiceProvider.GetRequiredService<IWeakEventManagerFactory>();
_bindingFactory = ServiceProvider.GetRequiredService<IBindingFactory>();
_weakEventManager = _weakEventManagerFactory.Create();
}

protected internal TValue Bind<TViewModel, TValue>(TViewModel viewModel,
Expand Down Expand Up @@ -87,8 +87,8 @@ protected static PropertyInfo ValidateAndResolveBindingContext<TViewModel, TValu

if (!(m.Member is PropertyInfo p))
throw new BindingException("Binding member needs to be a property");

if (p.DeclaringType != viewModel.GetType())
if (typeof(TViewModel).GetProperty(p.Name) is null)
throw new BindingException($"Cannot find property {p.Name} in type {viewModel.GetType().FullName}");

return p;
Expand Down
6 changes: 3 additions & 3 deletions src/MvvmBlazor/MvvmBlazor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="IDisposableAnalyzers" Version="3.3.9">
<PackageReference Include="IDisposableAnalyzers" Version="3.4.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.6" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>

Expand Down

0 comments on commit fa9616a

Please sign in to comment.