├── .gitignore
├── README.md
├── TypeConverter.NuGet
├── NuGet.config
├── NuGet.exe
├── NuGetPackage.ps1
├── NuGetSetup.ps1
├── Package.nuspec
├── Properties
│ └── AssemblyInfo.cs
├── TypeConverter.NuGet.csproj
├── TypeConverterIcon.png
├── UpdateAssemblyInfo.ps1
└── tools
│ ├── init.ps1
│ ├── install.ps1
│ └── uninstall.ps1
├── TypeConverter.Tests
├── App.config
├── Caching
│ └── CacheManagerTests.cs
├── ConverterRegistryExtensionsTests.cs
├── ConverterRegistryTests.cs
├── Converters
│ ├── StringToBoolConverterTests.cs
│ ├── StringToDateTimeConverterTests.cs
│ ├── StringToDateTimeOffsetConverterTests.cs
│ ├── StringToDecimalConverterTests.cs
│ ├── StringToDoubleConverterTests.cs
│ ├── StringToFloatConverterTests.cs
│ ├── StringToGuidConverterTests.cs
│ ├── StringToIntegerConverterTests.cs
│ └── StringToUriConverterTests.cs
├── Extensions
│ └── TypeExtensionsTests.cs
├── Properties
│ └── AssemblyInfo.cs
├── Stubs
│ ├── DerivedOperators.cs
│ ├── MyEnum.cs
│ ├── MyEnumConverter.cs
│ ├── Operators.cs
│ ├── Operators2.cs
│ ├── OperatorsStruct.cs
│ └── TestStruct1.cs
├── TypeConverter.Tests.csproj
├── TypeHelperTests.cs
├── Utils
│ ├── CastTestRunner.cs
│ ├── CompilerConversionTestCase.cs
│ └── CompilerException.cs
└── packages.config
├── TypeConverter.sln
└── TypeConverter
├── Attempts
├── CastAttempt.cs
├── ChangeTypeAttempt.cs
├── CustomConvertAttempt.cs
├── EnumParseAttempt.cs
├── IConversionAttempt.cs
├── MapAttempt.cs
└── StringParseAttempt.cs
├── Caching
├── CacheManager.cs
└── CacheResult.cs
├── CastFlag.cs
├── CastResult.cs
├── ConversionResult.cs
├── ConverterRegistry.cs
├── Converters
├── StringToBoolConverter.cs
├── StringToDateTimeConverter.cs
├── StringToDateTimeOffsetConverter.cs
├── StringToDecimalConverter.cs
├── StringToDoubleConverter.cs
├── StringToFloatConverter.cs
├── StringToGuidConverter.cs
├── StringToIntegerConverter.cs
├── StringToUriConverter.cs
└── ToStringFormattableConvertable.cs
├── Exceptions
└── ConversionNotSupportedException.cs
├── Extensions
├── ConverterRegistryExtensions.cs
└── TypeExtensions.cs
├── IConvertable.cs
├── IConverter.cs
├── IConverterCache.cs
├── IConverterRegistry.cs
├── Properties
└── AssemblyInfo.cs
├── TypeConverter.csproj
├── TypeConverterKey.snk
├── TypeConverterPublicKey.snk
├── Utils
├── ReflectionHelper.cs
└── TypeHelper.cs
└── packages.config
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 |
24 | # Visual Studio 2015 cache/options directory
25 | .vs/
26 | # Uncomment if you have tasks that create the project's static files in wwwroot
27 | #wwwroot/
28 |
29 | # MSTest test Results
30 | [Tt]est[Rr]esult*/
31 | [Bb]uild[Ll]og.*
32 |
33 | # NUNIT
34 | *.VisualState.xml
35 | TestResult.xml
36 |
37 | # Build Results of an ATL Project
38 | [Dd]ebugPS/
39 | [Rr]eleasePS/
40 | dlldata.c
41 |
42 | # DNX
43 | project.lock.json
44 | artifacts/
45 |
46 | *_i.c
47 | *_p.c
48 | *_i.h
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.tmp_proj
63 | *.log
64 | *.vspscc
65 | *.vssscc
66 | .builds
67 | *.pidb
68 | *.svclog
69 | *.scc
70 |
71 | # Chutzpah Test files
72 | _Chutzpah*
73 |
74 | # Visual C++ cache files
75 | ipch/
76 | *.aps
77 | *.ncb
78 | *.opendb
79 | *.opensdf
80 | *.sdf
81 | *.cachefile
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 | *.vspx
87 | *.sap
88 |
89 | # TFS 2012 Local Workspace
90 | $tf/
91 |
92 | # Guidance Automation Toolkit
93 | *.gpState
94 |
95 | # ReSharper is a .NET coding add-in
96 | _ReSharper*/
97 | *.[Rr]e[Ss]harper
98 | *.DotSettings.user
99 |
100 | # JustCode is a .NET coding add-in
101 | .JustCode
102 |
103 | # TeamCity is a build add-in
104 | _TeamCity*
105 |
106 | # DotCover is a Code Coverage Tool
107 | *.dotCover
108 |
109 | # NCrunch
110 | _NCrunch_*
111 | .*crunch*.local.xml
112 | nCrunchTemp_*
113 |
114 | # MightyMoose
115 | *.mm.*
116 | AutoTest.Net/
117 |
118 | # Web workbench (sass)
119 | .sass-cache/
120 |
121 | # Installshield output folder
122 | [Ee]xpress/
123 |
124 | # DocProject is a documentation generator add-in
125 | DocProject/buildhelp/
126 | DocProject/Help/*.HxT
127 | DocProject/Help/*.HxC
128 | DocProject/Help/*.hhc
129 | DocProject/Help/*.hhk
130 | DocProject/Help/*.hhp
131 | DocProject/Help/Html2
132 | DocProject/Help/html
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | # TODO: Comment the next line if you want to checkin your web deploy settings
141 | # but database connection strings (with potential passwords) will be unencrypted
142 | *.pubxml
143 | *.publishproj
144 |
145 | # NuGet Packages
146 | *.nupkg
147 | # The packages folder can be ignored because of Package Restore
148 | **/packages/*
149 | # except build/, which is used as an MSBuild target.
150 | !**/packages/build/
151 | # Uncomment if necessary however generally it will be regenerated when needed
152 | #!**/packages/repositories.config
153 | # NuGet v3's project.json files produces more ignoreable files
154 | *.nuget.props
155 | *.nuget.targets
156 |
157 | # Microsoft Azure Build Output
158 | csx/
159 | *.build.csdef
160 |
161 | # Microsoft Azure Emulator
162 | ecf/
163 | rcf/
164 |
165 | # Microsoft Azure ApplicationInsights config file
166 | ApplicationInsights.config
167 |
168 | # Windows Store app package directory
169 | AppPackages/
170 | BundleArtifacts/
171 |
172 | # Visual Studio cache files
173 | # files ending in .cache can be ignored
174 | *.[Cc]ache
175 | # but keep track of directories ending in .cache
176 | !*.[Cc]ache/
177 |
178 | # Others
179 | ClientBin/
180 | ~$*
181 | *~
182 | *.dbmdl
183 | *.dbproj.schemaview
184 | *.pfx
185 | *.publishsettings
186 | node_modules/
187 | orleans.codegen.cs
188 |
189 | # RIA/Silverlight projects
190 | Generated_Code/
191 |
192 | # Backup & report files from converting an old project file
193 | # to a newer Visual Studio version. Backup files are not needed,
194 | # because we have git ;-)
195 | _UpgradeReport_Files/
196 | Backup*/
197 | UpgradeLog*.XML
198 | UpgradeLog*.htm
199 |
200 | # SQL Server files
201 | *.mdf
202 | *.ldf
203 |
204 | # Business Intelligence projects
205 | *.rdl.data
206 | *.bim.layout
207 | *.bim_*.settings
208 |
209 | # Microsoft Fakes
210 | FakesAssemblies/
211 |
212 | # GhostDoc plugin setting file
213 | *.GhostDoc.xml
214 |
215 | # Node.js Tools for Visual Studio
216 | .ntvs_analysis.dat
217 |
218 | # Visual Studio 6 build log
219 | *.plg
220 |
221 | # Visual Studio 6 workspace options file
222 | *.opt
223 |
224 | # Visual Studio LightSwitch build output
225 | **/*.HTMLClient/GeneratedArtifacts
226 | **/*.DesktopClient/GeneratedArtifacts
227 | **/*.DesktopClient/ModelManifest.xml
228 | **/*.Server/GeneratedArtifacts
229 | **/*.Server/ModelManifest.xml
230 | _Pvt_Extensions
231 |
232 | # Paket dependency manager
233 | .paket/paket.exe
234 |
235 | # FAKE - F# Make
236 | .fake/
237 | *.bak
238 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TypeConverter
2 |
3 | TypeConverter is a lightweight, portable class library which allows to convert between objects of different types. The philosophy behind TypeConverter is that type conversion should no longer be a painfull topic to developers. As a developer, you simply specify source and target type and pass in your desired object which you want to convert.
4 |
5 | This library is shipped with some basic sample conversion strategies, however, you are free to write your own type converters and register them in the IConverterRegistry. The most important type conversions provided by the .Net framework are integrated into TypeConverter. However, your own converters are always preferred over the .Net integrated default converstion/casting strategy. Following order of priority is respected:
6 | - Attempt 1: Try to convert using registered, user-defined IConverters
7 | - Attempt 2: Return source value if source and target type are the same
8 | - Attempt 3: Try to cast implicitly to the target type
9 | - Attempt 4: Try to cast explicitly to the target type
10 | - Attempt 5: Try to convert between string and enum value if either source or target type is an enum resp. a string
11 | - Attempt 6: Try to use String.Parse if either source or target type is a string
12 |
13 | If all attempts fail, the Convert method throws a ConversionNotSupportedException with the specified reason. TryConvert does return null if no conversion could be done.
14 |
15 | ### Download and Install TypeConverter
16 | This library is available on NuGet: https://www.nuget.org/packages/TypeConverter/
17 | Use the following command to install TypeConverter using NuGet package manager console:
18 |
19 | PM> Install-Package TypeConverter
20 |
21 | You can use this library in any .Net project which is compatible to PCL (e.g. Xamarin Android, iOS, Windows Phone, Windows Store, Universal Apps, etc.)
22 |
23 | ### API Usage
24 | #### Create your own type converter
25 | If you want to implement a type converter, you simply implement the IConverter interface where TFrom is the generic type from which you want to convert and TTo is the type to which you want to convert to.
26 | Following sample code illustrates a converter which converts between string and System.Uri.
27 | ```
28 | public class StringToUriConverter : IConverter, IConverter
29 | {
30 | public Uri Convert(string value)
31 | {
32 | return new Uri(value);
33 | }
34 |
35 | public string Convert(Uri value)
36 | {
37 | return value.AbsoluteUri;
38 | }
39 | }
40 | ```
41 |
42 | #### Register a converter
43 | Create (or retrieve via dependency injection) an instance of ConverterRegistry and register those converters you like to use later on. Beware that you will have to register a converter for each direction you want to convert (if you support two-way conversion). Following example shows how to register the StringToUriConverter to convert between string and Uri and vice versa.
44 | ```
45 | IConverterRegistry converterRegistry = new ConverterRegistry();
46 | converterRegistry.RegisterConverter(() => new StringToUriConverter());
47 | converterRegistry.RegisterConverter(() => new StringToUriConverter());
48 | ```
49 |
50 | #### Convert between types
51 | Now, after having set-up a basic converter, we can use IConverterRegistry to convert between object of different types.
52 |
53 | Convert from string to System.Uri
54 | ```
55 | var uri = converterRegistry.Convert("http://github.com/");
56 | ```
57 | Convert from System.Uri to string
58 | ```
59 | var uriAsString = converterRegistry.Convert(uri);
60 | ```
61 |
62 | ### License
63 | TypeConverter is Copyright © 2018 [Thomas Galliker](https://ch.linkedin.com/in/thomasgalliker). Free for non-commercial use. For commercial use please contact the author.
64 |
--------------------------------------------------------------------------------
/TypeConverter.NuGet/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TypeConverter.NuGet/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomasgalliker/TypeConverter/565afd5a018221a39bbf24e517f87cce683feaff/TypeConverter.NuGet/NuGet.exe
--------------------------------------------------------------------------------
/TypeConverter.NuGet/NuGetPackage.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [switch]$Publish
3 | )
4 |
5 | $ErrorActionPreference = "Stop"
6 | $global:ExitCode = 1
7 |
8 | function Write-Log {
9 |
10 | #region Parameters
11 |
12 | [cmdletbinding()]
13 | Param(
14 | [Parameter(ValueFromPipeline=$true)]
15 | [array] $Messages,
16 |
17 | [Parameter()] [ValidateSet("Error", "Warn", "Info")]
18 | [string] $Level = "Info",
19 |
20 | [Parameter()]
21 | [Switch] $NoConsoleOut = $false,
22 |
23 | [Parameter()]
24 | [String] $ForegroundColor = 'White',
25 |
26 | [Parameter()] [ValidateRange(1,30)]
27 | [Int16] $Indent = 0,
28 |
29 | [Parameter()]
30 | [IO.FileInfo] $Path = ".\NuGet.log",
31 |
32 | [Parameter()]
33 | [Switch] $Clobber,
34 |
35 | [Parameter()]
36 | [String] $EventLogName,
37 |
38 | [Parameter()]
39 | [String] $EventSource,
40 |
41 | [Parameter()]
42 | [Int32] $EventID = 1
43 |
44 | )
45 |
46 | #endregion
47 |
48 | Begin {}
49 |
50 | Process {
51 |
52 | $ErrorActionPreference = "Continue"
53 |
54 | if ($Messages.Length -gt 0) {
55 | try {
56 | foreach($m in $Messages) {
57 | if ($NoConsoleOut -eq $false) {
58 | switch ($Level) {
59 | 'Error' {
60 | Write-Error $m -ErrorAction SilentlyContinue
61 | Write-Host ('{0}{1}' -f (" " * $Indent), $m) -ForegroundColor Red
62 | }
63 | 'Warn' {
64 | Write-Warning $m
65 | }
66 | 'Info' {
67 | Write-Host ('{0}{1}' -f (" " * $Indent), $m) -ForegroundColor $ForegroundColor
68 | }
69 | }
70 | }
71 |
72 | if ($m.Trim().Length -gt 0) {
73 | $msg = '{0}{1} [{2}] : {3}' -f (" " * $Indent), (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Level.ToUpper(), $m
74 |
75 | if ($Clobber) {
76 | $msg | Out-File -FilePath $Path -Force
77 | } else {
78 | $msg | Out-File -FilePath $Path -Append
79 | }
80 | }
81 |
82 | if ($EventLogName) {
83 |
84 | if (-not $EventSource) {
85 | $EventSource = ([IO.FileInfo] $MyInvocation.ScriptName).Name
86 | }
87 |
88 | if(-not [Diagnostics.EventLog]::SourceExists($EventSource)) {
89 | [Diagnostics.EventLog]::CreateEventSource($EventSource, $EventLogName)
90 | }
91 |
92 | $log = New-Object System.Diagnostics.EventLog
93 | $log.set_log($EventLogName)
94 | $log.set_source($EventSource)
95 |
96 | switch ($Level) {
97 | "Error" { $log.WriteEntry($Message, 'Error', $EventID) }
98 | "Warn" { $log.WriteEntry($Message, 'Warning', $EventID) }
99 | "Info" { $log.WriteEntry($Message, 'Information', $EventID) }
100 | }
101 | }
102 | }
103 | }
104 | catch {
105 | throw "Failed to create log entry in: '$Path'. The error was: '$_'."
106 | }
107 | }
108 | }
109 |
110 | End {}
111 |
112 | <#
113 | .SYNOPSIS
114 | Writes logging information to screen and log file simultaneously.
115 |
116 | .DESCRIPTION
117 | Writes logging information to screen and log file simultaneously. Supports multiple log levels.
118 |
119 | .PARAMETER Messages
120 | The messages to be logged.
121 |
122 | .PARAMETER Level
123 | The type of message to be logged.
124 |
125 | .PARAMETER NoConsoleOut
126 | Specifies to not display the message to the console.
127 |
128 | .PARAMETER ConsoleForeground
129 | Specifies what color the text should be be displayed on the console. Ignored when switch 'NoConsoleOut' is specified.
130 |
131 | .PARAMETER Indent
132 | The number of spaces to indent the line in the log file.
133 |
134 | .PARAMETER Path
135 | The log file path.
136 |
137 | .PARAMETER Clobber
138 | Existing log file is deleted when this is specified.
139 |
140 | .PARAMETER EventLogName
141 | The name of the system event log, e.g. 'Application'.
142 |
143 | .PARAMETER EventSource
144 | The name to appear as the source attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
145 |
146 | .PARAMETER EventID
147 | The ID to appear as the event ID attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
148 |
149 | .EXAMPLE
150 | PS C:\> Write-Log -Message "It's all good!" -Path C:\MyLog.log -Clobber -EventLogName 'Application'
151 |
152 | .EXAMPLE
153 | PS C:\> Write-Log -Message "Oops, not so good!" -Level Error -EventID 3 -Indent 2 -EventLogName 'Application' -EventSource "My Script"
154 |
155 | .INPUTS
156 | System.String
157 |
158 | .OUTPUTS
159 | No output.
160 |
161 | .NOTES
162 | Revision History:
163 | 2011-03-10 : Andy Arismendi - Created.
164 | #>
165 | }
166 |
167 | function Create-Process() {
168 | param([string] $fileName, [string] $arguments)
169 |
170 | $pinfo = New-Object System.Diagnostics.ProcessStartInfo
171 | $pinfo.RedirectStandardError = $true
172 | $pinfo.RedirectStandardOutput = $true
173 | $pinfo.UseShellExecute = $false
174 | $pinfo.FileName = $fileName
175 | $pinfo.Arguments = $arguments
176 |
177 | $p = New-Object System.Diagnostics.Process
178 | $p.StartInfo = $pinfo
179 |
180 | return $p
181 | }
182 |
183 | function HandlePublishError {
184 | param([string] $ErrorMessage)
185 |
186 | # Run NuGet Setup
187 | $encodedMessage = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($ErrorMessage))
188 | $setupTask = Start-Process PowerShell.exe "-ExecutionPolicy Unrestricted -File .\NuGetSetup.ps1 -Url $url -Base64EncodedMessage $encodedMessage" -Wait -PassThru
189 |
190 | #Write-Log ("NuGet Setup Task Exit Code: " + $setupTask.ExitCode)
191 |
192 | if ($setupTask.ExitCode -eq 0) {
193 | # Try to push package again
194 | $publishTask = Create-Process .\NuGet.exe ("push " + $_.Name + " -Source " + $url)
195 | $publishTask.Start() | Out-Null
196 | $publishTask.WaitForExit()
197 |
198 | $output = ($publishTask.StandardOutput.ReadToEnd() -Split '[\r\n]') |? {$_}
199 | $error = (($publishTask.StandardError.ReadToEnd() -Split '[\r\n]') |? {$_})
200 | Write-Log $output
201 | Write-Log $error Error
202 |
203 | if ($publishTask.ExitCode -eq 0) {
204 | $global:ExitCode = 0
205 | }
206 | }
207 | elseif ($setupTask.ExitCode -eq 2) {
208 | $global:ExitCode = 2
209 | }
210 | else {
211 | $global:ExitCode = 0
212 | }
213 | }
214 |
215 | function Publish {
216 |
217 | Write-Log " "
218 | Write-Log "Publishing package..." -ForegroundColor Green
219 |
220 | # Get nuget config
221 | [xml]$nugetConfig = Get-Content .\NuGet.Config
222 |
223 | $nugetConfig.configuration.packageSources.add | ForEach-Object {
224 | $url = $_.value
225 |
226 | Write-Log "Repository Url: $url"
227 | Write-Log " "
228 |
229 | Get-ChildItem *.nupkg | Where-Object { $_.Name.EndsWith(".symbols.nupkg") -eq $false } | ForEach-Object {
230 |
231 | # Try to push package
232 | $task = Create-Process .\NuGet.exe ("push " + $_.Name + " -Source " + $url)
233 | $task.Start() | Out-Null
234 | $task.WaitForExit()
235 |
236 | $output = ($task.StandardOutput.ReadToEnd() -Split '[\r\n]') |? { $_ }
237 | $error = ($task.StandardError.ReadToEnd() -Split '[\r\n]') |? { $_ }
238 | Write-Log $output
239 | Write-Log $error Error
240 |
241 | if ($task.ExitCode -gt 0) {
242 | HandlePublishError -ErrorMessage $error
243 | #Write-Log ("HandlePublishError() Exit Code: " + $global:ExitCode)
244 | }
245 | else {
246 | $global:ExitCode = 0
247 | }
248 | }
249 | }
250 | }
251 |
252 | Write-Log " "
253 | Write-Log "NuGet Packager 2.0.3" -ForegroundColor Yellow
254 |
255 | # Make sure the nuget executable is writable
256 | Set-ItemProperty NuGet.exe -Name IsReadOnly -Value $false
257 |
258 | # Make sure the nupkg files are writeable and create backup
259 | if (Test-Path *.nupkg) {
260 | Set-ItemProperty *.nupkg -Name IsReadOnly -Value $false
261 |
262 | Write-Log " "
263 | Write-Log "Creating backup..." -ForegroundColor Green
264 |
265 | Get-ChildItem *.nupkg | ForEach-Object {
266 | Move-Item $_.Name ($_.Name + ".bak") -Force
267 | Write-Log ("Renamed " + $_.Name + " to " + $_.Name + ".bak")
268 | }
269 | }
270 |
271 | Write-Log " "
272 | Write-Log "Updating NuGet..." -ForegroundColor Green
273 | Write-Log (Invoke-Command {.\NuGet.exe update -Self} -ErrorAction Stop)
274 |
275 | Write-Log " "
276 | Write-Log "Creating package..." -ForegroundColor Green
277 |
278 | # Create symbols package if any .pdb files are located in the lib folder
279 | If ((Get-ChildItem *.pdb -Path .\lib -Recurse).Count -gt 0) {
280 | $packageTask = Create-Process .\NuGet.exe ("pack Package.nuspec -Symbol -Verbosity Detailed")
281 | $packageTask.Start() | Out-Null
282 | $packageTask.WaitForExit()
283 |
284 | $output = ($packageTask.StandardOutput.ReadToEnd() -Split '[\r\n]') |? {$_}
285 | $error = (($packageTask.StandardError.ReadToEnd() -Split '[\r\n]') |? {$_})
286 | Write-Log $output
287 | Write-Log $error Error
288 |
289 | $global:ExitCode = $packageTask.ExitCode
290 | }
291 | Else {
292 | $packageTask = Create-Process .\NuGet.exe ("pack Package.nuspec -Verbosity Detailed")
293 | $packageTask.Start() | Out-Null
294 | $packageTask.WaitForExit()
295 |
296 | $output = ($packageTask.StandardOutput.ReadToEnd() -Split '[\r\n]') |? {$_}
297 | $error = (($packageTask.StandardError.ReadToEnd() -Split '[\r\n]') |? {$_})
298 | Write-Log $output
299 | Write-Log $error Error
300 |
301 | $global:ExitCode = $packageTask.ExitCode
302 | }
303 |
304 | # Check if package should be published
305 | if ($Publish -and $global:ExitCode -eq 0) {
306 | Publish
307 | }
308 |
309 | Write-Log " "
310 | Write-Log "Exit Code: $global:ExitCode" -ForegroundColor Gray
311 |
312 | $host.SetShouldExit($global:ExitCode)
313 | Exit $global:ExitCode
--------------------------------------------------------------------------------
/TypeConverter.NuGet/NuGetSetup.ps1:
--------------------------------------------------------------------------------
1 | Param (
2 | [string]$Url,
3 | [string]$Base64EncodedMessage
4 | )
5 |
6 | $ErrorActionPreference = "Stop"
7 | $ExitCode = 1
8 |
9 | function Write-Log {
10 |
11 | #region Parameters
12 |
13 | [cmdletbinding()]
14 | Param(
15 | [Parameter(ValueFromPipeline=$true)]
16 | [array] $Messages,
17 |
18 | [Parameter()] [ValidateSet("Error", "Warn", "Info")]
19 | [string] $Level = "Info",
20 |
21 | [Parameter()]
22 | [Switch] $NoConsoleOut = $false,
23 |
24 | [Parameter()]
25 | [String] $ForegroundColor = 'White',
26 |
27 | [Parameter()] [ValidateRange(1,30)]
28 | [Int16] $Indent = 0,
29 |
30 | [Parameter()]
31 | [IO.FileInfo] $Path = ".\NuGet.log",
32 |
33 | [Parameter()]
34 | [Switch] $Clobber,
35 |
36 | [Parameter()]
37 | [String] $EventLogName,
38 |
39 | [Parameter()]
40 | [String] $EventSource,
41 |
42 | [Parameter()]
43 | [Int32] $EventID = 1
44 |
45 | )
46 |
47 | #endregion
48 |
49 | Begin {}
50 |
51 | Process {
52 |
53 | $ErrorActionPreference = "Continue"
54 |
55 | if ($Messages.Length -gt 0) {
56 | try {
57 | foreach($m in $Messages) {
58 | if ($NoConsoleOut -eq $false) {
59 | switch ($Level) {
60 | 'Error' {
61 | Write-Error $m -ErrorAction SilentlyContinue
62 | Write-Host ('{0}{1}' -f (" " * $Indent), $m) -ForegroundColor Red
63 | }
64 | 'Warn' {
65 | Write-Warning $m
66 | }
67 | 'Info' {
68 | Write-Host ('{0}{1}' -f (" " * $Indent), $m) -ForegroundColor $ForegroundColor
69 | }
70 | }
71 | }
72 |
73 | if ($m.Trim().Length -gt 0) {
74 | $msg = '{0}{1} [{2}] : {3}' -f (" " * $Indent), (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Level.ToUpper(), $m
75 |
76 | if ($Clobber) {
77 | $msg | Out-File -FilePath $Path -Force
78 | } else {
79 | $msg | Out-File -FilePath $Path -Append
80 | }
81 | }
82 |
83 | if ($EventLogName) {
84 |
85 | if (-not $EventSource) {
86 | $EventSource = ([IO.FileInfo] $MyInvocation.ScriptName).Name
87 | }
88 |
89 | if(-not [Diagnostics.EventLog]::SourceExists($EventSource)) {
90 | [Diagnostics.EventLog]::CreateEventSource($EventSource, $EventLogName)
91 | }
92 |
93 | $log = New-Object System.Diagnostics.EventLog
94 | $log.set_log($EventLogName)
95 | $log.set_source($EventSource)
96 |
97 | switch ($Level) {
98 | "Error" { $log.WriteEntry($Message, 'Error', $EventID) }
99 | "Warn" { $log.WriteEntry($Message, 'Warning', $EventID) }
100 | "Info" { $log.WriteEntry($Message, 'Information', $EventID) }
101 | }
102 | }
103 | }
104 | }
105 | catch {
106 | throw "Failed to create log entry in: '$Path'. The error was: '$_'."
107 | }
108 | }
109 | }
110 |
111 | End {}
112 |
113 | <#
114 | .SYNOPSIS
115 | Writes logging information to screen and log file simultaneously.
116 |
117 | .DESCRIPTION
118 | Writes logging information to screen and log file simultaneously. Supports multiple log levels.
119 |
120 | .PARAMETER Messages
121 | The messages to be logged.
122 |
123 | .PARAMETER Level
124 | The type of message to be logged.
125 |
126 | .PARAMETER NoConsoleOut
127 | Specifies to not display the message to the console.
128 |
129 | .PARAMETER ConsoleForeground
130 | Specifies what color the text should be be displayed on the console. Ignored when switch 'NoConsoleOut' is specified.
131 |
132 | .PARAMETER Indent
133 | The number of spaces to indent the line in the log file.
134 |
135 | .PARAMETER Path
136 | The log file path.
137 |
138 | .PARAMETER Clobber
139 | Existing log file is deleted when this is specified.
140 |
141 | .PARAMETER EventLogName
142 | The name of the system event log, e.g. 'Application'.
143 |
144 | .PARAMETER EventSource
145 | The name to appear as the source attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
146 |
147 | .PARAMETER EventID
148 | The ID to appear as the event ID attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
149 |
150 | .EXAMPLE
151 | PS C:\> Write-Log -Message "It's all good!" -Path C:\MyLog.log -Clobber -EventLogName 'Application'
152 |
153 | .EXAMPLE
154 | PS C:\> Write-Log -Message "Oops, not so good!" -Level Error -EventID 3 -Indent 2 -EventLogName 'Application' -EventSource "My Script"
155 |
156 | .INPUTS
157 | System.String
158 |
159 | .OUTPUTS
160 | No output.
161 |
162 | .NOTES
163 | Revision History:
164 | 2011-03-10 : Andy Arismendi - Created.
165 | #>
166 | }
167 |
168 | $choices = [System.Management.Automation.Host.ChoiceDescription[]](
169 | (New-Object System.Management.Automation.Host.ChoiceDescription "&Add API Key","Add an API Key for this URL"),
170 | (New-Object System.Management.Automation.Host.ChoiceDescription "&Skip","Skip pushing to this URL"))
171 |
172 | Write-Output ""
173 | Write-Log "Invalid API key for this repository URL, or there is a version conflict" Warn
174 |
175 | If ($Base64EncodedMessage) {
176 | Write-Warning ([System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($Base64EncodedMessage)))
177 | }
178 |
179 | $firstAnswer = $Host.UI.PromptForChoice(("Would you like to try adding an API key for " + $Url + "?"), "", $choices, (1))
180 |
181 | if ($firstAnswer -eq 0) {
182 | $fields = new-object "System.Collections.ObjectModel.Collection``1[[System.Management.Automation.Host.FieldDescription]]"
183 |
184 | $f = New-Object System.Management.Automation.Host.FieldDescription "API Key for $Url"
185 | $f.SetParameterType( [System.Security.SecureString] )
186 | $f.HelpMessage = "Please enter API Key for $Url"
187 | $f.Label = "&API Key for $Url"
188 |
189 | $fields.Add($f)
190 |
191 | $results = $Host.UI.Prompt( "Add API Key", "", $fields )
192 |
193 | $pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($results["API Key for $Url"]))
194 |
195 | # Add API Key to config file
196 | Write-Log (.\NuGet.exe setApiKey $pass -Source $Url)
197 |
198 | if ($LASTEXITCODE -le 0) {
199 | $ExitCode = 0
200 | }
201 | }
202 | else {
203 | Write-Log "Skipping..."
204 | $ExitCode = 2
205 | }
206 |
207 | $host.SetShouldExit($ExitCode)
208 | Exit $ExitCode
--------------------------------------------------------------------------------
/TypeConverter.NuGet/Package.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TypeConverter
5 | 1.0.28-pre92
6 | TypeConverter
7 | Thomas Galliker
8 | http://opensource.org/licenses/Apache-2.0
9 | https://github.com/thomasgalliker/TypeConverter/
10 | https://raw.githubusercontent.com/thomasgalliker/TypeConverter/master/TypeConverter.NuGet/TypeConverterIcon.png
11 | false
12 |
13 | TypeConverter is a lightweight, portable class library which allows to convert between objects of different types.
14 |
15 |
16 | TypeConverter is a lightweight, portable class library which allows to convert between objects of different types.
17 | This library is shipped with some basic sample converters, however, you are free to write your own type converters
18 | and register them in the IConverterRegistry.
19 |
20 |
21 | TypeConverter convert conversion type mapping mapper
22 | windows phone winphone wp8 wpa81 win81 windowsphone android xamarin.forms xamarin.ios ios xamarin.android monoandroid monodroid monotouch
23 |
24 |
25 | 1.0.28-pre
26 | - Added new converters
27 | - Added new RegisterConverter method in IConverterRegistry which allows to register non-generic IConvertable converters
28 | - Added new RegisterMapping method which allows to specify simple property-to-property mappings
29 | - Minor performance improvements and bug fixes
30 |
31 | 1.0.27
32 | - Complete refactoring of caching mechanism
33 | - New IConverterCache interface to interact with caching configuration
34 | - Cache size limit with read access weighting
35 |
36 | 1.0.26
37 | - Added ChangeType support (which uses Convert.ToXYZ(value) methods)
38 |
39 | 1.0.25
40 | - Improved support for implicit and explicit type casting
41 | - TryConvert API cleaned-up
42 |
43 | Copyright 2017
44 | en-US
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/TypeConverter.NuGet/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 |
8 | [assembly: AssemblyTitle("TypeConverter.NuGet")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Thomas Galliker")]
12 | [assembly: AssemblyProduct("TypeConverter.NuGet")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 |
21 | [assembly: ComVisible(false)]
22 |
23 | // The following GUID is for the ID of the typelib if this project is exposed to COM
24 |
25 | [assembly: Guid("5b586874-8d3e-4137-9ba8-e982413416d5")]
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 | // You can specify all the values or you can default the Build and Revision Numbers
35 | // by using the '*' as shown below:
36 | // [assembly: AssemblyVersion("1.0.28")]
37 |
38 | [assembly: AssemblyVersion("1.0.28")]
39 | [assembly: AssemblyFileVersion("1.0.28-pre92")]
40 |
--------------------------------------------------------------------------------
/TypeConverter.NuGet/TypeConverter.NuGet.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {2CF5E868-1098-4C6D-9001-27D8DC0D87BE}
9 | Library
10 | Properties
11 | TypeConverter.NuGet
12 | TypeConverter.NuGet
13 | v3.5
14 |
15 |
16 | 512
17 |
18 |
19 | AnyCPU
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 |
28 |
29 | AnyCPU
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 | AnyCPU
39 | bin\Debug\
40 |
41 |
42 | AnyCPU
43 | bin\Release\
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Designer
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/TypeConverter.NuGet/TypeConverterIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomasgalliker/TypeConverter/565afd5a018221a39bbf24e517f87cce683feaff/TypeConverter.NuGet/TypeConverterIcon.png
--------------------------------------------------------------------------------
/TypeConverter.NuGet/UpdateAssemblyInfo.ps1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomasgalliker/TypeConverter/565afd5a018221a39bbf24e517f87cce683feaff/TypeConverter.NuGet/UpdateAssemblyInfo.ps1
--------------------------------------------------------------------------------
/TypeConverter.NuGet/tools/init.ps1:
--------------------------------------------------------------------------------
1 | # Runs the first time a package is installed in a solution, and every time the solution is opened.
2 |
3 | param($installPath, $toolsPath, $package, $project)
4 |
5 | # $installPath is the path to the folder where the package is installed.
6 | # $toolsPath is the path to the tools directory in the folder where the package is installed.
7 | # $package is a reference to the package object.
8 | # $project is null in init.ps1
9 |
--------------------------------------------------------------------------------
/TypeConverter.NuGet/tools/install.ps1:
--------------------------------------------------------------------------------
1 | # Runs every time a package is installed in a project
2 |
3 | param($installPath, $toolsPath, $package, $project)
4 |
5 | # $installPath is the path to the folder where the package is installed.
6 | # $toolsPath is the path to the tools directory in the folder where the package is installed.
7 | # $package is a reference to the package object.
8 | # $project is a reference to the project the package was installed to.
9 |
--------------------------------------------------------------------------------
/TypeConverter.NuGet/tools/uninstall.ps1:
--------------------------------------------------------------------------------
1 | # Runs every time a package is uninstalled
2 |
3 | param($installPath, $toolsPath, $package, $project)
4 |
5 | # $installPath is the path to the folder where the package is installed.
6 | # $toolsPath is the path to the tools directory in the folder where the package is installed.
7 | # $package is a reference to the package object.
8 | # $project is a reference to the project the package was installed to.
9 |
--------------------------------------------------------------------------------
/TypeConverter.Tests/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/TypeConverter.Tests/Caching/CacheManagerTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | using FluentAssertions;
5 |
6 | using TypeConverter.Attempts;
7 | using TypeConverter.Caching;
8 |
9 | using Xunit;
10 |
11 | namespace TypeConverter.Tests.Caching
12 | {
13 | public class ConverterCacheTests
14 | {
15 | [Fact]
16 | public void ShouldNotGetCachedValueWhenEmpty()
17 | {
18 | // Arrange
19 | var cacheManager = new CacheManager();
20 | cacheManager.IsCacheEnabled = true;
21 |
22 | // Act
23 | var cacheResult = cacheManager.TryGetCachedValue(typeof(int), typeof(double));
24 |
25 | // Assert
26 | cacheResult.ConversionAttempt.Should().BeNull();
27 | cacheResult.IsCached.Should().BeFalse();
28 | }
29 |
30 | [Fact]
31 | public void ShouldGetCachedValue()
32 | {
33 | // Arrange
34 | var cacheManager = new CacheManager();
35 | cacheManager.IsCacheEnabled = true;
36 |
37 | // Act
38 | cacheManager.UpdateCache(typeof(int), typeof(double), isConvertable: true, conversionAttempt: new CastAttempt());
39 |
40 | // Assert
41 | var cacheResult = cacheManager.TryGetCachedValue(typeof(int), typeof(double));
42 |
43 | cacheResult.ConversionAttempt.Should().BeOfType(typeof(CastAttempt));
44 | cacheResult.IsCached.Should().BeTrue();
45 | }
46 |
47 | [Fact]
48 | public void ShouldNotGetCachedValueIfCachingIsDisabled()
49 | {
50 | // Arrange
51 | var cacheManager = new CacheManager();
52 | cacheManager.IsCacheEnabled = true;
53 | cacheManager.UpdateCache(typeof(int), typeof(double), isConvertable: true, conversionAttempt: new CastAttempt());
54 | cacheManager.IsCacheEnabled = false;
55 |
56 | // Act
57 | var cacheResult = cacheManager.TryGetCachedValue(typeof(int), typeof(double));
58 |
59 | // Assert
60 | cacheResult.ConversionAttempt.Should().BeNull();
61 | cacheResult.IsCached.Should().BeFalse();
62 | }
63 |
64 | [Fact]
65 | public void ShouldResetCache()
66 | {
67 | // Arrange
68 | var cacheManager = new CacheManager();
69 | cacheManager.IsCacheEnabled = true;
70 |
71 | cacheManager.UpdateCache(typeof(int), typeof(double), isConvertable: true, conversionAttempt: new CastAttempt());
72 |
73 | var cacheResultBeforeReset = cacheManager.TryGetCachedValue(typeof(int), typeof(double));
74 |
75 | // Act
76 | cacheManager.Reset();
77 |
78 | // Assert
79 | var cacheResultAfterReset = cacheManager.TryGetCachedValue(typeof(int), typeof(double));
80 |
81 | cacheResultBeforeReset.ConversionAttempt.Should().BeOfType(typeof(CastAttempt));
82 | cacheResultBeforeReset.IsCached.Should().BeTrue();
83 |
84 | cacheResultAfterReset.ConversionAttempt.Should().BeNull();
85 | cacheResultAfterReset.IsCached.Should().BeFalse();
86 | }
87 |
88 | [Fact]
89 | public void ShouldLimitCacheToMaxCacheSize()
90 | {
91 | // Arrange
92 | var cacheManager = new CacheManager();
93 | cacheManager.IsCacheEnabled = true;
94 | cacheManager.MaxCacheSize = 3;
95 | cacheManager.IsMaxCacheSizeEnabled = true;
96 |
97 | // Seed cache with some data
98 | cacheManager.UpdateCache(typeof(int), typeof(double), isConvertable: true, conversionAttempt: new CastAttempt());
99 | cacheManager.UpdateCache(typeof(int), typeof(string), isConvertable: true, conversionAttempt: new CastAttempt());
100 | cacheManager.UpdateCache(typeof(int), typeof(long), isConvertable: true, conversionAttempt: new CastAttempt());
101 |
102 | // Perform some read actions to weight the data
103 | for (int i = 0; i < 3; i++)
104 | {
105 | cacheManager.TryGetCachedValue(typeof(int), typeof(double));
106 | cacheManager.TryGetCachedValue(typeof(int), typeof(string));
107 | }
108 |
109 | // Act: Insert new data
110 | cacheManager.UpdateCache(typeof(int), typeof(decimal), isConvertable: true, conversionAttempt: new CastAttempt());
111 |
112 | // Assert: Check what data has to leave the buffer
113 | var cacheResultIntDecimal = cacheManager.TryGetCachedValue(typeof(int), typeof(decimal));
114 | cacheResultIntDecimal.IsCached.Should().BeTrue();
115 |
116 | var cacheResultIntLong = cacheManager.TryGetCachedValue(typeof(int), typeof(long));
117 | cacheResultIntLong.IsCached.Should().BeFalse();
118 | }
119 |
120 | [Fact]
121 | public void ShouldDisableCacheSizeLimit()
122 | {
123 | // Arrange
124 | var cacheManager = new CacheManager();
125 | cacheManager.IsCacheEnabled = true;
126 | cacheManager.MaxCacheSize = 3;
127 | cacheManager.IsMaxCacheSizeEnabled = false;
128 |
129 | // Seed cache with some data
130 | cacheManager.UpdateCache(typeof(int), typeof(double), isConvertable: true, conversionAttempt: new CastAttempt());
131 | cacheManager.UpdateCache(typeof(int), typeof(string), isConvertable: true, conversionAttempt: new CastAttempt());
132 | cacheManager.UpdateCache(typeof(int), typeof(long), isConvertable: true, conversionAttempt: new CastAttempt());
133 |
134 | // Act: Insert new data
135 | cacheManager.UpdateCache(typeof(int), typeof(decimal), isConvertable: true, conversionAttempt: new CastAttempt());
136 |
137 | // Assert: Check what data has to leave the buffer
138 | var cacheResultIntDecimal = cacheManager.TryGetCachedValue(typeof(int), typeof(decimal));
139 | cacheResultIntDecimal.IsCached.Should().BeTrue();
140 |
141 | var cacheResultIntLong = cacheManager.TryGetCachedValue(typeof(int), typeof(long));
142 | cacheResultIntLong.IsCached.Should().BeTrue();
143 | }
144 |
145 |
146 | [Fact]
147 | public void ShouldReduceCacheSizeWhenMaxCacheSizeIsEnabled()
148 | {
149 | // Arrange
150 | var cacheManager = new CacheManager();
151 | cacheManager.IsCacheEnabled = true;
152 | cacheManager.MaxCacheSize = 3;
153 | cacheManager.IsMaxCacheSizeEnabled = false;
154 |
155 | cacheManager.UpdateCache(typeof(int), typeof(double), isConvertable: true, conversionAttempt: new CastAttempt());
156 | cacheManager.UpdateCache(typeof(int), typeof(string), isConvertable: true, conversionAttempt: new CastAttempt());
157 | cacheManager.UpdateCache(typeof(int), typeof(long), isConvertable: true, conversionAttempt: new CastAttempt());
158 | cacheManager.UpdateCache(typeof(int), typeof(decimal), isConvertable: true, conversionAttempt: new CastAttempt());
159 |
160 | // Perform some read actions to weight the data
161 | for (int i = 0; i < 3; i++)
162 | {
163 | cacheManager.TryGetCachedValue(typeof(int), typeof(double));
164 | cacheManager.TryGetCachedValue(typeof(int), typeof(string));
165 | }
166 | cacheManager.TryGetCachedValue(typeof(int), typeof(decimal));
167 |
168 | // Act
169 | cacheManager.IsMaxCacheSizeEnabled = true;
170 |
171 | // Assert
172 | var cacheResultIntDecimal = cacheManager.TryGetCachedValue(typeof(int), typeof(decimal));
173 | cacheResultIntDecimal.IsCached.Should().BeTrue();
174 |
175 | var cacheResultIntLong = cacheManager.TryGetCachedValue(typeof(int), typeof(long));
176 | cacheResultIntLong.IsCached.Should().BeFalse();
177 | }
178 | }
179 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/ConverterRegistryExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using FluentAssertions;
4 |
5 | using TypeConverter.Converters;
6 | using TypeConverter.Extensions;
7 |
8 | using Xunit;
9 |
10 | namespace TypeConverter.Tests
11 | {
12 | public class ConverterRegistryExtensionsTests
13 | {
14 | [Fact]
15 | public void ShouldRegisterMultipleConvertables()
16 | {
17 | // Arrange
18 | const string InputUriString = "http://www.superdev.ch/";
19 | const string InputBoolString = "True";
20 | IConverterRegistry converterRegistry = new ConverterRegistry();
21 | IConvertable[] converters = { new StringToUriConverter(), new StringToBoolConverter() };
22 | converterRegistry.RegisterConverters(converters);
23 |
24 | // Act
25 | var outputUri = converterRegistry.Convert(InputUriString);
26 | var outputUriString = converterRegistry.Convert(outputUri);
27 |
28 | var outputBool = converterRegistry.Convert(InputBoolString);
29 | var outputBoolString = converterRegistry.Convert(outputBool);
30 |
31 |
32 | // Assert
33 | outputUriString.Should().Be(InputUriString);
34 | outputBoolString.Should().Be(InputBoolString);
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/ConverterRegistryTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | using FluentAssertions;
5 | using TypeConverter.Converters;
6 | using TypeConverter.Exceptions;
7 | using TypeConverter.Tests.Stubs;
8 | using TypeConverter.Tests.Utils;
9 |
10 | using Xunit;
11 | using Xunit.Abstractions;
12 |
13 | namespace TypeConverter.Tests
14 | {
15 | public class ConverterRegistryTests
16 | {
17 | private readonly ITestOutputHelper testOutputHelper;
18 |
19 | public ConverterRegistryTests(ITestOutputHelper testOutputHelper)
20 | {
21 | this.testOutputHelper = testOutputHelper;
22 | }
23 |
24 | #region IConvertable Tests
25 |
26 | [Fact]
27 | public void ShouldThrowConversionNotSupportedExceptionWhenTryingToConvertWithoutValidRegistration()
28 | {
29 | // Arrange
30 | const string InputString = "http://www.superdev.ch/";
31 | IConverterRegistry converterRegistry = new ConverterRegistry();
32 |
33 | // Act
34 | Action action = () => converterRegistry.Convert(typeof(string), typeof(Uri), InputString);
35 |
36 | // Assert
37 | Assert.Throws(action);
38 | }
39 |
40 | [Fact]
41 | public void ShouldThrowConversionNotSupportedExceptionWhenTryingToConvertGenericWithoutValidRegistration()
42 | {
43 | // Arrange
44 | const string InputString = "http://www.superdev.ch/";
45 | IConverterRegistry converterRegistry = new ConverterRegistry();
46 |
47 | // Act
48 | Action action = () => converterRegistry.Convert(InputString);
49 |
50 | // Assert
51 | Assert.Throws(action);
52 | }
53 |
54 | [Fact]
55 | public void ShouldThrowConversionNotSupportedExceptionWhenWrongConversionWayIsConfigured()
56 | {
57 | // Arrange
58 | const string InputString = "http://www.superdev.ch/";
59 | IConverterRegistry converterRegistry = new ConverterRegistry();
60 | converterRegistry.RegisterConverter(() => new StringToUriConverter());
61 |
62 | // Act
63 | Action action = () => converterRegistry.Convert(typeof(string), typeof(Uri), InputString);
64 |
65 | // Assert
66 | Assert.Throws(action);
67 | }
68 |
69 | [Fact]
70 | public void ShouldRegisterConverterImplicitly()
71 | {
72 | // Arrange
73 | const string InputString = "http://www.superdev.ch/";
74 | var stringToUriConverter = new StringToUriConverter();
75 | IConverterRegistry converterRegistry = new ConverterRegistry();
76 | converterRegistry.RegisterConverter(stringToUriConverter);
77 |
78 | // Act
79 | var convertedObject = converterRegistry.Convert(InputString);
80 | var outputString = converterRegistry.Convert(convertedObject);
81 |
82 | // Assert
83 | convertedObject.Should().NotBeNull();
84 | convertedObject.Should().BeOfType();
85 | convertedObject.As().AbsoluteUri.Should().Be(InputString);
86 |
87 | outputString.Should().NotBeNullOrEmpty();
88 | outputString.Should().Be(InputString);
89 | }
90 |
91 | [Fact]
92 | public void ShouldConvertUsingConverterType()
93 | {
94 | // Arrange
95 | const string InputString = "http://www.superdev.ch/";
96 | Type converterType = typeof(StringToUriConverter);
97 | IConverterRegistry converterRegistry = new ConverterRegistry();
98 | converterRegistry.RegisterConverter(converterType);
99 | converterRegistry.RegisterConverter(converterType);
100 |
101 | // Act
102 | var convertedObject = converterRegistry.Convert(InputString);
103 | var outputString = converterRegistry.Convert(convertedObject);
104 |
105 | // Assert
106 | convertedObject.Should().NotBeNull();
107 | convertedObject.Should().BeOfType();
108 | convertedObject.As().AbsoluteUri.Should().Be(InputString);
109 |
110 | outputString.Should().NotBeNullOrEmpty();
111 | outputString.Should().Be(InputString);
112 | }
113 |
114 | [Fact]
115 | public void ShouldConvertIfSourceTypeEqualsTargetType()
116 | {
117 | // Arrange
118 | var inputUri = new Uri("http://www.superdev.ch/");
119 | IConverterRegistry converterRegistry = new ConverterRegistry();
120 |
121 | // Act
122 | var outputUri = (Uri)converterRegistry.Convert(typeof(Uri), typeof(Uri), inputUri);
123 |
124 | // Assert
125 | outputUri.Should().NotBeNull();
126 | outputUri.Should().Be(inputUri);
127 | }
128 |
129 | [Fact]
130 | public void ShouldConvertUsingGenericSourceTypeAndNongenericTargetType()
131 | {
132 | // Arrange
133 | const string InputString = "http://www.superdev.ch/";
134 | Type converterType = typeof(StringToUriConverter);
135 | IConverterRegistry converterRegistry = new ConverterRegistry();
136 | converterRegistry.RegisterConverter(converterType);
137 | converterRegistry.RegisterConverter(converterType);
138 |
139 | // Act
140 | var convertedObject = (Uri)converterRegistry.Convert(typeof(Uri), InputString);
141 | var outputString = converterRegistry.Convert(typeof(string), convertedObject);
142 |
143 | // Assert
144 | convertedObject.Should().NotBeNull();
145 | convertedObject.Should().BeOfType();
146 | convertedObject.As().AbsoluteUri.Should().Be(InputString);
147 |
148 | outputString.Should().NotBeNull();
149 | outputString.Should().Be(InputString);
150 | }
151 |
152 | [Fact]
153 | public void ShouldConvertUsingGenericTargetTypeAndObjectSourceType()
154 | {
155 | // Arrange
156 | const string InputString = "http://www.superdev.ch/";
157 | Type converterType = typeof(StringToUriConverter);
158 | IConverterRegistry converterRegistry = new ConverterRegistry();
159 | converterRegistry.RegisterConverter(converterType);
160 | converterRegistry.RegisterConverter(converterType);
161 |
162 | // Act
163 | var convertedObject = (Uri)converterRegistry.Convert(InputString);
164 | var outputString = converterRegistry.Convert(convertedObject);
165 |
166 | // Assert
167 | convertedObject.Should().NotBeNull();
168 | convertedObject.Should().BeOfType();
169 | convertedObject.As().AbsoluteUri.Should().Be(InputString);
170 |
171 | outputString.Should().NotBeNull();
172 | outputString.Should().Be(InputString);
173 | }
174 |
175 | [Fact]
176 | public void ShouldReturnDefaultValueWhenTryConvertToReferenceTypeFails()
177 | {
178 | // Arrange
179 | const string InputString = "http://www.superdev.ch/";
180 | IConverterRegistry converterRegistry = new ConverterRegistry();
181 |
182 | // Act
183 | var convertedObject = converterRegistry.TryConvert(InputString, null);
184 |
185 | // Assert
186 | convertedObject.Should().BeNull();
187 | }
188 |
189 | [Fact]
190 | public void ShouldReturnDefaultValueWhenTryConvertToValueTypeFails()
191 | {
192 | // Arrange
193 | TestStruct1 testStruct1 = new TestStruct1 { TestString = Guid.NewGuid().ToString() };
194 | IConverterRegistry converterRegistry = new ConverterRegistry();
195 |
196 | // Act
197 | var convertedObject = converterRegistry.TryConvert(testStruct1, default(Guid));
198 |
199 | // Assert
200 | convertedObject.Should().Be(Guid.Empty);
201 | }
202 |
203 | [Fact]
204 | public void ShouldTryConvertEnumImplicitlyWithGenericMethod()
205 | {
206 | // Arrange
207 | object sourceObject = MyEnum.TestValue;
208 | const MyEnum DefaultValue = default(MyEnum);
209 | IConverterRegistry converterRegistry = new ConverterRegistry();
210 |
211 | // Act
212 | MyEnum convertedObject = converterRegistry.TryConvert(sourceObject, DefaultValue);
213 |
214 | // Assert
215 | convertedObject.Should().Be(sourceObject);
216 | }
217 |
218 | [Fact]
219 | public void ShouldTryConvertEnumImplicitlyWithNonGenericMethod()
220 | {
221 | // Arrange
222 | object sourceObject = MyEnum.TestValue;
223 | const MyEnum DefaultValue = default(MyEnum);
224 | IConverterRegistry converterRegistry = new ConverterRegistry();
225 |
226 | // Act
227 | object convertedObject = converterRegistry.TryConvert(typeof(object), typeof(MyEnum), sourceObject, DefaultValue);
228 |
229 | // Assert
230 | convertedObject.Should().Be(sourceObject);
231 | }
232 |
233 | #endregion
234 |
235 | #region Implicit and explicit cast tests
236 |
237 | [Fact]
238 | public void ShouldConvertIfSourceTypeIsEqualToTargetType()
239 | {
240 | // Arrange
241 | const string InputString = "999";
242 | IConverterRegistry converterRegistry = new ConverterRegistry();
243 |
244 | // Act
245 | var convertedObject = (string)converterRegistry.Convert(typeof(string), typeof(string), InputString);
246 |
247 | // Assert
248 | convertedObject.Should().Be(InputString);
249 | }
250 |
251 | [Fact]
252 | public void ShouldConvertIfTargetTypeIsAssignableFromSourceType()
253 | {
254 | // Arrange
255 | List stringList = new List { "a", "b", "c" };
256 | IConverterRegistry converterRegistry = new ConverterRegistry();
257 |
258 | // Act
259 | var convertedList = (IEnumerable)converterRegistry.Convert(typeof(IEnumerable), stringList);
260 |
261 | // Assert
262 | convertedList.Should().BeEquivalentTo(stringList);
263 | }
264 |
265 | [Fact]
266 | public void ShouldConvertEnumerableToArray()
267 | {
268 | // Arrange
269 | string[] stringArray = { "a", "b", "c" };
270 | IConverterRegistry converterRegistry = new ConverterRegistry();
271 |
272 | // Act
273 | var convertedList = (IEnumerable)converterRegistry.Convert(typeof(IEnumerable), stringArray);
274 |
275 | // Assert
276 | convertedList.Should().BeEquivalentTo(stringArray);
277 | }
278 |
279 | [Fact]
280 | public void ShouldThrowConversionNotSupportedExceptionWhenTryingToConvertArrayToEnumerable()
281 | {
282 | // Arrange
283 | List stringList = new List { "a", "b", "c" };
284 | IConverterRegistry converterRegistry = new ConverterRegistry();
285 |
286 | // Act
287 | Action action = () => converterRegistry.Convert(typeof(string[]), stringList);
288 |
289 | // Assert
290 | Assert.Throws(action);
291 | }
292 |
293 | [Fact]
294 | public void ShouldConvertNullableTypeToValueType()
295 | {
296 | // Arrange
297 | bool? nullableValue = true;
298 | IConverterRegistry converterRegistry = new ConverterRegistry();
299 |
300 | // Act
301 | var valueType = converterRegistry.Convert(nullableValue);
302 |
303 | // Assert
304 | valueType.Should().Be(nullableValue.Value);
305 | }
306 |
307 | [Fact]
308 | public void ShouldConvertValueTypeToNullableType()
309 | {
310 | // Arrange
311 | const bool ValueType = true;
312 | IConverterRegistry converterRegistry = new ConverterRegistry();
313 |
314 | // Act
315 | var nullableValue = converterRegistry.Convert(ValueType);
316 |
317 | // Assert
318 | nullableValue.Should().Be(ValueType);
319 | }
320 |
321 | [Fact]
322 | public void ShouldConvertDoubleToIntegerExplicitly()
323 | {
324 | // Arrange
325 | const double DoubleValue = 999.99d;
326 | IConverterRegistry converterRegistry = new ConverterRegistry();
327 |
328 | // Act
329 | var convertedValue = converterRegistry.Convert(DoubleValue);
330 |
331 | // Assert
332 | convertedValue.Should().Be((int)DoubleValue);
333 | }
334 |
335 | [Fact]
336 | public void ShouldConvertIntegerToDoubleExplicitly()
337 | {
338 | // Arrange
339 | //const double DoubleValue = 0.0d;
340 | int IntegerValue = 999;
341 | IConverterRegistry converterRegistry = new ConverterRegistry();
342 |
343 |
344 | // Act
345 | var convertedValue = converterRegistry.TryConvert((object)(int)999, (int)0);
346 | var convertedValue2 = converterRegistry.TryConvert((object)(int)999, (double)0);
347 |
348 | var convertedValue3 = converterRegistry.TryConvert((object)(int)999, (int)0);
349 | var convertedValue4 = converterRegistry.TryConvert((object)(int)999, (double)0);
350 |
351 | // Assert
352 | convertedValue.Should().Be(IntegerValue);
353 | }
354 |
355 | [Fact]
356 | public void ShouldConvertULongToDecimalImplicitly()
357 | {
358 | // Arrange
359 | const ulong UlongValue = 999UL;
360 | IConverterRegistry converterRegistry = new ConverterRegistry();
361 |
362 | // Act
363 | var convertedValue = converterRegistry.Convert(UlongValue);
364 |
365 | // Assert
366 | convertedValue.Should().Be(Convert.ToDecimal(UlongValue));
367 | }
368 |
369 | [Fact]
370 | public void ShouldConvertFromOpenGenericTypeToGenericType()
371 | {
372 | // Arrange
373 | IGenericOperators inputValue = new Operators();
374 | IConverterRegistry converterRegistry = new ConverterRegistry();
375 |
376 | // Act
377 | var convertedValue = converterRegistry.Convert(typeof(IGenericOperators<>), typeof(IGenericOperators), inputValue);
378 |
379 | // Assert
380 | convertedValue.Should().Be(inputValue);
381 | }
382 |
383 | [Fact]
384 | public void ShouldThrowConversionNotSupportedExceptionWhenTryingToConvertToOpenGenericType()
385 | {
386 | // Arrange
387 | IGenericOperators value = new Operators();
388 | IConverterRegistry converterRegistry = new ConverterRegistry();
389 |
390 | // Act
391 | Action action = () => converterRegistry.Convert(typeof(IGenericOperators), typeof(IGenericOperators<>), value);
392 |
393 | // Assert
394 | Assert.Throws(action);
395 | }
396 |
397 | [Fact]
398 | public void ShouldRunAllDefaultCasts()
399 | {
400 | IConverterRegistry converterRegistry = new ConverterRegistry();
401 |
402 | CastTestRunner.RunTests((testCase) =>
403 | {
404 | // Arrange
405 | var value = CastTestRunner.GenerateValueForType(testCase.SourceType);
406 | var generatedTestSuccessful = CastTestRunner.CastValueWithGeneratedCode(value, testCase.SourceType, testCase.TargetType, testCase.CastFlag);
407 |
408 | // Act
409 | var convertedObject = converterRegistry.TryConvert(
410 | sourceType: testCase.SourceType,
411 | targetType: testCase.TargetType,
412 | value: value,
413 | defaultReturnValue: null);
414 |
415 | // Assert
416 | var castResult = new CastResult(convertedObject, testCase.CastFlag);
417 | var isSuccessful = CastTestRunner.AreEqual(
418 | this.testOutputHelper,
419 | testCase.SourceType,
420 | testCase.TargetType,
421 | generatedTestSuccessful,
422 | castResult,
423 | testCase.CastFlag);
424 |
425 | return isSuccessful;
426 | });
427 | }
428 |
429 | #endregion
430 |
431 | #region Enum Parse Tests
432 |
433 | [Fact]
434 | public void ShouldConvertEnumsImplicitly()
435 | {
436 | // Arrange
437 | string inputString = MyEnum.TestValue.ToString();
438 | IConverterRegistry converterRegistry = new ConverterRegistry();
439 |
440 | // Act
441 | var convertedObject = (MyEnum)converterRegistry.Convert(typeof(MyEnum), inputString);
442 | var outputString = converterRegistry.Convert(typeof(string), convertedObject);
443 |
444 | // Assert
445 | convertedObject.Should().NotBeNull();
446 | convertedObject.Should().BeOfType();
447 | convertedObject.Should().Be(MyEnum.TestValue);
448 |
449 | outputString.Should().NotBeNull();
450 | outputString.Should().Be(inputString);
451 | }
452 |
453 | [Fact]
454 | public void ShouldConvertEnumsImplicitlyWithGenerics()
455 | {
456 | // Arrange
457 | string inputString = MyEnum.TestValue.ToString();
458 | IConverterRegistry converterRegistry = new ConverterRegistry();
459 |
460 | // Act
461 | var convertedObject = converterRegistry.Convert(inputString);
462 | var outputString = converterRegistry.Convert(typeof(string), convertedObject);
463 |
464 | // Assert
465 | convertedObject.Should().NotBeNull();
466 | convertedObject.Should().BeOfType();
467 | convertedObject.Should().Be(MyEnum.TestValue);
468 |
469 | outputString.Should().NotBeNull();
470 | outputString.Should().Be(inputString);
471 | }
472 |
473 | [Fact]
474 | public void ShouldConvertEnumsExplicitly()
475 | {
476 | // Arrange
477 | string inputString = MyEnum.TestValue.ToString();
478 | IConverterRegistry converterRegistry = new ConverterRegistry();
479 | converterRegistry.RegisterConverter(() => new MyEnumConverter());
480 | converterRegistry.RegisterConverter(() => new MyEnumConverter());
481 |
482 | // Act
483 | var convertedObject = (MyEnum)converterRegistry.Convert(inputString);
484 | var outputString = converterRegistry.Convert(convertedObject);
485 |
486 | // Assert
487 | convertedObject.Should().NotBeNull();
488 | convertedObject.Should().BeOfType();
489 | convertedObject.Should().Be(MyEnum.TestValue);
490 |
491 | outputString.Should().NotBeNull();
492 | outputString.Should().Be(inputString);
493 | }
494 |
495 | #endregion
496 |
497 | #region ChangeType Tests
498 |
499 | [Fact]
500 | public void ShouldConvertUsingChangeType()
501 | {
502 | // Arrange
503 | bool? nullableBool = true;
504 | string valueTypeString = nullableBool.ToString();
505 | IConverterRegistry converterRegistry = new ConverterRegistry();
506 |
507 | // Act
508 | var nullableValue = converterRegistry.Convert(valueTypeString);
509 |
510 | // Assert
511 | nullableValue.Should().Be(nullableBool.Value);
512 | }
513 |
514 | [Fact]
515 | public void ShouldConvertUsingChangeTypeMethodFromStringToInt()
516 | {
517 | // Arrange
518 | const string InputString = "999";
519 | IConverterRegistry converterRegistry = new ConverterRegistry();
520 |
521 | // Act
522 | var convertedObject = (int)converterRegistry.Convert(typeof(int), InputString);
523 | var outputString = converterRegistry.Convert(typeof(string), convertedObject);
524 |
525 | // Assert
526 | convertedObject.Should().Be(999);
527 |
528 | outputString.Should().NotBeNull();
529 | outputString.Should().Be(InputString);
530 | }
531 |
532 | [Fact]
533 | public void ShouldConvertUsingChangeTypeMethodFromStringToBool()
534 | {
535 | // Arrange
536 | const string InputString = "True";
537 | IConverterRegistry converterRegistry = new ConverterRegistry();
538 |
539 | // Act
540 | var convertedObject = (bool)converterRegistry.Convert(typeof(bool), InputString);
541 | var outputString = converterRegistry.Convert(typeof(string), convertedObject);
542 |
543 | // Assert
544 | convertedObject.Should().BeTrue();
545 |
546 | outputString.Should().NotBeNull();
547 | outputString.Should().Be(InputString);
548 | }
549 | #endregion
550 |
551 | #region String Parse Tests
552 | [Fact]
553 | public void ShouldConvertUsingStringParse()
554 | {
555 | // Arrange
556 | const string InputString = "http://www.thomasgalliker.ch/";
557 | Uri inputUri = new Uri(InputString);
558 |
559 | IConverterRegistry converterRegistry = new ConverterRegistry();
560 |
561 | // Act
562 | var uriAsString = converterRegistry.Convert(inputUri);
563 |
564 | // Assert
565 | uriAsString.Should().Be(InputString);
566 | }
567 | #endregion
568 |
569 | #region Mapping Tests
570 | [Fact]
571 | public void ShouldConvertUsingRegisterMapping()
572 | {
573 | // Arrange
574 | var model = new ModelA { Name = "Thomas", Age = 30 };
575 |
576 | IConverterRegistry converterRegistry = new ConverterRegistry();
577 | converterRegistry.RegisterMapping(src => src.Name, dest => dest.Name);
578 | converterRegistry.RegisterMapping(src => src.Age, dest => dest.Age);
579 |
580 | // Act
581 | var viewModelA = converterRegistry.Convert(model);
582 |
583 | // Assert
584 | viewModelA.Name.Should().Be("Thomas");
585 | viewModelA.Age.Should().Be(30);
586 | }
587 | #endregion
588 |
589 | #region General Tests
590 | [Fact]
591 | public void ShouldResetRegistrations()
592 | {
593 | // Arrange
594 | const string InputString = "http://www.thomasgalliker.ch";
595 | int numberOfConvertCalls = 0;
596 | IConverterRegistry converterRegistry = new ConverterRegistry();
597 | var converter = new TestConverter(() => { numberOfConvertCalls++; });
598 | converterRegistry.RegisterConverter(() => converter);
599 |
600 | // Act
601 | var convertedInputStringBeforeReset = converterRegistry.TryConvert(InputString, null);
602 |
603 | converterRegistry.Reset();
604 |
605 | var convertedInputStringAfterReset = converterRegistry.TryConvert(InputString, null);
606 |
607 | // Assert
608 | numberOfConvertCalls.Should().Be(1);
609 | convertedInputStringBeforeReset.Should().Be(InputString);
610 | convertedInputStringAfterReset.Should().BeNull();
611 | }
612 |
613 | private class TestConverter : IConvertable
614 | {
615 | private readonly Action convert;
616 |
617 | public TestConverter(Action convert)
618 | {
619 | this.convert = convert;
620 | }
621 |
622 | public Uri Convert(string value)
623 | {
624 | this.convert();
625 | return new Uri(value);
626 | }
627 | }
628 | #endregion
629 | }
630 |
631 | public class ViewModelA
632 | {
633 | public string Name { get; set; }
634 |
635 | public int Age { get; set; }
636 | }
637 |
638 | public class ModelA
639 | {
640 | public string Name { get; set; }
641 |
642 | public int Age { get; set; }
643 | }
644 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToBoolConverterTests.cs:
--------------------------------------------------------------------------------
1 | using FluentAssertions;
2 |
3 | using TypeConverter.Converters;
4 |
5 | using Xunit;
6 |
7 | namespace TypeConverter.Tests.Converters
8 | {
9 | public class StringToBoolConverterTests
10 | {
11 | [Fact]
12 | public void ShouldConvertBothWays()
13 | {
14 | // Arrange
15 | const string InputString = "True";
16 | IConverterRegistry converterRegistry = new ConverterRegistry();
17 | converterRegistry.RegisterConverter(() => new StringToBoolConverter());
18 | converterRegistry.RegisterConverter(() => new StringToBoolConverter());
19 |
20 | // Act
21 | var convertedObject = converterRegistry.Convert(InputString);
22 | var outputString = converterRegistry.Convert(convertedObject);
23 |
24 | // Assert
25 | convertedObject.Should().BeTrue();
26 |
27 | outputString.Should().NotBeNullOrEmpty();
28 | outputString.Should().Be(InputString);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToDateTimeConverterTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using FluentAssertions;
4 |
5 | using TypeConverter.Converters;
6 |
7 | using Xunit;
8 |
9 | namespace TypeConverter.Tests.Converters
10 | {
11 | public class StringToDateTimeConverterTests
12 | {
13 | [Fact]
14 | public void ShouldConvertDateTimeToString_Universal()
15 | {
16 | // Arrange
17 | DateTime intputDateTime = new DateTime(1999, 12, 31, 23, 59, 59, DateTimeKind.Utc);
18 | IConverterRegistry converterRegistry = new ConverterRegistry();
19 | converterRegistry.RegisterConverter(() => new StringToDateTimeConverter());
20 |
21 | // Act
22 | var outputString = converterRegistry.Convert(intputDateTime);
23 |
24 | // Assert
25 | outputString.Should().Be("1999-12-31T23:59:59.0000000Z");
26 | }
27 |
28 | [Fact]
29 | public void ShouldConvertStringToDateTime_Universal()
30 | {
31 | // Arrange
32 | const string InputString = "1999-12-31T23:59:59.0000000Z";
33 | IConverterRegistry converterRegistry = new ConverterRegistry();
34 | converterRegistry.RegisterConverter(() => new StringToDateTimeConverter());
35 |
36 | // Act
37 | var outputDateTime = converterRegistry.Convert(InputString);
38 |
39 | // Assert
40 | outputDateTime.Should().Be(new DateTime(1999, 12, 31, 23, 59, 59, DateTimeKind.Utc));
41 | outputDateTime.Kind.Should().Be(DateTimeKind.Utc);
42 | }
43 |
44 | [Fact]
45 | public void ShouldConvertDateTimeToString_Local()
46 | {
47 | // Arrange
48 | DateTime intputDateTime = new DateTime(1999, 12, 31, 23, 59, 59, DateTimeKind.Local);
49 | IConverterRegistry converterRegistry = new ConverterRegistry();
50 | converterRegistry.RegisterConverter(() => new StringToDateTimeConverter());
51 |
52 | // Act
53 | var outputString = converterRegistry.Convert(intputDateTime);
54 |
55 | // Assert
56 | outputString.Should().Be("1999-12-31T23:59:59.0000000+01:00");
57 | }
58 |
59 | [Fact]
60 | public void ShouldConvertStringToDateTime_Local()
61 | {
62 | // Arrange
63 | const string InputString = "1999-12-31T23:59:59.0000000+01:00";
64 | IConverterRegistry converterRegistry = new ConverterRegistry();
65 | converterRegistry.RegisterConverter(() => new StringToDateTimeConverter());
66 |
67 | // Act
68 | var outputDateTime = converterRegistry.Convert(InputString);
69 |
70 | // Assert
71 | outputDateTime.Should().Be(new DateTime(1999, 12, 31, 23, 59, 59, DateTimeKind.Local));
72 | outputDateTime.Kind.Should().Be(DateTimeKind.Local);
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToDateTimeOffsetConverterTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using FluentAssertions;
4 |
5 | using TypeConverter.Converters;
6 |
7 | using Xunit;
8 |
9 | namespace TypeConverter.Tests.Converters
10 | {
11 | public class StringToDateTimeOffsetConverterTests
12 | {
13 | [Fact]
14 | public void ShouldConvertDateTimeToString_Universal()
15 | {
16 | // Arrange
17 | DateTimeOffset intputDateTime = new DateTimeOffset(new DateTime(1999, 12, 31, 23, 59, 59, DateTimeKind.Utc));
18 | IConverterRegistry converterRegistry = new ConverterRegistry();
19 | converterRegistry.RegisterConverter(() => new StringToDateTimeOffsetConverter());
20 |
21 | // Act
22 | var outputString = converterRegistry.Convert(intputDateTime);
23 |
24 | // Assert
25 | outputString.Should().Be("1999-12-31T23:59:59.0000000+00:00");
26 | }
27 |
28 | [Fact]
29 | public void ShouldConvertStringToDateTime_Universal()
30 | {
31 | // Arrange
32 | const string InputString = "1999-12-31T23:59:59.0000000+00:00";
33 | IConverterRegistry converterRegistry = new ConverterRegistry();
34 | converterRegistry.RegisterConverter(() => new StringToDateTimeOffsetConverter());
35 |
36 | // Act
37 | var outputDateTime = converterRegistry.Convert(InputString);
38 |
39 | // Assert
40 | outputDateTime.Should().Be(new DateTimeOffset(new DateTime(1999, 12, 31, 23, 59, 59, DateTimeKind.Utc)));
41 | }
42 |
43 | [Fact]
44 | public void ShouldConvertDateTimeToString_Local()
45 | {
46 | // Arrange
47 | DateTimeOffset intputDateTime = new DateTimeOffset(new DateTime(1999, 12, 31, 23, 59, 59), new TimeSpan(-7, 0, 0));
48 | IConverterRegistry converterRegistry = new ConverterRegistry();
49 | converterRegistry.RegisterConverter(() => new StringToDateTimeOffsetConverter());
50 |
51 | // Act
52 | var outputString = converterRegistry.Convert(intputDateTime);
53 |
54 | // Assert
55 | outputString.Should().Be("1999-12-31T23:59:59.0000000-07:00");
56 | }
57 |
58 | [Fact]
59 | public void ShouldConvertStringToDateTime_Local()
60 | {
61 | // Arrange
62 | const string InputString = "1999-12-31T23:59:59.0000000-07:00";
63 | IConverterRegistry converterRegistry = new ConverterRegistry();
64 | converterRegistry.RegisterConverter(() => new StringToDateTimeOffsetConverter());
65 |
66 | // Act
67 | var outputDateTime = converterRegistry.Convert(InputString);
68 |
69 | // Assert
70 | outputDateTime.Should().Be(new DateTimeOffset(new DateTime(1999, 12, 31, 23, 59, 59), new TimeSpan(-7, 0, 0)));
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToDecimalConverterTests.cs:
--------------------------------------------------------------------------------
1 | using FluentAssertions;
2 |
3 | using TypeConverter.Converters;
4 |
5 | using Xunit;
6 |
7 | namespace TypeConverter.Tests.Converters
8 | {
9 | public class StringToDecimalConverterTests
10 | {
11 | [Fact]
12 | public void ShouldConvertDecimalMaxValueToString()
13 | {
14 | // Arrange
15 | decimal inputDecimal = decimal.MaxValue;
16 | IConverterRegistry converterRegistry = new ConverterRegistry();
17 | converterRegistry.RegisterConverter(() => new StringToDecimalConverter());
18 |
19 | // Act
20 | var outputString = converterRegistry.Convert(inputDecimal);
21 |
22 | // Assert
23 | outputString.Should().Be("79228162514264337593543950335");
24 | }
25 |
26 | [Fact]
27 | public void ShouldConvertDecimalMinValueToString()
28 | {
29 | // Arrange
30 | decimal inputDecimal = decimal.MinValue;
31 | IConverterRegistry converterRegistry = new ConverterRegistry();
32 | converterRegistry.RegisterConverter(() => new StringToDecimalConverter());
33 |
34 | // Act
35 | var outputString = converterRegistry.Convert(inputDecimal);
36 |
37 | // Assert
38 | outputString.Should().Be("-79228162514264337593543950335");
39 | }
40 |
41 | [Fact]
42 | public void ShouldConvertStringToDecimalMaxValue()
43 | {
44 | // Arrange
45 | const string InputString = "79228162514264337593543950335";
46 | IConverterRegistry converterRegistry = new ConverterRegistry();
47 | converterRegistry.RegisterConverter(() => new StringToDecimalConverter());
48 |
49 | // Act
50 | var outputDecimal = converterRegistry.Convert(InputString);
51 |
52 | // Assert
53 | outputDecimal.Should().Be(decimal.MaxValue);
54 | }
55 |
56 | [Fact]
57 | public void ShouldConvertStringToDecimalMinValue()
58 | {
59 | // Arrange
60 | const string InputString = "-79228162514264337593543950335";
61 | IConverterRegistry converterRegistry = new ConverterRegistry();
62 | converterRegistry.RegisterConverter(() => new StringToDecimalConverter());
63 |
64 | // Act
65 | var outputDecimal = converterRegistry.Convert(InputString);
66 |
67 | // Assert
68 | outputDecimal.Should().Be(decimal.MinValue);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToDoubleConverterTests.cs:
--------------------------------------------------------------------------------
1 | using FluentAssertions;
2 |
3 | using TypeConverter.Converters;
4 |
5 | using Xunit;
6 |
7 | namespace TypeConverter.Tests.Converters
8 | {
9 | public class StringToDoubleConverterTests
10 | {
11 | [Fact]
12 | public void ShouldConvertDoubleMaxValueToString()
13 | {
14 | // Arrange
15 | double inputDouble = double.MaxValue;
16 | IConverterRegistry converterRegistry = new ConverterRegistry();
17 | converterRegistry.RegisterConverter(() => new StringToDoubleConverter());
18 |
19 | // Act
20 | var outputString = converterRegistry.Convert(inputDouble);
21 |
22 | // Assert
23 | outputString.Should().Be("1.7976931348623157E+308");
24 | }
25 |
26 | [Fact]
27 | public void ShouldConvertDoubleMinValueToString()
28 | {
29 | // Arrange
30 | double inputDouble = double.MinValue;
31 | IConverterRegistry converterRegistry = new ConverterRegistry();
32 | converterRegistry.RegisterConverter(() => new StringToDoubleConverter());
33 |
34 | // Act
35 | var outputString = converterRegistry.Convert(inputDouble);
36 |
37 | // Assert
38 | outputString.Should().Be("-1.7976931348623157E+308");
39 | }
40 |
41 | [Fact]
42 | public void ShouldConvertStringToDoubleMaxValue()
43 | {
44 | // Arrange
45 | const string InputString = "1.7976931348623157E+308";
46 | IConverterRegistry converterRegistry = new ConverterRegistry();
47 | converterRegistry.RegisterConverter(() => new StringToDoubleConverter());
48 |
49 | // Act
50 | var outputDouble = converterRegistry.Convert(InputString);
51 |
52 | // Assert
53 | outputDouble.Should().Be(double.MaxValue);
54 | }
55 |
56 | [Fact]
57 | public void ShouldConvertStringToDoubleMinValue()
58 | {
59 | // Arrange
60 | const string InputString = "-1.7976931348623157E+308";
61 | IConverterRegistry converterRegistry = new ConverterRegistry();
62 | converterRegistry.RegisterConverter(() => new StringToDoubleConverter());
63 |
64 | // Act
65 | var outputDouble = converterRegistry.Convert(InputString);
66 |
67 | // Assert
68 | outputDouble.Should().Be(double.MinValue);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToFloatConverterTests.cs:
--------------------------------------------------------------------------------
1 | using FluentAssertions;
2 |
3 | using TypeConverter.Converters;
4 |
5 | using Xunit;
6 |
7 | namespace TypeConverter.Tests.Converters
8 | {
9 | public class StringToFloatConverterTests
10 | {
11 | [Fact]
12 | public void ShouldConvertFloatMaxValueToString()
13 | {
14 | // Arrange
15 | float inputFloat = float.MaxValue;
16 | IConverterRegistry converterRegistry = new ConverterRegistry();
17 | converterRegistry.RegisterConverter(() => new StringToFloatConverter());
18 |
19 | // Act
20 | var outputString = converterRegistry.Convert(inputFloat);
21 |
22 | // Assert
23 | outputString.Should().Be("3.40282347E+38");
24 | }
25 |
26 | [Fact]
27 | public void ShouldConvertFloatMinValueToString()
28 | {
29 | // Arrange
30 | float inputFloat = float.MinValue;
31 | IConverterRegistry converterRegistry = new ConverterRegistry();
32 | converterRegistry.RegisterConverter(() => new StringToFloatConverter());
33 |
34 | // Act
35 | var outputString = converterRegistry.Convert(inputFloat);
36 |
37 | // Assert
38 | outputString.Should().Be("-3.40282347E+38");
39 | }
40 |
41 | [Fact]
42 | public void ShouldConvertStringToFloatMaxValue()
43 | {
44 | // Arrange
45 | const string InputString = "3.40282347E+38";
46 | IConverterRegistry converterRegistry = new ConverterRegistry();
47 | converterRegistry.RegisterConverter(() => new StringToFloatConverter());
48 |
49 | // Act
50 | var outputFloat = converterRegistry.Convert(InputString);
51 |
52 | // Assert
53 | outputFloat.Should().Be(float.MaxValue);
54 | }
55 |
56 | [Fact]
57 | public void ShouldConvertStringToFloatMinValue()
58 | {
59 | // Arrange
60 | const string InputString = "-3.40282347E+38";
61 | IConverterRegistry converterRegistry = new ConverterRegistry();
62 | converterRegistry.RegisterConverter(() => new StringToFloatConverter());
63 |
64 | // Act
65 | var outputFloat = converterRegistry.Convert(InputString);
66 |
67 | // Assert
68 | outputFloat.Should().Be(float.MinValue);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToGuidConverterTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using FluentAssertions;
4 |
5 | using TypeConverter.Converters;
6 |
7 | using Xunit;
8 |
9 | namespace TypeConverter.Tests.Converters
10 | {
11 | public class StringToGuidConverterTests
12 | {
13 | [Fact]
14 | public void ShouldConvertFormatBStringToGuid()
15 | {
16 | // Arrange
17 | const string InputString = "{1E20D9BB-D64C-4449-AC1B-36CB690601ED}";
18 | IConverterRegistry converterRegistry = new ConverterRegistry();
19 | converterRegistry.RegisterConverter(() => new StringToGuidConverter());
20 |
21 | // Act
22 | var outputGuid = converterRegistry.Convert(InputString);
23 |
24 | // Assert
25 | outputGuid.Should().Be(new Guid(InputString));
26 | }
27 |
28 | [Fact]
29 | public void ShouldConvertFormatNStringToGuid()
30 | {
31 | // Arrange
32 | const string InputString = "4568CA6400E742BAAA41E76916DE7118";
33 | IConverterRegistry converterRegistry = new ConverterRegistry();
34 | converterRegistry.RegisterConverter(() => new StringToGuidConverter());
35 |
36 | // Act
37 | var outputGuid = converterRegistry.Convert(InputString);
38 |
39 | // Assert
40 | outputGuid.Should().Be(new Guid(InputString));
41 | }
42 |
43 | [Fact]
44 | public void ShouldConvertGuidToBFormatString()
45 | {
46 | // Arrange
47 | var inputGuid = new Guid("83EDDA8A-4538-4BA8-8D40-E82C561CD745");
48 | IConverterRegistry converterRegistry = new ConverterRegistry();
49 | converterRegistry.RegisterConverter(() => new StringToGuidConverter());
50 |
51 | // Act
52 | var outputString = converterRegistry.Convert(inputGuid);
53 |
54 | // Assert
55 | outputString.Should().Be("{83edda8a-4538-4ba8-8d40-e82c561cd745}");
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToIntegerConverterTests.cs:
--------------------------------------------------------------------------------
1 | using FluentAssertions;
2 |
3 | using TypeConverter.Converters;
4 |
5 | using Xunit;
6 |
7 | namespace TypeConverter.Tests.Converters
8 | {
9 | public class StringToIntegerConverterTests
10 | {
11 | [Fact]
12 | public void ShouldConvertBothWays()
13 | {
14 | // Arrange
15 | const string InputString = "999";
16 | IConverterRegistry converterRegistry = new ConverterRegistry();
17 | converterRegistry.RegisterConverter(() => new StringToIntegerConverter());
18 | converterRegistry.RegisterConverter(() => new StringToIntegerConverter());
19 |
20 | // Act
21 | var convertedObject = converterRegistry.Convert(InputString);
22 | var outputString = converterRegistry.Convert(convertedObject);
23 |
24 | // Assert
25 | convertedObject.Should().Be(999);
26 |
27 | outputString.Should().NotBeNullOrEmpty();
28 | outputString.Should().Be(InputString);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Converters/StringToUriConverterTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using FluentAssertions;
4 |
5 | using TypeConverter.Converters;
6 |
7 | using Xunit;
8 |
9 | namespace TypeConverter.Tests.Converters
10 | {
11 | public class StringToUriConverterTests
12 | {
13 | [Fact]
14 | public void ShouldConvertStringToUri()
15 | {
16 | // Arrange
17 | const string InputString = "http://www.superdev.ch/";
18 | IConverterRegistry converterRegistry = new ConverterRegistry();
19 | converterRegistry.RegisterConverter(() => new StringToUriConverter());
20 | converterRegistry.RegisterConverter(() => new StringToUriConverter());
21 |
22 | // Act
23 | var outputUri = converterRegistry.Convert(InputString);
24 |
25 | // Assert
26 | outputUri.Should().NotBeNull();
27 | outputUri.AbsoluteUri.Should().Be(InputString);
28 | }
29 |
30 | [Fact]
31 | public void ShouldConvertUriToString()
32 | {
33 | // Arrange
34 | var inputUri = new Uri("http://www.superdev.ch/");
35 | IConverterRegistry converterRegistry = new ConverterRegistry();
36 | converterRegistry.RegisterConverter(() => new StringToUriConverter());
37 |
38 | // Act
39 | var outputString = converterRegistry.Convert(inputUri);
40 |
41 | // Assert
42 | outputString.Should().Be(inputUri.AbsoluteUri);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Extensions/TypeExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Reflection;
3 |
4 | using FluentAssertions;
5 |
6 | using TypeConverter.Extensions;
7 | using TypeConverter.Tests.Stubs;
8 |
9 | using Xunit;
10 |
11 | namespace TypeConverter.Tests.Extensions
12 | {
13 | public class TypeExtensionsTests
14 | {
15 | [Fact]
16 | public void ShouldReturnAllMethodsOfType()
17 | {
18 | // Arrange
19 | var type = typeof(Operators);
20 |
21 | // Act
22 | var declaredMethods = type.GetDeclaredMethodsRecursively();
23 |
24 | // Assert
25 | declaredMethods.Should().HaveCount(17);
26 | declaredMethods.Count(x => x.Name == "op_Implicit").Should().Be(2);
27 | declaredMethods.Count(x => x.Name == "op_Explicit").Should().Be(3);
28 | }
29 |
30 | [Fact]
31 | public void ShouldReturnAllMethodsOfDerivedType()
32 | {
33 | // Arrange
34 | var type = typeof(DerivedOperators);
35 |
36 | // Act
37 | var declaredMethods = type.GetDeclaredMethodsRecursively();
38 |
39 | // Assert
40 | declaredMethods.Should().HaveCount(20);
41 | declaredMethods.Count(x => x.Name == "op_Implicit").Should().Be(2);
42 | declaredMethods.Count(x => x.Name == "op_Explicit").Should().Be(6);
43 | }
44 |
45 | [Fact]
46 | public void ShouldReturnAllMethodsOfDerivedTypeInfo()
47 | {
48 | // Arrange
49 | var typeInfo = typeof(DerivedOperators).GetTypeInfo();
50 |
51 | // Act
52 | var declaredMethods = typeInfo.GetDeclaredMethodsRecursively();
53 |
54 | // Assert
55 | declaredMethods.Should().HaveCount(20);
56 | declaredMethods.Count(x => x.Name == "op_Implicit").Should().Be(2);
57 | declaredMethods.Count(x => x.Name == "op_Explicit").Should().Be(6);
58 | }
59 |
60 | [Fact]
61 | public void IsSameOrParentShouldDetectSameType()
62 | {
63 | // Arrange
64 | var childTypeInfo = typeof(Operators).GetTypeInfo();
65 | var parentTypeInfo = typeof(Operators).GetTypeInfo();
66 |
67 | // Act
68 | var isSameOrParent = parentTypeInfo.IsSameOrParent(childTypeInfo);
69 |
70 | // Assert
71 | isSameOrParent.Should().BeTrue();
72 | }
73 |
74 | [Fact]
75 | public void IsSameOrParentShouldDetectParent()
76 | {
77 | // Arrange
78 | var childTypeInfo = typeof(DerivedOperators).GetTypeInfo();
79 | var parentTypeInfo = typeof(Operators).GetTypeInfo();
80 |
81 | // Act
82 | var isSameOrParent = parentTypeInfo.IsSameOrParent(childTypeInfo);
83 |
84 | // Assert
85 | isSameOrParent.Should().BeTrue();
86 | }
87 | }
88 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 |
8 | [assembly: AssemblyTitle("TypeConverter.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TypeConverter.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 |
21 | [assembly: ComVisible(false)]
22 |
23 | // The following GUID is for the ID of the typelib if this project is exposed to COM
24 |
25 | [assembly: Guid("7a0d7d00-c346-451f-932d-fc2b8c8518c8")]
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 | // You can specify all the values or you can default the Build and Revision Numbers
35 | // by using the '*' as shown below:
36 | // [assembly: AssemblyVersion("1.0.28")]
37 |
38 | [assembly: AssemblyVersion("1.0.28")]
39 | [assembly: AssemblyFileVersion("1.0.28-pre92")]
40 |
--------------------------------------------------------------------------------
/TypeConverter.Tests/Stubs/DerivedOperators.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TypeConverter.Tests.Stubs
4 | {
5 | public class DerivedOperators : Operators
6 | {
7 | public static explicit operator DateTime(DerivedOperators o)
8 | {
9 | return DateTime.Now;
10 | }
11 |
12 | public static explicit operator Byte(DerivedOperators o)
13 | {
14 | return (byte)0x08;
15 | }
16 |
17 | public static explicit operator Char(DerivedOperators o)
18 | {
19 | return 'X';
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Stubs/MyEnum.cs:
--------------------------------------------------------------------------------
1 | namespace TypeConverter.Tests.Stubs
2 | {
3 | public enum MyEnum
4 | {
5 | Undefined,
6 | TestValue
7 | }
8 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Stubs/MyEnumConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TypeConverter.Tests.Stubs
4 | {
5 | public class MyEnumConverter : IConvertable, IConvertable
6 | {
7 | public MyEnum Convert(string value)
8 | {
9 | return (MyEnum)Enum.Parse(typeof(MyEnum), value);
10 | }
11 |
12 | public string Convert(MyEnum value)
13 | {
14 | return value.ToString();
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Stubs/Operators.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TypeConverter.Tests.Stubs
4 | {
5 | public class Operators : IOperators, IGenericOperators
6 | {
7 | public static implicit operator string(Operators o)
8 | {
9 | return "Operators";
10 | }
11 |
12 | public static implicit operator int(Operators o)
13 | {
14 | return 2;
15 | }
16 |
17 | public static explicit operator decimal?(Operators o)
18 | {
19 | return 3.456m;
20 | }
21 |
22 | public static explicit operator StringSplitOptions(Operators o)
23 | {
24 | return StringSplitOptions.RemoveEmptyEntries;
25 | }
26 |
27 | public static explicit operator Operators2(Operators o)
28 | {
29 | return new Operators2();
30 | }
31 |
32 | public string GenericProperty
33 | {
34 | get
35 | {
36 | return "GenericProperty";
37 | }
38 | }
39 | }
40 |
41 | public interface IOperators
42 | {
43 | }
44 |
45 | public interface IGenericOperators
46 | {
47 | T GenericProperty { get; }
48 | }
49 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Stubs/Operators2.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 |
4 | namespace TypeConverter.Tests.Stubs
5 | {
6 | public class Operators2 : IEquatable
7 | {
8 | public int Value { get { return 999; } }
9 |
10 | public static explicit operator bool(Operators2 o)
11 | {
12 | return false;
13 | }
14 |
15 | public static implicit operator Operators2(DerivedOperators o)
16 | {
17 | return null;
18 | }
19 |
20 | public static explicit operator Operators2(int i)
21 | {
22 | return new Operators2();
23 | }
24 |
25 | public override bool Equals(object obj)
26 | {
27 | return this.Equals(obj as Operators2);
28 | }
29 |
30 | public override int GetHashCode()
31 | {
32 | return this.Value.GetHashCode();
33 | }
34 |
35 | public bool Equals(Operators2 other)
36 | {
37 | return other != null && this.Value == other.Value;
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Stubs/OperatorsStruct.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TypeConverter.Tests.Stubs
4 | {
5 | public struct OperatorsStruct
6 | {
7 | public static implicit operator string(OperatorsStruct o)
8 | {
9 | return "OperatorsStruct";
10 | }
11 |
12 | public static implicit operator int(OperatorsStruct o)
13 | {
14 | return 1;
15 | }
16 |
17 | public static explicit operator decimal?(OperatorsStruct o)
18 | {
19 | return 1.0m;
20 | }
21 |
22 | public static explicit operator StringSplitOptions(OperatorsStruct o)
23 | {
24 | return StringSplitOptions.RemoveEmptyEntries;
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/Stubs/TestStruct1.cs:
--------------------------------------------------------------------------------
1 | namespace TypeConverter.Tests.Stubs
2 | {
3 | public struct TestStruct1
4 | {
5 | public string TestString { get; set; }
6 | }
7 | }
--------------------------------------------------------------------------------
/TypeConverter.Tests/TypeConverter.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Debug
7 | AnyCPU
8 | {74632D78-F918-401D-8197-F49E844F522B}
9 | Library
10 | Properties
11 | TypeConverter.Tests
12 | TypeConverter.Tests
13 | v4.5
14 | 512
15 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
16 | 10.0
17 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
18 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
19 | False
20 | UnitTest
21 | 98a22752
22 |
23 |
24 | true
25 | full
26 | false
27 | bin\Debug\
28 | DEBUG;TRACE
29 | prompt
30 | 4
31 |
32 |
33 | pdbonly
34 | true
35 | bin\Release\
36 | TRACE
37 | prompt
38 | 4
39 |
40 |
41 | true
42 |
43 |
44 | ..\TypeConverter\TypeConverterKey.snk
45 |
46 |
47 |
48 | ..\packages\AutoMapper.4.2.1\lib\net45\AutoMapper.dll
49 | True
50 |
51 |
52 | ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll
53 | True
54 |
55 |
56 | ..\packages\FluentAssertions.4.14.0\lib\net45\FluentAssertions.dll
57 | True
58 |
59 |
60 | ..\packages\FluentAssertions.4.14.0\lib\net45\FluentAssertions.Core.dll
61 | True
62 |
63 |
64 |
65 | ..\packages\Moq.4.5.21\lib\net45\Moq.dll
66 | True
67 |
68 |
69 |
70 |
71 |
72 | ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll
73 | True
74 |
75 |
76 | ..\packages\xunit.assert.2.1.0\lib\portable-net45+win8+wp8+wpa81\xunit.assert.dll
77 | True
78 |
79 |
80 | ..\packages\xunit.extensibility.core.2.1.0\lib\portable-net45+win8+wp8+wpa81\xunit.core.dll
81 | True
82 |
83 |
84 | ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll
85 | True
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | Code
122 |
123 |
124 |
125 |
126 |
127 | TypeConverterKey.snk
128 |
129 |
130 | Designer
131 |
132 |
133 |
134 |
135 |
136 | {a6fcef44-d2ba-42c7-b3cb-13667bcd7b54}
137 | TypeConverter
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | False
146 |
147 |
148 | False
149 |
150 |
151 | False
152 |
153 |
154 | False
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
164 |
165 |
166 |
167 |
168 |
175 |
--------------------------------------------------------------------------------
/TypeConverter.Tests/TypeHelperTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 |
6 | using FluentAssertions;
7 |
8 | using TypeConverter.Extensions;
9 | using TypeConverter.Tests.Stubs;
10 | using TypeConverter.Tests.Utils;
11 | using TypeConverter.Utils;
12 |
13 | using Xunit;
14 | using Xunit.Abstractions;
15 |
16 | namespace TypeConverter.Tests
17 | {
18 | public class TypeHelperTests
19 | {
20 | private readonly ITestOutputHelper testOutputHelper;
21 |
22 | public TypeHelperTests(ITestOutputHelper testOutputHelper)
23 | {
24 | this.testOutputHelper = testOutputHelper;
25 | }
26 |
27 | [Fact]
28 | public void ShouldRunAllCasts()
29 | {
30 | CastTestRunner.RunTests(testCase =>
31 | {
32 | // Arrange
33 | var value = CastTestRunner.GenerateValueForType(testCase.SourceType);
34 | var generatedTestSuccessful = CastTestRunner.CastValueWithGeneratedCode(value, testCase.SourceType, testCase.TargetType, testCase.CastFlag);
35 |
36 | // Act
37 | var castResult = TypeHelper.CastTo(value, testCase.TargetType);
38 |
39 | // Assert
40 | var isSuccessful = CastTestRunner.AreEqual(
41 | this.testOutputHelper,
42 | testCase.SourceType,
43 | testCase.TargetType,
44 | generatedTestSuccessful,
45 | castResult,
46 | testCase.CastFlag);
47 |
48 | if (!isSuccessful)
49 | {
50 | Debugger.Launch();
51 | }
52 |
53 | return isSuccessful;
54 | });
55 | }
56 |
57 | [Fact]
58 | public void ShouldGenerateValueForEachConsideredType()
59 | {
60 | // Arrange
61 | var allTypesToConsider = CastTestRunner.GetAllTestTypes().ToList();
62 | var values = new List