Added a Compiler Assert class (work in progress); Updated Struct declaration as read-only; Minor changes to Listin 9.18 which is frequently (but not always), failing.
MODIFY
EssentialCSharp.sln
EssentialCSharp.sln
@@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{91698F73-19EB-4531-980C-5B8B76DC28C9}"
ProjectSection(SolutionItems) = preProject
+ src\Shared\CompilerAssert.cs = src\Shared\CompilerAssert.cs
src\Shared\DoWorkEventArgs.cs = src\Shared\DoWorkEventArgs.cs
src\Shared\NetCore.cs = src\Shared\NetCore.cs
src\Shared\PiCalculator+InternalPiDigitCalculator.cs = src\Shared\PiCalculator+InternalPiDigitCalculator.cs
@@ -608,8 +609,6 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {712ED6C0-5F52-4F27-B3D2-B0273E92F5F0}
EndGlobalSection

MODIFY
src/Chapter09.Tests/Chapter09.Tests.csproj
src/Chapter09.Tests/Chapter09.Tests.csproj
<ProductName>Chapter09.Tests</ProductName>
</PropertyGroup>
<Import Project="..\ChapterTests.props" />
+ <ItemGroup>
+ <Compile Include="..\Shared\CompilerAssert.cs" Link="CompilerAssert.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.3.1" />
+ </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Chapter09\Chapter09.csproj" />
</ItemGroup>

MODIFY
src/Chapter09.Tests/Listing09.18.UsingFlagsAttribute.cs
src/Chapter09.Tests/Listing09.18.UsingFlagsAttribute.cs
@@ -10,10 +10,6 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter09.Listing09_18.Tests
[TestMethod]
public void Main_FileAttributes_UseFlagsAttribute()
{
- if (File.Exists("enum.txt"))
- {
- File.Delete("enum.txt");
- }
string expected = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? @"""ReadOnly | Hidden"" outputs as ""ReadOnly, Hidden""
ReadOnly, Hidden"

MODIFY
src/Chapter09/Listing09.18.UsingFlagsAttribute.cs
src/Chapter09/Listing09.18.UsingFlagsAttribute.cs
public static void Main()
{
string fileName = @"enumtest.txt";
+ File.Delete(fileName);
FileInfo file = new FileInfo(fileName);
- file.Open(FileMode.Create).Dispose();
+ file.Open(FileMode.OpenOrCreate).Dispose();
FileAttributes startingAttributes =
file.Attributes;

ADD
src/Shared/CompilerAssert.cs
+using Microsoft.CSharp;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.CodeAnalysis.CSharp.Scripting;
+using Microsoft.CodeAnalysis.Scripting;
+using Microsoft.CodeAnalysis;
+using System.Linq;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+#nullable enable
+namespace AddisonWesley.Michaelis.EssentialCSharp.Shared
+{
+ readonly public struct CompileError
+ {
+ public string Id { get; }
+ public string Message { get; }
+
+ public CompileError(string id, string message)
+ {
+ Id = id;
+ Message = message;
+ }
+ public void Deconstruct(out string id, out string message)
+ {
+ (id, message) = (Id, Message);
+ }
+ }
+ static public class CompilerAssert
+ {
+ static CSharpCodeProvider Compiler { get; } = new CSharpCodeProvider();
+ //public static ICodeCompiler CodeCompiler { get; } = CodeProvider.CreateCompiler();
+ async static public Task ExpectErrorsAsync(string sourceCode, params CompileError[] diagnostics)
+ {
+ try
+ {
+ await CSharpScript.EvaluateAsync(sourceCode);
+ }
+ catch(CompilationErrorException exception)
+ {
+ Assert.IsTrue(exception.Diagnostics.Length > 0);
+ if(diagnostics is { } && diagnostics.Length >0)
+ {
+ CompileError[] actualCompileErrors = exception.Diagnostics.Select(item =>
+ new CompileError(item.Id, item.GetMessage())).ToArray();
+
+ Assert.AreEqual<int>(diagnostics.Length, actualCompileErrors.Length,
+ "The number of errors returned does not match what was expected.");
+
+ for (int i = 0; i < actualCompileErrors.Length; i++)
+ {
+ Assert.AreEqual<string>(diagnostics[i].Id, diagnostics[i].Id,
+ $"The expected Ids do not match for item {i}: " +
+ $"{diagnostics[i].Id} <> {diagnostics[i].Id}");
+ Assert.AreEqual<string>(diagnostics[i].Message, actualCompileErrors[i].Message,
+ $"The expected Messages do not match for item {i}: " +
+ $"{diagnostics[i].Message} <> {diagnostics[i].Message}");
+ }
+ //CollectionAssert.AreEquivalent(
+ // diagnostics,
+ // actualCompileErrors.ToList());
+ }
+ }
+ Assert.Fail("The expected compilation errors did not occur.");
+ }
+ }
+}

Added a Compiler Assert class (work in progress); Updated Struct declaration as read-only; Minor changes to Listin 9.18 which is frequently (but not always), failing.