Skip to content

Commit d18331b

Browse files
authored
Add ignoreOutput option for example metadata (#724)
This allows the output to be ignored for nondeterministic or implementation-defined behavior.
1 parent 82671a4 commit d18331b

File tree

4 files changed

+20
-4
lines changed

4 files changed

+20
-4
lines changed

standard/basic-concepts.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ The behavior of the garbage collector can be controlled, to some degree, via sta
968968
969969
> *Example*: Since the garbage collector is allowed wide latitude in deciding when to collect objects and run finalizers, a conforming implementation might produce output that differs from that shown by the following code. The program
970970
>
971-
> <!-- ImplementationDefined$Example: {template:"standalone-console",name:"MemoryManagement1", expectedOutput:["xx"]} -->
971+
> <!-- Example: {template:"standalone-console",name:"MemoryManagement1", ignoreOutput:true} -->
972972
> <!-- Maintenance Note: The behavior of this example is implementation-defined. As such, the metadata does *not* compare test output with any ```console block. -->
973973
> ```csharp
974974
> class A
@@ -1023,7 +1023,7 @@ The behavior of the garbage collector can be controlled, to some degree, via sta
10231023
>
10241024
> In subtle cases, the distinction between “eligible for finalization” and “eligible for collection” can be important. For example,
10251025
>
1026-
> <!-- ImplementationDefined$Example: {template:"standalone-console",name:"MemoryManagement2", expectedOutput:["xx"]} -->
1026+
> <!-- Example: {template:"standalone-console",name:"MemoryManagement2", ignoreOutput:true} -->
10271027
> <!-- Maintenance Note: The behavior of this example is implementation-defined. As such, the metadata does *not* compare test output with any ```console block. -->
10281028
> ```csharp
10291029
> class A

tools/ExampleExtractor/Example.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,19 @@ private static IEnumerable<Example> LoadExamplesFromFile(string markdownFile)
105105
metadata.EndLine = closingLine;
106106
metadata.MarkdownFile = Path.GetFileName(markdownFile);
107107

108+
if (metadata.IgnoreOutput)
109+
{
110+
if (metadata.InferOutput || metadata.ExpectedOutput is not null)
111+
{
112+
throw new InvalidOperationException($"Example {metadata.Name} has both {nameof(metadata.IgnoreOutput)} and either {nameof(metadata.InferOutput)} or {nameof(metadata.ExpectedOutput)}");
113+
}
114+
}
115+
108116
if (metadata.InferOutput)
109117
{
110118
if (metadata.ExpectedOutput is not null)
111119
{
112-
throw new InvalidOperationException($"Example {metadata.Name} has both ${nameof(metadata.InferOutput)} and {nameof(metadata.ExpectedOutput)}");
120+
throw new InvalidOperationException($"Example {metadata.Name} has both {nameof(metadata.InferOutput)} and {nameof(metadata.ExpectedOutput)}");
113121
}
114122
int openingConsoleLine = FindLineEnding(closingLine + 1, "```console");
115123
// We expect the output to appear very shortly after the example.

tools/ExampleExtractor/ExampleMetadata.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ public class ExampleMetadata
4646
[JsonProperty("inferOutput")]
4747
public bool InferOutput { get; set; }
4848

49+
/// <summary>
50+
/// If this is set, ExpectedOutput must be null and InferOutput must be false.
51+
/// The actual output is then ignored by the test runner.
52+
/// This option should be used when output is nondeterministic.
53+
/// </summary>
54+
[JsonProperty("ignoreOutput")]
55+
public bool IgnoreOutput { get; set; }
56+
4957
[JsonProperty("expectedException")]
5058
public string ExpectedException { get; set; }
5159

tools/ExampleTester/GeneratedExample.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ bool ValidateOutput()
161161
}
162162
var expectedLines = Metadata.ExpectedOutput ?? new List<string>();
163163
return ValidateException(actualException, Metadata.ExpectedException) &&
164-
ValidateExpectedAgainstActual("output", expectedLines, actualLines);
164+
(Metadata.IgnoreOutput || ValidateExpectedAgainstActual("output", expectedLines, actualLines));
165165
}
166166

167167
bool ValidateException(Exception? actualException, string? expectedExceptionName)

0 commit comments

Comments
 (0)