From 1595b5c3a7673e262cfbfeed874b23c1384233a3 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Sun, 21 Jun 2026 11:43:21 -0400 Subject: [PATCH 1/3] Add self-validation for all file types. --- .reviewmark.yaml | 2 +- .../design/file-assert/selftest/validation.md | 26 +++++- .../file-assert/selftest/validation.yaml | 64 ++++++++++++-- .../file-assert/selftest/validation.md | 44 +++++++++- .../SelfTest/Validation.cs | 87 +++---------------- .../SelfTest/ValidationFile.cs | 71 +++++++++++++++ .../SelfTest/ValidationHtml.cs | 76 ++++++++++++++++ .../SelfTest/ValidationJson.cs | 74 ++++++++++++++++ .../SelfTest/ValidationPdf.cs | 87 +++++++++++++++++++ .../SelfTest/ValidationText.cs | 72 +++++++++++++++ .../SelfTest/ValidationXml.cs | 76 ++++++++++++++++ .../SelfTest/ValidationYaml.cs | 75 ++++++++++++++++ .../SelfTest/ValidationZip.cs | 83 ++++++++++++++++++ .../SelfTest/ValidationTests.cs | 82 +++++++++++++++-- 14 files changed, 820 insertions(+), 99 deletions(-) create mode 100644 src/DemaConsulting.FileAssert/SelfTest/ValidationFile.cs create mode 100644 src/DemaConsulting.FileAssert/SelfTest/ValidationHtml.cs create mode 100644 src/DemaConsulting.FileAssert/SelfTest/ValidationJson.cs create mode 100644 src/DemaConsulting.FileAssert/SelfTest/ValidationPdf.cs create mode 100644 src/DemaConsulting.FileAssert/SelfTest/ValidationText.cs create mode 100644 src/DemaConsulting.FileAssert/SelfTest/ValidationXml.cs create mode 100644 src/DemaConsulting.FileAssert/SelfTest/ValidationYaml.cs create mode 100644 src/DemaConsulting.FileAssert/SelfTest/ValidationZip.cs diff --git a/.reviewmark.yaml b/.reviewmark.yaml index 7676bea..9c49805 100644 --- a/.reviewmark.yaml +++ b/.reviewmark.yaml @@ -143,7 +143,7 @@ reviews: - "docs/reqstream/file-assert/selftest/validation.yaml" # requirements - "docs/design/file-assert/selftest/validation.md" # design - "docs/verification/file-assert/selftest/validation.md" # verification - - "src/**/SelfTest/Validation.cs" # implementation + - "src/**/SelfTest/Validation*.cs" # implementation - "test/**/SelfTest/ValidationTests.cs" # unit tests # FileAssert-Utilities-PathHelpers Review (one per unit) diff --git a/docs/design/file-assert/selftest/validation.md b/docs/design/file-assert/selftest/validation.md index 26dc769..88eac16 100644 --- a/docs/design/file-assert/selftest/validation.md +++ b/docs/design/file-assert/selftest/validation.md @@ -9,6 +9,12 @@ file. #### Class Structure +`Validation` is implemented as a `partial class` spread across 9 source files: +`Validation.cs`, `ValidationFile.cs`, `ValidationText.cs`, `ValidationHtml.cs`, +`ValidationXml.cs`, `ValidationYaml.cs`, `ValidationJson.cs`, `ValidationPdf.cs`, +and `ValidationZip.cs`. The orchestrating `Run()` method and shared utilities remain +in `Validation.cs`; each per-type test method lives in its own file. + ##### Run Method ```csharp @@ -31,8 +37,14 @@ Entry point for self-validation. Executes the following steps: | `FileAssert_VersionDisplay` | | `FileAssert_HelpDisplay` | | `FileAssert_Results` | -| `FileAssert_Exists` | -| `FileAssert_Contains` | +| `FileAssert_File` | +| `FileAssert_Text` | +| `FileAssert_Html` | +| `FileAssert_Xml` | +| `FileAssert_Yaml` | +| `FileAssert_Json` | +| `FileAssert_Pdf` | +| `FileAssert_Zip` | Each test is dispatched via `RunValidationTest`, which handles the common boilerplate: @@ -108,8 +120,14 @@ N/A — `Validation` is a `static` class with no instance fields. All state is l | `RunVersionTest(Context, TestResults)` *(private)* | | `RunHelpTest(Context, TestResults)` *(private)* | | `RunResultsTest(Context, TestResults)` *(private)* | -| `RunExistsTest(Context, TestResults)` *(private)* | -| `RunContainsTest(Context, TestResults)` *(private)* | +| `RunFileTest(Context, TestResults)` *(private)* | +| `RunTextTest(Context, TestResults)` *(private)* | +| `RunHtmlTest(Context, TestResults)` *(private)* | +| `RunXmlTest(Context, TestResults)` *(private)* | +| `RunYamlTest(Context, TestResults)` *(private)* | +| `RunJsonTest(Context, TestResults)` *(private)* | +| `RunPdfTest(Context, TestResults)` *(private)* | +| `RunZipTest(Context, TestResults)` *(private)* | | `RunValidationTest(Context, TestResults, string, Func)` *(private)* | | `WriteResultsFile(Context, TestResults)` *(private)* | | `CreateTestResult(string)` *(private)* | diff --git a/docs/reqstream/file-assert/selftest/validation.yaml b/docs/reqstream/file-assert/selftest/validation.yaml index 60ac866..8c33b61 100644 --- a/docs/reqstream/file-assert/selftest/validation.yaml +++ b/docs/reqstream/file-assert/selftest/validation.yaml @@ -36,23 +36,77 @@ sections: tests: - Validation_Run_WithSilentContext_LogContainsFileAssertResults - - id: FileAssert-Validation-ExistsTest + - id: FileAssert-Validation-FileTest title: The Validation class shall include a self-test that verifies file-existence checking. justification: | Demonstrates that glob-pattern file-existence assertions work correctly in the deployment environment, providing evidence that the core file-matching feature is functioning as expected. tests: - - Validation_Run_WithSilentContext_LogContainsFileAssertExists + - Validation_Run_WithSilentContext_LogContainsFileAssertFile - - id: FileAssert-Validation-ContainsTest - title: The Validation class shall include a self-test that verifies file-content checking. + - id: FileAssert-Validation-TextTest + title: The Validation class shall include a self-test that verifies text-content checking. justification: | Demonstrates that text-contains assertions work correctly in the deployment environment, providing evidence that the file content inspection feature is functioning as expected. tests: - - Validation_Run_WithSilentContext_LogContainsFileAssertContains + - Validation_Run_WithSilentContext_LogContainsFileAssertText + + - id: FileAssert-Validation-HtmlTest + title: The Validation class shall include a self-test that verifies HTML assertion checking. + justification: | + Demonstrates that HTML XPath assertions work correctly in the deployment + environment, providing evidence that the HTML content inspection feature + is functioning as expected. + tests: + - Validation_Run_WithSilentContext_LogContainsFileAssertHtml + + - id: FileAssert-Validation-XmlTest + title: The Validation class shall include a self-test that verifies XML assertion checking. + justification: | + Demonstrates that XML XPath assertions work correctly in the deployment + environment, providing evidence that the XML content inspection feature + is functioning as expected. + tests: + - Validation_Run_WithSilentContext_LogContainsFileAssertXml + + - id: FileAssert-Validation-YamlTest + title: The Validation class shall include a self-test that verifies YAML assertion checking. + justification: | + Demonstrates that YAML dot-path assertions work correctly in the deployment + environment, providing evidence that the YAML content inspection feature + is functioning as expected. + tests: + - Validation_Run_WithSilentContext_LogContainsFileAssertYaml + + - id: FileAssert-Validation-JsonTest + title: The Validation class shall include a self-test that verifies JSON assertion checking. + justification: | + Demonstrates that JSON dot-path assertions work correctly in the deployment + environment, providing evidence that the JSON content inspection feature + is functioning as expected. + tests: + - Validation_Run_WithSilentContext_LogContainsFileAssertJson + + - id: FileAssert-Validation-PdfTest + title: The Validation class shall include a self-test that verifies PDF assertion checking. + justification: | + Demonstrates that PDF metadata and text assertions work correctly in the + deployment environment, providing evidence that the PDF content inspection + feature is functioning as expected. + tests: + - Validation_Run_WithSilentContext_LogContainsFileAssertPdf + + - id: FileAssert-Validation-ZipTest + title: The Validation class shall include a self-test that verifies ZIP assertion checking. + justification: | + Demonstrates that ZIP nested file assertions work correctly in the + deployment environment, providing evidence that the ZIP archive inspection + feature is functioning as expected. + tests: + - Validation_Run_WithSilentContext_LogContainsFileAssertZip - id: FileAssert-Validation-NullContext title: The Validation class shall reject a null context argument. diff --git a/docs/verification/file-assert/selftest/validation.md b/docs/verification/file-assert/selftest/validation.md index 8ea7ca3..23d2b89 100644 --- a/docs/verification/file-assert/selftest/validation.md +++ b/docs/verification/file-assert/selftest/validation.md @@ -86,17 +86,53 @@ is written to `context` indicating the unsupported format. **Expected**: The log contains FileAssert results output. -##### Validation_Run_WithSilentContext_LogContainsFileAssertExists +##### Validation_Run_WithSilentContext_LogContainsFileAssertFile **Scenario**: `Validation.Run` is called with a context that has logging enabled. -**Expected**: The log contains output from the FileAssert "exists" self-validation test. +**Expected**: The log contains output from the `FileAssert_File` self-validation test. -##### Validation_Run_WithSilentContext_LogContainsFileAssertContains +##### Validation_Run_WithSilentContext_LogContainsFileAssertText **Scenario**: `Validation.Run` is called with a context that has logging enabled. -**Expected**: The log contains output from the FileAssert "contains" self-validation test. +**Expected**: The log contains output from the `FileAssert_Text` self-validation test. + +##### Validation_Run_WithSilentContext_LogContainsFileAssertHtml + +**Scenario**: `Validation.Run` is called with a context that has logging enabled. + +**Expected**: The log contains output from the `FileAssert_Html` self-validation test. + +##### Validation_Run_WithSilentContext_LogContainsFileAssertXml + +**Scenario**: `Validation.Run` is called with a context that has logging enabled. + +**Expected**: The log contains output from the `FileAssert_Xml` self-validation test. + +##### Validation_Run_WithSilentContext_LogContainsFileAssertYaml + +**Scenario**: `Validation.Run` is called with a context that has logging enabled. + +**Expected**: The log contains output from the `FileAssert_Yaml` self-validation test. + +##### Validation_Run_WithSilentContext_LogContainsFileAssertJson + +**Scenario**: `Validation.Run` is called with a context that has logging enabled. + +**Expected**: The log contains output from the `FileAssert_Json` self-validation test. + +##### Validation_Run_WithSilentContext_LogContainsFileAssertPdf + +**Scenario**: `Validation.Run` is called with a context that has logging enabled. + +**Expected**: The log contains output from the `FileAssert_Pdf` self-validation test. + +##### Validation_Run_WithSilentContext_LogContainsFileAssertZip + +**Scenario**: `Validation.Run` is called with a context that has logging enabled. + +**Expected**: The log contains output from the `FileAssert_Zip` self-validation test. ##### Validation_Run_WithDepth_UsesSpecifiedHeadingDepth diff --git a/src/DemaConsulting.FileAssert/SelfTest/Validation.cs b/src/DemaConsulting.FileAssert/SelfTest/Validation.cs index 94851e3..29f8689 100644 --- a/src/DemaConsulting.FileAssert/SelfTest/Validation.cs +++ b/src/DemaConsulting.FileAssert/SelfTest/Validation.cs @@ -53,8 +53,16 @@ public static void Run(Context context) RunVersionTest(context, testResults); RunHelpTest(context, testResults); RunResultsTest(context, testResults); - RunExistsTest(context, testResults); - RunContainsTest(context, testResults); + + // Run per-assertion-type tests + RunFileTest(context, testResults); + RunTextTest(context, testResults); + RunHtmlTest(context, testResults); + RunXmlTest(context, testResults); + RunYamlTest(context, testResults); + RunJsonTest(context, testResults); + RunPdfTest(context, testResults); + RunZipTest(context, testResults); // Calculate totals var totalTests = testResults.Results.Count; @@ -213,81 +221,6 @@ private static void RunResultsTest(Context context, DemaConsulting.TestResults.T }); } - /// - /// Runs a test for file-existence checking via glob pattern. - /// - /// The context for output. - /// The test results collection. - private static void RunExistsTest(Context context, DemaConsulting.TestResults.TestResults testResults) - { - RunValidationTest(context, testResults, "FileAssert_Exists", () => - { - using var tempDir = new TemporaryDirectory(); - var configFile = tempDir.GetFilePath(".fileassert.yaml"); - - // Create a text file that the glob pattern should match - File.WriteAllText(tempDir.GetFilePath("hello.txt"), "Hello World"); - - // Write a config that verifies exactly one .txt file exists in the directory - File.WriteAllText(configFile, - """ - tests: - - name: FileAssert_Exists_Test - files: - - pattern: "*.txt" - count: 1 - """); - - // Run the program - int exitCode; - using (var testContext = Context.Create(["--silent", "--config", configFile])) - { - Program.Run(testContext); - exitCode = testContext.ExitCode; - } - - return exitCode == 0 ? null : $"Program exited with code {exitCode}"; - }); - } - - /// - /// Runs a test for file-contains checking. - /// - /// The context for output. - /// The test results collection. - private static void RunContainsTest(Context context, DemaConsulting.TestResults.TestResults testResults) - { - RunValidationTest(context, testResults, "FileAssert_Contains", () => - { - using var tempDir = new TemporaryDirectory(); - var configFile = tempDir.GetFilePath(".fileassert.yaml"); - - // Create a text file with known content for the contains assertion - File.WriteAllText(tempDir.GetFilePath("hello.txt"), "Hello World"); - - // Write a config that verifies the file contains the expected text - File.WriteAllText(configFile, - """ - tests: - - name: FileAssert_Contains_Test - files: - - pattern: "*.txt" - text: - - contains: "Hello World" - """); - - // Run the program - int exitCode; - using (var testContext = Context.Create(["--silent", "--config", configFile])) - { - Program.Run(testContext); - exitCode = testContext.ExitCode; - } - - return exitCode == 0 ? null : $"Program exited with code {exitCode}"; - }); - } - /// /// Runs a single validation test, recording the outcome in the test results collection. /// diff --git a/src/DemaConsulting.FileAssert/SelfTest/ValidationFile.cs b/src/DemaConsulting.FileAssert/SelfTest/ValidationFile.cs new file mode 100644 index 0000000..9763a7f --- /dev/null +++ b/src/DemaConsulting.FileAssert/SelfTest/ValidationFile.cs @@ -0,0 +1,71 @@ +// Copyright (c) DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using DemaConsulting.FileAssert.Cli; +using DemaConsulting.FileAssert.Utilities; + +namespace DemaConsulting.FileAssert.SelfTest; + +/// +/// Provides the file-existence self-validation test for FileAssert. +/// +internal static partial class Validation +{ + /// + /// Runs a test for file-existence checking via glob pattern. + /// + /// + /// Verifies that the FileAssert_File assertion correctly detects exactly one + /// matching file in a temporary directory, confirming glob-based file counting works end-to-end. + /// + /// The context for output. + /// The test results collection. + private static void RunFileTest(Context context, DemaConsulting.TestResults.TestResults testResults) + { + RunValidationTest(context, testResults, "FileAssert_File", () => + { + using var tempDir = new TemporaryDirectory(); + var configFile = tempDir.GetFilePath(".fileassert.yaml"); + + // Create a text file that the glob pattern should match + File.WriteAllText(tempDir.GetFilePath("hello.txt"), "Hello World"); + + // Write a config that verifies exactly one .txt file exists in the directory + File.WriteAllText(configFile, + """ + tests: + - name: FileAssert_File + files: + - pattern: "*.txt" + count: 1 + """); + + // Run the program + int exitCode; + using (var testContext = Context.Create(["--silent", "--config", configFile])) + { + Program.Run(testContext); + exitCode = testContext.ExitCode; + } + + return exitCode == 0 ? null : $"Program exited with code {exitCode}"; + }); + } +} diff --git a/src/DemaConsulting.FileAssert/SelfTest/ValidationHtml.cs b/src/DemaConsulting.FileAssert/SelfTest/ValidationHtml.cs new file mode 100644 index 0000000..f2e65db --- /dev/null +++ b/src/DemaConsulting.FileAssert/SelfTest/ValidationHtml.cs @@ -0,0 +1,76 @@ +// Copyright (c) DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using DemaConsulting.FileAssert.Cli; +using DemaConsulting.FileAssert.Utilities; + +namespace DemaConsulting.FileAssert.SelfTest; + +/// +/// Provides the HTML self-validation test for FileAssert. +/// +internal static partial class Validation +{ + /// + /// Runs a test for HTML XPath-query assertions against an HTML file. + /// + /// + /// Verifies that the FileAssert_Html assertion correctly queries an HTML element + /// using an XPath expression, confirming HTML structural assertions work end-to-end. + /// + /// The context for output. + /// The test results collection. + private static void RunHtmlTest(Context context, DemaConsulting.TestResults.TestResults testResults) + { + RunValidationTest(context, testResults, "FileAssert_Html", () => + { + using var tempDir = new TemporaryDirectory(); + var configFile = tempDir.GetFilePath(".fileassert.yaml"); + + // Create a minimal HTML file with a known element to query + File.WriteAllText( + tempDir.GetFilePath("test.html"), + "Test

