[Tests] Add a new iOS app to run the xunit and nunit tests (#4914)

Mono know provides a set of testing assemblies that contain the tests to be ran in each of the supported platforms. This commit adds the following:

1. Two different runners that can be used to execute NUnit and xUnit tests.
2. The necessary  glue to get xharness to run the new tests and report the results.
3. A new test that will ensure that if mono adds new tests, xharness will report failures if the tests are not run or not ignored.
This commit is contained in:
Manuel de la Pena 2018-11-16 13:31:40 -05:00 коммит произвёл GitHub
Родитель 6ebf136073
Коммит 505006952c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
104 изменённых файлов: 7976 добавлений и 19 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -18,3 +18,6 @@ packages
jenkins-results
.vs
*.raw
bcl-test-importer
tests/bcl-test/BCLTests/generated
tests/xharness/System.ValueTuple.xml

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

@ -194,6 +194,10 @@ $(TOP)/tools/mtouch/SdkVersions.cs: $(TOP)/tools/common/SdkVersions.cs.in
@touch $@
xharness/xharness.exe: $(wildcard xharness/*.cs) xharness/xharness.csproj $(TOP)/tools/mtouch/SdkVersions.cs test.config test-system.config .stamp-src-project-files
make -j8 -C $(TOP)/external/mono/mcs/class -i do-test PROFILE=MONOTOUCH # TODO: This should not be needed and we should get the dlls from the SDK.
make -j8 -C $(TOP)/external/mono/mcs/class -i do-xunit-test PROFILE=MONOTOUCH # TODO: This should not be needed and we should get the dlls from the SDK.
nuget restore xharness/xharness.csproj
nuget restore bcl-test/BCLTests/BCLTests.csproj
$(Q_GEN) $(SYSTEM_MSBUILD) $(MSBUILD_VERBOSITY_QUIET) xharness/xharness.csproj
killall:

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

@ -0,0 +1,202 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
},
{
"size" : "24x24",
"idiom" : "watch",
"scale" : "2x",
"role" : "notificationCenter",
"subtype" : "38mm"
},
{
"size" : "27.5x27.5",
"idiom" : "watch",
"scale" : "2x",
"role" : "notificationCenter",
"subtype" : "42mm"
},
{
"size" : "29x29",
"idiom" : "watch",
"role" : "companionSettings",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "watch",
"role" : "companionSettings",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "watch",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "38mm"
},
{
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"role" : "longLook",
"subtype" : "42mm"
},
{
"size" : "86x86",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "38mm"
},
{
"size" : "98x98",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "42mm"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

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

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

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

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\xunit.core.2.4.0\build\xunit.core.props" Condition="Exists('..\..\..\packages\xunit.core.2.4.0\build\xunit.core.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}</ProjectGuid>
<ProjectTypeGuids>{06FA79CB-D6CD-4721-BB4B-1BD202089C55}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>%NAME%</RootNamespace>
<AssemblyName>%NAME%</AssemblyName>
<NoWarn>67,168,169,219,414,612,618,649,672</NoWarn>
<TargetFrameworkIdentifier>Xamarin.TVOS</TargetFrameworkIdentifier>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<DefineConstants>XAMCORE_2_0;XAMCORE_2_0;XAMCORE_3_0;</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%\iPhoneSimulator\Debug-tvos</OutputPath>
<DefineConstants>DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchDebug>True</MtouchDebug>
<MtouchLink>None</MtouchLink>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>x86_64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhoneSimulator\Release-tvos</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>x86_64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%\iPhone\Debug-tvos</OutputPath>
<DefineConstants>DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>True</MtouchDebug>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\Release-tvos</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
<MtouchUseLlvm>true</MtouchUseLlvm>
<MtouchExtraArgs>--bitcode:asmonly</MtouchExtraArgs>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-bitcode|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\Release-bitcode-tvos</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
<MtouchUseLlvm>true</MtouchUseLlvm>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release32|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\Release32-tvos</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
<MtouchUseLlvm>true</MtouchUseLlvm>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release64|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\Release64-tvos</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
<MtouchUseLlvm>true</MtouchUseLlvm>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-bitcode|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\Release-bitcode-tvos</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
<MtouchExtraArgs>--bitcode:full --bitcode:full</MtouchExtraArgs>
<MtouchUseLlvm>true</MtouchUseLlvm>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.TVOS" />
<Reference Include="xunit.core">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.assert">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.abstractions">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.dotnet">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.execution.dotnet.dll</HintPath>
</Reference>
<Reference Include="nunitlite">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\nunitlite.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="System.Buffers">
<HintPath>..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe">
<HintPath>..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Memory">
<HintPath>..\..\..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives">
<HintPath>..\..\..\packages\Microsoft.Extensions.Primitives.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Binder">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Binder.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options">
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath>
</Reference>
<Reference Include="xunit.runner.utility.netstandard20">
<HintPath>..\..\..\packages\xunit.runner.utility.2.4.0\lib\netstandard2.0\xunit.runner.utility.netstandard20.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization.Formatters.Soap">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\System.Runtime.Serialization.Formatters.Soap.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Configuration">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Console">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Console.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Console.dll</HintPath>
</Reference>
<Reference Include="Mono.Options">
<HintPath>..\..\..\packages\Mono.Options.5.3.0.1\lib\netstandard1.3\Mono.Options.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
%REFERENCES%
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json" />
<ImageAsset Include="Assets.xcassets\Contents.json" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
</ItemGroup>
<ItemGroup>
<None Include="%PLIST PATH%">
<Link>Info.plist</Link>
</None>
<None Include="templates\tvOSApp\Entitlements.plist">
<Link>Entitlements.plist</Link>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="templates\common\TestRunner.NUnit\NUnitTestRunner.cs">
<Link>TestRunner.NUnit\NUnitTestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\Extensions.Bool.cs">
<Link>TestRunner.Core\Extensions.Bool.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\LogWriter.cs">
<Link>TestRunner.Core\LogWriter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\MinimumLogLevel.cs">
<Link>TestRunner.Core\MinimumLogLevel.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TcpTextWriter.cs">
<Link>TestRunner.Core\TcpTextWriter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestAssemblyInfo.cs">
<Link>TestRunner.Core\TestAssemblyInfo.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestCompletionStatus.cs">
<Link>TestRunner.Core\TestCompletionStatus.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestExecutionState.cs">
<Link>TestRunner.Core\TestExecutionState.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestFailureInfo.cs">
<Link>TestRunner.Core\TestFailureInfo.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestRunner.cs">
<Link>TestRunner.Core\TestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilter.cs">
<Link>TestRunner.xUnit\XUnitFilter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilterType.cs">
<Link>TestRunner.xUnit\XUnitFilterType.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitResultFileFormat.cs">
<Link>TestRunner.xUnit\XUnitResultFileFormat.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitTestRunner.cs">
<Link>TestRunner.xUnit\XUnitTestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\ApplicationOptions.cs">
<Link>ApplicationOptions.cs</Link>
</Compile>
<Compile Include="templates\tvOSApp\AppDelegate.cs">
<Link>AppDelegate.cs</Link>
</Compile>
<Compile Include="templates\tvOSApp\Main.cs">
<Link>Main.cs</Link>
</Compile>
<Compile Include="templates\tvOSApp\ViewController.cs">
<Link>ViewController.cs</Link>
</Compile>
<Compile Include="templates\tvOSApp\ViewController.designer.cs">
<Link>ViewController.designer.cs</Link>
<DependentUpon>ViewController.cs</DependentUpon>
</Compile>
%REGISTER TYPE%
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="templates\common\TestRunner.xUnit\NUnitXml.xslt">
<Link>TestRunner.xUnit\NUnitXml.xslt</Link>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\TVOS\Xamarin.TVOS.CSharp.targets" />
<Import Project="..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" />
<Import Project="..\..\..\packages\xunit.core.2.4.0\build\xunit.core.targets" Condition="Exists('..\..\..\packages\xunit.core.2.4.0\build\xunit.core.targets')" />
</Project>

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

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectTypeGuids>{A9A6EAC2-568B-4F3E-869D-32CBBA122DF2};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{34A6793F-37B2-4A7F-9286-7BDF52F412F3}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>%NAME%-watchos-app</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<AssemblyName>%NAME%-watchos-app</AssemblyName>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)-watchos-app</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<OutputPath>bin\%NAME%-app\iPhoneSimulator\$(Configuration)-watchos-app</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>i386</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchFastDev>true</MtouchFastDev>
<MtouchDebug>true</MtouchDebug>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchProfiling>true</MtouchProfiling>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<OutputPath>bin\%NAME%-watchos-app\iPhone\$(Configuration)-watchos-app</OutputPath>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>ARMv7k</MtouchArch>
<CodesignEntitlements>%TEMPLATE PATH%\Entitlements.plist</CodesignEntitlements>
<MtouchFloat32>true</MtouchFloat32>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<OutputPath>bin\%NAME%-watchos-app\iPhoneSimulator\$(Configuration)-watchos-app</OutputPath>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>i386</MtouchArch>
<MtouchLink>None</MtouchLink>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<OutputPath>bin\%NAME%-watchos-app\iPhone\$(Configuration)-watchos-app</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>ARMv7k</MtouchArch>
<CodesignEntitlements>%TEMPLATE PATH%\Entitlements.plist</CodesignEntitlements>
<MtouchFloat32>true</MtouchFloat32>
<CodesignKey>iPhone Developer</CodesignKey>
<DeviceSpecificBuild>true</DeviceSpecificBuild>
<MtouchDebug>true</MtouchDebug>
<MtouchProfiling>true</MtouchProfiling>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.WatchOS" />
</ItemGroup>
<ItemGroup>
<ImageAsset Include="%TEMPLATE PATH%\Resources\Images.xcassets\AppIcons.appiconset\Contents.json" />
</ItemGroup>
<ItemGroup>
<None Include="%PLIST PATH%">
<LogicalName>Info.plist</LogicalName>
</None>
<None Include="%TEMPLATE PATH%\Entitlements.plist" />
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="%TEMPLATE PATH%\Interface.storyboard" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\WatchOS\Xamarin.WatchOS.App.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="%WATCH EXTENSION PROJECT PATH%">
<Project>{716209E4-C1D4-4DEE-9B03-CA768D5219B5}</Project>
<Name>%NAME%-watchos-extension</Name>
<IsAppExtension>True</IsAppExtension>
<LogicalName>%NAME%-watchos-extension.csproj</LogicalName>
</ProjectReference>
</ItemGroup>
</Project>

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

@ -0,0 +1,220 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{716209E4-C1D4-4DEE-9B03-CA768D5219B5}</ProjectGuid>
<ProjectTypeGuids>{1E2E965C-F6D2-49ED-B86E-418A60C69EEF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<RootNamespace>%NAME%-watchos-extension</RootNamespace>
<AssemblyName>%NAME%-watchos-extension</AssemblyName>
<SignAssembly>True</SignAssembly>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)-unified</IntermediateOutputPath>
<DefineConstants>XAMCORE_2_0</DefineConstants>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)-watchos-extension</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME5-watchos-extension\iPhoneSimulator\Debug-watchos-extension</OutputPath>
<DefineConstants>DEBUG;;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>0</WarningLevel>
<MtouchDebug>True</MtouchDebug>
<MtouchExtraArgs></MtouchExtraArgs>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>i386</MtouchArch>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchLink>None</MtouchLink>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%-watchos-extension\iPhoneSimulator\Release-watchos-extension</OutputPath>
<DefineConstants>MONOTOUCH;;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink>
<MtouchExtraArgs></MtouchExtraArgs>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>i386</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%-watchos-extension\iPhone\Debug-watchos-extension</OutputPath>
<DefineConstants>DEBUG;;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>0</WarningLevel>
<MtouchDebug>True</MtouchDebug>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchExtraArgs></MtouchExtraArgs>
<MtouchArch>ARMv7k</MtouchArch>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<IpaPackageName>
</IpaPackageName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%-watchos-extension\iPhone\Release-watchos-extension</OutputPath>
<DefineConstants>MONOTOUCH;;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchExtraArgs>-v -v -v -v --nosymbolstrip</MtouchExtraArgs>
<MtouchArch>ARMv7k</MtouchArch>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchUseLlvm>true</MtouchUseLlvm>
<MtouchEnableBitcode>true</MtouchEnableBitcode>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.WatchOS" />
<Reference Include="xunit.core">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.assert">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.abstractions">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.dotnet">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.execution.dotnet.dll</HintPath>
</Reference>
<Reference Include="nunitlite">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\nunitlite.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="System.Buffers">
<HintPath>..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe">
<HintPath>..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Memory">
<HintPath>..\..\..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives">
<HintPath>..\..\..\packages\Microsoft.Extensions.Primitives.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Binder">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Binder.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options">
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath>
</Reference>
<Reference Include="xunit.runner.utility.netstandard20">
<HintPath>..\..\..\packages\xunit.runner.utility.2.4.0\lib\netstandard2.0\xunit.runner.utility.netstandard20.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization.Formatters.Soap">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\System.Runtime.Serialization.Formatters.Soap.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Configuration">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Console">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Console.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Console.dll</HintPath>
</Reference>
<Reference Include="Mono.Options">
<HintPath>..\..\..\packages\Mono.Options.5.3.0.1\lib\netstandard1.3\Mono.Options.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
%REFERENCES%
</ItemGroup>
<ItemGroup>
<None Include="%PLIST PATH%">
<LogicalName>Info.plist</LogicalName>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="%TEMPLATE PATH%\InterfaceController.cs" />
<Compile Include="templates\common\TestRunner.Core\Extensions.Bool.cs">
<Link>TestRunner.Core\Extensions.Bool.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\LogWriter.cs">
<Link>TestRunner.Core\LogWriter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\MinimumLogLevel.cs">
<Link>TestRunner.Core\MinimumLogLevel.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\HttpTextWriter.cs">
<Link>TestRunner.Core\HttpTextWriter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestAssemblyInfo.cs">
<Link>TestRunner.Core\TestAssemblyInfo.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestCompletionStatus.cs">
<Link>TestRunner.Core\TestCompletionStatus.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestExecutionState.cs">
<Link>TestRunner.Core\TestExecutionState.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestFailureInfo.cs">
<Link>TestRunner.Core\TestFailureInfo.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestRunner.cs">
<Link>TestRunner.Core\TestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.NUnit\NUnitTestRunner.cs">
<Link>TestRunner.NUnit\NUnitTestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilter.cs">
<Link>TestRunner.xUnit\XUnitFilter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilterType.cs">
<Link>TestRunner.xUnit\XUnitFilterType.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitResultFileFormat.cs">
<Link>TestRunner.xUnit\XUnitResultFileFormat.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitTestRunner.cs">
<Link>TestRunner.xUnit\XUnitTestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\ApplicationOptions.cs">
<Link>ApplicationOptions.cs</Link>
</Compile>
%REGISTER TYPE%
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="templates\common\TestRunner.xUnit\NUnitXml.xslt">
<Link>TestRunner.xUnit\NUnitXml.xslt</Link>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Folder Include="TestRunner.Core\" />
<Folder Include="TestRunner.NUnit\" />
<Folder Include="TestRunner.xUnit\" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\WatchOS\Xamarin.WatchOS.AppExtension.CSharp.targets" />
<Import Project="..\..\..\packages\xunit.core.2.4.1\build\xunit.core.targets" Condition="Exists('..\..\..\packages\xunit.core.2.4.1\build\xunit.core.targets')" />
<Import Project="..\..\..\packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\..\..\packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" />
</Project>

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

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ProjectGuid>{C5902CDB-EAB0-B07F-4102-F96A90C93B35}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>%NAME%-container</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<AssemblyName>%NAME%-container</AssemblyName>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)-watchos</IntermediateOutputPath>
<DefineConstants>XAMCORE_2_0;XAMCORE_3_0;</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;$(DefineConstants)</DefineConstants>
<OutputPath>bin\%NAME%\iPhoneSimulator\$(Configuration)-watchos</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchProfiling>true</MtouchProfiling>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-watchos</OutputPath>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>ARM64</MtouchArch>
<CodesignEntitlements>%TEMPLATE PATH%\Entitlements.plist</CodesignEntitlements>
<MtouchFloat32>true</MtouchFloat32>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchLink>Full</MtouchLink>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<OutputPath>bin\%NAME%\iPhoneSimulator\$(Configuration)-watchos</OutputPath>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-watchos</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>ARM64</MtouchArch>
<MtouchLink>Full</MtouchLink>
<CodesignEntitlements>%TEMPLATE PATH%\Entitlements.plist</CodesignEntitlements>
<MtouchFloat32>true</MtouchFloat32>
<CodesignKey>iPhone Developer</CodesignKey>
<DeviceSpecificBuild>true</DeviceSpecificBuild>
<MtouchDebug>true</MtouchDebug>
<MtouchProfiling>true</MtouchProfiling>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
</ItemGroup>
<ItemGroup>
<ImageAsset Include="%TEMPLATE PATH%\Resources\Images.xcassets\AppIcons.appiconset\Contents.json">
<LogicalName>Resources\Images.xcassets\AppIcons.appiconset\Contents.json</LogicalName>
</ImageAsset>
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="%TEMPLATE PATH%\Resources\LaunchScreen.xib">
<LogicalName>Resources\LaunchScreen.xib</LogicalName>
</InterfaceDefinition>
<InterfaceDefinition Include="%TEMPLATE PATH%\Main.storyboard">
<LogicalName>Main.storyboard</LogicalName>
</InterfaceDefinition>
</ItemGroup>
<ItemGroup>
<None Include="%PLIST PATH%">
<LogicalName>Info.plist</LogicalName>
</None>
<None Include="%TEMPLATE PATH%\Entitlements.plist">
<LogicalName>Entitlements.plist</LogicalName>
</None>
</ItemGroup>
<ItemGroup>
<Compile Include="%TEMPLATE PATH%\Main.cs">
<LogicalName>Main.cs</LogicalName>
</Compile>
<Compile Include="%TEMPLATE PATH%\AppDelegate.cs">
<LogicalName>AppDelegate.cs</LogicalName>
</Compile>
<Compile Include="%TEMPLATE PATH%\ViewController.cs">
<LogicalName>ViewController.cs</LogicalName>
</Compile>
<Compile Include="%TEMPLATE PATH%\ViewController.designer.cs">
<DependentUpon>ViewController.cs</DependentUpon>
<LogicalName>ViewController.designer.cs</LogicalName>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="%WATCH APP PROJECT PATH%">
<Project>{34A6793F-37B2-4A7F-9286-7BDF52F412F3}</Project>
<Name>%NAME%-watchos-app</Name>
<IsWatchApp>True</IsWatchApp>
<LogicalName>%NAME%-watchos-app.csproj</LogicalName>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>

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

@ -0,0 +1,391 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\xunit.core.2.4.0\build\xunit.core.props" Condition="Exists('..\..\..\packages\xunit.core.2.4.0\build\xunit.core.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}</ProjectGuid>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>BCLTests</RootNamespace>
<AssemblyName>BCLTests</AssemblyName>
<NoWarn>67,168,169,219,414,612,618,649,672</NoWarn>
<TargetFrameworkIdentifier>Xamarin.iOS</TargetFrameworkIdentifier>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG;ENABLE_TEST_CLOUD;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchFastDev>true</MtouchFastDev>
<IOSDebuggerPort>57777</IOSDebuggerPort>
<MtouchLink>None</MtouchLink>
<MtouchArch>i386, x86_64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchUseLlvm>true</MtouchUseLlvm>
<MtouchFloat32>true</MtouchFloat32>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchArch>ARM64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchLink>None</MtouchLink>
<MtouchArch>x86_64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG;ENABLE_TEST_CLOUD;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<DeviceSpecificBuild>true</DeviceSpecificBuild>
<MtouchDebug>true</MtouchDebug>
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<MtouchFastDev>true</MtouchFastDev>
<MtouchFloat32>true</MtouchFloat32>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<IOSDebuggerPort>64686</IOSDebuggerPort>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchArch>ARM64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug64|iPhone' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-unified</OutputPath>
<DefineConstants>DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>True</MtouchDebug>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
<Reference Include="nunitlite">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\nunitlite.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="System.Buffers">
<HintPath>..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe">
<HintPath>..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Memory">
<HintPath>..\..\..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives">
<HintPath>..\..\..\packages\Microsoft.Extensions.Primitives.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Binder">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Binder.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options">
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath>
</Reference>
<Reference Include="xunit.abstractions">
<HintPath>..\..\..\packages\xunit.abstractions.2.0.3\lib\netstandard2.0\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.assert">
<HintPath>..\..\..\packages\xunit.assert.2.4.0\lib\netstandard2.0\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.core">
<HintPath>..\..\..\packages\xunit.extensibility.core.2.4.0\lib\netstandard2.0\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.dotnet">
<HintPath>..\..\..\packages\xunit.extensibility.execution.2.4.0\lib\netstandard2.0\xunit.execution.dotnet.dll</HintPath>
</Reference>
<Reference Include="xunit.runner.utility.netstandard20">
<HintPath>..\..\..\packages\xunit.runner.utility.2.4.0\lib\netstandard2.0\xunit.runner.utility.netstandard20.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Commons.Xml.Relaxng_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Commons.Xml.Relaxng_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_corlib_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_corlib_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Cscompmgd_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Cscompmgd_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_I18N.CJK_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_I18N.CJK_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_I18N.MidEast_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_I18N.MidEast_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_I18N.Other_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_I18N.Other_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_I18N.Rare_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_I18N.Rare_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_I18N.West_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_I18N.West_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Mono.C5_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Mono.C5_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Mono.CodeContracts_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Mono.CodeContracts_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Mono.CSharp_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Mono.CSharp_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Mono.Data.Tds_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Mono.Data.Tds_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Mono.Parallel_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Mono.Parallel_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Mono.Runtime.Tests_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Mono.Runtime.Tests_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Mono.Security_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Mono.Security_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Mono.Tasklets_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Mono.Tasklets_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_Novell.Directory.Ldap_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_Novell.Directory.Ldap_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.ComponentModel.DataAnnotations_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.ComponentModel.DataAnnotations_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Core_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Core_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Data_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Data_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Data.DataSetExtensions_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Data.DataSetExtensions_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.IO.Compression_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.IO.Compression_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.IO.Compression.FileSystem_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.IO.Compression.FileSystem_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Json_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Json_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Json.Microsoft_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Json.Microsoft_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Net.Http_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Net.Http_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Numerics_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Numerics_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Runtime.Serialization_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Runtime.Serialization_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Runtime.Serialization.Formatters.Soap_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Runtime.Serialization.Formatters.Soap_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Security_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Security_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.ServiceModel_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.ServiceModel_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.ServiceModel.Web_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.ServiceModel.Web_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Threading.Tasks.Dataflow_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Threading.Tasks.Dataflow_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Transactions_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Transactions_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Xml_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Xml_test.dll</HintPath>
</Reference>
<Reference Include="MONOTOUCH_System.Xml.Linq_test">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\tests\MONOTOUCH_System.Xml.Linq_test.dll</HintPath>
</Reference>
<Reference Include="Commons.Xml.Relaxng">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\Commons.Xml.Relaxng.dll</HintPath>
</Reference>
<Reference Include="Mono.Parallel">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\Mono.Parallel.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization.Formatters.Soap">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\System.Runtime.Serialization.Formatters.Soap.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Dataflow">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\System.Threading.Tasks.Dataflow.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Configuration">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Console">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Console.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Console.dll</HintPath>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\System.Data.DataSetExtensions.dll</HintPath>
</Reference>
<Reference Include="Novell.Directory.Ldap">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\Novell.Directory.Ldap.dll</HintPath>
</Reference>
<Reference Include="Mono.C5">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\Mono.C5.dll</HintPath>
</Reference>
<Reference Include="Mono.Options">
<HintPath>..\..\..\packages\Mono.Options.5.3.0.1\lib\netstandard1.3\Mono.Options.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json" />
<ImageAsset Include="Assets.xcassets\Contents.json" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
<Folder Include="TestRunner.NUnit\" />
<Folder Include="TestRunner.NUnit\" />
<Folder Include="TestRunner.Core\" />
<Folder Include="TestRunner.Core\" />
<Folder Include="TestRunner.xUnit\" />
<Folder Include="TestRunner.xUnit\" />
</ItemGroup>
<ItemGroup>
<None Include="Info.plist" />
<None Include="packages.config" />
<None Include="templates\iOSApp\Entitlements.plist">
<Link>Entitlements.plist</Link>
</None>
</ItemGroup>
<ItemGroup>
<Compile Include="generated\MonoCSharpTests\RegisterType.cs">
<Link>RegisterType.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.NUnit\NUnitTestRunner.cs">
<Link>TestRunner.NUnit\NUnitTestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\Extensions.Bool.cs">
<Link>TestRunner.Core\Extensions.Bool.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\LogWriter.cs">
<Link>TestRunner.Core\LogWriter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\MinimumLogLevel.cs">
<Link>TestRunner.Core\MinimumLogLevel.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TcpTextWriter.cs">
<Link>TestRunner.Core\TcpTextWriter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestAssemblyInfo.cs">
<Link>TestRunner.Core\TestAssemblyInfo.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestCompletionStatus.cs">
<Link>TestRunner.Core\TestCompletionStatus.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestExecutionState.cs">
<Link>TestRunner.Core\TestExecutionState.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestFailureInfo.cs">
<Link>TestRunner.Core\TestFailureInfo.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestRunner.cs">
<Link>TestRunner.Core\TestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilter.cs">
<Link>TestRunner.xUnit\XUnitFilter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilterType.cs">
<Link>TestRunner.xUnit\XUnitFilterType.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitResultFileFormat.cs">
<Link>TestRunner.xUnit\XUnitResultFileFormat.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitTestRunner.cs">
<Link>TestRunner.xUnit\XUnitTestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\ApplicationOptions.cs">
<Link>ApplicationOptions.cs</Link>
</Compile>
<Compile Include="templates\iOSApp\AppDelegate.cs">
<Link>AppDelegate.cs</Link>
</Compile>
<Compile Include="templates\iOSApp\Main.cs">
<Link>Main.cs</Link>
</Compile>
<Compile Include="templates\iOSApp\ViewController.cs">
<Link>ViewController.cs</Link>
</Compile>
<Compile Include="templates\iOSApp\ViewController.designer.cs">
<Link>ViewController.designer.cs</Link>
<DependentUpon>ViewController.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="templates\common\TestRunner.xUnit\NUnitXml.xslt">
<Link>TestRunner.xUnit\NUnitXml.xslt</Link>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<Import Project="..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" />
<Import Project="..\..\..\packages\xunit.core.2.4.0\build\xunit.core.targets" Condition="Exists('..\..\..\packages\xunit.core.2.4.0\build\xunit.core.targets')" />
</Project>

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

@ -0,0 +1,290 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\packages\xunit.core.2.4.0\build\xunit.core.props" Condition="Exists('..\..\..\packages\xunit.core.2.4.0\build\xunit.core.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}</ProjectGuid>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>%NAME%</RootNamespace>
<AssemblyName>%NAME%</AssemblyName>
<NoWarn>67,168,169,219,414,612,618,649,672</NoWarn>
<TargetFrameworkIdentifier>Xamarin.iOS</TargetFrameworkIdentifier>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%\iPhoneSimulator\$(Configuration)-unified</OutputPath>
<DefineConstants>DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchDebug>True</MtouchDebug>
<MtouchLink>None</MtouchLink>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>i386, x86_64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhoneSimulator\$(Configuration)-unified</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>i386, x86_64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-unified</OutputPath>
<DefineConstants>DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>True</MtouchDebug>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARMv7, ARM64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug32|iPhone' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-unified</OutputPath>
<DefineConstants>DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>True</MtouchDebug>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARMv7</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug64|iPhone' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-unified</OutputPath>
<DefineConstants>DEBUG;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>True</MtouchDebug>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-unified</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<MtouchUseLlvm>true</MtouchUseLlvm>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release32|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-unified</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARMv7</MtouchArch>
<MtouchUseLlvm>true</MtouchUseLlvm>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release64|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-unified</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARM64</MtouchArch>
<MtouchUseLlvm>true</MtouchUseLlvm>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-bitcode|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\%NAME%\iPhone\$(Configuration)-unified</OutputPath>
<DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;NET_2_1;MOBILE;MONOTOUCH;FULL_AOT_RUNTIME;DISABLE_CAS_USE;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<MtouchExtraArgs>--bitcode:full</MtouchExtraArgs>
<MtouchUseLlvm>true</MtouchUseLlvm>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
<Reference Include="xunit.core">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.assert">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.abstractions">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.dotnet">
<HintPath>..\..\..\external\mono\external\xunit-binaries\xunit.execution.dotnet.dll</HintPath>
</Reference>
<Reference Include="nunitlite">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\nunitlite.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="System.Buffers">
<HintPath>..\..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe">
<HintPath>..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Memory">
<HintPath>..\..\..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives">
<HintPath>..\..\..\packages\Microsoft.Extensions.Primitives.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Binder">
<HintPath>..\..\..\packages\Microsoft.Extensions.Configuration.Binder.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options">
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath>
</Reference>
<Reference Include="xunit.runner.utility.netstandard20">
<HintPath>..\..\..\packages\xunit.runner.utility.2.4.0\lib\netstandard2.0\xunit.runner.utility.netstandard20.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization.Formatters.Soap">
<HintPath>..\..\..\external\mono\mcs\class\lib\monotouch\System.Runtime.Serialization.Formatters.Soap.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions">
<HintPath>..\..\..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Configuration">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Configuration.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Console">
<HintPath>..\..\..\packages\Microsoft.Extensions.Logging.Console.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Console.dll</HintPath>
</Reference>
<Reference Include="Mono.Options">
<HintPath>..\..\..\packages\Mono.Options.5.3.0.1\lib\netstandard1.3\Mono.Options.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
%REFERENCES%
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json" />
<ImageAsset Include="Assets.xcassets\Contents.json" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
</ItemGroup>
<ItemGroup>
<None Include="%PLIST PATH%">
<Link>Info.plist</Link>
</None>
<None Include="templates\iOSApp\Entitlements.plist">
<Link>Entitlements.plist</Link>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="templates\common\TestRunner.NUnit\NUnitTestRunner.cs">
<Link>TestRunner.NUnit\NUnitTestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\Extensions.Bool.cs">
<Link>TestRunner.Core\Extensions.Bool.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\LogWriter.cs">
<Link>TestRunner.Core\LogWriter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\MinimumLogLevel.cs">
<Link>TestRunner.Core\MinimumLogLevel.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TcpTextWriter.cs">
<Link>TestRunner.Core\TcpTextWriter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestAssemblyInfo.cs">
<Link>TestRunner.Core\TestAssemblyInfo.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestCompletionStatus.cs">
<Link>TestRunner.Core\TestCompletionStatus.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestExecutionState.cs">
<Link>TestRunner.Core\TestExecutionState.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestFailureInfo.cs">
<Link>TestRunner.Core\TestFailureInfo.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.Core\TestRunner.cs">
<Link>TestRunner.Core\TestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilter.cs">
<Link>TestRunner.xUnit\XUnitFilter.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitFilterType.cs">
<Link>TestRunner.xUnit\XUnitFilterType.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitResultFileFormat.cs">
<Link>TestRunner.xUnit\XUnitResultFileFormat.cs</Link>
</Compile>
<Compile Include="templates\common\TestRunner.xUnit\XUnitTestRunner.cs">
<Link>TestRunner.xUnit\XUnitTestRunner.cs</Link>
</Compile>
<Compile Include="templates\common\ApplicationOptions.cs">
<Link>ApplicationOptions.cs</Link>
</Compile>
<Compile Include="templates\iOSApp\AppDelegate.cs">
<Link>AppDelegate.cs</Link>
</Compile>
<Compile Include="templates\iOSApp\Main.cs">
<Link>Main.cs</Link>
</Compile>
<Compile Include="templates\iOSApp\ViewController.cs">
<Link>ViewController.cs</Link>
</Compile>
<Compile Include="templates\iOSApp\ViewController.designer.cs">
<Link>ViewController.designer.cs</Link>
<DependentUpon>ViewController.cs</DependentUpon>
</Compile>
%REGISTER TYPE%
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="templates\common\TestRunner.xUnit\NUnitXml.xslt">
<Link>TestRunner.xUnit\NUnitXml.xslt</Link>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<Import Project="..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\..\..\packages\NETStandard.Library.2.0.0\build\netstandard2.0\NETStandard.Library.targets')" />
<Import Project="..\..\..\packages\xunit.core.2.4.0\build\xunit.core.targets" Condition="Exists('..\..\..\packages\xunit.core.2.4.0\build\xunit.core.targets')" />
</Project>

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

@ -0,0 +1,23 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BCLTests", "BCLTests.csproj", "{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Release|iPhone = Release|iPhone
Release|iPhoneSimulator = Release|iPhoneSimulator
Debug|iPhone = Debug|iPhone
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}.Release|iPhone.ActiveCfg = Release|iPhone
{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}.Release|iPhone.Build.0 = Release|iPhone
{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}.Debug|iPhone.ActiveCfg = Debug|iPhone
{C459A4DD-0AFF-4B2C-9DEC-4B62CE04F4E2}.Debug|iPhone.Build.0 = Debug|iPhone
EndGlobalSection
EndGlobal

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

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>%APPLICATION NAME%</string>
<key>CFBundleIdentifier</key>
<string>%BUNDLE INDENTIFIER%</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>9.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>3</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
</dict>
</plist>

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

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>%APPLICATION NAME%-watch</string>
<key>CFBundleIdentifier</key>
<string>%BUNDLE INDENTIFIER%-watch.watchkitapp</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.33</string>
<key>MinimumOSVersion</key>
<string>2.0</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>WKCompanionAppBundleIdentifier</key>
<string>%BUNDLE INDENTIFIER%-watch</string>
<key>WKWatchKitApp</key>
<true/>
<key>XSAppIconAssets</key>
<string>Resources/Images.xcassets/AppIcons.appiconset</string>
</dict>
</plist>

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

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"[]>
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>%APPLICATION NAME%-watch</string>
<key>CFBundleIdentifier</key>
<string>%BUNDLE INDENTIFIER%-watch.watchkitapp.watchkitextension</string>
<key>CFBundleName</key>
<string>TestApp</string>
<key>MinimumOSVersion</key>
<string>2</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true />
</dict>
<key>UIDeviceFamily</key>
<array>
<integer>4</integer>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiresFullScreen</key>
<true />
<key>RemoteInterfacePrincipleClass</key>
<string>InterfaceController</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>WKAppBundleIdentifier</key>
<string>%BUNDLE INDENTIFIER%-watch.watchkitapp</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.watchkit</string>
</dict>
</dict>
</plist>

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

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>%APPLICATION NAME%-watch</string>
<key>CFBundleIdentifier</key>
<string>%BUNDLE INDENTIFIER%-watch</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>9.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIMainStoryboardFile~ipad</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Resources/Images.xcassets/AppIcons.appiconset</string>
</dict>
</plist>

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

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>BCLTests</string>
<key>CFBundleIdentifier</key>
<string>com.xamarin.BCLTests</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>6.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
</dict>
</plist>

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

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>%APPLICATION NAME%</string>
<key>CFBundleIdentifier</key>
<string>%BUNDLE INDENTIFIER%</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>6.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
</dict>
</plist>

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

@ -0,0 +1,20 @@
DESTDIR ?= /usr/local/bin/
CONFIGURATION ?= Debug
MONO_ROOT:=../../../external/mono/
test-importer:
@make -C ../../../tools/bcl-test-importer/ all
@rm -Rf bcl-test-importer
@mkdir -p bcl-test-importer
cp ../../../tools/bcl-test-importer/BCLTestImporter/bin/Debug/* bcl-test-importer
generate-test-projects: test-importer ./RegisterType.cs.in ./BCLTests.csproj.in
mono ./bcl-test-importer/BCLTestImporter.exe --generate-all-projects --output=. --clean
mono ./bcl-test-importer/BCLTestImporter.exe --generate-all-projects --output=. --override --register-type-template=RegisterType.cs.in --project-template=. --plist-template=. --mono-root=../../../external/mono/ -iOS -v
all: build-test-projects
clean: test-importer
mono ./bcl-test-importer/BCLTestImporter.exe --generate-all-projects --output=. --clean
@rm -Rf ./bin
@rm -Rf ./obj

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

@ -0,0 +1,29 @@
using System;
using System.IO;
using System.Collections.Generic;
using Xunit;
using Xunit.Abstractions;
%USING%
namespace Xamarin.iOS.UnitTests {
// autogenerated class that uses types from the test assemblies so that
// they are aot and not linked away.
public static class RegisterType
{
public static bool IsXUnit = %IS XUNIT%;
public static Dictionary <string, Type> TypesToRegister = new Dictionary <string, Type> {
%KEY VALUES%
};
public static void RegisterTypes ()
{
// line used to ensure that the runner is not remove by the linker :/
Console.WriteLine ($"Got the runner for the linker {typeof(Xunit.Sdk.TypeUtility)}");
foreach (var a in TypesToRegister.Keys) {
// do something with the type, so that it is not removed
var assemblyPath = Path.GetFileName (TypesToRegister[a].Assembly.Location);
Console.WriteLine ($"We are using type {TypesToRegister[a]} from assembly {assemblyPath}");
}
}
}
}

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

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Extensions.Configuration" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Configuration.Abstractions" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Configuration.Binder" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Logging" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Logging.Abstractions" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Logging.Configuration" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Logging.Console" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Options" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Options.ConfigurationExtensions" version="2.1.1" targetFramework="xamarinios10" />
<package id="Microsoft.Extensions.Primitives" version="2.1.1" targetFramework="xamarinios10" />
<package id="Mono.Options" version="5.3.0.1" targetFramework="xamarinios10" />
<package id="System.Buffers" version="4.4.0" targetFramework="xamarinios10" />
<package id="System.Memory" version="4.5.1" targetFramework="xamarinios10" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.1" targetFramework="xamarinios10" />
<package id="xunit" version="2.4.0" targetFramework="xamarinios10" />
<package id="xunit.analyzers" version="0.10.0" targetFramework="xamarinios10" />
<package id="xunit.extensibility.core" version="2.4.0" targetFramework="xamarinios10" />
<package id="xunit.extensibility.execution" version="2.4.0" targetFramework="xamarinios10" />
<package id="xunit.runner.utility" version="2.4.0" targetFramework="xamarinios10" />
</packages>

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

@ -0,0 +1,98 @@
// Modified version of the TouchOptions found in
using System;
using Foundation;
using Mono.Options;
namespace BCLTests {
public enum XmlMode {
Default = 0,
Wrapped = 1,
}
public class ApplicationOptions {
static public ApplicationOptions Current = new ApplicationOptions ();
public ApplicationOptions ()
{
var defaults = NSUserDefaults.StandardUserDefaults;
TerminateAfterExecution = defaults.BoolForKey ("execution.autoexit");
AutoStart = defaults.BoolForKey ("execution.autostart");
EnableNetwork = defaults.BoolForKey ("network.enabled");
EnableXml = defaults.BoolForKey ("xml.enabled");
HostName = defaults.StringForKey ("network.host.name");
HostPort = (int)defaults.IntForKey ("network.host.port");
Transport = defaults.StringForKey ("network.transport");
SortNames = defaults.BoolForKey ("display.sort");
LogFile = defaults.StringForKey ("log.file");
bool b;
if (bool.TryParse (Environment.GetEnvironmentVariable ("NUNIT_AUTOEXIT"), out b))
TerminateAfterExecution = b;
if (bool.TryParse (Environment.GetEnvironmentVariable ("NUNIT_AUTOSTART"), out b))
AutoStart = b;
if (bool.TryParse (Environment.GetEnvironmentVariable ("NUNIT_ENABLE_NETWORK"), out b))
EnableNetwork = b;
if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("NUNIT_HOSTNAME")))
HostName = Environment.GetEnvironmentVariable ("NUNIT_HOSTNAME");
int i;
if (int.TryParse (Environment.GetEnvironmentVariable ("NUNIT_HOSTPORT"), out i))
HostPort = i;
if (bool.TryParse (Environment.GetEnvironmentVariable ("NUNIT_SORTNAMES"), out b))
SortNames = b;
if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("NUNIT_TRANSPORT")))
Transport = Environment.GetEnvironmentVariable ("NUNIT_TRANSPORT");
if (bool.TryParse (Environment.GetEnvironmentVariable ("NUNIT_ENABLE_XML_OUTPUT"), out b))
EnableXml = b;
var xml_mode = Environment.GetEnvironmentVariable ("NUNIT_ENABLE_XML_MODE");
if (!string.IsNullOrEmpty (xml_mode))
XmlMode = (XmlMode) Enum.Parse (typeof (XmlMode), xml_mode, true);
if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("NUNIT_LOG_FILE")))
LogFile = Environment.GetEnvironmentVariable ("NUNIT_LOG_FILE");
var os = new OptionSet () {
{ "autoexit", "If the app should exit once the test run has completed.", v => TerminateAfterExecution = true },
{ "autostart", "If the app should automatically start running the tests.", v => AutoStart = true },
{ "hostname=", "Comma-separated list of host names or IP address to (try to) connect to", v => HostName = v },
{ "hostport=", "HTTP/TCP port to connect to.", v => HostPort = int.Parse (v) },
{ "enablenetwork", "Enable the network reporter.", v => EnableNetwork = true },
{ "transport=", "Select transport method. Either TCP (default), HTTP or FILE.", v => Transport = v },
{ "enablexml", "Enable the xml reported.", v => EnableXml = false },
{ "xmlmode", "The xml mode.", v => XmlMode = (XmlMode) Enum.Parse (typeof (XmlMode), v, false) },
{ "logfile=", "A path where output will be saved.", v => LogFile = v },
};
try {
os.Parse (Environment.GetCommandLineArgs ());
} catch (OptionException oe) {
Console.WriteLine ("{0} for options '{1}'", oe.Message, oe.OptionName);
}
}
private bool EnableNetwork { get; set; }
public XmlMode XmlMode { get; set; }
public bool EnableXml { get; set; }
public string HostName { get; private set; }
public int HostPort { get; private set; }
public bool AutoStart { get; set; }
public bool TerminateAfterExecution { get; set; }
public string Transport { get; set; } = "TCP";
public string LogFile { get; set; }
public bool ShowUseNetworkLogger {
get { return (EnableNetwork && !String.IsNullOrWhiteSpace (HostName) && (HostPort > 0 || Transport == "FILE")); }
}
public bool SortNames { get; set; }
}
}

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

@ -0,0 +1,10 @@
namespace Xamarin.iOS.UnitTests
{
public static partial class Extensions
{
public static string YesNo (this bool b)
{
return b ? "yes" : "no";
}
}
}

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

@ -0,0 +1,128 @@
// HttpTextWriter.cs: Class to report test results using http requests
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright 2016 Xamarin Inc.
//
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
#if __UNIFIED__
using Foundation;
#else
using MonoTouch.Foundation;
#endif
namespace BCLTests.TestRunner.Core {
class HttpTextWriter : TextWriter
{
public string HostName;
public int Port;
TaskCompletionSource<bool> finished = new TaskCompletionSource<bool> ();
TaskCompletionSource<bool> closed = new TaskCompletionSource<bool> ();
StringBuilder log = new StringBuilder ();
public Task FinishedTask {
get {
return finished.Task;
}
}
public override Encoding Encoding {
get {
return Encoding.UTF8;
}
}
public override void Close ()
{
var valueWasSet = closed.TrySetResult (true);
if (valueWasSet) {
Task.Run (async () =>
{
await finished.Task;
base.Close ();
});
}
}
Task<bool> SendData (NSUrl url, string uploadData)
{
var tcs = new TaskCompletionSource<bool> ();
var request = new NSMutableUrlRequest (url);
request.HttpMethod = "POST";
var rv = NSUrlSession.SharedSession.CreateUploadTask (request, NSData.FromString (uploadData), (NSData data, NSUrlResponse response, NSError error) =>
{
if (error != null) {
Console.WriteLine ("Failed to send data to {0}: {1}", url.AbsoluteString, error);
tcs.SetResult (false);
} else {
//Console.WriteLine ("Succeeded sending data to {0}", url.AbsoluteString);
tcs.SetResult (true);
}
});
rv.Resume ();
return tcs.Task;
}
async Task SendData (string action, string uploadData)
{
var url = NSUrl.FromString ("http://" + HostName + ":" + Port + "/" + action);
int attempts_left = 10;
while (!await SendData (url, uploadData)) {
if (--attempts_left == 0) {
Console.WriteLine ("Not resending data anymore.");
throw new Exception ("Failed to send data.");
}
Console.WriteLine ("Resending data: {0} Length: {1} to: {2} Attempts left: {3}", action, uploadData.Length, url.AbsoluteString, attempts_left);
};
}
async void SendThread ()
{
try {
await SendData ("Start", "");
await closed.Task;
await SendData ("Finish", log.ToString ());
} catch (Exception ex) {
Console.WriteLine ("HttpTextWriter failed: {0}", ex);
} finally {
finished.SetResult (true);
}
}
public void Open ()
{
new Thread (SendThread)
{
IsBackground = true,
}.Start ();
}
public override void Write (char value)
{
Console.Out.Write (value);
log.Append (value);
}
public override void Write (char [] buffer)
{
Console.Out.Write (buffer);
log.Append (buffer);
}
public override void WriteLine (string value)
{
Console.Out.WriteLine (value);
log.AppendLine (value);
}
}
}

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

@ -0,0 +1,104 @@
using System;
using System.IO;
using Foundation;
using UIKit;
using ObjCRuntime;
using Constants = global::ObjCRuntime.Constants;
namespace Xamarin.iOS.UnitTests
{
public class LogWriter
{
TextWriter writer;
public MinimumLogLevel MinimumLogLevel { get; set; } = MinimumLogLevel.Info;
public LogWriter () : this (Console.Out) { }
public LogWriter (TextWriter w)
{
writer = w ?? Console.Out;
InitLogging ();
}
[System.Runtime.InteropServices.DllImport ("/usr/lib/libobjc.dylib")]
static extern IntPtr objc_msgSend (IntPtr receiver, IntPtr selector);
static string UniqueIdentifier {
get {
#if !__WATCHOS__
IntPtr handle = UIDevice.CurrentDevice.Handle;
if (UIDevice.CurrentDevice.RespondsToSelector (new Selector ("uniqueIdentifier")))
return NSString.FromHandle (objc_msgSend (handle, Selector.GetHandle("uniqueIdentifier")));
#endif
return "unknown";
}
}
public void InitLogging ()
{
#if !__WATCHOS__
UIDevice device = UIDevice.CurrentDevice;
#endif
// print some useful info
writer.WriteLine ("[Runner executing:\t{0}]", "Run everything");
writer.WriteLine ("[MonoTouch Version:\t{0}]", Constants.Version);
writer.WriteLine ("[Assembly:\t{0}.dll ({1} bits)]", typeof (NSObject).Assembly.GetName ().Name, IntPtr.Size * 8);
#if !__WATCHOS__
writer.WriteLine ("[{0}:\t{1} v{2}]", device.Model, device.SystemName, device.SystemVersion);
writer.WriteLine ("[Device Name:\t{0}]", device.Name);
#endif
writer.WriteLine ("[Device UDID:\t{0}]", UniqueIdentifier);
writer.WriteLine ("[Device Locale:\t{0}]", NSLocale.CurrentLocale.Identifier);
writer.WriteLine ("[Device Date/Time:\t{0}]", DateTime.Now); // to match earlier C.WL output
writer.WriteLine ("[Bundle:\t{0}]", NSBundle.MainBundle.BundleIdentifier);
}
public void OnError (string message)
{
if (MinimumLogLevel < MinimumLogLevel.Error)
return;
writer.WriteLine (message);
writer.Flush ();
}
public void OnWarning (string message)
{
if (MinimumLogLevel < MinimumLogLevel.Warning)
return;
writer.WriteLine (message);
writer.Flush ();
}
public void OnDebug (string message)
{
if (MinimumLogLevel < MinimumLogLevel.Debug)
return;
writer.WriteLine (message);
writer.Flush ();
}
public void OnDiagnostic (string message)
{
if (MinimumLogLevel < MinimumLogLevel.Verbose)
return;
writer.WriteLine (message);
writer.Flush ();
}
public void OnInfo (string message)
{
if (MinimumLogLevel < MinimumLogLevel.Info)
return;
writer.WriteLine (message);
writer.Flush ();
}
public void Info (string message)
{
writer.WriteLine (message);
writer.Flush ();
}
}
}

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

@ -0,0 +1,14 @@
using System;
namespace Xamarin.iOS.UnitTests
{
public enum MinimumLogLevel
{
Critical,
Error,
Warning,
Info,
Debug,
Verbose
}
}

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

@ -0,0 +1,97 @@
// this is an adaptation of NUnitLite's TcpWriter.cs with an additional
// overrides and with network-activity UI enhancement
// This code is a small modification of
// https://github.com/spouliot/Touch.Unit/blob/master/NUnitLite/TouchRunner/TcpTextWriter.cs
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using UIKit;
namespace BCLTests.TestRunner.Core {
public class TcpTextWriter : TextWriter {
TcpClient client;
StreamWriter writer;
public TcpTextWriter (string hostName, int port)
{
if ((port < 0) || (port > ushort.MaxValue))
throw new ArgumentOutOfRangeException (nameof (port), $"Port must be between 0 and {ushort.MaxValue}" );
HostName = hostName ?? throw new ArgumentNullException (nameof (hostName));
Port = port;
#if __IOS__
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
#endif
try {
client = new TcpClient (hostName, port);
writer = new StreamWriter (client.GetStream ());
}
catch {
#if __IOS__
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
#endif
throw;
}
}
public string HostName { get; private set; }
public int Port { get; private set; }
// we override everything that StreamWriter overrides from TextWriter
public override System.Text.Encoding Encoding => Encoding.UTF8;
public override void Close ()
{
#if __IOS__
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
#endif
writer.Close ();
}
protected override void Dispose (bool disposing)
{
writer.Dispose ();
}
public override void Flush ()
{
writer.Flush ();
}
// minimum to override - see http://msdn.microsoft.com/en-us/library/system.io.textwriter.aspx
public override void Write (char value)
{
writer.Write (value);
}
public override void Write (char[] buffer)
{
writer.Write (buffer);
}
public override void Write (char[] buffer, int index, int count)
{
writer.Write (buffer, index, count);
}
public override void Write (string value)
{
writer.Write (value);
}
// special extra override to ensure we flush data regularly
public override void WriteLine ()
{
writer.WriteLine ();
writer.Flush ();
}
}
}

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

@ -0,0 +1,17 @@
using System;
using System.Reflection;
namespace Xamarin.iOS.UnitTests
{
public class TestAssemblyInfo
{
public Assembly Assembly { get; }
public string FullPath { get; }
public TestAssemblyInfo (Assembly assembly, string fullPath)
{
Assembly = assembly ?? throw new ArgumentNullException (nameof (assembly));
FullPath = fullPath ?? String.Empty;
}
}
}

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

@ -0,0 +1,11 @@
namespace Xamarin.iOS.UnitTests
{
public enum TestCompletionStatus
{
Undefined,
Passed,
Failed,
Skipped,
Inconclusive,
}
}

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

@ -0,0 +1,25 @@
using System;
namespace Xamarin.iOS.UnitTests
{
public class TestExecutionState
{
public string TestName { get; internal set; }
public TimeSpan Started { get; private set; } = TimeSpan.MinValue;
public TimeSpan Finished { get; private set; } = TimeSpan.MinValue;
public TestCompletionStatus CompletionStatus { get; set; } = TestCompletionStatus.Undefined;
internal TestExecutionState ()
{}
internal void Start ()
{
Started = new TimeSpan (DateTime.Now.Ticks);
}
internal void Finish ()
{
Finished = new TimeSpan (DateTime.Now.Ticks);
}
}
}

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

@ -0,0 +1,32 @@
using System;
namespace Xamarin.iOS.UnitTests
{
/// <summary>
/// Contains information about a single test failure. Information is used at the end of the run to print
/// summary of failures to logcat as well as put them in the results Bundle. <see cref="TestName"/> is used
/// only to generate unique index when storing information in the Bundle, so <see cref="Message"/> must contain
/// the test name.
/// </summary>
public class TestFailureInfo
{
/// <summary>
/// Gets or sets the name of the test. Must not be null or empty (all whitespace isn't allowed either)
/// </summary>
/// <value>The name of the test.</value>
public string TestName { get; set; }
/// <summary>
/// Gets or sets the message.
/// </summary>
/// <value>The message.</value>
public string Message { get; set; }
/// <summary>
/// Gets a value indicating whether this <see cref="T:Xamarin.Android.UnitTests.TestFailureInfo"/> has info
/// about failure.
/// </summary>
/// <value><c>true</c> info exists; otherwise, <c>false</c>.</value>
public bool HasInfo => !String.IsNullOrEmpty (TestName?.Trim ()) && !String.IsNullOrEmpty (Message);
}
}

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

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Xamarin.iOS.UnitTests
{
public abstract class TestRunner
{
public long InconclusiveTests { get; protected set; } = 0;
public long FailedTests { get; protected set; } = 0;
public long PassedTests { get; protected set; } = 0;
public long SkippedTests { get; protected set; } = 0;
public long ExecutedTests { get; protected set; } = 0;
public long TotalTests { get; protected set; } = 0;
public long FilteredTests { get; protected set; } = 0;
public bool RunInParallel { get; set; } = false;
public string TestsRootDirectory { get; set; }
public TextWriter Writer { get; set; }
public List<TestFailureInfo> FailureInfos { get; } = new List<TestFailureInfo> ();
protected LogWriter Logger { get; }
protected abstract string ResultsFileName { get; set; }
protected TestRunner (LogWriter logger)
{
Logger = logger ?? throw new ArgumentNullException (nameof (logger));
}
public abstract void Run (IList <TestAssemblyInfo> testAssemblies);
public abstract string WriteResultsToFile ();
public abstract void WriteResultsToFile (TextWriter writer);
protected void OnError (string message)
{
Logger.OnError (message);
}
protected void OnWarning (string message)
{
Logger.OnWarning (message);
}
protected void OnDebug (string message)
{
Logger.OnDebug (message);
}
protected void OnDiagnostic (string message)
{
Logger.OnDiagnostic (message);
}
protected void OnInfo (string message)
{
Logger.OnInfo (message);
}
protected void OnAssemblyStart (Assembly asm)
{
}
protected void OnAssemblyFinish (Assembly asm)
{
}
protected void LogFailureSummary ()
{
if (FailureInfos == null || FailureInfos.Count == 0)
return;
OnInfo ("Failed tests:");
for (int i = 1; i <= FailureInfos.Count; i++) {
TestFailureInfo info = FailureInfos [i - 1];
if (info == null || !info.HasInfo)
continue;
OnInfo ($"{i}) {info.Message}");
}
}
void AssertExecutionState (TestExecutionState state)
{
if (state == null)
throw new ArgumentNullException (nameof (state));
}
protected virtual string GetResultsFilePath ()
{
if (String.IsNullOrEmpty (ResultsFileName))
throw new InvalidOperationException ("Runner didn't specify a valid results file name");
string resultsPath = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
if (!Directory.Exists (resultsPath))
Directory.CreateDirectory (resultsPath);
return Path.Combine (resultsPath, ResultsFileName);
}
}
}

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

@ -0,0 +1,200 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Foundation;
using NUnitLite.Runner;
using NUnit.Framework.Api;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.WorkItems;
using NUnit.Framework.Internal.Filters;
using NUnitTest = NUnit.Framework.Internal.Test;
namespace Xamarin.iOS.UnitTests.NUnit
{
public class NUnitTestRunner : TestRunner, ITestListener
{
Dictionary<string, object> builderSettings;
TestSuiteResult results;
public ITestFilter Filter { get; set; } = TestFilter.Empty;
public bool GCAfterEachFixture { get; set; }
protected override string ResultsFileName { get; set; } = "TestResults.NUnit.xml";
public NUnitTestRunner (LogWriter logger) : base (logger)
{
builderSettings = new Dictionary<string, object> (StringComparer.OrdinalIgnoreCase);
}
public override void Run (IList<TestAssemblyInfo> testAssemblies)
{
if (testAssemblies == null)
throw new ArgumentNullException (nameof (testAssemblies));
var builder = new NUnitLiteTestAssemblyBuilder ();
var runner = new NUnitLiteTestAssemblyRunner (builder, new FinallyDelegate ());
var testSuite = new TestSuite (NSBundle.MainBundle.BundleIdentifier);
results = new TestSuiteResult (testSuite);
foreach (TestAssemblyInfo assemblyInfo in testAssemblies) {
if (assemblyInfo == null || assemblyInfo.Assembly == null)
continue;
if (!runner.Load (assemblyInfo.Assembly, builderSettings)) {
OnWarning ($"Failed to load tests from assembly '{assemblyInfo.Assembly}");
continue;
}
if (runner.LoadedTest is NUnitTest tests)
testSuite.Add (tests);
// Messy API. .Run returns ITestResult which is, in reality, an instance of TestResult since that's
// what WorkItem returns and we need an instance of TestResult to add it to TestSuiteResult. So, cast
// the return to TestResult and hope for the best.
ITestResult result = null;
try {
OnAssemblyStart (assemblyInfo.Assembly);
result = runner.Run (this, Filter);
} finally {
OnAssemblyFinish (assemblyInfo.Assembly);
}
if (result == null)
continue;
var testResult = result as TestResult;
if (testResult == null)
throw new InvalidOperationException ($"Unexpected test result type '{result.GetType ()}'");
results.AddResult (testResult);
}
LogFailureSummary ();
}
public bool Pass (ITest test)
{
return true;
}
public void TestFinished (ITestResult result)
{
if (result.Test is TestSuite) {
//if (!result.IsError && !result.IsFailure && !result.IsSuccess && !result.Executed)
//Writer.WriteLine ("\t[INFO] {0}", result.Message);
if (result.ResultState.Status != TestStatus.Failed &&
result.ResultState.Status != TestStatus.Skipped &&
result.ResultState.Status != TestStatus.Passed &&
result.ResultState.Status != TestStatus.Inconclusive) {
Logger.OnInfo ($"\t[INFO] {result.Message}");
}
string name = result.Test.Name;
if (!String.IsNullOrEmpty (name))
Logger.OnInfo ($"{name} : {result.Duration.TotalMilliseconds} ms\n");
if (GCAfterEachFixture)
GC.Collect ();
} else {
var sb = new StringBuilder ();
switch (result.ResultState.Status) {
case TestStatus.Passed:
sb.Append ("\t[PASS] ");
PassedTests++;
break;
case TestStatus.Skipped:
sb.Append ("\t[IGNORED] ");
SkippedTests++;
break;
case TestStatus.Failed:
sb.Append ("\t[FAIL] ");
FailedTests++;
break;
case TestStatus.Inconclusive:
sb.Append ("\t[INCONCLUSIVE] ");
InconclusiveTests++;
break;
default:
sb.Append ("\t[INFO] ");
break;
}
TotalTests++;
sb.Append (result.Test.FixtureType.Name);
sb.Append (".");
sb.Append (result.Test.Name);
string message = result.Message;
if (!string.IsNullOrEmpty (message)) {
message = message.Replace ("\r\n", "\\r\\n");
sb.Append ($" : {message}");
}
Logger.OnInfo (sb.ToString ());
string stacktrace = result.StackTrace;
if (!string.IsNullOrEmpty (result.StackTrace)) {
string[] lines = stacktrace.Split (new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
Logger.OnInfo ($"\t\t{line}");
}
if (result.ResultState.Status == TestStatus.Failed) {
FailureInfos.Add (new TestFailureInfo {
TestName = result.Test.FullName,
Message = sb.ToString ()
});
}
}
}
public void TestOutput (TestOutput testOutput)
{
if (testOutput == null || String.IsNullOrEmpty (testOutput.Text))
return;
string kind = testOutput.Type.ToString ();
foreach (string l in testOutput.Text.Split ('\n')) {
Logger.OnInfo ($" {kind}: {l}");
}
}
public void TestStarted (ITest test)
{
if (test == null)
return;
if (!string.IsNullOrEmpty (TestsRootDirectory))
Environment.CurrentDirectory = TestsRootDirectory;
if (test is TestSuite) {
Logger.OnInfo (test.Name);
}
}
public override string WriteResultsToFile ()
{
if (results == null)
return string.Empty;
string ret = GetResultsFilePath ();
if (string.IsNullOrEmpty (ret))
return string.Empty;
var resultsXml = new NUnit2XmlOutputWriter (DateTime.UtcNow);
resultsXml.WriteResultFile (results, ret);
return ret;
}
public override void WriteResultsToFile (TextWriter writer)
{
if (results == null)
return;
var resultsXml = new NUnit2XmlOutputWriter (DateTime.UtcNow);
resultsXml.WriteResultFile (results, writer);
}
}
}

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

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output cdata-section-elements="message stack-trace"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="assemblies">
<test-results name="Test results" errors="0" inconclusive="0" ignored="0" invalid="0" not-run="0">
<xsl:attribute name="date">
<xsl:value-of select="assembly[1]/@run-date"/>
</xsl:attribute>
<xsl:attribute name="time">
<xsl:value-of select="assembly[1]/@run-time"/>
</xsl:attribute>
<xsl:attribute name="total">
<xsl:value-of select="sum(assembly/@total)"/>
</xsl:attribute>
<xsl:attribute name="failures">
<xsl:value-of select="sum(assembly/@failed)"/>
</xsl:attribute>
<xsl:attribute name="skipped">
<xsl:value-of select="sum(assembly/@skipped)"/>
</xsl:attribute>
<environment os-version="unknown" platform="unknown" cwd="unknown" machine-name="unknown" user="unknown" user-domain="unknown">
<xsl:attribute name="nunit-version">
<xsl:value-of select="assembly[1]/@test-framework"/>
</xsl:attribute>
<xsl:attribute name="clr-version">
<xsl:value-of select="assembly[1]/@environment"/>
</xsl:attribute>
</environment>
<culture-info current-culture="unknown" current-uiculture="unknown" />
<test-suite type="Assemblies" name="xUnit.net Tests" executed="True">
<xsl:attribute name="success">
<xsl:if test="sum(assembly/@failed) > 0">False</xsl:if>
<xsl:if test="sum(assembly/@failed) = 0">True</xsl:if>
</xsl:attribute>
<xsl:attribute name="result">
<xsl:if test="sum(assembly/@failed) > 0">Failure</xsl:if>
<xsl:if test="sum(assembly/@failed) = 0">Success</xsl:if>
</xsl:attribute>
<xsl:attribute name="time">
<xsl:value-of select="sum(assembly/@time)"/>
</xsl:attribute>
<results>
<xsl:apply-templates select="assembly"/>
</results>
</test-suite>
</test-results>
</xsl:template>
<xsl:template match="assembly">
<test-suite type="Assembly" executed="True">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="result">
<xsl:if test="@failed > 0">Failure</xsl:if>
<xsl:if test="@failed = 0">Success</xsl:if>
</xsl:attribute>
<xsl:attribute name="success">
<xsl:if test="@failed > 0">False</xsl:if>
<xsl:if test="@failed = 0">True</xsl:if>
</xsl:attribute>
<xsl:attribute name="time">
<xsl:value-of select="@time"/>
</xsl:attribute>
<results>
<xsl:apply-templates select="collection"/>
</results>
</test-suite>
</xsl:template>
<xsl:template match="collection">
<test-suite type="TestCollection" executed="True">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="result">
<xsl:if test="@failed > 0">Failure</xsl:if>
<xsl:if test="@failed = 0">Success</xsl:if>
</xsl:attribute>
<xsl:attribute name="success">
<xsl:if test="@failed > 0">False</xsl:if>
<xsl:if test="@failed = 0">True</xsl:if>
</xsl:attribute>
<xsl:attribute name="time">
<xsl:value-of select="@time"/>
</xsl:attribute>
<xsl:if test="failure">
<xsl:copy-of select="failure"/>
</xsl:if>
<xsl:if test="reason">
<reason>
<xsl:apply-templates select="reason"/>
</reason>
</xsl:if>
<results>
<xsl:apply-templates select="test"/>
</results>
</test-suite>
</xsl:template>
<xsl:template match="test">
<test-case>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="executed">
<xsl:if test="@result='Skip'">False</xsl:if>
<xsl:if test="@result!='Skip'">True</xsl:if>
</xsl:attribute>
<xsl:attribute name="result">
<xsl:if test="@result='Fail'">Failure</xsl:if>
<xsl:if test="@result='Pass'">Success</xsl:if>
<xsl:if test="@result='Skip'">Skipped</xsl:if>
</xsl:attribute>
<xsl:if test="@result!='Skip'">
<xsl:attribute name="success">
<xsl:if test="@result='Fail'">False</xsl:if>
<xsl:if test="@result='Pass'">True</xsl:if>
</xsl:attribute>
</xsl:if>
<xsl:if test="@time">
<xsl:attribute name="time">
<xsl:value-of select="@time"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="traits"/>
<xsl:if test="reason">
<reason>
<message>
<xsl:apply-templates select="reason"/>
</message>
</reason>
</xsl:if>
<xsl:apply-templates select="failure"/>
</test-case>
</xsl:template>
<xsl:template match="traits">
<properties>
<xsl:apply-templates select="trait"/>
</properties>
</xsl:template>
<xsl:template match="trait">
<property>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="@value"/>
</xsl:attribute>
</property>
</xsl:template>
<xsl:template match="failure">
<failure>
<xsl:copy-of select="node()"/>
</failure>
</xsl:template>
</xsl:stylesheet>

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

@ -0,0 +1,28 @@
using System;
namespace Xamarin.iOS.UnitTests.XUnit
{
public class XUnitFilter
{
public string TraitName { get; }
public string TraitValue { get; }
public string TestCaseName { get; }
public bool Exclude { get; }
public XUnitFilterType FilterType { get; }
public XUnitFilter (string testCaseName, bool exclude)
{
FilterType = XUnitFilterType.TypeName;
TestCaseName = testCaseName;
Exclude = exclude;
}
public XUnitFilter (string traitName, string traitValue, bool exclude)
{
FilterType = XUnitFilterType.Trait;
TraitName = traitName;
TraitValue = traitValue;
Exclude = exclude;
}
}
}

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

@ -0,0 +1,10 @@
using System;
namespace Xamarin.iOS.UnitTests.XUnit
{
public enum XUnitFilterType
{
Trait,
TypeName,
}
}

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

@ -0,0 +1,9 @@
namespace Xamarin.iOS.UnitTests.XUnit
{
public enum XUnitResultFileFormat
{
XunitV2,
XunitV1,
NUnit
}
}

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

@ -0,0 +1,901 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using Xunit;
using Xunit.Abstractions;
namespace Xamarin.iOS.UnitTests.XUnit
{
public class XUnitTestRunner : TestRunner
{
readonly TestMessageSink messageSink;
XElement assembliesElement;
List<XUnitFilter> filters;
public XUnitResultFileFormat ResultFileFormat { get; set; } = XUnitResultFileFormat.NUnit;
public AppDomainSupport AppDomainSupport { get; set; } = AppDomainSupport.Denied;
protected override string ResultsFileName { get; set; } = "TestResults.xUnit.xml";
public XUnitTestRunner (LogWriter logger) : base (logger)
{
messageSink = new TestMessageSink ();
messageSink.Diagnostics.DiagnosticMessageEvent += HandleDiagnosticMessage;
messageSink.Diagnostics.ErrorMessageEvent += HandleDiagnosticErrorMessage;
messageSink.Discovery.DiscoveryCompleteMessageEvent += HandleDiscoveryCompleteMessage;
messageSink.Discovery.TestCaseDiscoveryMessageEvent += HandleDiscoveryTestCaseMessage;
messageSink.Runner.TestAssemblyDiscoveryFinishedEvent += HandleTestAssemblyDiscoveryFinished;
messageSink.Runner.TestAssemblyDiscoveryStartingEvent += HandleTestAssemblyDiscoveryStarting;
messageSink.Runner.TestAssemblyExecutionFinishedEvent += HandleTestAssemblyExecutionFinished;
messageSink.Runner.TestAssemblyExecutionStartingEvent += HandleTestAssemblyExecutionStarting;
messageSink.Runner.TestExecutionSummaryEvent += HandleTestExecutionSummary;
messageSink.Execution.AfterTestFinishedEvent += (MessageHandlerArgs <IAfterTestFinished> args) => HandleEvent ("AfterTestFinishedEvent", args, HandleAfterTestFinished);
messageSink.Execution.AfterTestStartingEvent += (MessageHandlerArgs <IAfterTestStarting> args) => HandleEvent ("AfterTestStartingEvent", args, HandleAfterTestStarting);
messageSink.Execution.BeforeTestFinishedEvent += (MessageHandlerArgs<IBeforeTestFinished> args) => HandleEvent ("BeforeTestFinishedEvent", args, HandleBeforeTestFinished);
messageSink.Execution.BeforeTestStartingEvent += (MessageHandlerArgs<IBeforeTestStarting> args) => HandleEvent ("BeforeTestStartingEvent", args, HandleBeforeTestStarting);
messageSink.Execution.TestAssemblyCleanupFailureEvent += (MessageHandlerArgs<ITestAssemblyCleanupFailure> args) => HandleEvent ("TestAssemblyCleanupFailureEvent", args, HandleTestAssemblyCleanupFailure);
messageSink.Execution.TestAssemblyFinishedEvent += (MessageHandlerArgs<ITestAssemblyFinished> args) => HandleEvent ("TestAssemblyFinishedEvent", args, HandleTestAssemblyFinished);
messageSink.Execution.TestAssemblyStartingEvent += (MessageHandlerArgs<ITestAssemblyStarting> args) => HandleEvent ("TestAssemblyStartingEvent", args, HandleTestAssemblyStarting);
messageSink.Execution.TestCaseCleanupFailureEvent += (MessageHandlerArgs<ITestCaseCleanupFailure> args) => HandleEvent ("TestCaseCleanupFailureEvent", args, HandleTestCaseCleanupFailure);
messageSink.Execution.TestCaseFinishedEvent += (MessageHandlerArgs<ITestCaseFinished> args) => HandleEvent ("TestCaseFinishedEvent", args, HandleTestCaseFinished);
messageSink.Execution.TestCaseStartingEvent += (MessageHandlerArgs<ITestCaseStarting> args) => HandleEvent ("TestStartingEvent", args, HandleTestCaseStarting);
messageSink.Execution.TestClassCleanupFailureEvent += (MessageHandlerArgs<ITestClassCleanupFailure> args) => HandleEvent ("TestClassCleanupFailureEvent", args, HandleTestClassCleanupFailure);
messageSink.Execution.TestClassConstructionFinishedEvent += (MessageHandlerArgs<ITestClassConstructionFinished> args) => HandleEvent ("TestClassConstructionFinishedEvent", args, HandleTestClassConstructionFinished);
messageSink.Execution.TestClassConstructionStartingEvent += (MessageHandlerArgs<ITestClassConstructionStarting> args) => HandleEvent ("TestClassConstructionStartingEvent", args, HandleTestClassConstructionStarting);
messageSink.Execution.TestClassDisposeFinishedEvent += (MessageHandlerArgs<ITestClassDisposeFinished> args) => HandleEvent ("TestClassDisposeFinishedEvent", args, HandleTestClassDisposeFinished);
messageSink.Execution.TestClassDisposeStartingEvent += (MessageHandlerArgs<ITestClassDisposeStarting> args) => HandleEvent ("TestClassDisposeStartingEvent", args, HandleTestClassDisposeStarting);
messageSink.Execution.TestClassFinishedEvent += (MessageHandlerArgs<ITestClassFinished> args) => HandleEvent ("TestClassFinishedEvent", args, HandleTestClassFinished);
messageSink.Execution.TestClassStartingEvent += (MessageHandlerArgs<ITestClassStarting> args) => HandleEvent ("TestClassStartingEvent", args, HandleTestClassStarting);
messageSink.Execution.TestCleanupFailureEvent += (MessageHandlerArgs<ITestCleanupFailure> args) => HandleEvent ("TestCleanupFailureEvent", args, HandleTestCleanupFailure);
messageSink.Execution.TestCollectionCleanupFailureEvent += (MessageHandlerArgs<ITestCollectionCleanupFailure> args) => HandleEvent ("TestCollectionCleanupFailureEvent", args, HandleTestCollectionCleanupFailure);
messageSink.Execution.TestCollectionFinishedEvent += (MessageHandlerArgs<ITestCollectionFinished> args) => HandleEvent ("TestCollectionFinishedEvent", args, HandleTestCollectionFinished);
messageSink.Execution.TestCollectionStartingEvent += (MessageHandlerArgs<ITestCollectionStarting> args) => HandleEvent ("TestCollectionStartingEvent", args, HandleTestCollectionStarting);
messageSink.Execution.TestFailedEvent += (MessageHandlerArgs<ITestFailed> args) => HandleEvent ("TestFailedEvent", args, HandleTestFailed);
messageSink.Execution.TestFinishedEvent += (MessageHandlerArgs<ITestFinished> args) => HandleEvent ("TestFinishedEvent", args, HandleTestFinished);
messageSink.Execution.TestMethodCleanupFailureEvent += (MessageHandlerArgs<ITestMethodCleanupFailure> args) => HandleEvent ("TestMethodCleanupFailureEvent", args, HandleTestMethodCleanupFailure);
messageSink.Execution.TestMethodFinishedEvent += (MessageHandlerArgs<ITestMethodFinished> args) => HandleEvent ("TestMethodFinishedEvent", args, HandleTestMethodFinished);
messageSink.Execution.TestMethodStartingEvent += (MessageHandlerArgs<ITestMethodStarting> args) => HandleEvent ("TestMethodStartingEvent", args, HandleTestMethodStarting);
messageSink.Execution.TestOutputEvent += (MessageHandlerArgs<ITestOutput> args) => HandleEvent ("TestOutputEvent", args, HandleTestOutput);
messageSink.Execution.TestPassedEvent += (MessageHandlerArgs<ITestPassed> args) => HandleEvent ("TestPassedEvent", args, HandleTestPassed);
messageSink.Execution.TestSkippedEvent += (MessageHandlerArgs<ITestSkipped> args) => HandleEvent ("TestSkippedEvent", args, HandleTestSkipped);
messageSink.Execution.TestStartingEvent += (MessageHandlerArgs<ITestStarting> args) => HandleEvent ("TestStartingEvent", args, HandleTestStarting);
}
public void SetFilters (List<XUnitFilter> newFilters)
{
if (newFilters == null) {
filters = null;
return;
}
if (filters == null)
filters = new List<XUnitFilter> ();
filters.AddRange (newFilters);
}
void HandleEvent<T> (string name, MessageHandlerArgs <T> args, Action <MessageHandlerArgs<T>> actualHandler) where T: class, IMessageSinkMessage
{
try {
actualHandler (args);
} catch (Exception ex) {
OnError ($"Handler for event {name} failed with exception");
OnError (ex.ToString ());
}
}
void HandleTestStarting (MessageHandlerArgs<ITestStarting> args)
{
if (args == null || args.Message == null)
return;
OnDebug ("Test starting");
LogTestDetails (args.Message.Test, log: OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, args.Message.TestCase, OnDiagnostic);
}
void HandleTestSkipped (MessageHandlerArgs <ITestSkipped> args)
{
if (args == null || args.Message == null)
return;
SkippedTests++;
OnInfo ($"\t[IGNORED] {args.Message.TestCase.DisplayName}");
LogTestDetails (args.Message.Test, log: OnDebug);
LogTestOutput (args.Message, log: OnDiagnostic);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestPassed (MessageHandlerArgs <ITestPassed> args)
{
if (args == null || args.Message == null)
return;
PassedTests++;
OnInfo ($"\t[PASS] {args.Message.TestCase.DisplayName}");
LogTestDetails (args.Message.Test, log: OnDebug);
LogTestOutput (args.Message, log: OnDiagnostic);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestOutput (MessageHandlerArgs <ITestOutput> args)
{
if (args == null || args.Message == null)
return;
OnInfo (args.Message.Output);
}
void HandleTestMethodStarting (MessageHandlerArgs <ITestMethodStarting> args)
{
if (args == null || args.Message == null)
return;
OnDebug ("Test method starting");
LogTestMethodDetails (args.Message.TestMethod.Method, log: OnDebug);
LogTestClassDetails (args.Message.TestMethod.TestClass, log: OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestMethodFinished (MessageHandlerArgs <ITestMethodFinished> args)
{
if (args == null || args.Message == null)
return;
OnDebug ("Test method finished");
LogTestMethodDetails (args.Message.TestMethod.Method, log: OnDebug);
LogTestClassDetails (args.Message.TestMethod.TestClass, log: OnDebug);
LogSummary (args.Message, log: OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestMethodCleanupFailure (MessageHandlerArgs <ITestMethodCleanupFailure> args)
{
if (args == null || args.Message == null)
return;
OnError ($"Test method cleanup failure{GetAssemblyInfo (args.Message.TestAssembly)}");
LogTestMethodDetails (args.Message.TestMethod.Method, log: OnError);
LogTestClassDetails (args.Message.TestMethod.TestClass, log: OnError);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
LogFailureInformation (args.Message, log: OnError);
}
void HandleTestFinished (MessageHandlerArgs <ITestFinished> args)
{
if (args == null || args.Message == null)
return;
ExecutedTests++;
OnDiagnostic ("Test finished");
LogTestDetails (args.Message.Test, log: OnDiagnostic);
LogTestOutput (args.Message, log: OnDiagnostic);
ReportTestCases (" Associated", args.Message.TestCases, args.Message.TestCase, OnDiagnostic);
}
void HandleTestFailed (MessageHandlerArgs<ITestFailed> args)
{
if (args == null || args.Message == null)
return;
FailedTests++;
string assemblyInfo = GetAssemblyInfo (args.Message.TestAssembly);
var sb = new StringBuilder ($"\t[FAIL] {args.Message.TestCase.DisplayName}");
LogTestDetails (args.Message.Test, OnError, sb);
sb.AppendLine ();
if (!string.IsNullOrEmpty (assemblyInfo))
sb.AppendLine ($" Assembly: {assemblyInfo}");
LogSourceInformation (args.Message.TestCase.SourceInformation, OnError, sb);
LogFailureInformation (args.Message, OnError, sb);
sb.AppendLine ();
LogTestOutput (args.Message, OnError, sb);
sb.AppendLine ();
if (args.Message.TestCase.Traits != null && args.Message.TestCase.Traits.Count > 0) {
foreach (var kvp in args.Message.TestCase.Traits) {
string message = $" Test trait name: {kvp.Key}";
OnError (message);
sb.AppendLine (message);
foreach (string v in kvp.Value) {
message = $" value: {v}";
OnError (message);
sb.AppendLine (message);
}
}
sb.AppendLine ();
}
ReportTestCases (" Associated", args.Message.TestCases, args.Message.TestCase, OnDiagnostic);
FailureInfos.Add (new TestFailureInfo {
TestName = args.Message.Test?.DisplayName,
Message = sb.ToString ()
});
OnInfo ($"\t[FAIL] {args.Message.Test.TestCase.DisplayName}");
OnInfo (sb.ToString ());
}
void HandleTestCollectionStarting (MessageHandlerArgs <ITestCollectionStarting> args)
{
if (args == null || args.Message == null)
return;
OnInfo ($"\n{args.Message.TestCollection.DisplayName}");
OnDebug ("Test collection starting");
LogTestCollectionDetails (args.Message.TestCollection, log: OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestCollectionFinished (MessageHandlerArgs <ITestCollectionFinished> args)
{
if (args == null || args.Message == null)
return;
OnDebug ("Test collection finished");
LogSummary (args.Message, log: OnDebug);
LogTestCollectionDetails (args.Message.TestCollection, log: OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestCollectionCleanupFailure (MessageHandlerArgs <ITestCollectionCleanupFailure> args)
{
if (args == null || args.Message == null)
return;
OnError ("Error during test collection cleanup");
LogTestCollectionDetails (args.Message.TestCollection, log:OnError);
ReportTestCases (" Associated", args.Message.TestCases, log: OnError);
LogFailureInformation (args.Message, log: OnError);
}
void HandleTestCleanupFailure (MessageHandlerArgs <ITestCleanupFailure> args)
{
if (args == null || args.Message == null)
return;
OnError ($"Test cleanup failure{GetAssemblyInfo (args.Message.TestAssembly)}");
LogTestDetails (args.Message.Test, log: OnError);
ReportTestCases (" Associated", args.Message.TestCases, log: OnError);
LogFailureInformation (args.Message, log: OnError);
}
void HandleTestClassStarting (MessageHandlerArgs <ITestClassStarting> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ("Test class starting");
LogTestClassDetails (args.Message.TestClass, log: OnDiagnostic);
}
void HandleTestClassFinished (MessageHandlerArgs <ITestClassFinished> args)
{
if (args == null || args.Message == null)
return;
OnDebug ("Test class finished");
OnInfo ($"{args.Message.TestClass.Class.Name} {args.Message.ExecutionTime} ms");
LogTestClassDetails (args.Message.TestClass, OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestClassDisposeStarting (MessageHandlerArgs <ITestClassDisposeStarting> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ("Test class dispose starting");
LogTestDetails (args.Message.Test, log: OnDiagnostic);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestClassDisposeFinished (MessageHandlerArgs <ITestClassDisposeFinished> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ("Test class dispose finished");
LogTestDetails (args.Message.Test, log: OnDiagnostic);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestClassConstructionStarting (MessageHandlerArgs <ITestClassConstructionStarting> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ("Test class construction starting");
LogTestDetails (args.Message.Test, OnDiagnostic);
ReportTestCases (" Associated", args.Message.TestCases, args.Message.TestCase, OnDiagnostic);
}
void HandleTestClassConstructionFinished (MessageHandlerArgs <ITestClassConstructionFinished> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ("Test class construction finished");
LogTestDetails (args.Message.Test, log: OnDiagnostic);
ReportTestCases (" Associated", args.Message.TestCases, args.Message.TestCase, OnDiagnostic);
}
void HandleTestClassCleanupFailure (MessageHandlerArgs <ITestClassCleanupFailure> args)
{
if (args == null || args.Message == null)
return;
OnError ($"Test class cleanup error{GetAssemblyInfo (args.Message.TestAssembly)}");
LogTestClassDetails (args.Message.TestClass, log: OnError);
LogTestCollectionDetails (args.Message.TestCollection, log: OnError);
ReportTestCases (" Associated", args.Message.TestCases, log: OnError);
LogFailureInformation (args.Message, log: OnError);
}
void HandleTestCaseStarting (MessageHandlerArgs <ITestCaseStarting> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ("Test case starting");
ReportTestCase (" Starting", args.Message.TestCase, log: OnDiagnostic);
ReportTestCases (" Associated", args.Message.TestCases, args.Message.TestCase, OnDiagnostic);
}
void HandleTestCaseFinished (MessageHandlerArgs <ITestCaseFinished> args)
{
if (args == null || args.Message == null)
return;
OnDebug ("Test case finished executing");
ReportTestCase (" Finished", args.Message.TestCase, log: OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, args.Message.TestCase, OnDebug);
LogSummary (args.Message, log: OnDebug);
}
void HandleTestCaseCleanupFailure (MessageHandlerArgs <ITestCaseCleanupFailure> args)
{
if (args == null || args.Message == null)
return;
OnError ("Test case cleanup failure");
ReportTestCase (" Failed", args.Message.TestCase, log: OnError);
ReportTestCases (" Associated", args.Message.TestCases, args.Message.TestCase, OnError);
LogFailureInformation (args.Message, log: OnError);
}
void HandleTestAssemblyStarting (MessageHandlerArgs <ITestAssemblyStarting> args)
{
if (args == null || args.Message == null)
return;
OnInfo ($"[Test environment: {args.Message.TestEnvironment}]");
OnInfo ($"[Test framework: {args.Message.TestFrameworkDisplayName}]");
LogAssemblyInformation (args.Message, log: OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDebug);
}
void HandleTestAssemblyFinished (MessageHandlerArgs <ITestAssemblyFinished> args)
{
if (args == null || args.Message == null)
return;
TotalTests = args.Message.TestsRun; // HACK: We are not counting correctly all the tests
OnDebug ("Execution process for assembly finished");
LogAssemblyInformation (args.Message, log: OnDebug);
LogSummary (args.Message, log: OnDebug);
ReportTestCases (" Associated", args.Message.TestCases, log: OnDiagnostic);
}
void HandleTestAssemblyCleanupFailure (MessageHandlerArgs <ITestAssemblyCleanupFailure> args)
{
if (args == null || args.Message == null)
return;
OnError ("Assembly cleanup failure");
LogAssemblyInformation (args.Message, OnError);
ReportTestCases (" Associated", args.Message.TestCases, log: OnError);
LogFailureInformation (args.Message, log: OnError);
}
void HandleBeforeTestStarting (MessageHandlerArgs <IBeforeTestStarting> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ($"'Before' method for test '{args.Message.Test.DisplayName}' starting");
}
void HandleBeforeTestFinished (MessageHandlerArgs <IBeforeTestFinished> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ($"'Before' method for test '{args.Message.Test.DisplayName}' finished");
}
void HandleAfterTestStarting (MessageHandlerArgs <IAfterTestStarting> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ($"'After' method for test '{args.Message.Test.DisplayName}' starting");
}
void HandleAfterTestFinished (MessageHandlerArgs <IAfterTestFinished> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic ($"'After' method for test '{args.Message.Test.DisplayName}' finished");
}
void HandleTestExecutionSummary (MessageHandlerArgs <ITestExecutionSummary> args)
{
if (args == null || args.Message == null)
return;
OnInfo ("All tests finished");
OnInfo ($" Elapsed time: {args.Message.ElapsedClockTime}");
if (args.Message.Summaries == null || args.Message.Summaries.Count == 0)
return;
foreach (KeyValuePair <string, ExecutionSummary> summary in args.Message.Summaries) {
OnInfo (String.Empty);
OnInfo ($" Assembly: {summary.Key}");
LogSummary (summary.Value, log: OnDebug);
}
}
void HandleTestAssemblyExecutionStarting (MessageHandlerArgs <ITestAssemblyExecutionStarting> args)
{
if (args == null || args.Message == null)
return;
OnInfo ($"Execution starting for assembly {args.Message.Assembly.AssemblyFilename}");
}
void HandleTestAssemblyExecutionFinished (MessageHandlerArgs <ITestAssemblyExecutionFinished> args)
{
if (args == null || args.Message == null)
return;
OnInfo ($"Execution finished for assembly {args.Message.Assembly.AssemblyFilename}");
LogSummary (args.Message.ExecutionSummary, log: OnDebug);
}
void HandleTestAssemblyDiscoveryStarting (MessageHandlerArgs <ITestAssemblyDiscoveryStarting> args)
{
if (args == null || args.Message == null)
return;
OnInfo ($"Discovery for assembly {args.Message.Assembly.AssemblyFilename} starting");
OnInfo ($" Will use AppDomain: {args.Message.AppDomain.YesNo ()}");
}
void HandleTestAssemblyDiscoveryFinished (MessageHandlerArgs <ITestAssemblyDiscoveryFinished> args)
{
if (args == null || args.Message == null)
return;
OnInfo ($"Discovery for assembly {args.Message.Assembly.AssemblyFilename} finished");
OnInfo ($" Test cases discovered: {args.Message.TestCasesDiscovered}");
OnInfo ($" Test cases to run: {args.Message.TestCasesToRun}");
}
void HandleDiagnosticMessage (MessageHandlerArgs <IDiagnosticMessage> args)
{
if (args == null || args.Message == null)
return;
OnDiagnostic (args.Message.Message);
}
void HandleDiagnosticErrorMessage (MessageHandlerArgs <IErrorMessage> args)
{
if (args == null || args.Message == null)
return;
LogFailureInformation (args.Message);
}
void HandleDiscoveryCompleteMessage (MessageHandlerArgs <IDiscoveryCompleteMessage> args)
{
if (args == null || args.Message == null)
return;
OnInfo ("Discovery complete");
}
void HandleDiscoveryTestCaseMessage (MessageHandlerArgs <ITestCaseDiscoveryMessage> args)
{
if (args == null || args.Message == null)
return;
ITestCase singleTestCase = args.Message.TestCase;
ReportTestCases ("Discovered", args.Message.TestCases, log: OnInfo, ignore: (ITestCase tc) => tc == singleTestCase);
ReportTestCase ("Discovered", singleTestCase, log: OnInfo);
}
void ReportTestCases (string verb, IEnumerable<ITestCase> testCases, ITestCase ignoreTestCase, Action<string> log = null)
{
ReportTestCases (verb, testCases, log, (ITestCase tc) => ignoreTestCase == tc);
}
void ReportTestCases (string verb, IEnumerable<ITestCase> testCases, Action<string> log = null, Func<ITestCase, bool> ignore = null)
{
if (testCases == null)
return;
foreach (ITestCase tc in testCases) {
if (ignore != null && ignore (tc))
continue;
ReportTestCase (verb, tc, log);
}
}
void ReportTestCase (string verb, ITestCase testCase, Action<string> log = null)
{
if (testCase == null)
return;
EnsureLogger (log)($"{verb} test case: {testCase.DisplayName}");
}
void LogAssemblyInformation (ITestAssemblyMessage message, Action<string> log = null, StringBuilder sb = null)
{
if (message == null)
return;
do_log ($"[Assembly name: {message.TestAssembly.Assembly.Name}]", log, sb);
do_log ($"[Assembly path: {message.TestAssembly.Assembly.AssemblyPath}]", OnDiagnostic, sb);
}
void LogFailureInformation (IFailureInformation info, Action<string> log = null, StringBuilder sb = null)
{
if (info == null)
return;
string message = ExceptionUtility.CombineMessages (info);
do_log ($" Exception messages: {message}", log, sb);
string traces = ExceptionUtility.CombineStackTraces (info);
do_log ($" Exception stack traces: {traces}", log, sb);
}
Action<string> EnsureLogger (Action<string> log)
{
return log ?? OnInfo;
}
void LogTestMethodDetails (IMethodInfo method, Action<string> log = null, StringBuilder sb = null)
{
log = EnsureLogger (log);
//log ($" Test method name: {method.Type.Name}.{method.Name}");
}
void LogTestOutput (ITestFinished test, Action<string> log = null, StringBuilder sb = null)
{
LogTestOutput (test.ExecutionTime, test.Output, log, sb);
}
void LogTestOutput (ITestResultMessage test, Action<string> log = null, StringBuilder sb = null)
{
LogTestOutput (test.ExecutionTime, test.Output, log, sb);
}
void LogTestOutput (decimal executionTime, string output, Action<string> log = null, StringBuilder sb = null)
{
do_log ($" Execution time: {executionTime}", log, sb);
if (!String.IsNullOrEmpty (output)) {
do_log (" **** Output start ****", log, sb);
foreach (string line in output.Split ('\n'))
do_log (line, log, sb);
do_log (" **** Output end ****", log, sb);
}
}
void LogTestCollectionDetails (ITestCollection collection, Action<string> log = null, StringBuilder sb = null)
{
do_log ($" Test collection: {collection.DisplayName}", log, sb);
}
void LogTestClassDetails (ITestClass klass, Action<string> log = null, StringBuilder sb = null)
{
do_log ($" Class name: {klass.Class.Name}", log, sb);
do_log ($" Class assembly: {klass.Class.Assembly.Name}", OnDebug, sb);
do_log ($" Class assembly path: {klass.Class.Assembly.AssemblyPath}", OnDebug, sb);
}
void LogTestDetails (ITest test, Action<string> log = null, StringBuilder sb = null)
{
do_log ($" Test name: {test.DisplayName}", log, sb);
if (String.Compare (test.DisplayName, test.TestCase.DisplayName, StringComparison.Ordinal) != 0)
do_log ($" Test case: {test.TestCase.DisplayName}", log, sb);
}
void LogSummary (IFinishedMessage summary, Action<string> log = null, StringBuilder sb = null)
{
do_log ($" Time: {summary.ExecutionTime}", log, sb);
do_log ($" Total tests run: {summary.TestsRun}", log, sb);
do_log ($" Skipped tests: {summary.TestsSkipped}", log, sb);
do_log ($" Failed tests: {summary.TestsFailed}", log, sb);
}
void LogSummary (ExecutionSummary summary, Action<string> log = null, StringBuilder sb = null)
{
do_log ($" Time: {summary.Time}", log, sb);
do_log ($" Total tests run: {summary.Total}", log, sb);
do_log ($" Total errors: {summary.Errors}", log, sb);
do_log ($" Skipped tests: {summary.Skipped}", log, sb);
do_log ($" Failed tests: {summary.Failed}", log, sb);
}
void LogSourceInformation (ISourceInformation source, Action<string> log = null, StringBuilder sb = null)
{
if (source == null || String.IsNullOrEmpty (source.FileName))
return;
string location = source.FileName;
if (source.LineNumber != null && source.LineNumber >= 0)
location += $":{source.LineNumber}";
do_log ($" Source: {location}", log, sb);
sb?.AppendLine ();
}
string GetAssemblyInfo (ITestAssembly assembly)
{
string name = assembly?.Assembly?.Name?.Trim ();
if (String.IsNullOrEmpty (name))
return name;
return $" [{name}]";
}
void do_log (string message, Action<string> log = null, StringBuilder sb = null)
{
log = EnsureLogger (log);
if (sb != null)
sb.Append (message);
log (message);
}
public override void Run (IList <TestAssemblyInfo> testAssemblies)
{
if (testAssemblies == null)
throw new ArgumentNullException (nameof (testAssemblies));
assembliesElement = new XElement ("assemblies");
foreach (TestAssemblyInfo assemblyInfo in testAssemblies) {
if (assemblyInfo == null || assemblyInfo.Assembly == null)
continue;
if (String.IsNullOrEmpty (assemblyInfo.FullPath)) {
OnWarning ($"Assembly '{assemblyInfo.Assembly}' cannot be found on the filesystem. xUnit requires access to actual on-disk file.");
continue;
}
OnInfo ($"Assembly: {assemblyInfo.Assembly} ({assemblyInfo.FullPath})");
XElement assemblyElement = null;
try {
OnAssemblyStart (assemblyInfo.Assembly);
assemblyElement = Run (assemblyInfo.Assembly, assemblyInfo.FullPath);
} finally {
OnAssemblyFinish (assemblyInfo.Assembly);
if (assemblyElement != null)
assembliesElement.Add (assemblyElement);
}
}
LogFailureSummary ();
}
public override string WriteResultsToFile ()
{
if (assembliesElement == null)
return String.Empty;
string outputFilePath = GetResultsFilePath ();
var settings = new XmlWriterSettings { Indent = true };
using (var xmlWriter = XmlWriter.Create (outputFilePath, settings)) {
switch (ResultFileFormat) {
case XUnitResultFileFormat.XunitV2:
assembliesElement.Save (xmlWriter);
break;
case XUnitResultFileFormat.NUnit:
Transform_Results ("NUnitXml.xslt", assembliesElement, xmlWriter); // TODO: Add resource
break;
default:
throw new InvalidOperationException ($"Result output format '{ResultFileFormat}' is not currently supported");
}
}
return outputFilePath;
}
public override void WriteResultsToFile (TextWriter writer)
{
if (assembliesElement == null)
return;
var settings = new XmlWriterSettings { Indent = true };
using (var xmlWriter = XmlWriter.Create (writer, settings)) {
switch (ResultFileFormat) {
case XUnitResultFileFormat.XunitV2:
assembliesElement.Save (xmlWriter);
break;
case XUnitResultFileFormat.NUnit:
try {
Transform_Results ("NUnitXml.xslt", assembliesElement, xmlWriter);
} catch (Exception e) {
writer.WriteLine ($"{e}");
}
break;
default:
throw new InvalidOperationException ($"Result output format '{ResultFileFormat}' is not currently supported");
}
}
}
void Transform_Results (string xsltResourceName, XElement element, XmlWriter writer)
{
var xmlTransform = new System.Xml.Xsl.XslCompiledTransform ();
var name = GetType ().Assembly.GetManifestResourceNames ().Select ((arg) => { arg.EndsWith (xsltResourceName, StringComparison.Ordinal); return arg; }).First ();
if (name == null)
return;
using (var xsltStream = GetType ().Assembly.GetManifestResourceStream (name)) {
if (xsltStream == null) {
throw new Exception ($"Stream with name {name} cannot be found! We have {GetType ().Assembly.GetManifestResourceNames ()[0]}");
}
using (var xsltReader = XmlReader.Create (xsltStream))
using (var xmlReader = element.CreateReader ()) {
xmlTransform.Load (xsltReader);
xmlTransform.Transform (xmlReader, writer);
}
}
}
protected virtual Stream GetConfigurationFileStream (Assembly assembly)
{
if (assembly == null)
throw new ArgumentNullException (nameof (assembly));
string path = assembly.Location?.Trim ();
if (String.IsNullOrEmpty (path))
return null;
path = Path.Combine (path, ".xunit.runner.json");
if (!File.Exists (path))
return null;
return File.OpenRead (path);
}
protected virtual TestAssemblyConfiguration GetConfiguration (Assembly assembly)
{
if (assembly == null)
throw new ArgumentNullException (nameof (assembly));
Stream configStream = GetConfigurationFileStream (assembly);
if (configStream != null) {
using (configStream) {
return ConfigReader.Load (configStream);
}
}
return null;
}
protected virtual ITestFrameworkDiscoveryOptions GetFrameworkOptionsForDiscovery (TestAssemblyConfiguration configuration)
{
if (configuration == null)
throw new ArgumentNullException (nameof (configuration));
return TestFrameworkOptions.ForDiscovery (configuration);
}
protected virtual ITestFrameworkExecutionOptions GetFrameworkOptionsForExecution (TestAssemblyConfiguration configuration)
{
if (configuration == null)
throw new ArgumentNullException (nameof (configuration));
return TestFrameworkOptions.ForExecution (configuration);
}
XElement Run (Assembly assembly, string assemblyPath)
{
using (var frontController = new XunitFrontController (AppDomainSupport, assemblyPath, null, false)) {
using (var discoverySink = new TestDiscoverySink ()) {
var configuration = GetConfiguration (assembly) ?? new TestAssemblyConfiguration ();
ITestFrameworkDiscoveryOptions discoveryOptions = GetFrameworkOptionsForDiscovery (configuration);
discoveryOptions.SetSynchronousMessageReporting (true);
Logger.OnDebug ($"Starting test discovery in the '{assembly}' assembly");
frontController.Find (false, discoverySink, discoveryOptions);
Logger.OnDebug ($"Test discovery in assembly '{assembly}' completed");
discoverySink.Finished.WaitOne ();
if (discoverySink.TestCases == null || discoverySink.TestCases.Count == 0) {
Logger.Info ("No test cases discovered");
return null;
}
TotalTests += discoverySink.TestCases.Count;
List<ITestCase> testCases;
if (filters != null && filters.Count > 0) {
testCases = discoverySink.TestCases.Where (tc => IsIncluded (tc)).ToList ();
FilteredTests += discoverySink.TestCases.Count - testCases.Count;
} else
testCases = discoverySink.TestCases;
var assemblyElement = new XElement ("assembly");
IExecutionSink resultsSink = new DelegatingExecutionSummarySink (messageSink, null, null);
resultsSink = new DelegatingXmlCreationSink (resultsSink, assemblyElement);
ITestFrameworkExecutionOptions executionOptions = GetFrameworkOptionsForExecution (configuration);
executionOptions.SetDisableParallelization (!RunInParallel);
executionOptions.SetSynchronousMessageReporting (true);
try {
frontController.RunTests (testCases, resultsSink, executionOptions);
resultsSink.Finished.WaitOne ();
} finally {
resultsSink.Dispose ();
}
return assemblyElement;
}
}
}
bool IsIncluded (ITestCase testCase)
{
if (testCase.Traits == null || testCase.Traits.Count == 0)
return true;
foreach (XUnitFilter filter in filters) {
List<string> values;
if (filter == null)
continue;
if (filter.FilterType == XUnitFilterType.Trait) {
if (!testCase.Traits.TryGetValue (filter.TraitName, out values))
continue;
if (values == null || values.Count == 0) {
// We have no values and the filter doesn't specify one - that means we match on
// the trait name only.
if (String.IsNullOrEmpty (filter.TraitValue))
return !filter.Exclude;
continue;
}
if (values.Contains (filter.TraitValue, StringComparer.OrdinalIgnoreCase))
return !filter.Exclude;
continue;
}
if (filter.FilterType == XUnitFilterType.TypeName) {
Logger.Info ($"IsIncluded: filter: '{filter.TestCaseName}', test case name: {testCase.DisplayName}");
if (String.Compare (testCase.DisplayName, filter.TestCaseName, StringComparison.OrdinalIgnoreCase) == 0)
return !filter.Exclude;
continue;
}
throw new InvalidOperationException ($"Unsupported filter type {filter.FilterType}");
}
return true;
}
}
}

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

@ -0,0 +1,27 @@
using Foundation;
using UIKit;
namespace BCLTests {
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to application events from iOS.
[Register ("AppDelegate")]
public class AppDelegate : UIApplicationDelegate {
// class-level declarations
public override UIWindow Window
{
get;
set;
}
public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
Window = new UIWindow (UIScreen.MainScreen.Bounds) {
RootViewController = new ViewController (),
};
Window.MakeKeyAndVisible ();
return true;
}
}
}

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

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>

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

@ -0,0 +1,13 @@
using UIKit;
namespace BCLTests {
public class Application {
// This is the main entry point of the application.
static void Main (string [] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main (args, null, "AppDelegate");
}
}
}

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

@ -0,0 +1,98 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using UIKit;
using ObjCRuntime;
using Xamarin.iOS.UnitTests;
using Xamarin.iOS.UnitTests.NUnit;
using BCLTests.TestRunner.Core;
using Xamarin.iOS.UnitTests.XUnit;
namespace BCLTests {
public partial class ViewController : UIViewController {
internal static IEnumerable<TestAssemblyInfo> GetTestAssemblies ()
{
// var t = Path.GetFileName (typeof (ActivatorCas).Assembly.Location);
foreach (var name in RegisterType.TypesToRegister.Keys) {
var a = Assembly.Load (name);
if (a == null) {
Console.WriteLine ($"# WARNING: Unable to load assembly {name}.");
continue;
}
yield return new TestAssemblyInfo (a, name);
}
}
public ViewController ()
{
}
protected ViewController (IntPtr handle) : base (handle)
{
// Note: this .ctor should not contain any initialization logic.
}
#if __WATCH__
[DllImport ("libc")]
static extern void exit (int code);
protected virtual void TerminateWithSuccess ()
{
// For WatchOS we're terminating the extension, not the watchos app itself.
Console.WriteLine ("Exiting test run with success");
exit (0);
}
#else
protected virtual void TerminateWithSuccess ()
{
// For WatchOS we're terminating the extension, not the watchos app itself.
Console.WriteLine ("Exiting test run with success");
Selector s = new Selector ("terminateWithSuccess");
UIApplication.SharedApplication.PerformSelector (s, UIApplication.SharedApplication, 0);
}
#endif
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
var options = ApplicationOptions.Current;
TcpTextWriter writer = null;
if (!string.IsNullOrEmpty (options.HostName))
writer = new TcpTextWriter (options.HostName, options.HostPort);
// we generate the logs in two different ways depending if the generate xml flag was
// provided. If it was, we will write the xml file to the tcp writer if present, else
// we will write the normal console output using the LogWriter
var logger = (writer == null || options.EnableXml) ? new LogWriter () : new LogWriter (writer);
logger.MinimumLogLevel = MinimumLogLevel.Info;
var testAssemblies = GetTestAssemblies ();
Xamarin.iOS.UnitTests.TestRunner runner;
if (RegisterType.IsXUnit)
runner = new XUnitTestRunner (logger);
else
runner = new NUnitTestRunner (logger);
runner.Run ((IList<TestAssemblyInfo>)testAssemblies);
if (options.EnableXml) {
runner.WriteResultsToFile (writer);
logger.Info ("Xml file was written to the tcp listener.");
} else {
string resultsFilePath = runner.WriteResultsToFile ();
logger.Info ($"Xml result can be found {resultsFilePath}");
}
logger.Info ($"Tests run: {runner.TotalTests} Passed: {runner.PassedTests} Inconclusive: {runner.InconclusiveTests} Failed: {runner.FailedTests} Ignored: {runner.SkippedTests}");
if (options.TerminateAfterExecution)
TerminateWithSuccess ();
}
public override void DidReceiveMemoryWarning ()
{
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
}
}

20
tests/bcl-test/BCLTests/templates/iOSApp/ViewController.designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,20 @@
// WARNING
//
// This file has been generated automatically by Visual Studio from the outlets and
// actions declared in your storyboard file.
// Manual changes to this file will not be maintained.
//
using Foundation;
using System;
using System.CodeDom.Compiler;
namespace BCLTests
{
[Register ("ViewController")]
partial class ViewController
{
void ReleaseDesignerOutlets ()
{
}
}
}

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

@ -0,0 +1,27 @@
using Foundation;
using UIKit;
namespace BCLTests {
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to application events from iOS.
[Register ("AppDelegate")]
public class AppDelegate : UIApplicationDelegate {
// class-level declarations
public override UIWindow Window
{
get;
set;
}
public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
Window = new UIWindow (UIScreen.MainScreen.Bounds) {
RootViewController = new ViewController (),
};
Window.MakeKeyAndVisible ();
return true;
}
}
}

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

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>

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

@ -0,0 +1,13 @@
using UIKit;
namespace BCLTests {
public class Application {
// This is the main entry point of the application.
static void Main (string [] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main (args, null, "AppDelegate");
}
}
}

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

@ -0,0 +1,98 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using UIKit;
using ObjCRuntime;
using Xamarin.iOS.UnitTests;
using Xamarin.iOS.UnitTests.NUnit;
using BCLTests.TestRunner.Core;
using Xamarin.iOS.UnitTests.XUnit;
namespace BCLTests {
public partial class ViewController : UIViewController {
internal static IEnumerable<TestAssemblyInfo> GetTestAssemblies ()
{
// var t = Path.GetFileName (typeof (ActivatorCas).Assembly.Location);
foreach (var name in RegisterType.TypesToRegister.Keys) {
var a = Assembly.Load (name);
if (a == null) {
Console.WriteLine ($"# WARNING: Unable to load assembly {name}.");
continue;
}
yield return new TestAssemblyInfo (a, name);
}
}
public ViewController ()
{
}
protected ViewController (IntPtr handle) : base (handle)
{
// Note: this .ctor should not contain any initialization logic.
}
#if __WATCH__
[DllImport ("libc")]
static extern void exit (int code);
protected virtual void TerminateWithSuccess ()
{
// For WatchOS we're terminating the extension, not the watchos app itself.
Console.WriteLine ("Exiting test run with success");
exit (0);
}
#else
protected virtual void TerminateWithSuccess ()
{
// For WatchOS we're terminating the extension, not the watchos app itself.
Console.WriteLine ("Exiting test run with success");
Selector s = new Selector ("terminateWithSuccess");
UIApplication.SharedApplication.PerformSelector (s, UIApplication.SharedApplication, 0);
}
#endif
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
var options = ApplicationOptions.Current;
TcpTextWriter writer = null;
if (!string.IsNullOrEmpty (options.HostName))
writer = new TcpTextWriter (options.HostName, options.HostPort);
// we generate the logs in two different ways depending if the generate xml flag was
// provided. If it was, we will write the xml file to the tcp writer if present, else
// we will write the normal console output using the LogWriter
var logger = (writer == null || options.EnableXml) ? new LogWriter () : new LogWriter (writer);
logger.MinimumLogLevel = MinimumLogLevel.Info;
var testAssemblies = GetTestAssemblies ();
Xamarin.iOS.UnitTests.TestRunner runner;
if (RegisterType.IsXUnit)
runner = new XUnitTestRunner (logger);
else
runner = new NUnitTestRunner (logger);
runner.Run ((IList<TestAssemblyInfo>)testAssemblies);
if (options.EnableXml) {
runner.WriteResultsToFile (writer);
logger.Info ("Xml file was written to the tcp listener.");
} else {
string resultsFilePath = runner.WriteResultsToFile ();
logger.Info ($"Xml result can be found {resultsFilePath}");
}
logger.Info ($"Tests run: {runner.TotalTests} Passed: {runner.PassedTests} Inconclusive: {runner.InconclusiveTests} Failed: {runner.FailedTests} Ignored: {runner.SkippedTests}");
if (options.TerminateAfterExecution)
TerminateWithSuccess ();
}
public override void DidReceiveMemoryWarning ()
{
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
}
}

20
tests/bcl-test/BCLTests/templates/tvOSApp/ViewController.designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,20 @@
// WARNING
//
// This file has been generated automatically by Visual Studio from the outlets and
// actions declared in your storyboard file.
// Manual changes to this file will not be maintained.
//
using Foundation;
using System;
using System.CodeDom.Compiler;
namespace BCLTests
{
[Register ("ViewController")]
partial class ViewController
{
void ReleaseDesignerOutlets ()
{
}
}
}

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

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>

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

@ -0,0 +1,165 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "57x57",
"scale" : "1x"
},
{
"idiom" : "iphone",
"size" : "57x57",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "50x50",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "50x50",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "72x72",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "72x72",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"size" : "24x24",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-24x24@2x.png",
"role" : "notificationCenter",
"subtype" : "38mm"
},
{
"size" : "27.5x27.5",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-27.5x27.5@2x.png",
"role" : "notificationCenter",
"subtype" : "42mm"
},
{
"size" : "29x29",
"idiom" : "watch",
"filename" : "Icon-29x29@2x.png",
"role" : "companionSettings",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "watch",
"filename" : "Icon-29x29@3x.png",
"role" : "companionSettings",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-40x40@2x.png",
"role" : "appLauncher",
"subtype" : "38mm"
},
{
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-44x44@2x.png",
"role" : "longLook",
"subtype" : "42mm"
},
{
"size" : "86x86",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-86x86@2x.png",
"role" : "quickLook",
"subtype" : "38mm"
},
{
"size" : "98x98",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-98x98@2x.png",
"role" : "quickLook",
"subtype" : "42mm"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.5 KiB

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

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="8173.3" systemVersion="14E46" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="AgC-eL-Hgc">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8142"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="8089"/>
</dependencies>
<scenes>
<!--Interface Controller-->
<scene sceneID="aou-V4-d1y">
<objects>
<controller id="AgC-eL-Hgc" customClass="InterfaceController">
<items>
<label alignment="center" text="Loading tests..." id="11" width="1" textAlignment="center">
<fontDescription key="font" style="UICTFontTextStyleCaption1"/>
</label>
<label alignment="center" id="12" textAlignment="center" width="134" height="0">
<fontDescription key="font" style="UICTFontTextStyleFootnote"/>
</label>
<label alignment="center" id="13" width="1" textAlignment="center">
<fontDescription key="font" style="UICTFontTextStyleFootnote"/>
</label>
<label alignment="center" id="14" textAlignment="center" width="1">
<fontDescription key="font" style="UICTFontTextStyleFootnote"/>
</label>
<button width="1" alignment="center" title="Run tests" id="10" enabled="NO" hidden="YES" verticalAlignment="bottom">
<connections>
<action selector="runTests:" destination="AgC-eL-Hgc" id="Wls-1L-AuI"/>
</connections>
</button>
</items>
<connections>
<outlet property="lblStatus" destination="11" id="name-outlet-11"/>
<outlet property="lblSuccess" destination="12" id="name-outlet-12"/>
<outlet property="lblFailed" destination="13" id="name-outlet-13"/>
<outlet property="lblIgnInc" destination="14" id="name-outlet-14"/>
<outlet property="cmdRun" destination="10" id="name-outlet-10"/>
</connections>
</controller>
</objects>
<point key="canvasLocation" x="0.0" y="0.0"/>
</scene>
</scenes>
</document>

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

@ -0,0 +1,165 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "57x57",
"scale" : "1x"
},
{
"idiom" : "iphone",
"size" : "57x57",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "50x50",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "50x50",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "72x72",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "72x72",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"size" : "24x24",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-24x24@2x.png",
"role" : "notificationCenter",
"subtype" : "38mm"
},
{
"size" : "27.5x27.5",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-27.5x27.5@2x.png",
"role" : "notificationCenter",
"subtype" : "42mm"
},
{
"size" : "29x29",
"idiom" : "watch",
"filename" : "Icon-29x29@2x.png",
"role" : "companionSettings",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "watch",
"filename" : "Icon-29x29@3x.png",
"role" : "companionSettings",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-40x40@2x.png",
"role" : "appLauncher",
"subtype" : "38mm"
},
{
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-44x44@2x.png",
"role" : "longLook",
"subtype" : "42mm"
},
{
"size" : "86x86",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-86x86@2x.png",
"role" : "quickLook",
"subtype" : "38mm"
},
{
"size" : "98x98",
"idiom" : "watch",
"scale" : "2x",
"filename" : "Icon-98x98@2x.png",
"role" : "quickLook",
"subtype" : "42mm"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.5 KiB

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

@ -0,0 +1,59 @@
using Foundation;
using UIKit;
namespace Container
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to application events from iOS.
[Register ("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
// class-level declarations
public override UIWindow Window {
get;
set;
}
public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
// Override point for customization after application launch.
// If not required for your application you can safely delete this method
return true;
}
public override void OnResignActivation (UIApplication application)
{
// Invoked when the application is about to move from active to inactive state.
// This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message)
// or when the user quits the application and it begins the transition to the background state.
// Games should use this method to pause the game.
}
public override void DidEnterBackground (UIApplication application)
{
// Use this method to release shared resources, save user data, invalidate timers and store the application state.
// If your application supports background exection this method is called instead of WillTerminate when the user quits.
}
public override void WillEnterForeground (UIApplication application)
{
// Called as part of the transiton from background to active state.
// Here you can undo many of the changes made on entering the background.
}
public override void OnActivated (UIApplication application)
{
// Restart any tasks that were paused (or not yet started) while the application was inactive.
// If the application was previously in the background, optionally refresh the user interface.
}
public override void WillTerminate (UIApplication application)
{
// Called when the application is about to terminate. Save data, if needed. See also DidEnterBackground.
}
}
}

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

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ProjectGuid>{E5F28C19-AF9E-498C-9362-F2E514DE1487}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Container</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<AssemblyName>Container</AssemblyName>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)-watchos</IntermediateOutputPath>
<DefineConstants>XAMCORE_2_0;XAMCORE_3_0;</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;$(DefineConstants)</DefineConstants>
<OutputPath>bin\iPhoneSimulator\$(Configuration)-watchos</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchProfiling>true</MtouchProfiling>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<OutputPath>bin\iPhone\$(Configuration)-watchos</OutputPath>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>ARM64</MtouchArch>
<CodesignEntitlements>%CONTAINER_PATH%Entitlements.plist</CodesignEntitlements>
<MtouchFloat32>true</MtouchFloat32>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchLink>Full</MtouchLink>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<OutputPath>bin\iPhoneSimulator\$(Configuration)-watchos</OutputPath>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<OutputPath>bin\iPhone\$(Configuration)-watchos</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>DEBUG;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>ARM64</MtouchArch>
<MtouchLink>Full</MtouchLink>
<CodesignEntitlements>%CONTAINER_PATH%Entitlements.plist</CodesignEntitlements>
<MtouchFloat32>true</MtouchFloat32>
<CodesignKey>iPhone Developer</CodesignKey>
<DeviceSpecificBuild>true</DeviceSpecificBuild>
<MtouchDebug>true</MtouchDebug>
<MtouchProfiling>true</MtouchProfiling>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
</ItemGroup>
<ItemGroup>
<ImageAsset Include="%CONTAINER_PATH%Resources\Images.xcassets\AppIcons.appiconset\Contents.json" />
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="%CONTAINER_PATH%Resources\LaunchScreen.xib" />
<InterfaceDefinition Include="%CONTAINER_PATH%Main.storyboard" />
</ItemGroup>
<ItemGroup>
<None Include="Info-watchos.plist">
<LogicalName>Info.plist</LogicalName>
</None>
<None Include="%CONTAINER_PATH%Entitlements.plist" />
</ItemGroup>
<ItemGroup>
<Compile Include="%CONTAINER_PATH%Main.cs" />
<Compile Include="%CONTAINER_PATH%AppDelegate.cs" />
<Compile Include="%CONTAINER_PATH%ViewController.cs" />
<Compile Include="%CONTAINER_PATH%ViewController.designer.cs">
<DependentUpon>%CONTAINER_PATH%ViewController.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="%WATCHAPP_CSPROJ%">
<Project>{34A6793F-37B2-4A7F-9286-7BDF52F412F3}</Project>
<Name>%WATCHAPP_NAME%</Name>
<IsWatchApp>True</IsWatchApp>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>

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

@ -0,0 +1,23 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Container", "Container.csproj", "{E5F28C19-AF9E-498C-9362-F2E514DE1487}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Release|iPhone = Release|iPhone
Release|iPhoneSimulator = Release|iPhoneSimulator
Debug|iPhone = Debug|iPhone
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E5F28C19-AF9E-498C-9362-F2E514DE1487}.Debug|iPhone.ActiveCfg = Debug|iPhone
{E5F28C19-AF9E-498C-9362-F2E514DE1487}.Debug|iPhone.Build.0 = Debug|iPhone
{E5F28C19-AF9E-498C-9362-F2E514DE1487}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{E5F28C19-AF9E-498C-9362-F2E514DE1487}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{E5F28C19-AF9E-498C-9362-F2E514DE1487}.Release|iPhone.ActiveCfg = Release|iPhone
{E5F28C19-AF9E-498C-9362-F2E514DE1487}.Release|iPhone.Build.0 = Release|iPhone
{E5F28C19-AF9E-498C-9362-F2E514DE1487}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{E5F28C19-AF9E-498C-9362-F2E514DE1487}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
EndGlobalSection
EndGlobal

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

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>

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

@ -0,0 +1,15 @@
using UIKit;
namespace Container
{
public class Application
{
// This is the main entry point of the application.
static void Main (string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main (args, null, "AppDelegate");
}
}
}

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

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204" />
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ" />
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE" />
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600" />
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" />
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite" />
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder" />
</objects>
</scene>
</scenes>
</document>

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

@ -0,0 +1,157 @@
{
"images": [
{
"idiom": "iphone",
"size": "29x29",
"scale": "1x"
},
{
"idiom": "iphone",
"size": "29x29",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "29x29",
"scale": "3x"
},
{
"idiom": "iphone",
"size": "40x40",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "40x40",
"scale": "3x"
},
{
"idiom": "iphone",
"size": "57x57",
"scale": "1x"
},
{
"idiom": "iphone",
"size": "57x57",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "60x60",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "60x60",
"scale": "3x"
},
{
"idiom": "ipad",
"size": "29x29",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "29x29",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "40x40",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "40x40",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "50x50",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "50x50",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "72x72",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "72x72",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "76x76",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "76x76",
"scale": "2x"
},
{
"size": "24x24",
"idiom": "watch",
"scale": "2x",
"role": "notificationCenter",
"subtype": "38mm"
},
{
"size": "27.5x27.5",
"idiom": "watch",
"scale": "2x",
"role": "notificationCenter",
"subtype": "42mm"
},
{
"size": "29x29",
"idiom": "watch",
"role": "companionSettings",
"scale": "2x"
},
{
"size": "29x29",
"idiom": "watch",
"role": "companionSettings",
"scale": "3x"
},
{
"size": "40x40",
"idiom": "watch",
"scale": "2x",
"role": "appLauncher",
"subtype": "38mm"
},
{
"size": "44x44",
"idiom": "watch",
"scale": "2x",
"role": "longLook",
"subtype": "42mm"
},
{
"size": "86x86",
"idiom": "watch",
"scale": "2x",
"role": "quickLook",
"subtype": "38mm"
},
{
"size": "98x98",
"idiom": "watch",
"scale": "2x",
"role": "quickLook",
"subtype": "42mm"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}

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

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207" />
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1" />
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" />
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder" />
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480" />
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" />
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 (C) Rolf Bjarne Kvinge" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines"
minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21" />
<fontDescription key="fontDescription" type="system" pointSize="17" />
<color key="textColor" cocoaTouchSystemColor="darkTextColor" />
<nil key="highlightedColor" />
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Container" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines"
minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43" />
<fontDescription key="fontDescription" type="boldSystem" pointSize="36" />
<color key="textColor" cocoaTouchSystemColor="darkTextColor" />
<nil key="highlightedColor" />
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite" />
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC" />
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk" />
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l" />
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0" />
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9" />
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g" />
</constraints>
<nil key="simulatedStatusBarMetrics" />
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics" />
<point key="canvasLocation" x="548" y="455" />
</view>
</objects>
</document>

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

@ -0,0 +1,26 @@
using System;
using UIKit;
namespace Container
{
public partial class ViewController : UIViewController
{
public ViewController (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
}
public override void DidReceiveMemoryWarning ()
{
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
}
}

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

@ -0,0 +1,17 @@
//
// This file has been generated automatically by MonoDevelop to store outlets and
// actions made in the Xcode designer. If it is removed, they will be lost.
// Manual changes to this file may not be handled correctly.
//
using Foundation;
namespace Container
{
[Register ("ViewController")]
partial class ViewController
{
void ReleaseDesignerOutlets ()
{
}
}
}

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

@ -0,0 +1,196 @@
using System;
using System.Collections;
using System.Linq;
using System.Threading;
using WatchKit;
using Foundation;
using NUnit.Framework.Internal.Filters;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using Xamarin.iOS.UnitTests;
using System.Reflection;
using Xamarin.iOS.UnitTests.XUnit;
using Xamarin.iOS.UnitTests.NUnit;
using BCLTests;
using BCLTests.TestRunner.Core;
using System.IO;
namespace monotouchtestWatchKitExtension
{
[Register ("InterfaceController")]
public partial class InterfaceController : WKInterfaceController
{
bool running;
Xamarin.iOS.UnitTests.TestRunner runner;
[Action ("runTests:")]
partial void RunTests (NSObject obj);
[Outlet ("lblStatus")]
WatchKit.WKInterfaceLabel lblStatus { get; set; }
[Outlet ("lblSuccess")]
WatchKit.WKInterfaceLabel lblSuccess { get; set; }
[Outlet ("lblFailed")]
WatchKit.WKInterfaceLabel lblFailed { get; set; }
[Outlet ("lblIgnInc")]
WatchKit.WKInterfaceLabel lblIgnInc { get; set; }
[Outlet ("cmdRun")]
WatchKit.WKInterfaceButton cmdRun { get; set; }
[DllImport ("libc")]
static extern void exit (int code);
protected virtual void TerminateWithSuccess ()
{
// For WatchOS we're terminating the extension, not the watchos app itself.
Console.WriteLine ("Exiting test run with success");
exit (0);
}
static InterfaceController ()
{
ObjCRuntime.Runtime.MarshalManagedException += (object sender, ObjCRuntime.MarshalManagedExceptionEventArgs args) =>
{
Console.WriteLine ("Managed exception: {0}", args.Exception);
};
ObjCRuntime.Runtime.MarshalObjectiveCException += (object sender, ObjCRuntime.MarshalObjectiveCExceptionEventArgs args) =>
{
Console.WriteLine ("Objective-C exception: {0}", args.Exception);
};
}
public InterfaceController (IntPtr handle) : base (handle)
{
}
public override void Awake (NSObject context)
{
base.Awake (context);
BeginInvokeOnMainThread (RunTests);
}
internal static IEnumerable<TestAssemblyInfo> GetTestAssemblies ()
{
// var t = Path.GetFileName (typeof (ActivatorCas).Assembly.Location);
foreach (var name in RegisterType.TypesToRegister.Keys) {
var a = Assembly.Load (name);
if (a == null) {
Console.WriteLine ($"# WARNING: Unable to load assembly {name}.");
continue;
}
yield return new TestAssemblyInfo (a, name);
}
}
void RunTests ()
{
var options = ApplicationOptions.Current;
TextWriter writer = null;
if (!string.IsNullOrEmpty (options.HostName) && string.IsNullOrEmpty(options.LogFile))
writer = new HttpTextWriter () { HostName = options.HostName, Port = options.HostPort };
if (!string.IsNullOrEmpty (options.LogFile))
writer = new StreamWriter (options.LogFile);
// we generate the logs in two different ways depending if the generate xml flag was
// provided. If it was, we will write the xml file to the tcp writer if present, else
// we will write the normal console output using the LogWriter
var logger = (writer == null || options.EnableXml) ? new LogWriter () : new LogWriter (writer);
logger.MinimumLogLevel = MinimumLogLevel.Info;
var testAssemblies = GetTestAssemblies ();
if (RegisterType.IsXUnit)
runner = new XUnitTestRunner (logger);
else
runner = new NUnitTestRunner (logger);
ThreadPool.QueueUserWorkItem ((v) =>
{
BeginInvokeOnMainThread (() =>
{
lblStatus.SetText (string.Format ("{0} tests", runner.TotalTests));
runner.Run ((IList<TestAssemblyInfo>)testAssemblies);
RenderResults ();
cmdRun.SetEnabled (true);
cmdRun.SetHidden (false);
if (options.EnableXml) {
runner.WriteResultsToFile (writer);
logger.Info ("Xml file was written to the http listener.");
} else {
string resultsFilePath = runner.WriteResultsToFile ();
logger.Info ($"Xml result can be found {resultsFilePath}");
}
logger.Info ($"Tests run: {runner.TotalTests} Passed: {runner.PassedTests} Inconclusive: {runner.InconclusiveTests} Failed: {runner.FailedTests} Ignored: {runner.SkippedTests}");
if (options.TerminateAfterExecution)
TerminateWithSuccess ();
});
});
}
void RenderResults ()
{
var options = ApplicationOptions.Current;
if (runner.TotalTests == 0)
return;
lblSuccess.SetText (string.Format ("P: {0}/{1} {2}%", runner.PassedTests, runner.TotalTests, 100 * runner.PassedTests / runner.TotalTests));
lblFailed.SetText (string.Format ("F: {0}/{1} {2}%", runner.FailedTests, runner.TotalTests, 100 * runner.FailedTests / runner.TotalTests));
lblIgnInc.SetText (string.Format ("I: {0}/{1} {2}%", (runner.SkippedTests + runner.InconclusiveTests), runner.TotalTests, 100 * (runner.SkippedTests + runner.InconclusiveTests) / runner.TotalTests));
if (running == false && runner.PassedTests > 0) {
if (runner.FailedTests == 0) {
lblSuccess.SetTextColor (UIKit.UIColor.Green);
lblStatus.SetTextColor (UIKit.UIColor.Green);
lblStatus.SetText ("Success");
}
if (runner.FailedTests > 0) {
lblFailed.SetTextColor (UIKit.UIColor.Red);
lblStatus.SetTextColor (UIKit.UIColor.Red);
lblStatus.SetText ("Failed");
}
}
}
partial void RunTests (NSObject obj)
{
RunTests ();
}
}
}
class NameStartsWithFilter : NUnit.Framework.Internal.TestFilter
{
public char FirstChar;
public char LastChar;
public override bool Match (NUnit.Framework.Api.ITest test)
{
if (test is NUnit.Framework.Internal.TestAssembly)
return true;
var method = test as NUnit.Framework.Internal.TestMethod;
if (method != null)
return Match (method.Parent);
var name = !string.IsNullOrEmpty (test.Name) ? test.Name : test.FullName;
bool rv;
if (string.IsNullOrEmpty (name)) {
rv = true;
} else {
var z = Char.ToUpperInvariant (name [0]);
rv = z >= Char.ToUpperInvariant (FirstChar) && z <= Char.ToUpperInvariant (LastChar);
}
return rv;
}
public override bool Pass (NUnit.Framework.Api.ITest test)
{
return Match (test);
}
}

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

@ -0,0 +1,96 @@
namespace monotouchtestWatchKitExtension
open System
open System.Collections
open System.Linq
open System.Threading
open WatchKit
open Foundation
open NUnit.Framework.Internal.Filters
open MonoTouch.NUnit.UI
[<Register ("InterfaceController")>]
type InterfaceController (handle: IntPtr) =
inherit WKInterfaceController (handle)
let mutable runner = Unchecked.defaultof<WatchOSRunner>
let mutable running = false
[<Outlet ("lblStatus")>]
member val lblStatus = Unchecked.defaultof<WKInterfaceLabel> with get, set
[<Outlet ("lblSuccess")>]
member val lblSuccess = Unchecked.defaultof<WKInterfaceLabel> with get, set
[<Outlet ("lblFailed")>]
member val lblFailed = Unchecked.defaultof<WKInterfaceLabel> with get, set
[<Outlet ("lblIgnInc")>]
member val lblIgnInc = Unchecked.defaultof<WKInterfaceLabel> with get, set
[<Outlet ("cmdRun")>]
member val cmdRun = Unchecked.defaultof<WKInterfaceButton> with get, set
member this.LoadTests () =
runner <- new WatchOSRunner ()
let ce = new CategoryExpression ("MobileNotWorking,NotOnMac,NotWorking,ValueAdd,CAS,InetAccess,NotWorkingLinqInterpreter")
runner.Filter <- new NotFilter (ce.Filter)
let tp = this.GetType ()
runner.Add (tp.Assembly)
ThreadPool.QueueUserWorkItem (fun v ->
runner.LoadSync ()
this.BeginInvokeOnMainThread (fun x ->
this.lblStatus.SetText (String.Format ("{0} tests", runner.TestCount))
this.RenderResults ()
this.cmdRun.SetEnabled (true)
this.cmdRun.SetHidden (false)
runner.AutoRun ()
)
)
|> ignore
override this.Awake (context: NSObject) =
base.Awake (context)
this.BeginInvokeOnMainThread (fun x ->
this.LoadTests ()
()
)
member this.RenderResults () =
if runner.TestCount > 0 then
this.lblSuccess.SetText (String.Format ("P: {0}/{1} {2}%", runner.PassedCount, runner.TestCount, 100 * runner.PassedCount / runner.TestCount))
this.lblFailed.SetText (String.Format ("F: {0}/{1} {2}%", runner.FailedCount, runner.TestCount, 100 * runner.FailedCount / runner.TestCount))
this.lblIgnInc.SetText (String.Format ("I: {0}/{1} {2}%", (runner.IgnoredCount + runner.InconclusiveCount), runner.TestCount, 100 * (runner.IgnoredCount + runner.InconclusiveCount) / runner.TestCount))
if running && runner.PassedCount > 0 then
if runner.FailedCount = 0 then
this.lblSuccess.SetTextColor (UIKit.UIColor.Green);
this.lblStatus.SetTextColor (UIKit.UIColor.Green);
this.lblStatus.SetText ("Success");
if runner.FailedCount > 0 then
this.lblFailed.SetTextColor (UIKit.UIColor.Red);
this.lblStatus.SetTextColor (UIKit.UIColor.Red);
this.lblStatus.SetText ("Failed");
member this.RunTests () =
if running then
printf "Already running"
else
let running = true
this.cmdRun.SetEnabled (false)
this.lblStatus.SetText ("Running")
this.BeginInvokeOnMainThread (fun v ->
runner.Run ()
this.lblStatus.SetText ("Done")
let running = false
this.RenderResults ()
)
[<Action ("runTests:")>]
member this.RunTests (obj: NSObject) =
this.RunTests ()

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

@ -339,6 +339,76 @@ namespace xharness
ensure_clean_simulator_state = value;
}
}
bool IsTouchUnitResult (XmlDocument log)
{
return log.SelectSingleNode ("/TouchUnitTestRun/NUnitOutput") != null;
}
(XmlDocument xml, string human) ParseTouchUnitXml (XmlDocument log)
{
var nunit_output = log.SelectSingleNode ("/TouchUnitTestRun/NUnitOutput");
var nunitXml = new XmlDocument ();
nunitXml.LoadXml (nunit_output.InnerXml);
return (xml: nunitXml, human: log.SelectSingleNode ("/TouchUnitTestRun/TouchUnitExtraData").InnerText);
}
(XmlDocument xml, string human) ParseNUnitXml (XmlDocument log)
{
var str = log.InnerXml;
var humanReadableLog = new StringBuilder ();
var resultsNode = log.SelectSingleNode ("test-results");
// parse the xml and build a human readable version
int total = int.Parse (resultsNode.Attributes ["total"].InnerText);
int errors = int.Parse (resultsNode.Attributes ["errors"].InnerText);
int failed = int.Parse (resultsNode.Attributes ["failures"].InnerText);
int notRun = int.Parse (resultsNode.Attributes ["not-run"].InnerText);
int inconclusive = int.Parse (resultsNode.Attributes ["inconclusive"].InnerText);
int ignored = int.Parse (resultsNode.Attributes ["ignored"].InnerText);
int skipped = int.Parse (resultsNode.Attributes ["skipped"].InnerText);
int invalid = int.Parse (resultsNode.Attributes ["invalid"].InnerText);
int passed = total - errors - failed - notRun - inconclusive - ignored - skipped - invalid;
var testFixtures = resultsNode.SelectNodes ("//test-suite[@type='TestFixture' or @type='TestCollection']");
for (var i = 0; i < testFixtures.Count; i++) {
var node = testFixtures [i];
humanReadableLog.AppendLine (node.Attributes ["name"].InnerText);
var testCases = node.SelectNodes ("//test-case");
for (var j = 0; j < testCases.Count; j++) {
var result = testCases [j];
var status = result.Attributes ["result"].InnerText;
switch (status) {
case "Success":
humanReadableLog.Append ("\t[PASS] ");
break;
case "Ignored":
humanReadableLog.Append ("\t[IGNORED] ");
break;
case "Error":
case "Failure":
humanReadableLog.Append ("\t[FAIL] ");
break;
case "Inconclusive":
humanReadableLog.Append ("\t[INCONCLUSIVE] ");
break;
default:
humanReadableLog.Append ("\t[INFO] ");
break;
}
humanReadableLog.Append (result.Attributes ["name"].InnerText);
if (status == "Failure" || status == "Error") { // we need to print the message
humanReadableLog.Append ($" : {result.InnerText}");
}
// add a new line
humanReadableLog.AppendLine ();
}
var time = node.Attributes ["time"]?.InnerText ?? "0"; // some nodes might not have the time :/
humanReadableLog.AppendLine ($"{node.Attributes ["name"].InnerXml} {time} ms");
}
humanReadableLog.AppendLine ($"Tests run: {total} Passed: {passed} Inconclusive: {inconclusive} Failed: {failed + errors} Ignored: {ignored + skipped + invalid}");
return (xml: log, human: humanReadableLog.ToString());
}
public bool TestsSucceeded (Log listener_log, bool timed_out, bool crashed)
{
string log;
@ -355,17 +425,19 @@ namespace xharness
var xmldoc = new XmlDocument ();
try {
xmldoc.LoadXml (log);
var nunit_output = xmldoc.SelectSingleNode ("/TouchUnitTestRun/NUnitOutput");
var xmllog = nunit_output.InnerXml;
var extra_output = xmldoc.SelectSingleNode ("/TouchUnitTestRun/TouchUnitExtraData");
log = extra_output.InnerText;
var testsResults = new XmlDocument ();
if (IsTouchUnitResult (xmldoc)) {
var (xml, human) = ParseTouchUnitXml (xmldoc);
testsResults = xml;
log = human;
} else {
var (xml, human) = ParseNUnitXml (xmldoc);
testsResults = xml;
log = human;
}
File.WriteAllText (listener_log.FullPath, log);
var testsResults = new XmlDocument ();
testsResults.LoadXml (xmllog);
var mainResultNode = testsResults.SelectSingleNode ("test-results");
if (mainResultNode == null) {
Harness.LogWrench ($"Node is null.");

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

@ -0,0 +1,45 @@
using System;
using System.IO;
using System.Collections.Generic;
using BCLTestImporter;
namespace xharness.BCLTestImporter {
// Class that is use as the connection between xharness and the BCLImporter
// This class knows about both worlds, will get the required information,
// from xharness, that will then be passed to the importer to generate
// the different projects, once those projects are generater, the factory
// will return the iOS targets to be executed.
public class BCLTestImportTargetFactory {
public Harness Harness;
BCLTestProjectGenerator projectGenerator;
public BCLTestImportTargetFactory (Harness harness)
{
Harness = harness;
var outputDir = Path.GetFullPath (Path.Combine (Harness.RootDirectory, "bcl-test", "BCLTests"));
var projectTemplatePath = outputDir;
var registerTypesTemplatePath = Path.Combine (outputDir, "RegisterType.cs.in");
var plistTemplatePath = outputDir;
projectGenerator = new BCLTestProjectGenerator (outputDir, Harness.MONO_PATH, projectTemplatePath, registerTypesTemplatePath, plistTemplatePath) {
Override = true
};
}
// generate all the different test targets.
public List<iOSTestProject> GetBclTargets ()
{
var result = new List<iOSTestProject> ();
// generate all projects, then create a new iOSTarget per project
foreach (var (name, path, xunit, platforms) in projectGenerator.GenerateAllTestProjects ()) {
var prefix = xunit ? "xUnit" : "NUnit";
result.Add (new iOSTestProject (path) {
Name = $"[{prefix}] Mono {name}",
SkiptvOSVariation=!platforms.Contains (Platform.TvOS),
SkipwatchOSVariation=!platforms.Contains (Platform.WatchOS)
});
}
return result;
}
}
}

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Xamarin.Utils;
using xharness.BCLTestImporter;
namespace xharness
{
@ -353,6 +354,12 @@ namespace xharness
IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "linker", "ios", "link all", "link all.csproj"))) { Configurations = new string [] { "Debug", "Release" } });
IOSTestProjects.Add (new iOSTestProject (Path.GetFullPath (Path.Combine (RootDirectory, "linker", "ios", "link sdk", "link sdk.csproj"))) { Configurations = new string [] { "Debug", "Release" } });
// add all the tests that are using the precompiled mono assemblies
var monoImportTestFactory = new BCLTestImportTargetFactory (this);
foreach (var target in monoImportTestFactory.GetBclTargets ()) {
IOSTestProjects.Add (target);
}
WatchOSContainerTemplate = Path.GetFullPath (Path.Combine (RootDirectory, "templates/WatchContainer"));
WatchOSAppTemplate = Path.GetFullPath (Path.Combine (RootDirectory, "templates/WatchApp"));
WatchOSExtensionTemplate = Path.GetFullPath (Path.Combine (RootDirectory, "templates/WatchExtension"));

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

@ -316,7 +316,7 @@ namespace xharness
public static void SetImport (this XmlDocument csproj, string value)
{
var imports = csproj.SelectNodes ("/*/*[local-name() = 'Import']");
var imports = csproj.SelectNodes ("/*/*[local-name() = 'Import'][not(@Condition)]");
if (imports.Count != 1)
throw new Exception ("More than one import");
imports [0].Attributes ["Project"].Value = value;
@ -446,7 +446,7 @@ namespace xharness
public static string GetImport (this XmlDocument csproj)
{
var imports = csproj.SelectNodes ("/*/*[local-name() = 'Import']");
var imports = csproj.SelectNodes ("/*/*[local-name() = 'Import'][not(@Condition)]");
if (imports.Count != 1)
throw new Exception ("More than one import");
return imports [0].Attributes ["Project"].Value;
@ -548,8 +548,8 @@ namespace xharness
public static void FixInfoPListInclude (this XmlDocument csproj, string suffix)
{
var import = csproj.SelectSingleNode ("/*/*/*[local-name() = 'None' and @Include = 'Info.plist']");
import.Attributes ["Include"].Value = "Info" + suffix + ".plist";
var import = csproj.SelectSingleNode ("/*/*/*[local-name() = 'None' and contains(@Include ,'Info.plist')]");
import.Attributes ["Include"].Value = import.Attributes ["Include"].Value.Replace("Info.plist", $"Info{suffix}.plist");
var logicalName = import.SelectSingleNode ("./*[local-name() = 'LogicalName']");
if (logicalName == null) {
logicalName = csproj.CreateElement ("LogicalName", MSBuild_Namespace);
@ -562,14 +562,19 @@ namespace xharness
{
var logicalNames = csproj.SelectNodes ("//*[local-name() = 'LogicalName']");
foreach (XmlNode ln in logicalNames) {
if (ln.InnerText != "Info.plist")
if (!ln.InnerText.Contains("Info.plist"))
continue;
return ln.ParentNode.Attributes ["Include"].Value;
}
var nones = csproj.SelectNodes ("//*[local-name() = 'None' and @Include = 'Info.plist']");
if (nones.Count > 0)
return "Info.plist";
throw new Exception ("Could not find Info.plist include");
var nodes = csproj.SelectNodes ("//*[local-name() = 'None' and contains(@Include ,'Info.plist')]");
if (nodes.Count > 0) {
return nodes [0].Attributes [0].Value; // return the value, which could be Info.plist or a full path (linked).
}
nodes = csproj.SelectNodes ("//*[local-name() = 'None' and contains(@Include ,'Info-tv.plist')]");
if (nodes.Count > 0) {
return nodes [0].Attributes [0].Value; // return the value, which could be Info.plist or a full path (linked).
}
throw new Exception ($"Could not find Info.plist include.");
}
public static IEnumerable<string> GetProjectReferences (this XmlDocument csproj)
@ -776,7 +781,7 @@ namespace xharness
return;
}
throw new Exception ("Configuration not found.");
throw new Exception ($"Configuration not found: {platform}:{configuration}");
}
static IEnumerable<XmlNode> SelectElementNodes (this XmlNode node, string name)

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

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />
</packages>

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

@ -63,6 +63,10 @@
<Reference Include="System.Web" />
<Reference Include="Mono.Posix" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ValueTuple">
<HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@ -107,6 +111,31 @@
</Compile>
<Compile Include="SimpleFileListener.cs" />
<Compile Include="iOSTarget.cs" />
<Compile Include="..\..\tools\bcl-test-importer\BCLTestImporter\BCLTestAssemblyDefinition.cs">
<Link>BCLTestImporter\BCLTestAssemblyDefinition.cs</Link>
</Compile>
<Compile Include="..\..\tools\bcl-test-importer\BCLTestImporter\BCLTestProjectDefinition.cs">
<Link>BCLTestImporter\BCLTestProjectDefinition.cs</Link>
</Compile>
<Compile Include="..\..\tools\bcl-test-importer\BCLTestImporter\BCLTestProjectGenerator.cs">
<Link>BCLTestImporter\BCLTestProjectGenerator.cs</Link>
</Compile>
<Compile Include="..\..\tools\bcl-test-importer\BCLTestImporter\Platform.cs">
<Link>BCLTestImporter\Platform.cs</Link>
</Compile>
<Compile Include="..\..\tools\bcl-test-importer\BCLTestImporter\RegisterTypeGenerator.cs">
<Link>BCLTestImporter\RegisterTypeGenerator.cs</Link>
</Compile>
<Compile Include="BCLTestImporter\BCLTestImportTargetFactory.cs" />
<Compile Include="..\..\tools\bcl-test-importer\BCLTestImporter\BCLTestInfoPlistGenerator.cs">
<Link>BCLTestImporter\BCLTestInfoPlistGenerator.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="BCLTestImporter\" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

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

@ -0,0 +1,369 @@
using System;
using System.IO;
using System.Collections.Generic;
using Mono.Options;
namespace BCLTestImporter {
// struct used to store the options of the command line after they have been parsed
// it provides ways to validate that the combinations are correct.
public class ApplicationOptions {
#region static vars
static readonly string partialPath = "mcs/class/lib";
static readonly Dictionary <Platform, string> PlatformPathMatch = new Dictionary <Platform, string> {
{Platform.iOS, "monotouch"},
{Platform.WatchOS, "monotouch_watch"},
{Platform.TvOS, "monotouch_tv"},
{Platform.MacOS, "xammac"},
};
#endregion
#region properties
// bool flags
internal bool ShouldShowHelp { get; set; }
internal bool Verbose { get; set; }
internal bool ShowDict { get; set; }
internal bool ListAssemblies { get; set; }
internal bool GenerateProject { get; set; }
internal bool GenerateAllProjects { get; set; }
internal bool GenerateTypeRegister { get; set; }
internal bool IsXUnit { get; set; }
internal bool Override { get; set; }
internal bool ClearAll{ get; set; }
internal bool IgnoreMissingAssemblies{ get; set; }
// path options
string monoPath;
public string MonoPath {
get => monoPath;
set => monoPath = FixPath (value);
}
public Platform Platform { get; set; }
string output;
public string Output {
get => output;
set => output = FixPath (value);
}
string registerTypeTemplate;
public string RegisterTypeTemplate {
get => registerTypeTemplate;
set => registerTypeTemplate = FixPath (value);
}
string projectTemplate;
public string ProjectTemplate {
get => projectTemplate;
set => projectTemplate = FixPath (value);
}
string plistTemplate;
public string PlistTemplate{
get => plistTemplate;
set => plistTemplate = FixPath (value);
}
string assembly;
public string Assembly {
get => assembly;
set => assembly = FixPath (value);
}
string registerTypesPath;
public string RegisterTypesPath {
get => registerTypesPath;
set => registerTypesPath = FixPath (value);
}
public string TestsDirectory => GetTestsDirectoryPath (monoPath, Platform);
// multiple value options
public List<string> TestAssemblies { get; private set; }
public string ProjectName { get; set; }
#endregion
public ApplicationOptions ()
{
TestAssemblies = new List<string> ();
}
// get a path, and make sure that is abs and that ~ is expanded
string FixPath (string path)
{
var result = path;
if (Path.IsPathRooted (result))
return result;
if (result.StartsWith ("~", StringComparison.Ordinal)) {
if (Verbose)
Console.WriteLine ($"Expanding home dir for path {result}.");
result = result.Replace ("~", Environment.GetEnvironmentVariable("HOME"));
}
if (Verbose)
Console.WriteLine ($"Converting path {result} to absolute.");
result = Path.GetFullPath (result);
if (Verbose)
Console.WriteLine ($"New output path is {result}");
return result;
}
bool MonoPathIsValid (string path, out string message)
{
if (string.IsNullOrEmpty (path)) {
message = "Mono checkout is missing.";
return false;
}
if (!Directory.Exists (monoPath)) {
message = $"Could not find mono checkout: '{path}'";
return false;
}
message = "";
return true;
}
static string GetTestsDirectoryPath (string monoPath, Platform platform)
=> Path.Combine (monoPath, partialPath, PlatformPathMatch[platform], "tests");
bool GenerateTypeRegisterOptionsAreValid (out string message)
{
var cmd = "--generate-type-register";
if (!MonoPathIsValid (monoPath, out message)) {
message = $"{cmd} {message}"; // let the user the param he used
return false;
}
if (string.IsNullOrEmpty (registerTypeTemplate)) {
message = $"{cmd} Template must be provided.";
return false;
}
if (!File.Exists (registerTypeTemplate)) {
message = $"{cmd} Template is missing.";
return false;
}
if (string.IsNullOrEmpty (output)) {
message = $"{cmd} output path must be provided.";
return false;
}
if (!Override && File.Exists (output)) {
message = $"{cmd} Output path already exists.";
return false;
}
// we need other data depending on what is being generated
if (TestAssemblies.Count == 0) {
message = $"{cmd} test assemblies must be passed for code generation.";
return false;
}
message = "";
return true;
}
bool GenerateProjectOptionsAreValid (out string message)
{
// we are dealing with two possible options, the project generation or the type registration
// generation, both need the mono path and the platform to be correct
var cmd = "--generate-project";
if (!MonoPathIsValid (monoPath, out message)) {
message = $"{cmd} {message}"; // let the user the param he used
return false;
}
if (string.IsNullOrEmpty (projectTemplate)) {
message = $"{cmd} Project emplate must be provided.";
return false;
}
if (!File.Exists (projectTemplate)) {
message = $"{cmd} Project template is missing.";
return false;
}
if (string.IsNullOrEmpty (plistTemplate)) {
message = $"{cmd} Plist template must be provided.";
return false;
}
if (!File.Exists (plistTemplate)) {
message = $"{cmd} Plist template is missing.";
return false;
}
if (string.IsNullOrEmpty (output)) {
message = $"{cmd} output path must be provided.";
return false;
}
if (!Override && File.Exists (output)) {
message = $"{cmd} Output path already exists.";
return false;
}
// we need other data depending on what is being generated
if (TestAssemblies.Count == 0) {
message = $"{cmd} test assemblies must be passed for project generation.";
return false;
}
if (string.IsNullOrEmpty (ProjectName)) {
message = $"{cmd} a project name is needed when generating a new test app.";
return false;
}
if (string.IsNullOrEmpty (registerTypesPath)) {
message = $"{cmd} the path to the generated class is needed.";
return false;
}
if (!File.Exists (registerTypesPath)) {
message = $"{cmd} the path to the generated class could not be found.";
return false;
}
message = "";
return false;
}
bool GenerateAllProjectsOptionsAreValid (out string message)
{
const string cmd = "--generate-all-projects";
if (ClearAll) { // special case in which we only need the output
if (string.IsNullOrEmpty (output)) {
message = $"{cmd} output path must be provided.";
return false;
}
if (!Directory.Exists (output)) {
message = $"{cmd} Output path must be an existing directory.";
return false;
}
message = "";
return true;
}
if (!MonoPathIsValid (monoPath, out message)) {
message = $"{cmd} {message}"; // let the user the param he used
return false;
}
if (string.IsNullOrEmpty (registerTypeTemplate)) {
message = $"{cmd} Register type template must be provided.";
return false;
}
if (string.IsNullOrEmpty (projectTemplate)) {
message = $"{cmd} Project template must be provided.";
return false;
}
if (string.IsNullOrEmpty (plistTemplate)) {
message = $"{cmd} Plist template must be provided.";
return false;
}
if (!File.Exists (registerTypeTemplate)) {
message = $"{cmd} Register type template is missing.";
return false;
}
if (!Directory.Exists (projectTemplate)) {
message = $"{cmd} Project template is missing.";
return false;
}
if (!Directory.Exists (plistTemplate)) {
message = $"{cmd} Plist template is missing.";
return false;
}
if (string.IsNullOrEmpty (output)) {
message = $"{cmd} output path must be provided.";
return false;
}
if (!Directory.Exists (output)) {
message = $"{cmd} Output path must be an existing directory.";
return false;
}
message = "";
return true;
}
// validate the options and return a message with the possible issue.
public bool OptionsAreValid (out string message)
{
if (!string.IsNullOrEmpty (assembly)) {
// we need to ensure that no other options have been given
if (ShouldShowHelp || ShowDict || ListAssemblies || GenerateProject || GenerateTypeRegister || IsXUnit
|| !string.IsNullOrEmpty (monoPath) || !string.IsNullOrEmpty (output)
|| !string.IsNullOrEmpty (registerTypeTemplate) || TestAssemblies.Count > 0) {
message = "--assemblyref does not take any other arguments.";
return false;
}
}
if (ShowDict) {
if (ShouldShowHelp || ListAssemblies || GenerateProject || GenerateTypeRegister
|| !string.IsNullOrEmpty (monoPath) || !string.IsNullOrEmpty (output)
|| !string.IsNullOrEmpty (assembly) || !string.IsNullOrEmpty (registerTypeTemplate)
|| TestAssemblies.Count > 0) {
message = "--d received unrecognized parameters..";
return false;
}
if (string.IsNullOrEmpty (monoPath)) {
message = "(-d) Mono checkout is missing.";
return false;
}
// assert that the platform is supported
if (!PlatformPathMatch.ContainsKey (Platform)) {
message = "(-d) Unrecognized platform.";
return false;
}
}
if (ListAssemblies) {
if (!MonoPathIsValid (monoPath, out message)) {
message = $"(-d) {message}"; // let the user the param he used
return false;
}
}
if (GenerateTypeRegister)
return GenerateTypeRegisterOptionsAreValid (out message);
if (GenerateProject)
return GenerateProjectOptionsAreValid (out message);
if (GenerateAllProjects)
return GenerateAllProjectsOptionsAreValid (out message);
message = "";
return true;
}
/// <summary>
/// Returns the option set to parse the cmd line of the application.
/// </summary>
/// <returns>A configured option set for the command line.</returns>
public OptionSet CreateCommandLineOptionSet ()
{
return new OptionSet {
{ "mono-root=", "Root directory of the mono check out that will be use to search for the unit tests."
+ " Example: '/Users/test/xamarin-macios/external/mono'.", p => MonoPath = p },
{ "iOS", "Specifies that the platform to which the projects are going to be build is iOS.", i => Platform = Platform.iOS },
{ "watchOS", "Specifies that the platform to which the projects are going to be build is watchOS.", w => Platform = Platform.WatchOS },
{ "tvOS", "Specifies that the platform to which the projects are going to be build is tvOS.", t => Platform = Platform.TvOS },
{ "macOS", "Specifies that the platform to which the projects are going to be build is macOS.", m => Platform = Platform.MacOS },
{ "generate-project", "Flag used to state that a new test project should be generated."
+ " Output path must be provided via -o.", f => GenerateProject = f != null },
{ "generate-all-projects", "Flag used to state that all the test projects should be generated."
+ " Output path must be provided via -o which should be a directory.", f => GenerateAllProjects = f != null },
{ "clean", "Clear the output directory when used with the --generate-all-projects options.", c => ClearAll = c != null},
{ "generate-type-register", "Flag used to state that a new type register should be generated."
+ "Output path must be provided via -o." , f => GenerateTypeRegister = f != null },
{ "override", "State if the output should be overriden or not.", o => Override = o != null},
{ "o|output=", "Specifies the output of the generated code.", o => Output = o },
{ "register-type-template=", "Specifies the template to be used for the code generation.", t => RegisterTypeTemplate = t},
{ "project-template=", "Specifies the template to be used for the project generation.", t => ProjectTemplate = t},
{ "plist-template=", "Specifies the template to be used for the plist generation.", p => PlistTemplate = p},
{ "assemblyref=", "Gets an assembly and returns all the references to it.", a => Assembly = a },
{ "ignore-missing-assemblies", "Tells the application not to throw an error when there are test assemblies that have not been added.", i => IgnoreMissingAssemblies = i != null},
{ "a|assembly=", "Allows to pass the test assemblies to be used for the code generation", a => TestAssemblies.Add (a) },
{ "x|xunit", "Flag that states if the assemblies contain xunit tests.", x => IsXUnit = x != null},
{ "d|dictionary", "Lists the assemblies found and a relation with a type found in it.", d => ShowDict = d != null},
{ "l|list", "Lists the assemblies found.", l => ListAssemblies = l != null},
{ "project-name=", "Allows to specify the name of the project to be generated.", p => ProjectName = p},
{ "register-types-path=", "Allows to specify the location of the RegisterTypes generated class.", p => RegisterTypesPath = p},
{ "h|?|help", "Show this message and exit", h => ShouldShowHelp = h != null },
{ "v|verbose", "Be verbose when searching for the tests.", v => Verbose = v != null},
};
}
}
}

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

@ -0,0 +1,63 @@
using System;
using System.IO;
using System.Collections.Generic;
namespace BCLTestImporter {
public struct BCLTestAssemblyDefinition {
#region static vars
static string partialPath = "mcs/class/lib";
static Dictionary <Platform, string> platformPathMatch = new Dictionary <Platform, string> {
{Platform.iOS, "monotouch"},
{Platform.WatchOS, "monotouch"},
{Platform.TvOS, "monotouch"},
{Platform.MacOS, "xammac"},
};
#endregion
#region properties
public string Name { get; set; }
public bool IsXUnit { get; set; }
#endregion
public BCLTestAssemblyDefinition (string name)
{
Name = name;
// the following pattern is used when generating xunit test
// assemblies
IsXUnit = name.Contains ("_xunit-test");
}
/// <summary>
/// Returns the mono directory where test can be found.
/// </summary>
/// <param name="monoRootPath">The root path of the mono checkout.</param>
/// <param name="platform">The platform whose test directory we need.</param>
/// <returns>The full path of the test directory.</returns>
/// <exception cref="ArgumentNullException">Raised when one of the parameters is null.</exception>
public static string GetTestDirectory (string monoRootPath, Platform platform)
{
if (monoRootPath == null)
throw new ArgumentNullException (nameof (monoRootPath));
var fullPath = monoRootPath;
return Path.Combine (fullPath, partialPath, platformPathMatch[platform], "tests");
}
public static string GetHintPathForRefenreceAssembly (string assembly, string monoRootPath, Platform plaform)
{
var hintPath = Path.Combine (monoRootPath, partialPath, platformPathMatch[plaform], $"{assembly}.dll");
return File.Exists (hintPath) ? hintPath : null;
}
/// <summary>
/// Returns the path of the test assembly within the mono checkout.
/// </summary>
/// <param name="monoRootPath">The root path of the mono checkout.</param>
/// <param name="platform">The platform we are working with.</param>
/// <returns>The full path of the assembly.</returns>
public string GetPath (string monoRootPath, Platform platform) => Path.Combine (GetTestDirectory (monoRootPath, platform), Name);
}
}

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

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{933A4790-49E7-4CE3-B2F9-06824DAB902A}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>BCLTestImporter</RootNamespace>
<AssemblyName>BCLTestImporter</AssemblyName>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ExternalConsole>true</ExternalConsole>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ExternalConsole>true</ExternalConsole>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Mono.Options">
<HintPath>..\..\..\packages\Mono.Options.5.3.0.1\lib\net4-client\Mono.Options.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple">
<HintPath>..\..\..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
</ItemGroup>
<ItemGroup>
<Compile Include="BCLTestInfoPlistGenerator.cs" />
<Compile Include="Platform.cs" />
<Compile Include="Program.cs" />
<Compile Include="RegisterTypeGenerator.cs" />
<Compile Include="BCLTestProjectGenerator.cs" />
<Compile Include="ApplicationOptions.cs" />
<Compile Include="BCLTestProjectDefinition.cs" />
<Compile Include="BCLTestAssemblyDefinition.cs" />
<Compile Include="ConsoleWriter.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

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

@ -0,0 +1,23 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BCLTestImporter", "BCLTestImporter.csproj", "{933A4790-49E7-4CE3-B2F9-06824DAB902A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BCLTestImporterTests", "BCLTestImporterTests\BCLTestImporterTests.csproj", "{47A0E800-6C8B-4DCD-B572-731D0661EEB4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{933A4790-49E7-4CE3-B2F9-06824DAB902A}.Debug|x86.ActiveCfg = Debug|x86
{933A4790-49E7-4CE3-B2F9-06824DAB902A}.Debug|x86.Build.0 = Debug|x86
{933A4790-49E7-4CE3-B2F9-06824DAB902A}.Release|x86.ActiveCfg = Release|x86
{933A4790-49E7-4CE3-B2F9-06824DAB902A}.Release|x86.Build.0 = Release|x86
{47A0E800-6C8B-4DCD-B572-731D0661EEB4}.Debug|x86.ActiveCfg = Debug|Any CPU
{47A0E800-6C8B-4DCD-B572-731D0661EEB4}.Debug|x86.Build.0 = Debug|Any CPU
{47A0E800-6C8B-4DCD-B572-731D0661EEB4}.Release|x86.ActiveCfg = Release|Any CPU
{47A0E800-6C8B-4DCD-B572-731D0661EEB4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

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

@ -0,0 +1,490 @@
using System;
using System.IO;
using Xunit;
using Xunit.Sdk;
using BCLTestImporter;
namespace BCLTestImporterTests {
public class ApplicationOptionsTest : IDisposable {
readonly string registerTypesTemplatePath;
readonly string projectTemplatePath;
readonly string plistTemplatePath;
readonly string outputPath;
readonly string monoCheckout;
readonly Platform platform = Platform.iOS;
static void WriteJunk (string path)
{
using (var file = new StreamWriter (path, false)) {
file.Write ("Data");
}
}
public ApplicationOptionsTest ()
{
var tmpPath = Path.GetTempPath ();
registerTypesTemplatePath = Path.Combine (tmpPath, Path.GetRandomFileName());
WriteJunk (registerTypesTemplatePath);
projectTemplatePath = Path.Combine (tmpPath, Path.GetRandomFileName());
WriteJunk (projectTemplatePath);
plistTemplatePath = Path.Combine (tmpPath, Path.GetRandomFileName());
WriteJunk (plistTemplatePath);
outputPath = Path.Combine (tmpPath, Path.GetRandomFileName());
monoCheckout = Path.Combine (tmpPath, Path.GetRandomFileName());
var testDir = BCLTestAssemblyDefinition.GetTestDirectory (monoCheckout, platform);
if (Directory.Exists (testDir)) return;
// we need to create the mono dir and the test dir
if (!Directory.Exists (testDir))
Directory.CreateDirectory (testDir);
}
public void Dispose ()
{
if (registerTypesTemplatePath != null && File.Exists (registerTypesTemplatePath))
File.Delete (registerTypesTemplatePath);
if (projectTemplatePath != null && File.Exists (projectTemplatePath))
File.Delete (projectTemplatePath);
if (outputPath != null && File.Exists (outputPath))
File.Delete (outputPath);
if (monoCheckout != null && Directory.Exists (monoCheckout))
Directory.Delete (monoCheckout, true);
}
[Fact]
public void DefaultValues ()
{
var appOptions = new ApplicationOptions ();
// flag values
Assert.False (appOptions.ShouldShowHelp, "appOptions.ShouldShowHelp");
Assert.False (appOptions.Verbose, "appOptions.Verbose");
Assert.False (appOptions.ShowDict, "appOptions.ShowDict");
Assert.False (appOptions.ListAssemblies, "appOptions.ListAssemblies");
Assert.False (appOptions.GenerateProject, "appOptions.GenerateProject");
Assert.False (appOptions.GenerateAllProjects, "appOptions.GenerateAllProjects");
Assert.False (appOptions.GenerateTypeRegister, "appOptions.GenerateTypeRegister");
Assert.False (appOptions.IsXUnit, "appOptions.IsXUnit");
Assert.False (appOptions.Override, "appOptions.Override");
Assert.False (appOptions.ClearAll, "appOptions.ClearAll");
// string values
Assert.Null (appOptions.MonoPath);
Assert.Null (appOptions.Output);
Assert.Null (appOptions.RegisterTypeTemplate);
Assert.Null (appOptions.ProjectTemplate);
Assert.Null (appOptions.Assembly);
Assert.Null (appOptions.RegisterTypesPath);
Assert.Null (appOptions.ProjectName);
Assert.Null (appOptions.PlistTemplate);
// lists
Assert.Empty(appOptions.TestAssemblies);
}
[Fact]
public void TypeRegisterMonoPathMissing ()
{
var appOptions = new ApplicationOptions {
GenerateTypeRegister = true,
RegisterTypeTemplate = registerTypesTemplatePath,
Output = outputPath,
Override = true
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-type-register Mono checkout is missing.", errorMessage);
}
[Fact]
public void TypeRegisterMonoNotValid ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
var appOptions = new ApplicationOptions {
GenerateTypeRegister = true,
RegisterTypeTemplate = registerTypesTemplatePath,
Output = outputPath,
Override = true,
MonoPath = Path.Combine (home, "foo"),
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Contains ("--generate-type-register Could not find mono checkout:", errorMessage);
}
[Fact]
public void TypeRegisterTemplateMissing ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
var appOptions = new ApplicationOptions {
GenerateTypeRegister = true,
RegisterTypeTemplate = Path.Combine (home, "foo.in"),
Output = outputPath,
Override = true,
MonoPath = monoCheckout,
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-type-register Template is missing.", errorMessage);
}
[Fact]
public void TypeRegisterMissingOutput ()
{
var appOptions = new ApplicationOptions {
GenerateTypeRegister = true,
RegisterTypeTemplate = registerTypesTemplatePath,
Override = true,
MonoPath = monoCheckout,
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-type-register output path must be provided.", errorMessage);
}
[Fact]
public void TypeRegisterNotOverrideAndPresentFile ()
{
WriteJunk (outputPath);
var appOptions = new ApplicationOptions {
GenerateTypeRegister = true,
RegisterTypeTemplate = registerTypesTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-type-register Output path already exists.", errorMessage);
}
[Fact]
public void TypeRegisterNoTestAssemblies ()
{
var appOptions = new ApplicationOptions {
GenerateTypeRegister = true,
RegisterTypeTemplate = registerTypesTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-type-register test assemblies must be passed for code generation.", errorMessage);
}
[Fact]
public void GenerateProjectMonoPathNotValid ()
{
var appOptions = new ApplicationOptions {
GenerateProject = true,
ProjectName = "Test",
ProjectTemplate = registerTypesTemplatePath,
Output = outputPath,
Override = true
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-project Mono checkout is missing.", errorMessage);
}
[Fact]
public void GenerateProjectPlatformNotValid ()
{
var appOptions = new ApplicationOptions {
GenerateProject = true,
ProjectName = "Test",
ProjectTemplate = registerTypesTemplatePath,
Output = outputPath,
Override = true
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-project Mono checkout is missing.", errorMessage);
}
[Fact]
public void GenerateProjectTemplateMissing ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
var appOptions = new ApplicationOptions {
GenerateProject = true,
ProjectName = "Test",
ProjectTemplate = Path.Combine (home, "foo.in"),
Output = outputPath,
Override = true,
MonoPath = monoCheckout,
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-project Project template is missing.", errorMessage);
}
[Fact]
public void GeneratePlistTemplateNoProvided ()
{
var appOptions = new ApplicationOptions {
GenerateProject = true,
ProjectName = "Test",
ProjectTemplate = projectTemplatePath,
Output = outputPath,
Override = true,
MonoPath = monoCheckout,
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-project Plist template must be provided.", errorMessage);
}
[Fact]
public void GeneratePlistTemplateMissing ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
var appOptions = new ApplicationOptions {
GenerateProject = true,
ProjectName = "Test",
ProjectTemplate = projectTemplatePath,
PlistTemplate = Path.Combine (home, "foo.in"),
Output = outputPath,
Override = true,
MonoPath = monoCheckout,
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-project Plist template is missing.", errorMessage);
}
[Fact]
public void GenerateProjectMissingOutput ()
{
var appOptions = new ApplicationOptions {
GenerateProject = true,
ProjectName = "Test",
ProjectTemplate = projectTemplatePath,
PlistTemplate = plistTemplatePath,
Override = true,
MonoPath = monoCheckout,
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-project output path must be provided.", errorMessage);
}
[Fact]
public void GenerateProjectNotOverrideAndPresentFile ()
{
WriteJunk (outputPath);
var appOptions = new ApplicationOptions {
GenerateProject = true,
ProjectName = "Test",
ProjectTemplate = projectTemplatePath,
PlistTemplate = plistTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
appOptions.TestAssemblies.Add ("Foo.dll");
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-project Output path already exists.", errorMessage);
}
[Fact]
public void GenerateProjectNoTestAssemblies ()
{
var appOptions = new ApplicationOptions {
GenerateProject = true,
ProjectName = "Test",
ProjectTemplate = projectTemplatePath,
PlistTemplate = plistTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-project test assemblies must be passed for project generation.", errorMessage);
}
[Fact]
public void GenerateAllProjectsMonoPathNotValid ()
{
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ProjectName = "Test",
ProjectTemplate = projectTemplatePath,
RegisterTypeTemplate = registerTypesTemplatePath,
Output = outputPath,
Override = true
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Mono checkout is missing.", errorMessage);
}
[Fact]
public void GenerateAllProjectsPlatformNotValid ()
{
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ProjectName = "Test",
ProjectTemplate = projectTemplatePath,
RegisterTypeTemplate = registerTypesTemplatePath,
Output = outputPath,
Override = true
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Mono checkout is missing.", errorMessage);
}
[Fact]
public void GenerateAllProjectsMissingOutput ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ProjectName = "Test",
ProjectTemplate = home,
PlistTemplate = home,
RegisterTypeTemplate = registerTypesTemplatePath,
Override = true,
MonoPath = monoCheckout,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects output path must be provided.", errorMessage);
}
[Fact]
public void GenerateAllProjectsOutputNotDir ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
WriteJunk (outputPath);
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ProjectTemplate = home,
PlistTemplate = home,
RegisterTypeTemplate = registerTypesTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Output path must be an existing directory.", errorMessage);
}
[Fact]
public void GenerateAllProjectsProjectTemplateNotProvided ()
{
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
RegisterTypeTemplate = registerTypesTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Project template must be provided.", errorMessage);
}
[Fact]
public void GenerateAllProjectsProjectTemplateMissing ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
RegisterTypeTemplate = registerTypesTemplatePath,
ProjectTemplate = Path.Combine (home, "foo.in"),
PlistTemplate = plistTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Project template is missing.", errorMessage);
}
[Fact]
public void GenerateAllProjectsRegisterTypeTemplateNotProvided ()
{
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ProjectTemplate = projectTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Register type template must be provided.", errorMessage);
}
[Fact]
public void GenerateAllProjectsRegisterTypeTemplateMissing ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ProjectTemplate = projectTemplatePath,
RegisterTypeTemplate = Path.Combine (home, "foo.in"),
PlistTemplate = plistTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Register type template is missing.", errorMessage);
}
[Fact]
public void GenerateAllProjectsPlistTemplateNotProvided ()
{
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ProjectTemplate = projectTemplatePath,
RegisterTypeTemplate = registerTypesTemplatePath,
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Plist template must be provided.", errorMessage);
}
[Fact]
public void GenerateAllProjectsPlistTemplateMissing ()
{
var home = Environment.GetEnvironmentVariable ("HOME");
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ProjectTemplate = home,
RegisterTypeTemplate = registerTypesTemplatePath,
PlistTemplate = Path.Combine (home, "foo.in"),
Override = false,
Output = outputPath,
MonoPath = monoCheckout,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Plist template is missing.", errorMessage);
}
[Fact]
public void GenerateAllProjectsClearMissingOutput ()
{
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ClearAll = true,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects output path must be provided.", errorMessage);
}
[Fact]
public void GenerateAllProjectsOutputClearNotDir ()
{
WriteJunk (outputPath);
var appOptions = new ApplicationOptions {
GenerateAllProjects = true,
ClearAll = true,
Output = outputPath,
};
Assert.False (appOptions.OptionsAreValid (out var errorMessage));
Assert.Equal ("--generate-all-projects Output path must be an existing directory.", errorMessage);
}
}
}

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

@ -0,0 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
<PackageReference Include="Mono.Options" Version="5.3.0.1" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\ApplicationOptions.cs">
<Link>ApplicationOptions.cs</Link>
</Compile>
<Compile Include="..\BCLTestInfoPlistGenerator.cs">
<Link>BCLTestInfoPlistGenerator.cs</Link>
</Compile>
<Compile Include="..\BCLTestProjectGenerator.cs">
<Link>BCLTestProjectGenerator.cs</Link>
</Compile>
<Compile Include="..\Platform.cs">
<Link>Platform.cs</Link>
</Compile>
<Compile Include="..\BCLTestAssemblyDefinition.cs">
<Link>BCLTestAssemblyDefinition.cs</Link>
</Compile>
<Compile Include="..\BCLTestProjectDefinition.cs">
<Link>BCLTestProjectDefinition.cs</Link>
</Compile>
<Compile Include="..\RegisterTypeGenerator.cs">
<Link>RegisterTypeGenerator.cs</Link>
</Compile>
</ItemGroup>
</Project>

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

@ -0,0 +1,48 @@
using System;
using System.IO;
using Xunit;
using Xunit.Sdk;
using BCLTestImporter;
namespace BCLTestImporterTests {
public class BCLTestInfoPlistGeneratorTest {
[Fact]
public async void GenerateCodeNullTemplateFile ()
{
await Assert.ThrowsAsync<ArgumentNullException> (() =>
BCLTestInfoPlistGenerator.GenerateCodeAsync (null, "Project Name"));
}
[Fact]
public async void GenerateCodeNullProjectName ()
{
await Assert.ThrowsAsync <ArgumentNullException> (() =>
BCLTestInfoPlistGenerator.GenerateCodeAsync ("A/path", null));
}
[Fact]
public async void GenerateCode ()
{
const string projectName = "MyTest";
var fakeTemplate = $"{BCLTestInfoPlistGenerator.ApplicationNameReplacement}-{BCLTestInfoPlistGenerator.IndentifierReplacement}";
var tmpPath = Path.GetTempPath ();
var templatePath = Path.Combine (tmpPath, Path.GetRandomFileName());
using (var file = new StreamWriter (templatePath, false)) {
await file.WriteAsync (fakeTemplate);
}
var result = await BCLTestInfoPlistGenerator.GenerateCodeAsync (templatePath, projectName);
try {
Assert.DoesNotContain (BCLTestInfoPlistGenerator.ApplicationNameReplacement, result);
Assert.DoesNotContain (BCLTestInfoPlistGenerator.IndentifierReplacement, result);
Assert.Contains (projectName, result);
}
finally {
File.Delete (templatePath);
}
}
}
}

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

@ -0,0 +1,146 @@
using System;
using System.IO;
using System.Text;
using Xunit;
using BCLTestImporter;
namespace BCLTestImporterTests {
public class BCLTestProjectGeneratorTest
{
readonly string outputdir;
public BCLTestProjectGeneratorTest ()
{
outputdir = Path.GetTempPath ();
}
[Fact]
public void ConstructorNullOutputDir ()
{
Assert.Throws<ArgumentNullException> (() => new BCLTestProjectGenerator (null));
Assert.Throws<ArgumentNullException> (() => new BCLTestProjectGenerator (null, "", "", "", ""));
}
[Fact]
public void ConstructorNullMonoDir ()
{
Assert.Throws<ArgumentNullException> (() => new BCLTestProjectGenerator ("", null, "", "", ""));
}
[Fact]
public void ConstructorNullProjectTemplatePath ()
{
Assert.Throws<ArgumentNullException> (() => new BCLTestProjectGenerator ("", "", null, "", ""));
}
[Fact]
public void ConstructorNullRegisterPath ()
{
Assert.Throws<ArgumentNullException> (() => new BCLTestProjectGenerator ("", "", "", null, ""));
}
[Fact]
public void ConstructorNullPlistTemplatePath ()
{
Assert.Throws<ArgumentNullException> (() => new BCLTestProjectGenerator ("", "", "", "", null));
}
[Theory]
[InlineData ("iOSProject", Platform.iOS, "iOSProject.csproj")]
[InlineData ("WatchOSProject", Platform.WatchOS, "WatchOSProject-watchos.csproj")]
[InlineData ("TvOSProject", Platform.TvOS, "TvOSProject-tvos.csproj")]
// TODO: [InlineData ("MacProject", Platform.MacOS, null)] not implemented yet
public void GetProjectPath (string projectName, Platform platform, string expectedName)
{
// ignore the fact that all params are the same, we do not care
var generator = new BCLTestProjectGenerator (outputdir, outputdir, outputdir, outputdir, outputdir);
var path = generator.GetProjectPath (projectName, platform);
Assert.Equal (Path.Combine (generator.OutputDirectoryPath, expectedName), path);
}
[Theory]
[InlineData ("WatchApp", BCLTestProjectGenerator.WatchAppType.App, "WatchApp-watchos-app.csproj")]
[InlineData ("WatchExtension", BCLTestProjectGenerator.WatchAppType.Extension, "WatchExtension-watchos-extension.csproj")]
public void GetProjectPathWatchOS (string projectName, BCLTestProjectGenerator.WatchAppType appType, string expectedName)
{
// ignore the fact that all params are the same, we do not care
var generator = new BCLTestProjectGenerator (outputdir, outputdir, outputdir, outputdir, outputdir);
var path = generator.GetProjectPath (projectName, appType);
Assert.Equal (Path.Combine (generator.OutputDirectoryPath, expectedName), path);
}
[Theory]
[InlineData ("/usr/path", Platform.iOS, "Info.plist")]
[InlineData ("/usr/second/path", Platform.TvOS, "Info-tv.plist")]
[InlineData ("/usr/other/path", Platform.WatchOS, "Info-watchos.plist")]
// TODO: [InlineData ("/usr/mac/path", Platform.MacOS)] not implemented yet
public void GetPListPath (string rootDir, Platform platform, string expectedName)
{
var path = BCLTestProjectGenerator.GetPListPath (rootDir, platform);
Assert.Equal (Path.Combine (rootDir, expectedName), path);
}
[Theory]
[InlineData ("/usr/bin", BCLTestProjectGenerator.WatchAppType.App, "Info-watchos-app.plist")]
[InlineData ("/usr/local", BCLTestProjectGenerator.WatchAppType.Extension, "Info-watchos-extension.plist")]
public void GetPListPathWatchOS (string rootDir, BCLTestProjectGenerator.WatchAppType appType, string expectedName)
{
var path = BCLTestProjectGenerator.GetPListPath (rootDir, appType);
Assert.Equal (Path.Combine (rootDir, expectedName), path);
}
[Theory]
[InlineData ("System.Xml.dll")]
[InlineData ("MyAssembly.dll")]
public void GetReferenceNodeNullHint (string assembly)
{
var expected = $"<Reference Include=\"{assembly}\" />";
Assert.Equal (expected, BCLTestProjectGenerator.GetReferenceNode (assembly));
}
[Theory]
[InlineData ("System.Xml.dll", "my/path/to/the/dll")]
[InlineData ("MyAssembly.dll", "thepath")]
public void GetReferenceNode (string assembly, string hint)
{
var fixedHint = hint.Replace ("/", "\\");
var sb = new StringBuilder ();
sb.AppendLine ($"<Reference Include=\"{assembly}\" >");
sb.AppendLine ($"<HintPath>{fixedHint}</HintPath>");
sb.AppendLine ("</Reference>");
var expected = sb.ToString ();
Assert.Equal (expected, BCLTestProjectGenerator.GetReferenceNode (assembly, hint));
}
[Theory]
[InlineData ("my/path/to/the/dll")]
[InlineData ("my/other/path/to/the/dll")]
public void GetRegisterTypeNode (string registerPath)
{
var fixedPath = registerPath.Replace ("/", "\\");
var sb = new StringBuilder ();
sb.AppendLine ($"<Compile Include=\"{fixedPath}\">");
sb.AppendLine ($"<Link>{Path.GetFileName (registerPath)}</Link>");
sb.AppendLine ("</Compile>");
var expected = sb.ToString ();
Assert.Equal (expected, BCLTestProjectGenerator.GetRegisterTypeNode (registerPath));
}
[Theory]
[InlineData ("TestProject", "/my/project/plist/path")]
[InlineData ("OtherProject", "\\test\\project\\plist")]
public void GenerateWatchProject (string projectName, string plistPath)
{
var generator = new BCLTestProjectGenerator (outputdir, outputdir, outputdir, outputdir, outputdir);
var template = $"{BCLTestProjectGenerator.NameKey} {BCLTestProjectGenerator.WatchOSTemplatePathKey} {BCLTestProjectGenerator.PlistKey} {BCLTestProjectGenerator.WatchOSCsporjAppKey}";
var generatedProject = generator.GenerateWatchProject (projectName, template, plistPath);
Assert.DoesNotContain (BCLTestProjectGenerator.NameKey, generatedProject);
Assert.Contains (projectName, generatedProject);
Assert.DoesNotContain (BCLTestProjectGenerator.WatchOSTemplatePathKey, generatedProject);
Assert.DoesNotContain (BCLTestProjectGenerator.PlistKey, generatedProject);
Assert.Contains (plistPath.Replace ("/", "\\"), generatedProject);
}
}
}

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

@ -0,0 +1,69 @@
using System;
using System.IO;
using Xunit;
using Xunit.Sdk;
using BCLTestImporter;
namespace BCLTestImporterTests {
public class TestAssemblyDefinitionTest {
[Fact]
public void GetPathNullMonoRoot ()
{
var testAssemblyDefinition = new BCLTestAssemblyDefinition ("MONOTOUCH_System.Json.Microsoft_test.dll");
Assert.Throws<ArgumentNullException> (() => testAssemblyDefinition.GetPath (null, Platform.iOS));
}
[Fact]
public void IsNotXUnit ()
{
var testAssemblyDefinition = new BCLTestAssemblyDefinition ("MONOTOUCH_System.Json.Microsoft_test.dll");
Assert.False (testAssemblyDefinition.IsXUnit);
}
[Fact]
public void IsXUnit ()
{
var testAssemblyDefinition = new BCLTestAssemblyDefinition ("MONOTOUCH_System.Json.Microsoft_xunit-test.dll");
Assert.True( testAssemblyDefinition.IsXUnit);
}
[Fact]
public void GetPathiOS ()
{
var testAssemblyDefinition = new BCLTestAssemblyDefinition ("MONOTOUCH_System.Json.Microsoft_xunit-test.dll");
var home = Environment.GetEnvironmentVariable ("HOME");
var expectedPath = Path.Combine (home, "mcs/class/lib", "monotouch", "tests", testAssemblyDefinition.Name);
Assert.Equal (expectedPath, testAssemblyDefinition.GetPath (Environment.GetEnvironmentVariable("HOME"), Platform.iOS));
}
[Fact]
public void GetPathTvOS ()
{
var testAssemblyDefinition = new BCLTestAssemblyDefinition ("MONOTOUCH_System.Json.Microsoft_xunit-test.dll");
var home = Environment.GetEnvironmentVariable ("HOME");
var expectedPath = Path.Combine (home, "mcs/class/lib", "monotouch", "tests", testAssemblyDefinition.Name);
Assert.Equal (expectedPath, testAssemblyDefinition.GetPath (Environment.GetEnvironmentVariable("HOME"), Platform.TvOS));
}
[Fact]
public void GetPathWatchOS ()
{
var testAssemblyDefinition = new BCLTestAssemblyDefinition ("MONOTOUCH_System.Json.Microsoft_xunit-test.dll");
var home = Environment.GetEnvironmentVariable ("HOME");
var expectedPath = Path.Combine (home, "mcs/class/lib", "monotouch_watch", "tests", testAssemblyDefinition.Name);
Assert.Equal (expectedPath, testAssemblyDefinition.GetPath (Environment.GetEnvironmentVariable("HOME"), Platform.WatchOS));
}
[Fact]
public void GetPathMacOS ()
{
var testAssemblyDefinition = new BCLTestAssemblyDefinition ("MONOTOUCH_System.Json.Microsoft_xunit-test.dll");
var home = Environment.GetEnvironmentVariable ("HOME");
var expectedPath = Path.Combine (home, "mcs/class/lib", "xammac", "tests", testAssemblyDefinition.Name);
Assert.Equal (expectedPath, testAssemblyDefinition.GetPath (Environment.GetEnvironmentVariable("HOME"), Platform.MacOS));
}
}
}

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

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.IO;
using Xunit;
using Xunit.Sdk;
using BCLTestImporter;
namespace BCLTestImporterTests {
public class TestProjectDefinitionTest {
[Fact]
public void GetTypeForAssembliesNullMonoPath ()
{
var projectDefinition = new BCLTestProjectDefinition ("MyProject", new List<BCLTestAssemblyDefinition> ());
Assert.Throws<ArgumentNullException> (() => projectDefinition.GetTypeForAssemblies (null, Platform.iOS));
}
}
}

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

@ -0,0 +1,33 @@
using System;
using System.IO;
using System.Threading.Tasks;
namespace BCLTestImporter {
/// <summary>
/// Class that knows how to generate the plist of a test project.
/// </summary>
public class BCLTestInfoPlistGenerator {
internal static string ApplicationNameReplacement = "%APPLICATION NAME%";
internal static string IndentifierReplacement = "%BUNDLE INDENTIFIER%";
internal static string WatchAppIndentifierReplacement = "%WATCHAPP INDENTIFIER%";
public static async Task<string> GenerateCodeAsync (string templatePath, string projectName)
{
if (templatePath == null)
throw new ArgumentNullException (nameof (templatePath));
if (projectName == null)
throw new ArgumentNullException (nameof (projectName));
// got the lines we want to add, read the template and substitute
using (var reader = new StreamReader(templatePath)) {
var result = await reader.ReadToEndAsync ();
result = result.Replace (ApplicationNameReplacement, projectName);
result = result.Replace (IndentifierReplacement, $"com.xamarin.bcltests.{projectName}");
result = result.Replace (WatchAppIndentifierReplacement, $"com.xamarin.bcltests.{projectName}.container");
return result;
}
}
// Generates the code for the type registration using the give path to the template to use
public static string GenerateCode (string templatePath, string projectName) => GenerateCodeAsync (templatePath, projectName).Result;
}
}

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

@ -0,0 +1,129 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
namespace BCLTestImporter {
/// <summary>
/// Class that defines a bcl test project. A bcl test project by definition is the combination of the name
/// of the project and a set on assemblies to be tested.
/// </summary>
public struct BCLTestProjectDefinition {
public string Name { get; set; }
public List<BCLTestAssemblyDefinition> TestAssemblies {get; private set;}
public bool IsXUnit {
get {
if (TestAssemblies.Count > 0)
return TestAssemblies [0].IsXUnit;
return false;
}
}
public BCLTestProjectDefinition (string name, string[] assemblies)
{
if (assemblies.Length == 0)
throw new ArgumentException ("Most provide at least an assembly.");
Name = name;
TestAssemblies = new List<BCLTestAssemblyDefinition> (assemblies.Length);
foreach (var assembly in assemblies) {
TestAssemblies.Add (new BCLTestAssemblyDefinition (assembly));
}
}
public BCLTestProjectDefinition (string name, List<BCLTestAssemblyDefinition> assemblies)
{
Name = name;
TestAssemblies = assemblies;
}
static IEnumerable<string> GetAssemblyReferences (string assemblyPath) {
var a = Assembly.LoadFile (assemblyPath);
return a.GetReferencedAssemblies ().Select ((arg) => arg.Name);
}
/// <summary>
/// Ensures that the project is correctly defined and does not mix NUnit and xUnit.
/// </summary>
/// <returns></returns>
public bool Validate ()
{
// what a lame way to test this!
var xUnitAssemblies = new List<BCLTestAssemblyDefinition> ();
var nUnitAssemblies = new List<BCLTestAssemblyDefinition> ();
foreach (var assemblyDefinition in TestAssemblies) {
if (assemblyDefinition.IsXUnit)
xUnitAssemblies.Add (assemblyDefinition);
else
nUnitAssemblies.Add (assemblyDefinition);
}
return TestAssemblies.Count == xUnitAssemblies.Count || TestAssemblies.Count == nUnitAssemblies.Count;
}
/// <summary>
/// Returns the assemblies that a referenced by the given test assembly.
/// </summary>
/// <returns></returns>
IEnumerable<string> GetProjectAssemblyReferences (string monoRootPath, Platform platform)
{
var set = new HashSet<string> ();
foreach (var definition in TestAssemblies) {
foreach (var reference in GetAssemblyReferences (definition.GetPath (monoRootPath, platform))) {
set.Add (reference);
}
}
return set;
}
public Dictionary <string, Type> GetTypeForAssemblies (string monoRootPath, Platform platform) {
if (monoRootPath == null)
throw new ArgumentNullException (nameof (monoRootPath));
var dict = new Dictionary <string, Type> ();
// loop over the paths, grab the assembly, find a type and then add it
foreach (var definition in TestAssemblies) {
var path = definition.GetPath (monoRootPath, platform);
var a = Assembly.LoadFile (path);
try {
var types = a.ExportedTypes;
if (!types.Any ()) {
continue;
}
dict[Path.GetFileName (path)] = types.First (t => !t.IsAbstract && !t.IsGenericType && t.FullName.Contains ("Test"));
} catch (ReflectionTypeLoadException e) { // ReflectionTypeLoadException
// we did get an exception, possible reason, the type comes from an assebly not loaded, but
// nevertheless we can do something about it, get all the not null types in the exception
// and use one of them
var types = e.Types.Where (t => t != null).Where (t => !t.IsAbstract && !t.IsGenericType && t.FullName.Contains ("Test"));
if (types.Any()) {
dict[Path.GetFileName (path)] = types.First ();
}
}
}
return dict;
}
/// <summary>
/// Returns a list of tuples that contains the name of the assembly and the required hint path. If the
/// path is null it means that the assembly is part of the distribution.
/// </summary>
/// <param name="monoRootPath">The root path of the mono checkout.</param>
/// <param name="platform">The platform we are working with.</param>
/// <returns>The list of tuples (assembly name, path hint) for all the assemblies in the project.</returns>
public List<(string assembly, string hintPath)> GetAssemblyInclusionInformation (string monoRootPath,
Platform platform)
{
if (monoRootPath == null)
throw new ArgumentNullException (nameof (monoRootPath));
return GetProjectAssemblyReferences (monoRootPath, platform).Select (
a => (assembly: a,
hintPath: BCLTestAssemblyDefinition.GetHintPathForRefenreceAssembly (a, monoRootPath, platform))).Union (
TestAssemblies.Select (
definition => (assembly: definition.Name,
hintPath: definition.GetPath (monoRootPath, platform))))
.ToList ();
}
}
}

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

@ -0,0 +1,619 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace BCLTestImporter {
/// <summary>
/// Class that knows how to generate .csproj files based on a BCLTestProjectDefinition.
/// </summary>
public class BCLTestProjectGenerator {
static string NUnitPattern = "MONOTOUCH_*_test.dll";
static string xUnitPattern = "MONOTOUCH_*_xunit-test.dll";
internal static readonly string NameKey = "%NAME%";
internal static readonly string ReferencesKey = "%REFERENCES%";
internal static readonly string RegisterTypeKey = "%REGISTER TYPE%";
internal static readonly string PlistKey = "%PLIST PATH%";
internal static readonly string WatchOSTemplatePathKey = "%TEMPLATE PATH%";
internal static readonly string WatchOSCsporjAppKey = "%WATCH APP PROJECT PATH%";
internal static readonly string WatchOSCsporjExtensionKey ="%WATCH EXTENSION PROJECT PATH%";
static readonly Dictionary<Platform, string> plistTemplateMatches = new Dictionary<Platform, string> {
{Platform.iOS, "Info.plist.in"},
{Platform.TvOS, "Info-tv.plist.in"},
{Platform.WatchOS, "Info-watchos.plist.in"},
};
static readonly Dictionary<Platform, string> projectTemplateMatches = new Dictionary<Platform, string> {
{Platform.iOS, "BCLTests.csproj.in"},
{Platform.TvOS, "BCLTests-tv.csproj.in"},
{Platform.WatchOS, "BCLTests-watchos.csproj.in"},
};
static readonly Dictionary<WatchAppType, string> watchOSProjectTemplateMatches = new Dictionary<WatchAppType, string>
{
{ WatchAppType.App, "BCLTests-watchos-app.csproj.in"},
{ WatchAppType.Extension, "BCLTests-watchos-extension.csproj.in"}
};
public enum WatchAppType {
App,
Extension
}
static readonly Dictionary<WatchAppType, string> watchOSPlistTemplateMatches = new Dictionary<WatchAppType, string> {
{WatchAppType.App, "Info-watchos-app.plist.in"},
{WatchAppType.Extension, "Info-watchos-extension.plist.in"}
};
//list of reference that we are already adding, and we do not want to readd (although it is just a warning)
static readonly List<string> excludeDlls = new List<string> {
"mscorlib",
"nunitlite",
"System",
"System.Xml",
"System.Xml.Linq",
};
// Ww have different lists for the test projects:
// 1. commonTestProjects: Those projects that can be ran in all platforms.
// 2. iOSTestProjects: Those projects that can be ran on iOS
static readonly List<(string name, string[] assemblies)> commonTestProjects = new List<(string name, string[] assemblies)> {
// NUNIT TESTS
(name:"SystemTests", assemblies: new[] {"MONOTOUCH_System_test.dll"}),
(name:"SystemCoreTests", assemblies: new [] {"MONOTOUCH_System.Core_test.dll"}),
(name:"SystemDataTests", assemblies: new [] {"MONOTOUCH_System.Data_test.dll"}),
(name:"SystemNetHttpTests", assemblies: new [] {"MONOTOUCH_System.Net.Http_test.dll"}),
(name:"SystemNumericsTests", assemblies: new [] {"MONOTOUCH_System.Numerics_test.dll"}),
(name:"SystemRuntimeSerializationTests", assemblies: new [] {"MONOTOUCH_System.Runtime.Serialization_test.dll"}),
(name:"SystemTransactionsTests", assemblies: new [] {"MONOTOUCH_System.Transactions_test.dll"}),
(name:"SystemXmlTests", assemblies: new [] {"MONOTOUCH_System.Xml_test.dll"}),
(name:"SystemXmlLinqTests", assemblies: new [] {"MONOTOUCH_System.Xml.Linq_test.dll"}),
(name:"MonoSecurityTests", assemblies: new [] {"MONOTOUCH_Mono.Security_test.dll"}),
(name:"SystemComponentModelDataAnnotationTests", assemblies: new [] {"MONOTOUCH_System.ComponentModel.DataAnnotations_test.dll"}),
(name:"SystemJsonTests", assemblies: new [] {"MONOTOUCH_System.Json_test.dll"}),
(name:"SystemServiceModelWebTests", assemblies: new [] {"MONOTOUCH_System.ServiceModel.Web_test.dll"}),
(name:"MonoDataTdsTests", assemblies: new [] {"MONOTOUCH_Mono.Data.Tds_test.dll"}),
(name:"SystemIOCompressionTests", assemblies: new [] {"MONOTOUCH_System.IO.Compression_test.dll"}),
(name:"SystemIOCompressionFileSystemTests", assemblies: new [] {"MONOTOUCH_System.IO.Compression.FileSystem_test.dll"}),
(name:"MonoCSharpTests", assemblies: new [] {"MONOTOUCH_Mono.CSharp_test.dll"}),
(name:"SystemSecurityTests", assemblies: new [] {"MONOTOUCH_System.Security_test.dll"}),
(name:"SystemServiceModelTests", assemblies: new [] {"MONOTOUCH_System.ServiceModel_test.dll"}),
(name:"SystemJsonMicrosoftTests", assemblies: new [] {"MONOTOUCH_System.Json.Microsoft_test.dll"}),
(name:"SystemDataDataSetExtensionTests", assemblies: new [] {"MONOTOUCH_System.Data.DataSetExtensions_test.dll"}),
(name:"SystemRuntimeSerializationFormattersSoapTests", assemblies: new [] {"MONOTOUCH_System.Runtime.Serialization.Formatters.Soap_test.dll"}),
(name:"CorlibTests", assemblies: new [] {"MONOTOUCH_corlib_test.dll"}),
(name:"MonoParallelTests", assemblies: new [] {"MONOTOUCH_Mono.Parallel_test.dll"}),
(name:"MonoRuntimeTests", assemblies: new [] {"MONOTOUCH_Mono.Runtime.Tests_test.dll"}),
(name:"MonoTaskletsTests", assemblies: new [] {"MONOTOUCH_Mono.Tasklets_test.dll"}),
(name:"SystemThreadingTasksDataflowTests", assemblies: new [] {"MONOTOUCH_System.Threading.Tasks.Dataflow_test.dll"}),
// XUNIT TESTS
(name:"SystemDataXunit", assemblies: new [] {"MONOTOUCH_System.Data_xunit-test.dll"}),
(name:"SystemJsonXunit", assemblies: new [] {"MONOTOUCH_System.Json_xunit-test.dll"}),
(name:"SystemNumericsXunit", assemblies: new [] {"MONOTOUCH_System.Numerics_xunit-test.dll"}),
(name:"SystemSecurityXunit", assemblies: new [] {"MONOTOUCH_System.Security_xunit-test.dll"}),
(name:"SystemThreadingTaskXunit", assemblies: new [] {"MONOTOUCH_System.Threading.Tasks.Dataflow_xunit-test.dll"}),
(name:"SystemLinqXunit", assemblies: new [] {"MONOTOUCH_System.Xml.Linq_xunit-test.dll"}),
(name:"SystemRuntimeCompilerServicesUnsafeXunit", assemblies: new [] {"MONOTOUCH_System.Runtime.CompilerServices.Unsafe_xunit-test.dll"}),
};
static readonly List <string> CommonIgnoredAssemblies = new List <string> {
"MONOTOUCH_System.Data_xunit-test.dll", // issue https://github.com/xamarin/maccore/issues/1131
"MONOTOUCH_System.Security_xunit-test.dll",// issue https://github.com/xamarin/maccore/issues/1128
"MONOTOUCH_System.Threading.Tasks.Dataflow_xunit-test.dll", // issue https://github.com/xamarin/maccore/issues/1132
"MONOTOUCH_System.Xml_test.dll", // issue https://github.com/xamarin/maccore/issues/1133
"MONOTOUCH_System.Transactions_test.dll", // issue https://github.com/xamarin/maccore/issues/1134
"MONOTOUCH_System_test.dll", // issues https://github.com/xamarin/maccore/issues/1135
"MONOTOUCH_System.ServiceModel.Web_test.dll", // issue https://github.com/xamarin/maccore/issues/1137
"MONOTOUCH_System.ServiceModel_test.dll", // issue https://github.com/xamarin/maccore/issues/1138
"MONOTOUCH_System.Security_test.dll", // issue https://github.com/xamarin/maccore/issues/1139
"MONOTOUCH_System.Runtime.Serialization.Formatters.Soap_test.dll", // issue https://github.com/xamarin/maccore/issues/1140
"MONOTOUCH_System.Net.Http_test.dll", // issue https://github.com/xamarin/maccore/issues/1144 and https://github.com/xamarin/maccore/issues/1145
"MONOTOUCH_System.IO.Compression_test.dll", // issue https://github.com/xamarin/maccore/issues/1146
"MONOTOUCH_System.IO.Compression.FileSystem_test.dll", // issue https://github.com/xamarin/maccore/issues/1147 and https://github.com/xamarin/maccore/issues/1148
"MONOTOUCH_System.Data_test.dll", // issue https://github.com/xamarin/maccore/issues/1149
"MONOTOUCH_System.Data.DataSetExtensions_test.dll", // issue https://github.com/xamarin/maccore/issues/1150 and https://github.com/xamarin/maccore/issues/1151
"MONOTOUCH_System.Core_test.dll", // issue https://github.com/xamarin/maccore/issues/1143
"MONOTOUCH_Mono.Runtime.Tests_test.dll", // issue https://github.com/xamarin/maccore/issues/1141
"MONOTOUCH_corlib_test.dll", // issue https://github.com/xamarin/maccore/issues/1153
"MONOTOUCH_Commons.Xml.Relaxng_test.dll", // not supported by xamarin
"MONOTOUCH_Cscompmgd_test.dll", // not supported by xamarin
"MONOTOUCH_I18N.CJK_test.dll",
"MONOTOUCH_I18N.MidEast_test.dll",
"MONOTOUCH_I18N.Other_test.dll",
"MONOTOUCH_I18N.Rare_test.dll",
"MONOTOUCH_I18N.West_test.dll",
"MONOTOUCH_Mono.C5_test.dll", // not supported by xamarin
"MONOTOUCH_Mono.CodeContracts_test.dll", // not supported by xamarin
"MONOTOUCH_Novell.Directory.Ldap_test.dll", // not supported by xamarin
"MONOTOUCH_Mono.Profiler.Log_xunit-test.dll", // special tests that need an extra app to connect as a profiler
};
// list of assemblies that are going to be ignored, any project with an assemblies that is ignored will
// be ignored
static readonly List<string> iOSIgnoredAssemblies = new List<string> {};
static readonly List<string> tvOSIgnoredAssemblies = new List<string> {
"MONOTOUCH_System.Xml.Linq_xunit-test.dll", // issue https://github.com/xamarin/maccore/issues/1130
"MONOTOUCH_System.Numerics_xunit-test.dll", // issue https://github.com/xamarin/maccore/issues/1129
};
static readonly List<string> watcOSIgnoredAssemblies = new List<string> {
"MONOTOUCH_System.Xml.Linq_xunit-test.dll", // issue https://github.com/xamarin/maccore/issues/1130
"MONOTOUCH_System.Numerics_xunit-test.dll", // issue https://github.com/xamarin/maccore/issues/1129
"MONOTOUCH_Mono.Security_test.dll", // issue https://github.com/xamarin/maccore/issues/1142
"MONOTOUCH_Mono.Data.Tds_test.dll", // issue https://gist.github.com/mandel-macaque/d97fa28f8a73c3016d1328567da77a0b
};
readonly bool isCodeGeneration;
public bool Override { get; set; }
public string OutputDirectoryPath { get; private set; }
public string MonoRootPath { get; private set; }
public string ProjectTemplateRootPath { get; private set; }
public string PlistTemplateRootPath{ get; private set; }
public string RegisterTypesTemplatePath { get; private set; }
string GeneratedCodePathRoot => Path.Combine (OutputDirectoryPath, "generated");
string WatchContainerTemplatePath => Path.Combine (OutputDirectoryPath, "templates", "watchOS", "Container").Replace ("/", "\\");
string WatchAppTemplatePath => Path.Combine (OutputDirectoryPath, "templates", "watchOS", "App").Replace ("/", "\\");
string WatchExtensionTemplatePath => Path.Combine (OutputDirectoryPath, "templates", "watchOS", "Extension").Replace ("/", "\\");
public BCLTestProjectGenerator (string outputDirectory)
{
OutputDirectoryPath = outputDirectory ?? throw new ArgumentNullException (nameof (outputDirectory));
}
public BCLTestProjectGenerator (string outputDirectory, string monoRootPath, string projectTemplatePath, string registerTypesTemplatePath, string plistTemplatePath)
{
isCodeGeneration = true;
OutputDirectoryPath = outputDirectory ?? throw new ArgumentNullException (nameof (outputDirectory));
MonoRootPath = monoRootPath ?? throw new ArgumentNullException (nameof (monoRootPath));
ProjectTemplateRootPath = projectTemplatePath ?? throw new ArgumentNullException (nameof (projectTemplatePath));
PlistTemplateRootPath = plistTemplatePath ?? throw new ArgumentNullException (nameof (plistTemplatePath));
RegisterTypesTemplatePath = registerTypesTemplatePath ?? throw new ArgumentNullException (nameof (registerTypesTemplatePath));
}
/// <summary>
/// Returns the path to be used to store the project file depending on the platform.
/// </summary>
/// <param name="projectName">The name of the project being generated.</param>
/// <param name="platform">The supported platform by the project.</param>
/// <returns></returns>
internal string GetProjectPath (string projectName, Platform platform)
{
switch (platform) {
case Platform.iOS:
return Path.Combine (OutputDirectoryPath, $"{projectName}.csproj");
case Platform.TvOS:
return Path.Combine (OutputDirectoryPath, $"{projectName}-tvos.csproj");
case Platform.WatchOS:
return Path.Combine (OutputDirectoryPath, $"{projectName}-watchos.csproj");
default:
return null;
}
}
internal string GetProjectPath (string projectName, WatchAppType appType)
{
switch (appType) {
case WatchAppType.App:
return Path.Combine (OutputDirectoryPath, $"{projectName}-watchos-app.csproj");
default:
return Path.Combine (OutputDirectoryPath, $"{projectName}-watchos-extension.csproj");
}
}
/// <summary>
/// Returns the path to be used to store the projects plist file depending on the platform.
/// </summary>
/// <param name="rootDir">The root dir to use.</param>
/// <param name="platform">The platform that is supported by the project.</param>
/// <returns></returns>
internal static string GetPListPath (string rootDir, Platform platform)
{
switch (platform) {
case Platform.iOS:
return Path.Combine (rootDir, "Info.plist");
case Platform.TvOS:
return Path.Combine (rootDir, "Info-tv.plist");
case Platform.WatchOS:
return Path.Combine (rootDir, "Info-watchos.plist");
default:
return Path.Combine (rootDir, "Info.plist");
}
}
internal static string GetPListPath (string rootDir, WatchAppType appType)
{
switch (appType) {
case WatchAppType.App:
return Path.Combine (rootDir, "Info-watchos-app.plist");
default:
return Path.Combine (rootDir, "Info-watchos-extension.plist");
}
}
// creates the reference node
internal static string GetReferenceNode (string assemblyName, string hintPath = null)
{
// lets not complicate our life with Xml, we just need to replace two things
if (string.IsNullOrEmpty (hintPath)) {
return $"<Reference Include=\"{assemblyName}\" />";
} else {
// the hint path is using unix separators, we need to use windows ones
hintPath = hintPath.Replace ('/', '\\');
var sb = new StringBuilder ();
sb.AppendLine ($"<Reference Include=\"{assemblyName}\" >");
sb.AppendLine ($"<HintPath>{hintPath}</HintPath>");
sb.AppendLine ("</Reference>");
return sb.ToString ();
}
}
internal static string GetRegisterTypeNode (string registerPath)
{
var sb = new StringBuilder ();
sb.AppendLine ($"<Compile Include=\"{registerPath}\">");
sb.AppendLine ($"<Link>{Path.GetFileName (registerPath)}</Link>");
sb.AppendLine ("</Compile>");
return sb.ToString ();
}
/// <summary>
/// Returns is a project should be ignored in a platform. A project is ignored in one of the assemblies in the
/// project is ignored in the platform.
/// </summary>
/// <param name="project">The project which is under test.</param>
/// <param name="platform">The platform to which we are testing against.</param>
/// <returns>If the project should be ignored in a platform or not.</returns>
bool IsIgnored(BCLTestProjectDefinition project, Platform platform)
{
foreach (var a in project.TestAssemblies){
if (CommonIgnoredAssemblies.Contains (a.Name))
return true;
switch (platform){
case Platform.iOS:
return iOSIgnoredAssemblies.Contains (a.Name);
case Platform.TvOS:
return tvOSIgnoredAssemblies.Contains (a.Name);
case Platform.WatchOS:
return watcOSIgnoredAssemblies.Contains (a.Name);
default:
return true;
}
}
return false;
}
async Task<List<(string name, string path, bool xunit)>> GenerateWatchOSTestProjectsAsync (
IEnumerable<(string name, string[] assemblies)> projects, string generatedDir)
{
var projectPaths = new List<(string name, string path, bool xunit)> ();
foreach (var def in projects) {
// each watch os project requires 3 different ones:
// 1. The app
// 2. The container
// 3. The extensions
// TODO: The following is very similar to what is done in the iOS generation. Must be grouped
var projectDefinition = new BCLTestProjectDefinition (def.name, def.assemblies);
if (IsIgnored (projectDefinition, Platform.WatchOS)) // if it is ignored, continue
continue;
if (!projectDefinition.Validate ())
throw new InvalidOperationException ("xUnit and NUnit assemblies cannot be mixed in a test project.");
var generatedCodeDir = Path.Combine (generatedDir, projectDefinition.Name);
if (!Directory.Exists (generatedCodeDir)) {
Directory.CreateDirectory (generatedCodeDir);
}
var registerTypePath = Path.Combine (generatedCodeDir, "RegisterType.cs");
var typesPerAssembly = projectDefinition.GetTypeForAssemblies (MonoRootPath, Platform.WatchOS);
var registerCode = await RegisterTypeGenerator.GenerateCodeAsync (typesPerAssembly,
projectDefinition.IsXUnit, RegisterTypesTemplatePath);
using (var file = new StreamWriter (registerTypePath, false)) { // false is do not append
await file.WriteAsync (registerCode);
}
// create the plist for each of the apps
var projectData = new Dictionary<WatchAppType, (string plist, string project)> ();
foreach (var appType in new [] {WatchAppType.Extension, WatchAppType.App}) {
(string plist, string project) data;
var plistTemplate = Path.Combine (PlistTemplateRootPath, watchOSPlistTemplateMatches[appType]);
var plist = await BCLTestInfoPlistGenerator.GenerateCodeAsync (plistTemplate, projectDefinition.Name);
data.plist = GetPListPath (generatedCodeDir, appType);
using (var file = new StreamWriter (data.plist, false)) { // false is do not append
await file.WriteAsync (plist);
}
string generatedProject;
var projetTemplate = Path.Combine (ProjectTemplateRootPath, watchOSProjectTemplateMatches[appType]);
switch (appType) {
case WatchAppType.App:
generatedProject = await GenerateWatchAppAsync (projectDefinition.Name, projetTemplate, data.plist);
break;
default:
generatedProject = await GenerateWatchExtensionAsync (projectDefinition.Name, projetTemplate, data.plist, registerTypePath, projectDefinition.GetAssemblyInclusionInformation (MonoRootPath, Platform.WatchOS));
break;
}
data.project = GetProjectPath (projectDefinition.Name, appType);
using (var file = new StreamWriter (data.project, false)) { // false is do not append
await file.WriteAsync (generatedProject);
}
projectData[appType] = data;
} // foreach app type
var rootPlistTemplate = Path.Combine (PlistTemplateRootPath, plistTemplateMatches[Platform.WatchOS]);
var rootPlist = await BCLTestInfoPlistGenerator.GenerateCodeAsync (rootPlistTemplate, projectDefinition.Name);
var infoPlistPath = GetPListPath (generatedCodeDir, Platform.WatchOS);
using (var file = new StreamWriter (infoPlistPath, false)) { // false is do not append
await file.WriteAsync (rootPlist);
}
var projectTemplatePath = Path.Combine (ProjectTemplateRootPath, projectTemplateMatches[Platform.WatchOS]);
var rootProjectPath = GetProjectPath (projectDefinition.Name, Platform.WatchOS);
using (var file = new StreamWriter (rootProjectPath, false)) // false is do not append
using (var reader = new StreamReader (projectTemplatePath)){
var template = await reader.ReadToEndAsync ();
var generatedRootProject = GenerateWatchProject (def.name, template, infoPlistPath);
await file.WriteAsync (generatedRootProject);
}
// we have the 3 projects we depend on, we need the root one, the one that will be used by harness
projectPaths.Add ((name: projectDefinition.Name, path: rootProjectPath, xunit: projectDefinition.IsXUnit));
} // foreach project
return projectPaths;
}
async Task<List<(string name, string path, bool xunit)>> GenerateiOSTestProjectsAsync (
IEnumerable<(string name, string[] assemblies)> projects, Platform platform, string generatedDir)
{
if (platform == Platform.WatchOS)
throw new ArgumentException (nameof (platform));
var projectPaths = new List<(string name, string path, bool xunit)> ();
foreach (var def in projects) {
var projectDefinition = new BCLTestProjectDefinition (def.name, def.assemblies);
if (IsIgnored (projectDefinition, platform)) // some projects are ignored, so we just continue
continue;
if (!projectDefinition.Validate ())
throw new InvalidOperationException ("xUnit and NUnit assemblies cannot be mixed in a test project.");
// generate the required type registration info
var generatedCodeDir = Path.Combine (generatedDir, projectDefinition.Name);
if (!Directory.Exists (generatedCodeDir)) {
Directory.CreateDirectory (generatedCodeDir);
}
var registerTypePath = Path.Combine (generatedCodeDir, "RegisterType.cs");
var typesPerAssembly = projectDefinition.GetTypeForAssemblies (MonoRootPath, platform);
var registerCode = await RegisterTypeGenerator.GenerateCodeAsync (typesPerAssembly,
projectDefinition.IsXUnit, RegisterTypesTemplatePath);
using (var file = new StreamWriter (registerTypePath, false)) { // false is do not append
await file.WriteAsync (registerCode);
}
var plistTemplate = Path.Combine (PlistTemplateRootPath, plistTemplateMatches[platform]);
var plist = await BCLTestInfoPlistGenerator.GenerateCodeAsync (plistTemplate, projectDefinition.Name);
var infoPlistPath = GetPListPath (generatedCodeDir, platform);
using (var file = new StreamWriter (infoPlistPath, false)) { // false is do not append
await file.WriteAsync (plist);
}
var projectTemplatePath = Path.Combine (ProjectTemplateRootPath, projectTemplateMatches[platform]);
var generatedProject = await GenerateAsync (projectDefinition.Name, registerTypePath,
projectDefinition.GetAssemblyInclusionInformation (MonoRootPath, platform), projectTemplatePath, infoPlistPath);
var projectPath = GetProjectPath (projectDefinition.Name, platform);
projectPaths.Add ((name: projectDefinition.Name, path: projectPath, xunit: projectDefinition.IsXUnit));
using (var file = new StreamWriter (projectPath, false)) { // false is do not append
await file.WriteAsync (generatedProject);
}
} // foreach project
return projectPaths;
}
/// <summary>
/// Generates all the project files for the given projects and platform
/// </summary>
/// <param name="projects">The list of projects to be generated.</param>
/// <param name="platform">The platform to which the projects have to be generated. Each platform
/// has its own details.</param>
/// <param name="generatedDir">The dir where the projects will be saved.</param>
/// <returns></returns>
async Task<List<(string name, string path, bool xunit)>> GenerateTestProjectsAsync (
IEnumerable<(string name, string[] assemblies)> projects, Platform platform, string generatedDir)
{
List<(string name, string path, bool xunit)> result;
if (platform == Platform.WatchOS)
result = await GenerateWatchOSTestProjectsAsync (projects, generatedDir);
else
result = await GenerateiOSTestProjectsAsync (projects, platform, generatedDir);
return result;
}
// generates a project per platform of the common projects.
async Task<List<(string name, string path, bool xunit, List<Platform> platforms)>> GenerateAllCommonTestProjectsAsync ()
{
var projectPaths = new List<(string name, string path, bool xunit, List<Platform> platforms)> ();
if (!isCodeGeneration)
throw new InvalidOperationException ("Project generator was instantiated to delete the generated code.");
var generatedCodePathRoot = GeneratedCodePathRoot;
if (!Directory.Exists (generatedCodePathRoot)) {
Directory.CreateDirectory (generatedCodePathRoot);
}
var projects = new Dictionary<string, (string path, bool xunit, List<Platform> platforms)> ();
foreach (var platform in new [] {Platform.iOS, Platform.TvOS, Platform.WatchOS}) {
var generated = await GenerateTestProjectsAsync (commonTestProjects, platform, generatedCodePathRoot);
foreach (var (name, path, xunit) in generated) {
if (!projects.ContainsKey (name)) {
projects [name] = (path, xunit, new List<Platform> { platform });
} else {
projects [name].platforms.Add (platform);
}
}
} // foreach platform
// return the grouped projects
foreach (var name in projects.Keys) {
projectPaths.Add ((name, projects[name].path, projects[name].xunit, projects[name].platforms));
}
return projectPaths;
}
// creates all the projects that have already been defined
public async Task<List<(string name, string path, bool xunit, List<Platform> platforms)>> GenerateAllTestProjectsAsync ()
{
var projectPaths = new List<(string name, string path, bool xunit, List<Platform> platforms)> ();
if (!isCodeGeneration)
throw new InvalidOperationException ("Project generator was instantiated to delete the generated code.");
var generatedCodePathRoot = GeneratedCodePathRoot;
if (!Directory.Exists (generatedCodePathRoot)) {
Directory.CreateDirectory (generatedCodePathRoot);
}
// generate all the common projects
projectPaths.AddRange (await GenerateAllCommonTestProjectsAsync ());
return projectPaths;
}
public List<(string name, string path, bool xunit, List<Platform> platforms)> GenerateAllTestProjects () => GenerateAllTestProjectsAsync ().Result;
/// <summary>
/// Generates an iOS project for testing purposes. The generated project will contain the references to the
/// mono test assemblies to run.
/// </summary>
/// <param name="projectName">The name of the project under generation.</param>
/// <param name="registerPath">The path to the code that register the types so that the assemblies are not linked.</param>
/// <param name="info">The list of assemblies to be added to the project and their hint paths.</param>
/// <param name="templatePath">A path to the template used to generate the path.</param>
/// <param name="infoPlistPath">The path to the info plist of the project.</param>
/// <returns></returns>
static async Task<string> GenerateAsync (string projectName, string registerPath, List<(string assembly, string hintPath)> info, string templatePath, string infoPlistPath)
{
// fix possible issues with the paths to be included in the msbuild xml
infoPlistPath = infoPlistPath.Replace ('/', '\\');
var sb = new StringBuilder ();
foreach (var assemblyInfo in info) {
if (!excludeDlls.Contains (assemblyInfo.assembly))
sb.AppendLine (GetReferenceNode (assemblyInfo.assembly, assemblyInfo.hintPath));
}
using (var reader = new StreamReader(templatePath)) {
var result = await reader.ReadToEndAsync ();
result = result.Replace (NameKey, projectName);
result = result.Replace (ReferencesKey, sb.ToString ());
result = result.Replace (RegisterTypeKey, GetRegisterTypeNode (registerPath));
result = result.Replace (PlistKey, infoPlistPath);
return result;
}
}
internal string GenerateWatchProject (string projectName, string template, string infoPlistPath)
{
var result = template.Replace (NameKey, projectName);
result = result.Replace (WatchOSTemplatePathKey, WatchContainerTemplatePath);
result = result.Replace (PlistKey, infoPlistPath);
result = result.Replace (WatchOSCsporjAppKey, GetProjectPath (projectName, WatchAppType.App).Replace ("/", "\\"));
return result;
}
async Task<string> GenerateWatchAppAsync (string projectName, string templatePath, string infoPlistPath)
{
using (var reader = new StreamReader(templatePath)) {
var result = await reader.ReadToEndAsync ();
result = result.Replace (NameKey, projectName);
result = result.Replace (WatchOSTemplatePathKey, WatchAppTemplatePath);
result = result.Replace (PlistKey, infoPlistPath);
result = result.Replace (WatchOSCsporjExtensionKey, GetProjectPath (projectName, WatchAppType.Extension).Replace ("/", "\\"));
return result;
}
}
async Task<string> GenerateWatchExtensionAsync (string projectName, string templatePath, string infoPlistPath, string registerPath, List<(string assembly, string hintPath)> info)
{
var sb = new StringBuilder ();
foreach (var assemblyInfo in info) {
if (!excludeDlls.Contains (assemblyInfo.assembly))
sb.AppendLine (GetReferenceNode (assemblyInfo.assembly, assemblyInfo.hintPath));
}
using (var reader = new StreamReader(templatePath)) {
var result = await reader.ReadToEndAsync ();
result = result.Replace (NameKey, projectName);
result = result.Replace (WatchOSTemplatePathKey, WatchExtensionTemplatePath);
result = result.Replace (PlistKey, infoPlistPath);
result = result.Replace (RegisterTypeKey, GetRegisterTypeNode (registerPath));
result = result.Replace (ReferencesKey, sb.ToString ());
return result;
}
}
public static string Generate (string projectName, string registerPath, List<(string assembly, string hintPath)> info, string templatePath, string infoPlistPath) =>
GenerateAsync (projectName, registerPath, info, templatePath, infoPlistPath).Result;
/// <summary>
/// Removes all the generated files by the tool.
/// </summary>
public void CleanOutput ()
{
if (isCodeGeneration)
throw new InvalidOperationException ("Project generator was instantiated to project generation.");
if (Directory.Exists (GeneratedCodePathRoot))
Directory.Delete (GeneratedCodePathRoot, true);
// delete all the common projects
foreach (var platform in new [] {Platform.iOS, Platform.TvOS}) {
foreach (var testProject in commonTestProjects) {
var projectPath = GetProjectPath (testProject.name, platform);
if (File.Exists (projectPath))
File.Delete (projectPath);
}
}
// delete each of the generated project files
foreach (var projectDefinition in commonTestProjects) {
var projectPath = GetProjectPath (projectDefinition.name, Platform.iOS);
if (File.Exists (projectPath))
File.Delete (projectPath);
}
}
/// <summary>
/// Returns if all the test assemblies found in the mono path
/// </summary>
/// <param name="missingAssemblies"></param>
/// <returns></returns>
public bool AllTestAssembliesAreRan (out Dictionary<Platform, List<string>> missingAssemblies)
{
missingAssemblies = new Dictionary<Platform, List<string>> ();
foreach (var platform in new [] {Platform.iOS, Platform.TvOS}) {
var testDir = BCLTestAssemblyDefinition.GetTestDirectory (MonoRootPath, platform);
var missingAssembliesPlatform = Directory.GetFiles (testDir, NUnitPattern).Select (Path.GetFileName).Union (
Directory.GetFiles (testDir, xUnitPattern).Select (Path.GetFileName)).ToList ();
foreach (var assembly in CommonIgnoredAssemblies) {
missingAssembliesPlatform.Remove (assembly);
}
// loop over the mono root path and grab all the assemblies, then intersect the found ones with the added
// and ignored ones.
foreach (var projectDefinition in commonTestProjects) {
foreach (var testAssembly in projectDefinition.assemblies) {
missingAssembliesPlatform.Remove (testAssembly);
}
}
if (missingAssembliesPlatform.Count != 0) {
missingAssemblies[platform] = missingAssembliesPlatform;
}
}
return missingAssemblies.Keys.Count == 0;
}
}
}

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

@ -0,0 +1,36 @@
using System;
using System.IO;
using System.Reflection;
using System.Linq;
using System.Collections.Generic;
namespace BCLTestImporter {
class ConsoleWriter {
ApplicationOptions options;
public ConsoleWriter (ApplicationOptions o)
{
if (o == null)
throw new ArgumentNullException (nameof (o));
options = o;
}
public void WriteWarning (string message)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine (message);
Console.ResetColor ();
}
public void WriteError (string message)
{
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine (message);
Console.ResetColor ();
}
public void WriteLine (string message)
{
if (options.Verbose)
Console.WriteLine (message);
}
}
}

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

@ -0,0 +1,11 @@
namespace BCLTestImporter {
/// <summary>
/// Represents the supported platforms to which we can create projects.
/// </summary>
public enum Platform {
iOS,
WatchOS,
TvOS,
MacOS,
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше