Merge branch 'master' into shana/cloning-fixes

Conflicts:
	src/UnitTests/GitHub.App/Controllers/UIControllerTests.cs
This commit is contained in:
Andreia Gaita 2015-03-27 00:45:37 +01:00
Родитель e87e3d0275 e3cc0ac1ef
Коммит ec33bbea29
15 изменённых файлов: 400 добавлений и 19 удалений

Просмотреть файл

@ -37,6 +37,8 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<CodeAnalysisIgnoreGeneratedCode>true</CodeAnalysisIgnoreGeneratedCode>
<OutputPath>..\..\build\$(Configuration)\</OutputPath>
<CreateVsixContainer>True</CreateVsixContainer>
<DeployExtension>True</DeployExtension>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>

Просмотреть файл

@ -46,10 +46,10 @@ public class UIControllerTests
return factory;
}
[Fact]
[STAFact]
public void ShowingCloneDialogWithoutBeingLoggedInShowsLoginDialog()
{
var provider = Substitutes.ServiceProvider;
var provider = Substitutes.GetFullyMockedServiceProvider();
var hosts = provider.GetRepositoryHosts();
var factory = SetupFactory(provider);
@ -68,10 +68,10 @@ public class UIControllerTests
}
}
[Fact]
[STAFact]
public void ShowingCloneDialogWhenLoggedInShowsCloneDialog()
{
var provider = Substitutes.ServiceProvider;
var provider = Substitutes.GetFullyMockedServiceProvider();
var hosts = provider.GetRepositoryHosts();
var factory = SetupFactory(provider);
hosts.IsLoggedInToAnyHost.Returns(true);

Просмотреть файл

@ -4,13 +4,12 @@ using System.Windows;
using System.Windows.Controls;
using GitHub.UI;
using Xunit;
using Xunit.Extensions;
public class TwoFactorInputTests
{
public class TheTextProperty
{
[Fact]
[STAFact]
public void SetsTextBoxesToIndividualCharacters()
{
var twoFactorInput = new TwoFactorInput();
@ -27,7 +26,7 @@ public class TwoFactorInputTests
Assert.Equal("5", textBoxes[5].Text);
}
[Fact]
[STAFact]
public void IgnoresNonDigitCharacters()
{
var twoFactorInput = new TwoFactorInput();
@ -44,7 +43,7 @@ public class TwoFactorInputTests
Assert.Equal("5", textBoxes[5].Text);
}
[Fact]
[STAFact]
public void HandlesNotEnoughCharacters()
{
var twoFactorInput = new TwoFactorInput();
@ -61,7 +60,7 @@ public class TwoFactorInputTests
Assert.Equal("", textBoxes[5].Text);
}
[Theory]
[STATheory]
[InlineData(null, null)]
[InlineData("", "")]
[InlineData("xxxx", "")]

Просмотреть файл

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\xunit.runner.visualstudio.0.99.9-build1021\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\..\packages\xunit.runner.visualstudio.0.99.9-build1021\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -12,7 +13,7 @@
<AssemblyName>UnitTests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>ae156ccd</NuGetPackageImportStamp>
<NuGetPackageImportStamp>5a9d4ee1</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -90,11 +91,20 @@
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="xunit">
<HintPath>..\..\packages\xunit.1.9.2\lib\net20\xunit.dll</HintPath>
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.extensions">
<HintPath>..\..\packages\xunit.extensions.1.9.2\lib\net20\xunit.extensions.dll</HintPath>
<Reference Include="xunit.assert, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\xunit.assert.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.core, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\xunit.extensibility.core.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.extensibility.execution.2.0.0\lib\net45\xunit.execution.desktop.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@ -113,6 +123,16 @@
<Compile Include="Substitutes.cs" />
<Compile Include="TestDoubles\FakeMenuCommandService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="XUnit\ConditionalFactAttribute.cs" />
<Compile Include="XUnit\DelayedMessageBus.cs" />
<Compile Include="XUnit\RetryFactAttribute.cs" />
<Compile Include="XUnit\RetryFactDiscoverer.cs" />
<Compile Include="XUnit\RetryTestCase.cs" />
<Compile Include="XUnit\STAFactAttribute.cs" />
<Compile Include="XUnit\STAFactDiscoverer.cs" />
<Compile Include="XUnit\STATestCase.cs" />
<Compile Include="XUnit\STATheoryAttribute.cs" />
<Compile Include="XUnit\STATheoryDiscoverer.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\submodules\octokit.net\Octokit.Reactive\Octokit.Reactive.csproj">
@ -187,7 +207,8 @@
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.0.99.9-build1021\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.0.99.9-build1021\build\net20\xunit.runner.visualstudio.props'))" />
<Error Condition="!Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props'))" />
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

Просмотреть файл

@ -0,0 +1,55 @@
using System;
using Xunit;
namespace GitHub.Tests.Helpers
{
public class ConditionalFactAttribute : FactAttribute
{
public bool RunOnJanky { get; set; }
public override string Skip
{
get
{
if (!RunOnJanky && IsJanky())
{
return Message ?? "This test may not be run on Janky";
}
return base.Skip;
}
set { base.Skip = value; }
}
public string Message { get; set; }
static bool IsJanky()
{
return !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("JANKY_SHA1"));
}
}
public class ConditionalTheoryAttribute : TheoryAttribute
{
public bool RunOnJanky { get; set; }
public override string Skip
{
get
{
if (!RunOnJanky && IsJanky())
{
return Message ?? "This test may not be run on Janky";
}
return base.Skip;
}
set { base.Skip = value; }
}
public string Message { get; set; }
static bool IsJanky()
{
return !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("JANKY_SHA1"));
}
}
}

Просмотреть файл

@ -0,0 +1,34 @@
using System.Collections.Generic;
using Xunit.Abstractions;
using Xunit.Sdk;
/// <summary>
/// Used to capture messages to potentially be forwarded later. Messages are forwarded by
/// disposing of the message bus.
/// </summary>
public class DelayedMessageBus : IMessageBus
{
readonly IMessageBus innerBus;
readonly List<IMessageSinkMessage> messages = new List<IMessageSinkMessage>();
public DelayedMessageBus(IMessageBus innerBus)
{
this.innerBus = innerBus;
}
public bool QueueMessage(IMessageSinkMessage message)
{
lock (messages)
messages.Add(message);
// No way to ask the inner bus if they want to cancel without sending them the message, so
// we just go ahead and continue always.
return true;
}
public void Dispose()
{
foreach (var message in messages)
innerBus.QueueMessage(message);
}
}

Просмотреть файл

@ -0,0 +1,15 @@
using Xunit;
using Xunit.Sdk;
/// <summary>
/// Works just like [Fact] except that failures are retried (by default, 3 times).
/// </summary>
[XunitTestCaseDiscoverer("RetryFactDiscoverer", "GitHub.Tests.Utils")]
public class RetryFactAttribute : FactAttribute
{
/// <summary>
/// Number of retries allowed for a failed test. If unset (or set less than 1), will
/// default to 3 attempts.
/// </summary>
public int MaxRetries { get; set; }
}

Просмотреть файл

@ -0,0 +1,23 @@
using System.Collections.Generic;
using Xunit.Abstractions;
using Xunit.Sdk;
public class RetryFactDiscoverer : IXunitTestCaseDiscoverer
{
readonly IMessageSink diagnosticMessageSink;
public RetryFactDiscoverer(IMessageSink diagnosticMessageSink)
{
this.diagnosticMessageSink = diagnosticMessageSink;
}
public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
{
var maxRetries = factAttribute.GetNamedArgument<int>("MaxRetries");
if (maxRetries < 1)
maxRetries = 3;
yield return new RetryTestCase(diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod, maxRetries);
}
}

Просмотреть файл

@ -0,0 +1,68 @@
using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using Xunit.Abstractions;
using Xunit.Sdk;
[Serializable]
public class RetryTestCase : XunitTestCase
{
int maxRetries;
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Called by the de-serializer", true)]
public RetryTestCase()
{
}
public RetryTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay testMethodDisplay, ITestMethod testMethod, int maxRetries)
: base(diagnosticMessageSink, testMethodDisplay, testMethod, testMethodArguments: null)
{
this.maxRetries = maxRetries;
}
// This method is called by the xUnit test framework classes to run the test case. We will do the
// loop here, forwarding on to the implementation in XunitTestCase to do the heavy lifting. We will
// continue to re-run the test until the aggregator has an error (meaning that some internal error
// condition happened), or the test runs without failure, or we've hit the maximum number of tries.
public override async Task<RunSummary> RunAsync(IMessageSink diagnosticMessageSink,
IMessageBus messageBus,
object[] constructorArguments,
ExceptionAggregator aggregator,
CancellationTokenSource cancellationTokenSource)
{
var runCount = 0;
while (true)
{
// This is really the only tricky bit: we need to capture and delay messages (since those will
// contain run status) until we know we've decided to accept the final result;
var delayedMessageBus = new DelayedMessageBus(messageBus);
var summary = await base.RunAsync(diagnosticMessageSink, delayedMessageBus, constructorArguments, aggregator, cancellationTokenSource);
if (aggregator.HasExceptions || summary.Failed == 0 || ++runCount >= maxRetries)
{
delayedMessageBus.Dispose(); // Sends all the delayed messages
return summary;
}
diagnosticMessageSink.OnMessage(new DiagnosticMessage("Execution of '{0}' failed (attempt #{1}), retrying...", DisplayName, runCount));
}
}
public override void Serialize(IXunitSerializationInfo data)
{
base.Serialize(data);
data.AddValue("MaxRetries", maxRetries);
}
public override void Deserialize(IXunitSerializationInfo data)
{
base.Deserialize(data);
maxRetries = data.GetValue<int>("MaxRetries");
}
}