Hello HTML

"); + + // Write a config that verifies the HTML file contains exactly one element + File.WriteAllText(configFile, + """ + tests: + - name: FileAssert_Html + files: + - pattern: "*.html" + count: 1 + html: + - query: "//title" + count: 1 + """); + + // Run the program + int exitCode; + using (var testContext = Context.Create(["--silent", "--config", configFile])) + { + Program.Run(testContext); + exitCode = testContext.ExitCode; + } + + return exitCode == 0 ? null : $"Program exited with code {exitCode}"; + }); + } +} diff --git a/src/DemaConsulting.FileAssert/SelfTest/ValidationJson.cs b/src/DemaConsulting.FileAssert/SelfTest/ValidationJson.cs new file mode 100644 index 0000000..9607a69 --- /dev/null +++ b/src/DemaConsulting.FileAssert/SelfTest/ValidationJson.cs @@ -0,0 +1,74 @@ +// Copyright (c) DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using DemaConsulting.FileAssert.Cli; +using DemaConsulting.FileAssert.Utilities; + +namespace DemaConsulting.FileAssert.SelfTest; + +/// <summary> +/// Provides the JSON self-validation test for FileAssert. +/// </summary> +internal static partial class Validation +{ + /// <summary> + /// Runs a test for JSON key-path query assertions against a JSON file. + /// </summary> + /// <remarks> + /// Verifies that the FileAssert_Json assertion correctly queries a JSON property + /// using a key-path expression, confirming JSON structural assertions work end-to-end. + /// </remarks> + /// <param name="context">The context for output.</param> + /// <param name="testResults">The test results collection.</param> + private static void RunJsonTest(Context context, DemaConsulting.TestResults.TestResults testResults) + { + RunValidationTest(context, testResults, "FileAssert_Json", () => + { + using var tempDir = new TemporaryDirectory(); + var configFile = tempDir.GetFilePath(".fileassert.yaml"); + + // Create a minimal JSON file with a known property to query + File.WriteAllText(tempDir.GetFilePath("test.json"), """{"greeting": "Hello JSON"}"""); + + // Write a config that verifies the JSON file contains exactly one 'greeting' property + File.WriteAllText(configFile, + """ + tests: + - name: FileAssert_Json + files: + - pattern: "*.json" + count: 1 + json: + - query: "greeting" + count: 1 + """); + + // Run the program + int exitCode; + using (var testContext = Context.Create(["--silent", "--config", configFile])) + { + Program.Run(testContext); + exitCode = testContext.ExitCode; + } + + return exitCode == 0 ? null : $"Program exited with code {exitCode}"; + }); + } +} diff --git a/src/DemaConsulting.FileAssert/SelfTest/ValidationPdf.cs b/src/DemaConsulting.FileAssert/SelfTest/ValidationPdf.cs new file mode 100644 index 0000000..845bdfe --- /dev/null +++ b/src/DemaConsulting.FileAssert/SelfTest/ValidationPdf.cs @@ -0,0 +1,87 @@ +// Copyright (c) DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using DemaConsulting.FileAssert.Cli; +using DemaConsulting.FileAssert.Utilities; +using UglyToad.PdfPig.Content; +using UglyToad.PdfPig.Core; +using UglyToad.PdfPig.Fonts.Standard14Fonts; +using UglyToad.PdfPig.Writer; + +namespace DemaConsulting.FileAssert.SelfTest; + +/// <summary> +/// Provides the PDF self-validation test for FileAssert. +/// </summary> +internal static partial class Validation +{ + /// <summary> + /// Runs a test for PDF metadata and text assertions against a programmatically created PDF file. + /// </summary> + /// <remarks> + /// Verifies that the FileAssert_Pdf assertion correctly reads document metadata and + /// extracted page text from a PDF file, confirming PDF assertions work end-to-end. + /// </remarks> + /// <param name="context">The context for output.</param> + /// <param name="testResults">The test results collection.</param> + private static void RunPdfTest(Context context, DemaConsulting.TestResults.TestResults testResults) + { + RunValidationTest(context, testResults, "FileAssert_Pdf", () => + { + using var tempDir = new TemporaryDirectory(); + var configFile = tempDir.GetFilePath(".fileassert.yaml"); + + // Build a minimal PDF in memory using PdfPig's writer API + var builder = new PdfDocumentBuilder(); + builder.DocumentInformation.Title = "Test PDF"; + var font = builder.AddStandard14Font(Standard14Font.Helvetica); + var page = builder.AddPage(PageSize.A4); + page.AddText("Hello PDF", 12, new PdfPoint(25, 700), font); + var pdfBytes = builder.Build(); + File.WriteAllBytes(tempDir.GetFilePath("test.pdf"), pdfBytes); + + // Write a config that verifies the PDF metadata title and body text + File.WriteAllText(configFile, + """ + tests: + - name: FileAssert_Pdf + files: + - pattern: "*.pdf" + count: 1 + pdf: + metadata: + - field: "Title" + contains: "Test PDF" + text: + - contains: "Hello PDF" + """); + + // Run the program + int exitCode; + using (var testContext = Context.Create(["--silent", "--config", configFile])) + { + Program.Run(testContext); + exitCode = testContext.ExitCode; + } + + return exitCode == 0 ? null : $"Program exited with code {exitCode}"; + }); + } +} diff --git a/src/DemaConsulting.FileAssert/SelfTest/ValidationText.cs b/src/DemaConsulting.FileAssert/SelfTest/ValidationText.cs new file mode 100644 index 0000000..30aeb55 --- /dev/null +++ b/src/DemaConsulting.FileAssert/SelfTest/ValidationText.cs @@ -0,0 +1,72 @@ +// Copyright (c) DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using DemaConsulting.FileAssert.Cli; +using DemaConsulting.FileAssert.Utilities; + +namespace DemaConsulting.FileAssert.SelfTest; + +/// <summary> +/// Provides the plain-text self-validation test for FileAssert. +/// </summary> +internal static partial class Validation +{ + /// <summary> + /// Runs a test for file-contains checking against plain-text files. + /// </summary> + /// <remarks> + /// Verifies that the FileAssert_Text assertion correctly detects a known substring + /// inside a matching file, confirming text-content assertions work end-to-end. + /// </remarks> + /// <param name="context">The context for output.</param> + /// <param name="testResults">The test results collection.</param> + private static void RunTextTest(Context context, DemaConsulting.TestResults.TestResults testResults) + { + RunValidationTest(context, testResults, "FileAssert_Text", () => + { + using var tempDir = new TemporaryDirectory(); + var configFile = tempDir.GetFilePath(".fileassert.yaml"); + + // Create a text file with known content for the contains assertion + File.WriteAllText(tempDir.GetFilePath("hello.txt"), "Hello World"); + + // Write a config that verifies the file contains the expected text + File.WriteAllText(configFile, + """ + tests: + - name: FileAssert_Text + files: + - pattern: "*.txt" + text: + - contains: "Hello World" + """); + + // Run the program + int exitCode; + using (var testContext = Context.Create(["--silent", "--config", configFile])) + { + Program.Run(testContext); + exitCode = testContext.ExitCode; + } + + return exitCode == 0 ? null : $"Program exited with code {exitCode}"; + }); + } +} diff --git a/src/DemaConsulting.FileAssert/SelfTest/ValidationXml.cs b/src/DemaConsulting.FileAssert/SelfTest/ValidationXml.cs new file mode 100644 index 0000000..7be67e8 --- /dev/null +++ b/src/DemaConsulting.FileAssert/SelfTest/ValidationXml.cs @@ -0,0 +1,76 @@ +// Copyright (c) DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using DemaConsulting.FileAssert.Cli; +using DemaConsulting.FileAssert.Utilities; + +namespace DemaConsulting.FileAssert.SelfTest; + +/// <summary> +/// Provides the XML self-validation test for FileAssert. +/// </summary> +internal static partial class Validation +{ + /// <summary> + /// Runs a test for XML XPath-query assertions against an XML file. + /// </summary> + /// <remarks> + /// Verifies that the FileAssert_Xml assertion correctly queries an XML element + /// using an XPath expression, confirming XML structural assertions work end-to-end. + /// </remarks> + /// <param name="context">The context for output.</param> + /// <param name="testResults">The test results collection.</param> + private static void RunXmlTest(Context context, DemaConsulting.TestResults.TestResults testResults) + { + RunValidationTest(context, testResults, "FileAssert_Xml", () => + { + using var tempDir = new TemporaryDirectory(); + var configFile = tempDir.GetFilePath(".fileassert.yaml"); + + // Create a minimal XML file with a known element to query + File.WriteAllText( + tempDir.GetFilePath("test.xml"), + """<?xml version="1.0"?><root><item>Hello XML</item></root>"""); + + // Write a config that verifies the XML file contains exactly one <item> element + File.WriteAllText(configFile, + """ + tests: + - name: FileAssert_Xml + files: + - pattern: "*.xml" + count: 1 + xml: + - query: "//item" + count: 1 + """); + + // Run the program + int exitCode; + using (var testContext = Context.Create(["--silent", "--config", configFile])) + { + Program.Run(testContext); + exitCode = testContext.ExitCode; + } + + return exitCode == 0 ? null : $"Program exited with code {exitCode}"; + }); + } +} diff --git a/src/DemaConsulting.FileAssert/SelfTest/ValidationYaml.cs b/src/DemaConsulting.FileAssert/SelfTest/ValidationYaml.cs new file mode 100644 index 0000000..2d77285 --- /dev/null +++ b/src/DemaConsulting.FileAssert/SelfTest/ValidationYaml.cs @@ -0,0 +1,75 @@ +// Copyright (c) DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using DemaConsulting.FileAssert.Cli; +using DemaConsulting.FileAssert.Utilities; + +namespace DemaConsulting.FileAssert.SelfTest; + +/// <summary> +/// Provides the YAML self-validation test for FileAssert. +/// </summary> +internal static partial class Validation +{ + /// <summary> + /// Runs a test for YAML key-path query assertions against a YAML file. + /// </summary> + /// <remarks> + /// Verifies that the FileAssert_Yaml assertion correctly queries a YAML key + /// using a dot-path expression, confirming YAML structural assertions work end-to-end. + /// </remarks> + /// <param name="context">The context for output.</param> + /// <param name="testResults">The test results collection.</param> + private static void RunYamlTest(Context context, DemaConsulting.TestResults.TestResults testResults) + { + RunValidationTest(context, testResults, "FileAssert_Yaml", () => + { + using var tempDir = new TemporaryDirectory(); + var configFile = tempDir.GetFilePath(".fileassert.yaml"); + + // Create a minimal YAML file in a subdirectory to avoid the config file + // (.fileassert.yaml) being matched by the *.yaml glob pattern + File.WriteAllText(tempDir.GetFilePath("data/test.yaml"), "greeting: Hello YAML"); + + // Write a config that verifies the YAML file contains exactly one 'greeting' key + File.WriteAllText(configFile, + """ + tests: + - name: FileAssert_Yaml + files: + - pattern: "data/*.yaml" + count: 1 + yaml: + - query: "greeting" + count: 1 + """); + + // Run the program + int exitCode; + using (var testContext = Context.Create(["--silent", "--config", configFile])) + { + Program.Run(testContext); + exitCode = testContext.ExitCode; + } + + return exitCode == 0 ? null : $"Program exited with code {exitCode}"; + }); + } +} diff --git a/src/DemaConsulting.FileAssert/SelfTest/ValidationZip.cs b/src/DemaConsulting.FileAssert/SelfTest/ValidationZip.cs new file mode 100644 index 0000000..b1b261e --- /dev/null +++ b/src/DemaConsulting.FileAssert/SelfTest/ValidationZip.cs @@ -0,0 +1,83 @@ +// Copyright (c) DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using DemaConsulting.FileAssert.Cli; +using DemaConsulting.FileAssert.Utilities; + +namespace DemaConsulting.FileAssert.SelfTest; + +/// <summary> +/// Provides the ZIP self-validation test for FileAssert. +/// </summary> +internal static partial class Validation +{ + /// <summary> + /// Runs a test for ZIP entry assertions against a programmatically created ZIP archive. + /// </summary> + /// <remarks> + /// Verifies that the FileAssert_Zip assertion correctly locates a named entry inside a + /// ZIP archive and checks its text content, confirming ZIP assertions work end-to-end. + /// </remarks> + /// <param name="context">The context for output.</param> + /// <param name="testResults">The test results collection.</param> + private static void RunZipTest(Context context, DemaConsulting.TestResults.TestResults testResults) + { + RunValidationTest(context, testResults, "FileAssert_Zip", () => + { + using var tempDir = new TemporaryDirectory(); + var configFile = tempDir.GetFilePath(".fileassert.yaml"); + + // Create a ZIP archive containing a single text entry with known content + var zipPath = tempDir.GetFilePath("test.zip"); + using (var zip = System.IO.Compression.ZipFile.Open(zipPath, System.IO.Compression.ZipArchiveMode.Create)) + { + var entry = zip.CreateEntry("hello.txt"); + using var writer = new System.IO.StreamWriter(entry.Open()); + writer.Write("Hello Zip"); + } + + // Write a config that verifies the ZIP contains hello.txt with the expected content + File.WriteAllText(configFile, + """ + tests: + - name: FileAssert_Zip + files: + - pattern: "*.zip" + count: 1 + zip: + files: + - pattern: "hello.txt" + count: 1 + text: + - contains: "Hello Zip" + """); + + // Run the program + int exitCode; + using (var testContext = Context.Create(["--silent", "--config", configFile])) + { + Program.Run(testContext); + exitCode = testContext.ExitCode; + } + + return exitCode == 0 ? null : $"Program exited with code {exitCode}"; + }); + } +} diff --git a/test/DemaConsulting.FileAssert.Tests/SelfTest/ValidationTests.cs b/test/DemaConsulting.FileAssert.Tests/SelfTest/ValidationTests.cs index 2e7c741..17d5674 100644 --- a/test/DemaConsulting.FileAssert.Tests/SelfTest/ValidationTests.cs +++ b/test/DemaConsulting.FileAssert.Tests/SelfTest/ValidationTests.cs @@ -194,25 +194,91 @@ public void Validation_Run_WithSilentContext_LogContainsFileAssertResults() } /// <summary> - /// Test that Run logs a passing FileAssert_Exists result. + /// Test that Run logs a passing FileAssert_File result. /// </summary> [Fact] - public void Validation_Run_WithSilentContext_LogContainsFileAssertExists() + public void Validation_Run_WithSilentContext_LogContainsFileAssertFile() { // Act & Assert - // Proves that the FileAssert_Exists self-validation test is executed and passes. - AssertLogContains("✓ FileAssert_Exists - Passed"); + // Proves that the FileAssert_File self-validation test is executed and passes. + AssertLogContains("✓ FileAssert_File - Passed"); } /// <summary> - /// Test that Run logs a passing FileAssert_Contains result. + /// Test that Run logs a passing FileAssert_Text result. /// </summary> [Fact] - public void Validation_Run_WithSilentContext_LogContainsFileAssertContains() + public void Validation_Run_WithSilentContext_LogContainsFileAssertText() { // Act & Assert - // Proves that the FileAssert_Contains self-validation test is executed and passes. - AssertLogContains("✓ FileAssert_Contains - Passed"); + // Proves that the FileAssert_Text self-validation test is executed and passes. + AssertLogContains("✓ FileAssert_Text - Passed"); + } + + /// <summary> + /// Test that Run logs a passing FileAssert_Html result. + /// </summary> + [Fact] + public void Validation_Run_WithSilentContext_LogContainsFileAssertHtml() + { + // Act & Assert + // Proves that the FileAssert_Html self-validation test is executed and passes. + AssertLogContains("✓ FileAssert_Html - Passed"); + } + + /// <summary> + /// Test that Run logs a passing FileAssert_Xml result. + /// </summary> + [Fact] + public void Validation_Run_WithSilentContext_LogContainsFileAssertXml() + { + // Act & Assert + // Proves that the FileAssert_Xml self-validation test is executed and passes. + AssertLogContains("✓ FileAssert_Xml - Passed"); + } + + /// <summary> + /// Test that Run logs a passing FileAssert_Yaml result. + /// </summary> + [Fact] + public void Validation_Run_WithSilentContext_LogContainsFileAssertYaml() + { + // Act & Assert + // Proves that the FileAssert_Yaml self-validation test is executed and passes. + AssertLogContains("✓ FileAssert_Yaml - Passed"); + } + + /// <summary> + /// Test that Run logs a passing FileAssert_Json result. + /// </summary> + [Fact] + public void Validation_Run_WithSilentContext_LogContainsFileAssertJson() + { + // Act & Assert + // Proves that the FileAssert_Json self-validation test is executed and passes. + AssertLogContains("✓ FileAssert_Json - Passed"); + } + + /// <summary> + /// Test that Run logs a passing FileAssert_Pdf result. + /// </summary> + [Fact] + public void Validation_Run_WithSilentContext_LogContainsFileAssertPdf() + { + // Act & Assert + // Proves that the FileAssert_Pdf self-validation test is executed and passes. + AssertLogContains("✓ FileAssert_Pdf - Passed"); + } + + /// <summary> + /// Test that Run logs a passing FileAssert_Zip result. + /// </summary> + [Fact] + public void Validation_Run_WithSilentContext_LogContainsFileAssertZip() + { + // Act & Assert + // Proves that the FileAssert_Zip self-validation test is executed and passes. + AssertLogContains("✓ FileAssert_Zip - Passed"); } /// <summary> From 27b6f9c8e31d846eeb8abf2fa004808b561bef13 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Jun 2026 12:39:07 -0400 Subject: [PATCH 2/3] Update docs and traceability for expanded self-validation suite (#56) * Update self-validation documentation * Fix self-validation traceability --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- README.md | 26 ++++++++++++----- docs/reqstream/file-assert/selftest.yaml | 10 +++++-- docs/user_guide/introduction.md | 36 ++++++++++++++++-------- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1f5dabd..4745e51 100644 --- a/README.md +++ b/README.md @@ -279,11 +279,17 @@ Running self-validation produces a report demonstrating that FileAssert is funct ✓ FileAssert_VersionDisplay - Passed ✓ FileAssert_HelpDisplay - Passed ✓ FileAssert_Results - Passed -✓ FileAssert_Exists - Passed -✓ FileAssert_Contains - Passed - -Total Tests: 5 -Passed: 5 +✓ FileAssert_File - Passed +✓ FileAssert_Text - Passed +✓ FileAssert_Html - Passed +✓ FileAssert_Xml - Passed +✓ FileAssert_Yaml - Passed +✓ FileAssert_Json - Passed +✓ FileAssert_Pdf - Passed +✓ FileAssert_Zip - Passed + +Total Tests: 11 +Passed: 11 Failed: 0 ``` @@ -292,8 +298,14 @@ Each test in the report proves: - **`FileAssert_VersionDisplay`** - `--version` outputs a valid version string. - **`FileAssert_HelpDisplay`** - `--help` outputs usage and options information. - **`FileAssert_Results`** - `--results` generates test results with pass and fail outcomes. -- **`FileAssert_Exists`** - `--config` verifies file-existence via glob pattern. -- **`FileAssert_Contains`** - `--config` verifies file content with contains assertions. +- **`FileAssert_File`** - `--config` verifies file-existence via glob pattern. +- **`FileAssert_Text`** - `--config` verifies file content with contains assertions. +- **`FileAssert_Html`** - `--config` verifies HTML XPath assertions. +- **`FileAssert_Xml`** - `--config` verifies XML XPath assertions. +- **`FileAssert_Yaml`** - `--config` verifies YAML key-path assertions. +- **`FileAssert_Json`** - `--config` verifies JSON key-path assertions. +- **`FileAssert_Pdf`** - `--config` verifies PDF metadata and text assertions. +- **`FileAssert_Zip`** - `--config` verifies zip archive entry assertions. See the [User Guide][link-guide] for more details on the self-validation tests. diff --git a/docs/reqstream/file-assert/selftest.yaml b/docs/reqstream/file-assert/selftest.yaml index 5e80c05..df5b67e 100644 --- a/docs/reqstream/file-assert/selftest.yaml +++ b/docs/reqstream/file-assert/selftest.yaml @@ -19,8 +19,14 @@ sections: - FileAssert-Validation-Run - FileAssert-Validation-Results - FileAssert-Validation-ResultsTest - - FileAssert-Validation-ExistsTest - - FileAssert-Validation-ContainsTest + - FileAssert-Validation-FileTest + - FileAssert-Validation-TextTest + - FileAssert-Validation-HtmlTest + - FileAssert-Validation-XmlTest + - FileAssert-Validation-YamlTest + - FileAssert-Validation-JsonTest + - FileAssert-Validation-PdfTest + - FileAssert-Validation-ZipTest - FileAssert-Validation-NullContext - FileAssert-Validation-Depth tests: diff --git a/docs/user_guide/introduction.md b/docs/user_guide/introduction.md index bd2b757..edbc519 100644 --- a/docs/user_guide/introduction.md +++ b/docs/user_guide/introduction.md @@ -130,20 +130,26 @@ Example validation report: | Information | Value | | :------------------ | :------------------------------------------------- | -| Tool Version | 1.0.0 | -| Machine Name | BUILD-SERVER | -| OS Version | Ubuntu 22.04.3 LTS | -| DotNet Runtime | .NET 10.0.0 | -| Time Stamp | 2024-01-15 10:30:00 UTC | +| Tool Version | <version> | +| Machine Name | <machine-name> | +| OS Version | <os-version> | +| DotNet Runtime | <dotnet-runtime-version> | +| Time Stamp | 2026-06-21 15:48:28 UTC | ✓ FileAssert_VersionDisplay - Passed ✓ FileAssert_HelpDisplay - Passed ✓ FileAssert_Results - Passed -✓ FileAssert_Exists - Passed -✓ FileAssert_Contains - Passed - -Total Tests: 5 -Passed: 5 +✓ FileAssert_File - Passed +✓ FileAssert_Text - Passed +✓ FileAssert_Html - Passed +✓ FileAssert_Xml - Passed +✓ FileAssert_Yaml - Passed +✓ FileAssert_Json - Passed +✓ FileAssert_Pdf - Passed +✓ FileAssert_Zip - Passed + +Total Tests: 11 +Passed: 11 Failed: 0 ``` @@ -154,8 +160,14 @@ Each test proves specific functionality works correctly: - **`FileAssert_VersionDisplay`** - `--version` outputs a valid version string. - **`FileAssert_HelpDisplay`** - `--help` outputs usage and options information. - **`FileAssert_Results`** - `--results` generates test results with pass and fail outcomes. -- **`FileAssert_Exists`** - `--config` verifies file-existence via glob pattern. -- **`FileAssert_Contains`** - `--config` verifies file content with contains assertions. +- **`FileAssert_File`** - `--config` verifies file-existence via glob pattern. +- **`FileAssert_Text`** - `--config` verifies file content with contains assertions. +- **`FileAssert_Html`** - `--config` verifies HTML XPath assertions. +- **`FileAssert_Xml`** - `--config` verifies XML XPath assertions. +- **`FileAssert_Yaml`** - `--config` verifies YAML key-path assertions. +- **`FileAssert_Json`** - `--config` verifies JSON key-path assertions. +- **`FileAssert_Pdf`** - `--config` verifies PDF metadata and text assertions. +- **`FileAssert_Zip`** - `--config` verifies zip archive entry assertions. ## Silent Mode From 043749d4fa5c7aa8ace693e281c6d8bdd847e213 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon <Malcolm.nixon@gmail.com> Date: Sun, 21 Jun 2026 12:44:26 -0400 Subject: [PATCH 3/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/user_guide/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user_guide/introduction.md b/docs/user_guide/introduction.md index edbc519..52a5763 100644 --- a/docs/user_guide/introduction.md +++ b/docs/user_guide/introduction.md @@ -134,7 +134,7 @@ Example validation report: | Machine Name | <machine-name> | | OS Version | <os-version> | | DotNet Runtime | <dotnet-runtime-version> | -| Time Stamp | 2026-06-21 15:48:28 UTC | +| Time Stamp | <timestamp> | ✓ FileAssert_VersionDisplay - Passed ✓ FileAssert_HelpDisplay - Passed