diff --git a/standard/arrays.md b/standard/arrays.md index 87702a383..f762d5d66 100644 --- a/standard/arrays.md +++ b/standard/arrays.md @@ -128,6 +128,7 @@ Because of array covariance, assignments to elements of reference type arrays in > *Example*: > +> > ```csharp > class Test > { diff --git a/tools/ExampleExtractor/ExampleMetadata.cs b/tools/ExampleExtractor/ExampleMetadata.cs index c719b1d49..25e28cf79 100644 --- a/tools/ExampleExtractor/ExampleMetadata.cs +++ b/tools/ExampleExtractor/ExampleMetadata.cs @@ -23,6 +23,7 @@ public class ExampleMetadata public List ExpectedErrors { get; set; } public List ExpectedWarnings { get; set; } public List ExpectedOutput { get; set; } + public string ExpectedException { get; set; } // Information provided by the example extractor public string MarkdownFile { get; set; } diff --git a/tools/ExampleTester/GeneratedExample.cs b/tools/ExampleTester/GeneratedExample.cs index 7c0d3c0a6..968c49c2d 100644 --- a/tools/ExampleTester/GeneratedExample.cs +++ b/tools/ExampleTester/GeneratedExample.cs @@ -95,11 +95,19 @@ bool ValidateOutput() var oldOut = Console.Out; List actualLines; + Exception? actualException = null; try { var builder = new StringBuilder(); Console.SetOut(new StringWriter(builder)); - method.Invoke(null, arguments); + try + { + method.Invoke(null, arguments); + } + catch (TargetInvocationException outer) + { + actualException = outer.InnerException ?? throw new InvalidOperationException("TargetInvocationException had no nested exception"); + } // Skip blank lines, to avoid unnecessary trailing empties. actualLines = builder.ToString().Replace("\r\n", "\n").Split('\n').Where(line => line != "").ToList(); } @@ -108,7 +116,31 @@ bool ValidateOutput() Console.SetOut(oldOut); } var expectedLines = Metadata.ExpectedOutput ?? new List(); - return ValidateExpectedAgainstActual("output", expectedLines, actualLines); + return ValidateException(actualException, Metadata.ExpectedException) && + ValidateExpectedAgainstActual("output", expectedLines, actualLines); + } + + bool ValidateException(Exception? actualException, string? expectedExceptionName) + { + return (actualException, expectedExceptionName) switch + { + (null, null) => true, + (Exception ex, string name) => + MaybeReportError(ex.GetType().Name == name, $" Mismatched exception type: Expected {name}; Was {ex.GetType().Name}"), + (null, string name) => + MaybeReportError(false, $" Expected exception type {name}; no exception was thrown"), + (Exception ex, null) => + MaybeReportError(false, $" Exception type {ex.GetType().Name} was thrown unexpectedly; Message: {ex.Message}") + }; + + bool MaybeReportError(bool result, string message) + { + if (!result) + { + Console.WriteLine(message); + } + return result; + } } bool ValidateExpectedAgainstActual(string type, List expected, List actual)