├── .gitattributes ├── .gitignore ├── .nuget ├── NuGet.Config ├── NuGet.exe └── NuGet.targets ├── CHANGELOG.md ├── CONTRIBUTING.md ├── CreateNuget.cmd ├── DeployToNuget.cmd ├── HowToRelease.txt ├── LICENSE.md ├── README.md ├── Settings.StyleCop ├── StatePrinter.Tests ├── Configurations │ └── ConfigurationTest.cs ├── ExamplesForDocumentation │ ├── ExampleEndlessAsserts.cs │ ├── ExampleListAndArrays.cs │ └── ExampleOnSimpleAsserts.cs ├── FieldHarvesters │ ├── AllHarvesterTest.cs │ ├── AnonymousHarvesterTest.cs │ ├── ProjectionHarvesterByTypeTest.cs │ ├── ProjectionHarvesterTest.cs │ └── ToStringAwareHarvesterTest.cs ├── IntegrationTests │ ├── CallStackReflectorTest.cs │ ├── CultureTests.cs │ ├── DictionaryTest.cs │ ├── IEnumeratbleTest.cs │ ├── InheritanceTest.cs │ ├── ObjectGraphsTest.cs │ ├── PropertiesTest.cs │ ├── PublicPropertiesTest.cs │ ├── StandardConfigurationTest.cs │ ├── ToStringMethodTest.cs │ └── TwoDimensionArrayTest.cs ├── Introspection │ ├── ReferenceTest.cs │ └── TokenTest.cs ├── Mocks │ └── Mocks.cs ├── OutputFormatters │ ├── RollingGuidValueConverterTest.cs │ ├── StringBuilderTrimmerTest.cs │ └── TokenFilterTest.cs ├── PerformanceTests │ ├── ManySmallCollections.cs │ ├── ManySmallObjects.cs │ ├── PerformanceTestsBase.cs │ └── ToStringTests.cs ├── Properties │ └── AssemblyInfo.cs ├── StatePrinter.Tests.csproj ├── TestHelper.cs ├── TestingAssistance │ ├── EnvironmentReaderTest.cs │ ├── ParserTest.cs │ ├── ReWriterMockedTests.cs │ ├── TestingAssistanceReWriteTest.cs │ ├── TestingAssistanceTest.cs │ └── USerStory.cs ├── ValueConverters │ └── GenericValueConverterTest.cs └── packages.config ├── StatePrinter.nuspec ├── StatePrinter.sln ├── StatePrinter ├── Configurations │ ├── Configuration.cs │ ├── ConfigurationHelper.cs │ ├── LegacyBehaviour.cs │ └── TestingBehaviour.cs ├── FieldHarvesters │ ├── AllFieldsAndPropertiesHarvester.cs │ ├── AllFieldsHarvester.cs │ ├── AnonymousFieldHarvester.cs │ ├── HarvestHelper.cs │ ├── IFieldHarvester.cs │ ├── IRunTimeCodeGenerator.cs │ ├── ProjectionHarvester.cs │ ├── PublicFieldsAndPropertiesHarvester .cs │ ├── PublicFieldsHarvester.cs │ ├── RunTimeCodeGenerator.cs │ ├── SanitizedFieldInfo.cs │ └── ToStringAwareHarvester.cs ├── Introspection │ ├── HarvestInfoCache.cs │ ├── IntroSpector.cs │ ├── Reference.cs │ ├── ReflectionInfo.cs │ ├── Token.cs │ └── TokenType.cs ├── OutputFormatters │ ├── CurlyBraceStyle.cs │ ├── FastestPossibleStyle.cs │ ├── IOutputFormatter.cs │ ├── IndentingStringBuilder.cs │ ├── JsonStyle.cs │ ├── OutputFormatterHelpers.cs │ ├── StringBuilderTrimmer.cs │ ├── UnusedReferencesTokenFilter.cs │ └── XmlStyle.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Settings.StyleCop ├── StatePrinter.cs ├── StatePrinter.csproj ├── StatePrinterStrongNameKeyFile_DoNotDelete.snk ├── TestAssistance │ ├── Asserter.cs │ ├── DefaultAssertMessage.cs │ ├── EnvironmentReader.cs │ ├── FileRepository.cs │ ├── Parser.cs │ ├── StringUtils.cs │ └── TestRewriter.cs ├── ValueConverters │ ├── DateTimeConverter.cs │ ├── EnumConverter.cs │ ├── GenericValueConverter.cs │ ├── IValueConverter.cs │ ├── RollingGuidValueConverter.cs │ ├── StandardTypesConverter.cs │ └── StringConverter.cs └── gfx │ ├── stateprinter.ico │ └── stateprinter.png ├── appveyor.yml └── doc ├── AutomatingToStrings.md ├── AutomatingUnitTesting.md ├── ComprehensibleTestingOfGuids.md ├── HowToConfigure.md └── TheProblemsWithTraditionalUnitTesting.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * eol=crlf 3 | 4 | # Denote all files that are truly binary and should not be modified. 5 | *.snk binary 6 | *.exe binary 7 | 8 | *.dll binary 9 | *.png binary 10 | *.jpg binary 11 | *.gif binary 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | .vs/ 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Rr]elease/ 20 | x64/ 21 | *_i.c 22 | *_p.c 23 | *.ilk 24 | *.meta 25 | *.obj 26 | *.pch 27 | *.pdb 28 | *.pgc 29 | *.pgd 30 | *.rsp 31 | *.sbr 32 | *.tlb 33 | *.tli 34 | *.tlh 35 | *.tmp 36 | *.log 37 | *.vspscc 38 | *.vssscc 39 | .builds 40 | 41 | 42 | # Visual Studio profiler 43 | *.psess 44 | *.vsp 45 | *.vspx 46 | 47 | # Guidance Automation Toolkit 48 | *.gpState 49 | 50 | # ReSharper is a .NET coding add-in 51 | _ReSharper* 52 | 53 | # NCrunch 54 | *.ncrunch* 55 | .*crunch*.local.xml 56 | _NCrunch_* 57 | 58 | # Installshield output folder 59 | [Ee]xpress 60 | 61 | # DocProject is a documentation generator add-in 62 | DocProject/buildhelp/ 63 | DocProject/Help/*.HxT 64 | DocProject/Help/*.HxC 65 | DocProject/Help/*.hhc 66 | DocProject/Help/*.hhk 67 | DocProject/Help/*.hhp 68 | DocProject/Help/Html2 69 | DocProject/Help/html 70 | 71 | # Click-Once directory 72 | publish 73 | 74 | # Publish Web Output 75 | *.Publish.xml 76 | 77 | # NuGet Packages Directory 78 | packages 79 | nuget_packages/ 80 | 81 | # Windows Azure Build Output 82 | csx 83 | *.build.csdef 84 | 85 | # Windows Store app package directory 86 | AppPackages/ 87 | 88 | # Others 89 | [Bb]in 90 | [Oo]bj 91 | sql 92 | TestResults 93 | [Tt]est[Rr]esult* 94 | *.Cache 95 | ClientBin 96 | [Ss]tyle[Cc]op.* 97 | ~$* 98 | *.dbmdl 99 | Generated_Code #added for RIA/Silverlight projects 100 | 101 | # Backup & report files from converting an old project file to a newer 102 | # Visual Studio version. Backup files are not needed, because we have git ;-) 103 | _UpgradeReport_Files/ 104 | Backup*/ 105 | UpgradeLog*.XML 106 | /.project 107 | 108 | *.orig 109 | -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbilsted/StatePrinter/76e70caf955303a39116dbf4e750efb9fcea1972/.nuget/NuGet.exe -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ![](https://raw.github.com/kbilsted/StatePrinter/master/StatePrinter/gfx/stateprinter.png) 2 | 3 | # Version history 4 | 5 | Full documentation on usage and motivating examples at https://github.com/kbilsted/StatePrinter/tree/master/doc 6 | 7 | ## V4.0 (unreleased) 8 | * Requires .NET Framework 4.7.2 9 | * Added `TestingBehaviour.SetAreEqualsMethod()` for easier integration with NUnit v3.x 10 | * Removed all obsolete functionality. 11 | 12 | ## 3.0.1 (last version for .NET framework 3.5) 13 | * Issue #48 Added `AnonymousFieldHarvester` for convenience 14 | * Issue #49 bugfix parsing brackets 15 | * Issue #51 bugfix thread problem 16 | * Performance improvements between 5%-40% 17 | 18 | ## v3.0 19 | * Issue #38 fixed root name 20 | * Issue #40 fixed output format for xml and json 21 | * Issue #46, changed namespace from "Stateprinter" to "Stateprinting" in order for the project to be usable from VB# 22 | * 10% speed up 23 | * Changed the namespace from "StatePrinter" to "StatePrinting" in order to be CLS compliant (cross language support) 24 | 25 | 26 | 27 | ## v2.2.xxx-pr 28 | 29 | * #43 Bugfix `\` in expected data failed on unit test rewrite due to lack of escaping. 30 | 31 | 32 | ## v2.2.281-pr 33 | * Caching run-time generated getter methods. 34 | 35 | ## v2.2.274-pr 36 | 37 | Added 38 | * Improved performance by 10% for curly and json outputformatters 39 | * #28 - General **50%-70% times speed up** of execution speed due to run-time code generation of reflection 40 | * #31 - `RollingGuidValueConverter` - Unit testing data containing Guid's just became much easier 41 | * Bugfixed the Json and Xml outputformatters when outputting dictionary/enumerables as the root element. 42 | 43 | 44 | ## v2.1.220 45 | 46 | Added 47 | 48 | * Functionality for controlling automatic test rewrite using an environment variable. 49 | * Functionality for including or excluding fields and properties based on one or more type descriptions. See `IncludeByType()` and `ExcludeByType()`. 50 | * Added `AreAlike()`, replacing `IsSame()` (which is deprecated). Similar story for `PrintAreAlike` replacing `PrintIsSame()`. 51 | * Made error message tell about `AreAlike()` when two strings are alike but not equals, when using `AreEquals()`. 52 | * Prepared for future expansion of functionality, by placing unit testing configuration in a sub-configuration class. 53 | * Obsoleted a lot of methods, describing the alternative API introduced in v2.1 54 | 55 | 56 | Fixed 57 | 58 | * [#22 Make error message configurable upon assertion failure](https://github.com/kbilsted/StatePrinter/issues/22) 59 | 60 | 61 | 62 | 63 | ## v2.0.169 64 | 65 | Added 66 | 67 | * Added automatic unit test rewriting 68 | * Added configuration of how line-endings are generated during state printing. This is to mitigate problems due to different operating systems uses different line-endings. 69 | * Added assertion helper methods `Stateprinter.Assert.AreEqual`, `Stateprinter.Assert.IsSame`, `Stateprinter.Assert.PrintIsSame` and `Stateprinter.Assert.That`. Improves the unit test experience by printing a suggested expected string as C# code. 70 | * Added a `AllFieldsAndPropertiesHarvester` which is able to harvest properties and fields. 71 | * `StringConverter` is now configurable with respect to quote character. 72 | * BREAKING CHANGE: Projective harvester is now using the `AllFieldsAndPropertiesHarvester` rather instead of the `FieldHarvester`. This means both fields and properties are now harvested. 73 | 74 | 75 | ## v1.0.6 76 | 77 | Added 78 | 79 | * Executing stylecop on the build server. 80 | * Made the `Configuration` class API a bit more fluent 81 | * BUGFIX: Harvesting of types were cached across `Stateprinter` instances, which no longer makes sense since harvesting is configurable from instance to instance. 82 | * BUGFIX: Changed how `ToString()` methods are harvested. Thanks to "Sjdirect". 83 | 84 | 85 | ## v1.0.5 86 | 87 | Added 88 | 89 | * Support for using the native `ToString()` implementation on types through a field harvester 90 | * Added a Projective field harvester to easily reduce the harvesting of selective fields on types in a type-safe manner. See the section on unit testing in the readme.md 91 | * Added the type `Stateprinter` and obsoleted the `StatePrinter` type 92 | 93 | 94 | ## v1.0.4 95 | 96 | 97 | Added 98 | 99 | * CLS compliance 100 | * 20% Performance boost 101 | 102 | 103 | 104 | Have fun! 105 | 106 | Kasper B. Graversen 107 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | All input welcome.. 2 | -------------------------------------------------------------------------------- /CreateNuget.cmd: -------------------------------------------------------------------------------- 1 | if not exist .\nuget_packages mkdir nuget_packages 2 | if not exist .\distro mkdir distro 3 | xcopy StatePrinter\*.cs distro\src\ /Y /Q /E 4 | xcopy StatePrinter\bin\Debug\*.dll distro\lib\net472\ /Q 5 | xcopy StatePrinter.nuspec distro\ /Q 6 | cd distro 7 | 8 | ..\.nuget\nuget.exe pack StatePrinter.nuspec -symbols -Prop Platform=AnyCPU 9 | 10 | xcopy *.nupkg ..\nuget_packages\ /Y /Q 11 | 12 | pause 13 | cd .. 14 | rmdir distro /s /q 15 | -------------------------------------------------------------------------------- /DeployToNuget.cmd: -------------------------------------------------------------------------------- 1 | REM ON FIRST RUN, RUN THIS (change the key to whatever is found on your profile on www.nuget.org -> 2 | REM .nuget\NuGet.exe setapikey e39ea-get-the-full-key-on-nuget.org 3 | 4 | call CreateNuget.cmd 5 | .nuget\NuGet.exe push nuget_packages\StatePrinter.4.*.*.symbols.nupkg 6 | .nuget\NuGet.exe push nuget_packages\StatePrinter.4.*.*.nupkg 7 | 8 | cd nuget_packages 9 | del /q * 10 | cd .. 11 | rmdir nuget_packages 12 | 13 | pause -------------------------------------------------------------------------------- /HowToRelease.txt: -------------------------------------------------------------------------------- 1 | Steps for creating a new release 2 | -------------------------------- 3 | 4 | * Edit Stateprinter/Properties/Assemblyinfo.cs 5 | * Edit appveyor.yml 6 | * Update CHANGELOG.md 7 | * Update StatePrinter.nuspec 8 | * Run DeployToNuget.cmd 9 | * Add release on github.com 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![](https://raw.github.com/kbilsted/StatePrinter/master/StatePrinter/gfx/stateprinter.png) StatePrinter 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/vx0nl4y4iins506u/branch/master?svg=true)](https://ci.appveyor.com/project/kbilsted/stateprinter/branch/master) 4 | [![Nuget](https://img.shields.io/nuget/dt/stateprinter.svg)](http://nuget.org/packages/stateprinter) 5 | [![Nuget](https://img.shields.io/nuget/v/stateprinter.svg)](http://nuget.org/packages/stateprinter) 6 | [![Nuget](https://img.shields.io/nuget/vpre/stateprinter.svg)](http://nuget.org/packages/stateprinter) 7 | [![Coverage Status](https://coveralls.io/repos/kbilsted/StatePrinter/badge.svg?branch=master)](https://coveralls.io/r/kbilsted/StatePrinter?branch=master) 8 | [![License](http://img.shields.io/badge/License-Apache_2-red.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0) 9 | [![Stats](https://img.shields.io/badge/Code_lines-4,1_K-ff69b4.svg)]() 10 | [![Stats](https://img.shields.io/badge/Doc_lines-2,1_K-ff69b4.svg)]() 11 | 12 | [![Join the chat at https://gitter.im/kbilsted/StatePrinter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/kbilsted/StatePrinter?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 13 | 14 | 15 | **THIS PROJECT IS BEING SUPERSEDED BY *ReassureTest*! GO TO https://github.com/kbilsted/ReassureTest.Net** 16 | 17 | 18 | 19 |
20 |
21 |
22 | 23 | # What is Stateprinter 24 | A simple framework for **automating** aspects of implementing `ToString()`-methods, unit testing, and debugging. Speed is achieved through **run-time code generation** and caching. 25 | 26 | Why you should take StatePrinter for a spin 27 | 28 | * *No more manual `ToString()`* - it is much easier to write robust and self-sufficient `ToString()` methods. Seamless integration into a code-base with manually implemented ToString-methods. 29 | * *No more manual writing/updating Asserts* - both for new tests and when the code changes, all tests can automatically be corrected. 30 | * *No more screens full of asserts*. Especially testing against object-graphs is a bliss. 31 | * Very configurable and extensible. 32 | * It is part of the back-end engine of other projects 33 | * The very nice [ApprovalTests framework](http://approvaltests.sourceforge.net/). 34 | 35 | 36 | 37 | ## How do I get started 38 | 39 | The documentation is split into 40 | 41 | * [Automating ToString methods](https://github.com/kbilsted/StatePrinter/blob/master/doc/AutomatingToStrings.md) 42 | 43 | and 44 | 45 | * [Automating unit testing](https://github.com/kbilsted/StatePrinter/blob/master/doc/AutomatingUnitTesting.md) 46 | * [The problems with traditional unit testing (that stateprinter solves)](https://github.com/kbilsted/StatePrinter/blob/master/doc/TheProblemsWithTraditionalUnitTesting.md) 47 | 48 | and 49 | 50 | * [Configuration and exension](https://github.com/kbilsted/StatePrinter/blob/master/doc/HowToConfigure.md) 51 | 52 | 53 | ## Where can I get it? 54 | Install Stateprinter from the package manager console: 55 | 56 | ``` 57 | PM> Install-Package StatePrinter 58 | ``` 59 | 60 | And for pre-release versions 61 | 62 | ``` 63 | PM> Install-Package StatePrinter -Pre 64 | ``` 65 | 66 | 67 | ## How can I get help? 68 | For quick questions, [Stack Overflow](http://stackoverflow.com/questions/tagged/stateprinter?sort=newest) is your best bet. For harder questions, bugs, issues or feature requests, [create a GitHub Issue (and let's chat)](https://github.com/kbilsted/StatePrinter/issues/new). 69 | 70 | 71 | 72 | ## How can I help out 73 | Everyone is encouraged to help improve this project. Here are a few ways you can help: 74 | * Blog about your experinces with the tool. We highly need publicity. I'll gladly link from here to your blog. 75 | * [Report bugs](https://github.com/kbilsted/StatePrinter/issues/new) 76 | * [Fix issues](https://github.com/kbilsted/StatePrinter/issues/) and submit pull requests 77 | * Write, clarify, or fix [the documentation](doc/) 78 | * [Suggest](https://github.com/kbilsted/StatePrinter/issues/new) or add new features 79 | 80 | 81 | *StatePrinter has been awarded a ReSharper group license, to share among all active contributers*. 82 | 83 | 84 | 85 | ## Versioning 86 | Stateprinter is maintained under the Semantic Versioning guidelines as much as possible. Releases will be numbered with the following format: 87 | 88 | `..` 89 | 90 | and constructed with the following guidelines: 91 | 92 | * Breaking backward compatibility bumps the major 93 | * New additions without breaking backward compatibility bumps the minor 94 | * Bug fixes and misc changes increase the build number 95 | 96 | For more information on SemVer, please visit http://semver.org/. 97 | 98 | 99 | 100 | ## History 101 | Version History: http://github.com/kbilsted/StatePrinter/blob/master/CHANGELOG.md 102 | 103 | This file describes the latest pushed changes. For documentation of earlier releases see: 104 | [1.0.6](https://github.com/kbilsted/StatePrinter/blob/1.0.6/README.md), [1.0.5](https://github.com/kbilsted/StatePrinter/blob/1.0.5/README.md), [1.0.4](https://github.com/kbilsted/StatePrinter/blob/1.0.4/README.md) 105 | 106 | Upgrading from v1.xx to v2.0.x should be a matter of configuring the `Configuration.LegacyBehaviour` 107 | 108 | Upgrading from v2.0 to v2.1 simply follow the documentation in the obsolete attributes. 109 | 110 | 111 | 112 | 113 | ## Requirements 114 | Requires .NET 3.5 or newer. 115 | 116 | 117 | 118 | 119 | ## License 120 | Stateprinter is under the Apache License 2.0, meaning that you can freely use this in other open source or commercial products. If you use it for commercial products please have the courtesy to leave me an email with a 'thank you'. 121 | 122 | 123 | 124 | 125 | **THIS PROJECT IS BEING SUPERSEDED BY *ReassureTest*! GO TO https://github.com/kbilsted/ReassureTest.Net** 126 | 127 | 128 | 129 | 130 | Have fun! 131 | 132 | Kasper B. Graversen 133 | -------------------------------------------------------------------------------- /StatePrinter.Tests/Configurations/ConfigurationTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using NUnit.Framework; 23 | using NUnit.Framework.Internal; 24 | using StatePrinting.Configurations; 25 | using StatePrinting.FieldHarvesters; 26 | using StatePrinting.TestAssistance; 27 | using StatePrinting.ValueConverters; 28 | 29 | namespace StatePrinting.Tests.Configurations 30 | { 31 | [TestFixture] 32 | class ConfigurationTest 33 | { 34 | [Test] 35 | public void TryFind() 36 | { 37 | var config = new Configuration(); 38 | config.Add(new StandardTypesConverter(null)); 39 | 40 | IValueConverter h; 41 | Assert.IsTrue(config.TryGetValueConverter(typeof(decimal), out h)); 42 | Assert.IsTrue(h is StandardTypesConverter); 43 | } 44 | 45 | [Test] 46 | public void SettingNullValues() 47 | { 48 | var sut = new Configuration(); 49 | Assert.Throws(() => sut.SetCulture(null)); 50 | Assert.Throws(() => sut.SetIndentIncrement(null)); 51 | Assert.Throws(() => sut.SetNewlineDefinition(null)); 52 | Assert.Throws(() => sut.SetOutputFormatter(null)); 53 | 54 | Assert.Throws(() => sut.Add((IFieldHarvester)null)); 55 | Assert.Throws(() => sut.Add((IValueConverter)null)); 56 | 57 | Assert.Throws(() => sut.AddHandler(null, t => new List())); 58 | Assert.Throws(() => sut.AddHandler(t => true, null)); 59 | Assert.Throws(() => sut.AddHandler(null, null)); 60 | 61 | Assert.Throws(() => sut.Test.SetAreEqualsMethod((TestFrameworkAreEqualsMethod) null)); 62 | Assert.Throws(() => sut.Test.SetAutomaticTestRewrite(null)); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /StatePrinter.Tests/ExamplesForDocumentation/ExampleEndlessAsserts.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using NUnit.Framework; 22 | 23 | namespace StatePrinting.Tests.ExamplesForDocumentation 24 | { 25 | [TestFixture] 26 | class ExampleListAndArrays 27 | { 28 | 29 | [Test] 30 | public void EndlessAssertsAlternative() 31 | { 32 | var allocation = new AllocationData 33 | { 34 | Premium = 22, 35 | FixedCosts = 23, 36 | PremiumCosts = 140, 37 | Tax = 110 38 | }; 39 | 40 | var sut = new Allocator(); 41 | var allocateData = sut.CreateAllocation(allocation); 42 | 43 | var printer = TestHelper.CreateTestPrinter(); 44 | var expected = @"new AllocationDataResult() 45 | { 46 | Premium = 22 47 | OriginalDueDate = 01-01-2010 00:00:00 48 | Costs = new CostData() 49 | { 50 | MonthlyBillingFixedInternalCost = 38 51 | BillingInternalCost = 55 52 | MonthlyBillingFixedRunningRemuneration = 63 53 | MonthlyBillingFixedEstablishment = 53 54 | MonthlyBillingRegistration = 2 55 | } 56 | PremiumInternalCost = 1 57 | PremiumRemuneration = 2 58 | PremiumRegistration = 332 59 | PremiumEstablishment = 14 60 | PremiumInternalCostBeforeDiscount = 57 61 | PremiumInternalCostAfterDiscount = 37 62 | Tax = 110 63 | }"; 64 | printer.Assert.PrintAreAlike(expected, allocateData); 65 | } 66 | 67 | } 68 | 69 | class Allocator 70 | { 71 | public AllocationDataResult CreateAllocation(AllocationData allocation) 72 | { 73 | var allocateData = new AllocationDataResult(); 74 | allocateData.Premium = allocation.Premium; 75 | 76 | allocateData.OriginalDueDate = new DateTime(2010, 1, 1); 77 | 78 | allocateData.Costs = new CostData(); 79 | allocateData.Costs.MonthlyBillingFixedInternalCost = 38; 80 | allocateData.Costs.BillingInternalCost = 55; 81 | allocateData.Costs.MonthlyBillingFixedRunningRemuneration = 63; 82 | allocateData.Costs.MonthlyBillingFixedEstablishment = 53; 83 | allocateData.Costs.MonthlyBillingRegistration = 2; 84 | 85 | allocateData.PremiumInternalCost = 1; 86 | allocateData.PremiumRemuneration = 2; 87 | allocateData.PremiumRegistration = 332; 88 | allocateData.PremiumEstablishment = 14; 89 | 90 | allocateData.PremiumInternalCostBeforeDiscount = 57; 91 | allocateData.PremiumInternalCostAfterDiscount = 37; 92 | 93 | allocateData.Tax = allocation.Tax; 94 | return allocateData; 95 | } 96 | } 97 | 98 | class AllocationDataResult 99 | { 100 | public int Premium { get; set; } 101 | public DateTime OriginalDueDate { get; set; } 102 | public CostData Costs { get; set; } 103 | public int PremiumInternalCost { get; set; } 104 | public int PremiumRemuneration { get; set; } 105 | public int PremiumRegistration { get; set; } 106 | public int PremiumEstablishment { get; set; } 107 | public int PremiumInternalCostBeforeDiscount { get; set; } 108 | public int PremiumInternalCostAfterDiscount { get; set; } 109 | public int Tax { get; set; } 110 | } 111 | 112 | class CostData 113 | { 114 | public int MonthlyBillingFixedInternalCost { get; set; } 115 | public int BillingInternalCost { get; set; } 116 | public int MonthlyBillingFixedRunningRemuneration { get; set; } 117 | public int MonthlyBillingFixedEstablishment { get; set; } 118 | public int MonthlyBillingRegistration { get; set; } 119 | } 120 | 121 | class AllocationData 122 | { 123 | public int Premium { get; set; } 124 | public int FixedCosts { get; set; } 125 | public int PremiumCosts { get; set; } 126 | public int Tax { get; set; } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /StatePrinter.Tests/ExamplesForDocumentation/ExampleListAndArrays.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | 22 | namespace StatePrinting.Tests.ExamplesForDocumentation 23 | { 24 | [TestFixture] 25 | class ExampleEndlessAsserts 26 | { 27 | 28 | [Test] 29 | public void ExampleListAndArraysAlternative() 30 | { 31 | object products = 1; 32 | object vendors = 2; 33 | object year = 2222; 34 | int added1 = 0; 35 | int added2 = 0; 36 | int added3 = 0; 37 | var vendorManager = new TaxvendorManager(products, vendors, year); 38 | vendorManager.AddVendor(JobType.JobType1, added1); 39 | vendorManager.AddVendor(JobType.JobType2, added2); 40 | vendorManager.AddVendor(JobType.JobType3, added3); 41 | 42 | var expected = @"new VendorAllocation[]() 43 | { 44 | [0] = new VendorAllocation() 45 | { 46 | Allocation = 100 47 | Price = 20 48 | Share = 20 49 | } 50 | [1] = new VendorAllocation() 51 | { 52 | Allocation = 120 53 | Price = 550 54 | Share = 30 55 | } 56 | [2] = new VendorAllocation() 57 | { 58 | Allocation = 880 59 | Price = 11 60 | Share = 50 61 | } 62 | }"; 63 | 64 | TestHelper.Assert().PrintAreAlike(expected, vendorManager.VendorJobSplit); 65 | } 66 | } 67 | 68 | 69 | enum JobType 70 | { 71 | JobType3, 72 | JobType2, 73 | JobType1 74 | } 75 | 76 | class TaxvendorManager 77 | { 78 | public TaxvendorManager(object products, object vendors, object year) 79 | { 80 | VendorJobSplit = new VendorAllocation[] 81 | { 82 | new VendorAllocation(){Allocation = 100, Price = 20, Share = 20f}, 83 | new VendorAllocation(){Allocation = 120, Price = 550, Share = 30f}, 84 | new VendorAllocation(){Allocation = 880, Price = 11, Share = 50f}, 85 | }; 86 | } 87 | 88 | public VendorAllocation[] VendorJobSplit { get; set; } 89 | 90 | public void AddVendor(object jobType3, object added3) 91 | { 92 | 93 | } 94 | } 95 | 96 | class VendorAllocation 97 | { 98 | public int Allocation, Price; 99 | public float Share; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /StatePrinter.Tests/ExamplesForDocumentation/ExampleOnSimpleAsserts.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Globalization; 21 | using NUnit.Framework; 22 | using StatePrinting.TestAssistance; 23 | using StatePrinting.ValueConverters; 24 | 25 | namespace StatePrinting.Tests.ExamplesForDocumentation 26 | { 27 | [TestFixture] 28 | class ExampleOnSimpleAsserts 29 | { 30 | #region hidden 31 | object a = 1, b = 2, c = 3, d = 4; 32 | #endregion 33 | 34 | public Stateprinter CreatePrinter() 35 | { 36 | var printer = new Stateprinter(); 37 | printer.Configuration 38 | .SetCulture(CultureInfo.CreateSpecificCulture("en-US")) 39 | .Test.SetAreEqualsMethod(NUnit.Framework.Assert.AreEqual) 40 | .Test.SetAutomaticTestRewrite(filename => new EnvironmentReader().UseTestAutoRewrite()) 41 | .Test.SetAutomaticTestRewrite(filename => true) 42 | .Add(new StringConverter("")); 43 | 44 | return printer; 45 | } 46 | 47 | [Test] 48 | public void TestName() 49 | { 50 | var printer = CreatePrinter(); 51 | var sut = new AmountSplitter(); 52 | var actual = sut.Split(100, 3); 53 | 54 | printer.Assert.AreEqual("3", printer.PrintObject(actual.Length)); 55 | printer.Assert.AreEqual("33.333333333333333333333333333", printer.PrintObject(actual[0])); 56 | printer.Assert.AreEqual("33.333333333333333333333333333", printer.PrintObject(actual[1])); 57 | printer.Assert.AreEqual("33.333333333333333333333333333", printer.PrintObject(actual[2])); 58 | } 59 | 60 | [Test] 61 | public void TestImprovedSyntax() 62 | { 63 | var assert = CreatePrinter().Assert; 64 | var sut = new AmountSplitter(); 65 | var actual = sut.Split(100, 3); 66 | 67 | assert.PrintEquals("3", actual.Length); 68 | assert.PrintEquals("33.333333333333333333333333333", actual[0]); 69 | assert.PrintEquals("33.333333333333333333333333333", actual[1]); 70 | assert.PrintEquals("33.333333333333333333333333333", actual[2]); 71 | } 72 | 73 | 74 | 75 | [Test] 76 | public void TestProcessOrder() 77 | { 78 | var printer = CreatePrinter(); 79 | 80 | var sut = new OrderProcessor(a, b); 81 | var actual = sut.Process(c, d); 82 | 83 | printer.Assert.AreEqual("1", printer.PrintObject(actual.OrderNumber)); 84 | printer.Assert.AreEqual("X-mas present", printer.PrintObject(actual.OrderDescription)); 85 | printer.Assert.AreEqual("43", printer.PrintObject(actual.Total)); 86 | } 87 | 88 | [Test] 89 | public void TestProcessOrderImproved() 90 | { 91 | var assert = CreatePrinter().Assert; 92 | 93 | var sut = new OrderProcessor(a, b); 94 | var actual = sut.Process(c, d); 95 | 96 | assert.PrintEquals("1", actual.OrderNumber); 97 | assert.PrintEquals("X-mas present", actual.OrderDescription); 98 | assert.PrintEquals("43", actual.Total); 99 | } 100 | 101 | 102 | class AmountSplitter 103 | { 104 | public decimal[] Split(decimal amount, int parts) 105 | { 106 | var moneyBags = new decimal[parts]; 107 | for (int i = 0; i < parts; i++) 108 | moneyBags[i] = amount / parts; 109 | return moneyBags; 110 | } 111 | } 112 | 113 | class OrderProcessor 114 | { 115 | public OrderProcessor(object a, object b) 116 | { 117 | } 118 | 119 | public Order Process(object c, object d) 120 | { 121 | return new Order(1, "X-mas present"); 122 | } 123 | } 124 | } 125 | 126 | class Order 127 | { 128 | public int OrderNumber; 129 | public string OrderDescription; 130 | public decimal Total = 43; 131 | 132 | public Order(int orderNumber, string orderDescription) 133 | { 134 | this.OrderNumber = orderNumber; 135 | this.OrderDescription = orderDescription; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /StatePrinter.Tests/FieldHarvesters/AllHarvesterTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Linq; 21 | using NUnit.Framework; 22 | using StatePrinting.FieldHarvesters; 23 | using StatePrinting.Tests.IntegrationTests; 24 | 25 | namespace StatePrinting.Tests.FieldHarvesters 26 | { 27 | [TestFixture] 28 | class AllHarvesterTest 29 | { 30 | HarvestHelper helper = new HarvestHelper(); 31 | 32 | [Test] 33 | public void AllFieldsHarvestTest() 34 | { 35 | var harvester = new AllFieldsHarvester(); 36 | 37 | var fields = harvester.GetFields(typeof(Car)).Select(x => x.SanitizedName).ToArray(); 38 | CollectionAssert.AreEquivalent(new[] { "StereoAmplifiers", "steeringWheel", "Brand" }, fields); 39 | 40 | fields = harvester.GetFields(typeof(SteeringWheel)).Select(x => x.SanitizedName).ToArray(); 41 | CollectionAssert.AreEquivalent(new[] { "Size", "Grip", "Weight" }, fields); 42 | } 43 | 44 | [Test] 45 | public void PublicFieldsHarvesterTest() 46 | { 47 | var harvester = new PublicFieldsHarvester(); 48 | 49 | var fields = harvester.GetFields(typeof(Car)).Select(x => x.SanitizedName).ToArray(); 50 | CollectionAssert.AreEquivalent(new[] { "Brand" }, fields); 51 | 52 | fields = harvester.GetFields(typeof(SteeringWheel)).Select(x => x.SanitizedName).ToArray(); 53 | CollectionAssert.AreEquivalent(new string[0] { }, fields); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /StatePrinter.Tests/FieldHarvesters/AnonymousHarvesterTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using NUnit.Framework; 23 | using StatePrinting.Configurations; 24 | using StatePrinting.FieldHarvesters; 25 | 26 | namespace StatePrinting.Tests.FieldHarvesters 27 | { 28 | /// 29 | /// Shows how the can be used 30 | /// 31 | [TestFixture] 32 | class AnonymousHarvesterTest 33 | { 34 | class A 35 | { 36 | public string Name; 37 | } 38 | 39 | class B 40 | { 41 | public int Age; 42 | } 43 | 44 | [Test] 45 | public void SpecializedClassHandlerHandledClass() 46 | { 47 | Configuration cfg = ConfigurationHelper.GetStandardConfiguration(" "); 48 | AddAnonymousHandler(cfg); 49 | var sut = new Stateprinter(cfg); 50 | 51 | var expected = @"new B() 52 | { 53 | Age = ""Its age is 1"" 54 | }"; 55 | 56 | var actual = sut.PrintObject(new B { Age = 1 }); 57 | Assert.AreEqual(expected, actual); 58 | } 59 | 60 | [Test] 61 | public void SpecializedClassHandlerNotHandledClass() 62 | { 63 | var cfg = new Configuration(" "); 64 | AddAnonymousHandler(cfg); 65 | 66 | var sut = new Stateprinter(cfg); 67 | 68 | Assert.Throws(() => sut.PrintObject(new A { Name = "MyName" }), ""); 69 | } 70 | 71 | private void AddAnonymousHandler(Configuration cfg) 72 | { 73 | cfg.AddHandler( 74 | t => t == typeof(B), 75 | t => new List { new SanitizedFieldInfo(null, "Age", o => "Its age is " + ((B)o).Age) }); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /StatePrinter.Tests/FieldHarvesters/ProjectionHarvesterByTypeTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | using StatePrinting.TestAssistance; 22 | 23 | namespace StatePrinting.Tests.FieldHarvesters 24 | { 25 | [TestFixture] 26 | public class TypeFilteringTests 27 | { 28 | interface IA 29 | { 30 | int A { get; set; } 31 | } 32 | 33 | interface IB 34 | { 35 | int B { get; set; } 36 | } 37 | 38 | interface IC 39 | { 40 | int C { get; set; } 41 | } 42 | 43 | interface ID 44 | { 45 | int D { get; set; } 46 | } 47 | 48 | class AtoD : IA, IB, IC, ID 49 | { 50 | public int A { get; set; } 51 | public int B { get; set; } 52 | public int C { get; set; } 53 | public int D { get; set; } 54 | 55 | public AtoD() 56 | { 57 | A = 1; 58 | B = 2; 59 | C = 3; 60 | D = 4; 61 | } 62 | } 63 | 64 | [Test] 65 | public void TestIncludeByType() 66 | { 67 | var sut = new AtoD(); 68 | Asserter assert; 69 | 70 | assert = TestHelper.CreateShortAsserter(); 71 | assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut); 72 | 73 | assert = TestHelper.CreateShortAsserter(); 74 | assert.Project.IncludeByType(); 75 | assert.PrintEquals("new AtoD() { A = 1 }", sut); 76 | 77 | assert = TestHelper.CreateShortAsserter(); 78 | assert.Project.IncludeByType(); 79 | assert.PrintEquals("new AtoD() { A = 1 B = 2 }", sut); 80 | 81 | assert = TestHelper.CreateShortAsserter(); 82 | assert.Project.IncludeByType(); 83 | assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 }", sut); 84 | 85 | assert = TestHelper.CreateShortAsserter(); 86 | assert.Project.IncludeByType(); 87 | assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut); 88 | } 89 | 90 | [Test] 91 | public void TestExcludeByType() 92 | { 93 | var sut = new AtoD(); 94 | Asserter assert; 95 | 96 | assert = TestHelper.CreateShortAsserter(); 97 | assert.PrintEquals("new AtoD() { A = 1 B = 2 C = 3 D = 4 }", sut); 98 | 99 | assert = TestHelper.CreateShortAsserter(); 100 | assert.Project.ExcludeByType(); 101 | assert.PrintEquals("new AtoD() { B = 2 C = 3 D = 4 }", sut); 102 | 103 | assert = TestHelper.CreateShortAsserter(); 104 | assert.Project.ExcludeByType(); 105 | assert.PrintEquals("new AtoD() { C = 3 D = 4 }", sut); 106 | 107 | assert = TestHelper.CreateShortAsserter(); 108 | assert.Project.ExcludeByType(); 109 | assert.PrintEquals("new AtoD() { D = 4 }", sut); 110 | 111 | assert = TestHelper.CreateShortAsserter(); 112 | assert.Project.ExcludeByType(); 113 | assert.PrintEquals("new AtoD() { }", sut); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /StatePrinter.Tests/FieldHarvesters/ToStringAwareHarvesterTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | using StatePrinting.Configurations; 22 | using StatePrinting.FieldHarvesters; 23 | 24 | namespace StatePrinting.Tests.FieldHarvesters 25 | { 26 | /// 27 | /// Shows how the can be used 28 | /// 29 | [TestFixture] 30 | class ToStringAwareHarvesterTest 31 | { 32 | class A 33 | { 34 | public int X; 35 | 36 | int somePrivateVariable; 37 | //should not be printed since the PublicFieldsHarvester should be used if there is no explicit ToString() 38 | 39 | public B b = new B() { Age = 2 }; 40 | public void Dummy() 41 | { 42 | somePrivateVariable++; 43 | } 44 | } 45 | 46 | class B 47 | { 48 | public int Age; 49 | 50 | public override string ToString() 51 | { 52 | return "My age is " + Age; 53 | } 54 | } 55 | 56 | class C : B 57 | { 58 | public C() 59 | { 60 | Age = 42; 61 | } 62 | } 63 | 64 | [Test] 65 | public void Userstory_PrintUseToString_WhenDirectlyAvailable() 66 | { 67 | var sut = CreatePrinter(); 68 | var expected = @"new B() 69 | { 70 | ToString() = ""My age is 1"" 71 | }"; 72 | var actual = sut.PrintObject(new B { Age = 1 }); 73 | Assert.AreEqual(expected, actual); 74 | } 75 | 76 | [Test] 77 | public void Userstory_PrintUseToString_WhenAvailable() 78 | { 79 | var sut = CreatePrinter(); 80 | var expected = @"new A() 81 | { 82 | X = 1 83 | b = new B() 84 | { 85 | ToString() = ""My age is 2"" 86 | } 87 | }"; 88 | var actual = sut.PrintObject(new A { X = 1 }); 89 | Assert.AreEqual(expected, actual); 90 | } 91 | 92 | 93 | 94 | [Test] 95 | public void Userstory_PrintDontUseToString_WhenInherited() 96 | { 97 | var sut = CreatePrinter(); 98 | var expected = @"new A() 99 | { 100 | X = 1 101 | b = new C() 102 | { 103 | Age = 42 104 | } 105 | }"; 106 | var actual = sut.PrintObject(new A { X = 1, b = new C() }); 107 | Assert.AreEqual(expected, actual); 108 | } 109 | 110 | Stateprinter CreatePrinter() 111 | { 112 | Configuration cfg = ConfigurationHelper.GetStandardConfiguration(" "); 113 | cfg.Add(new PublicFieldsHarvester()); 114 | cfg.Add(new ToStringAwareHarvester()); 115 | 116 | var sut = new Stateprinter(cfg); 117 | return sut; 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /StatePrinter.Tests/IntegrationTests/CallStackReflectorTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using NUnit.Framework; 22 | using StatePrinting.TestAssistance; 23 | 24 | namespace StatePrinting.Tests.IntegrationTests 25 | { 26 | [TestFixture] 27 | class CallStackReflectorTest 28 | { 29 | [Test] 30 | public void TryGetInfo_inside_test_method() 31 | { 32 | var res = new CallStackReflector().TryGetLocation(); 33 | 34 | Assert.IsTrue(res.Filepath.EndsWith("ReflectorTest.cs")); 35 | Assert.AreEqual(32, res.LineNumber); 36 | } 37 | 38 | [Test] 39 | public void TryGetInfo_inside_lambda_expected_outside_lambda() 40 | { 41 | UnitTestLocationInfo res = null; 42 | 43 | Action x = () => res = new CallStackReflector().TryGetLocation(); 44 | x(); 45 | 46 | Assert.IsTrue(res.Filepath.EndsWith("ReflectorTest.cs")); 47 | Assert.AreEqual(43, res.LineNumber); 48 | } 49 | 50 | [Test] 51 | public void TryGetInfo_inside_AssertThrowsLambda_expected_outside_lambda() 52 | { 53 | UnitTestLocationInfo res = null; 54 | 55 | Assert.DoesNotThrow(() => res = new CallStackReflector().TryGetLocation()); 56 | 57 | Assert.IsTrue(res.Filepath.EndsWith("ReflectorTest.cs")); 58 | Assert.AreEqual(55, res.LineNumber); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /StatePrinter.Tests/IntegrationTests/CultureTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Globalization; 22 | using NUnit.Framework; 23 | 24 | namespace StatePrinting.Tests.IntegrationTests 25 | { 26 | [TestFixture] 27 | class CultureTests 28 | { 29 | const decimal DecimalNumber = 12345.343M; 30 | readonly DateTime dateTime = new DateTime(2010, 2, 28, 22, 10, 59); 31 | 32 | [Test] 33 | public void CultureDependentPrinting_us() 34 | { 35 | var usPrinter = new Stateprinter(); 36 | usPrinter.Configuration.Culture = new CultureInfo("en-US"); 37 | 38 | Assert.AreEqual("12345.343", usPrinter.PrintObject(DecimalNumber)); 39 | Assert.AreEqual("12345.34", usPrinter.PrintObject((float)DecimalNumber)); 40 | Assert.AreEqual("2/28/2010 10:10:59 PM", usPrinter.PrintObject(dateTime)); 41 | } 42 | 43 | [Test] 44 | public void CultureDependentPrinting_dk() 45 | { 46 | var dkPrinter = new Stateprinter(); 47 | dkPrinter.Configuration.Culture = new CultureInfo("da-DK"); 48 | 49 | Assert.AreEqual("12345,343", dkPrinter.PrintObject(DecimalNumber)); 50 | Assert.AreEqual("12345,34", dkPrinter.PrintObject((float)DecimalNumber)); 51 | Assert.AreEqual("28-02-2010 22:10:59", dkPrinter.PrintObject(dateTime)); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /StatePrinter.Tests/IntegrationTests/InheritanceTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | 22 | namespace StatePrinting.Tests.IntegrationTests 23 | { 24 | [TestFixture] 25 | class InheritanceTest 26 | { 27 | [Test] 28 | public void HarvestSameFieldsInTypAndSubtype() 29 | { 30 | B b = new B(); 31 | ((A)b).SomeFieldOnlyInA = 1; 32 | ((A)b).SameFieldInAB = "A part"; 33 | b.SomeFieldOnlyInB = 2; 34 | b.SameFieldInAB = "B part"; 35 | 36 | var expected = @"new B() 37 | { 38 | SomeFieldOnlyInA = 1 39 | SameFieldInAB = ""A part"" 40 | SomeFieldOnlyInB = 2 41 | SameFieldInAB = ""B part"" 42 | }"; 43 | TestHelper.Assert().PrintAreAlike(expected, (B) b); 44 | TestHelper.Assert().PrintAreAlike(expected, (A) b); 45 | } 46 | 47 | 48 | class A 49 | { 50 | public int SomeFieldOnlyInA; 51 | public string SameFieldInAB; 52 | } 53 | 54 | 55 | class B : A 56 | { 57 | public int SomeFieldOnlyInB; 58 | public new string SameFieldInAB; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /StatePrinter.Tests/IntegrationTests/PublicPropertiesTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Collections; 21 | using System.Collections.Generic; 22 | using NUnit.Framework; 23 | using StatePrinting.Configurations; 24 | using StatePrinting.FieldHarvesters; 25 | 26 | namespace StatePrinting.Tests.IntegrationTests 27 | { 28 | [TestFixture] 29 | class PublicPropertiesTest 30 | { 31 | class GetterOnly 32 | { 33 | public int i; 34 | 35 | int j = 22; 36 | 37 | public int Sum 38 | { 39 | get 40 | { 41 | return i + j; 42 | } 43 | } 44 | 45 | internal int Sum2 46 | { 47 | get 48 | { 49 | return i + j; 50 | } 51 | } 52 | } 53 | 54 | class SetterOnly 55 | { 56 | public int i, j; 57 | 58 | public int Sum 59 | { 60 | set 61 | { 62 | i = value; 63 | } 64 | } 65 | } 66 | 67 | class GetterSetter 68 | { 69 | public int I { get; set; } 70 | int J { get; set; } 71 | int K { get; set; } 72 | } 73 | 74 | class GetterSetterExplicitBackingField 75 | { 76 | int i, j; 77 | 78 | public int I 79 | { 80 | get 81 | { 82 | return i; 83 | } 84 | set 85 | { 86 | i = value; 87 | } 88 | } 89 | 90 | internal int J 91 | { 92 | get 93 | { 94 | return j; 95 | } 96 | set 97 | { 98 | j = value; 99 | } 100 | } 101 | } 102 | 103 | class IndexedProperty 104 | { 105 | public int i, j; 106 | 107 | public int this[int index] 108 | { 109 | get 110 | { 111 | if (index == 1) return i; 112 | if (index == 2) return j; 113 | return -1; 114 | } 115 | } 116 | } 117 | 118 | [Test] 119 | public void GetterOnly_IsIncluded() 120 | { 121 | var sut = new GetterOnly() { i = 1 }; 122 | var printer = CreatePrinter(); 123 | Assert.AreEqual(@"new GetterOnly() 124 | { 125 | Sum = 23 126 | i = 1 127 | }", printer.PrintObject(sut, "")); 128 | } 129 | 130 | 131 | [Test] 132 | public void SetterOnly_NotIncluded() 133 | { 134 | var sut = new SetterOnly() { i = 1, j = 2 }; 135 | var printer = CreatePrinter(); 136 | Assert.AreEqual(@"new SetterOnly() 137 | { 138 | i = 1 139 | j = 2 140 | }", printer.PrintObject(sut, "")); 141 | } 142 | 143 | 144 | [Test] 145 | public void GetterSetterOnly_IsIncluded() 146 | { 147 | var sut = new GetterSetter() { I = 1 }; 148 | var printer = CreatePrinter(); 149 | 150 | Assert.AreEqual(@"new GetterSetter() 151 | { 152 | I = 1 153 | }", printer.PrintObject(sut, "")); 154 | } 155 | 156 | 157 | /// 158 | /// unfortunately both are printed. A is needed in order to reduce the number of fields. 159 | /// 160 | /// We see this kind of implementation in 161 | /// 162 | /// and 163 | /// 164 | [Test] 165 | public void GetterSetter_WithExplicitBackingField_BothAreIncluded() 166 | { 167 | var sut = new GetterSetterExplicitBackingField() { I = 1, J = 2 }; 168 | var printer = CreatePrinter(); 169 | 170 | Assert.AreEqual(@"new GetterSetterExplicitBackingField() 171 | { 172 | I = 1 173 | }", printer.PrintObject(sut, "")); 174 | } 175 | 176 | 177 | [Test] 178 | public void GetterIndexedProperty_not_included() 179 | { 180 | var sut = new IndexedProperty() { i = 1, j = 2 }; 181 | var printer = CreatePrinter(); 182 | 183 | Assert.AreEqual(@"new IndexedProperty() 184 | { 185 | i = 1 186 | j = 2 187 | }", printer.PrintObject(sut, "")); 188 | } 189 | 190 | 191 | Stateprinter CreatePrinter() 192 | { 193 | return 194 | new Stateprinter( 195 | ConfigurationHelper.GetStandardConfiguration() 196 | .Add(new PublicFieldsAndPropertiesHarvester())); 197 | } 198 | } 199 | } -------------------------------------------------------------------------------- /StatePrinter.Tests/IntegrationTests/ToStringMethodTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | 22 | namespace StatePrinting.Tests.IntegrationTests 23 | { 24 | /// 25 | /// An example of using the state printer as a generic ToString() implementation. 26 | /// 27 | [TestFixture] 28 | class ToStringMethodTest 29 | { 30 | [Test] 31 | public void TestToStringMethod() 32 | { 33 | var a = new AClassWithToString(); 34 | string expected = 35 | @"new AClassWithToString() 36 | { 37 | B = ""hello"" 38 | C = new Int32[]() 39 | { 40 | [0] = 5 41 | [1] = 4 42 | [2] = 3 43 | [3] = 2 44 | [4] = 1 45 | } 46 | }"; 47 | Assert.AreEqual(expected, a.ToString()); 48 | } 49 | } 50 | 51 | 52 | class AClassWithToString 53 | { 54 | string B = "hello"; 55 | int[] C = { 5, 4, 3, 2, 1 }; 56 | static readonly Stateprinter printer = new Stateprinter(); 57 | 58 | public override string ToString() 59 | { 60 | return printer.PrintObject(this); 61 | } 62 | 63 | public void Dummy() 64 | { 65 | B = B + " "; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /StatePrinter.Tests/IntegrationTests/TwoDimensionArrayTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | using StatePrinting.OutputFormatters; 22 | 23 | namespace StatePrinting.Tests.IntegrationTests 24 | { 25 | [TestFixture] 26 | class TwoDimensionArrayTest 27 | { 28 | static readonly int[,] twoDimArray = { { 1, 2 }, { 3, 4 } }; 29 | 30 | [TestFixture] 31 | class ArrayTestCurly 32 | { 33 | string expected = @"new Int32[,]() 34 | { 35 | [0] = 1 36 | [1] = 2 37 | [2] = 3 38 | [3] = 4 39 | }"; 40 | 41 | [Test] 42 | public void TwoDimArray() 43 | { 44 | var printer = new Stateprinter(); 45 | Assert.AreEqual(expected, printer.PrintObject(twoDimArray, "")); 46 | } 47 | 48 | [Test] 49 | public void TwoDimArray_LegacyApi() 50 | { 51 | var printer = new Stateprinter(); 52 | printer.Configuration.LegacyBehaviour.TrimTrailingNewlines = false; 53 | Assert.AreEqual(expected + "\r\n", printer.PrintObject(twoDimArray, "")); 54 | } 55 | } 56 | 57 | 58 | [TestFixture] 59 | class ArrayTestJson 60 | { 61 | 62 | [Test] 63 | public void TwoDimArray() 64 | { 65 | var printer = TestHelper.CreateTestPrinter(); 66 | printer.Configuration.SetOutputFormatter(new JsonStyle(printer.Configuration)); 67 | 68 | var expected = @"[ 69 | 1, 70 | 2, 71 | 3, 72 | 4 73 | ]"; 74 | printer.Assert.PrintEquals(expected, twoDimArray); 75 | } 76 | } 77 | 78 | [TestFixture] 79 | class ArrayTestXml 80 | { 81 | 82 | [Test] 83 | public void TwoDimArray() 84 | { 85 | var printer = TestHelper.CreateTestPrinter(); 86 | printer.Configuration.SetOutputFormatter(new XmlStyle(printer.Configuration)); 87 | 88 | var expected = @" 89 | 1 90 | 2 91 | 3 92 | 4 93 | "; 94 | printer.Assert.PrintEquals(expected, twoDimArray); 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /StatePrinter.Tests/Introspection/ReferenceTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | using StatePrinting.Introspection; 22 | 23 | namespace StatePrinting.Tests.Introspection 24 | { 25 | [TestFixture] 26 | class ReferenceTest 27 | { 28 | [Test] 29 | public void Equals() 30 | { 31 | var a = new Reference(1); 32 | var b = new Reference(1); 33 | Assert.AreEqual(a, a); 34 | Assert.AreEqual(a, b); 35 | Assert.IsTrue(a.Equals((object) b)); 36 | } 37 | 38 | [Test] 39 | public void NotEquals() 40 | { 41 | var a = new Reference(1); 42 | var b = new Reference(2); 43 | Assert.AreNotEqual(a, b); 44 | Assert.AreNotEqual(a, null); 45 | } 46 | 47 | [Test] 48 | public void TestToString() 49 | { 50 | var a = new Reference(1); 51 | Assert.AreEqual("1", a.ToString()); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /StatePrinter.Tests/Introspection/TokenTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Collections.Generic; 21 | using System.Linq; 22 | using NUnit.Framework; 23 | using StatePrinting.Introspection; 24 | using StatePrinting.OutputFormatters; 25 | 26 | namespace StatePrinting.Tests.Introspection 27 | { 28 | [TestFixture] 29 | class TokenTest 30 | { 31 | [Test] 32 | public void Equals() 33 | { 34 | var a = new Token(TokenType.StartScope); 35 | var b = new Token(TokenType.StartScope); 36 | Assert.AreEqual(a, a); 37 | Assert.AreEqual(a, b); 38 | Assert.IsFalse(a.Equals((Token)null)); 39 | Assert.IsTrue(a.Equals(a)); 40 | Assert.IsTrue(a.Equals((object)b)); 41 | } 42 | 43 | [Test] 44 | public void NotEquals() 45 | { 46 | var a = new Token(TokenType.StartScope); 47 | var b = new Token(TokenType.EndScope); 48 | Assert.AreNotEqual(a, b); 49 | Assert.AreNotEqual(a, null); 50 | 51 | b = new Token(TokenType.StartScope, reference: new Reference(2)); 52 | Assert.AreNotEqual(a, b); 53 | } 54 | } 55 | 56 | /// 57 | /// Outputformatter that can show what has been introspected. For unit testing only 58 | /// 59 | public class TokenOutputter : IOutputFormatter 60 | { 61 | public List IntrospectedTokens; 62 | 63 | public string Print(List tokens) 64 | { 65 | IntrospectedTokens = tokens.ToList(); 66 | return "The result of this outputter is found in the field 'IntrospectedTokens'"; 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /StatePrinter.Tests/Mocks/Mocks.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using StatePrinting.TestAssistance; 21 | 22 | namespace StatePrinting.Tests.Mocks 23 | { 24 | class AreEqualsMethodMock 25 | { 26 | public string Expected { get; private set; } 27 | public string Actual { get; private set; } 28 | public string Message { get; private set; } 29 | 30 | public void AreEqualsMock(string exp, string actual, string msg) 31 | { 32 | Expected = exp; 33 | Actual = actual; 34 | Message = msg; 35 | } 36 | } 37 | 38 | class FileRepositoryMock : FileRepository 39 | { 40 | byte[] whatToRead; 41 | public string WritePath { get; private set; } 42 | public byte[] WriteContent { get; private set; } 43 | 44 | public FileRepositoryMock(byte[] whatToRead) 45 | { 46 | this.whatToRead = whatToRead; 47 | } 48 | 49 | public override byte[] Read(string path) 50 | { 51 | return whatToRead; 52 | } 53 | 54 | public override void Write(string path, byte[] content) 55 | { 56 | WritePath = path; 57 | WriteContent = content; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /StatePrinter.Tests/OutputFormatters/RollingGuidValueConverterTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using NUnit.Framework; 22 | using StatePrinting.ValueConverters; 23 | 24 | namespace StatePrinting.Tests.OutputFormatters 25 | { 26 | [TestFixture] 27 | class RollingGuidValueConverterTest 28 | { 29 | [Test] 30 | public void TestRolling() 31 | { 32 | var sut = new RollingGuidValueConverter(); 33 | Assert.AreEqual("00000000-0000-0000-0000-000000000001", sut.Convert(Guid.NewGuid())); 34 | Assert.AreEqual("00000000-0000-0000-0000-000000000002", sut.Convert(Guid.NewGuid())); 35 | Assert.AreEqual("00000000-0000-0000-0000-000000000003", sut.Convert(Guid.NewGuid())); 36 | Assert.AreEqual("00000000-0000-0000-0000-000000000004", sut.Convert(Guid.NewGuid())); 37 | Assert.AreEqual("00000000-0000-0000-0000-000000000005", sut.Convert(Guid.NewGuid())); 38 | Assert.AreEqual("00000000-0000-0000-0000-000000000006", sut.Convert(Guid.NewGuid())); 39 | Assert.AreEqual("00000000-0000-0000-0000-000000000007", sut.Convert(Guid.NewGuid())); 40 | Assert.AreEqual("00000000-0000-0000-0000-000000000008", sut.Convert(Guid.NewGuid())); 41 | Assert.AreEqual("00000000-0000-0000-0000-000000000009", sut.Convert(Guid.NewGuid())); 42 | Assert.AreEqual("00000000-0000-0000-0000-000000000010", sut.Convert(Guid.NewGuid())); 43 | } 44 | 45 | [Test] 46 | public void TestReuseRolledValues() 47 | { 48 | var sut = new RollingGuidValueConverter(); 49 | Guid g1 = Guid.NewGuid(); 50 | Guid g2 = Guid.NewGuid(); 51 | Assert.AreEqual("00000000-0000-0000-0000-000000000001", sut.Convert(g1)); 52 | Assert.AreEqual("00000000-0000-0000-0000-000000000002", sut.Convert(g2)); 53 | Assert.AreEqual("00000000-0000-0000-0000-000000000001", sut.Convert(g1)); 54 | Assert.AreEqual("00000000-0000-0000-0000-000000000002", sut.Convert(g2)); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /StatePrinter.Tests/OutputFormatters/StringBuilderTrimmerTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Text; 21 | using NUnit.Framework; 22 | using StatePrinting.OutputFormatters; 23 | 24 | namespace StatePrinting.Tests.OutputFormatters 25 | { 26 | [TestFixture] 27 | class StringBuilderTrimmerTest 28 | { 29 | [Test] 30 | public void TestTrimLast_Empty() 31 | { 32 | var sb = new StringBuilder(""); 33 | Assert.AreEqual(0, new StringBuilderTrimmer(true).TrimLast(sb)); 34 | } 35 | 36 | [Test] 37 | public void TestTrimLast_NothingToTrim() 38 | { 39 | var sb = new StringBuilder("abvc"); 40 | Assert.AreEqual(0, new StringBuilderTrimmer(true).TrimLast(sb)); 41 | } 42 | 43 | [Test] 44 | public void TestTrimLast_TrimSpaces() 45 | { 46 | var sb = new StringBuilder("abvc "); 47 | Assert.AreEqual(2, new StringBuilderTrimmer(true).TrimLast(sb)); 48 | } 49 | 50 | [Test] 51 | public void TestTrimLast_TrimAllSpaces() 52 | { 53 | var sb = new StringBuilder(" "); 54 | Assert.AreEqual(3, new StringBuilderTrimmer(true).TrimLast(sb)); 55 | Assert.AreEqual(3, new StringBuilderTrimmer(false).TrimLast(sb)); 56 | } 57 | [Test] 58 | public void TestTrimLast_TrimAllNewlines() 59 | { 60 | var sb = new StringBuilder(" \r\n"); 61 | Assert.AreEqual(2, new StringBuilderTrimmer(true).TrimLast(sb)); 62 | Assert.AreEqual(0, new StringBuilderTrimmer(false).TrimLast(sb)); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /StatePrinter.Tests/OutputFormatters/TokenFilterTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Collections.Generic; 21 | using NUnit.Framework; 22 | using StatePrinting.Introspection; 23 | using StatePrinting.OutputFormatters; 24 | 25 | namespace StatePrinting.Tests.OutputFormatters 26 | { 27 | [TestFixture] 28 | class TokenFilterTest 29 | { 30 | 31 | [Test] 32 | public void GetHashcode() 33 | { 34 | var sut = new Token(TokenType.FieldnameWithTypeAndReference, null, null, null, null); 35 | Assert.AreEqual(1156279432, sut.GetHashCode()); 36 | } 37 | 38 | [Test] 39 | public void Transform_noncycle() 40 | { 41 | var nonCycleTokens = new List() 42 | { 43 | new Token(TokenType.FieldnameWithTypeAndReference, new Field("fieldA"), "value1", new Reference(1), typeof(string) ), 44 | new Token(TokenType.FieldnameWithTypeAndReference, new Field("fieldB"), "value2", new Reference(2), typeof(string)), 45 | }; 46 | 47 | var filter = new UnusedReferencesTokenFilter(); 48 | var newlist = filter.FilterUnusedReferences(nonCycleTokens); 49 | 50 | // test 51 | var expected = new List() 52 | { 53 | new Token(TokenType.FieldnameWithTypeAndReference, new Field("fieldA"), "value1", null, typeof(string)), 54 | new Token(TokenType.FieldnameWithTypeAndReference, new Field("fieldB"), "value2", null, typeof(string)), 55 | }; 56 | 57 | CollectionAssert.AreEqual(expected, newlist); 58 | } 59 | 60 | [Test] 61 | public void Transform_cycle() 62 | { 63 | var nonCycleTokens = new List() 64 | { 65 | new Token(TokenType.FieldnameWithTypeAndReference, new Field("fieldA"), "value1", new Reference(0), typeof(string)), 66 | new Token(TokenType.FieldnameWithTypeAndReference, new Field("fieldB"), "value2", new Reference(1), typeof(int)), 67 | Token.SeenBefore(new Field("FieldB"), new Reference(1)), 68 | }; 69 | 70 | var filter = new UnusedReferencesTokenFilter(); 71 | var newlist = filter.FilterUnusedReferences(nonCycleTokens); 72 | 73 | // test 74 | var expected = new List() 75 | { 76 | new Token(TokenType.FieldnameWithTypeAndReference, new Field("fieldA"), "value1", null, typeof(string)), 77 | new Token(TokenType.FieldnameWithTypeAndReference, new Field("fieldB"), "value2", new Reference(0), typeof(int)), 78 | Token.SeenBefore(new Field("FieldB"), new Reference(0)), 79 | }; 80 | 81 | CollectionAssert.AreEqual(expected, newlist); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /StatePrinter.Tests/PerformanceTests/PerformanceTestsBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Diagnostics; 22 | using NUnit.Framework; 23 | 24 | namespace StatePrinting.Tests.PerformanceTests 25 | { 26 | [TestFixture] 27 | public abstract class PerformanceTestsBase 28 | { 29 | [SetUp] 30 | public void Setup() 31 | { 32 | #if DEBUG 33 | throw new Exception("Only do performance in release mode"); 34 | #endif 35 | } 36 | 37 | protected long Time(Action a) 38 | { 39 | var watch = new Stopwatch(); 40 | watch.Start(); 41 | a(); 42 | watch.Stop(); 43 | return watch.ElapsedMilliseconds; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /StatePrinter.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Reflection; 22 | using System.Runtime.InteropServices; 23 | 24 | // General Information about an assembly is controlled through the following 25 | // set of attributes. Change these attribute values to modify the information 26 | // associated with an assembly. 27 | [assembly: AssemblyTitle("StatePrinter.Tests")] 28 | [assembly: AssemblyDescription("Tests for the StatePrinter. Apache v2.0 License")] 29 | [assembly: AssemblyConfiguration("")] 30 | [assembly: AssemblyCompany("Kasper B. Graversen, Inc.")] 31 | [assembly: AssemblyProduct("StatePrinter.Tests")] 32 | [assembly: AssemblyCopyright("Kasper B. Graversen")] 33 | [assembly: AssemblyTrademark("")] 34 | [assembly: AssemblyCulture("")] 35 | [assembly: CLSCompliant(false)] 36 | 37 | // Setting ComVisible to false makes the types in this assembly not visible 38 | // to COM components. If you need to access a type in this assembly from 39 | // COM, set the ComVisible attribute to true on that type. 40 | [assembly: ComVisible(false)] 41 | 42 | // The following GUID is for the ID of the typelib if this project is exposed to COM 43 | [assembly: Guid("c1cd611d-2fe0-4f10-9202-72161591749a")] 44 | 45 | // Version information for an assembly consists of the following four values: 46 | // 47 | // Major Version 48 | // Minor Version 49 | // Build Number 50 | // Revision 51 | // 52 | // You can specify all the values or you can default the Build and Revision Numbers 53 | // by using the '*' as shown below: 54 | // [assembly: AssemblyVersion("1.0.*")] 55 | [assembly: AssemblyVersion("1.0.0.0")] 56 | [assembly: AssemblyFileVersion("1.0.0.0")] 57 | -------------------------------------------------------------------------------- /StatePrinter.Tests/TestHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Globalization; 21 | using StatePrinting.Configurations; 22 | using StatePrinting.TestAssistance; 23 | 24 | namespace StatePrinting.Tests 25 | { 26 | static class TestHelper 27 | { 28 | public static Asserter Assert() 29 | { 30 | return CreateTestPrinter().Assert; 31 | } 32 | 33 | public static Asserter CreateShortAsserter() 34 | { 35 | return new Stateprinter(CreateTestConfiguration()).Assert; 36 | } 37 | 38 | public static Stateprinter CreateTestPrinter() 39 | { 40 | var cfg = ConfigurationHelper.GetStandardConfiguration() 41 | .SetCulture(CultureInfo.CreateSpecificCulture("da-DK")) 42 | .Test.SetAreEqualsMethod(NUnit.Framework.Assert.AreEqual) 43 | .Test.SetAutomaticTestRewrite(filename => new EnvironmentReader().UseTestAutoRewrite()); 44 | 45 | return new Stateprinter(cfg); 46 | } 47 | 48 | public static Configuration CreateTestConfiguration() 49 | { 50 | var cfg = ConfigurationHelper 51 | .GetStandardConfiguration("") 52 | .SetNewlineDefinition(" ") 53 | .SetCulture(CultureInfo.CreateSpecificCulture("da-DK")) 54 | .Test.SetAreEqualsMethod(NUnit.Framework.Assert.AreEqual) 55 | .Test.SetAutomaticTestRewrite(filename => new EnvironmentReader().UseTestAutoRewrite()); 56 | 57 | return cfg; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /StatePrinter.Tests/TestingAssistance/EnvironmentReaderTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using NUnit.Framework; 22 | using StatePrinting.TestAssistance; 23 | 24 | namespace StatePrinting.Tests.TestingAssistance 25 | { 26 | [TestFixture] 27 | class EnvironmentReaderTest 28 | { 29 | [Test] 30 | public void TestReadUseAutoReWrite() 31 | { 32 | var org = Environment.GetEnvironmentVariable(EnvironmentReader.Usetestautorewrite, EnvironmentVariableTarget.User); 33 | try 34 | { 35 | Environment.SetEnvironmentVariable(EnvironmentReader.Usetestautorewrite, "false", EnvironmentVariableTarget.User); 36 | 37 | var reader = new EnvironmentReader(); 38 | Assert.AreEqual(false, reader.UseTestAutoRewrite()); 39 | 40 | Environment.SetEnvironmentVariable(EnvironmentReader.Usetestautorewrite, "true", EnvironmentVariableTarget.User); 41 | Assert.AreEqual(true, reader.UseTestAutoRewrite()); 42 | } 43 | finally 44 | { 45 | Environment.SetEnvironmentVariable(EnvironmentReader.Usetestautorewrite, org, EnvironmentVariableTarget.User); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /StatePrinter.Tests/TestingAssistance/ReWriterMockedTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | 21 | using System; 22 | using NUnit.Framework; 23 | using StatePrinting.Tests.Mocks; 24 | 25 | namespace StatePrinting.Tests.TestingAssistance 26 | { 27 | public class UserStory_Integration_with_underlying_testing_framework 28 | { 29 | [Test] 30 | public void Rewriter_calls_to_testframework_autorewriting() 31 | { 32 | var printer = TestHelper.CreateTestPrinter(); 33 | 34 | var fakeReadContent = new System.Text.UTF8Encoding(true).GetBytes(TestFileContent); 35 | var mock = new FileRepositoryMock(fakeReadContent); 36 | printer.Configuration.FactoryFileRepository = () => mock; 37 | printer.Configuration.Test.SetAutomaticTestRewrite(x => true); 38 | 39 | var assertMock = new AreEqualsMethodMock(); 40 | printer.Configuration.Test.SetAreEqualsMethod(assertMock.AreEqualsMock); 41 | 42 | string expected = "boo"; 43 | printer.Assert.AreAlike(expected, "actul"); 44 | 45 | Assert.AreEqual("boo", assertMock.Expected); 46 | Assert.AreEqual("actul", assertMock.Actual); 47 | Assert.IsTrue(assertMock.Message.StartsWith("Rewritting test expectations in '")); 48 | Assert.IsTrue(assertMock.Message.EndsWith(@"'. 49 | Compile and re-run to see green lights. 50 | New expectations: 51 | ""actul""")); 52 | Assert.IsTrue(mock.WritePath.EndsWith("ReWriterMockedTests.cs")); 53 | } 54 | 55 | const string TestFileContent = @" 56 | must 57 | contain 58 | more 59 | lines than the 60 | test above 61 | such that the 62 | file contains as many lines as the line number 63 | reported by the callstackreflector 64 | 0 65 | 1 66 | 2 67 | 3 68 | 4 69 | 5 70 | 6 71 | 7 72 | 8 73 | 9 74 | 0 75 | 1 76 | 2 77 | 3 78 | 4 79 | 5 80 | 6 81 | 7 82 | 8 83 | 9 84 | 0 85 | 1 86 | 2 87 | 3 88 | 4 89 | 5 90 | 6 91 | 7 92 | 8 93 | 9 94 | string expected = @""boo""; 95 | 0 96 | 1 97 | 2 98 | 3 99 | 4 100 | 5 101 | "; 102 | 103 | 104 | /// 105 | /// By running again against the same file, the line number has now increased to something larger than the input file 106 | /// 107 | [Test] 108 | public void Rewriter_calls_to_testframework_fileTooShort() 109 | { 110 | var printer = TestHelper.CreateTestPrinter(); 111 | 112 | var fakeReadContent = new System.Text.UTF8Encoding(true).GetBytes(TestFileContent); 113 | printer.Configuration.FactoryFileRepository = () => new FileRepositoryMock(fakeReadContent); 114 | printer.Configuration.Test.SetAutomaticTestRewrite((x) => true); 115 | 116 | var assertMock = new AreEqualsMethodMock(); 117 | printer.Configuration.Test.SetAreEqualsMethod(assertMock.AreEqualsMock); 118 | 119 | string expected = @"expect"; 120 | 121 | var ex = Assert.Throws(() => printer.Assert.AreAlike(expected, "actul")); 122 | Assert.AreEqual("File does not have 121 lines. Only 47 lines.\r\nParameter name: content", ex.Message); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /StatePrinter.Tests/TestingAssistance/TestingAssistanceReWriteTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | 22 | namespace StatePrinting.Tests.TestingAssistance 23 | { 24 | 25 | /// 26 | /// These tests are a bit weird, in that they autocorrect themselves. Ie. we cannot make them fail as they rewrite. 27 | /// 28 | /// used for manually testing that the rewrite still works. 29 | /// 30 | [TestFixture] 31 | class TestingAssistanceRewriteTest 32 | { 33 | [Test] 34 | [Explicit] 35 | public void Autocorrection_works_var() 36 | { 37 | var assert = TestHelper.Assert(); 38 | assert.Configuration.Test.SetAutomaticTestRewrite((x) => true); 39 | 40 | var expected = @"""test auto"""; 41 | assert.PrintAreAlike(expected, "test auto"); 42 | } 43 | 44 | [Test] 45 | [Explicit] 46 | public void Autocorrection_works_string() 47 | { 48 | var assert = TestHelper.Assert(); 49 | assert.Configuration.Test.SetAutomaticTestRewrite((x) => true); 50 | 51 | string expected = @"""test auto"""; 52 | assert.PrintAreAlike(expected, "test auto"); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /StatePrinter.Tests/TestingAssistance/USerStory.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | 21 | using NUnit.Framework; 22 | using Is = StatePrinting.TestAssistance.Is; 23 | 24 | namespace StatePrinting.Tests.TestingAssistance 25 | { 26 | [TestFixture] 27 | class Userstory_nonexplicit 28 | { 29 | [Test] 30 | public void AreAlike_differentNewlines() 31 | { 32 | TestHelper.Assert().AreAlike("a\n", "a\r\n"); 33 | TestHelper.Assert().AreAlike("a\r\n", "a\n"); 34 | TestHelper.Assert().AreAlike("a\r", "a\n"); 35 | TestHelper.Assert().AreAlike("a\r", "a\r\n"); 36 | 37 | TestHelper.Assert().PrintAreAlike("\"a\r\"", "a\r\n"); 38 | TestHelper.Assert().PrintAreAlike("\"a\r\"", "a\r"); 39 | TestHelper.Assert().PrintEquals("\"a\r\"", "a\r"); 40 | } 41 | } 42 | 43 | [Explicit("Run these in order to see how Nunit integrates with the testing assistance")] 44 | [TestFixture] 45 | class Userstory 46 | { 47 | [Test] 48 | public void AreEquals_without() 49 | { 50 | TestHelper.Assert().AreEqual("a", "b"); 51 | } 52 | 53 | [Test] 54 | public void That_without() 55 | { 56 | TestHelper.Assert().That("a", Is.EqualTo("b")); 57 | } 58 | 59 | [Test] 60 | public void AreEquals_with() 61 | { 62 | TestHelper.Assert().AreEqual("a", "\"b\""); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /StatePrinter.Tests/ValueConverters/GenericValueConverterTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using NUnit.Framework; 21 | using StatePrinting.ValueConverters; 22 | 23 | namespace StatePrinting.Tests.ValueConverters 24 | { 25 | [TestFixture] 26 | class GenericValueConverterTest 27 | { 28 | const int anyInt = 42; 29 | 30 | [Test] 31 | public void TestConvertCallsLambda() 32 | { 33 | bool called = false; 34 | var sut = new GenericValueConverter(x=>"" + (called = true)); 35 | 36 | sut.Convert(anyInt); 37 | 38 | Assert.IsTrue(called); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /StatePrinter.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /StatePrinter.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | StatePrinter 5 | 4.0.0 6 | 7 | An open source utility to turn object graphs into strings. Automate your ToString and unit tests asserts. 8 | 9 | 10 | * Requires .NET Framework 4.7.2 11 | * Added `TestingBehaviour.SetAreEqualsMethod()` for easier integration with NUnit v3.x 12 | * Removed all obsolete functionality. 13 | 14 | UnitTest ToString Serialization Approvals Test Testing ApprovalsTest 15 | Copyright 2014-2020 16 | en-US 17 | Kasper B. Graversen 18 | https://github.com/kbilsted/StatePrinter 19 | https://raw.githubusercontent.com/kbilsted/StatePrinter/master/StatePrinter/gfx/stateprinter.png 20 | false 21 | 22 | 23 | -------------------------------------------------------------------------------- /StatePrinter.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29806.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatePrinter", "StatePrinter\StatePrinter.csproj", "{10181C0E-31FF-48B3-A293-D9ED83D38C8D}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{653DACEF-B390-4AAB-87B8-CE18674319EE}" 9 | ProjectSection(SolutionItems) = preProject 10 | .nuget\NuGet.Config = .nuget\NuGet.Config 11 | .nuget\NuGet.exe = .nuget\NuGet.exe 12 | .nuget\NuGet.targets = .nuget\NuGet.targets 13 | EndProjectSection 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatePrinter.Tests", "StatePrinter.Tests\StatePrinter.Tests.csproj", "{05FFACFD-A00F-4A47-9DDA-CAD57C2DDC59}" 16 | EndProject 17 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5DF8CA6E-4233-40D0-B3FF-F2FA145A351C}" 18 | ProjectSection(SolutionItems) = preProject 19 | appveyor.yml = appveyor.yml 20 | CHANGELOG.md = CHANGELOG.md 21 | CreateNuget.cmd = CreateNuget.cmd 22 | DeployToNuget.cmd = DeployToNuget.cmd 23 | StatePrinter.nuspec = StatePrinter.nuspec 24 | EndProjectSection 25 | EndProject 26 | Global 27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 28 | Debug|Any CPU = Debug|Any CPU 29 | Release|Any CPU = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {10181C0E-31FF-48B3-A293-D9ED83D38C8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {10181C0E-31FF-48B3-A293-D9ED83D38C8D}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {10181C0E-31FF-48B3-A293-D9ED83D38C8D}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {10181C0E-31FF-48B3-A293-D9ED83D38C8D}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {05FFACFD-A00F-4A47-9DDA-CAD57C2DDC59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {05FFACFD-A00F-4A47-9DDA-CAD57C2DDC59}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {05FFACFD-A00F-4A47-9DDA-CAD57C2DDC59}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {05FFACFD-A00F-4A47-9DDA-CAD57C2DDC59}.Release|Any CPU.Build.0 = Release|Any CPU 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | GlobalSection(ExtensibilityGlobals) = postSolution 45 | SolutionGuid = {4A127BF8-6D2D-444A-84C6-3CCD19F1AF58} 46 | EndGlobalSection 47 | EndGlobal 48 | -------------------------------------------------------------------------------- /StatePrinter/Configurations/ConfigurationHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using StatePrinting.FieldHarvesters; 22 | using StatePrinting.OutputFormatters; 23 | using StatePrinting.TestAssistance; 24 | using StatePrinting.ValueConverters; 25 | 26 | namespace StatePrinting.Configurations 27 | { 28 | /// 29 | /// Helper for configuration 30 | /// 31 | public static class ConfigurationHelper 32 | { 33 | /// 34 | /// Return a configuration which covers most usages. 35 | /// The configuration returned can be further remolded by adding additional handlers. 36 | /// 37 | /// Eg. add a to restrict the printed state to only public fields. 38 | /// 39 | public static Configuration GetStandardConfiguration(TestFrameworkAreEqualsMethod areEqualsMethod) 40 | { 41 | if (areEqualsMethod == null) 42 | throw new ArgumentNullException("areEqualsMethod"); 43 | 44 | return GetStandardConfiguration( 45 | Configuration.DefaultIndention, 46 | areEqualsMethod: areEqualsMethod); 47 | } 48 | 49 | /// 50 | /// Return a configuration which covers most usages. 51 | /// The configuration returned can be further remolded by adding additional handlers. 52 | /// 53 | /// Eg. add a to restrict the printed state to only public fields. 54 | /// 55 | public static Configuration GetStandardConfiguration( 56 | string indentIncrement = Configuration.DefaultIndention, 57 | TestFrameworkAreEqualsMethod areEqualsMethod = null) 58 | { 59 | var cfg = new Configuration(indentIncrement, areEqualsMethod); 60 | 61 | // valueconverters 62 | cfg.Add(new StandardTypesConverter(cfg)); 63 | cfg.Add(new StringConverter()); 64 | cfg.Add(new DateTimeConverter(cfg)); 65 | cfg.Add(new EnumConverter()); 66 | 67 | // harvesters 68 | cfg.Add(new AllFieldsHarvester()); 69 | 70 | // outputformatters 71 | cfg.OutputFormatter = new CurlyBraceStyle(cfg); 72 | 73 | return cfg; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /StatePrinter/Configurations/LegacyBehaviour.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | namespace StatePrinting.Configurations 21 | { 22 | public class LegacyBehaviour 23 | { 24 | /// 25 | /// To mimic the behaviour of v1.0.6 and below, set this to false. 26 | /// 27 | public bool TrimTrailingNewlines = true; 28 | } 29 | } -------------------------------------------------------------------------------- /StatePrinter/Configurations/TestingBehaviour.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Data.SqlClient; 22 | using StatePrinting.TestAssistance; 23 | 24 | namespace StatePrinting.Configurations 25 | { 26 | public class TestingBehaviour 27 | { 28 | readonly Configuration configuration; 29 | 30 | public TestingBehaviour(Configuration configuration) 31 | { 32 | this.configuration = configuration; 33 | } 34 | 35 | /// 36 | /// Configure how to call AreEquals in the unit testing framework of your choice. 37 | /// Only set this field if you are using the functionality. 38 | /// 39 | public Configuration SetAreEqualsMethod(TestFrameworkAreEqualsMethod areEqualsMethod) 40 | { 41 | if (areEqualsMethod == null) 42 | throw new ArgumentNullException("areEqualsMethod"); 43 | AreEqualsMethod = areEqualsMethod; 44 | 45 | return configuration; 46 | } 47 | 48 | private static readonly object[] NoArg = new object[0]; 49 | 50 | /// 51 | /// Configure how to call AreEquals in the unit testing framework of your choice. 52 | /// Only set this field if you are using the functionality. 53 | /// This overload is for easy integration with NUnit 3.x Asert.AreEqual 54 | /// 55 | public Configuration SetAreEqualsMethod(Action nunitAreEqualsMethod) 56 | { 57 | if (nunitAreEqualsMethod == null) 58 | throw new ArgumentNullException("nunitAreEqualsMethod"); 59 | AreEqualsMethod = new TestFrameworkAreEqualsMethod((actual, expected, message) => nunitAreEqualsMethod(actual,expected,message,NoArg)); 60 | 61 | return configuration; 62 | } 63 | 64 | /// 65 | /// Configure how to call AreEquals in the unit testing framework of your choice. 66 | /// Only set this field if you are using the functionality. 67 | /// 68 | public TestFrameworkAreEqualsMethod AreEqualsMethod { get; private set; } 69 | 70 | /// 71 | /// The signature for finding out if a test's expected value may be automatically re-written. 72 | /// 73 | /// True if the test may be rewritten with the new expected value to make the test pass again. 74 | public delegate bool TestRewriteIndicator(UnitTestLocationInfo location); 75 | 76 | /// 77 | /// Evaluate the function for each failing test. 78 | /// Your function can rely on anything such as an environment variable or a file on the file system. 79 | /// If you only want to do this evaluation once pr. test suite execution you should wrap your function in a Lazy<> 80 | /// 81 | public TestRewriteIndicator AutomaticTestRewrite { get; private set; } 82 | 83 | /// 84 | /// Evaluate the function for each failing test. 85 | /// Your function can rely on anything such as an environment variable or a file on the file system. 86 | /// If you only want to do this evaluation once pr. test suite execution you should wrap your function in a Lazy<> 87 | /// 88 | public Configuration SetAutomaticTestRewrite(TestRewriteIndicator indicator) 89 | { 90 | if (indicator == null) 91 | throw new ArgumentNullException("indicator"); 92 | AutomaticTestRewrite = indicator; 93 | 94 | return configuration; 95 | } 96 | 97 | /// 98 | /// Defines how the error message shown when tests are failing 99 | /// 100 | public delegate string CreateAssertMessageCallback( 101 | string expected, 102 | string actual, 103 | string escapedActual, 104 | bool willPerformAutomaticRewrite, 105 | UnitTestLocationInfo location); 106 | 107 | public CreateAssertMessageCallback AssertMessageCreator { get; private set; } 108 | 109 | /// 110 | /// Set the method to be called when an assert message is to be created 111 | /// 112 | public Configuration SetAssertMessageCreator(CreateAssertMessageCallback assertMessageCreator) 113 | { 114 | if (assertMessageCreator == null) 115 | throw new ArgumentNullException("indicator"); 116 | AssertMessageCreator = assertMessageCreator; 117 | 118 | return configuration; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/AllFieldsAndPropertiesHarvester.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace StatePrinting.FieldHarvesters 24 | { 25 | /// 26 | /// Harvest all fields, public and private. 27 | /// 28 | /// We ignore the types from the following namespaces 29 | /// 30 | /// 31 | /// 32 | /// 33 | public class AllFieldsAndPropertiesHarvester : IFieldHarvester 34 | { 35 | readonly HarvestHelper harvestHelper = new HarvestHelper(); 36 | 37 | public bool CanHandleType(Type type) 38 | { 39 | return true; 40 | } 41 | 42 | /// 43 | /// We ignore all properties as they, in the end, will only point to some computed state or other fields. 44 | /// Hence they do not provide information about the actual state of the object. 45 | /// 46 | public List GetFields(Type type) 47 | { 48 | return harvestHelper.GetFieldsAndProperties(type); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/AllFieldsHarvester.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace StatePrinting.FieldHarvesters 24 | { 25 | /// 26 | /// Harvest all fields, public and private. 27 | /// 28 | /// We ignore the types from the following namespaces 29 | /// 30 | /// 31 | /// 32 | /// 33 | public class AllFieldsHarvester : IFieldHarvester 34 | { 35 | readonly HarvestHelper harvestHelper = new HarvestHelper(); 36 | public bool CanHandleType(Type type) 37 | { 38 | return true; 39 | } 40 | 41 | /// 42 | /// We ignore all properties as they, in the end, will only point to some computed state or other fields. 43 | /// Hence they do not provide information about the actual state of the object. 44 | /// 45 | public List GetFields(Type type) 46 | { 47 | return harvestHelper.GetFields(type); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/AnonymousFieldHarvester.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace StatePrinting.FieldHarvesters 24 | { 25 | /// 26 | /// Harvest from a type as specified by the provided functions. 27 | /// 28 | public class AnonymousHarvester : IFieldHarvester 29 | { 30 | private readonly Func canHandleTypeFunc; 31 | private readonly Func> getFieldsFunc; 32 | 33 | public AnonymousHarvester(Func canHandleTypeFunc, Func> getFieldsFunc) 34 | { 35 | this.canHandleTypeFunc = canHandleTypeFunc; 36 | this.getFieldsFunc = getFieldsFunc; 37 | } 38 | 39 | public bool CanHandleType(Type type) 40 | { 41 | return canHandleTypeFunc(type); 42 | } 43 | 44 | public List GetFields(Type type) 45 | { 46 | return getFieldsFunc(type); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/IFieldHarvester.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace StatePrinting.FieldHarvesters 24 | { 25 | /// 26 | /// A fieldharvester is a configuration part that given a type is able to harvest all fields on it. 27 | /// 28 | public interface IFieldHarvester 29 | { 30 | bool CanHandleType(Type type); 31 | 32 | List GetFields(Type type); 33 | } 34 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/IRunTimeCodeGenerator.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Reflection; 22 | 23 | namespace StatePrinting.FieldHarvesters 24 | { 25 | public interface IRunTimeCodeGenerator 26 | { 27 | Func CreateGetter(MemberInfo memberInfo); 28 | } 29 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/PublicFieldsAndPropertiesHarvester .cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | using System.Reflection; 24 | 25 | namespace StatePrinting.FieldHarvesters 26 | { 27 | /// 28 | /// Harvest only public fields and properties from types. 29 | /// 30 | /// We ignore the types from the following namespaces 31 | /// 32 | /// 33 | /// 34 | /// 35 | public class PublicFieldsAndPropertiesHarvester : IFieldHarvester 36 | { 37 | public bool CanHandleType(Type type) 38 | { 39 | return true; 40 | } 41 | 42 | /// 43 | /// Harvest only public fields and properties. 44 | /// 45 | public List GetFields(Type type) 46 | { 47 | var fields = new HarvestHelper().GetFieldsAndProperties(type); 48 | 49 | return fields.Where(IsPublic).ToList(); 50 | } 51 | 52 | bool IsPublic(SanitizedFieldInfo field) 53 | { 54 | switch (field.FieldInfo.MemberType) 55 | { 56 | case MemberTypes.Field: 57 | if ((field.FieldInfo as FieldInfo).IsPublic) return true; 58 | break; 59 | case MemberTypes.Property: 60 | var propertyInfo = (PropertyInfo)field.FieldInfo; 61 | if (propertyInfo.GetGetMethod(false) != null) return true; 62 | break; 63 | default: 64 | throw new ArgumentOutOfRangeException(); 65 | } 66 | return false; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/PublicFieldsHarvester.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | using System.Reflection; 24 | 25 | namespace StatePrinting.FieldHarvesters 26 | { 27 | /// 28 | /// Harvest only public fields from types. 29 | /// 30 | /// We ignore the types from the following namespaces 31 | /// 32 | /// 33 | /// 34 | /// 35 | public class PublicFieldsHarvester : IFieldHarvester 36 | { 37 | public bool CanHandleType(Type type) 38 | { 39 | return true; 40 | } 41 | 42 | /// 43 | /// We ignore all properties as they, in the end, will only point to some computed state or other fields. 44 | /// Hence they do not provide information about the actual state of the object. 45 | /// 46 | public List GetFields(Type type) 47 | { 48 | // we need all fields in order to get the private backing field of public properties 49 | var fields = new HarvestHelper().GetFields(type); 50 | var res = 51 | fields.Where( 52 | x => 53 | ((FieldInfo)x.FieldInfo).IsPublic 54 | || x.FieldInfo.Name.EndsWith(HarvestHelper.BackingFieldSuffix, StringComparison.Ordinal)); 55 | 56 | return res.ToList(); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/RunTimeCodeGenerator.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq.Expressions; 23 | using System.Reflection; 24 | 25 | namespace StatePrinting.FieldHarvesters 26 | { 27 | public class RunTimeCodeGeneratorCache : IRunTimeCodeGenerator 28 | { 29 | static readonly Dictionary> cache = new Dictionary>(); 30 | readonly IRunTimeCodeGenerator generator; 31 | 32 | public RunTimeCodeGeneratorCache(IRunTimeCodeGenerator generator) 33 | { 34 | this.generator = generator; 35 | } 36 | 37 | public Func CreateGetter(MemberInfo memberInfo) 38 | { 39 | Func getter; 40 | lock (cache) 41 | { 42 | if (cache.TryGetValue(memberInfo, out getter)) 43 | return getter; 44 | } 45 | 46 | var generatedGetter = generator.CreateGetter(memberInfo); 47 | 48 | lock (cache) 49 | { 50 | if (cache.TryGetValue(memberInfo, out getter)) 51 | return getter; 52 | 53 | cache.Add(memberInfo, generatedGetter); 54 | } 55 | 56 | return generatedGetter; 57 | } 58 | } 59 | 60 | /// 61 | /// Run-time code generation is much faster than using ordinary reflection such 62 | /// 63 | public class RunTimeCodeGenerator : IRunTimeCodeGenerator 64 | { 65 | /// 66 | /// A fast alternative to the reflection methods and 67 | /// 68 | public Func CreateGetter(MemberInfo memberInfo) 69 | { 70 | if (!(memberInfo is FieldInfo) && !(memberInfo is PropertyInfo)) 71 | throw new ArgumentException("Parameter memberInfo must be of type FieldInfo or PropertyInfo."); 72 | 73 | if (memberInfo.DeclaringType == null) 74 | throw new ArgumentException("MemberInfo cannot be a global member."); 75 | 76 | var p = Expression.Parameter(typeof(object), "p"); 77 | var castparam = Expression.Convert(p, memberInfo.DeclaringType); 78 | var field = Expression.PropertyOrField(castparam, memberInfo.Name); 79 | var castRes = Expression.Convert(field, typeof(object)); 80 | var getter = Expression.Lambda>(castRes, p).Compile(); 81 | 82 | return getter; 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/SanitizedFieldInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Reflection; 22 | 23 | namespace StatePrinting.FieldHarvesters 24 | { 25 | /// 26 | /// For each type we print, we hold the reflected and the readable version of the fields 27 | /// 28 | public class SanitizedFieldInfo 29 | { 30 | public readonly MemberInfo FieldInfo; 31 | 32 | /// 33 | /// The sanitized name is the name the user would expect. 34 | /// E.g. the field 'X' has the value 'X' and the property 'Y' has the value 'Y' rather than the value '<Y>k__BackingField'. 35 | /// 36 | public readonly string SanitizedName; 37 | 38 | /// 39 | /// Functionality to fetch the value of the field. 40 | /// 41 | public readonly Func ValueProvider; 42 | 43 | public SanitizedFieldInfo( 44 | MemberInfo fieldInfo, 45 | string sanitizedName, 46 | Func valueProvider) 47 | { 48 | FieldInfo = fieldInfo; 49 | SanitizedName = sanitizedName; 50 | ValueProvider = valueProvider; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /StatePrinter/FieldHarvesters/ToStringAwareHarvester.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Reflection; 23 | 24 | namespace StatePrinting.FieldHarvesters 25 | { 26 | /// 27 | /// Harvest all fields, public and private. Or use the ToString() if such is implemented on the class. 28 | /// 29 | /// We ignore the types from the following namespaces 30 | /// 31 | /// 32 | /// 33 | /// 34 | public class ToStringAwareHarvester : IFieldHarvester 35 | { 36 | readonly Dictionary cache = new Dictionary(); 37 | 38 | readonly Dictionary methodInfos = new Dictionary(); 39 | 40 | public ToStringAwareHarvester() 41 | { 42 | } 43 | 44 | public bool CanHandleType(Type type) 45 | { 46 | bool hasToString; 47 | if (!cache.TryGetValue(type, out hasToString)) 48 | { 49 | var methodInfo = GetMethodInfo(type); 50 | hasToString = methodInfo != null; 51 | cache[type] = hasToString; 52 | if (hasToString) 53 | methodInfos[type] = methodInfo; 54 | } 55 | 56 | return hasToString; 57 | } 58 | 59 | /// 60 | /// We ignore all properties as they, in the end, will only point to some computed state or other fields. 61 | /// Hence they do not provide information about the actual state of the object. 62 | /// 63 | public List GetFields(Type type) 64 | { 65 | Func valueProvider = (o) => methodInfos[type].Invoke(o, new object[0]); 66 | var syntesizedField = new SanitizedFieldInfo(null, "ToString()", valueProvider); 67 | 68 | return new List() { syntesizedField }; 69 | } 70 | 71 | /// 72 | /// This more thorough way to avoid the "Ambiguous match found" exception while retrieving the ToString method 73 | /// Explained here http://stackoverflow.com/questions/11443707/getproperty-reflection-results-in-ambiguous-match-found-on-new-property 74 | /// 75 | MethodInfo GetMethodInfo(Type type) 76 | { 77 | var methodInfo = type.GetMethod( 78 | "ToString", 79 | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, 80 | null, 81 | new Type[] { }, // Method ToString() without parameters 82 | null); 83 | return methodInfo; 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /StatePrinter/Introspection/HarvestInfoCache.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Threading; 23 | 24 | namespace StatePrinting.Introspection 25 | { 26 | /// 27 | /// Assume that types don't change at run-time. Cache harvested information. 28 | /// 29 | class HarvestInfoCache : IDisposable 30 | { 31 | /// 32 | /// Due to supporting C# 3.5 we cannot use ConcurrentDictionary 33 | /// 34 | readonly Dictionary harvestCache = new Dictionary(); 35 | readonly ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(); 36 | 37 | public ReflectionInfo TryGet(Type type) 38 | { 39 | cacheLock.EnterReadLock(); 40 | try 41 | { 42 | ReflectionInfo res; 43 | harvestCache.TryGetValue(type, out res); 44 | return res; 45 | } 46 | finally 47 | { 48 | cacheLock.ExitReadLock(); 49 | } 50 | } 51 | 52 | public void TryAdd(Type type, ReflectionInfo fields) 53 | { 54 | cacheLock.EnterWriteLock(); 55 | try 56 | { 57 | if (!harvestCache.ContainsKey(type)) 58 | harvestCache.Add(type, fields); 59 | } 60 | finally 61 | { 62 | cacheLock.ExitWriteLock(); 63 | } 64 | } 65 | 66 | public void Dispose() 67 | { 68 | cacheLock.Dispose(); 69 | } 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /StatePrinter/Introspection/Reference.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | 22 | namespace StatePrinting.Introspection 23 | { 24 | /// 25 | /// A numeric value denoting an already outputted object that is referred to by current object 26 | /// 27 | public class Reference : IEquatable 28 | { 29 | public readonly int Number; 30 | 31 | public Reference(int number) 32 | { 33 | Number = number; 34 | } 35 | 36 | public override bool Equals(object obj) 37 | { 38 | return Equals(obj as Reference); 39 | } 40 | 41 | public bool Equals(Reference other) 42 | { 43 | if (other == null) return false; 44 | return Number == other.Number; 45 | } 46 | 47 | public override int GetHashCode() 48 | { 49 | return Number; 50 | } 51 | 52 | public override string ToString() 53 | { 54 | return Number.ToString(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /StatePrinter/Introspection/ReflectionInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | using StatePrinting.FieldHarvesters; 24 | 25 | namespace StatePrinting.Introspection 26 | { 27 | /// 28 | /// For a given type we hold the relevant fields with regards to printing, and functors for retrieving the content of the fields. 29 | /// The functors enables synthetic fields. E.g. a field that represents the call to the object's ToString(). 30 | /// 31 | class ReflectionInfo 32 | { 33 | public readonly Field[] Fields; 34 | public readonly Func[] ValueProviders; 35 | 36 | public ReflectionInfo(List rawReflectedFields) 37 | { 38 | Fields = rawReflectedFields.Select(x => new Field(x.SanitizedName)).ToArray(); 39 | ValueProviders = rawReflectedFields.Select(x => x.ValueProvider).ToArray(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /StatePrinter/Introspection/Token.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using StatePrinting.OutputFormatters; 22 | 23 | namespace StatePrinting.Introspection 24 | { 25 | /// 26 | /// The result of introspection. 27 | /// A transforms tokens into the final output format. 28 | /// 29 | public class Token : IEquatable 30 | { 31 | public readonly TokenType Tokenkind; 32 | public readonly Type FieldType; 33 | public readonly Field Field; 34 | public readonly string Value; 35 | 36 | /// 37 | /// Each entry is assigned an internal referenceno. 38 | /// 39 | public readonly Reference ReferenceNo; 40 | 41 | /// 42 | /// constructor method 43 | /// 44 | public static Token SeenBefore(Field field, Reference reference) 45 | { 46 | return new Token(TokenType.SeenBeforeWithReference, field, null, reference, null); 47 | } 48 | 49 | public Token(TokenType type, Field field = null, string value = null, Reference reference = null, Type fieldFieldType = null) 50 | { 51 | Tokenkind = type; 52 | Field = field; 53 | 54 | ReferenceNo = reference; 55 | Value = value; 56 | FieldType = fieldFieldType; 57 | } 58 | 59 | public override bool Equals(object obj) 60 | { 61 | return Equals(obj as Token); 62 | } 63 | 64 | public bool Equals(Token other) 65 | { 66 | if (other == null) return false; 67 | if (ReferenceEquals(other, this)) return true; 68 | if (Tokenkind != other.Tokenkind) return false; 69 | if (!Equals(ReferenceNo, other.ReferenceNo)) return false; 70 | if (Value != other.Value) return false; 71 | if (FieldType != other.FieldType) return false; 72 | 73 | return true; 74 | } 75 | 76 | public override int GetHashCode() 77 | { 78 | unchecked 79 | { 80 | var hashCode = (int)Tokenkind; 81 | hashCode = (hashCode * 397) ^ (FieldType != null ? FieldType.GetHashCode() : 0); 82 | hashCode = (hashCode * 397) ^ (Field != null ? Field.GetHashCode() : 0); 83 | hashCode = (hashCode * 397) ^ (Value != null ? Value.GetHashCode() : 0); 84 | hashCode = (hashCode * 397) ^ (ReferenceNo != null ? ReferenceNo.GetHashCode() : 0); 85 | 86 | return hashCode; 87 | } 88 | } 89 | 90 | public override string ToString() 91 | { 92 | if (Field == null) 93 | return string.Format("{0}: {1} = {2}", Tokenkind, FieldType, Value); 94 | string name = string.IsNullOrEmpty(Field.Name) ? "" : " " + Field.Name; 95 | string key = Field.Index.HasValue ? Field.Index.Value.ToString() : Field.Key; 96 | string subscript = key == null ? "" : "[" + key + "]"; 97 | return string.Format("{0}: {1}{2}{3} = {4}", Tokenkind, FieldType, name, subscript, Value); 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /StatePrinter/Introspection/TokenType.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | namespace StatePrinting.Introspection 20 | { 21 | public enum TokenType 22 | { 23 | StartScope, 24 | EndScope, 25 | StartList, 26 | EndList, 27 | StartDict, 28 | EndDict, 29 | SeenBeforeWithReference, 30 | SimpleFieldValue, 31 | FieldnameWithTypeAndReference, 32 | } 33 | } -------------------------------------------------------------------------------- /StatePrinter/OutputFormatters/CurlyBraceStyle.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using StatePrinting.Configurations; 23 | using StatePrinting.Introspection; 24 | 25 | namespace StatePrinting.OutputFormatters 26 | { 27 | /// 28 | /// Formatting the tokens to a curly-brace style representation. 29 | /// 30 | /// In order to reduce clutter in the output, only reference that are referred to by later 31 | /// outputted objects will have a referencenumber attached to them. 32 | /// 33 | public class CurlyBraceStyle : IOutputFormatter 34 | { 35 | Configuration configuration; 36 | 37 | public CurlyBraceStyle(Configuration configuration) 38 | { 39 | this.configuration = configuration; 40 | } 41 | 42 | public string Print(List tokens) 43 | { 44 | var filter = new UnusedReferencesTokenFilter(); 45 | var processed = filter.FilterUnusedReferences(tokens); 46 | 47 | return MakeString(processed); 48 | } 49 | 50 | string MakeString(IEnumerable tokens) 51 | { 52 | var sb = new IndentingStringBuilder(configuration); 53 | 54 | foreach (var token in tokens) 55 | { 56 | MakeTokenString(token, sb); 57 | } 58 | 59 | sb.TrimLast(); 60 | 61 | return sb.ToString(); 62 | } 63 | 64 | void MakeTokenString(Token token, IndentingStringBuilder sb) 65 | { 66 | switch (token.Tokenkind) 67 | { 68 | case TokenType.StartScope: 69 | case TokenType.StartList: 70 | case TokenType.StartDict: 71 | sb.AppendFormatLine("{{"); 72 | sb.Indent(); 73 | break; 74 | 75 | case TokenType.EndScope: 76 | case TokenType.EndList: 77 | case TokenType.EndDict: 78 | sb.DeIndent(); 79 | sb.AppendFormatLine("}}"); 80 | break; 81 | 82 | case TokenType.SimpleFieldValue: 83 | sb.AppendFormatLine("{0}", MakeFieldValue(token, token.Value)); 84 | break; 85 | 86 | case TokenType.SeenBeforeWithReference: 87 | sb.AppendFormatLine("{0}", MakeFieldValue(token, "-> " + token.ReferenceNo.Number)); 88 | break; 89 | 90 | case TokenType.FieldnameWithTypeAndReference: 91 | var optionReferenceInfo = token.ReferenceNo == null 92 | ? "" 93 | : string.Format(", ref: {0}", token.ReferenceNo.Number); 94 | 95 | var fieldType = OutputFormatterHelpers.MakeReadable(token.FieldType); 96 | 97 | string value = string.Format("new {0}(){1}", fieldType, optionReferenceInfo); 98 | sb.AppendFormatLine("{0}", MakeFieldValue(token, value)); 99 | break; 100 | 101 | default: 102 | throw new ArgumentOutOfRangeException(); 103 | } 104 | } 105 | 106 | string MakeFieldValue(Token token, string value) 107 | { 108 | if (token.Field == null) 109 | return value; 110 | 111 | if (token.Field.Index.HasValue) 112 | return string.Format("[{0}] = {1}", token.Field.Index, value); 113 | 114 | if (token.Field.Key != null) 115 | return string.Format("[{0}] = {1}", token.Field.Key, value); 116 | 117 | // Field.Name is empty if the ROOT-element-name has not been supplied. 118 | if (string.IsNullOrEmpty(token.Field.Name)) 119 | return value; 120 | 121 | return string.Format("{0} = {1}", token.Field.Name, value); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /StatePrinter/OutputFormatters/FastestPossibleStyle.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Globalization; 23 | using System.Text; 24 | using StatePrinting.Configurations; 25 | using StatePrinting.Introspection; 26 | 27 | namespace StatePrinting.OutputFormatters 28 | { 29 | /// 30 | /// Formatting the tokens to a curly-brace style representation. 31 | /// 32 | /// In order to reduce clutter in the output, only reference that are referred to by later 33 | /// outputted objects will have a referencenumber attached to them. 34 | /// 35 | public class FastestPossibleStyle : IOutputFormatter 36 | { 37 | readonly Configuration configuration; 38 | 39 | public FastestPossibleStyle(Configuration configuration) 40 | { 41 | this.configuration = configuration; 42 | configuration.Culture= CultureInfo.InvariantCulture; 43 | } 44 | 45 | public string Print(List tokens) 46 | { 47 | var sb = new StringBuilder(tokens.Count*7); 48 | var newline = configuration.NewLineDefinition; 49 | var count = tokens.Count; 50 | for (int i = 0; i < count; i++) 51 | { 52 | var token = tokens[i]; 53 | 54 | switch (token.Tokenkind) 55 | { 56 | case TokenType.StartScope: 57 | sb.Append(newline); 58 | break; 59 | case TokenType.StartList: 60 | case TokenType.StartDict: 61 | sb.Append("["+newline+"]"); 62 | break; 63 | 64 | case TokenType.EndScope: 65 | sb.Append(configuration.NewLineDefinition); 66 | break; 67 | case TokenType.EndList: 68 | case TokenType.EndDict: 69 | sb.Append("]"+configuration.NewLineDefinition); 70 | break; 71 | 72 | case TokenType.SimpleFieldValue: 73 | case TokenType.SeenBeforeWithReference: 74 | sb.Append(token.Value); 75 | break; 76 | 77 | case TokenType.FieldnameWithTypeAndReference: 78 | var fieldType = OutputFormatterHelpers.MakeReadable(token.FieldType); 79 | sb.Append(MakeFieldValue(token, newline+"new ("+fieldType+")") ); 80 | break; 81 | 82 | default: 83 | throw new ArgumentOutOfRangeException(); 84 | } 85 | } 86 | return sb.ToString(); 87 | } 88 | 89 | string MakeFieldValue(Token token, string value) 90 | { 91 | if (token.Field == null) 92 | return value; 93 | 94 | if (token.Field.Index.HasValue) 95 | return string.Format("[{0}] = {1}", token.Field.Index, value); 96 | 97 | if (token.Field.Key != null) 98 | return string.Format("[{0}] = {1}", token.Field.Key, value); 99 | 100 | // Field.Name is empty if the ROOT-element-name has not been supplied. 101 | if (string.IsNullOrEmpty(token.Field.Name)) 102 | return value; 103 | 104 | return string.Format("{0} = {1}", token.Field.Name, value); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /StatePrinter/OutputFormatters/IOutputFormatter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Collections.Generic; 21 | using StatePrinting.Introspection; 22 | 23 | namespace StatePrinting.OutputFormatters 24 | { 25 | public interface IOutputFormatter 26 | { 27 | string Print(List tokens); 28 | } 29 | } -------------------------------------------------------------------------------- /StatePrinter/OutputFormatters/IndentingStringBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Text; 21 | using StatePrinting.Configurations; 22 | 23 | namespace StatePrinting.OutputFormatters 24 | { 25 | class IndentingStringBuilder 26 | { 27 | readonly StringBuilder sb = new StringBuilder(); 28 | readonly string IndentIncrement; 29 | readonly string NewLineDefinition; 30 | readonly Configuration configuration; 31 | 32 | string indent = ""; 33 | bool mustIndent = true; 34 | 35 | public IndentingStringBuilder(Configuration configuration) 36 | { 37 | IndentIncrement = configuration.IndentIncrement; 38 | NewLineDefinition = configuration.NewLineDefinition; 39 | this.configuration = configuration; 40 | } 41 | 42 | public void Indent() 43 | { 44 | indent += IndentIncrement; 45 | } 46 | 47 | public void DeIndent() 48 | { 49 | indent = indent.Substring(IndentIncrement.Length); 50 | } 51 | 52 | public void AppendFormat(string format, params object[] args) 53 | { 54 | if (mustIndent) 55 | { 56 | sb.Append(indent); 57 | mustIndent = false; 58 | } 59 | sb.AppendFormat(format, args); 60 | } 61 | 62 | public void AppendFormatLine(string format, params object[] args) 63 | { 64 | AppendFormat(format, args); 65 | sb.Append(NewLineDefinition); 66 | mustIndent = true; 67 | } 68 | 69 | public override string ToString() 70 | { 71 | return sb.ToString(); 72 | } 73 | 74 | public void TrimLast() 75 | { 76 | int trim = new StringBuilderTrimmer(configuration.LegacyBehaviour.TrimTrailingNewlines).TrimLast(sb); 77 | if(trim > 0) 78 | sb.Remove(sb.Length - trim, trim); 79 | 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /StatePrinter/OutputFormatters/OutputFormatterHelpers.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Linq; 22 | 23 | namespace StatePrinting.OutputFormatters 24 | { 25 | public static class OutputFormatterHelpers 26 | { 27 | /// 28 | /// Convert a type into a human readable string 29 | /// 30 | public static string MakeReadable(Type type) 31 | { 32 | if (type == null) 33 | throw new ArgumentNullException("type"); 34 | 35 | if (!type.IsGenericType) 36 | return type.Name; 37 | 38 | var typename = type.Name.Split('`')[0]; 39 | var genericName = type.GetGenericArguments().Select(x => MakeReadable(x)).ToArray(); 40 | string generictypes = string.Join(", ", genericName); 41 | 42 | return String.Format("{0}<{1}>", typename, generictypes); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /StatePrinter/OutputFormatters/StringBuilderTrimmer.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.Text; 21 | 22 | namespace StatePrinting.OutputFormatters 23 | { 24 | public class StringBuilderTrimmer 25 | { 26 | readonly bool trimTrailingNewlines; 27 | 28 | public StringBuilderTrimmer(bool trimTrailingNewlines) 29 | { 30 | this.trimTrailingNewlines = trimTrailingNewlines; 31 | } 32 | 33 | public int TrimLast(StringBuilder sb) 34 | { 35 | int p = sb.Length; 36 | while (--p >= 0 && sb[p] == ' ') 37 | { } 38 | p++; 39 | 40 | if (trimTrailingNewlines) 41 | { 42 | while (--p >= 0 && (sb[p] == '\r' || sb[p] == '\n')) 43 | { } 44 | p++; 45 | } 46 | 47 | return sb.Length - p; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /StatePrinter/OutputFormatters/UnusedReferencesTokenFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | using StatePrinting.Introspection; 24 | 25 | namespace StatePrinting.OutputFormatters 26 | { 27 | public class UnusedReferencesTokenFilter 28 | { 29 | /// 30 | /// In order to reduce clutter in the output, only show reference in the output if the object 31 | /// is referred to from other objects using a back-reference. 32 | /// 33 | public List FilterUnusedReferences(List tokens) 34 | { 35 | var backreferences = GetBackreferences(tokens); 36 | 37 | var remappedReferences = RemappedReferences(backreferences); 38 | 39 | var result = tokens 40 | .Select( 41 | x => 42 | { 43 | switch (x.Tokenkind) 44 | { 45 | case TokenType.StartScope: 46 | case TokenType.EndScope: 47 | case TokenType.StartList: 48 | case TokenType.EndList: 49 | case TokenType.StartDict: 50 | case TokenType.EndDict: 51 | case TokenType.SimpleFieldValue: 52 | return x; 53 | case TokenType.SeenBeforeWithReference: 54 | case TokenType.FieldnameWithTypeAndReference: 55 | return new Token( 56 | x.Tokenkind, 57 | x.Field, 58 | x.Value, 59 | CreateNewReferenceOrClear(remappedReferences, x.ReferenceNo), 60 | x.FieldType); 61 | default: throw new Exception("Unknown token type "+ x.Tokenkind); 62 | } 63 | }) 64 | .ToList(); 65 | 66 | return result; 67 | } 68 | 69 | public Reference[] GetBackreferences(List tokens) 70 | { 71 | return tokens 72 | .Where(x => x.Tokenkind == TokenType.SeenBeforeWithReference) 73 | .Select(x => x.ReferenceNo) 74 | .Distinct() 75 | .ToArray(); 76 | } 77 | 78 | Dictionary RemappedReferences(Reference[] backreferences) 79 | { 80 | var remappedReferences = new Dictionary(); 81 | int newReference = 0; 82 | foreach (var backreference in backreferences) 83 | remappedReferences[backreference] = new Reference(newReference++); 84 | 85 | return remappedReferences; 86 | } 87 | 88 | Reference CreateNewReferenceOrClear(Dictionary remappedReferences, Reference currentReference) 89 | { 90 | Reference newReference; 91 | 92 | // if not remapped, clear the reference 93 | if(!remappedReferences.TryGetValue(currentReference, out newReference)) 94 | return null; 95 | 96 | return newReference; 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /StatePrinter/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2017 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Reflection; 22 | using System.Runtime.InteropServices; 23 | 24 | // General Information about an assembly is controlled through the following 25 | // set of attributes. Change these attribute values to modify the information 26 | // associated with an assembly. 27 | [assembly: AssemblyTitle("StatePrinter")] 28 | [assembly: AssemblyDescription("An open source utility to turn object graphs into strings. Automatic unit testing and ToString() methods. Apache v2.0 License")] 29 | [assembly: AssemblyConfiguration("")] 30 | [assembly: AssemblyCompany("Kasper B. Graversen, Inc.")] 31 | [assembly: AssemblyProduct("StatePrinter")] 32 | [assembly: AssemblyCopyright("Kasper B. Graversen")] 33 | [assembly: AssemblyTrademark("")] 34 | [assembly: AssemblyCulture("")] 35 | [assembly: CLSCompliant(true)] 36 | 37 | // Setting ComVisible to false makes the types in this assembly not visible 38 | // to COM components. If you need to access a type in this assembly from 39 | // COM, set the ComVisible attribute to true on that type. 40 | [assembly: ComVisible(false)] 41 | 42 | // The following GUID is for the ID of the typelib if this project is exposed to COM 43 | [assembly: Guid("ba9aa723-9df7-414b-93a6-c1a6c8c57b2d")] 44 | 45 | // Version information for an assembly consists of the following four values: 46 | // 47 | // Major Version 48 | // Minor Version 49 | // Build Number 50 | // Revision 51 | // 52 | // You can specify all the values or you can default the Build and Revision Numbers 53 | // by using the '*' as shown below: 54 | // [assembly: AssemblyVersion("1.0.*")] 55 | [assembly: AssemblyVersion("3.0.0.0")] // Change this upon breaking changes 56 | [assembly: AssemblyFileVersion("3.0.311.0")] // Bump this at every release 57 | //[assembly: AssemblyInformationalVersion("2.2.281-rc")] // Only set on pre-releases. Customer public info (setting a version across multiple products each possibly with their own versioning) 58 | -------------------------------------------------------------------------------- /StatePrinter/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace StatePrinter.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("StatePrinter.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /StatePrinter/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | text/microsoft-resx 91 | 92 | 93 | 1.3 94 | 95 | 96 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 97 | 98 | 99 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 100 | 101 | -------------------------------------------------------------------------------- /StatePrinter/Settings.StyleCop: -------------------------------------------------------------------------------- 1 | 2 | 3 | True 4 | 5 | 6 | 7 | 8 | 9 | 10 | False 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | False 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /StatePrinter/StatePrinter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using StatePrinting.Configurations; 22 | using StatePrinting.FieldHarvesters; 23 | using StatePrinting.Introspection; 24 | using StatePrinting.TestAssistance; 25 | 26 | namespace StatePrinting 27 | { 28 | /// 29 | /// A class able to dump an object graph to a string. 30 | /// class inheritance hierarchies as well as cyclic graphs are supported. 31 | /// 32 | /// Simply call the with an object or object-graph to get a string representation. 33 | /// 34 | /// The printing process is thread safe. 35 | /// 36 | /// The state printer is highly customizable both in terms of which types and fields are printed as well as how printing of values is done. 37 | /// 38 | public class Stateprinter 39 | { 40 | Asserter asserter; 41 | 42 | /// 43 | /// Get the configuration for further fine-tuning 44 | /// 45 | public readonly Configuration Configuration; 46 | 47 | /// 48 | /// The cache cannot be static since we have many different harvesters, and potentially many different usages of 49 | /// 50 | readonly HarvestInfoCache harvestCache = new HarvestInfoCache(); 51 | 52 | /// 53 | /// Create an state printer using the supplied configuration. 54 | /// 55 | public Stateprinter(Configuration configuration) 56 | { 57 | if (configuration == null) 58 | throw new ArgumentNullException("configuration"); 59 | 60 | this.Configuration = configuration; 61 | } 62 | 63 | /// 64 | /// Create an state printer using the 65 | /// 66 | public Stateprinter() : this(ConfigurationHelper.GetStandardConfiguration()) 67 | { 68 | } 69 | 70 | /// 71 | /// Print an object graph to a string. 72 | /// 73 | /// What to print. 74 | public string PrintObject(object objectToPrint) 75 | { 76 | return PrintObject(objectToPrint, null); 77 | } 78 | 79 | /// 80 | /// Print an object graph to a string. 81 | /// 82 | /// What to print. 83 | /// The name of the root as it is printed. 84 | public string PrintObject(object objectToPrint, string rootname) 85 | { 86 | var introSpector = new IntroSpector(Configuration, harvestCache); 87 | var tokens = introSpector.PrintObject(objectToPrint, rootname); 88 | 89 | var formatter = Configuration.OutputFormatter; 90 | 91 | var result = formatter.Print(tokens); 92 | 93 | return result; 94 | } 95 | 96 | /// 97 | /// Lazily create an asserter based on the configuration "Configuration.Test.AreEqualsMethod". 98 | /// Throws exception if not configured. 99 | /// 100 | public Asserter Assert 101 | { 102 | get 103 | { 104 | // lazy fetch so not to require people to set up an asserter when it is not used 105 | if (asserter == null) 106 | { 107 | if (Configuration.Test.AreEqualsMethod == null) 108 | { 109 | const string message = "The configuration has no value for AreEqualsMethod which is to point to your testing framework, " 110 | + "e.g. use the value: 'Nunit.Framework.Assert.AreEqual' " 111 | + "or the more long-winded: '(expected, actual, msg) => Assert.AreEqual(expected, actual, msg)'.\r\n" 112 | + "Parameter name: Configuration.AreEqualsMethod"; 113 | throw new ArgumentNullException("Configuration.AreEqualsMethod", message); 114 | } 115 | asserter = new Asserter(this); 116 | } 117 | 118 | return asserter; 119 | } 120 | } 121 | 122 | /// 123 | /// We need to dispose the lock for the caches 124 | /// 125 | ~Stateprinter() 126 | { 127 | harvestCache.Dispose(); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /StatePrinter/StatePrinterStrongNameKeyFile_DoNotDelete.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbilsted/StatePrinter/76e70caf955303a39116dbf4e750efb9fcea1972/StatePrinter/StatePrinterStrongNameKeyFile_DoNotDelete.snk -------------------------------------------------------------------------------- /StatePrinter/TestAssistance/DefaultAssertMessage.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | 22 | namespace StatePrinting.TestAssistance 23 | { 24 | class DefaultAssertMessage 25 | { 26 | readonly StringUtils stringUtils = new StringUtils(); 27 | 28 | const string AreAlikeNotice = @"Info: Expected value and Actual value are not equal, but they are alike. Use 'Asserter.AreAlike()' if you expected the values to be alike. 29 | "; 30 | public string Create( 31 | string expected, 32 | string actual, 33 | string escapedActual, 34 | bool willPerformAutomaticRewrite, 35 | UnitTestLocationInfo location) 36 | { 37 | // It is important to use verbatim-strings in order to get the correct Environment.NewLine at line endings 38 | string message = ""; 39 | 40 | bool areAlike = stringUtils.UnifyNewLines(expected) == stringUtils.UnifyNewLines(actual); 41 | if (areAlike) 42 | message = AreAlikeNotice; 43 | 44 | if (willPerformAutomaticRewrite) 45 | { 46 | message += string.Format(@"Rewritting test expectations in '{0}:{1}'. 47 | Compile and re-run to see green lights. 48 | New expectations: 49 | {2}", location.Filepath, location.LineNumber, escapedActual); 50 | } 51 | else 52 | { 53 | var newExpected = string.Format("var expected = {0};", escapedActual); 54 | message += string.Format("{0}{0}Proposed output for unit test:{0}{0}{1}{0}", Environment.NewLine, newExpected); 55 | } 56 | 57 | return message; 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /StatePrinter/TestAssistance/EnvironmentReader.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | 22 | namespace StatePrinting.TestAssistance 23 | { 24 | public class EnvironmentReader 25 | { 26 | public const string Usetestautorewrite = "StatePrinter_UseTestAutoRewrite"; 27 | 28 | public bool UseTestAutoRewrite() 29 | { 30 | string result = Environment.GetEnvironmentVariable( 31 | Usetestautorewrite, 32 | EnvironmentVariableTarget.User); 33 | return "true".Equals(result, StringComparison.Ordinal); 34 | } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /StatePrinter/TestAssistance/FileRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System.IO; 21 | 22 | namespace StatePrinting.TestAssistance 23 | { 24 | public class FileRepository 25 | { 26 | public virtual byte[] Read(string path) 27 | { 28 | var bytes = File.ReadAllBytes(path); 29 | return bytes; 30 | } 31 | 32 | public virtual void Write(string path, byte[] content) 33 | { 34 | File.WriteAllBytes(path, content); 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /StatePrinter/TestAssistance/Parser.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Linq; 22 | using System.Text.RegularExpressions; 23 | 24 | namespace StatePrinting.TestAssistance 25 | { 26 | public class Parser 27 | { 28 | static readonly RegexOptions options = RegexOptions.Singleline | RegexOptions.RightToLeft; 29 | 30 | public string ReplaceExpected(string content, int lineNo, string originalExpected, string newExpected) 31 | { 32 | int index = FindLastIndexOfLineNo(content, lineNo); 33 | 34 | // The expected value to replace may either be represened as a string or a verbatim string. Thus we must look for both representations 35 | var reString = EscapeForString(originalExpected); 36 | var reVerbString = EscapeForVerbatimString(originalExpected); 37 | Regex re = new Regex("(" 38 | + reString 39 | + "|" 40 | + reVerbString 41 | + ")", options); 42 | 43 | var match = re.Match(content, index); 44 | if (!match.Success) 45 | throw new ArgumentException("Did not find '" + originalExpected + "'"); 46 | 47 | int start = match.Index; 48 | int end = match.Index + match.Length; 49 | var res = content.Substring(0, start) 50 | + newExpected 51 | + content.Substring(end); 52 | 53 | return res; 54 | } 55 | 56 | string EscapeForString(string s) 57 | { 58 | return "@?\"" + EscapeForRegEx(s) 59 | .Replace("\n", "\\n") 60 | .Replace("\r", "\\r") 61 | .Replace("\t", "\\t") 62 | .Replace("\"", "\\\"") 63 | .Replace(".", "\\.") 64 | + "\""; 65 | } 66 | 67 | string EscapeForVerbatimString(string s) 68 | { 69 | return "@\"" 70 | + EscapeForRegEx(s).Replace("\"", "\"\"") 71 | + "\""; 72 | } 73 | 74 | string EscapeForRegEx(string s) 75 | { 76 | return s 77 | // escape "\" as otherwise we interpret eg a windows file path as illegal RegEx 78 | .Replace("\\", "\\\\") 79 | .Replace("(", "\\(") 80 | .Replace(")", "\\)") 81 | .Replace("|", "\\|") 82 | .Replace("+", "\\+") 83 | .Replace("[", "\\[") 84 | .Replace("]", "\\]"); 85 | } 86 | 87 | /// 88 | /// Does not support files using only \r as newlines 89 | /// 90 | int FindLastIndexOfLineNo(string content, int lineNo) 91 | { 92 | int line = 1; 93 | bool found = false; 94 | int i = 0; 95 | for (; i < content.Count(); i++) 96 | { 97 | if (line == lineNo) 98 | found = true; 99 | if (content[i] == '\n') 100 | { 101 | if (found) 102 | return i; 103 | line++; 104 | } 105 | } 106 | if (line == lineNo) 107 | found = true; 108 | 109 | if (found) 110 | return i; 111 | 112 | throw new ArgumentOutOfRangeException("content", "File does not have " + lineNo + " lines. Only " + line + " lines."); 113 | } 114 | } 115 | } 116 | 117 | -------------------------------------------------------------------------------- /StatePrinter/TestAssistance/StringUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | namespace StatePrinting.TestAssistance 21 | { 22 | public class StringUtils 23 | { 24 | public string UnifyNewLines(string text) 25 | { 26 | return text 27 | .Replace("\r\n", "\n") 28 | .Replace("\r", "\n"); 29 | } 30 | 31 | public string Escape(string actual) 32 | { 33 | var needEscaping = actual.Contains("\"") || actual.Contains("\n"); 34 | if (needEscaping) 35 | return string.Format("@\"{0}\"", actual.Replace("\"", "\"\"")); 36 | return string.Format("\"{0}\"", actual); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /StatePrinter/TestAssistance/TestRewriter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Diagnostics; 22 | using System.Linq; 23 | using System.Text; 24 | 25 | namespace StatePrinting.TestAssistance 26 | { 27 | 28 | public class UnitTestLocationInfo 29 | { 30 | public string Filepath; 31 | public int LineNumber; 32 | } 33 | 34 | class TestRewriter 35 | { 36 | static readonly Encoding[] encodings = new[] 37 | { 38 | new UTF8Encoding(true), 39 | Encoding.BigEndianUnicode, 40 | new UTF32Encoding(false, true), 41 | new UTF32Encoding(true, true), 42 | 43 | // fallback 44 | new UTF8Encoding(false), 45 | }; 46 | 47 | Func fileRepositoryFactory; 48 | 49 | public TestRewriter(Func fileRepositoryFactory) 50 | { 51 | this.fileRepositoryFactory = fileRepositoryFactory; 52 | } 53 | 54 | public void RewriteTest(UnitTestLocationInfo info, string originalExpected, string newExpected) 55 | { 56 | Encoding enc = null; 57 | string content = null; 58 | var fileRepository = fileRepositoryFactory(); 59 | var bytes = fileRepository.Read(info.Filepath); 60 | 61 | enc = encodings.First(x => TryConvertFromEncoding(x, bytes, out content)); 62 | 63 | var newTestContent = new Parser().ReplaceExpected(content, info.LineNumber, originalExpected, newExpected); 64 | fileRepository.Write(info.Filepath, enc.GetBytes(newTestContent)); 65 | } 66 | 67 | bool TryConvertFromEncoding(Encoding enc, byte[] bytes, out string result) 68 | { 69 | var preamble = enc.GetPreamble(); 70 | if (preamble.Where((p, i) => p != bytes[i]).Any()) 71 | { 72 | result = null; 73 | return false; 74 | } 75 | 76 | result = enc.GetString(bytes.Skip(preamble.Length).ToArray()); 77 | return true; 78 | } 79 | } 80 | 81 | public class CallStackReflector 82 | { 83 | public UnitTestLocationInfo TryGetLocation() 84 | { 85 | var info = TryFindFirstCallOutsideStatePrinterAssembly(); 86 | if (info == null) 87 | return null; 88 | 89 | return new UnitTestLocationInfo() 90 | { 91 | Filepath = info.GetFileName(), 92 | LineNumber = info.GetFileLineNumber(), 93 | }; 94 | } 95 | 96 | /// 97 | /// This code only works in debug mode, when in release mode, null is returned 98 | /// 99 | StackFrame TryFindFirstCallOutsideStatePrinterAssembly() 100 | { 101 | var trace = new StackTrace(true); 102 | 103 | var stateprinterAssembly = trace.GetFrame(0).GetMethod().Module.Assembly; 104 | for (int i = 1; i < trace.FrameCount; i++) 105 | { 106 | var frame = trace.GetFrame(i); 107 | var mth = frame.GetMethod(); 108 | if (!stateprinterAssembly.Equals(mth.Module.Assembly) && frame.GetFileName() != null) 109 | return frame; 110 | } 111 | 112 | return null; 113 | } 114 | } 115 | 116 | } 117 | 118 | -------------------------------------------------------------------------------- /StatePrinter/ValueConverters/DateTimeConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using StatePrinting.Configurations; 22 | 23 | namespace StatePrinting.ValueConverters 24 | { 25 | /// 26 | /// Handles the printing of and 27 | /// 28 | public class DateTimeConverter : IValueConverter 29 | { 30 | readonly Configuration configuration; 31 | 32 | public DateTimeConverter(Configuration configuration) 33 | { 34 | this.configuration = configuration; 35 | } 36 | 37 | public bool CanHandleType(Type t) 38 | { 39 | return t == typeof(DateTime) || t == typeof(DateTimeOffset); 40 | } 41 | 42 | public string Convert(object source) 43 | { 44 | if (source is DateTime) 45 | return ((DateTime)source).ToString(configuration.Culture); 46 | 47 | if (source is DateTimeOffset) 48 | return ((DateTimeOffset)source).ToString(configuration.Culture); 49 | 50 | throw new Exception("We should never reach here"); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /StatePrinter/ValueConverters/EnumConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | 22 | namespace StatePrinting.ValueConverters 23 | { 24 | /// 25 | /// Handles enums and prints their programatic name 26 | /// 27 | public class EnumConverter : IValueConverter 28 | { 29 | public bool CanHandleType(Type t) 30 | { 31 | return t.IsEnum; 32 | } 33 | 34 | public string Convert(object source) 35 | { 36 | return System.Enum.GetName(source.GetType(), source); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /StatePrinter/ValueConverters/GenericValueConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | 22 | namespace StatePrinting.ValueConverters 23 | { 24 | /// 25 | /// A general converter, taking a lambda as configuration 26 | /// 27 | public class GenericValueConverter : IValueConverter 28 | { 29 | readonly Func convert; 30 | 31 | public GenericValueConverter(Func convert) 32 | { 33 | this.convert = convert; 34 | } 35 | 36 | /// 37 | /// Is the type covered by this handler. 38 | /// 39 | public bool CanHandleType(Type type) 40 | { 41 | return type == typeof(T); 42 | } 43 | 44 | /// 45 | /// Convert objects of handled types into a simple one-line representation. 46 | /// 47 | public string Convert(object source) 48 | { 49 | return convert((T)source); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /StatePrinter/ValueConverters/IValueConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | 22 | namespace StatePrinting.ValueConverters 23 | { 24 | /// 25 | /// A handler that is able to convert a value of specific types to on a single line string. 26 | /// 27 | public interface IValueConverter 28 | { 29 | /// 30 | /// Is the type covered by this handler. 31 | /// 32 | bool CanHandleType(Type type); 33 | 34 | /// 35 | /// Convert objects of handled types into a simple one-line representation. 36 | /// 37 | string Convert(object source); 38 | } 39 | } -------------------------------------------------------------------------------- /StatePrinter/ValueConverters/RollingGuidValueConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace StatePrinting.ValueConverters 24 | { 25 | /// 26 | /// Handles the printing of guids, where each guid is transformed into a very readable form by 27 | /// transforming a small integer into the guid-format. 28 | /// 29 | /// When the same guid is to be printed multiple times, it retains its new simpler-to-read value. 30 | /// 31 | /// This is nice for unit testing, since guids now become stable across multiple executions 32 | /// 33 | public class RollingGuidValueConverter : IValueConverter 34 | { 35 | readonly Dictionary producedGuids = new Dictionary(); 36 | int count = 0; 37 | 38 | public bool CanHandleType(Type t) 39 | { 40 | return t == typeof(Guid); 41 | } 42 | 43 | public string Convert(object source) 44 | { 45 | var guid = (Guid)source; 46 | string result; 47 | if (!producedGuids.TryGetValue(guid, out result)) 48 | { 49 | result = CreateRollingGuid(); 50 | producedGuids.Add(guid, result); 51 | } 52 | return result; 53 | } 54 | 55 | string CreateRollingGuid() 56 | { 57 | if(count == int.MaxValue) 58 | throw new Exception("Such hign number is Not yet supported"); 59 | count++; 60 | 61 | return string.Format("00000000-0000-0000-0000-00{0:D10}", count); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /StatePrinter/ValueConverters/StandardTypesConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | using StatePrinting.Configurations; 22 | 23 | namespace StatePrinting.ValueConverters 24 | { 25 | /// 26 | /// Handles the printing of 27 | /// Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, 28 | /// Double, Single, decimal, Guid 29 | /// 30 | public class StandardTypesConverter : IValueConverter 31 | { 32 | readonly Configuration configuration; 33 | 34 | public StandardTypesConverter(Configuration configuration) 35 | { 36 | this.configuration = configuration; 37 | } 38 | 39 | public bool CanHandleType(Type t) 40 | { 41 | // Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single. 42 | if (t.IsPrimitive) 43 | return true; 44 | 45 | if (t == typeof(decimal) || t == typeof(Guid)) 46 | return true; 47 | 48 | return false; 49 | } 50 | 51 | public string Convert(object source) 52 | { 53 | if (source is float) 54 | return ((float)source).ToString(configuration.Culture); 55 | if (source is double) 56 | return ((double)source).ToString(configuration.Culture); 57 | if (source is decimal) 58 | return ((decimal)source).ToString(configuration.Culture); 59 | 60 | return source.ToString(); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /StatePrinter/ValueConverters/StringConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Kasper B. Graversen 2 | // 3 | // Licensed to the Apache Software Foundation (ASF) under one 4 | // or more contributor license agreements. See the NOTICE file 5 | // distributed with this work for additional information 6 | // regarding copyright ownership. The ASF licenses this file 7 | // to you under the Apache License, Version 2.0 (the 8 | // "License"); you may not use this file except in compliance 9 | // with the License. You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, 14 | // software distributed under the License is distributed on an 15 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | // KIND, either express or implied. See the License for the 17 | // specific language governing permissions and limitations 18 | // under the License. 19 | 20 | using System; 21 | 22 | namespace StatePrinting.ValueConverters 23 | { 24 | /// 25 | /// Handles the printing of 26 | /// 27 | public class StringConverter : IValueConverter 28 | { 29 | readonly string quoteSymbol; 30 | 31 | public StringConverter(string quoteSymbol = "\"") 32 | { 33 | this.quoteSymbol = quoteSymbol; 34 | } 35 | 36 | public bool CanHandleType(Type t) 37 | { 38 | return t == typeof(string); 39 | } 40 | 41 | public string Convert(object source) 42 | { 43 | return string.Format("{0}{1}{0}", quoteSymbol, source); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /StatePrinter/gfx/stateprinter.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbilsted/StatePrinter/76e70caf955303a39116dbf4e750efb9fcea1972/StatePrinter/gfx/stateprinter.ico -------------------------------------------------------------------------------- /StatePrinter/gfx/stateprinter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbilsted/StatePrinter/76e70caf955303a39116dbf4e750efb9fcea1972/StatePrinter/gfx/stateprinter.png -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 3.0.{build} 2 | image: Visual Studio 2019 3 | environment: 4 | COVERALLS_REPO_TOKEN: 5 | secure: RoEmApsXRqFebGBxdrnjuuPoy9+DpcTu5v2s5DCJdtrmh6EsYYN2r+A1e1IuhzUZ 6 | 7 | install: 8 | - nuget restore 9 | 10 | build: 11 | project: StatePrinter.sln 12 | verbosity: minimal 13 | # verbosity: detailed 14 | 15 | 16 | after_test: 17 | - packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -filter:"+[StatePrinter]*" -target:"packages\NUnit.ConsoleRunner.3.9.0\tools\nunit3-console.exe" -targetargs:"StatePrinter.Tests\bin\debug\StatePrinter.Tests.dll /domain:single" -output:"coverage.xml" 18 | 19 | - packages\coveralls.io.1.1.86\tools\coveralls.net.exe --opencover "coverage.xml" 20 | 21 | -------------------------------------------------------------------------------- /doc/ComprehensibleTestingOfGuids.md: -------------------------------------------------------------------------------- 1 | # Making comprehensible tests on data containing Guids 2 | 3 | A common practice in sofware developments, is to guids as the identity of an object. This practice has a number of advantages, but at the same time, makes it tedius to test. 4 | 5 | One advantage is that the primary key can safely be generated in memory rather than the database. Thus an object graph may be stored in one request to the database. Another advantage is, that data from two or more instances of the software components can easily be joined/merged since there are no colliding keys. And despite its crititcs scorning the size of the guid is four times that of an int, and that id `4001` is easier to remember than say `855b152c-c7ee-4510-9449-b2c840b933a6`, it is a safe bet, that guid's are here to stay. 6 | 7 | 8 | 9 | ## Identifying the problem 10 | 11 | Testing data containing guids can be problematic, in that we can rarely make assertions on the specific value of a guid field. Assume an online webshop with the data structure 12 | 13 | ```C# 14 | class Order { 15 | Guid Id = Guid.NewGuid(); 16 | List Lines = new List(); 17 | 18 | public void Add(OrderLine line) { 19 | line.OrderId = Id; 20 | Lines.Add(line); 21 | } 22 | } 23 | ``` 24 | 25 | and the order line 26 | 27 | ```C# 28 | class OrderLine { 29 | public Guid Id = Guid.NewGuid(); 30 | public Guid OrderId; 31 | 32 | public int Quantity; 33 | public Guid ItemId; 34 | public string Description; 35 | } 36 | ``` 37 | --------------------------------------------------------------------------------