Просмотреть файл

@ -0,0 +1,9 @@
using System;
using Xunit;
using Xunit.Sdk;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("STAFactDiscoverer", "UnitTests")]
public class STAFactAttribute : FactAttribute
{
}

Просмотреть файл

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Linq;
using Xunit.Abstractions;
using Xunit.Sdk;
public class STAFactDiscoverer : IXunitTestCaseDiscoverer
{
readonly FactDiscoverer factDiscoverer;
public STAFactDiscoverer(IMessageSink diagnosticMessageSink)
{
factDiscoverer = new FactDiscoverer(diagnosticMessageSink);
}
public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
{
return factDiscoverer.Discover(discoveryOptions, testMethod, factAttribute)
.Select(testCase => new STATestCase(testCase));
}
}

Просмотреть файл

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Xunit.Abstractions;
using Xunit.Sdk;
/// <summary>
/// Wraps test cases for FactAttribute and TheoryAttribute so the test case runs in the STA Thread
/// </summary>
[DebuggerDisplay(@"\{ class = {TestMethod.TestClass.Class.Name}, method = {TestMethod.Method.Name}, display = {DisplayName}, skip = {SkipReason} \}")]
public class STATestCase : LongLivedMarshalByRefObject, IXunitTestCase
{
IXunitTestCase testCase;
public STATestCase(IXunitTestCase testCase)
{
this.testCase = testCase;
}
/// <summary/>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Called by the de-serializer", error: true)]
public STATestCase()
{
}
public IMethodInfo Method
{
get { return testCase.Method; }
}
public Task<RunSummary> RunAsync(IMessageSink diagnosticMessageSink, IMessageBus messageBus, object[] constructorArguments,
ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource)
{
var tcs = new TaskCompletionSource<RunSummary>();
var thread = new Thread(() =>
{
try
{
var testCaseTask = testCase.RunAsync(diagnosticMessageSink, messageBus, constructorArguments, aggregator,
cancellationTokenSource);
tcs.SetResult(testCaseTask.Result);
}
catch (Exception e)
{
tcs.SetException(e);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return tcs.Task;
}
public string DisplayName
{
get { return testCase.DisplayName; }
}
public string SkipReason
{
get { return testCase.SkipReason; }
}
public ISourceInformation SourceInformation
{
get { return testCase.SourceInformation; }
set { testCase.SourceInformation = value; }
}
public ITestMethod TestMethod
{
get { return testCase.TestMethod; }
}
public object[] TestMethodArguments
{
get { return testCase.TestMethodArguments; }
}
public Dictionary<string, List<string>> Traits
{
get { return testCase.Traits; }
}
public string UniqueID
{
get { return testCase.UniqueID; }
}
public void Deserialize(IXunitSerializationInfo info)
{
testCase = info.GetValue<IXunitTestCase>("InnerTestCase");
}
public void Serialize(IXunitSerializationInfo info)
{
info.AddValue("InnerTestCase", testCase);
}
}

Просмотреть файл

@ -0,0 +1,9 @@
using System;
using Xunit;
using Xunit.Sdk;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("STATheoryDiscoverer", "UnitTests")]
public class STATheoryAttribute : TheoryAttribute
{
}

Просмотреть файл

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Linq;
using Xunit.Abstractions;
using Xunit.Sdk;
public class STATheoryDiscoverer : IXunitTestCaseDiscoverer
{
readonly TheoryDiscoverer theoryDiscoverer;
public STATheoryDiscoverer(IMessageSink diagnosticMessageSink)
{
theoryDiscoverer = new TheoryDiscoverer(diagnosticMessageSink);
}
public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
{
return theoryDiscoverer.Discover(discoveryOptions, testMethod, factAttribute)
.Select(testCase => new STATestCase(testCase));
}
}

Просмотреть файл

@ -7,7 +7,11 @@
<package id="Rx-Main" version="2.2.5" targetFramework="net45" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net45" />
<package id="Rx-XAML" version="2.2.5" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" />
<package id="xunit.extensions" version="1.9.2" targetFramework="net45" />
<package id="xunit.runner.visualstudio" version="0.99.9-build1021" targetFramework="net45" />
<package id="xunit" version="2.0.0" targetFramework="net45" />
<package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />
<package id="xunit.assert" version="2.0.0" targetFramework="net45" />
<package id="xunit.core" version="2.0.0" targetFramework="net45" />
<package id="xunit.extensibility.core" version="2.0.0" targetFramework="net45" />
<package id="xunit.extensibility.execution" version="2.0.0" targetFramework="net45" />
<package id="xunit.runner.visualstudio" version="2.0.0" targetFramework="net45" />
</packages>