From f3a19214be0aa0442c47a204447e1cdaaa6a70b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20van=20Duijkeren?= Date: Sun, 19 Nov 2017 18:35:37 +0100 Subject: [PATCH 1/4] Change ContinuousDeployment to ContinuousDelivery , Added Coverage again --- GitVersion.yml | 5 +- NodaMoney.sln.DotSettings | 403 ------------------ appveyor.yml | 8 +- build.cake | 74 +++- build.ps1 | 80 ++-- build.sh | 36 +- src/Directory.build.props | 6 +- ...odaMoney.Serialization.AspNet.Tests.csproj | 2 +- 8 files changed, 119 insertions(+), 495 deletions(-) delete mode 100644 NodaMoney.sln.DotSettings diff --git a/GitVersion.yml b/GitVersion.yml index 7d9a7a6..1756f70 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,6 +1,5 @@ -mode: ContinuousDeployment -continuous-delivery-fallback-tag: rc +mode: ContinuousDelivery next-version: 1.0.0 branches: {} ignore: - sha: [] + sha: [] \ No newline at end of file diff --git a/NodaMoney.sln.DotSettings b/NodaMoney.sln.DotSettings deleted file mode 100644 index a9e3904..0000000 --- a/NodaMoney.sln.DotSettings +++ /dev/null @@ -1,403 +0,0 @@ - - SOLUTION - True - <?xml version="1.0" encoding="utf-16"?><Profile name="Full Cleanup (no file header)"><CSArrangeQualifiers>True</CSArrangeQualifiers><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>True</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>True</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>True</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>True</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>True</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>True</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>True</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>True</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>True</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>False</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>True</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>True</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>True</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><CssReformatCode>True</CssReformatCode><XMLReformatCode>True</XMLReformatCode><VBOptimizeImports>True</VBOptimizeImports><VBShortenReferences>True</VBShortenReferences><VBReformatCode>True</VBReformatCode><VBFormatDocComments>True</VBFormatDocComments><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSShortenReferences>True</CSShortenReferences><CSharpFormatDocComments>True</CSharpFormatDocComments><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><HtmlReformatCode>True</HtmlReformatCode><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><JsInsertSemicolon>True</JsInsertSemicolon><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><CssAlphabetizeProperties>True</CssAlphabetizeProperties></Profile> - <?xml version="1.0" encoding="utf-16"?><Profile name="StyleCop"><CSArrangeQualifiers>True</CSArrangeQualifiers><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>True</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>True</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>True</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>True</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>True</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>True</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>True</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>True</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>True</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>False</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>True</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>True</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>True</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>True</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>True</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>True</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>True</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Maintainability><SA1119StatementMustNotUseUnnecessaryParenthesis>True</SA1119StatementMustNotUseUnnecessaryParenthesis></StyleCop.Maintainability><StyleCop.Ordering><ExpandUsingDirectives>True</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>True</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>True</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>True</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>True</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>True</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>True</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing></Profile> - StyleCop - True - True - True - True - True - True - True - True - True - NEXT_LINE_SHIFTED_2 - 1 - 1 - 1 - 1 - 1 - NEXT_LINE_SHIFTED_2 - SEPARATE - ALWAYS_ADD - ALWAYS_ADD - ALWAYS_ADD - ONLY_FOR_MULTILINE - ALWAYS_ADD - NEXT_LINE_SHIFTED_2 - 1 - 1 - False - public protected internal private static new abstract virtual override sealed readonly extern unsafe volatile async - False - False - False - False - True - LINE_BREAK - False - True - False - False - True - False - True - True - CHOP_IF_LONG - True - True - CHOP_IF_LONG - 130 - CHOP_IF_LONG - ZeroIndent - False - - <?xml version="1.0" encoding="utf-16"?> -<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> - <TypePattern DisplayName="COM interfaces"> - <TypePattern.Match> - <Or> - <And> - <Kind Is="Interface" /> - <Or> - <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /> - <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> - </Or> - </And> - </Or> - </TypePattern.Match> - </TypePattern> - <TypePattern DisplayName="P/Invoke structs"> - <TypePattern.Match> - <And> - <Or> - <Kind Is="Struct" /> - <Kind Is="Class" /> - </Or> - <HasAttribute Name="System.Runtime.InteropServices.StructLayoutAttribute" /> - </And> - </TypePattern.Match> - </TypePattern> - <TypePattern DisplayName="P/Invoke classes (called xxxNativeMethods)"> - <TypePattern.Match> - <And> - <Kind Is="Class" /> - <Name Is=".*NativeMethods" /> - </And> - </TypePattern.Match> - </TypePattern> - <TypePattern DisplayName="StyleCop pattern" RemoveRegions="AllExceptGenerated" Priority="100"> - <TypePattern.Match> - <Or> - <Kind Is="Class" /> - <Kind Is="Struct" /> - <Kind Is="Interface" /> - </Or> - </TypePattern.Match> - <Entry DisplayName="Constants"> - <Entry.Match> - <Kind Is="Constant" /> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - </Entry.SortBy> - </Entry> - <Entry DisplayName="Static Fields"> - <Entry.Match> - <And> - <Kind Is="Field" /> - <Static /> - </And> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <Readonly /> - </Entry.SortBy> - </Entry> - <Entry DisplayName="Fields"> - <Entry.Match> - <Kind Is="Field" /> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <Readonly /> - </Entry.SortBy> - </Entry> - <Entry DisplayName="Constructors and destructors" Priority="150"> - <Entry.Match> - <Or> - <Kind Is="Constructor" /> - <Kind Is="Destructor" /> - </Or> - </Entry.Match> - <Entry.SortBy> - <Static /> - <Kind Order="Constructor Destructor" /> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - </Entry.SortBy> - </Entry> - - <Entry DisplayName="Delegates"> - <Entry.Match> - <Kind Is="delegate"/> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <Static /> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Delegates"/> --> - </Entry> - - <Entry DisplayName="Public Events"> - <Entry.Match> - <And> - <Kind Is="event"/> - <Access Is="public"/> - </And> - </Entry.Match> - <Entry.SortBy> - <Static /> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Public Events"/> --> - </Entry> - - <Entry DisplayName="Interface events"> - <Entry.Match> - <And> - <Kind Is="event"/> - <ImplementsInterface/> - </And> - </Entry.Match> - <Entry.SortBy> - <ImplementsInterface Immediate="true"/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Explicit Interface Events" /> --> - </Entry> - - <Entry DisplayName="Other events"> - <Entry.Match> - <Kind Is="event"/> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <Static /> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Events"/> --> - </Entry> - - <Entry DisplayName= "Enums"> - <Entry.Match> - <Kind Is="enum"/> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Enums"/> --> - </Entry> - - <Entry DisplayName = "Interfaces"> - <Entry.Match> - <Kind Is="interface" /> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Interfaces"/> --> - </Entry> - - <Entry DisplayName = "Public properties"> - <Entry.Match> - <And> - <Kind Is="property"/> - <Access Is="public"/> - </And> - </Entry.Match> - <Entry.SortBy> - <Static/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Public Properties"/> --> - </Entry> - - <Entry DisplayName = "Interface properties"> - <Entry.Match> - <And> - <Kind Is="property"/> - <ImplementsInterface/> - </And> - </Entry.Match> - <Entry.SortBy> - <ImplementsInterface Immediate="true"/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Explicit Interface Properties" /> --> - </Entry> - - <Entry DisplayName="Other properties"> - <Entry.Match> - <Kind Is="property"/> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private"/> - <Static/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Properties"/> --> - </Entry> - - <Entry DisplayName="Public indexers" Priority="100"> - <Entry.Match> - <And> - <Kind Is="indexer"/> - <Access Is="public"/> - </And> - </Entry.Match> - <Entry.SortBy> - <Static/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Public Indexers"/> --> - </Entry> - - <Entry DisplayName="Interface indexers"> - <Entry.Match> - <And> - <Kind Is="indexer"/> - <ImplementsInterface/> - </And> - </Entry.Match> - <Entry.SortBy> - <ImplementsInterface Immediate="true"/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Explicit Interface Indexers" /> --> - </Entry> - - <Entry DisplayName = "Other indexers" Priority = "100"> - <Entry.Match> - <Kind Is="indexer"/> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <Static/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Indexers"/> --> - </Entry> - - <Entry DisplayName="Public methods (includes operators)"> - <Entry.Match> - <And> - <Or> - <Kind Is="method"/> - <Kind Is="operator"/> - </Or> - <Access Is="public"/> - </And> - </Entry.Match> - <Entry.SortBy> - <Static/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Public Methods and Operators"/> --> - </Entry> - - <Entry DisplayName = "Interface methods"> - <Entry.Match> - <And> - <Kind Is="method"/> - <ImplementsInterface/> - </And> - </Entry.Match> - <Entry.SortBy> - <ImplementsInterface Immediate="true"/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Explicit Interface Methods" /> --> - </Entry> - - <Entry DisplayName = "Other methods"> - <Entry.Match> - <Kind Is="method"/> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private"/> - <Static/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Methods"/> --> - </Entry> - - <Entry DisplayName = "Operators"> - <Entry.Match> - <Kind Is="operator"/> - </Entry.Match> - <Entry.SortBy> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <Static/> - <!-- <Name/> --> - </Entry.SortBy> - <!-- <Group Region="Operators"/> --> - </Entry> - - <Entry DisplayName = "Nested structs" Priority = "60"> - <Entry.Match> - <Kind Is="struct" /> - </Entry.Match> - <Entry.SortBy> - <Static /> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <!-- <Name/> --> - </Entry.SortBy> - </Entry> - - <Entry DisplayName = "Nested classes" Priority = "70"> - <Entry.Match> - <Kind Is="class"/> - </Entry.Match> - <Entry.SortBy> - <Static /> - <Access Order="Public Internal ProtectedInternal Protected Private" /> - <!-- <Name/> --> - </Entry.SortBy> - </Entry> - - <Entry DisplayName = "All other members"/> - - </TypePattern> -</Patterns> - - UseExplicitType - UseVarWhenEvident - UseVarWhenEvident - $object$_On$event$ - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> - True - True - True - True - False - True \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 8fc7e0b..0e3d48c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -46,10 +46,4 @@ deploy: #---------------------------------# # notifications # #---------------------------------# -notifications: -- provider: Slack - incoming_webhook: - secure: HzeM1/SGr4DgedFcdh1D17XdOCLKRG81irFVeMPTC5rg7O/WRFm0xEIJgOs92wb7UrOqQIe4dWujPHAVC8mCcmMPZ/U4dYDwvCUC6Jkltxc= - on_build_success: false - on_build_failure: false - on_build_status_changed: true \ No newline at end of file +notifications: \ No newline at end of file diff --git a/build.cake b/build.cake index 9b9bad0..3fa16db 100644 --- a/build.cake +++ b/build.cake @@ -1,6 +1,9 @@ -#tool "xunit.runner.console" -#tool "GitVersion.CommandLine" -#addin "Cake.Figlet" +#tool nuget:?package=xunit.runner.console +#tool nuget:?package=GitVersion.CommandLine +#tool nuget:?package=OpenCover +#tool nuget:?package=coveralls.net +#addin nuget:?package=Cake.Figlet +#addin nuget:?package=Cake.Coveralls var target = Argument("target", "Default"); var configuration = Argument("configuration", "Release"); @@ -74,12 +77,14 @@ Task("Build") .IsDependentOn("Version") .Does(() => { - DotNetCoreBuild(solutionFile, new DotNetCoreBuildSettings { Configuration = configuration }); + DotNetCoreBuild(solutionFile, new DotNetCoreBuildSettings + { + Configuration = configuration, + ArgumentCustomization = arg => arg.AppendSwitch("/p:DebugType","=","Full") // needed for OpenCover + }); }); Task("Test") -.IsDependentOn("Clean") -.IsDependentOn("Restore") .IsDependentOn("Build") .Does(() => { @@ -89,10 +94,31 @@ Task("Test") } }); -Task("Package") -.IsDependentOn("Build") +Task("Coverage") .IsDependentOn("Test") .Does(() => +{ + var openCoverSettings = new OpenCoverSettings + { + OldStyle = true, + MergeOutput = true + } + .WithFilter("+[NodaMoney*]* -[*.Tests*]*"); + + var xunit2Settings = new XUnit2Settings { ShadowCopy = false }; + + foreach(var testLib in GetFiles("./tests/**/bin/Release/*/NodaMoney*.Tests.dll")) + { + OpenCover( + context => { context.XUnit2(testLib.FullPath, xunit2Settings); }, + artifactsDir.Path + "/coverage.xml", + openCoverSettings); + } +}); + +Task("Package") +.IsDependentOn("Coverage") +.Does(() => { var packSettings = new DotNetCorePackSettings { @@ -107,6 +133,36 @@ Task("Package") } }); +Task("Upload-Coverage-CoverallsIo") +.WithCriteria(() => HasEnvironmentVariable("COVERALLS_REPO_TOKEN")) +.WithCriteria(() => !AppVeyor.Environment.PullRequest.IsPullRequest) +.IsDependentOn("Coverage") +.Does(() => +{ + if (AppVeyor.IsRunningOnAppVeyor) + { + CoverallsNet(artifactsDir.Path + "/coverage.xml", CoverallsNetReportType.OpenCover, new CoverallsNetSettings() + { + RepoToken = EnvironmentVariable("COVERALLS_REPO_TOKEN"), + CommitId = AppVeyor.Environment.Repository.Commit.Id, + CommitBranch = AppVeyor.Environment.Repository.Branch, + CommitAuthor = AppVeyor.Environment.Repository.Commit.Author, + CommitEmail = AppVeyor.Environment.Repository.Commit.Email, + CommitMessage = AppVeyor.Environment.Repository.Commit.Message, + JobId = Convert.ToInt32(EnvironmentVariable("APPVEYOR_BUILD_NUMBER")), + ServiceName = "appveyor" + }); + } + else + { + CoverallsNet(artifactsDir.Path + "/coverage.xml", CoverallsNetReportType.OpenCover, new CoverallsNetSettings() + { + RepoToken = EnvironmentVariable("COVERALLS_REPO_TOKEN"), + ServiceName = "local" + }); + } +}); + Task("Upload-AppVeyor-Artifacts") .WithCriteria(() => AppVeyor.IsRunningOnAppVeyor) .WithCriteria(() => !AppVeyor.Environment.PullRequest.IsPullRequest) @@ -122,6 +178,7 @@ Task("Upload-AppVeyor-Artifacts") Task("Publish-NuGet") .WithCriteria(() => HasEnvironmentVariable("NUGET_API_KEY")) .WithCriteria(() => AppVeyor.Environment.Repository.Branch == "master") +.WithCriteria(() => AppVeyor.Environment.Repository.Tag.IsTag) .IsDependentOn("Package") .Does(() => { @@ -139,6 +196,7 @@ Task("Default") Task("AppVeyor") .IsDependentOn("Package") .IsDependentOn("Upload-AppVeyor-Artifacts") +.IsDependentOn("Upload-Coverage-CoverallsIo") .IsDependentOn("Publish-NuGet"); RunTarget(target); \ No newline at end of file diff --git a/build.ps1 b/build.ps1 index 1d4173a..b250f4a 100644 --- a/build.ps1 +++ b/build.ps1 @@ -21,13 +21,14 @@ The build script target to run. The build configuration to use. .PARAMETER Verbosity Specifies the amount of information to be displayed. +.PARAMETER ShowDescription +Shows description about tasks. +.PARAMETER DryRun +Performs a dry run. .PARAMETER Experimental -Tells Cake to use the latest Roslyn release. -.PARAMETER WhatIf -Performs a dry run of the build script. -No tasks will be executed. +Uses the nightly builds of the Roslyn script engine. .PARAMETER Mono -Tells Cake to use the Mono scripting engine. +Uses the Mono Compiler rather than the Roslyn script engine. .PARAMETER SkipToolPackageRestore Skips restoring of packages. .PARAMETER ScriptArgs @@ -41,14 +42,14 @@ https://cakebuild.net [CmdletBinding()] Param( [string]$Script = "build.cake", - [string]$Target = "Default", - [ValidateSet("Release", "Debug")] - [string]$Configuration = "Release", + [string]$Target, + [string]$Configuration, [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] - [string]$Verbosity = "Verbose", + [string]$Verbosity, + [switch]$ShowDescription, + [Alias("WhatIf", "Noop")] + [switch]$DryRun, [switch]$Experimental, - [Alias("DryRun","Noop")] - [switch]$WhatIf, [switch]$Mono, [switch]$SkipToolPackageRestore, [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] @@ -80,6 +81,15 @@ function MD5HashFile([string] $filePath) } } +function GetProxyEnabledWebClient +{ + $wc = New-Object System.Net.WebClient + $proxy = [System.Net.WebRequest]::GetSystemWebProxy() + $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials + $wc.Proxy = $proxy + return $wc +} + Write-Host "Preparing to run build script..." if(!$PSScriptRoot){ @@ -97,26 +107,6 @@ $PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" $ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" $MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" -# Should we use mono? -$UseMono = ""; -if($Mono.IsPresent) { - Write-Verbose -Message "Using the Mono based scripting engine." - $UseMono = "-mono" -} - -# Should we use the new Roslyn? -$UseExperimental = ""; -if($Experimental.IsPresent -and !($Mono.IsPresent)) { - Write-Verbose -Message "Using experimental version of Roslyn." - $UseExperimental = "-experimental" -} - -# Is this a dry run? -$UseDryRun = ""; -if($WhatIf.IsPresent) { - $UseDryRun = "-dryrun" -} - # Make sure tools folder exists if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { Write-Verbose -Message "Creating tools directory..." @@ -125,8 +115,10 @@ if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { # Make sure that packages.config exist. if (!(Test-Path $PACKAGES_CONFIG)) { - Write-Verbose -Message "Downloading packages.config..." - try { (New-Object System.Net.WebClient).DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { + Write-Verbose -Message "Downloading packages.config..." + try { + $wc = GetProxyEnabledWebClient + $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { Throw "Could not download packages.config." } } @@ -146,7 +138,8 @@ if (!(Test-Path $NUGET_EXE)) { if (!(Test-Path $NUGET_EXE)) { Write-Verbose -Message "Downloading NuGet.exe..." try { - (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) + $wc = GetProxyEnabledWebClient + $wc.DownloadFile($NUGET_URL, $NUGET_EXE) } catch { Throw "Could not download NuGet.exe." } @@ -179,7 +172,7 @@ if(-Not $SkipToolPackageRestore.IsPresent) { $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" } Write-Verbose -Message ($NuGetOutput | out-string) - + Pop-Location } @@ -222,7 +215,20 @@ if (!(Test-Path $CAKE_EXE)) { Throw "Could not find Cake.exe at $CAKE_EXE" } + + +# Build Cake arguments +$cakeArguments = @("$Script"); +if ($Target) { $cakeArguments += "-target=$Target" } +if ($Configuration) { $cakeArguments += "-configuration=$Configuration" } +if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } +if ($ShowDescription) { $cakeArguments += "-showdescription" } +if ($DryRun) { $cakeArguments += "-dryrun" } +if ($Experimental) { $cakeArguments += "-experimental" } +if ($Mono) { $cakeArguments += "-mono" } +$cakeArguments += $ScriptArgs + # Start Cake Write-Host "Running build script..." -Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" -exit $LASTEXITCODE +&$CAKE_EXE $cakeArguments +exit $LASTEXITCODE \ No newline at end of file diff --git a/build.sh b/build.sh index a1dfdc4..0e42a0a 100644 --- a/build.sh +++ b/build.sh @@ -9,14 +9,10 @@ # Define directories. SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) TOOLS_DIR=$SCRIPT_DIR/tools -ADDINS_DIR=$TOOLS_DIR/Addins -MODULES_DIR=$TOOLS_DIR/Modules NUGET_EXE=$TOOLS_DIR/nuget.exe CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe PACKAGES_CONFIG=$TOOLS_DIR/packages.config PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum -ADDINS_PACKAGES_CONFIG=$ADDINS_DIR/packages.config -MODULES_PACKAGES_CONFIG=$MODULES_DIR/packages.config # Define md5sum or md5 depending on Linux/OSX MD5_EXE= @@ -77,46 +73,20 @@ fi # Restore tools from NuGet. pushd "$TOOLS_DIR" >/dev/null -if [ ! -f "$PACKAGES_CONFIG_MD5" ] || [ "$( cat "$PACKAGES_CONFIG_MD5" | sed 's/\r$//' )" != "$( $MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' )" ]; then +if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then find . -type d ! -name . | xargs rm -rf fi mono "$NUGET_EXE" install -ExcludeVersion if [ $? -ne 0 ]; then - echo "Could not restore NuGet tools." + echo "Could not restore NuGet packages." exit 1 fi -$MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' >| "$PACKAGES_CONFIG_MD5" +$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5 popd >/dev/null -# Restore addins from NuGet. -if [ -f "$ADDINS_PACKAGES_CONFIG" ]; then - pushd "$ADDINS_DIR" >/dev/null - - mono "$NUGET_EXE" install -ExcludeVersion - if [ $? -ne 0 ]; then - echo "Could not restore NuGet addins." - exit 1 - fi - - popd >/dev/null -fi - -# Restore modules from NuGet. -if [ -f "$MODULES_PACKAGES_CONFIG" ]; then - pushd "$MODULES_DIR" >/dev/null - - mono "$NUGET_EXE" install -ExcludeVersion - if [ $? -ne 0 ]; then - echo "Could not restore NuGet modules." - exit 1 - fi - - popd >/dev/null -fi - # Make sure that Cake has been installed. if [ ! -f "$CAKE_EXE" ]; then echo "Could not find Cake.exe at '$CAKE_EXE'." diff --git a/src/Directory.build.props b/src/Directory.build.props index 79e3c67..0410b64 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -10,9 +10,9 @@ https://github.com/remyvd/NodaMoney/blob/master/LICENSE.txt git https://github.com/remyvd/NodaMoney - 1.0.1-extend-plus-oper0018 + 1.0.2-changedeployment0001 1.0.0.0 - 1.0.1.0 - 1.0.1-extend-plus-operator.18 + 1.0.2.0 + 1.0.2-changeDeploymentModel.1+13 \ No newline at end of file diff --git a/tests/NodaMoney.Serialization.AspNet.Tests/NodaMoney.Serialization.AspNet.Tests.csproj b/tests/NodaMoney.Serialization.AspNet.Tests/NodaMoney.Serialization.AspNet.Tests.csproj index 0d5e445..7377370 100644 --- a/tests/NodaMoney.Serialization.AspNet.Tests/NodaMoney.Serialization.AspNet.Tests.csproj +++ b/tests/NodaMoney.Serialization.AspNet.Tests/NodaMoney.Serialization.AspNet.Tests.csproj @@ -1,7 +1,7 @@  - net452 + net462 NodaMoney.Serialization.AspNet.Tests NodaMoney.Serialization.AspNet.Tests true From 2afc28c94783426288b8fe5633f35d7043e961cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20van=20Duijkeren?= Date: Sun, 17 Dec 2017 14:50:10 +0100 Subject: [PATCH 2/4] ISO 4217 Amendment Number 165 --- src/NodaMoney/CurrencyRegistry.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/NodaMoney/CurrencyRegistry.cs b/src/NodaMoney/CurrencyRegistry.cs index 9c83cf3..d13f8cf 100644 --- a/src/NodaMoney/CurrencyRegistry.cs +++ b/src/NodaMoney/CurrencyRegistry.cs @@ -206,7 +206,7 @@ private static IDictionary InitializeIsoCurrencies() ["ISO-4217::MMK"] = new Currency("MMK", "104", 0, "Myanma kyat", "K"), ["ISO-4217::MNT"] = new Currency("MNT", "496", 2, "Mongolian tugrik", "₮"), ["ISO-4217::MOP"] = new Currency("MOP", "446", 2, "Macanese pataca", "MOP$"), - ["ISO-4217::MRO"] = new Currency("MRO", "478", Z07, "Mauritanian ouguiya", "UM"), // divided into five subunits rather than by a power of ten. 5 is 10 to the power of 0.69897... + ["ISO-4217::MRU"] = new Currency("MRU", "929", Z07, "Mauritanian ouguiya", "UM", validFrom: new DateTime(2018, 01, 01)), // divided into five subunits rather than by a power of ten. 5 is 10 to the power of 0.69897... ["ISO-4217::MUR"] = new Currency("MUR", "480", 2, "Mauritian rupee", "Rs"), ["ISO-4217::MVR"] = new Currency("MVR", "462", 2, "Maldivian rufiyaa", "Rf"), // or , MRf, MVR, .ރ or /- ["ISO-4217::MWK"] = new Currency("MWK", "454", 2, "Malawi kwacha", "MK"), @@ -292,6 +292,7 @@ private static IDictionary InitializeIsoCurrencies() ["ISO-4217::STD"] = new Currency("STD", "678", 2, "Dobra", "Db", validTo: new DateTime(2018, 1, 1)), // To be replaced Currency of São Tomé and Príncipe from 1 Jan 2018 (Amendment 164), inflation has rendered the cêntimo obsolete // Historic ISO-4217 currencies (list three) + ["ISO-4217-HISTORIC::MRO"] = new Currency("MRO", "478", Z07, "Mauritanian ouguiya", "UM", "ISO-4217-HISTORIC", new DateTime(2018, 1, 1)), // replaced by MRU ["ISO-4217-HISTORIC::ESA"] = new Currency("ESA", "996", NotApplicable, "Spanish peseta (account A)", "Pta", "ISO-4217-HISTORIC", new DateTime(2002, 3, 1)), // replaced by ESP (EUR) ["ISO-4217-HISTORIC::ESB"] = new Currency("ESB", "995", NotApplicable, "Spanish peseta (account B)", "Pta", "ISO-4217-HISTORIC", new DateTime(2002, 3, 1)), // replaced by ESP (EUR) ["ISO-4217-HISTORIC::LTL"] = new Currency("LTL", "440", 2, "Lithuanian litas", "Lt", "ISO-4217-HISTORIC", new DateTime(2014, 12, 31), new DateTime(1993, 1, 1)), // replaced by EUR From f1ed6e2478ef2b94b94e3e18d9c45aee86906b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20van=20Duijkeren?= Date: Sun, 17 Dec 2017 17:43:19 +0100 Subject: [PATCH 3/4] Added Deconstructers and other C# 6/7 features --- src/NodaMoney/Currency.cs | 51 +++--- src/NodaMoney/ExchangeRate.cs | 39 ++--- .../Extensions/MoneyExtensions.SaveDivide.cs | 10 +- src/NodaMoney/Money.BinaryOperators.cs | 70 ++------ src/NodaMoney/Money.Comparable.cs | 26 +-- src/NodaMoney/Money.Convertible.cs | 149 ++++------------- src/NodaMoney/Money.FiveMostUsedCurrencies.cs | 150 ++++-------------- src/NodaMoney/Money.Formattable.cs | 5 +- src/NodaMoney/Money.Serializable.cs | 5 +- src/NodaMoney/Money.UnaryOperators.cs | 40 +---- src/NodaMoney/Money.cs | 30 ++-- tests/NodaMoney.Tests/CurrencySpec.cs | 15 ++ tests/NodaMoney.Tests/ExchangeRateSpec.cs | 15 ++ tests/NodaMoney.Tests/MoneySpec.cs | 14 ++ .../MoneyUnaryOperatoresTests.cs | 21 ++- tests/NodaMoney.Tests/NodaMoney.Tests.csproj | 1 + 16 files changed, 200 insertions(+), 441 deletions(-) diff --git a/src/NodaMoney/Currency.cs b/src/NodaMoney/Currency.cs index a5f1fb7..a3fb5ea 100644 --- a/src/NodaMoney/Currency.cs +++ b/src/NodaMoney/Currency.cs @@ -59,6 +59,17 @@ internal Currency(string code, string number, double decimalDigits, string engli ValidFrom = validFrom; } + /// Deconstructs the current instance into its components. + /// The code. + /// The number. + /// The currency symbol. + public void Deconstruct(out string code, out string number, out string symbol) + { + code = Code; + number = Number; + symbol = Symbol; + } + /// Gets the Currency that represents the country/region used by the current thread. /// The Currency that represents the country/region used by the current thread. public static Currency CurrentCurrency => FromRegion(RegionInfo.CurrentRegion); @@ -133,19 +144,13 @@ public decimal MinorUnit /// The left Currency. /// The right Currency. /// The result of the operator. - public static bool operator ==(Currency left, Currency right) - { - return left.Equals(right); - } + public static bool operator ==(Currency left, Currency right) => left.Equals(right); /// Implements the operator ==. /// The left Currency. /// The right Currency. /// The result of the operator. - public static bool operator !=(Currency left, Currency right) - { - return !(left == right); - } + public static bool operator !=(Currency left, Currency right) => !(left == right); /// Create an instance of the , based on a ISO 4217 currency code. /// A ISO 4217 currency code, like EUR or USD. @@ -227,44 +232,29 @@ public static Currency FromRegion(string name) /// Get all currencies. /// An of all registered currencies. - public static IEnumerable GetAllCurrencies() - { - return Registry.GetAllCurrencies(); - } + public static IEnumerable GetAllCurrencies() => Registry.GetAllCurrencies(); /// Returns a value indicating whether two specified instances of represent the same value. /// The first object. /// The second object. /// true if left and right are equal to this instance; otherwise, false. [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Calling override method")] - public static bool Equals(Currency left, Currency right) - { - return left.Equals(right); - } + public static bool Equals(Currency left, Currency right) => left.Equals(right); /// Returns a value indicating whether this instance and a specified represent the same type and value. /// An . /// true if value is equal to this instance; otherwise, false. - public override bool Equals(object obj) - { - return (obj is Currency) && Equals((Currency)obj); - } + public override bool Equals(object obj) => (obj is Currency) && Equals((Currency)obj); /// Returns a value indicating whether this instance and a specified object represent the same value. /// A object. /// true if value is equal to this instance; otherwise, false. [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Calling override method")] - public bool Equals(Currency other) - { - return Equals(this.Code, other.Code); - } + public bool Equals(Currency other) => Equals(this.Code, other.Code); /// Returns the hash code for this instance. /// A 32-bit signed integer hash code. - public override int GetHashCode() - { - return Code.GetHashCode(); - } + public override int GetHashCode() => Code.GetHashCode(); /// This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should /// return null (Nothing in Visual Basic) from this method, and instead, if specifying a custom schema is required, apply @@ -273,10 +263,7 @@ public override int GetHashCode() /// produced by the method and /// consumed by the method. /// - public XmlSchema GetSchema() - { - return null; - } + public XmlSchema GetSchema() => null; /// Generates an object from its XML representation. /// The stream from which the object is deserialized. diff --git a/src/NodaMoney/ExchangeRate.cs b/src/NodaMoney/ExchangeRate.cs index 7ad7590..e3b5a63 100644 --- a/src/NodaMoney/ExchangeRate.cs +++ b/src/NodaMoney/ExchangeRate.cs @@ -60,6 +60,17 @@ public ExchangeRate(string baseCode, string quoteCode, double rate) { } + /// Deconstructs the current instance into its components. + /// The base currency. + /// The quote currency. + /// The rate of the exchange. + public void Deconstruct(out Currency baseCurrency, out Currency quoteCurrency, out decimal rate) + { + baseCurrency = BaseCurrency; + quoteCurrency = QuoteCurrency; + rate = Value; + } + /// Gets the base currency. /// The base currency. public Currency BaseCurrency { get; private set; } @@ -76,19 +87,13 @@ public ExchangeRate(string baseCode, string quoteCode, double rate) /// The left ExchangeRate. /// The right ExchangeRate. /// The result of the operator. - public static bool operator ==(ExchangeRate left, ExchangeRate right) - { - return left.Equals(right); - } + public static bool operator ==(ExchangeRate left, ExchangeRate right) => left.Equals(right); /// Implements the operator !=. /// The left ExchangeRate. /// The right ExchangeRate. /// The result of the operator. - public static bool operator !=(ExchangeRate left, ExchangeRate right) - { - return !(left == right); - } + public static bool operator !=(ExchangeRate left, ExchangeRate right) => !(left == right); /// Converts the string representation of an exchange rate to its equivalent. /// The string representation of the exchange rate to convert. @@ -99,8 +104,7 @@ public static ExchangeRate Parse(string rate) if (rate == null) throw new ArgumentNullException(nameof(rate)); - ExchangeRate fx; - if (!TryParse(rate, out fx)) + if (!TryParse(rate, out ExchangeRate fx)) { throw new FormatException("rate is not in the correct format! Currencies are the same or the rate is not a number."); } @@ -183,26 +187,17 @@ public override int GetHashCode() /// true if and this instance are the same type and represent the same value; otherwise, /// false. public bool Equals(ExchangeRate other) - { - return Value == other.Value && BaseCurrency == other.BaseCurrency && QuoteCurrency == other.QuoteCurrency; - } + => Value == other.Value && BaseCurrency == other.BaseCurrency && QuoteCurrency == other.QuoteCurrency; /// Indicates whether this instance and a specified object are equal. /// Another object to compare to. /// true if and this instance are the same type and represent the same value; otherwise, /// false. - public override bool Equals(object obj) - { - // ReSharper disable once ArrangeThisQualifier - return (obj is ExchangeRate) && this.Equals((ExchangeRate)obj); - } + public override bool Equals(object obj) => (obj is ExchangeRate) && this.Equals((ExchangeRate)obj); /// Converts this instance to its equivalent representation. /// A string that represents this instance. /// See http://en.wikipedia.org/wiki/Currency_Pair for more info about how an ExchangeRate can be presented. - public override string ToString() - { - return $"{BaseCurrency.Code}/{QuoteCurrency.Code} {Value}"; - } + public override string ToString() => $"{BaseCurrency.Code}/{QuoteCurrency.Code} {Value}"; } } \ No newline at end of file diff --git a/src/NodaMoney/Extensions/MoneyExtensions.SaveDivide.cs b/src/NodaMoney/Extensions/MoneyExtensions.SaveDivide.cs index 19ec7b1..d24bac1 100644 --- a/src/NodaMoney/Extensions/MoneyExtensions.SaveDivide.cs +++ b/src/NodaMoney/Extensions/MoneyExtensions.SaveDivide.cs @@ -17,10 +17,7 @@ public static class MoneyExtensions /// The behavior of this method follows IEEE Standard 754, section 4. This kind of rounding is sometimes called /// rounding to nearest, or banker's rounding. It minimizes rounding errors that result from consistently rounding a /// midpoint value in a single direction. - public static IEnumerable SafeDivide(this Money money, int shares) - { - return SafeDivide(money, shares, MidpointRounding.ToEven); - } + public static IEnumerable SafeDivide(this Money money, int shares) => SafeDivide(money, shares, MidpointRounding.ToEven); /// Divide the Money in equal shares, without losing Money. /// The instance. @@ -55,10 +52,7 @@ public static IEnumerable SafeDivide(this Money money, int shares, Midpoi /// The behavior of this method follows IEEE Standard 754, section 4. This kind of rounding is sometimes called /// rounding to nearest, or banker's rounding. It minimizes rounding errors that result from consistently rounding a /// midpoint value in a single direction. - public static IEnumerable SafeDivide(this Money money, int[] ratios) - { - return SafeDivide(money, ratios, MidpointRounding.ToEven); - } + public static IEnumerable SafeDivide(this Money money, int[] ratios) => SafeDivide(money, ratios, MidpointRounding.ToEven); /// Divide the Money in shares with a specific ratio, without losing Money. /// The instance. diff --git a/src/NodaMoney/Money.BinaryOperators.cs b/src/NodaMoney/Money.BinaryOperators.cs index 2e721aa..03b8b30 100644 --- a/src/NodaMoney/Money.BinaryOperators.cs +++ b/src/NodaMoney/Money.BinaryOperators.cs @@ -7,93 +7,63 @@ public partial struct Money /// A object on the left side. /// A object on the right side. /// The result of adding left and right. - public static Money operator +(Money left, Money right) - { - return Add(left, right); - } + public static Money operator +(Money left, Money right) => Add(left, right); /// Add the value with the given value. /// A object on the left side. /// A object on the right side. /// The result of adding left and right. - public static Money operator +(Money left, decimal right) - { - return Add(left, right); - } + public static Money operator +(Money left, decimal right) => Add(left, right); /// Add the value with the given value. /// A object on the left side. /// A object on the right side. /// The result of adding left and right. - public static Money operator +(decimal left, Money right) - { - return Add(right, left); - } + public static Money operator +(decimal left, Money right) => Add(right, left); /// Subtracts two specified values. /// A object on the left side. /// A object on the right side. /// The result of subtracting right from left. - public static Money operator -(Money left, Money right) - { - return Subtract(left, right); - } + public static Money operator -(Money left, Money right) => Subtract(left, right); /// Subtracts value with the given value. /// A object on the left side. /// A object on the right side. /// The result of subtracting right from left. - public static Money operator -(Money left, decimal right) - { - return Subtract(left, right); - } + public static Money operator -(Money left, decimal right) => Subtract(left, right); /// Subtracts value with the given value. /// A object on the left side. /// A object on the right side. /// The result of subtracting right from left. - public static Money operator -(decimal left, Money right) - { - return Subtract(right, left); - } + public static Money operator -(decimal left, Money right) => Subtract(right, left); /// Multiplies the value by the given value. /// A object on the left side. /// A object on the right side. /// The result of multiplying right with left. - public static Money operator *(Money left, decimal right) - { - return Multiply(left, right); - } + public static Money operator *(Money left, decimal right) => Multiply(left, right); /// Multiplies the value by the given value. /// A object on the left side. /// A object on the right side. /// The result of multiplying left with right. - public static Money operator *(decimal left, Money right) - { - return Multiply(right, left); - } + public static Money operator *(decimal left, Money right) => Multiply(right, left); /// Divides the value by the given value. /// A object on the left side. /// A object on the right side. /// The result of dividing left with right. /// This division can lose money! Use to do a safe division. - public static Money operator /(Money left, decimal right) - { - return Divide(left, right); - } + public static Money operator /(Money left, decimal right) => Divide(left, right); /// Divides the value by the given value. /// A object on the left side. /// A object on the right side. /// The result of dividing left with right. /// Division of Money by Money, means the unit is lost, so the result will be a ratio . - public static decimal operator /(Money left, Money right) - { - return Divide(left, right); - } + public static decimal operator /(Money left, Money right) => Divide(left, right); /// Adds two specified values. /// The first object. @@ -109,10 +79,7 @@ public static Money Add(Money money1, Money money2) /// The first object. /// The second object. /// A object with the values of both objects added. - public static Money Add(Money money1, decimal money2) - { - return new Money(decimal.Add(money1.Amount, money2), money1.Currency); - } + public static Money Add(Money money1, decimal money2) => new Money(decimal.Add(money1.Amount, money2), money1.Currency); /// Subtracts one specified value from another. /// The first object. @@ -128,29 +95,20 @@ public static Money Subtract(Money money1, Money money2) /// The first object. /// The second object. /// A object where the second object is subtracted from the first. - public static Money Subtract(Money money1, decimal money2) - { - return new Money(decimal.Subtract(money1.Amount, money2), money1.Currency); - } + public static Money Subtract(Money money1, decimal money2) => new Money(decimal.Subtract(money1.Amount, money2), money1.Currency); /// Multiplies the specified money. /// The money. /// The multiplier. /// The result as after multiplying. - public static Money Multiply(Money money, decimal multiplier) - { - return new Money(decimal.Multiply(money.Amount, multiplier), money.Currency); - } + public static Money Multiply(Money money, decimal multiplier) => new Money(decimal.Multiply(money.Amount, multiplier), money.Currency); /// Divides the specified money. /// The money. /// The divider. /// The division as . /// This division can lose money! Use to do a safe division. - public static Money Divide(Money money, decimal divisor) - { - return new Money(decimal.Divide(money.Amount, divisor), money.Currency); - } + public static Money Divide(Money money, decimal divisor) => new Money(decimal.Divide(money.Amount, divisor), money.Currency); /// Divides the specified money. /// The money. diff --git a/src/NodaMoney/Money.Comparable.cs b/src/NodaMoney/Money.Comparable.cs index 691c53d..422ab62 100644 --- a/src/NodaMoney/Money.Comparable.cs +++ b/src/NodaMoney/Money.Comparable.cs @@ -13,37 +13,25 @@ public partial struct Money : IComparable, IComparable /// A object on the left side. /// A object on the right side. /// true if left is less than right; otherwise, false. - public static bool operator <(Money left, Money right) - { - return Compare(left, right) < 0; - } + public static bool operator <(Money left, Money right) => Compare(left, right) < 0; /// Returns a value indicating whether a specified is greater than another specified . /// A object on the left side. /// A object on the right side. /// true if left is greater than right; otherwise, false. - public static bool operator >(Money left, Money right) - { - return Compare(left, right) > 0; - } + public static bool operator >(Money left, Money right) => Compare(left, right) > 0; /// Returns a value indicating whether a specified is less than or equal to another specified . /// A object on the left side. /// A object on the right side. /// true if left is less than or equal to right; otherwise, false. - public static bool operator <=(Money left, Money right) - { - return Compare(left, right) <= 0; - } + public static bool operator <=(Money left, Money right) => Compare(left, right) <= 0; /// Returns a value indicating whether a specified is greater than or equal to another specified . /// A object on the left side. /// A object on the right side. /// true if left is greater than or equal to right; otherwise, false. - public static bool operator >=(Money left, Money right) - { - return Compare(left, right) >= 0; - } + public static bool operator >=(Money left, Money right) => Compare(left, right) >= 0; /// Compares two specified values. /// The first object. @@ -69,10 +57,7 @@ public partial struct Money : IComparable, IComparable /// /// /// - public static int Compare(Money left, Money right) - { - return left.CompareTo(right); - } + public static int Compare(Money left, Money right) => left.CompareTo(right); /// Compares this instance to a specified object. /// A object. @@ -135,7 +120,6 @@ public int CompareTo(object obj) public int CompareTo(Money other) { AssertIsSameCurrency(this, other); - return Amount.CompareTo(other.Amount); } } diff --git a/src/NodaMoney/Money.Convertible.cs b/src/NodaMoney/Money.Convertible.cs index 7334d6a..59cdbdf 100644 --- a/src/NodaMoney/Money.Convertible.cs +++ b/src/NodaMoney/Money.Convertible.cs @@ -4,133 +4,91 @@ namespace NodaMoney { /// Represents Money, an amount defined in a specific Currency. public partial struct Money -#if !NETSTANDARD1_0 +#if !NETSTANDARD1_3 : IConvertible #endif { /// Performs an explicit conversion from to . /// The money. /// The result of the conversion. - public static explicit operator double(Money money) - { - return Convert.ToDouble(money.Amount); - } + public static explicit operator double(Money money) => Convert.ToDouble(money.Amount); /// Performs an explicit conversion from to . /// The money. /// The result of the conversion. - public static explicit operator long(Money money) - { - return Convert.ToInt64(money.Amount); - } + public static explicit operator long(Money money) => Convert.ToInt64(money.Amount); /// Performs an explicit conversion from to . /// The money. /// The result of the conversion. - public static explicit operator decimal(Money money) - { - return money.Amount; - } + public static explicit operator decimal(Money money) => money.Amount; /// Performs an implicit conversion from to . /// The money. /// The result of the conversion. - public static implicit operator Money(long money) - { - return new Money(money); - } + public static implicit operator Money(long money) => new Money(money); /// Performs an implicit conversion from to . /// The money. /// The result of the conversion. [CLSCompliant(false)] - public static implicit operator Money(ulong money) - { - return new Money(money); - } + public static implicit operator Money(ulong money) => new Money(money); /// Performs an implicit conversion from to . /// The money. /// The result of the conversion. - public static implicit operator Money(byte money) - { - return new Money(money); - } + public static implicit operator Money(byte money) => new Money(money); /// Performs an implicit conversion from to . /// The money. /// The result of the conversion. [CLSCompliant(false)] - public static implicit operator Money(ushort money) - { - return new Money(money); - } + public static implicit operator Money(ushort money) => new Money(money); /// Performs an implicit conversion from to . /// The money. /// The result of the conversion. [CLSCompliant(false)] - public static implicit operator Money(uint money) - { - return new Money(money); - } + public static implicit operator Money(uint money) => new Money(money); /// Performs an implicit conversion from to . /// The money. /// The result of the conversion. - public static explicit operator Money(double money) - { - return new Money((decimal)money); - } + public static explicit operator Money(double money) => new Money((decimal)money); /// Performs an implicit conversion from to . /// The money. /// The result of the conversion. - public static implicit operator Money(decimal money) - { - return new Money(money); - } + public static implicit operator Money(decimal money) => new Money(money); /// Converts the value of this instance to an . /// A value. /// The value of the instance, converted to a . /// Because a has fewer significant digits than a value, this operation may /// produce round-off errors. Also the information is lost. - public static float ToSingle(Money money) - { - return Convert.ToSingle(money.Amount); - } + public static float ToSingle(Money money) => Convert.ToSingle(money.Amount); /// Converts the value of this instance to an . /// A value. /// The value of the current instance, converted to a . /// Because a Double has fewer significant digits than a value, this operation may produce round-off /// errors. - public static double ToDouble(Money money) - { - return Convert.ToDouble(money.Amount); - } + public static double ToDouble(Money money) => Convert.ToDouble(money.Amount); /// Converts the value of this instance to an . /// A value. /// The value of the instance, converted to a . /// The information is lost. - public static decimal ToDecimal(Money money) - { - return money.Amount; - } + public static decimal ToDecimal(Money money) => money.Amount; -#if !NETSTANDARD1_0 +#if !NETSTANDARD1_3 /// /// Returns the for this instance. /// /// /// The enumerated constant that is the of the class or value type that implements this interface. /// - public TypeCode GetTypeCode() - { - return TypeCode.Object; - } + public TypeCode GetTypeCode() => TypeCode.Object; #endif /// Converts the value of this instance to an equivalent Boolean value using the specified culture-specific @@ -138,90 +96,63 @@ public TypeCode GetTypeCode() /// An interface implementation that supplies /// culture-specific formatting information. /// A Boolean value equivalent to the value of this instance. - public bool ToBoolean(IFormatProvider provider) - { - return Convert.ToBoolean(Amount, provider); - } + public bool ToBoolean(IFormatProvider provider) => Convert.ToBoolean(Amount, provider); /// Converts the value of this instance to an equivalent 8-bit unsigned integer using the specified /// culture-specific formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// An 8-bit unsigned integer equivalent to the value of this instance. - public byte ToByte(IFormatProvider provider) - { - return Convert.ToByte(Amount, provider); - } + public byte ToByte(IFormatProvider provider) => Convert.ToByte(Amount, provider); /// Converts the value of this instance to an equivalent Unicode character using the specified culture-specific /// formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// A Unicode character equivalent to the value of this instance. - public char ToChar(IFormatProvider provider) - { - return Convert.ToChar(Amount, provider); - } + public char ToChar(IFormatProvider provider) => Convert.ToChar(Amount, provider); /// Converts the value of this instance to an equivalent using the specified /// culture-specific formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// A instance equivalent to the value of this instance. - public DateTime ToDateTime(IFormatProvider provider) - { - return Convert.ToDateTime(Amount, provider); - } + public DateTime ToDateTime(IFormatProvider provider) => Convert.ToDateTime(Amount, provider); /// Converts the value of this instance to an equivalent number using the specified /// culture-specific formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// A number equivalent to the value of this instance. - public decimal ToDecimal(IFormatProvider provider) - { - return Convert.ToDecimal(Amount, provider); - } + public decimal ToDecimal(IFormatProvider provider) => Convert.ToDecimal(Amount, provider); /// Converts the value of this instance to an equivalent double-precision floating-point number using the /// specified culture-specific formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// A double-precision floating-point number equivalent to the value of this instance. - public double ToDouble(IFormatProvider provider) - { - return Convert.ToDouble(Amount, provider); - } + public double ToDouble(IFormatProvider provider) => Convert.ToDouble(Amount, provider); /// Converts the value of this instance to an equivalent 16-bit signed integer using the specified /// culture-specific formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// An 16-bit signed integer equivalent to the value of this instance. - public short ToInt16(IFormatProvider provider) - { - return Convert.ToInt16(Amount, provider); - } + public short ToInt16(IFormatProvider provider) => Convert.ToInt16(Amount, provider); /// Converts the value of this instance to an equivalent 32-bit signed integer using the specified /// culture-specific formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// An 32-bit signed integer equivalent to the value of this instance. - public int ToInt32(IFormatProvider provider) - { - return Convert.ToInt32(Amount, provider); - } + public int ToInt32(IFormatProvider provider) => Convert.ToInt32(Amount, provider); /// Converts the value of this instance to an equivalent 64-bit signed integer using the specified /// culture-specific formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// An 64-bit signed integer equivalent to the value of this instance. - public long ToInt64(IFormatProvider provider) - { - return Convert.ToInt64(Amount, provider); - } + public long ToInt64(IFormatProvider provider) => Convert.ToInt64(Amount, provider); /// Converts the value of this instance to an equivalent 8-bit signed integer using the specified culture-specific /// formatting information. @@ -229,20 +160,14 @@ public long ToInt64(IFormatProvider provider) /// culture-specific formatting information. /// An 8-bit signed integer equivalent to the value of this instance. [CLSCompliant(false)] - public sbyte ToSByte(IFormatProvider provider) - { - return Convert.ToSByte(Amount, provider); - } + public sbyte ToSByte(IFormatProvider provider) => Convert.ToSByte(Amount, provider); /// Converts the value of this instance to an equivalent single-precision floating-point number using the /// specified culture-specific formatting information. /// An interface implementation that supplies /// culture-specific formatting information. /// A single-precision floating-point number equivalent to the value of this instance. - public float ToSingle(IFormatProvider provider) - { - return Convert.ToSingle(Amount, provider); - } + public float ToSingle(IFormatProvider provider) => Convert.ToSingle(Amount, provider); /// Converts the value of this instance to an of the specified that has an equivalent value, using the specified culture-specific formatting information. /// The to which the value of this instance is converted. @@ -250,10 +175,7 @@ public float ToSingle(IFormatProvider provider) /// culture-specific formatting information. /// An instance of type whose value is equivalent /// to the value of this instance. - public object ToType(Type conversionType, IFormatProvider provider) - { - return Convert.ChangeType(Amount, conversionType, provider); - } + public object ToType(Type conversionType, IFormatProvider provider) => Convert.ChangeType(Amount, conversionType, provider); /// Converts the value of this instance to an equivalent 16-bit unsigned integer using the specified /// culture-specific formatting information. @@ -261,10 +183,7 @@ public object ToType(Type conversionType, IFormatProvider provider) /// culture-specific formatting information. /// An 16-bit unsigned integer equivalent to the value of this instance. [CLSCompliant(false)] - public ushort ToUInt16(IFormatProvider provider) - { - return Convert.ToUInt16(Amount, provider); - } + public ushort ToUInt16(IFormatProvider provider) => Convert.ToUInt16(Amount, provider); /// Converts the value of this instance to an equivalent 32-bit unsigned integer using the specified /// culture-specific formatting information. @@ -272,10 +191,7 @@ public ushort ToUInt16(IFormatProvider provider) /// culture-specific formatting information. /// An 32-bit unsigned integer equivalent to the value of this instance. [CLSCompliant(false)] - public uint ToUInt32(IFormatProvider provider) - { - return Convert.ToUInt32(Amount, provider); - } + public uint ToUInt32(IFormatProvider provider) => Convert.ToUInt32(Amount, provider); /// Converts the value of this instance to an equivalent 64-bit unsigned integer using the specified /// culture-specific formatting information. @@ -283,9 +199,6 @@ public uint ToUInt32(IFormatProvider provider) /// culture-specific formatting information. /// An 64-bit unsigned integer equivalent to the value of this instance. [CLSCompliant(false)] - public ulong ToUInt64(IFormatProvider provider) - { - return Convert.ToUInt64(Amount, provider); - } + public ulong ToUInt64(IFormatProvider provider) => Convert.ToUInt64(Amount, provider); } } \ No newline at end of file diff --git a/src/NodaMoney/Money.FiveMostUsedCurrencies.cs b/src/NodaMoney/Money.FiveMostUsedCurrencies.cs index ac967a5..91cfe32 100644 --- a/src/NodaMoney/Money.FiveMostUsedCurrencies.cs +++ b/src/NodaMoney/Money.FiveMostUsedCurrencies.cs @@ -8,19 +8,13 @@ public partial struct Money /// Initializes a new instance of the structure in euro's. /// The Amount of money in euro. /// A structure with EUR as . - public static Money Euro(decimal amount) - { - return new Money(amount, Currency.FromCode("EUR")); - } + public static Money Euro(decimal amount) => new Money(amount, Currency.FromCode("EUR")); /// Initializes a new instance of the structure in euro's. /// The Amount of money in euro. /// The rounding. /// A structure with EUR as . - public static Money Euro(decimal amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("EUR"), rounding); - } + public static Money Euro(decimal amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("EUR"), rounding); /// Initializes a new instance of the structure in euro's. /// The Amount of money in euro. @@ -32,10 +26,7 @@ public static Money Euro(decimal amount, MidpointRounding rounding) /// (). The behavior of this method follows IEEE Standard 754, section 4. This /// kind of rounding is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that /// result from consistently rounding a midpoint value in a single direction. - public static Money Euro(double amount) - { - return new Money(amount, Currency.FromCode("EUR")); - } + public static Money Euro(double amount) => new Money(amount, Currency.FromCode("EUR")); /// Initializes a new instance of the structure in euro's. /// The Amount of money in euro. @@ -45,44 +36,29 @@ public static Money Euro(double amount) /// to nearest. This is done even if the number has more than 15 digits and the less significant digits are zero. /// The amount will be rounded to the number of decimal digits of the specified currency /// (). - public static Money Euro(double amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("EUR"), rounding); - } + public static Money Euro(double amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("EUR"), rounding); /// Initializes a new instance of the structure in euro's. /// The Amount of money in euro. /// A structure with EUR as . - public static Money Euro(long amount) - { - return new Money(amount, Currency.FromCode("EUR")); - } + public static Money Euro(long amount) => new Money(amount, Currency.FromCode("EUR")); /// Initializes a new instance of the structure in euro's. /// The Amount of money in euro. /// A structure with EUR as . [CLSCompliant(false)] - public static Money Euro(ulong amount) - { - return new Money(amount, Currency.FromCode("EUR")); - } + public static Money Euro(ulong amount) => new Money(amount, Currency.FromCode("EUR")); /// Initializes a new instance of the structure in US dollars. /// The Amount of money in US dollar. /// A structure with USD as . - public static Money USDollar(decimal amount) - { - return new Money(amount, Currency.FromCode("USD")); - } + public static Money USDollar(decimal amount) => new Money(amount, Currency.FromCode("USD")); /// Initializes a new instance of the structure in US dollars. /// The Amount of money in euro. /// The rounding. /// A structure with USD as . - public static Money USDollar(decimal amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("USD"), rounding); - } + public static Money USDollar(decimal amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("USD"), rounding); /// Initializes a new instance of the structure in US dollars. /// The Amount of money in US dollar. @@ -94,10 +70,7 @@ public static Money USDollar(decimal amount, MidpointRounding rounding) /// (). The behavior of this method follows IEEE Standard 754, section 4. This /// kind of rounding is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that /// result from consistently rounding a midpoint value in a single direction. - public static Money USDollar(double amount) - { - return new Money(amount, Currency.FromCode("USD")); - } + public static Money USDollar(double amount) => new Money(amount, Currency.FromCode("USD")); /// Initializes a new instance of the structure in US dollars. /// The Amount of money in US dollar. @@ -107,44 +80,29 @@ public static Money USDollar(double amount) /// to nearest. This is done even if the number has more than 15 digits and the less significant digits are zero. /// The amount will be rounded to the number of decimal digits of the specified currency /// (). - public static Money USDollar(double amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("USD"), rounding); - } + public static Money USDollar(double amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("USD"), rounding); /// Initializes a new instance of the structure in US dollars. /// The Amount of money in US dollar. /// A structure with USD as . - public static Money USDollar(long amount) - { - return new Money(amount, Currency.FromCode("USD")); - } + public static Money USDollar(long amount) => new Money(amount, Currency.FromCode("USD")); /// Initializes a new instance of the structure in US dollars. /// The Amount of money in US dollar. /// A structure with USD as . [CLSCompliant(false)] - public static Money USDollar(ulong amount) - { - return new Money(amount, Currency.FromCode("USD")); - } + public static Money USDollar(ulong amount) => new Money(amount, Currency.FromCode("USD")); /// Initializes a new instance of the structure in Japanese Yens. /// The Amount of money in Japanese Yen. /// A structure with JPY as . - public static Money Yen(decimal amount) - { - return new Money(amount, Currency.FromCode("JPY")); - } + public static Money Yen(decimal amount) => new Money(amount, Currency.FromCode("JPY")); /// Initializes a new instance of the structure in Japanese Yens. /// The Amount of money in Japanese Yens. /// The rounding. /// A structure with JPY as . - public static Money Yen(decimal amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("JPY"), rounding); - } + public static Money Yen(decimal amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("JPY"), rounding); /// Initializes a new instance of the structure in Japanese Yens. /// The Amount of money in Japanese Yen. @@ -156,10 +114,7 @@ public static Money Yen(decimal amount, MidpointRounding rounding) /// (). The behavior of this method follows IEEE Standard 754, section 4. This /// kind of rounding is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that /// result from consistently rounding a midpoint value in a single direction. - public static Money Yen(double amount) - { - return new Money(amount, Currency.FromCode("JPY")); - } + public static Money Yen(double amount) => new Money(amount, Currency.FromCode("JPY")); /// Initializes a new instance of the structure in Japanese Yens. /// The Amount of money in Japanese Yen. @@ -169,44 +124,29 @@ public static Money Yen(double amount) /// to nearest. This is done even if the number has more than 15 digits and the less significant digits are zero. /// The amount will be rounded to the number of decimal digits of the specified currency /// (). - public static Money Yen(double amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("JPY"), rounding); - } + public static Money Yen(double amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("JPY"), rounding); /// Initializes a new instance of the structure in Japanese Yens. /// The Amount of money in Japanese Yen. /// A structure with JPY as . - public static Money Yen(long amount) - { - return new Money(amount, Currency.FromCode("JPY")); - } + public static Money Yen(long amount) => new Money(amount, Currency.FromCode("JPY")); /// Initializes a new instance of the structure in Japanese Yens. /// The Amount of money in Japanese Yen. /// A structure with JPY as . [CLSCompliant(false)] - public static Money Yen(ulong amount) - { - return new Money(amount, Currency.FromCode("JPY")); - } + public static Money Yen(ulong amount) => new Money(amount, Currency.FromCode("JPY")); /// Initializes a new instance of the structure in British pounds. /// The Amount of money in Pound Sterling. /// A structure with GBP as . - public static Money PoundSterling(decimal amount) - { - return new Money(amount, Currency.FromCode("GBP")); - } + public static Money PoundSterling(decimal amount) => new Money(amount, Currency.FromCode("GBP")); /// Initializes a new instance of the structure in British pounds. /// The Amount of money in euro. /// The rounding. /// A structure with GBP as . - public static Money PoundSterling(decimal amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("GBP"), rounding); - } + public static Money PoundSterling(decimal amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("GBP"), rounding); /// Initializes a new instance of the structure in British pounds. /// The Amount of money in Pound Sterling. @@ -218,10 +158,7 @@ public static Money PoundSterling(decimal amount, MidpointRounding rounding) /// (). The behavior of this method follows IEEE Standard 754, section 4. This /// kind of rounding is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that /// result from consistently rounding a midpoint value in a single direction. - public static Money PoundSterling(double amount) - { - return new Money(amount, Currency.FromCode("GBP")); - } + public static Money PoundSterling(double amount) => new Money(amount, Currency.FromCode("GBP")); /// Initializes a new instance of the structure in British pounds. /// The Amount of money in Pound Sterling. @@ -231,44 +168,29 @@ public static Money PoundSterling(double amount) /// to nearest. This is done even if the number has more than 15 digits and the less significant digits are zero. /// The amount will be rounded to the number of decimal digits of the specified currency /// (). - public static Money PoundSterling(double amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("GBP"), rounding); - } + public static Money PoundSterling(double amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("GBP"), rounding); /// Initializes a new instance of the structure in British pounds. /// The Amount of money in Pound Sterling. /// A structure with GBP as . - public static Money PoundSterling(long amount) - { - return new Money(amount, Currency.FromCode("GBP")); - } + public static Money PoundSterling(long amount) => new Money(amount, Currency.FromCode("GBP")); /// Initializes a new instance of the structure in British pounds. /// The Amount of money in Pound Sterling. /// A structure with GBP as . [CLSCompliant(false)] - public static Money PoundSterling(ulong amount) - { - return new Money(amount, Currency.FromCode("GBP")); - } + public static Money PoundSterling(ulong amount) => new Money(amount, Currency.FromCode("GBP")); /// Initializes a new instance of the structure in Chinese Yuan. /// The Amount of money in Chinese Yuan. /// A structure with CNY as . - public static Money Yuan(decimal amount) - { - return new Money(amount, Currency.FromCode("CNY")); - } + public static Money Yuan(decimal amount) => new Money(amount, Currency.FromCode("CNY")); /// Initializes a new instance of the structure in Chinese Yuan. /// The Amount of money in Chinese Yuan. /// The rounding. /// A structure with CNY as . - public static Money Yuan(decimal amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("CNY"), rounding); - } + public static Money Yuan(decimal amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("CNY"), rounding); /// Initializes a new instance of the structure in Chinese Yuan. /// The Amount of money in Chinese Yuan. @@ -280,10 +202,7 @@ public static Money Yuan(decimal amount, MidpointRounding rounding) /// (). The behavior of this method follows IEEE Standard 754, section 4. This /// kind of rounding is sometimes called rounding to nearest, or banker's rounding. It minimizes rounding errors that /// result from consistently rounding a midpoint value in a single direction. - public static Money Yuan(double amount) - { - return new Money(amount, Currency.FromCode("CNY")); - } + public static Money Yuan(double amount) => new Money(amount, Currency.FromCode("CNY")); /// Initializes a new instance of the structure in Chinese Yuan. /// The Amount of money in Chinese Yuan. @@ -293,26 +212,17 @@ public static Money Yuan(double amount) /// to nearest. This is done even if the number has more than 15 digits and the less significant digits are zero. /// The amount will be rounded to the number of decimal digits of the specified currency /// (). - public static Money Yuan(double amount, MidpointRounding rounding) - { - return new Money(amount, Currency.FromCode("CNY"), rounding); - } + public static Money Yuan(double amount, MidpointRounding rounding) => new Money(amount, Currency.FromCode("CNY"), rounding); /// Initializes a new instance of the structure in Chinese Yuan. /// The Amount of money in Chinese Yuan. /// A structure with CNY as . - public static Money Yuan(long amount) - { - return new Money(amount, Currency.FromCode("CNY")); - } + public static Money Yuan(long amount) => new Money(amount, Currency.FromCode("CNY")); /// Initializes a new instance of the structure in Chinese Yuan. /// The Amount of money in Chinese Yuan. /// A structure with CNY as . [CLSCompliant(false)] - public static Money Yuan(ulong amount) - { - return new Money(amount, Currency.FromCode("CNY")); - } + public static Money Yuan(ulong amount) => new Money(amount, Currency.FromCode("CNY")); } } \ No newline at end of file diff --git a/src/NodaMoney/Money.Formattable.cs b/src/NodaMoney/Money.Formattable.cs index af2985d..7222da3 100644 --- a/src/NodaMoney/Money.Formattable.cs +++ b/src/NodaMoney/Money.Formattable.cs @@ -12,10 +12,7 @@ public partial struct Money : IFormattable /// Converting will use the object for the current culture if this has the same /// ISOCurrencySymbol, otherwise the from the will be used. /// - public override string ToString() - { - return ConvertToString(null, null); - } + public override string ToString() => ConvertToString(null, null); /// Converts the value of this instance to its equivalent representation /// using the specified format. diff --git a/src/NodaMoney/Money.Serializable.cs b/src/NodaMoney/Money.Serializable.cs index cc25a12..4b73a25 100644 --- a/src/NodaMoney/Money.Serializable.cs +++ b/src/NodaMoney/Money.Serializable.cs @@ -20,10 +20,7 @@ public partial struct Money : IXmlSerializable /// produced by the method /// and consumed by the method. /// - public XmlSchema GetSchema() - { - return null; - } + public XmlSchema GetSchema() => null; /// Generates an object from its XML representation. /// The stream from which the object is deserialized. diff --git a/src/NodaMoney/Money.UnaryOperators.cs b/src/NodaMoney/Money.UnaryOperators.cs index c27359b..ec8944c 100644 --- a/src/NodaMoney/Money.UnaryOperators.cs +++ b/src/NodaMoney/Money.UnaryOperators.cs @@ -6,65 +6,41 @@ public partial struct Money /// Implements the operator +. /// The money. /// The result of the operator. - public static Money operator +(Money money) - { - return Plus(money); - } + public static Money operator +(Money money) => Plus(money); /// Implements the operator -. /// The money. /// The result of the operator. - public static Money operator -(Money money) - { - return Negate(money); - } + public static Money operator -(Money money) => Negate(money); /// Implements the operator ++. /// The money. /// The result of the operator. - public static Money operator ++(Money money) - { - return Increment(money); - } + public static Money operator ++(Money money) => Increment(money); /// Implements the operator --. /// The money. /// The result of the operator. - public static Money operator --(Money money) - { - return Decrement(money); - } + public static Money operator --(Money money) => Decrement(money); /// Pluses the specified money. /// The money. /// The result. - public static Money Plus(Money money) - { - return money; - } + public static Money Plus(Money money) => new Money(+money.Amount, money.Currency); /// Negates the specified money. /// The money. /// The result. - public static Money Negate(Money money) - { - return new Money(-money.Amount, money.Currency); - } + public static Money Negate(Money money) => new Money(-money.Amount, money.Currency); /// Increments the specified money. /// The money. /// The result. - public static Money Increment(Money money) - { - return Add(money, new Money(money.Currency.MinorUnit, money.Currency)); - } + public static Money Increment(Money money) => Add(money, new Money(money.Currency.MinorUnit, money.Currency)); /// Decrements the specified money. /// The money. /// The result. - public static Money Decrement(Money money) - { - return Subtract(money, new Money(money.Currency.MinorUnit, money.Currency)); - } + public static Money Decrement(Money money) => Subtract(money, new Money(money.Currency.MinorUnit, money.Currency)); } } \ No newline at end of file diff --git a/src/NodaMoney/Money.cs b/src/NodaMoney/Money.cs index 27a326c..059d69c 100644 --- a/src/NodaMoney/Money.cs +++ b/src/NodaMoney/Money.cs @@ -233,6 +233,15 @@ public Money(ulong amount, Currency currency) { } + /// Deconstructs the current instance into its components. + /// The Amount of money as . + /// The Currency of the money. + public void Deconstruct(out decimal amount, out Currency currency) + { + amount = Amount; + currency = Currency; + } + /// Gets the amount of money. [DataMember] public decimal Amount { get; private set; } @@ -245,38 +254,25 @@ public Money(ulong amount, Currency currency) /// A object on the left side. /// A object on the right side. /// true if left and right are equal; otherwise, false. - public static bool operator ==(Money left, Money right) - { - return left.Equals(right); - } + public static bool operator ==(Money left, Money right) => left.Equals(right); /// Returns a value indicating whether two instances of are not equal. /// A object on the left side. /// A object on the right side. /// true if left and right are not equal; otherwise, false. - public static bool operator !=(Money left, Money right) - { - return !(left == right); - } + public static bool operator !=(Money left, Money right) => !(left == right); /// Returns a value indicating whether this instance and a specified object represent the same /// value. /// A object. /// true if value is equal to this instance; otherwise, false. - public bool Equals(Money other) - { - return Amount == other.Amount && Currency == other.Currency; - } + public bool Equals(Money other) => Amount == other.Amount && Currency == other.Currency; /// Returns a value indicating whether this instance and a specified represent the same type /// and value. /// An . /// true if value is equal to this instance; otherwise, false. - public override bool Equals(object obj) - { - // ReSharper disable once ArrangeThisQualifier - return (obj is Money) && this.Equals((Money)obj); - } + public override bool Equals(object obj) => (obj is Money) && this.Equals((Money)obj); /// Returns the hash code for this instance. /// A 32-bit signed integer hash code. diff --git a/tests/NodaMoney.Tests/CurrencySpec.cs b/tests/NodaMoney.Tests/CurrencySpec.cs index b5da722..e611bee 100644 --- a/tests/NodaMoney.Tests/CurrencySpec.cs +++ b/tests/NodaMoney.Tests/CurrencySpec.cs @@ -459,4 +459,19 @@ public void WhenCreatingOneMillion_ThenItShouldBeWithinFourSeconds() sw.ElapsedMilliseconds / (max)); } } + + public class GivenIWantToDeconstructCurrency + { + [Fact] + public void WhenDeconstructing_ThenShouldSucceed() + { + var currency = Currency.FromCode("EUR"); + + var (code, number, symbol) = currency; + + code.Should().Be("EUR"); + number.Should().Be("978"); + symbol.Should().Be("€"); + } + } } \ No newline at end of file diff --git a/tests/NodaMoney.Tests/ExchangeRateSpec.cs b/tests/NodaMoney.Tests/ExchangeRateSpec.cs index 1f3b69b..d6bb9cc 100644 --- a/tests/NodaMoney.Tests/ExchangeRateSpec.cs +++ b/tests/NodaMoney.Tests/ExchangeRateSpec.cs @@ -357,4 +357,19 @@ public void WhenTheAreEquel_ThenComparingShouldBeTrueOtherwiseFalse(ExchangeRate (fx1 != fx2).Should().Be(!areEqual); //using Euality operators } } + + public class GivenIWantToDeconstructExchangeRate + { + [Fact] + public void WhenDeconstructing_ThenShouldSucceed() + { + var fx = new ExchangeRate(Currency.FromCode("EUR"), Currency.FromCode("USD"), 1.2591m); + + var (baseCurrency, quoteCurrency, rate) = fx; + + rate.Should().Be(1.2591m); + baseCurrency.Should().Be(Currency.FromCode("EUR")); + quoteCurrency.Should().Be(Currency.FromCode("USD")); + } + } } diff --git a/tests/NodaMoney.Tests/MoneySpec.cs b/tests/NodaMoney.Tests/MoneySpec.cs index 77614dd..981d964 100644 --- a/tests/NodaMoney.Tests/MoneySpec.cs +++ b/tests/NodaMoney.Tests/MoneySpec.cs @@ -426,4 +426,18 @@ public void WhenValueIsVerySmall_ThenCreatingShouldSucceed() _output.WriteLine(result4); } } + + public class GivenIWantToDeconstructMoney + { + [Fact] + public void WhenDeconstructing_ThenShouldSucceed() + { + var money = new Money(10m, "EUR"); + + var (amount, currency) = money; + + amount.Should().Be(10m); + currency.Should().Be(Currency.FromCode("EUR")); + } + } } \ No newline at end of file diff --git a/tests/NodaMoney.Tests/MoneyUnaryOperatoresTests.cs b/tests/NodaMoney.Tests/MoneyUnaryOperatoresTests.cs index adfbd21..7bafd61 100644 --- a/tests/NodaMoney.Tests/MoneyUnaryOperatoresTests.cs +++ b/tests/NodaMoney.Tests/MoneyUnaryOperatoresTests.cs @@ -65,24 +65,31 @@ public void WhenDecrementing_ThenAmountShouldDecrementWithMinorUnit() public class GivenIWantToAddAndSubtractMoneyUnary { - private readonly Money _tenEuro = new Money(10.00m, "EUR"); + private readonly Money _tenEuroPlus = new Money(10.00m, "EUR"); + private readonly Money _tenEuroMin = new Money(-10.00m, "EUR"); [Fact] public void WhenUsingUnaryPlusOperator_ThenThisSucceed() { - var m = +_tenEuro; + var r1 = +_tenEuroPlus; + var r2 = +_tenEuroMin; - m.Amount.Should().Be(10.00m); - m.Currency.Code.Should().Be("EUR"); + r1.Amount.Should().Be(10.00m); + r1.Currency.Code.Should().Be("EUR"); + r2.Amount.Should().Be(-10.00m); + r2.Currency.Code.Should().Be("EUR"); } [Fact] public void WhenUsingUnaryMinOperator_ThenThisSucceed() { - var m = -_tenEuro; + var r1 = -_tenEuroPlus; + var r2 = -_tenEuroMin; - m.Amount.Should().Be(-10.00m); - m.Currency.Code.Should().Be("EUR"); + r1.Amount.Should().Be(-10.00m); + r1.Currency.Code.Should().Be("EUR"); + r2.Amount.Should().Be(10.00m); + r2.Currency.Code.Should().Be("EUR"); } } } diff --git a/tests/NodaMoney.Tests/NodaMoney.Tests.csproj b/tests/NodaMoney.Tests/NodaMoney.Tests.csproj index f952ccb..38ba1bb 100644 --- a/tests/NodaMoney.Tests/NodaMoney.Tests.csproj +++ b/tests/NodaMoney.Tests/NodaMoney.Tests.csproj @@ -13,6 +13,7 @@ + From 6dcc51fd299cf97cacdede188941aab50cd66ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20van=20Duijkeren?= Date: Sun, 17 Dec 2017 18:34:42 +0100 Subject: [PATCH 4/4] Added Serialization Unit test --- src/NodaMoney/Money.cs | 1 - .../NodaMoney.Tests/MoneySerializableSpec.cs | 506 +++++++++--------- 2 files changed, 242 insertions(+), 265 deletions(-) diff --git a/src/NodaMoney/Money.cs b/src/NodaMoney/Money.cs index 059d69c..3849598 100644 --- a/src/NodaMoney/Money.cs +++ b/src/NodaMoney/Money.cs @@ -12,7 +12,6 @@ namespace NodaMoney /// and ensure that two different currencies cannot be added or subtracted to each other. /// [StructLayout(LayoutKind.Sequential)] - [DataContract] public partial struct Money : IEquatable { /// Initializes a new instance of the struct, based on the current culture. diff --git a/tests/NodaMoney.Tests/MoneySerializableSpec.cs b/tests/NodaMoney.Tests/MoneySerializableSpec.cs index 3999d21..99c10fb 100644 --- a/tests/NodaMoney.Tests/MoneySerializableSpec.cs +++ b/tests/NodaMoney.Tests/MoneySerializableSpec.cs @@ -1,264 +1,242 @@ -//using System; -//using System.IO; -//using System.Runtime.Serialization; -////using System.Runtime.Serialization.Formatters.Binary; -//using System.Xml; -//using System.Xml.Serialization; -//using FluentAssertions; -//using Xunit; -//using Newtonsoft.Json; -//using NodaMoney.Serialization.JsonNet; - -//using Formatting = Newtonsoft.Json.Formatting; - -//namespace NodaMoney.Tests.MoneySerializableSpec -//{ -// public class MoneySerializableTests -// { -// public static string StreamToString(Stream stream) -// { -// stream.Position = 0; -// using (var reader = new StreamReader(stream)) -// { -// return reader.ReadToEnd(); -// } -// } - -// public class GivenIWantToSerializeMoneyWithJsonNetSerializer -// { -// private Money yen = new Money(765m, Currency.FromCode("JPY")); -// private Money euro = new Money(765.43m, Currency.FromCode("EUR")); - -// [Fact] -// public void WhenSerializingYen_ThenThisShouldSucceed() -// { -// string json = JsonConvert.SerializeObject(yen); -// Console.WriteLine(json); -// var clone = JsonConvert.DeserializeObject(json); - -// clone.Should().Be(yen); -// } - -// [Fact] -// public void WhenSerializingEuro_ThenThisShouldSucceed() -// { -// string json = JsonConvert.SerializeObject(euro, Formatting.None, new MoneyJsonConverter()); -// Console.WriteLine(json); -// var clone = JsonConvert.DeserializeObject(json, new MoneyJsonConverter()); - -// clone.Should().Be(euro); -// } -// } - -// public class GivenIWantToSerializeMoneyWithDataContractJsonSerializer -// { -// private Money yen = new Money(765m, Currency.FromCode("JPY")); -// private Money euro = new Money(765.43m, Currency.FromCode("EUR")); - -// [Fact] -// public void WhenSerializingYen_ThenThisShouldSucceed() -// { -// Console.WriteLine(StreamToString(Serialize(yen))); - -// yen.Should().Be(Clone(yen)); -// } - -// [Fact] -// public void WhenSerializingEuro_ThenThisShouldSucceed() -// { -// Console.WriteLine(StreamToString(Serialize(euro))); - -// euro.Should().Be(Clone(euro)); -// } - -// public static Stream Serialize(object source) -// { -// Stream stream = new MemoryStream(); -// DataContractSerializer serializer = new DataContractSerializer(source.GetType()); -// serializer.WriteObject(stream, source); -// return stream; - -// //MemoryStream stream = new MemoryStream(); -// //DataContractJsonSerializer serializer = new DataContractJsonSerializer(source.GetType()); -// //serializer.WriteObject(stream, source); -// //string json = Encoding.UTF8.GetString(stream.ToArray()); -// //stream.Close(); - -// //return json; -// } - -// public static T Deserialize(Stream stream) -// { -// stream.Position = 0L; -// using (var reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas())) -// { -// var serializer = new DataContractSerializer(typeof(T)); -// return (T)serializer.ReadObject(reader, true); -// } - -// //DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); -// //MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); -// //return (T)serializer.ReadObject(stream); -// } -// private static T Clone(object source) -// { -// return Deserialize(Serialize(source)); -// } -// } - -// [DataContract] -// public class Article -// { -// [DataMember] -// public int Id { get; set; } -// [DataMember] -// public string Name { get; set; } -// [DataMember] -// public Money Amount { get; set; } -// } - -// public class GivenIWantToSerializeMoneyWithDataContractSerializer -// { -// private Money yen = new Money(765m, Currency.FromCode("JPY")); -// private Money euro = new Money(765.43m, Currency.FromCode("EUR")); - -// [Fact] -// public void WhenSerializingYen_ThenThisShouldSucceed() -// { -// Console.WriteLine(StreamToString(Serialize(yen))); - -// yen.Should().Be(Clone(yen)); -// } - -// [Fact] -// public void WhenSerializingEuro_ThenThisShouldSucceed() -// { -// Console.WriteLine(StreamToString(Serialize(euro))); - -// euro.Should().Be(Clone(euro)); -// } - -// [Fact] -// public void WhenSerializingArticle_ThenThisShouldSucceed() -// { -// var article = new Article -// { -// Id = 123, -// Amount = Money.Euro(27.15), -// Name = "Foo" -// }; - -// Console.WriteLine(StreamToString(Serialize(article))); - -// article.Amount.Should().Be(Clone
(article).Amount); -// } - -// public static Stream Serialize(object source) -// { -// Stream stream = new MemoryStream(); -// DataContractSerializer serializer = new DataContractSerializer(source.GetType()); -// serializer.WriteObject(stream, source); -// return stream; -// } - -// public static T Deserialize(Stream stream) -// { -// stream.Position = 0L; -// using (var reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas())) -// { -// var serializer = new DataContractSerializer(typeof(T)); -// return (T)serializer.ReadObject(reader, true); -// } -// } - -// private static T Clone(object source) -// { -// return Deserialize(Serialize(source)); -// } -// } - -// public class GivenIWantToSerializeMoneyWitXmlSerializer -// { -// private Money yen = new Money(765m, Currency.FromCode("JPY")); -// private Money euro = new Money(765.43m, Currency.FromCode("EUR")); - -// [Fact] -// public void WhenSerializingYen_ThenThisShouldSucceed() -// { -// Console.WriteLine(StreamToString(Serialize(yen))); - -// yen.Should().Be(Clone(yen)); -// } - -// [Fact] -// public void WhenSerializingEuro_ThenThisShouldSucceed() -// { -// Console.WriteLine(StreamToString(Serialize(euro))); - -// euro.Should().Be(Clone(euro)); -// } - -// public static Stream Serialize(object source) -// { -// Stream stream = new MemoryStream(); -// XmlSerializer xmlSerializer = new XmlSerializer(source.GetType()); -// xmlSerializer.Serialize(stream, source); -// return stream; -// } - -// public static T Deserialize(Stream stream) -// { -// stream.Position = 0L; -// XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); -// return (T)xmlSerializer.Deserialize(stream); -// } - -// private static T Clone(object source) -// { -// return Deserialize(Serialize(source)); -// } -// } - -// //public class GivenIWantToSerializeMoneyWithBinaryFormatter -// //{ -// // private Money yen = new Money(765m, Currency.FromCode("JPY")); -// // private Money euro = new Money(765.43m, Currency.FromCode("EUR")); - -// // [Fact(Skip = "Not possible with PCL")] -// // public void WhenSerializingYen_ThenThisShouldSucceed() -// // { -// // Console.WriteLine(StreamToString(Serialize(yen))); - -// // yen.Should().Be(Clone(yen)); -// // } - -// // [Fact(Skip = "Not possible with PCL")] -// // public void WhenSerializingEuro_ThenThisShouldSucceed() -// // { -// // Console.WriteLine(StreamToString(Serialize(euro))); - -// // euro.Should().Be(Clone(euro)); -// // } - -// // public static Stream Serialize(object source) -// // { -// // IFormatter formatter = new BinaryFormatter(); -// // Stream stream = new MemoryStream(); -// // formatter.Serialize(stream, source); -// // return stream; -// // } - -// // public static T Deserialize(Stream stream) -// // { -// // IFormatter formatter = new BinaryFormatter(); -// // stream.Position = 0L; -// // return (T)formatter.Deserialize(stream); -// // } - -// // public static T Clone(object source) -// // { -// // return Deserialize(Serialize(source)); -// // } -// //} -// } -//} +using System; +using System.IO; +using System.Runtime.Serialization; +//using System.Runtime.Serialization.Formatters.Binary; +using System.Xml; +using System.Xml.Serialization; +using FluentAssertions; +using Xunit; +using Newtonsoft.Json; +using NodaMoney.Serialization.JsonNet; + +using Formatting = Newtonsoft.Json.Formatting; + +namespace NodaMoney.Tests.MoneySerializableSpec +{ + public class MoneySerializableTests + { + public static string StreamToString(Stream stream) + { + stream.Position = 0; + using (var reader = new StreamReader(stream)) + { + return reader.ReadToEnd(); + } + } + + public class GivenIWantToSerializeMoneyWithJsonNetSerializer + { + private Money yen = new Money(765m, Currency.FromCode("JPY")); + private Money euro = new Money(765.43m, Currency.FromCode("EUR")); + + [Fact] + public void WhenSerializingYen_ThenThisShouldSucceed() + { + string json = JsonConvert.SerializeObject(yen); + Console.WriteLine(json); + var clone = JsonConvert.DeserializeObject(json); + + clone.Should().Be(yen); + } + + [Fact] + public void WhenSerializingEuro_ThenThisShouldSucceed() + { + string json = JsonConvert.SerializeObject(euro, Formatting.None, new MoneyJsonConverter()); + Console.WriteLine(json); + var clone = JsonConvert.DeserializeObject(json, new MoneyJsonConverter()); + + clone.Should().Be(euro); + } + + [Fact] + public void WhenSerializingArticle_ThenThisShouldSucceed() + { + var article = new Article + { + Id = 123, + Amount = Money.Euro(27.15), + Name = "Foo" + }; + + string json = JsonConvert.SerializeObject(article, Formatting.None, new MoneyJsonConverter()); + Console.WriteLine(json); + var clone = JsonConvert.DeserializeObject
(json, new MoneyJsonConverter()); + + clone.Id.Should().Be(article.Id); + clone.Name.Should().Be(article.Name); + clone.Amount.Should().Be(article.Amount); + //clone.Should().Be(article); + } + } + public class GivenIWantToSerializeMoneyWithDataContractSerializer + { + private Money yen = new Money(765m, Currency.FromCode("JPY")); + private Money euro = new Money(765.43m, Currency.FromCode("EUR")); + + [Fact] + public void WhenSerializingYen_ThenThisShouldSucceed() + { + Console.WriteLine(StreamToString(Serialize(yen))); + + yen.Should().Be(Clone(yen)); + } + + [Fact] + public void WhenSerializingEuro_ThenThisShouldSucceed() + { + Console.WriteLine(StreamToString(Serialize(euro))); + + euro.Should().Be(Clone(euro)); + } + + [Fact] + public void WhenSerializingArticle_ThenThisShouldSucceed() + { + var article = new Article + { + Id = 123, + Amount = Money.Euro(27.15), + Name = "Foo" + }; + + Console.WriteLine(StreamToString(Serialize(article))); + + article.Amount.Should().Be(Clone
(article).Amount); + } + + public static Stream Serialize(object source) + { + Stream stream = new MemoryStream(); + var serializer = new DataContractSerializer(source.GetType()); + serializer.WriteObject(stream, source); + return stream; + } + + public static T Deserialize(Stream stream) + { + stream.Position = 0L; + using (var reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas())) + { + var serializer = new DataContractSerializer(typeof(T)); + return (T)serializer.ReadObject(reader, true); + } + } + + private static T Clone(object source) + { + return Deserialize(Serialize(source)); + } + } + + public class GivenIWantToSerializeMoneyWitXmlSerializer + { + private Money yen = new Money(765m, Currency.FromCode("JPY")); + private Money euro = new Money(765.43m, Currency.FromCode("EUR")); + + [Fact] + public void WhenSerializingYen_ThenThisShouldSucceed() + { + Console.WriteLine(StreamToString(Serialize(yen))); + + yen.Should().Be(Clone(yen)); + } + + [Fact] + public void WhenSerializingEuro_ThenThisShouldSucceed() + { + Console.WriteLine(StreamToString(Serialize(euro))); + + euro.Should().Be(Clone(euro)); + } + + [Fact] + public void WhenSerializingArticle_ThenThisShouldSucceed() + { + var article = new Article + { + Id = 123, + Amount = Money.Euro(27.15), + Name = "Foo" + }; + + Console.WriteLine(StreamToString(Serialize(article))); + + article.Amount.Should().Be(Clone
(article).Amount); + } + + public static Stream Serialize(object source) + { + Stream stream = new MemoryStream(); + var xmlSerializer = new XmlSerializer(source.GetType()); + xmlSerializer.Serialize(stream, source); + return stream; + } + + public static T Deserialize(Stream stream) + { + stream.Position = 0L; + var xmlSerializer = new XmlSerializer(typeof(T)); + return (T)xmlSerializer.Deserialize(stream); + } + + private static T Clone(object source) + { + return Deserialize(Serialize(source)); + } + } + + [DataContract] + public class Article + { + [DataMember] + public int Id { get; set; } + [DataMember] + public string Name { get; set; } + [DataMember] + public Money Amount { get; set; } + } + + //public class GivenIWantToSerializeMoneyWithBinaryFormatter + //{ + // private Money yen = new Money(765m, Currency.FromCode("JPY")); + // private Money euro = new Money(765.43m, Currency.FromCode("EUR")); + + // [Fact(Skip = "Not possible with PCL")] + // public void WhenSerializingYen_ThenThisShouldSucceed() + // { + // Console.WriteLine(StreamToString(Serialize(yen))); + + // yen.Should().Be(Clone(yen)); + // } + + // [Fact(Skip = "Not possible with PCL")] + // public void WhenSerializingEuro_ThenThisShouldSucceed() + // { + // Console.WriteLine(StreamToString(Serialize(euro))); + + // euro.Should().Be(Clone(euro)); + // } + + // public static Stream Serialize(object source) + // { + // IFormatter formatter = new BinaryFormatter(); + // Stream stream = new MemoryStream(); + // formatter.Serialize(stream, source); + // return stream; + // } + + // public static T Deserialize(Stream stream) + // { + // IFormatter formatter = new BinaryFormatter(); + // stream.Position = 0L; + // return (T)formatter.Deserialize(stream); + // } + + // public static T Clone(object source) + // { + // return Deserialize(Serialize(source)); + // } + //} + } +}