Add source code
|
@ -0,0 +1,200 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.lock.json
|
||||
*.generated.cs
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
SimpleStubsDlls
|
||||
|
||||
# Visual Studo 2015 cache/options directory
|
||||
.vs/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding addin-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
*.[Cc]ache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
|
@ -0,0 +1,266 @@
|
|||
# SimpleStubs tutorial
|
||||
|
||||
In this tutorial we will show how to install and use SimpleStubs.
|
||||
|
||||
## Installation
|
||||
|
||||
To install SimpleStubs, simply install the `Etg.SimpleStubs` NuGet package to your unit test project.
|
||||
|
||||
Once installed, SimpleStubs will create stubs for all interfaces (`public` interfaces and optionally `internal` interfaces) in all referenced projects. No stubs will be generated for external libraries (dlls) but that's a feature we're considering.
|
||||
|
||||
The generated stubs will be added to the `Properties\SimpleStubs.generated.cs` file which will be regenerated every time the project is built (the stubs will be generated before the build and will be compiled as part of the build, so you don't need to worry about any of that). Because the stubs are regenerated every time, modifying the stubs manually has no effect (if you really want to modify a stub, copy it to a different file).
|
||||
|
||||
**Important note for UWP**: Because of a limitation in NuGet support for UWP (see discussion [here](https://github.com/NuGet/Home/wiki/Bringing-back-content-support,-September-24th,-2015)), the `Properties\SimpleStubs.generated.cs` file will not be automatically added to UWP projects and must be manually added (simply add the file to the `Properties` folder of your test project).
|
||||
|
||||
## Api
|
||||
|
||||
Let's consider the following interface and look at how we can use SimpleStubs to create stubs for it.
|
||||
|
||||
```csharp
|
||||
public interface IPhoneBook
|
||||
{
|
||||
long GetContactPhoneNumber(string firstName, string lastName);
|
||||
|
||||
long MyNumber { get; set; }
|
||||
|
||||
event EventHandler<long> PhoneNumberChanged;
|
||||
}
|
||||
```
|
||||
|
||||
### Stubbing methods
|
||||
```csharp
|
||||
var stub = new StubIPhoneBook
|
||||
{
|
||||
GetContactPhoneNumber_String_String = (fn, ln) =>
|
||||
{
|
||||
return 6041234567;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
You can also copy and verify the parameters values:
|
||||
```csharp
|
||||
string firstName = null;
|
||||
string lastName = null;
|
||||
var stub = new StubIPhoneBook
|
||||
{
|
||||
GetContactPhoneNumber_String_String = (fn, ln) =>
|
||||
{
|
||||
firstName = fn;
|
||||
lastName = ln;
|
||||
return 6041234567;
|
||||
}
|
||||
};
|
||||
|
||||
ClassUnderTest obj = new ClassUnderTest(stub);
|
||||
|
||||
Assert.AreEqual(expectedValue, obj.Foo());
|
||||
// parameters verification
|
||||
Assert.AreEqual("John", firstName);
|
||||
Assert.AreEqual("Smith", lastName);
|
||||
```
|
||||
|
||||
## Stubbing properties
|
||||
|
||||
```csharp
|
||||
long myNumber = 6041234567;
|
||||
var stub = new StubIPhoneBook
|
||||
{
|
||||
MyNumber_Get = () => myNumber,
|
||||
MyNumber_Set = num =>
|
||||
{
|
||||
myNumber = num;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Stubbing events
|
||||
|
||||
```csharp
|
||||
var stub = new StubIPhoneBook();
|
||||
|
||||
// Pass the stub to the code under test
|
||||
var obj = new ClassUnderTest(stub);
|
||||
|
||||
// Raise the event
|
||||
stub.PhoneNumberChanged_Raise(stub, 55);
|
||||
|
||||
// Verify the state of obj to ensure that it has reacted to the event
|
||||
```
|
||||
|
||||
## Stubbing a sequence of calls
|
||||
|
||||
In some cases, it might be useful to have a stub behave differently when it's called several times. SimpleStubs offers supports for stubbing a sequence of calls.
|
||||
|
||||
```csharp
|
||||
// Define the sequence first
|
||||
var sequence = StubsUtils.Sequence<Func<string, string, int>>()
|
||||
.Once((p1, p2) => { throw new Exception(); }) // first call will throw an exception
|
||||
.Repeat((p1, p2) => 11122233, 3) // next three calls will return 11122233
|
||||
.Forever((p1, p2) => 22233556); // any subsequent call will return 22233556
|
||||
|
||||
var stub = new StubIPhoneBook
|
||||
{
|
||||
// Get the next element from the sequence every time the method is called and invoke it
|
||||
GetContactPhoneNumber_String_String = (p1, p2) => sequence.Next(p1, p2)
|
||||
};
|
||||
|
||||
// you can also verify how many times the sequence was called
|
||||
Assert.AreEqual(5, sequence.CallCount);
|
||||
```
|
||||
|
||||
|
||||
## Full Example
|
||||
|
||||
Let's look at how we can unit test the following class (`LocationManager`) using SimpleStubs.
|
||||
|
||||
```csharp
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HelloApp
|
||||
{
|
||||
public class LocationManager
|
||||
{
|
||||
private readonly ILocationService _locationService;
|
||||
public LocationManager(ILocationService locationService)
|
||||
{
|
||||
_locationService = locationService;
|
||||
}
|
||||
|
||||
/// <returns>Current Location or null if the location could not be retrieved</returns>
|
||||
public async Task<Location> GetCurrentLocation()
|
||||
{
|
||||
try
|
||||
{
|
||||
string location = await _locationService.GetLocation();
|
||||
var ss = location.Split('/');
|
||||
return new Location(ss[0], ss[1]);
|
||||
}
|
||||
catch (LocationServiceUnavailableException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <returns>The current country code (e.g. US, CA) or null if the country code could not be retrieved</returns>
|
||||
public async Task<string> GetCurrentCountryCode()
|
||||
{
|
||||
try
|
||||
{
|
||||
Location location = await GetCurrentLocation();
|
||||
string loc = $"{location.Country}/{location.City}";
|
||||
return await _locationService.GetCountryCode(loc);
|
||||
}
|
||||
catch (LocationServiceUnavailableException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `ILocationService` interface is as follows:
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HelloApp
|
||||
{
|
||||
public interface ILocationService
|
||||
{
|
||||
/// <returns>
|
||||
/// the location in the format Country/City
|
||||
/// </returns>
|
||||
/// <exception cref="LocationServiceUnavailableException"></exception>
|
||||
Task<string> GetLocation();
|
||||
|
||||
/// <returns>the country code of the given location</returns>
|
||||
/// <exception cref="LocationServiceUnavailableException"></exception>
|
||||
Task<string> GetCountryCode(string location);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
SimpleStubs will automatically generate a stub for `ILocationService` called StubILocationService. The following tests show how the stub can be used to unit test the `LocationManager` class:
|
||||
|
||||
```csharp
|
||||
[TestMethod]
|
||||
public async Task TestGetCurrentLocation()
|
||||
{
|
||||
StubILocationService locationServiceStub = new StubILocationService
|
||||
{
|
||||
GetLocation = () => Task.FromResult("Canada/Vancouver")
|
||||
};
|
||||
|
||||
LocationManager locationManager = new LocationManager(locationServiceStub);
|
||||
Location location = await locationManager.GetCurrentLocation();
|
||||
|
||||
Assert.AreEqual("Canada", location.Country);
|
||||
Assert.AreEqual("Vancouver", location.City);
|
||||
Assert.AreEqual(1, locationServiceStub.ILocationService_GetLocation_CallCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestThatGetCurrentLocationReturnsNullIfLocationServiceIsUnavailable()
|
||||
{
|
||||
StubILocationService locationServiceStub = new StubILocationService
|
||||
{
|
||||
GetLocation = () =>
|
||||
{
|
||||
throw new LocationServiceUnavailableException();
|
||||
}
|
||||
};
|
||||
|
||||
LocationManager locationManager = new LocationManager(locationServiceStub);
|
||||
Assert.IsNull(await locationManager.GetCurrentLocation());
|
||||
Assert.AreEqual(1, locationServiceStub.ILocationService_GetLocation_CallCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestGetCurrentCountryCode()
|
||||
{
|
||||
StubILocationService locationServiceStub = new StubILocationService
|
||||
{
|
||||
GetLocation = () => Task.FromResult("Canada/Vancouver"),
|
||||
GetCountryCode_String = location => Task.FromResult("CA")
|
||||
};
|
||||
|
||||
LocationManager locationManager = new LocationManager(locationServiceStub);
|
||||
Assert.AreEqual("CA", await locationManager.GetCurrentCountryCode());
|
||||
Assert.AreEqual(1, locationServiceStub.ILocationService_GetCountryCode_String_CallCount);
|
||||
}
|
||||
```
|
||||
## Configuration
|
||||
|
||||
SimpleStubs also supports an optional configuration file that can be added to the root of your test project. The configuration file (named `SimpleStubs.json`) has the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"IgnoredProjects": [
|
||||
"IgnoredProject1",
|
||||
"IgnoredProject2"
|
||||
],
|
||||
"IgnoredInterfaces": [
|
||||
"MyNamespace.IFooInterface",
|
||||
"MyNamespace.IBarInterface"
|
||||
],
|
||||
"StubInternalInterfaces": false
|
||||
}
|
||||
```
|
||||
|
||||
The configuration file allows you to instruct SimpleStubs to omit creating stubs for a given project or interface.
|
||||
**Note** that this very useful to exclude interfaces that are causing SimpleStubs to generate stubs that don't compile (this can happen in some edge cases). If you encounter such a case, exclude the interface in question and report the problem so we can fix it.
|
||||
|
||||
It's also possible to instruct SimpleStubs to create stubs for internal interfaces (by default only public interfaces are stubbed) as shown in the configuration sample above.
|
||||
|
||||
## Current limitations
|
||||
* Methods signatures with pointers are not supported.
|
||||
* Generic methods are not supported (but generic interfaces are).
|
||||
* Only interfaces are stubbed.
|
||||
|
||||
## What if some stubs don't compile?
|
||||
|
||||
Exclude the interface that is causing the problem (using the `SimpleStubs.json` configuration file) and report the problem.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
SimpleStubs
|
||||
|
||||
Copyright (c) Microsoft Corporation
|
||||
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1 @@
|
|||
nuget pack SimpleStubs.nuspec
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"IgnoredProjects": [
|
||||
],
|
||||
"IgnoredInterfaces": [
|
||||
],
|
||||
"StubInternalInterfaces": false
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0"?>
|
||||
<package >
|
||||
<metadata>
|
||||
<id>Etg.SimpleStubs</id>
|
||||
<version>1.0.3</version>
|
||||
<title>SimpleStubs mocking framework</title>
|
||||
<authors>Microsoft Studios (BigPark)</authors>
|
||||
<owners>Microsoft Studios (BigPark)</owners>
|
||||
<licenseUrl>https://opensource.org/licenses/MIT</licenseUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>SimpleStubs is a simple mocking framework that supports Universal Windows Platform (UWP), .NET Core and .NET framework. SimpleStubs is currently developed and maintained by Microsoft BigPark Studios in Vancouver.</description>
|
||||
<releaseNotes></releaseNotes>
|
||||
<copyright>Copyright 2016</copyright>
|
||||
|
||||
</metadata>
|
||||
|
||||
<files>
|
||||
<file src="..\src\SimpleStubs\bin\Release\ETG.SimpleStubs.dll" target="lib\uap10.0" />
|
||||
<file src="..\src\SimpleStubs\bin\Release\ETG.SimpleStubs.dll" target="lib\netcore45" />
|
||||
<file src="..\src\SimpleStubs\bin\Release\ETG.SimpleStubs.dll" target="lib\netcore50" />
|
||||
<file src="..\src\SimpleStubs\bin\Release\ETG.SimpleStubs.dll" target="lib\dnxcore50" />
|
||||
<file src="..\src\SimpleStubs\bin\Release\ETG.SimpleStubs.dll" target="lib\dotnet" />
|
||||
<file src="..\src\SimpleStubs\bin\Release\ETG.SimpleStubs.dll" target="lib\net46" />
|
||||
<file src="..\src\SimpleStubs\bin\Release\ETG.SimpleStubs.dll" target="lib\dotnet50" />
|
||||
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Etg.SimpleStubs.CodeGen.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.Build.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.Build.Engine.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.Build.Framework.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.Build.Tasks.Core.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.Build.Utilities.Core.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.CodeAnalysis.CSharp.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.CodeAnalysis.CSharp.Workspaces.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.CodeAnalysis.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.CodeAnalysis.Workspaces.Desktop.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Microsoft.CodeAnalysis.Workspaces.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\System.Collections.Immutable.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\System.Composition.AttributedModel.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\System.Composition.Convention.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\System.Composition.Hosting.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\System.Composition.Runtime.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\System.Composition.TypedParts.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\System.Reflection.Metadata.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Newtonsoft.Json.dll" target="tools" />
|
||||
<file src="..\src\SimpleStubs.CodeGen\bin\Release\Autofac.dll" target="tools" />
|
||||
|
||||
<file src="..\Targets\Etg.SimpleStubs.targets" target="build" />
|
||||
<file src="SimpleStubs.generated.cs" target="content\Properties\SimpleStubs.generated.cs" />
|
||||
<file src="SimpleStubs.json" target="content\SimpleStubs.json" />
|
||||
</files>
|
||||
</package>
|
20
README.md
|
@ -1,2 +1,20 @@
|
|||
# SimpleStubs
|
||||
SimpleStubs
|
||||
=======
|
||||
|
||||
*SimpleStubs* is a simple mocking framework that supports Universal Windows Platform (UWP), .NET Core and .NET framework. SimpleStubs is currently developed and maintained by Microsoft BigPark Studios in Vancouver.
|
||||
|
||||
The framework can be installed to your test project using `Etg.SimpleStubs` NuGet package.
|
||||
|
||||
Please read the documentation below to learn more about how to install and use SimpleStubs.
|
||||
|
||||
Documentation
|
||||
=======
|
||||
* [Tutorial](Documentation/Tutorial.md).
|
||||
|
||||
Contribute!
|
||||
=======
|
||||
We welcome contributions of all sorts including pull requests, suggestions, documentation, etc. Please feel free to open an issue to discuss any matter.
|
||||
|
||||
License
|
||||
=======
|
||||
This project is licensed under the [MIT license](LICENSE).
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloApp", "HelloApp\HelloApp.csproj", "{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloAppTest", "HelloAppTest\HelloAppTest.csproj", "{C19251DF-36F9-46C6-B02D-22DAF2F8197D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Debug|x64.Build.0 = Debug|x64
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Debug|x86.Build.0 = Debug|x86
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Release|ARM.Build.0 = Release|ARM
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Release|x64.ActiveCfg = Release|x64
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Release|x64.Build.0 = Release|x64
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Release|x86.ActiveCfg = Release|x86
|
||||
{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}.Release|x86.Build.0 = Release|x86
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|x64.Build.0 = Debug|x64
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|x86.Build.0 = Debug|x86
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|ARM.Build.0 = Release|ARM
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|x64.ActiveCfg = Release|x64
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|x64.Build.0 = Release|x64
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|x64.Deploy.0 = Release|x64
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|x86.ActiveCfg = Release|x86
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|x86.Build.0 = Release|x86
|
||||
{C19251DF-36F9-46C6-B02D-22DAF2F8197D}.Release|x86.Deploy.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,128 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{51FAEF20-C80E-4A15-BC77-1375CA9F7DA8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>HelloApp</RootNamespace>
|
||||
<AssemblyName>HelloApp</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="LocationManager.cs" />
|
||||
<Compile Include="ILocationService.cs" />
|
||||
<Compile Include="Location.cs" />
|
||||
<Compile Include="LocationServiceUnavailableException.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Content Include="Properties\HelloApp.rd.xml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,20 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace HelloApp
|
||||
{
|
||||
public interface ILocationService
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// the location in the format Country/City
|
||||
/// </returns>
|
||||
/// <exception cref="LocationServiceUnavailableException"></exception>
|
||||
Task<string> GetLocation();
|
||||
|
||||
/// <returns>the country code of the given location</returns>
|
||||
/// <exception cref="LocationServiceUnavailableException"></exception>
|
||||
Task<string> GetCountryCode(string location);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
namespace HelloApp
|
||||
{
|
||||
public class Location
|
||||
{
|
||||
protected bool Equals(Location other)
|
||||
{
|
||||
return string.Equals(Country, other.Country) && string.Equals(City, other.City);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((Location) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((Country != null ? Country.GetHashCode() : 0)*397) ^ (City != null ? City.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(Location left, Location right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Location left, Location right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
|
||||
public Location(string country, string city)
|
||||
{
|
||||
Country = country;
|
||||
City = city;
|
||||
}
|
||||
|
||||
public string Country { get; }
|
||||
public string City { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Devices.PointOfService;
|
||||
|
||||
namespace HelloApp
|
||||
{
|
||||
public class LocationManager
|
||||
{
|
||||
private readonly ILocationService _locationService;
|
||||
public LocationManager(ILocationService locationService)
|
||||
{
|
||||
_locationService = locationService;
|
||||
}
|
||||
|
||||
/// <returns>Current Location or null if the location could not be retrieved</returns>
|
||||
public async Task<Location> GetCurrentLocation()
|
||||
{
|
||||
try
|
||||
{
|
||||
string location = await _locationService.GetLocation();
|
||||
var ss = location.Split('/');
|
||||
return new Location(ss[0], ss[1]);
|
||||
}
|
||||
catch (LocationServiceUnavailableException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <returns>The current country code (e.g. US, CA) or null if the country code could not be retrieved</returns>
|
||||
public async Task<string> GetCurrentCountryCode()
|
||||
{
|
||||
try
|
||||
{
|
||||
Location location = await GetCurrentLocation();
|
||||
string loc = $"{location.Country}/{location.City}";
|
||||
return await _locationService.GetCountryCode(loc);
|
||||
}
|
||||
catch (LocationServiceUnavailableException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace HelloApp
|
||||
{
|
||||
public class LocationServiceUnavailableException : Exception
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("HelloApp")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("HelloApp")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file contains Runtime Directives, specifications about types your application accesses
|
||||
through reflection and other dynamic code patterns. Runtime Directives are used to control the
|
||||
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
|
||||
library does not do any reflection, then you generally do not need to edit this file. However,
|
||||
if your library reflects over types, especially types passed to it or derived from its types,
|
||||
then you should write Runtime Directives.
|
||||
|
||||
The most common use of reflection in libraries is to discover information about types passed
|
||||
to the library. Runtime Directives have three ways to express requirements on types passed to
|
||||
your library.
|
||||
|
||||
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
|
||||
Use these directives to reflect over types passed as a parameter.
|
||||
|
||||
2. SubTypes
|
||||
Use a SubTypes directive to reflect over types derived from another type.
|
||||
|
||||
3. AttributeImplies
|
||||
Use an AttributeImplies directive to indicate that your library needs to reflect over
|
||||
types or methods decorated with an attribute.
|
||||
|
||||
For more information on writing Runtime Directives for libraries, please visit
|
||||
http://go.microsoft.com/fwlink/?LinkID=391919
|
||||
-->
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Library Name="HelloApp">
|
||||
|
||||
<!-- add directives for your library here -->
|
||||
|
||||
</Library>
|
||||
</Directives>
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"uap10.0": {}
|
||||
},
|
||||
"runtimes": {
|
||||
"win10-arm": {},
|
||||
"win10-arm-aot": {},
|
||||
"win10-x86": {},
|
||||
"win10-x86-aot": {},
|
||||
"win10-x64": {},
|
||||
"win10-x64-aot": {}
|
||||
}
|
||||
}
|
После Ширина: | Высота: | Размер: 1.4 KiB |
После Ширина: | Высота: | Размер: 7.5 KiB |
После Ширина: | Высота: | Размер: 2.9 KiB |
После Ширина: | Высота: | Размер: 1.6 KiB |
Двоичные данные
Samples/HelloApp/HelloAppTest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
Normal file
После Ширина: | Высота: | Размер: 1.2 KiB |
После Ширина: | Высота: | Размер: 1.4 KiB |
После Ширина: | Высота: | Размер: 3.1 KiB |
|
@ -0,0 +1,148 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{C19251DF-36F9-46C6-B02D-22DAF2F8197D}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>HelloAppTest</RootNamespace>
|
||||
<AssemblyName>HelloAppTest</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>HelloAppTest_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<UnitTestPlatformVersion Condition="'$(UnitTestPlatformVersion)' == ''">14.0</UnitTestPlatformVersion>
|
||||
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!--A reference to the entire .Net Framework and Windows SDK are automatically included-->
|
||||
<None Include="project.json" />
|
||||
<SDKReference Include="MSTestFramework.Universal, Version=$(UnitTestPlatformVersion)" />
|
||||
<SDKReference Include="TestPlatform.Universal, Version=$(UnitTestPlatformVersion)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\SimpleStubs.cs" />
|
||||
<Compile Include="UnitTestApp.xaml.cs">
|
||||
<DependentUpon>UnitTestApp.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="LocationManagerTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="UnitTestApp.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<None Include="HelloAppTest_TemporaryKey.pfx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Properties\UnitTestApp.rd.xml" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\HelloApp\HelloApp.csproj">
|
||||
<Project>{51faef20-c80e-4a15-bc77-1375ca9f7da8}</Project>
|
||||
<Name>HelloApp</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(NuGetPackageRoot)' == ''">
|
||||
<NuGetPackageRoot>$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
</PropertyGroup>
|
||||
<ImportGroup>
|
||||
<Import Project="$(NuGetPackageRoot)\Etg.SimpleStubs\0.0.1-beta\build\Etg.SimpleStubs.targets" Condition="Exists('$(NuGetPackageRoot)\Etg.SimpleStubs\0.0.1-beta\build\Etg.SimpleStubs.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,56 @@
|
|||
using System.Threading.Tasks;
|
||||
using HelloApp;
|
||||
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||
|
||||
namespace HelloAppTest
|
||||
{
|
||||
[TestClass]
|
||||
public class LocationManagerTest
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task TestGetCurrentLocation()
|
||||
{
|
||||
StubILocationService locationServiceStub = new StubILocationService
|
||||
{
|
||||
ILocationService_GetLocation = () => Task.FromResult("Canada/Vancouver")
|
||||
};
|
||||
|
||||
LocationManager locationManager = new LocationManager(locationServiceStub);
|
||||
Location location = await locationManager.GetCurrentLocation();
|
||||
|
||||
Assert.AreEqual("Canada", location.Country);
|
||||
Assert.AreEqual("Vancouver", location.City);
|
||||
Assert.AreEqual(1, locationServiceStub.ILocationService_GetLocation_CallCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestThatGetCurrentLocationReturnsNullIfLocationServiceIsUnavailable()
|
||||
{
|
||||
StubILocationService locationServiceStub = new StubILocationService
|
||||
{
|
||||
ILocationService_GetLocation = () =>
|
||||
{
|
||||
throw new LocationServiceUnavailableException();
|
||||
}
|
||||
};
|
||||
|
||||
LocationManager locationManager = new LocationManager(locationServiceStub);
|
||||
Assert.IsNull(await locationManager.GetCurrentLocation());
|
||||
Assert.AreEqual(1, locationServiceStub.ILocationService_GetLocation_CallCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestGetCurrentCountryCode()
|
||||
{
|
||||
StubILocationService locationServiceStub = new StubILocationService
|
||||
{
|
||||
ILocationService_GetLocation = () => Task.FromResult("Canada/Vancouver"),
|
||||
ILocationService_GetCountryCode_String = location => Task.FromResult("CA")
|
||||
};
|
||||
|
||||
LocationManager locationManager = new LocationManager(locationServiceStub);
|
||||
Assert.AreEqual("CA", await locationManager.GetCurrentCountryCode());
|
||||
Assert.AreEqual(1, locationServiceStub.ILocationService_GetCountryCode_String_CallCount);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
IgnorableNamespaces="uap mp">
|
||||
|
||||
<Identity Name="7381d360-7032-4a64-a385-1bd0786ce5fb"
|
||||
Publisher="CN=nbilal"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="7381d360-7032-4a64-a385-1bd0786ce5fb" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>HelloAppTest</DisplayName>
|
||||
<PublisherDisplayName>nbilal</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="vstest.executionengine.universal.App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="HelloAppTest.App">
|
||||
<uap:VisualElements
|
||||
DisplayName="HelloAppTest"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png"
|
||||
Description="HelloAppTest"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -0,0 +1,30 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("HelloAppTest")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("HelloAppTest")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyMetadata("TargetPlatform","UAP")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
|
@ -0,0 +1,31 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace HelloApp
|
||||
{
|
||||
public class StubILocationService : ILocationService
|
||||
{
|
||||
global::System.Threading.Tasks.Task<string> global::HelloApp.ILocationService.GetLocation()
|
||||
{
|
||||
++ILocationService_GetLocation_CallCount;
|
||||
return ILocationService_GetLocation();
|
||||
}
|
||||
|
||||
public delegate global::System.Threading.Tasks.Task<string> ILocationService_GetLocation_Delegate();
|
||||
|
||||
public ILocationService_GetLocation_Delegate ILocationService_GetLocation;
|
||||
|
||||
public int ILocationService_GetLocation_CallCount { get; private set; } = 0;
|
||||
|
||||
global::System.Threading.Tasks.Task<string> global::HelloApp.ILocationService.GetCountryCode(string location)
|
||||
{
|
||||
++ILocationService_GetCountryCode_String_CallCount;
|
||||
return ILocationService_GetCountryCode_String(location);
|
||||
}
|
||||
|
||||
public delegate global::System.Threading.Tasks.Task<string> ILocationService_GetCountryCode_String_Delegate(string location);
|
||||
|
||||
public ILocationService_GetCountryCode_String_Delegate ILocationService_GetCountryCode_String;
|
||||
|
||||
public int ILocationService_GetCountryCode_String_CallCount { get; private set; } = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<!--
|
||||
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
|
||||
developers. However, you can modify these parameters to modify the behavior of the .NET Native
|
||||
optimizer.
|
||||
|
||||
Runtime Directives are documented at http://go.microsoft.com/fwlink/?LinkID=391919
|
||||
|
||||
To fully enable reflection for App1.MyClass and all of its public/private members
|
||||
<Type Name="App1.MyClass" Dynamic="Required All"/>
|
||||
|
||||
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
|
||||
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
|
||||
|
||||
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
|
||||
<Namespace Name="DataClasses.ViewModels" Seralize="All" />
|
||||
-->
|
||||
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Application>
|
||||
<!--
|
||||
An Assembly element with Name="*Application*" applies to all assemblies in
|
||||
the application package. The asterisks are not wildcards.
|
||||
-->
|
||||
<Assembly Name="*Application*" Dynamic="Required All" />
|
||||
|
||||
<!-- Add your application specific runtime directives here. -->
|
||||
|
||||
|
||||
</Application>
|
||||
</Directives>
|
|
@ -0,0 +1,8 @@
|
|||
<Application
|
||||
x:Class="HelloAppTest.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HelloAppTest"
|
||||
RequestedTheme="Light">
|
||||
|
||||
</Application>
|
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace HelloAppTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
sealed partial class App : Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Suspending += OnSuspending;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
/// </summary>
|
||||
/// <param name="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
this.DebugSettings.EnableFrameRateCounter = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Frame rootFrame = Window.Current.Content as Frame;
|
||||
|
||||
// Do not repeat app initialization when the Window already has content,
|
||||
// just ensure that the window is active
|
||||
if (rootFrame == null)
|
||||
{
|
||||
// Create a Frame to act as the navigation context and navigate to the first page
|
||||
rootFrame = new Frame();
|
||||
|
||||
rootFrame.NavigationFailed += OnNavigationFailed;
|
||||
|
||||
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||
{
|
||||
//TODO: Load state from previously suspended application
|
||||
}
|
||||
|
||||
// Place the frame in the current Window
|
||||
Window.Current.Content = rootFrame;
|
||||
}
|
||||
|
||||
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
|
||||
|
||||
// Ensure the current window is active
|
||||
Window.Current.Activate();
|
||||
|
||||
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(e.Arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when Navigation to a certain page fails
|
||||
/// </summary>
|
||||
/// <param name="sender">The Frame which failed navigation</param>
|
||||
/// <param name="e">Details about the navigation failure</param>
|
||||
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when application execution is being suspended. Application state is saved
|
||||
/// without knowing whether the application will be terminated or resumed with the contents
|
||||
/// of memory still intact.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the suspend request.</param>
|
||||
/// <param name="e">Details about the suspend request.</param>
|
||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
{
|
||||
var deferral = e.SuspendingOperation.GetDeferral();
|
||||
//TODO: Save application state and stop any background activity
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Etg.SimpleStubs": "0.0.1-beta",
|
||||
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"uap10.0": {}
|
||||
},
|
||||
"runtimes": {
|
||||
"win10-arm": {},
|
||||
"win10-arm-aot": {},
|
||||
"win10-x86": {},
|
||||
"win10-x86-aot": {},
|
||||
"win10-x64": {},
|
||||
"win10-x64-aot": {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleStubs.CodeGen", "src\SimpleStubs.CodeGen\SimpleStubs.CodeGen.csproj", "{3E9C520A-94CF-46D0-864B-4293D439C92A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleStubs", "src\SimpleStubs\SimpleStubs.csproj", "{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClassLibrary", "test\TestClassLibrary\TestClassLibrary.csproj", "{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClassLibraryTest", "test\TestClassLibraryTest\TestClassLibraryTest.csproj", "{CB81F60F-1374-4B46-BB64-D848B5103A58}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Release|x64.Build.0 = Release|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3E9C520A-94CF-46D0-864B-4293D439C92A}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CB81F60F-1374-4B46-BB64-D848B5103A58}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,11 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask TaskName="Etg.SimpleStubs.CodeGen.Tasks.GenerateStubsTask" AssemblyFile="$(MSBuildThisFileDirectory)..\tools\Etg.SimpleStubs.CodeGen.dll" />
|
||||
|
||||
<PropertyGroup>
|
||||
<SimpleStubsCodeGenBeforeTargets>BeforeBuild</SimpleStubsCodeGenBeforeTargets>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="SimpleStubsCodeGen" BeforeTargets="$(SimpleStubsCodeGenBeforeTargets)">
|
||||
<GenerateStubsTask ProjectPath="$(ProjectDir)$(ProjectName)$(ProjectExt)" OutputPath="$(ProjectDir)Properties\SimpleStubs.generated.cs" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://www.nuget.org/api/v2/"/>
|
||||
<add key="nuget (SimpleStubs)" value="NuGet"/>
|
||||
</packageSources>
|
||||
</configuration>
|
|
@ -0,0 +1,98 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Etg.SimpleStubs.CodeGen.Utils;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen
|
||||
{
|
||||
using SF = SyntaxFactory;
|
||||
|
||||
class EventStubber : IMethodStubber
|
||||
{
|
||||
public ClassDeclarationSyntax StubMethod(ClassDeclarationSyntax classDclr, IMethodSymbol methodSymbol, INamedTypeSymbol stubbedInterface)
|
||||
{
|
||||
// only handle EventAdd and ignore EventRemove because we only need to stub the event once
|
||||
if (!methodSymbol.IsEventAdd())
|
||||
{
|
||||
return classDclr;
|
||||
}
|
||||
|
||||
// add the event implementation to the stub
|
||||
IEventSymbol eventSymbol = (IEventSymbol)methodSymbol.AssociatedSymbol;
|
||||
EventFieldDeclarationSyntax eventDclr = ToEventDclr(eventSymbol);
|
||||
classDclr = classDclr.AddMembers(eventDclr);
|
||||
|
||||
string eventName = eventSymbol.Name;
|
||||
ParameterSyntax[] parameters = GetEventParameters(eventSymbol);
|
||||
string onEventArgs = "sender";
|
||||
string eventTriggerArgs = "sender";
|
||||
if (parameters.Count() == 2)
|
||||
{
|
||||
onEventArgs += ", args";
|
||||
eventTriggerArgs += ", args";
|
||||
}
|
||||
else if (parameters.Count() == 1)
|
||||
{
|
||||
onEventArgs += ", null";
|
||||
}
|
||||
|
||||
string eventType = GetEventType(eventSymbol);
|
||||
string onEventMethodName = "On_" + eventName;
|
||||
|
||||
// Create OnEvent method
|
||||
MethodDeclarationSyntax onEventMethodDclr = SF.MethodDeclaration(SF.ParseTypeName("void"), onEventMethodName)
|
||||
.AddModifiers(SF.Token(SyntaxKind.ProtectedKeyword))
|
||||
.AddParameterListParameters(parameters)
|
||||
.WithBody(SF.Block(
|
||||
SF.ParseStatement($"{eventType} handler = {eventName};\n"),
|
||||
SF.ParseStatement($"if (handler != null) {{ handler({onEventArgs}); }}\n")
|
||||
));
|
||||
|
||||
classDclr = classDclr.AddMembers(onEventMethodDclr);
|
||||
|
||||
// Create event trigger method
|
||||
string eventTriggerMethodName = eventName + "_Raise";
|
||||
MethodDeclarationSyntax eventTriggerMethod = SF.MethodDeclaration(SF.ParseTypeName("void"), eventTriggerMethodName)
|
||||
.AddModifiers(SF.Token(SyntaxKind.PublicKeyword))
|
||||
.AddParameterListParameters(parameters)
|
||||
.WithBody(SF.Block(
|
||||
SF.ParseStatement($"{onEventMethodName}({eventTriggerArgs});\n")
|
||||
));
|
||||
classDclr = classDclr.AddMembers(eventTriggerMethod);
|
||||
|
||||
return classDclr;
|
||||
}
|
||||
|
||||
private static ParameterSyntax[] GetEventParameters(IEventSymbol eventSymbol)
|
||||
{
|
||||
List<ParameterSyntax> parameters = new List<ParameterSyntax>
|
||||
{
|
||||
SF.Parameter(SF.Identifier("sender")).WithType(SF.ParseTypeName("object"))
|
||||
};
|
||||
INamedTypeSymbol type = (INamedTypeSymbol)(eventSymbol.Type);
|
||||
if (type.TypeArguments.Any())
|
||||
{
|
||||
parameters.Add(SF.Parameter(SF.Identifier("args")).WithType(SF.ParseTypeName(type.TypeArguments[0].Name)));
|
||||
}
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
|
||||
private static EventFieldDeclarationSyntax ToEventDclr(IEventSymbol eventSymbol)
|
||||
{
|
||||
string eventName = eventSymbol.Name;
|
||||
string eventType = GetEventType(eventSymbol);
|
||||
EventFieldDeclarationSyntax eventDclr = SF.EventFieldDeclaration(
|
||||
SF.VariableDeclaration(SF.IdentifierName(eventType),
|
||||
SF.SeparatedList(new[] { SF.VariableDeclarator(eventName) }))).AddModifiers(SF.Token(SyntaxKind.PublicKeyword));
|
||||
return eventDclr;
|
||||
}
|
||||
|
||||
private static string GetEventType(IEventSymbol eventSymbol)
|
||||
{
|
||||
return eventSymbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen
|
||||
{
|
||||
interface IInterfaceStubber
|
||||
{
|
||||
CompilationUnitSyntax StubInterface(CompilationUnitSyntax cu, InterfaceDeclarationSyntax interfaceDclr, SemanticModel semanticModel);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen
|
||||
{
|
||||
interface IMethodStubber
|
||||
{
|
||||
ClassDeclarationSyntax StubMethod(ClassDeclarationSyntax classDclr, IMethodSymbol methodSymbol, INamedTypeSymbol stubbedInterface);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.CodeGen
|
||||
{
|
||||
interface IProjectStubber
|
||||
{
|
||||
Task<StubProjectResult> StubProject(Project project, CompilationUnitSyntax cu);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
using Etg.SimpleStubs.CodeGen.Utils;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen
|
||||
{
|
||||
class InterfaceStubber : IInterfaceStubber
|
||||
{
|
||||
private readonly IEnumerable<IMethodStubber> _methodStubbers;
|
||||
public InterfaceStubber(IEnumerable<IMethodStubber> methodStubbers)
|
||||
{
|
||||
_methodStubbers = new List<IMethodStubber>(methodStubbers);
|
||||
}
|
||||
|
||||
public CompilationUnitSyntax StubInterface(CompilationUnitSyntax cu, InterfaceDeclarationSyntax interfaceDclr,
|
||||
SemanticModel semanticModel)
|
||||
{
|
||||
INamedTypeSymbol interfaceType = semanticModel.GetDeclaredSymbol(interfaceDclr);
|
||||
NamespaceDeclarationSyntax namespaceNode = GetNamespaceNode(interfaceDclr);
|
||||
string interfaceName = interfaceType.GetGenericName();
|
||||
string stubName = NamingUtils.GetStubName(interfaceName);
|
||||
ClassDeclarationSyntax classDclr = SF.ClassDeclaration(SF.Identifier(stubName))
|
||||
.AddModifiers(SF.Token(RoslynUtils.GetVisibilityKeyword(interfaceType))
|
||||
//,SF.Token(SyntaxKind.PartialKeyword)
|
||||
)
|
||||
.WithBaseList(RoslynUtils.BaseList(interfaceName))
|
||||
.AddAttributeLists(AttributeListList(Attribute("CompilerGenerated")).ToArray());
|
||||
List<IMethodSymbol> methodsToStub = RoslynUtils.GetAllMethods(interfaceType);
|
||||
foreach (IMethodSymbol methodSymbol in methodsToStub)
|
||||
{
|
||||
foreach(IMethodStubber methodStubber in _methodStubbers)
|
||||
{
|
||||
classDclr = methodStubber.StubMethod(classDclr, methodSymbol, interfaceType);
|
||||
}
|
||||
}
|
||||
|
||||
string fullNameSpace = semanticModel.GetDeclaredSymbol(namespaceNode).ToString();
|
||||
NamespaceDeclarationSyntax namespaceDclr = SF.NamespaceDeclaration(SF.IdentifierName(fullNameSpace))
|
||||
.WithUsings(namespaceNode.Usings);
|
||||
namespaceDclr = namespaceDclr.AddMembers(classDclr);
|
||||
cu = cu.AddMembers(namespaceDclr);
|
||||
return cu;
|
||||
}
|
||||
|
||||
private static NamespaceDeclarationSyntax GetNamespaceNode(InterfaceDeclarationSyntax interfaceNode)
|
||||
{
|
||||
var namespaceNode = interfaceNode.Parent as NamespaceDeclarationSyntax;
|
||||
if (namespaceNode == null)
|
||||
{
|
||||
throw new Exception("A grain interface must be declared inside a namespace");
|
||||
}
|
||||
|
||||
return namespaceNode;
|
||||
}
|
||||
|
||||
private static SyntaxList<AttributeListSyntax> AttributeListList(params AttributeSyntax[] attributes)
|
||||
{
|
||||
var list = new SyntaxList<AttributeListSyntax>();
|
||||
foreach (AttributeSyntax attributeSyntax in attributes)
|
||||
{
|
||||
list = list.Add(AttributeList(attributeSyntax));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static AttributeListSyntax AttributeList(params AttributeSyntax[] attributes)
|
||||
{
|
||||
SeparatedSyntaxList<AttributeSyntax> separatedList = SF.SeparatedList<AttributeSyntax>();
|
||||
foreach (var attributeSyntax in attributes)
|
||||
{
|
||||
separatedList = separatedList.Add(attributeSyntax);
|
||||
}
|
||||
return SF.AttributeList(separatedList);
|
||||
}
|
||||
|
||||
private static AttributeSyntax Attribute(string attributeName)
|
||||
{
|
||||
return SF.Attribute(SF.IdentifierName(attributeName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
using Etg.SimpleStubs.CodeGen.Utils;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Linq;
|
||||
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen
|
||||
{
|
||||
class OrdinaryMethodStubber : IMethodStubber
|
||||
{
|
||||
public ClassDeclarationSyntax StubMethod(ClassDeclarationSyntax classDclr, IMethodSymbol methodSymbol, INamedTypeSymbol stubbedInterface)
|
||||
{
|
||||
if(!methodSymbol.IsOrdinaryMethod())
|
||||
{
|
||||
return classDclr;
|
||||
}
|
||||
|
||||
MethodDeclarationSyntax methodDclr = SF.MethodDeclaration(
|
||||
SF.ParseTypeName(methodSymbol.ReturnType.GetFullyQualifiedName()), methodSymbol.GetGenericName());
|
||||
methodDclr = methodDclr.WithParameterList(methodDclr.ParameterList.AddParameters(
|
||||
RoslynUtils.GetMethodParameterSyntaxList(methodSymbol).ToArray()));
|
||||
methodDclr = methodDclr.WithSemicolonToken(SF.Token(SyntaxKind.None))
|
||||
.WithExplicitInterfaceSpecifier(
|
||||
SF.ExplicitInterfaceSpecifier(
|
||||
SF.IdentifierName(methodSymbol.GetContainingInterfaceGenericQualifiedName())));
|
||||
if (methodSymbol.IsGenericMethod)
|
||||
{
|
||||
StatementSyntax stmtSyntax;
|
||||
if (methodSymbol.ReturnsVoid)
|
||||
{
|
||||
stmtSyntax = SF.ParseStatement("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
stmtSyntax = SF.ParseStatement($"return default({methodSymbol.ReturnType.GetFullyQualifiedName()});\n");
|
||||
}
|
||||
|
||||
classDclr = classDclr.AddMembers(methodDclr.WithBody(SF.Block(stmtSyntax)));
|
||||
}
|
||||
else
|
||||
{
|
||||
string delegatePropertyName = NamingUtils.GetDelegatePropertyName(methodSymbol, stubbedInterface);
|
||||
string callDelegateStmt = $"{delegatePropertyName}({string.Join(", ", methodSymbol.Parameters.Select(p => p.Name))});\n";
|
||||
if (!methodSymbol.ReturnsVoid)
|
||||
{
|
||||
callDelegateStmt = callDelegateStmt.Insert(0, "return ");
|
||||
}
|
||||
|
||||
classDclr = classDclr.AddMembers(
|
||||
methodDclr.WithBody(SF.Block(SF.ParseStatement(callDelegateStmt))));
|
||||
}
|
||||
|
||||
return classDclr;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
using Etg.SimpleStubs.CodeGen.Config;
|
||||
using Etg.SimpleStubs.CodeGen.Utils;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.CodeGen
|
||||
{
|
||||
class ProjectStubber : IProjectStubber
|
||||
{
|
||||
private readonly IInterfaceStubber _interfaceStubber;
|
||||
private readonly SimpleStubsConfig _config;
|
||||
public ProjectStubber(IInterfaceStubber interfaceStubber, SimpleStubsConfig config)
|
||||
{
|
||||
_interfaceStubber = interfaceStubber;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public async Task<StubProjectResult> StubProject(Project project, CompilationUnitSyntax cu)
|
||||
{
|
||||
var usings = new List<string>();
|
||||
foreach (Document document in project.Documents)
|
||||
{
|
||||
SyntaxTree syntaxTree = await document.GetSyntaxTreeAsync();
|
||||
SemanticModel semanticModel = await document.GetSemanticModelAsync();
|
||||
IEnumerable<InterfaceDeclarationSyntax> interfaces = syntaxTree.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>().Where(i => SatisfiesVisibilityConstraints(i));
|
||||
if (!interfaces.Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var interfaceDclr in interfaces)
|
||||
{
|
||||
try
|
||||
{
|
||||
INamedTypeSymbol interfaceType = semanticModel.GetDeclaredSymbol(interfaceDclr);
|
||||
if (!_config.IgnoredInterfaces.Contains(interfaceType.GetQualifiedName()))
|
||||
{
|
||||
LogWarningsIfAny(semanticModel);
|
||||
cu = _interfaceStubber.StubInterface(cu, interfaceDclr, semanticModel);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Trace.TraceError($"Could not generate stubs for interface {interfaceDclr}, Exception: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
usings.AddRange(syntaxTree.GetCompilationUnitRoot().Usings.Select(@using => @using.Name.ToString()));
|
||||
}
|
||||
|
||||
return new StubProjectResult(cu, usings);
|
||||
}
|
||||
|
||||
private bool SatisfiesVisibilityConstraints(InterfaceDeclarationSyntax i)
|
||||
{
|
||||
return i.IsPublic() || (_config.StubInternalInterfaces && i.IsInternal());
|
||||
}
|
||||
|
||||
private void LogWarningsIfAny(SemanticModel semanticModel)
|
||||
{
|
||||
foreach (var diagnostic in semanticModel.GetDiagnostics())
|
||||
{
|
||||
Trace.TraceInformation(diagnostic.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Etg.SimpleStubs.CodeGen.Utils;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen
|
||||
{
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using System.Linq;
|
||||
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
class PropertyStubber : IMethodStubber
|
||||
{
|
||||
public ClassDeclarationSyntax StubMethod(ClassDeclarationSyntax classDclr, IMethodSymbol methodSymbol, INamedTypeSymbol stubbedInterface)
|
||||
{
|
||||
if (!methodSymbol.IsPropertyAccessor())
|
||||
{
|
||||
return classDclr;
|
||||
}
|
||||
|
||||
string delegatePropertyName = NamingUtils.GetDelegatePropertyName(methodSymbol, stubbedInterface);
|
||||
|
||||
string propName = methodSymbol.AssociatedSymbol.Name;
|
||||
string propType = ((IPropertySymbol)methodSymbol.AssociatedSymbol).Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
var propDclr = GetPropDclr(classDclr, propName);
|
||||
if (propDclr == null)
|
||||
{
|
||||
propDclr = SF.PropertyDeclaration(SF.ParseTypeName(propType), SF.Identifier(propName))
|
||||
.WithExplicitInterfaceSpecifier(SF.ExplicitInterfaceSpecifier(
|
||||
SF.IdentifierName(methodSymbol.GetContainingInterfaceGenericQualifiedName())));
|
||||
}
|
||||
|
||||
if (methodSymbol.IsPropertyGetter())
|
||||
{
|
||||
var accessorDclr = SF.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, SF.Block(
|
||||
SF.List(new[] {
|
||||
SF.ReturnStatement(SF.IdentifierName(delegatePropertyName + "()")) })));
|
||||
propDclr = propDclr.AddAccessorListAccessors(accessorDclr);
|
||||
}
|
||||
else if (methodSymbol.IsPropertySetter())
|
||||
{
|
||||
var accessorDclr = SF.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration, SF.Block(
|
||||
SF.List(new[] {
|
||||
SF.ParseStatement($"{delegatePropertyName}(value);\n") })));
|
||||
propDclr = propDclr.AddAccessorListAccessors(accessorDclr);
|
||||
}
|
||||
|
||||
if (propDclr != null)
|
||||
{
|
||||
PropertyDeclarationSyntax existingPropDclr = GetPropDclr(classDclr, propName);
|
||||
if (existingPropDclr != null)
|
||||
{
|
||||
classDclr = classDclr.ReplaceNode(existingPropDclr, propDclr);
|
||||
}
|
||||
else
|
||||
{
|
||||
classDclr = classDclr.AddMembers(propDclr);
|
||||
}
|
||||
}
|
||||
|
||||
return classDclr;
|
||||
}
|
||||
|
||||
private static PropertyDeclarationSyntax GetPropDclr(ClassDeclarationSyntax classDclr, string propName)
|
||||
{
|
||||
return classDclr.DescendantNodes().OfType<PropertyDeclarationSyntax>().FirstOrDefault(p => p.Identifier.Text == propName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.MSBuild;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis.Formatting;
|
||||
using System.Threading.Tasks;
|
||||
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
using Etg.SimpleStubs.CodeGen.Config;
|
||||
using Etg.SimpleStubs.CodeGen.CodeGen;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen
|
||||
{
|
||||
internal class SimpleStubsGenerator
|
||||
{
|
||||
IProjectStubber _projectStubber;
|
||||
SimpleStubsConfig _config;
|
||||
public SimpleStubsGenerator(IProjectStubber projectStubber, SimpleStubsConfig config)
|
||||
{
|
||||
_projectStubber = projectStubber;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public async Task<string> GenerateStubs(string testProjectPath)
|
||||
{
|
||||
MSBuildWorkspace workspace = MSBuildWorkspace.Create();
|
||||
Project currentProject = await workspace.OpenProjectAsync(testProjectPath);
|
||||
if (currentProject == null)
|
||||
{
|
||||
throw new ArgumentException("Could not open the project located at " + testProjectPath);
|
||||
}
|
||||
|
||||
CompilationUnitSyntax cu = SF.CompilationUnit();
|
||||
var usings = new HashSet<string>();
|
||||
usings.Add("System");
|
||||
usings.Add("System.Runtime.CompilerServices");
|
||||
foreach (ProjectReference projectRef in currentProject.ProjectReferences)
|
||||
{
|
||||
Project project = workspace.CurrentSolution.GetProject(projectRef.ProjectId);
|
||||
if (_config.IgnoredProjects.Contains(project.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var res = await _projectStubber.StubProject(project, cu);
|
||||
cu = res.CompilationUnit;
|
||||
usings.UnionWith(res.Usings);
|
||||
}
|
||||
|
||||
cu = cu.AddUsings(usings.Select(@using => SF.UsingDirective(SF.IdentifierName(@using))).ToArray());
|
||||
return Formatter.Format(cu, workspace).ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.CodeGen
|
||||
{
|
||||
class StubProjectResult
|
||||
{
|
||||
public StubProjectResult(CompilationUnitSyntax cu, IEnumerable<string> usings)
|
||||
{
|
||||
CompilationUnit = cu;
|
||||
Usings = usings;
|
||||
}
|
||||
|
||||
public CompilationUnitSyntax CompilationUnit
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public IEnumerable<string> Usings
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Etg.SimpleStubs.CodeGen.Utils;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen
|
||||
{
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
class StubbingPropertiesGenerator : IMethodStubber
|
||||
{
|
||||
public ClassDeclarationSyntax StubMethod(ClassDeclarationSyntax classDclr, IMethodSymbol methodSymbol,
|
||||
INamedTypeSymbol stubbedInterface)
|
||||
{
|
||||
if (methodSymbol.IsPropertyAccessor() || methodSymbol.IsOrdinaryMethod())
|
||||
{
|
||||
if (!methodSymbol.IsGenericMethod)
|
||||
{
|
||||
string delegatePropertyName = NamingUtils.GetDelegatePropertyName(methodSymbol, stubbedInterface);
|
||||
string delegateTypeName = NamingUtils.GetDelegateTypeName(delegatePropertyName);
|
||||
|
||||
DelegateDeclarationSyntax delegateDclr = GenerateDelegateDclr(methodSymbol, delegateTypeName, stubbedInterface);
|
||||
PropertyDeclarationSyntax propDclr = GenerateDelegatePropDclr(
|
||||
delegatePropertyName, delegateTypeName, stubbedInterface);
|
||||
classDclr = classDclr.AddMembers(delegateDclr, propDclr);
|
||||
}
|
||||
}
|
||||
|
||||
return classDclr;
|
||||
}
|
||||
|
||||
private static PropertyDeclarationSyntax GenerateDelegatePropDclr(string delegatePropertyName,
|
||||
string delegateName, INamedTypeSymbol stubbedInterface)
|
||||
{
|
||||
SyntaxKind visibility = RoslynUtils.GetVisibilityKeyword(stubbedInterface);
|
||||
return SF.PropertyDeclaration(SF.ParseTypeName(delegateName), delegatePropertyName)
|
||||
.AddModifiers(SF.Token(visibility)).WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken));
|
||||
}
|
||||
|
||||
private static DelegateDeclarationSyntax GenerateDelegateDclr(IMethodSymbol methodSymbol, string delegateName,
|
||||
INamedTypeSymbol stubbedInterface)
|
||||
{
|
||||
SyntaxKind visibility = RoslynUtils.GetVisibilityKeyword(stubbedInterface);
|
||||
List<ParameterSyntax> paramsSyntaxList = RoslynUtils.GetMethodParameterSyntaxList(methodSymbol);
|
||||
return SF.DelegateDeclaration(SF.ParseTypeName(methodSymbol.ReturnType.GetFullyQualifiedName()), delegateName)
|
||||
.AddModifiers(SF.Token(visibility)).AddParameterListParameters(paramsSyntaxList.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.Config
|
||||
{
|
||||
class ConfigLoader
|
||||
{
|
||||
public SimpleStubsConfig LoadConfig(string configFilePath)
|
||||
{
|
||||
if (File.Exists(configFilePath))
|
||||
{
|
||||
return JsonConvert.DeserializeObject<SimpleStubsConfig>(File.ReadAllText(configFilePath));
|
||||
}
|
||||
|
||||
return new SimpleStubsConfig(new string[]{}, new string[]{}, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.Config
|
||||
{
|
||||
class SimpleStubsConfig
|
||||
{
|
||||
public SimpleStubsConfig(IEnumerable<string> ignoredProjects,
|
||||
IEnumerable<string> ignoredInterfaces,
|
||||
bool stubInternalInterfaces)
|
||||
{
|
||||
IgnoredProjects = new HashSet<string>(ignoredProjects);
|
||||
IgnoredInterfaces = new HashSet<string>(ignoredInterfaces);
|
||||
StubInternalInterfaces = stubInternalInterfaces;
|
||||
}
|
||||
|
||||
public ISet<string> IgnoredProjects
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public ISet<string> IgnoredInterfaces
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public bool StubInternalInterfaces
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using Autofac;
|
||||
using Etg.SimpleStubs.CodeGen.CodeGen;
|
||||
using Etg.SimpleStubs.CodeGen.Config;
|
||||
using System.IO;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.DI
|
||||
{
|
||||
class DiModule
|
||||
{
|
||||
private readonly IContainer _container;
|
||||
|
||||
public DiModule(string testProjectPath, string stubsFilePath)
|
||||
{
|
||||
_container = RegisterTypes(testProjectPath, stubsFilePath).Build();
|
||||
}
|
||||
|
||||
public static ContainerBuilder RegisterTypes(string testProjectPath, string stubsFilePath)
|
||||
{
|
||||
ContainerBuilder cb = new ContainerBuilder();
|
||||
|
||||
string configFilePath = Path.Combine(Path.GetDirectoryName(testProjectPath), "SimpleStubs.json");
|
||||
SimpleStubsConfig config = new ConfigLoader().LoadConfig(configFilePath);
|
||||
|
||||
cb.RegisterInstance(config);
|
||||
|
||||
cb.Register((c) =>
|
||||
{
|
||||
IInterfaceStubber interfaceStubber = new InterfaceStubber(
|
||||
new IMethodStubber[] {
|
||||
new OrdinaryMethodStubber(),
|
||||
new EventStubber(),
|
||||
new PropertyStubber(),
|
||||
new StubbingPropertiesGenerator() });
|
||||
return interfaceStubber;
|
||||
}).As<IInterfaceStubber>().SingleInstance();
|
||||
|
||||
cb.RegisterType<ProjectStubber>().As<IProjectStubber>().SingleInstance();
|
||||
cb.RegisterType<SimpleStubsGenerator>().AsSelf();
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
public SimpleStubsGenerator StubsGenerator => _container.Resolve<SimpleStubsGenerator>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SimpleStubs")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Etg.SimpleStubs.CodeGen")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("3e9c520a-94cf-46d0-864b-4293d439c92a")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.0.1.0")]
|
||||
|
||||
[assembly: InternalsVisibleTo("TestClassLibraryTest")]
|
|
@ -0,0 +1,139 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{3E9C520A-94CF-46D0-864B-4293D439C92A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Etg.SimpleStubs.CodeGen</RootNamespace>
|
||||
<AssemblyName>Etg.SimpleStubs.CodeGen</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Build.Framework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.CodeAnalysis, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.Common.1.1.1\lib\net45\Microsoft.CodeAnalysis.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.1.1.1\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.1.1\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.Workspaces, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.1.1\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.Workspaces.Desktop, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.1.1\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Collections.Immutable, Version=1.1.37.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.AttributedModel, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.Convention, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.Hosting, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.Runtime, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.TypedParts, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Reflection.Metadata, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Reflection.Metadata.1.1.0\lib\dotnet5.2\System.Reflection.Metadata.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CodeGen\IInterfaceStubber.cs" />
|
||||
<Compile Include="CodeGen\InterfaceStubber.cs" />
|
||||
<Compile Include="CodeGen\IProjectStubber.cs" />
|
||||
<Compile Include="CodeGen\ProjectStubber.cs" />
|
||||
<Compile Include="CodeGen\StubProjectResult.cs" />
|
||||
<Compile Include="Config\SimpleStubsConfig.cs" />
|
||||
<Compile Include="Config\ConfigLoader.cs" />
|
||||
<Compile Include="DI\DiModule.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="CodeGen\EventStubber.cs" />
|
||||
<Compile Include="Tasks\GenerateStubsTask.cs" />
|
||||
<Compile Include="CodeGen\IMethodStubber.cs" />
|
||||
<Compile Include="CodeGen\OrdinaryMethodStubber.cs" />
|
||||
<Compile Include="CodeGen\PropertyStubber.cs" />
|
||||
<Compile Include="CodeGen\StubbingPropertiesGenerator.cs" />
|
||||
<Compile Include="CodeGen\SimpleStubsGenerator.cs" />
|
||||
<Compile Include="Utils\NamingUtils.cs" />
|
||||
<Compile Include="Utils\RoslynExtensions.cs" />
|
||||
<Compile Include="Utils\RoslynUtils.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,58 @@
|
|||
using Microsoft.Build.Framework;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Etg.SimpleStubs.CodeGen.DI;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public class GenerateStubsTask : Microsoft.Build.Utilities.AppDomainIsolatedTask
|
||||
{
|
||||
[Required]
|
||||
public string OutputPath
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Required]
|
||||
public string ProjectPath
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
LogMessage("Generating stubs");
|
||||
DiModule diModule = new DiModule(ProjectPath, OutputPath);
|
||||
File.WriteAllText(OutputPath, diModule.StubsGenerator.GenerateStubs(ProjectPath).Result);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogMessage(e.ToString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void LogMessage(string message)
|
||||
{
|
||||
Log.LogMessage(MessageImportance.High, DecorateMessage(message));
|
||||
}
|
||||
|
||||
private static string DecorateMessage(string message)
|
||||
{
|
||||
return "SimpleStubs: " + message;
|
||||
}
|
||||
|
||||
private void LogWarning(string message)
|
||||
{
|
||||
Log.LogWarning(DecorateMessage(message));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.Utils
|
||||
{
|
||||
class NamingUtils
|
||||
{
|
||||
public string GetInterfaceStubName(string interfaceName)
|
||||
{
|
||||
return "Stub" + interfaceName;
|
||||
}
|
||||
|
||||
public static string GetDelegatePropertyName(IMethodSymbol methodSymbol, INamedTypeSymbol targetInterface)
|
||||
{
|
||||
string methodName = methodSymbol.Name;
|
||||
if (methodSymbol.IsPropertyGetter())
|
||||
{
|
||||
methodName = methodName.Substring(4) + "_Get";
|
||||
}
|
||||
else if (methodSymbol.IsPropertySetter())
|
||||
{
|
||||
methodName = methodName.Substring(4) + "_Set";
|
||||
}
|
||||
|
||||
// only prefix inherited members
|
||||
if (targetInterface.GetGenericName() != methodSymbol.ContainingSymbol.GetGenericName())
|
||||
{
|
||||
methodName = SerializeName(methodSymbol.ContainingSymbol) + "_" + methodName;
|
||||
}
|
||||
|
||||
if(methodSymbol.IsOrdinaryMethod())
|
||||
{
|
||||
if (methodSymbol.Parameters.Any())
|
||||
{
|
||||
methodName = methodName + "_" + string.Join("_", methodSymbol.Parameters.Select(SerializeName));
|
||||
}
|
||||
}
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public static string GetDelegateTypeName(string delegatePropertyName)
|
||||
{
|
||||
return delegatePropertyName + "_Delegate";
|
||||
}
|
||||
|
||||
public static string SerializeName(ISymbol param)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (var part in param.ToDisplayParts(SymbolDisplayFormat.MinimallyQualifiedFormat))
|
||||
{
|
||||
switch (part.ToString())
|
||||
{
|
||||
case "<":
|
||||
sb.Append("Of");
|
||||
break;
|
||||
case ">":
|
||||
break;
|
||||
case "]":
|
||||
break;
|
||||
case "[":
|
||||
sb.Append("Array");
|
||||
break;
|
||||
default:
|
||||
if (part.Symbol != null && part.Kind != SymbolDisplayPartKind.ParameterName)
|
||||
{
|
||||
sb.Append(part.Symbol.Name);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string GetStubName(string interfaceName)
|
||||
{
|
||||
return "Stub" + interfaceName;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.Utils
|
||||
{
|
||||
static class RoslynExtensions
|
||||
{
|
||||
public static SymbolDisplayFormat QualifiedFormat = new SymbolDisplayFormat(
|
||||
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces);
|
||||
|
||||
public static bool IsEvent(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
return methodSymbol.IsEventAdd() || methodSymbol.IsEventRemove();
|
||||
}
|
||||
|
||||
public static bool IsEventAdd(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
return methodSymbol.MethodKind == MethodKind.EventAdd;
|
||||
}
|
||||
|
||||
public static bool IsEventRemove(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
return methodSymbol.MethodKind == MethodKind.EventRemove;
|
||||
}
|
||||
|
||||
public static bool IsPropertyAccessor(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
return methodSymbol.IsPropertyGetter() || methodSymbol.IsPropertySetter();
|
||||
}
|
||||
|
||||
public static bool IsPropertySetter(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
return methodSymbol.MethodKind == MethodKind.PropertySet;
|
||||
}
|
||||
|
||||
public static bool IsPropertyGetter(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
return methodSymbol.MethodKind == MethodKind.PropertyGet;
|
||||
}
|
||||
|
||||
public static string GetGenericName(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
string name = methodSymbol.Name;
|
||||
if (methodSymbol.IsGenericMethod)
|
||||
{
|
||||
name = $"{name}<{string.Join(",", methodSymbol.TypeParameters.Select(p => p.Name))}>";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static string GetContainingInterfaceGenericQualifiedName(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
return methodSymbol.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
}
|
||||
|
||||
public static string GetGenericName(this ISymbol namedType)
|
||||
{
|
||||
return namedType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
|
||||
}
|
||||
|
||||
public static string GetFullyQualifiedName(this ITypeSymbol symbol)
|
||||
{
|
||||
return symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
}
|
||||
|
||||
public static string GetQualifiedName(this ITypeSymbol symbol)
|
||||
{
|
||||
return symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Split(new[] { "::" }, StringSplitOptions.RemoveEmptyEntries).Last();
|
||||
}
|
||||
|
||||
public static string GetMinimallyQualifiedName(this ITypeSymbol symbol)
|
||||
{
|
||||
return symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
|
||||
}
|
||||
|
||||
public static bool IsOrdinaryMethod(this IMethodSymbol methodSymbol)
|
||||
{
|
||||
return methodSymbol.MethodKind == MethodKind.Ordinary;
|
||||
}
|
||||
|
||||
public static bool IsPublic(this TypeDeclarationSyntax typeDclr)
|
||||
{
|
||||
return typeDclr.Modifiers.Any(modifier => modifier.RawKind.Equals(SyntaxFactory.Token(SyntaxKind.PublicKeyword).RawKind));
|
||||
}
|
||||
|
||||
public static bool IsInternal(this TypeDeclarationSyntax typeDclr)
|
||||
{
|
||||
var nonInternalModifiers = new List<int>
|
||||
{
|
||||
SyntaxFactory.Token(SyntaxKind.PublicKeyword).RawKind,
|
||||
SyntaxFactory.Token(SyntaxKind.PrivateKeyword).RawKind,
|
||||
SyntaxFactory.Token(SyntaxKind.ProtectedKeyword).RawKind
|
||||
};
|
||||
return !typeDclr.Modifiers.Any(modifier => nonInternalModifiers.Contains(modifier.RawKind));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.Utils
|
||||
{
|
||||
static class RoslynUtils
|
||||
{
|
||||
public static UsingDirectiveSyntax UsingDirective(string nameSpace)
|
||||
{
|
||||
return SF.UsingDirective(SF.IdentifierName(nameSpace));
|
||||
}
|
||||
|
||||
public static IEnumerable<MethodDeclarationSyntax> GetMethodDeclarations(TypeDeclarationSyntax interfaceNode)
|
||||
{
|
||||
return interfaceNode.DescendantNodes().OfType<MethodDeclarationSyntax>();
|
||||
}
|
||||
|
||||
public static ParameterSyntax CreateParameter(string type, string name)
|
||||
{
|
||||
return SF.Parameter(new SyntaxList<AttributeListSyntax>(), new SyntaxTokenList(), SF.IdentifierName(type), SF.Identifier(new SyntaxTriviaList().Add(SF.Space), name, new SyntaxTriviaList()), null);
|
||||
}
|
||||
|
||||
public static BaseListSyntax BaseList(params string[] names)
|
||||
{
|
||||
return SF.BaseList(SF.SeparatedList<BaseTypeSyntax>(names.Select(name => SF.SimpleBaseType(SF.IdentifierName(name)))));
|
||||
}
|
||||
|
||||
public static List<ParameterSyntax> GetMethodParameterSyntaxList(IMethodSymbol methodSymbol)
|
||||
{
|
||||
var paramsSyntaxList = new List<ParameterSyntax>();
|
||||
foreach (IParameterSymbol param in methodSymbol.Parameters)
|
||||
{
|
||||
ParameterSyntax paramSyntax = SF.Parameter(SF.Identifier(param.Name)).WithType(SF.ParseTypeName(param.Type.GetFullyQualifiedName()));
|
||||
paramsSyntaxList.Add(paramSyntax);
|
||||
}
|
||||
|
||||
return paramsSyntaxList;
|
||||
}
|
||||
|
||||
public static List<IMethodSymbol> GetAllMethods(INamedTypeSymbol interfaceType)
|
||||
{
|
||||
var methodsToStub = new List<IMethodSymbol>(interfaceType.GetMembers().OfType<IMethodSymbol>());
|
||||
methodsToStub.AddRange(GetAllInheritedMethods(interfaceType));
|
||||
return methodsToStub;
|
||||
}
|
||||
|
||||
public static IEnumerable<IMethodSymbol> GetAllInheritedMethods(ITypeSymbol typeSymbol)
|
||||
{
|
||||
var methods = new List<IMethodSymbol>();
|
||||
if (typeSymbol.AllInterfaces.Any())
|
||||
{
|
||||
foreach (var baseInterfaceType in typeSymbol.AllInterfaces)
|
||||
{
|
||||
methods.AddRange(baseInterfaceType.GetMembers().OfType<IMethodSymbol>());
|
||||
}
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
public static SyntaxKind GetVisibilityKeyword(ISymbol stubbedInterface)
|
||||
{
|
||||
return stubbedInterface.DeclaredAccessibility ==
|
||||
Accessibility.Internal ? SyntaxKind.InternalKeyword : SyntaxKind.PublicKeyword;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Autofac" version="3.5.2" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.Common" version="1.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.CSharp" version="1.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.CSharp.Workspaces" version="1.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.Workspaces.Common" version="1.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.Composition" version="1.0.27" targetFramework="net461" />
|
||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net461" />
|
||||
<package id="System.Collections" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Collections.Immutable" version="1.1.37" targetFramework="net461" />
|
||||
<package id="System.Diagnostics.Debug" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Globalization" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.IO" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Linq" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Reflection" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Reflection.Extensions" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Reflection.Metadata" version="1.2.0" targetFramework="net461" />
|
||||
<package id="System.Reflection.Primitives" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Resources.ResourceManager" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Runtime" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Runtime.Extensions" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Runtime.InteropServices" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Text.Encoding" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Text.Encoding.Extensions" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Threading" version="4.0.0" targetFramework="net461" />
|
||||
</packages>
|
|
@ -0,0 +1,29 @@
|
|||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SimpleStubs")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Etg.SimpleStubs")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.0.1.0")]
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Etg.SimpleStubs
|
||||
{
|
||||
public class SequenceContainer<T>
|
||||
{
|
||||
private readonly List<SequenceElement<T>> _sequence = new List<SequenceElement<T>>();
|
||||
|
||||
public virtual SequenceContainer<T> Repeat(T element, int count)
|
||||
{
|
||||
_sequence.Add(new SequenceElement<T>{Element = element, Count = count});
|
||||
return this;
|
||||
}
|
||||
|
||||
public int CallCount { get; private set; } = 0;
|
||||
|
||||
public SequenceContainer<T> Forever(T element)
|
||||
{
|
||||
return Repeat(element, int.MaxValue);
|
||||
}
|
||||
|
||||
public SequenceContainer<T> Once(T element)
|
||||
{
|
||||
return Repeat(element, 1);
|
||||
}
|
||||
|
||||
public SequenceContainer<T> Twice(T element)
|
||||
{
|
||||
return Repeat(element, 2);
|
||||
}
|
||||
|
||||
public virtual T Next
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sequence)
|
||||
{
|
||||
if (!_sequence.Any())
|
||||
{
|
||||
throw new SequenceContainerException(
|
||||
$"The stub sequence has been called more than expected; Make sure the {nameof(SequenceContainer<T>)} is setup correclty");
|
||||
}
|
||||
|
||||
var se = _sequence[0];
|
||||
T e = se.Element;
|
||||
if (--se.Count == 0)
|
||||
{
|
||||
_sequence.RemoveAt(0);
|
||||
}
|
||||
|
||||
CallCount++;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SequenceElement<TElement>
|
||||
{
|
||||
public TElement Element
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace Etg.SimpleStubs
|
||||
{
|
||||
public class SequenceContainerException : Exception
|
||||
{
|
||||
public SequenceContainerException(string msg) : base(msg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C1AAD08E-2A69-429C-8AFF-142B468E0A8F}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Etg.SimpleStubs</RootNamespace>
|
||||
<AssemblyName>Etg.SimpleStubs</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="project.json" />
|
||||
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SequenceContainer.cs" />
|
||||
<Compile Include="SequenceContainerException.cs" />
|
||||
<Compile Include="StubsUtils.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,10 @@
|
|||
namespace Etg.SimpleStubs
|
||||
{
|
||||
public static class StubsUtils
|
||||
{
|
||||
public static SequenceContainer<T> Sequence<T>()
|
||||
{
|
||||
return new SequenceContainer<T>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"supports": {
|
||||
"net46.app": {},
|
||||
"uwp.10.0.app": {},
|
||||
"dnxcore50.app": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore": "5.0.0",
|
||||
"Microsoft.NETCore.Portable.Compatibility": "1.0.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"dotnet": {
|
||||
"imports": "portable-net452+win81"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TestClassLibrary
|
||||
{
|
||||
public interface IAppConfigPeriodicRefreshHandler : IDisposable
|
||||
{
|
||||
void Start();
|
||||
}
|
||||
|
||||
public interface IPhoneBook
|
||||
{
|
||||
long GetContactPhoneNumber(string firstName, string lastName);
|
||||
|
||||
long MyNumber { get; set; }
|
||||
|
||||
int ContactsCount { get; }
|
||||
|
||||
event EventHandler<long> PhoneNumberChanged;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public interface ITestInterface : IDisposable
|
||||
{
|
||||
void DoSomething(string s, int x);
|
||||
|
||||
void DoSomething(List<IEnumerable<string>> list);
|
||||
|
||||
void DoSomething(string[] array);
|
||||
|
||||
Task<List<int>> DoSomething(int parameter);
|
||||
|
||||
string Prop1 { get; }
|
||||
|
||||
string Prop2 { set; }
|
||||
|
||||
string Prop3 { get; set; }
|
||||
|
||||
event EventHandler<EventArgs> Changed;
|
||||
|
||||
event EventHandler OtherEvent;
|
||||
|
||||
List<T> GetGenericList<T, A>();
|
||||
|
||||
void SetGenericValue<T>(T value);
|
||||
}
|
||||
|
||||
public interface IIgnoredInterface : IDisposable
|
||||
{
|
||||
}
|
||||
|
||||
interface IInternalInterface
|
||||
{
|
||||
void DoSomethingInternal();
|
||||
}
|
||||
|
||||
public interface IGenericInterface<T>
|
||||
{
|
||||
T GetX();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("TestClassLibrary")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("TestClassLibrary")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ecbcbae6-949e-4e9c-84e1-614d97909b6c")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
[assembly: InternalsVisibleTo("TestClassLibraryTest")]
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{ECBCBAE6-949E-4E9C-84E1-614D97909B6C}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TestClassLibrary</RootNamespace>
|
||||
<AssemblyName>TestClassLibrary</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ITestInterface.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,10 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<UsingTask TaskName="Etg.SimpleStubs.CodeGen.Tasks.GenerateStubsTask" AssemblyFile="$(ProjectDir)SimpleStubsDlls\Etg.SimpleStubs.CodeGen.dll" />
|
||||
<Target Name="BeforeBuild">
|
||||
<ItemGroup>
|
||||
<SimpleStubsDlls Include="$(ProjectDir)..\..\src\SimpleStubs.CodeGen\bin\$(ConfigurationName)\**\*.dll" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(SimpleStubsDlls)" DestinationFolder="$(ProjectDir)SimpleStubsDlls\%(RecursiveDir)" ContinueOnError="true" Retries="0"/>
|
||||
<GenerateStubsTask ProjectPath="$(ProjectDir)$(ProjectName).csproj" OutputPath="$(ProjectDir)Properties\SimpleStubs.generated.cs" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("TestClassLibraryTest")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("TestClassLibraryTest")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("cb81f60f-1374-4b46-bb64-d848b5103a58")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"IgnoredProjects": [
|
||||
"SimpleStubs",
|
||||
"SimpleStubs.CodeGen"
|
||||
],
|
||||
"IgnoredInterfaces": [
|
||||
"TestClassLibrary.IIgnoredInterface"
|
||||
],
|
||||
"StubInternalInterfaces": true
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{CB81F60F-1374-4B46-BB64-D848B5103A58}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TestClassLibraryTest</RootNamespace>
|
||||
<AssemblyName>TestClassLibraryTest</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Autofac, Version=3.5.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<Reference Include="Microsoft.CodeAnalysis, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.Common.1.1.1\lib\net45\Microsoft.CodeAnalysis.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.1.1.1\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.1.1\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.Workspaces, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.1.1\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CodeAnalysis.Workspaces.Desktop, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.1.1\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Collections.Immutable, Version=1.1.37.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.AttributedModel, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.Convention, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.Hosting, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.Runtime, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Composition.TypedParts, Version=1.0.27.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Reflection.Metadata, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Reflection.Metadata.1.1.0\lib\dotnet5.2\System.Reflection.Metadata.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
|
||||
</ItemGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\SimpleStubs.generated.cs" />
|
||||
<Compile Include="UnitTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\SimpleStubs.CodeGen\SimpleStubs.CodeGen.csproj">
|
||||
<Project>{3e9c520a-94cf-46d0-864b-4293d439c92a}</Project>
|
||||
<Name>SimpleStubs.CodeGen</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\SimpleStubs\SimpleStubs.csproj">
|
||||
<Project>{c1aad08e-2a69-429c-8aff-142b468e0a8f}</Project>
|
||||
<Name>SimpleStubs</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\TestClassLibrary\TestClassLibrary.csproj">
|
||||
<Project>{ecbcbae6-949e-4e9c-84e1-614d97909b6c}</Project>
|
||||
<Name>TestClassLibrary</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="SimpleStubs.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<ImportGroup>
|
||||
<Import Project="Etg.SimpleStubs.targets" Condition="Exists('Etg.SimpleStubs.targets')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -0,0 +1,115 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Etg.SimpleStubs;
|
||||
using Etg.SimpleStubs.CodeGen;
|
||||
using Etg.SimpleStubs.CodeGen.DI;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TestClassLibrary;
|
||||
|
||||
namespace TestClassLibraryTest
|
||||
{
|
||||
[TestClass]
|
||||
public class UnitTest1
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestMethodWithReturnTypeAndParameters()
|
||||
{
|
||||
long number = 6041234567;
|
||||
string firstName = null;
|
||||
string lastName = null;
|
||||
var stub = new StubIPhoneBook
|
||||
{
|
||||
GetContactPhoneNumber_String_String = (fn, ln) =>
|
||||
{
|
||||
firstName = fn;
|
||||
lastName = ln;
|
||||
return number;
|
||||
}
|
||||
};
|
||||
IPhoneBook phoneBook = stub;
|
||||
long actualNumber = phoneBook.GetContactPhoneNumber("John", "Smith");
|
||||
Assert.AreEqual(number, actualNumber);
|
||||
Assert.AreEqual("John", firstName);
|
||||
Assert.AreEqual("Smith", lastName);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestPropertyStubWithGetterAndSetter()
|
||||
{
|
||||
long myNumber = 6041234567;
|
||||
long newNumber = 0;
|
||||
var stub = new StubIPhoneBook
|
||||
{
|
||||
MyNumber_Get = () => myNumber,
|
||||
MyNumber_Set = num =>
|
||||
{
|
||||
newNumber = num;
|
||||
}
|
||||
};
|
||||
IPhoneBook phoneBook = stub;
|
||||
Assert.AreEqual(myNumber, phoneBook.MyNumber);
|
||||
phoneBook.MyNumber = 13;
|
||||
Assert.AreEqual(13, newNumber);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestPropertyStubWithGetterOnly()
|
||||
{
|
||||
int contactsCount = 55;
|
||||
var stub = new StubIPhoneBook { ContactsCount_Get = () => contactsCount };
|
||||
IPhoneBook phoneBook = stub;
|
||||
Assert.AreEqual(contactsCount, phoneBook.ContactsCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestEventStub()
|
||||
{
|
||||
object sender = null;
|
||||
long newNumber = 0;
|
||||
var stub = new StubIPhoneBook();
|
||||
stub.PhoneNumberChanged += (s, num) =>
|
||||
{
|
||||
sender = s;
|
||||
newNumber = num;
|
||||
}
|
||||
|
||||
;
|
||||
stub.PhoneNumberChanged_Raise(this, 55);
|
||||
Assert.AreEqual(55, newNumber);
|
||||
Assert.AreEqual(this, sender);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestCallSequence()
|
||||
{
|
||||
var sequence = StubsUtils.Sequence<Func<string, string, int>>()
|
||||
.Once((p1, p2) => 12345678) // first call
|
||||
.Repeat((p1, p2) => 11122233, 2) // next two call
|
||||
.Forever((p1, p2) => 22233556); // rest of the calls
|
||||
var stub = new StubIPhoneBook { GetContactPhoneNumber_String_String = (p1, p2) => sequence.Next(p1, p2) };
|
||||
IPhoneBook phoneBook = stub;
|
||||
Assert.AreEqual(12345678, phoneBook.GetContactPhoneNumber("John", "Smith"));
|
||||
Assert.AreEqual(11122233, phoneBook.GetContactPhoneNumber("John", "Smith"));
|
||||
Assert.AreEqual(11122233, phoneBook.GetContactPhoneNumber("John", "Smith"));
|
||||
Assert.AreEqual(22233556, phoneBook.GetContactPhoneNumber("John", "Smith"));
|
||||
Assert.AreEqual(22233556, phoneBook.GetContactPhoneNumber("John", "Smith"));
|
||||
Assert.AreEqual(22233556, phoneBook.GetContactPhoneNumber("John", "Smith"));
|
||||
|
||||
Assert.AreEqual(6, sequence.CallCount);
|
||||
}
|
||||
|
||||
// this test is only used for debugging
|
||||
[Ignore]
|
||||
[TestMethod]
|
||||
public async Task TestGenerateStubs()
|
||||
{
|
||||
string path = //@"C:\projects\JasperMain\Product\Jasper.Test\Jasper.Test.csproj";
|
||||
@"..\..\TestClassLibraryTest.csproj";
|
||||
//"..\\..\\SimpleStubsTest.csproj";
|
||||
SimpleStubsGenerator stubsGenerator = new DiModule(path, @"..\..\Properties\SimpleStubs.generated.cs").StubsGenerator;
|
||||
string stubs = await stubsGenerator.GenerateStubs(path);
|
||||
File.WriteAllText(@"..\..\Properties\SimpleStubs.generated.cs", stubs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Autofac" version="3.5.2" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.Common" version="1.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.CSharp" version="1.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.CSharp.Workspaces" version="1.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.Workspaces.Common" version="1.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.Composition" version="1.0.27" targetFramework="net461" />
|
||||
<package id="System.Collections" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Collections.Immutable" version="1.1.37" targetFramework="net461" />
|
||||
<package id="System.Diagnostics.Debug" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Globalization" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.IO" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Linq" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Reflection" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Reflection.Extensions" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Reflection.Metadata" version="1.1.0" targetFramework="net461" />
|
||||
<package id="System.Reflection.Primitives" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Resources.ResourceManager" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Runtime" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Runtime.Extensions" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Runtime.InteropServices" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Text.Encoding" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Text.Encoding.Extensions" version="4.0.0" targetFramework="net461" />
|
||||
<package id="System.Threading" version="4.0.0" targetFramework="net461" />
|
||||
</packages>
|