├── .gitignore
├── Simple.sln
├── lib
├── powerassert.zip
└── powerassert
│ └── powerassert
│ ├── .hg_archival.txt
│ ├── .hgignore
│ ├── .hgtags
│ ├── PowerAssert.sln
│ ├── PowerAssert
│ ├── Annotations.cs
│ ├── Extensions.cs
│ ├── Infrastructure
│ │ ├── ExpressionParser.cs
│ │ ├── NaturalExpressionProcessor.cs
│ │ ├── NodeFormatter.cs
│ │ ├── Nodes
│ │ │ ├── ArrayIndexNode.cs
│ │ │ ├── BinaryNode.cs
│ │ │ ├── ConditionalNode.cs
│ │ │ ├── ConstantNode.cs
│ │ │ ├── MemberAccessNode.cs
│ │ │ ├── MethodCallNode.cs
│ │ │ ├── NewArrayNode.cs
│ │ │ ├── Node.cs
│ │ │ └── UnaryNode.cs
│ │ ├── Util.Generated.cs
│ │ └── Util.tt
│ ├── PAssert.cs
│ ├── PowerAssertForked.csproj
│ └── Properties
│ │ └── AssemblyInfo.cs
│ ├── PowerAssertTests
│ ├── EndToEndTest.cs
│ ├── NodeFormatterTest.cs
│ ├── ParserTest.cs
│ ├── PowerAssertTests.csproj
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── ThrowsTest.cs
│ └── lib
│ └── nunit.framework.dll
└── src
├── DocGeneratorExample
├── AccountSpecifications.cs
├── DocGeneratorExample.csproj
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── app.config
├── Simple.Testing.CientFramework
├── Simple.Testing.ClientFramework.csproj
└── SpecificationTemplates.cs
├── Simple.Testing.ClientFramework
├── Properties
│ └── AssemblyInfo.cs
├── Simple.Testing.ClientFramework.csproj
└── SpecificationTemplates.cs
├── Simple.Testing.Example
├── DataDrivenSpecification.cs
├── FailingSpecification.cs
├── Properties
│ └── AssemblyInfo.cs
├── QuerySpecification.cs
├── Simple.Testing.Example.csproj
└── SutSpecification.cs
├── Simple.Testing.Framework.Tests
├── MightyMooseIgnoreAttribute.cs
├── NamedMethodGeneratorTests.cs
├── PartialApplicationVisitorSpecifications.cs
├── PassingSpecification.cs
├── Properties
│ └── AssemblyInfo.cs
├── Simple.Testing.Framework.Tests.csproj
└── SpecificationRunnerSpecifications.cs
├── Simple.Testing.Framework
├── ISpecificationGenerator.cs
├── NamedMethodsGenerator.cs
├── OnTypeGenerator.cs
├── PartialApplyicationVisitor.cs
├── Properties
│ └── AssemblyInfo.cs
├── RootGenerator.cs
├── RunResult.cs
├── Simple.Testing.Framework.csproj
├── SimpleRunner.cs
├── SpecificationRunner.cs
├── SpecificationToRun.cs
├── TypeReader.cs
└── extensions.cs
└── Simple.Testing.Runner
├── Options.cs
├── Program.cs
├── Properties
└── AssemblyInfo.cs
├── Simple.Testing.Runner.csproj
└── app.config
/.gitignore:
--------------------------------------------------------------------------------
1 | obj
2 | bin
3 | deploy
4 | deploy/*
5 | test-results/
6 | _ReSharper.*
7 | *.csproj.user
8 | *.resharper.user
9 | *.resharper
10 | *.suo
11 | *.cache
12 | *.userprefs
13 | *.pidb
14 | SolutionVersion.cs
15 | lib/MoMA/Reports/submit.xml
16 | build_output
17 | ReleaseBinaries
18 | code_drop
19 | TestResult.xml
20 | openlocal.sh
21 | openlocal.bat
22 | ~$*
23 | Debug/
24 | Release/
25 | AutoTest.VS.xml
26 | ldeploy.bat
27 | *_mm_cache.bin
28 | *.ncrunchsolution
29 | *.ncrunchsolution.user
30 | *~
31 |
--------------------------------------------------------------------------------
/Simple.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.Testing.Framework", "src\Simple.Testing.Framework\Simple.Testing.Framework.csproj", "{A6E67E2A-2A26-4016-BE26-D6F3141729D9}"
5 | EndProject
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{F4BD98A7-2250-4BD0-AAC5-4F4566E85D31}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DocGeneratorExample", "src\DocGeneratorExample\DocGeneratorExample.csproj", "{60800BA0-9F82-4CE4-A283-5BC27CC7DE04}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.Testing.Example", "src\Simple.Testing.Example\Simple.Testing.Example.csproj", "{A245A823-1DA4-4086-A265-158DC379B446}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.Testing.Framework.Tests", "src\Simple.Testing.Framework.Tests\Simple.Testing.Framework.Tests.csproj", "{25DA7F29-6653-40AA-BB99-35D4BDB840B0}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.Testing.Runner", "src\Simple.Testing.Runner\Simple.Testing.Runner.csproj", "{415B71AE-58D4-4DC3-AD50-6E816DB647A2}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simple.Testing.ClientFramework", "src\Simple.Testing.ClientFramework\Simple.Testing.ClientFramework.csproj", "{AFE5EA9F-2829-4D63-9850-34803552C793}"
17 | EndProject
18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerAssertForked", "lib\powerassert\powerassert\PowerAssert\PowerAssertForked.csproj", "{7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}"
19 | EndProject
20 | Global
21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
22 | Debug|Any CPU = Debug|Any CPU
23 | Debug|Mixed Platforms = Debug|Mixed Platforms
24 | Debug|x86 = Debug|x86
25 | NuPackRelease|Any CPU = NuPackRelease|Any CPU
26 | NuPackRelease|Mixed Platforms = NuPackRelease|Mixed Platforms
27 | NuPackRelease|x86 = NuPackRelease|x86
28 | Release|Any CPU = Release|Any CPU
29 | Release|Mixed Platforms = Release|Mixed Platforms
30 | Release|x86 = Release|x86
31 | EndGlobalSection
32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
33 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
36 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
37 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Debug|x86.ActiveCfg = Debug|Any CPU
38 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.NuPackRelease|Any CPU.ActiveCfg = Release|Any CPU
39 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.NuPackRelease|Any CPU.Build.0 = Release|Any CPU
40 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.NuPackRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
41 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.NuPackRelease|Mixed Platforms.Build.0 = Release|Any CPU
42 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.NuPackRelease|x86.ActiveCfg = Release|Any CPU
43 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
44 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Release|Any CPU.Build.0 = Release|Any CPU
45 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
46 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Release|Mixed Platforms.Build.0 = Release|Any CPU
47 | {A6E67E2A-2A26-4016-BE26-D6F3141729D9}.Release|x86.ActiveCfg = Release|Any CPU
48 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Debug|Any CPU.ActiveCfg = Debug|x86
49 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
50 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Debug|Mixed Platforms.Build.0 = Debug|x86
51 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Debug|x86.ActiveCfg = Debug|x86
52 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Debug|x86.Build.0 = Debug|x86
53 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.NuPackRelease|Any CPU.ActiveCfg = Release|x86
54 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.NuPackRelease|Mixed Platforms.ActiveCfg = Release|x86
55 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.NuPackRelease|Mixed Platforms.Build.0 = Release|x86
56 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.NuPackRelease|x86.ActiveCfg = Release|x86
57 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.NuPackRelease|x86.Build.0 = Release|x86
58 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Release|Any CPU.ActiveCfg = Release|x86
59 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Release|Mixed Platforms.ActiveCfg = Release|x86
60 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Release|Mixed Platforms.Build.0 = Release|x86
61 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Release|x86.ActiveCfg = Release|x86
62 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04}.Release|x86.Build.0 = Release|x86
63 | {A245A823-1DA4-4086-A265-158DC379B446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
64 | {A245A823-1DA4-4086-A265-158DC379B446}.Debug|Any CPU.Build.0 = Debug|Any CPU
65 | {A245A823-1DA4-4086-A265-158DC379B446}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
66 | {A245A823-1DA4-4086-A265-158DC379B446}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
67 | {A245A823-1DA4-4086-A265-158DC379B446}.Debug|x86.ActiveCfg = Debug|Any CPU
68 | {A245A823-1DA4-4086-A265-158DC379B446}.NuPackRelease|Any CPU.ActiveCfg = Release|Any CPU
69 | {A245A823-1DA4-4086-A265-158DC379B446}.NuPackRelease|Any CPU.Build.0 = Release|Any CPU
70 | {A245A823-1DA4-4086-A265-158DC379B446}.NuPackRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
71 | {A245A823-1DA4-4086-A265-158DC379B446}.NuPackRelease|Mixed Platforms.Build.0 = Release|Any CPU
72 | {A245A823-1DA4-4086-A265-158DC379B446}.NuPackRelease|x86.ActiveCfg = Release|Any CPU
73 | {A245A823-1DA4-4086-A265-158DC379B446}.Release|Any CPU.ActiveCfg = Release|Any CPU
74 | {A245A823-1DA4-4086-A265-158DC379B446}.Release|Any CPU.Build.0 = Release|Any CPU
75 | {A245A823-1DA4-4086-A265-158DC379B446}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
76 | {A245A823-1DA4-4086-A265-158DC379B446}.Release|Mixed Platforms.Build.0 = Release|Any CPU
77 | {A245A823-1DA4-4086-A265-158DC379B446}.Release|x86.ActiveCfg = Release|Any CPU
78 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
79 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
80 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
81 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
82 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Debug|x86.ActiveCfg = Debug|Any CPU
83 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.NuPackRelease|Any CPU.ActiveCfg = Release|Any CPU
84 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.NuPackRelease|Any CPU.Build.0 = Release|Any CPU
85 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.NuPackRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
86 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.NuPackRelease|Mixed Platforms.Build.0 = Release|Any CPU
87 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.NuPackRelease|x86.ActiveCfg = Release|Any CPU
88 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
89 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Release|Any CPU.Build.0 = Release|Any CPU
90 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
91 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
92 | {25DA7F29-6653-40AA-BB99-35D4BDB840B0}.Release|x86.ActiveCfg = Release|Any CPU
93 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Debug|Any CPU.ActiveCfg = Debug|x86
94 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
95 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Debug|Mixed Platforms.Build.0 = Debug|x86
96 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Debug|x86.ActiveCfg = Debug|x86
97 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Debug|x86.Build.0 = Debug|x86
98 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.NuPackRelease|Any CPU.ActiveCfg = Release|x86
99 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.NuPackRelease|Mixed Platforms.ActiveCfg = Release|x86
100 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.NuPackRelease|Mixed Platforms.Build.0 = Release|x86
101 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.NuPackRelease|x86.ActiveCfg = Release|x86
102 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.NuPackRelease|x86.Build.0 = Release|x86
103 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Release|Any CPU.ActiveCfg = Release|x86
104 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Release|Mixed Platforms.ActiveCfg = Release|x86
105 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Release|Mixed Platforms.Build.0 = Release|x86
106 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Release|x86.ActiveCfg = Release|x86
107 | {415B71AE-58D4-4DC3-AD50-6E816DB647A2}.Release|x86.Build.0 = Release|x86
108 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
109 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Debug|Any CPU.Build.0 = Debug|Any CPU
110 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
111 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
112 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Debug|x86.ActiveCfg = Debug|Any CPU
113 | {AFE5EA9F-2829-4D63-9850-34803552C793}.NuPackRelease|Any CPU.ActiveCfg = Release|Any CPU
114 | {AFE5EA9F-2829-4D63-9850-34803552C793}.NuPackRelease|Any CPU.Build.0 = Release|Any CPU
115 | {AFE5EA9F-2829-4D63-9850-34803552C793}.NuPackRelease|Mixed Platforms.ActiveCfg = Release|Any CPU
116 | {AFE5EA9F-2829-4D63-9850-34803552C793}.NuPackRelease|Mixed Platforms.Build.0 = Release|Any CPU
117 | {AFE5EA9F-2829-4D63-9850-34803552C793}.NuPackRelease|x86.ActiveCfg = Release|Any CPU
118 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Release|Any CPU.ActiveCfg = Release|Any CPU
119 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Release|Any CPU.Build.0 = Release|Any CPU
120 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
121 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Release|Mixed Platforms.Build.0 = Release|Any CPU
122 | {AFE5EA9F-2829-4D63-9850-34803552C793}.Release|x86.ActiveCfg = Release|Any CPU
123 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
124 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
125 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
126 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
127 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Debug|x86.ActiveCfg = Debug|Any CPU
128 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.NuPackRelease|Any CPU.ActiveCfg = NuPackRelease|Any CPU
129 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.NuPackRelease|Any CPU.Build.0 = NuPackRelease|Any CPU
130 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.NuPackRelease|Mixed Platforms.ActiveCfg = NuPackRelease|Any CPU
131 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.NuPackRelease|Mixed Platforms.Build.0 = NuPackRelease|Any CPU
132 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.NuPackRelease|x86.ActiveCfg = NuPackRelease|Any CPU
133 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
134 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Release|Any CPU.Build.0 = Release|Any CPU
135 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
136 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Release|Mixed Platforms.Build.0 = Release|Any CPU
137 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Release|x86.ActiveCfg = Release|Any CPU
138 | EndGlobalSection
139 | GlobalSection(SolutionProperties) = preSolution
140 | HideSolutionNode = FALSE
141 | EndGlobalSection
142 | GlobalSection(NestedProjects) = preSolution
143 | {60800BA0-9F82-4CE4-A283-5BC27CC7DE04} = {F4BD98A7-2250-4BD0-AAC5-4F4566E85D31}
144 | {A245A823-1DA4-4086-A265-158DC379B446} = {F4BD98A7-2250-4BD0-AAC5-4F4566E85D31}
145 | EndGlobalSection
146 | EndGlobal
147 |
--------------------------------------------------------------------------------
/lib/powerassert.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gregoryyoung/Simple.Testing/80e8cb06dc19d6d08c7ee9c48ba4a91c77d0c52a/lib/powerassert.zip
--------------------------------------------------------------------------------
/lib/powerassert/powerassert/.hg_archival.txt:
--------------------------------------------------------------------------------
1 | repo: 2c8ea7745a23d74598bea917327266eada703926
2 | node: 8e1d4d6874e16f7b2f925a23a19005a26bc386de
3 | branch: default
4 | latesttag: Release 1.0.2
5 | latesttagdistance: 2
6 |
--------------------------------------------------------------------------------
/lib/powerassert/powerassert/.hgignore:
--------------------------------------------------------------------------------
1 | glob:*.user
2 | glob:*/bin
3 | glob:*/obj
4 | glob:_*
5 | glob:*.suo
6 | glob:PowerAssert/release/lib
7 | glob:*.nupkg
8 |
--------------------------------------------------------------------------------
/lib/powerassert/powerassert/.hgtags:
--------------------------------------------------------------------------------
1 | 4d81d40701f2d8cf150917e79a64acd47339d6c5 Release 1.0
2 | 8ac20fe95c6598e3407e1aa4bbdbd4aeb0320d57 Release 1.0.1
3 | c6fcc7fc78f36207f75861062f8cae9c8dc4659c Release 1.0.2
4 |
--------------------------------------------------------------------------------
/lib/powerassert/powerassert/PowerAssert.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerAssert", "PowerAssert\PowerAssert.csproj", "{7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerAssertTests", "PowerAssertTests\PowerAssertTests.csproj", "{665FDD28-99EF-4038-9469-1B27F778BF1D}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | NuPackRelease|Any CPU = NuPackRelease|Any CPU
12 | Release|Any CPU = Release|Any CPU
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
16 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
17 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.NuPackRelease|Any CPU.ActiveCfg = NuPackRelease|Any CPU
18 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.NuPackRelease|Any CPU.Build.0 = NuPackRelease|Any CPU
19 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {7E9D2DB4-78FE-41BD-9566-15F68D42E4D9}.Release|Any CPU.Build.0 = Release|Any CPU
21 | {665FDD28-99EF-4038-9469-1B27F778BF1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {665FDD28-99EF-4038-9469-1B27F778BF1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {665FDD28-99EF-4038-9469-1B27F778BF1D}.NuPackRelease|Any CPU.ActiveCfg = Release|Any CPU
24 | {665FDD28-99EF-4038-9469-1B27F778BF1D}.NuPackRelease|Any CPU.Build.0 = Release|Any CPU
25 | {665FDD28-99EF-4038-9469-1B27F778BF1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {665FDD28-99EF-4038-9469-1B27F778BF1D}.Release|Any CPU.Build.0 = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(SolutionProperties) = preSolution
29 | HideSolutionNode = FALSE
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/lib/powerassert/powerassert/PowerAssert/Annotations.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace JetBrains.Annotations
5 | {
6 | ///
7 | /// Indicates that marked element should be localized or not.
8 | ///
9 | [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
10 | internal sealed class LocalizationRequiredAttribute : Attribute
11 | {
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | /// true if a element should be localized; otherwise, false.
16 | internal LocalizationRequiredAttribute(bool required)
17 | {
18 | Required = required;
19 | }
20 |
21 | ///
22 | /// Gets a value indicating whether a element should be localized.
23 | /// true if a element should be localized; otherwise, false.
24 | ///
25 | internal bool Required { get; set; }
26 |
27 | ///
28 | /// Returns whether the value of the given object is equal to the current .
29 | ///
30 | /// The object to test the value equality of.
31 | ///
32 | /// true if the value of the given object is equal to that of the current; otherwise, false.
33 | ///
34 | public override bool Equals(object obj)
35 | {
36 | var attribute = obj as LocalizationRequiredAttribute;
37 | return attribute != null && attribute.Required == Required;
38 | }
39 |
40 | ///
41 | /// Returns the hash code for this instance.
42 | ///
43 | /// A hash code for the current .
44 | public override int GetHashCode()
45 | {
46 | return base.GetHashCode();
47 | }
48 | }
49 |
50 | ///
51 | /// Indicates that marked method builds string by format pattern and (optional) arguments.
52 | /// Parameter, which contains format string, should be given in constructor.
53 | /// The format string should be in -like form
54 | ///
55 | [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
56 | internal sealed class StringFormatMethodAttribute : Attribute
57 | {
58 | private readonly string myFormatParameterName;
59 |
60 | ///
61 | /// Initializes new instance of StringFormatMethodAttribute
62 | ///
63 | /// Specifies which parameter of an annotated method should be treated as format-string
64 | internal StringFormatMethodAttribute(string formatParameterName)
65 | {
66 | myFormatParameterName = formatParameterName;
67 | }
68 |
69 | ///
70 | /// Gets format parameter name
71 | ///
72 | internal string FormatParameterName
73 | {
74 | get { return myFormatParameterName; }
75 | }
76 | }
77 |
78 | ///
79 | /// Indicates that the function argument should be string literal and match one of the parameters of the caller function.
80 | /// For example, has such parameter.
81 | ///
82 | [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
83 | internal sealed class InvokerParameterNameAttribute : Attribute
84 | {
85 | }
86 |
87 | ///
88 | /// Indicates that the marked method is assertion method, i.e. it halts control flow if one of the conditions is satisfied.
89 | /// To set the condition, mark one of the parameters with attribute
90 | ///
91 | ///
92 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
93 | internal sealed class AssertionMethodAttribute : Attribute
94 | {
95 | }
96 |
97 | ///
98 | /// Indicates the condition parameter of the assertion method.
99 | /// The method itself should be marked by attribute.
100 | /// The mandatory argument of the attribute is the assertion type.
101 | ///
102 | ///
103 | [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
104 | internal sealed class AssertionConditionAttribute : Attribute
105 | {
106 | private readonly AssertionConditionType myConditionType;
107 |
108 | ///
109 | /// Initializes new instance of AssertionConditionAttribute
110 | ///
111 | /// Specifies condition type
112 | internal AssertionConditionAttribute(AssertionConditionType conditionType)
113 | {
114 | myConditionType = conditionType;
115 | }
116 |
117 | ///
118 | /// Gets condition type
119 | ///
120 | internal AssertionConditionType ConditionType
121 | {
122 | get { return myConditionType; }
123 | }
124 | }
125 |
126 | ///
127 | /// Specifies assertion type. If the assertion method argument satisifes the condition, then the execution continues.
128 | /// Otherwise, execution is assumed to be halted
129 | ///
130 | internal enum AssertionConditionType
131 | {
132 | ///
133 | /// Indicates that the marked parameter should be evaluated to true
134 | ///
135 | IS_TRUE = 0,
136 |
137 | ///
138 | /// Indicates that the marked parameter should be evaluated to false
139 | ///
140 | IS_FALSE = 1,
141 |
142 | ///
143 | /// Indicates that the marked parameter should be evaluated to null value
144 | ///
145 | IS_NULL = 2,
146 |
147 | ///
148 | /// Indicates that the marked parameter should be evaluated to not null value
149 | ///
150 | IS_NOT_NULL = 3,
151 | }
152 |
153 | ///
154 | /// Indicates that the marked method unconditionally terminates control flow execution.
155 | /// For example, it could unconditionally throw exception
156 | ///
157 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
158 | internal sealed class TerminatesProgramAttribute : Attribute
159 | {
160 | }
161 |
162 | ///
163 | /// Indicates that the value of marked element could be null sometimes, so the check for null is necessary before its usage
164 | ///
165 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
166 | internal sealed class CanBeNullAttribute : Attribute
167 | {
168 | }
169 |
170 | ///
171 | /// Indicates that the value of marked element could never be null
172 | ///
173 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
174 | internal sealed class NotNullAttribute : Attribute
175 | {
176 | }
177 |
178 | ///
179 | /// Indicates that the value of marked type (or its derivatives) cannot be compared using '==' or '!=' operators.
180 | /// There is only exception to compare with null, it is permitted
181 | ///
182 | [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
183 | internal sealed class CannotApplyEqualityOperatorAttribute : Attribute
184 | {
185 | }
186 |
187 | ///
188 | /// When applied to target attribute, specifies a requirement for any type which is marked with
189 | /// target attribute to implement or inherit specific type or types
190 | ///
191 | ///
192 | ///
193 | /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement
194 | /// internal class ComponentAttribute : Attribute
195 | /// {}
196 | ///
197 | /// [Component] // ComponentAttribute requires implementing IComponent interface
198 | /// internal class MyComponent : IComponent
199 | /// {}
200 | ///
201 | ///
202 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
203 | [BaseTypeRequired(typeof(Attribute))]
204 | internal sealed class BaseTypeRequiredAttribute : Attribute
205 | {
206 | private readonly Type[] myBaseTypes;
207 |
208 | ///
209 | /// Initializes new instance of BaseTypeRequiredAttribute
210 | ///
211 | /// Specifies which types are required
212 | internal BaseTypeRequiredAttribute(params Type[] baseTypes)
213 | {
214 | myBaseTypes = baseTypes;
215 | }
216 |
217 | ///
218 | /// Gets enumerations of specified base types
219 | ///
220 | internal IEnumerable BaseTypes
221 | {
222 | get { return myBaseTypes; }
223 | }
224 | }
225 |
226 | ///
227 | /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library),
228 | /// so this symbol will not be marked as unused (as well as by other usage inspections)
229 | ///
230 | [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
231 | internal sealed class UsedImplicitlyAttribute : Attribute
232 | {
233 | [UsedImplicitly]
234 | internal UsedImplicitlyAttribute()
235 | : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
236 | {
237 | }
238 |
239 | [UsedImplicitly]
240 | internal UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
241 | {
242 | UseKindFlags = useKindFlags;
243 | TargetFlags = targetFlags;
244 | }
245 |
246 | [UsedImplicitly]
247 | internal UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
248 | : this(useKindFlags, ImplicitUseTargetFlags.Default)
249 | {
250 | }
251 |
252 | [UsedImplicitly]
253 | internal UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
254 | : this(ImplicitUseKindFlags.Default, targetFlags)
255 | {
256 | }
257 |
258 | [UsedImplicitly]
259 | internal ImplicitUseKindFlags UseKindFlags { get; private set; }
260 |
261 | ///
262 | /// Gets value indicating what is meant to be used
263 | ///
264 | [UsedImplicitly]
265 | internal ImplicitUseTargetFlags TargetFlags { get; private set; }
266 | }
267 |
268 | ///
269 | /// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes as unused (as well as by other usage inspections)
270 | ///
271 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
272 | internal sealed class MeansImplicitUseAttribute : Attribute
273 | {
274 | [UsedImplicitly]
275 | internal MeansImplicitUseAttribute()
276 | : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
277 | {
278 | }
279 |
280 | [UsedImplicitly]
281 | internal MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
282 | {
283 | UseKindFlags = useKindFlags;
284 | TargetFlags = targetFlags;
285 | }
286 |
287 | [UsedImplicitly]
288 | internal MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
289 | : this(useKindFlags, ImplicitUseTargetFlags.Default)
290 | {
291 | }
292 |
293 | [UsedImplicitly]
294 | internal MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
295 | : this(ImplicitUseKindFlags.Default, targetFlags)
296 | {
297 | }
298 |
299 | [UsedImplicitly]
300 | internal ImplicitUseKindFlags UseKindFlags { get; private set; }
301 |
302 | ///
303 | /// Gets value indicating what is meant to be used
304 | ///
305 | [UsedImplicitly]
306 | internal ImplicitUseTargetFlags TargetFlags { get; private set; }
307 | }
308 |
309 | [Flags]
310 | internal enum ImplicitUseKindFlags
311 | {
312 | Default = Access | Assign | Instantiated,
313 |
314 | ///
315 | /// Only entity marked with attribute considered used
316 | ///
317 | Access = 1,
318 |
319 | ///
320 | /// Indicates implicit assignment to a member
321 | ///
322 | Assign = 2,
323 |
324 | ///
325 | /// Indicates implicit instantiation of a type
326 | ///
327 | Instantiated = 4,
328 | }
329 |
330 | ///
331 | /// Specify what is considered used implicitly when marked with or
332 | ///
333 | [Flags]
334 | internal enum ImplicitUseTargetFlags
335 | {
336 | Default = Itself,
337 |
338 | Itself = 1,
339 |
340 | ///
341 | /// Members of entity marked with attribute are considered used
342 | ///
343 | Members = 2,
344 |
345 | ///
346 | /// Entity marked with attribute and all its members considered used
347 | ///
348 | WithMembers = Itself | Members
349 | }
350 | }
--------------------------------------------------------------------------------
/lib/powerassert/powerassert/PowerAssert/Extensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace PowerAssert
7 | {
8 | public static class Extensions
9 | {
10 | public static string CleanupName(this string name)
11 | {
12 | var tmp = name.CleanupUnderScores();
13 | return tmp.CleanupCamelCasing();
14 | }
15 |
16 | public static string CleanupUnderScores(this string name)
17 | {
18 | if (name.Contains('_'))
19 | return name.Replace('_', ' ');
20 | return name;
21 | }
22 |
23 | public static string CleanupCamelCasing(this string name)
24 | {
25 | return System.Text.RegularExpressions.Regex.Replace(name,
26 | "([A-Z])",
27 | " $1",
28 | System.Text.RegularExpressions.RegexOptions.Compiled
29 | ).Trim();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/powerassert/powerassert/PowerAssert/Infrastructure/ExpressionParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Globalization;
5 | using System.Linq;
6 | using System.Linq.Expressions;
7 | using System.Reflection;
8 | using System.Runtime.CompilerServices;
9 | using PowerAssert.Infrastructure.Nodes;
10 |
11 | namespace PowerAssert.Infrastructure
12 | {
13 | internal class ExpressionParser
14 | {
15 | public static Node Parse(Expression e)
16 | {
17 | if (e.NodeType == ExpressionType.ArrayIndex)
18 | {
19 | return ArrayIndex((BinaryExpression)e);
20 | }
21 | if (e is BinaryExpression)
22 | {
23 | return Binary((BinaryExpression)e, Util.Operators[e.NodeType]);
24 | }
25 | if (e is MemberExpression)
26 | {
27 | return Member((MemberExpression)e);
28 | }
29 | if (e is ConstantExpression)
30 | {
31 | return Constant((ConstantExpression)e);
32 | }
33 | if (e is MethodCallExpression)
34 | {
35 | return MethodCall((MethodCallExpression)e);
36 | }
37 | if (e is ConditionalExpression)
38 | {
39 | return Conditional((ConditionalExpression)e);
40 | }
41 | if (e is NewArrayExpression)
42 | {
43 | return NewArray((NewArrayExpression)e);
44 | }
45 | if (e is UnaryExpression)
46 | {
47 | return Unary((UnaryExpression)e);
48 | }
49 | if (e.NodeType == ExpressionType.Lambda)
50 | {
51 | return Lambda(e);
52 | }
53 | if (e is TypeBinaryExpression)
54 | {
55 | return TypeBinary((TypeBinaryExpression)e);
56 | }
57 | throw new ArgumentOutOfRangeException("e", string.Format("Can't handle expression of class {0} and type {1}", e.GetType().Name, e.NodeType));
58 |
59 | }
60 |
61 | static Node TypeBinary(TypeBinaryExpression e)
62 | {
63 | switch (e.NodeType)
64 | {
65 | case ExpressionType.TypeIs:
66 | return new BinaryNode()
67 | {
68 | Left = Parse(e.Expression),
69 | Operator = "is",
70 | Right = new ConstantNode() { Text = NameOfType(e.TypeOperand) },
71 | Value = GetValue(e)
72 | };
73 | default:
74 | throw new NotImplementedException(string.Format(CultureInfo.CurrentCulture,
75 | "Can't handle TypeBinaryExpression of type {0}",
76 | e.NodeType));
77 | }
78 | }
79 |
80 | static Node Lambda(Expression e)
81 | {
82 | return new ConstantNode() { Text = e.ToString() };
83 | }
84 |
85 | static Node Unary(UnaryExpression e)
86 | {
87 | switch (e.NodeType)
88 | {
89 | case ExpressionType.Convert:
90 | return new UnaryNode() { Prefix = "(" + NameOfType(e.Type) + ")(", Operand = Parse(e.Operand), Suffix = ")", PrefixValue = GetValue(e) };
91 | case ExpressionType.Not:
92 | return new UnaryNode() { Prefix = "!", Operand = Parse(e.Operand), PrefixValue = GetValue(e) };
93 | case ExpressionType.Negate:
94 | case ExpressionType.NegateChecked:
95 | return new UnaryNode() { Prefix = "-", Operand = Parse(e.Operand), PrefixValue = GetValue(e) };
96 |
97 |
98 | }
99 | throw new ArgumentOutOfRangeException("e", string.Format("Can't handle UnaryExpression expression of class {0} and type {1}", e.GetType().Name, e.NodeType));
100 |
101 | }
102 |
103 | static Node NewArray(NewArrayExpression e)
104 | {
105 | switch (e.NodeType)
106 | {
107 | case ExpressionType.NewArrayInit:
108 | Type t = e.Type.GetElementType();
109 | return new NewArrayNode
110 | {
111 | Items = e.Expressions.Select(Parse).ToList(),
112 | Type = NameOfType(t)
113 | };
114 | case ExpressionType.NewArrayBounds:
115 | //todo:
116 | default:
117 | throw new ArgumentOutOfRangeException();
118 | }
119 | }
120 |
121 | private static readonly Dictionary Aliases = new Dictionary()
122 | {
123 | { typeof(byte), "byte" },
124 | { typeof(sbyte), "sbyte" },
125 | { typeof(short), "short" },
126 | { typeof(ushort), "ushort" },
127 | { typeof(int), "int" },
128 | { typeof(uint), "uint" },
129 | { typeof(long), "long" },
130 | { typeof(ulong), "ulong" },
131 | { typeof(float), "float" },
132 | { typeof(double), "double" },
133 | { typeof(decimal), "decimal" },
134 | { typeof(object), "object" },
135 | { typeof(string), "string" },
136 | };
137 |
138 |
139 | static string NameOfType(Type t)
140 | {
141 | return Aliases.ContainsKey(t) ? Aliases[t] : t.Name;
142 | }
143 |
144 | static Node ArrayIndex(BinaryExpression e)
145 | {
146 | return new ArrayIndexNode() { Array = Parse(e.Left), Index = Parse(e.Right), Value = GetValue(e) };
147 | }
148 |
149 | static Node Conditional(ConditionalExpression e)
150 | {
151 | return new ConditionalNode
152 | {
153 | Condition = Parse(e.Test),
154 | FalseValue = Parse(e.IfFalse),
155 | TrueValue = Parse(e.IfTrue)
156 | };
157 | }
158 |
159 | static Node MethodCall(MethodCallExpression e)
160 | {
161 | var parameters = e.Arguments.Select(Parse);
162 | if(e.Method.GetCustomAttributes(typeof(ExtensionAttribute), true).Any())
163 | {
164 | return new MethodCallNode
165 | {
166 | Container = parameters.First(),
167 | MemberName = e.Method.Name,
168 | MemberValue = GetValue(e),
169 | Parameters = parameters.Skip(1).ToList(),
170 | };
171 | }
172 | else
173 | {
174 | return new MethodCallNode
175 | {
176 | Container = e.Object == null ? new ConstantNode() { Text = e.Method.DeclaringType.Name } : Parse(e.Object),
177 | MemberName = e.Method.Name,
178 | MemberValue = GetValue(e),
179 | Parameters = parameters.ToList(),
180 | };
181 | }
182 |
183 | }
184 |
185 | static Node Constant(ConstantExpression e)
186 | {
187 | string value = GetValue(e);
188 |
189 | return new ConstantNode
190 | {
191 | Text = value
192 | };
193 | }
194 |
195 | static Node Member(MemberExpression e)
196 | {
197 | if (IsDisplayClass(e.Expression) || e.Expression == null)
198 | {
199 | return new ConstantNode
200 | {
201 | Value = GetValue(e),
202 | Text = e.Member.Name
203 | };
204 | }
205 | return new MemberAccessNode
206 | {
207 | Container = Parse(e.Expression),
208 | MemberValue = GetValue(e),
209 | MemberName = e.Member.Name
210 | };
211 | }
212 |
213 |
214 | static bool IsDisplayClass(Expression expression)
215 | {
216 | if (expression is ConstantExpression)
217 | {
218 | return expression.Type.Name.StartsWith("<");
219 | }
220 | return false;
221 | }
222 |
223 | static Node Binary(BinaryExpression e, string text)
224 | {
225 | return new BinaryNode
226 | {
227 | Operator = text,
228 | Value = GetValue(e),
229 | Left = Parse(e.Left),
230 | Right = Parse(e.Right),
231 | };
232 | }
233 |
234 | static string GetValue(Expression e)
235 | {
236 | object value;
237 | try
238 | {
239 | value = DynamicInvoke(e);
240 | }
241 | catch (TargetInvocationException exception)
242 | {
243 | return FormatTargetInvocationException(exception);
244 | }
245 | var s = FormatObject(value);
246 | return s + GetHints(e, value);
247 | }
248 |
249 | static string FormatTargetInvocationException(TargetInvocationException exception)
250 | {
251 | var i = exception.InnerException;
252 | return string.Format("{0}: {1}", i.GetType().Name, i.Message);
253 | }
254 |
255 | static string GetHints(Expression e, object value)
256 | {
257 | if (value is bool && !(bool)value && e is BinaryExpression && e.NodeType == ExpressionType.Equal)
258 | {
259 | var be = (BinaryExpression)e;
260 | object left;
261 | object right;
262 | try
263 | {
264 | left = DynamicInvoke(be.Left);
265 | right = DynamicInvoke(be.Right);
266 | }
267 | catch (TargetInvocationException exception)
268 | {
269 | return FormatTargetInvocationException(exception);
270 | }
271 | if (Object.Equals(left, right))
272 | {
273 | return ", but would have been True with .Equals()";
274 | }
275 | if (left is string && right is string)
276 | {
277 | if (((string)left).Equals((string)right, StringComparison.InvariantCultureIgnoreCase))
278 | {
279 | return ", but would have been True if case insensitive";
280 | }
281 | return "";
282 | }
283 | if (left is IEnumerable && right is IEnumerable)
284 | {
285 | if (((IEnumerable)left).Cast