Skip to content

Commit

Permalink
housekeeping: add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
glennawatson committed Feb 26, 2019
1 parent 77fc15a commit 14d7bb3
Show file tree
Hide file tree
Showing 9 changed files with 518 additions and 45 deletions.
3 changes: 2 additions & 1 deletion build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ var packageWhitelist = new[]
MakeAbsolute(File("./src/ReactiveUI.Validation/ReactiveUI.Validation.csproj")),
};

var packageTestWhitelist = new FilePath[]
var packageTestWhitelist = new[]
{
MakeAbsolute(File("./src/ReactiveUI.Validation.Tests/ReactiveUI.Validation.Tests.csproj")),
};

BuildParameters.SetParameters(context: Context,
Expand Down
171 changes: 171 additions & 0 deletions src/ApiGeneratorGlobalSuppressions.cs

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions src/ReactiveUI.Validation.Tests/ModelObservableTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI.Validation.Components;
using Xunit;

namespace ReactiveUI.Validation.Tests
{
public class ModelObservableTests
{
[Fact]
public void InitialValidStateIsCorrect()
{
var model = new TestViewModel() {Name = "name", Name2 = "name2"};

Subject<bool> validState = new Subject<bool>();

var v = new ModelObservableValidation<TestViewModel>(model,(m) => validState.StartWith(true),(m,s) => "broken") ;

Assert.True(v.IsValid);
}

[Fact]
public void ObservableToInvalid()
{
var model = new TestViewModel() { Name = "name", Name2 = "name2" };

ReplaySubject<bool> validState = new ReplaySubject<bool>(1);

var v = new ModelObservableValidation<TestViewModel>(model, (m) => validState, (m,s) => "broken");

validState.OnNext(false);
validState.OnNext(true);
validState.OnNext(false);

Assert.False(v.IsValid);
Assert.Equal("broken",v.Text.ToSingleLine());
}
}
}
165 changes: 165 additions & 0 deletions src/ReactiveUI.Validation.Tests/PropertyObservableTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI.Validation.Comparators;
using ReactiveUI.Validation.Components;
using ReactiveUI.Validation.States;
using Xunit;

namespace ReactiveUI.Validation.Tests
{
public class PropertyValidationTests
{
/// <summary>
/// Default state is true.
/// </summary>
[Fact]
public void ValidModelDefaultState()
{
var model = CreateDefaultValidModel();

var validation = new BasePropertyValidation<TestViewModel, string>(model,
vm => vm.Name,
(n) => !string.IsNullOrEmpty(n),"broken");

Assert.True(validation.IsValid);
Assert.True(string.IsNullOrEmpty(validation.Text.ToSingleLine()));
}

[Fact]
public void StateTransitionsWhenValidityChangesTest()
{
var model = new TestViewModel();

var testValue = "test";

var validation = new BasePropertyValidation<TestViewModel, string>(model,
vm => vm.Name,
(n) => n != null && n.Length >= testValue.Length, "broken");

bool? lastVal = null;

var obs = validation.ValidationStatusChange.Subscribe(v => lastVal = v.IsValid);

Assert.False(validation.IsValid);
Assert.False(lastVal);
Assert.True(lastVal.HasValue);

model.Name = testValue+"-"+testValue;

Assert.True(validation.IsValid);
Assert.True(lastVal);
}

[Fact]
public void PropertyContentsProvidedToMessageTest()
{
var model = new TestViewModel();

var testValue = "bongo";

var validation = new BasePropertyValidation<TestViewModel, string>(model,
vm => vm.Name,
(n) => n != null && n.Length > testValue.Length, (v) => $"The value '{v}' is incorrect");

model.Name = testValue;

var i = validation.IsValid;

Assert.Equal("The value 'bongo' is incorrect", validation.Text.ToSingleLine());
}



/// <summary>
/// Verify that validation message updates are correctly propogated.
/// </summary>
[Fact]
public void MessageUpdatedWhenPropertyChanged()
{
var model = new TestViewModel();

var testRoot = "bon";
var testValue = testRoot+"go";


var validation = new BasePropertyValidation<TestViewModel, string>(model,
vm => vm.Name,
(n) => n != null && n.Length > testValue.Length, (v) => $"The value '{v}' is incorrect");

model.Name = testValue;

var i = validation.IsValid;

List<ValidationState> changes = new List<ValidationState>();

validation.ValidationStatusChange.Subscribe(v => changes.Add(v));

Assert.Equal("The value 'bongo' is incorrect", validation.Text.ToSingleLine());
Assert.Equal(1,changes.Count);
Assert.Equal(new ValidationState(false, "The value 'bongo' is incorrect", validation), changes[0], new ValidationStateComparer());

model.Name = testRoot;

Assert.Equal("The value 'bon' is incorrect", validation.Text.ToSingleLine());
Assert.Equal(2, changes.Count);
Assert.Equal(new ValidationState(false, "The value 'bon' is incorrect",validation),changes[1],new ValidationStateComparer() );
}

[Fact]
public void DualStateMessageTest()
{
var testRoot = "bon";
var testValue = testRoot + "go";

var model = new TestViewModel() {Name = testValue};


var validation = new BasePropertyValidation<TestViewModel, string>(model,
vm => vm.Name,
(n) => n != null && n.Length > testRoot.Length, (p,v) => v ? "cool" : $"The value '{p}' is incorrect");

Assert.Equal("cool",validation.Text.ToSingleLine());

model.Name = testRoot;

Assert.Equal("The value 'bon' is incorrect", validation.Text.ToSingleLine());

}


private TestViewModel CreateDefaultValidModel()
{
return new TestViewModel() {Name = "name"};

}
}

public class TestViewModel : ReactiveObject
{
private string _name;

public string Name
{
get { return _name; }
set { this.RaiseAndSetIfChanged(ref _name, value); }
}

private string _name2;

public string Name2
{
get { return _name2; }
set { this.RaiseAndSetIfChanged(ref _name2, value); }
}

public List<string> GetIt { get; set; } = new List<string>();

public string Go()
{
return "here";
}
}
}
18 changes: 18 additions & 0 deletions src/ReactiveUI.Validation.Tests/ReactiveUI.Validation.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="MSBuild.Sdk.Extras">

<PropertyGroup>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net472</TargetFrameworks>
<NoWarn>$(NoWarn);1591;CA1707;SA1633</NoWarn>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\ReactiveUI.Validation\ReactiveUI.Validation.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="xunit.runner.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
92 changes: 92 additions & 0 deletions src/ReactiveUI.Validation.Tests/ValidationContextTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI.Validation.Components;
using ReactiveUI.Validation.Contexts;
using Xunit;

namespace ReactiveUI.Validation.Tests
{
public class ValidationContextTests
{
[Fact]
public void EmptyValidationContextIsValid()
{
var vc = new ValidationContext();

Assert.True(vc.IsValid);
Assert.Equal(0,vc.Text.Count);
}

[Fact]
public void CanAddValidationComponentsTest()
{
var vc = new ValidationContext();

var validName = "valid";
var invalidName = String.Empty;

var vm = new TestViewModel() {Name = "valid"};

var v1 = new BasePropertyValidation<TestViewModel, string>(vm, v => v.Name,
(s) => !string.IsNullOrEmpty(s), s => $"{s} isn't valid");

vc.Add(v1);

Assert.True(vc.IsValid);

vm.Name = invalidName;

Assert.False(v1.IsValid);
Assert.False(vc.IsValid);

Assert.Equal(1,vc.Text.Count);
}

[Fact]
public void TwoValidationComponentsCorrectlyResultInContextTest()
{
var vc = new ValidationContext();

var validName = "valid";
var invalidName = String.Empty;

var vm = new TestViewModel() { Name = validName,Name2=validName };

var v1 = new BasePropertyValidation<TestViewModel, string>(vm, v => v.Name,
(s) => !string.IsNullOrEmpty(s), s => $"Name {s} isn't valid");

var v2 = new BasePropertyValidation<TestViewModel, string>(vm, v => v.Name2,
(s) => !string.IsNullOrEmpty(s), s => $"Name 2 {s} isn't valid");

vc.Add(v1);
vc.Add(v2);

Assert.True(vc.IsValid);
Assert.Equal(0, vc.Text.Count);

vm.Name = invalidName;

Assert.False(vc.IsValid);

Assert.Equal(1, vc.Text.Count);
Assert.Equal("Name " + invalidName + " isn't valid", vc.Text[0]);



vm.Name2 = invalidName;
Assert.False(vc.IsValid);
Assert.Equal(2, vc.Text.Count);
Assert.Equal("Name "+invalidName+" isn't valid",vc.Text[0]);
Assert.Equal("Name 2 " + invalidName + " isn't valid", vc.Text[1]);

vm.Name = validName;
vm.Name2 = validName;

Assert.True(vc.IsValid);
Assert.Equal(0,vc.Text.Count);
}
}
}
3 changes: 3 additions & 0 deletions src/ReactiveUI.Validation.Tests/xunit.runner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"shadowCopy": false
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Validation", "ReactiveUI.Validation.csproj", "{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Validation", "ReactiveUI.Validation\ReactiveUI.Validation.csproj", "{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Validation.Tests", "ReactiveUI.Validation.Tests\ReactiveUI.Validation.Tests.csproj", "{892D51D9-7A3F-4E66-A871-082A63D9BE05}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B62AABD0-22A4-470D-B6EB-F6B3EAE668DE}.Release|Any CPU.Build.0 = Release|Any CPU
{892D51D9-7A3F-4E66-A871-082A63D9BE05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{892D51D9-7A3F-4E66-A871-082A63D9BE05}.Debug|Any CPU.Build.0 = Debug|Any CPU
{892D51D9-7A3F-4E66-A871-082A63D9BE05}.Release|Any CPU.ActiveCfg = Release|Any CPU
{892D51D9-7A3F-4E66-A871-082A63D9BE05}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
Loading

0 comments on commit 14d7bb3

Please sign in to comment.