fix(converters): fix HtmlProvider WebView2 thread crash and add MarkdownProvider for pure .NET conversions
This commit is contained in:
parent
63d50c165d
commit
4e5285e27c
7 changed files with 447 additions and 28 deletions
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Everything2Everything.Core;
|
||||
using Everything2Everything.Core.Converters;
|
||||
using Everything2Everything.Core.Providers;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Everything2Everything.Tests;
|
||||
|
||||
public class HtmlEndToEndAllOutputsTests
|
||||
{
|
||||
private readonly ITestOutputHelper _output;
|
||||
|
||||
public HtmlEndToEndAllOutputsTests(ITestOutputHelper output)
|
||||
{
|
||||
_output = output;
|
||||
}
|
||||
|
||||
private static string TempDir()
|
||||
{
|
||||
var d = Path.Combine(Path.GetTempPath(), "e2e_html_all_" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(".pdf")]
|
||||
[InlineData(".png")]
|
||||
[InlineData(".jpg")]
|
||||
[InlineData(".webp")]
|
||||
[InlineData(".avif")]
|
||||
[InlineData(".bmp")]
|
||||
[InlineData(".tiff")]
|
||||
[InlineData(".gif")]
|
||||
public async Task Html_To_ImagesAndPdf_Via_Engine_Succeeds(string targetExt)
|
||||
{
|
||||
var dir = TempDir();
|
||||
var html = Path.Combine(dir, "sample.html");
|
||||
await File.WriteAllTextAsync(html, "<html><body><h1 style='color:red;'>Test Page</h1><p>Paragraph content</p></body></html>");
|
||||
|
||||
var engine = Everything2EverythingBootstrap.CreateDefault();
|
||||
var opt = new ConvertOptions
|
||||
{
|
||||
OutputLocation = OutputLocation.Custom,
|
||||
CustomOutputDirectory = dir
|
||||
};
|
||||
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var result = await engine.ConvertOneAsync(html, targetExt, opt, null, cts.Token);
|
||||
|
||||
_output.WriteLine($"Convert .html -> {targetExt}: Status={result.Status}, Msg={result.Message}");
|
||||
Assert.Equal(ConvertStatus.Success, result.Status);
|
||||
Assert.NotEmpty(result.OutputPaths);
|
||||
Assert.True(File.Exists(result.OutputPaths[0]));
|
||||
Assert.True(new FileInfo(result.OutputPaths[0]).Length > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Html_To_Markdown_Via_Engine_TestsAvailability()
|
||||
{
|
||||
var dir = TempDir();
|
||||
var html = Path.Combine(dir, "sample.html");
|
||||
await File.WriteAllTextAsync(html, "<html><body><h1>Markdown Title</h1><p>Bold <b>text</b></p></body></html>");
|
||||
|
||||
var engine = Everything2EverythingBootstrap.CreateDefault();
|
||||
var opt = new ConvertOptions
|
||||
{
|
||||
OutputLocation = OutputLocation.Custom,
|
||||
CustomOutputDirectory = dir
|
||||
};
|
||||
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15));
|
||||
var result = await engine.ConvertOneAsync(html, ".md", opt, null, cts.Token);
|
||||
|
||||
_output.WriteLine($"Convert .html -> .md: Status={result.Status}, Msg={result.Message}");
|
||||
}
|
||||
}
|
||||
60
src/Everything2Everything.Tests/HtmlProviderTests.cs
Normal file
60
src/Everything2Everything.Tests/HtmlProviderTests.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Everything2Everything.Core;
|
||||
using Everything2Everything.Core.Converters;
|
||||
using Everything2Everything.Core.Providers;
|
||||
using Xunit;
|
||||
|
||||
namespace Everything2Everything.Tests;
|
||||
|
||||
public class HtmlProviderTests
|
||||
{
|
||||
private static string TempDir()
|
||||
{
|
||||
var d = Path.Combine(Path.GetTempPath(), "e2e_html_test_" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HtmlProvider_ConvertAsync_HtmlToPdf_Succeeds()
|
||||
{
|
||||
var dir = TempDir();
|
||||
var html = Path.Combine(dir, "test.html");
|
||||
await File.WriteAllTextAsync(html, "<html><body><h1>Hello HTML Test</h1><p>Testing HTML to PDF</p></body></html>");
|
||||
|
||||
var provider = new HtmlProvider();
|
||||
var availability = await provider.CheckAvailabilityAsync();
|
||||
if (!availability.IsReady) return;
|
||||
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var result = await provider.ConvertAsync(html, dir, ".pdf", new ConvertOptions(), null, cts.Token);
|
||||
|
||||
Assert.Equal(ConvertStatus.Success, result.Status);
|
||||
Assert.NotEmpty(result.OutputPaths);
|
||||
Assert.True(File.Exists(result.OutputPaths[0]));
|
||||
Assert.True(new FileInfo(result.OutputPaths[0]).Length > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HtmlProvider_ConvertAsync_HtmlToPng_Succeeds()
|
||||
{
|
||||
var dir = TempDir();
|
||||
var html = Path.Combine(dir, "test.html");
|
||||
await File.WriteAllTextAsync(html, "<html><body><h1>Hello HTML Test</h1><p>Testing HTML to PNG</p></body></html>");
|
||||
|
||||
var provider = new HtmlProvider();
|
||||
var availability = await provider.CheckAvailabilityAsync();
|
||||
if (!availability.IsReady) return;
|
||||
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var result = await provider.ConvertAsync(html, dir, ".png", new ConvertOptions(), null, cts.Token);
|
||||
|
||||
Assert.Equal(ConvertStatus.Success, result.Status);
|
||||
Assert.NotEmpty(result.OutputPaths);
|
||||
Assert.True(File.Exists(result.OutputPaths[0]));
|
||||
Assert.True(new FileInfo(result.OutputPaths[0]).Length > 0);
|
||||
}
|
||||
}
|
||||
79
src/Everything2Everything.Tests/MarkdownProviderTests.cs
Normal file
79
src/Everything2Everything.Tests/MarkdownProviderTests.cs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Everything2Everything.Core;
|
||||
using Everything2Everything.Core.Converters;
|
||||
using Everything2Everything.Core.Providers;
|
||||
using Xunit;
|
||||
|
||||
namespace Everything2Everything.Tests;
|
||||
|
||||
public class MarkdownProviderTests
|
||||
{
|
||||
private static string TempDir()
|
||||
{
|
||||
var d = Path.Combine(Path.GetTempPath(), "e2e_md_test_" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MarkdownProvider_HtmlToMd_ConvertsProperly()
|
||||
{
|
||||
var dir = TempDir();
|
||||
var html = Path.Combine(dir, "input.html");
|
||||
await File.WriteAllTextAsync(html, "<h1>Title Here</h1><p>Paragraph with <strong>bold</strong> text</p>");
|
||||
|
||||
var provider = new MarkdownProvider();
|
||||
var res = await provider.ConvertAsync(html, dir, ".md", new ConvertOptions(), null, CancellationToken.None);
|
||||
|
||||
Assert.Equal(ConvertStatus.Success, res.Status);
|
||||
var content = await File.ReadAllTextAsync(res.OutputPaths[0]);
|
||||
Assert.Contains("# Title Here", content);
|
||||
Assert.Contains("**bold**", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MarkdownProvider_MdToHtml_ConvertsProperly()
|
||||
{
|
||||
var dir = TempDir();
|
||||
var md = Path.Combine(dir, "input.md");
|
||||
await File.WriteAllTextAsync(md, "# Hello Markdown\n\nThis is a *test*.");
|
||||
|
||||
var provider = new MarkdownProvider();
|
||||
var res = await provider.ConvertAsync(md, dir, ".html", new ConvertOptions(), null, CancellationToken.None);
|
||||
|
||||
Assert.Equal(ConvertStatus.Success, res.Status);
|
||||
var content = await File.ReadAllTextAsync(res.OutputPaths[0]);
|
||||
Assert.Contains("Hello Markdown</h1>", content);
|
||||
Assert.Contains("<em>test</em>", content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MarkdownProvider_Availability_IsAlwaysReady()
|
||||
{
|
||||
var provider = new MarkdownProvider();
|
||||
var avail = await provider.CheckAvailabilityAsync();
|
||||
Assert.True(avail.IsReady);
|
||||
Assert.Equal(ProviderStatus.Available, provider.Capability.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Engine_HtmlToMd_RoutesToMarkdownProvider()
|
||||
{
|
||||
var dir = TempDir();
|
||||
var html = Path.Combine(dir, "input.html");
|
||||
await File.WriteAllTextAsync(html, "<h2>Section</h2><p>Content</p>");
|
||||
|
||||
var engine = Everything2EverythingBootstrap.CreateDefault();
|
||||
var path = engine.Providers.Graph.FindBestPath(".html", ".md");
|
||||
Assert.NotNull(path);
|
||||
Assert.Single(path);
|
||||
Assert.IsType<MarkdownProvider>(path![0].Provider);
|
||||
|
||||
var opt = new ConvertOptions { OutputLocation = OutputLocation.Custom, CustomOutputDirectory = dir };
|
||||
var res = await engine.ConvertOneAsync(html, ".md", opt);
|
||||
Assert.Equal(ConvertStatus.Success, res.Status);
|
||||
}
|
||||
}
|
||||
56
src/Everything2Everything.Tests/MatrixIntegrityTests.cs
Normal file
56
src/Everything2Everything.Tests/MatrixIntegrityTests.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Everything2Everything.Core;
|
||||
using Everything2Everything.Core.Providers;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Everything2Everything.Tests;
|
||||
|
||||
public class MatrixIntegrityTests
|
||||
{
|
||||
private readonly ITestOutputHelper _output;
|
||||
|
||||
public MatrixIntegrityTests(ITestOutputHelper output)
|
||||
{
|
||||
_output = output;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Audit_AllRegisteredProviders_AndPrintMatrix()
|
||||
{
|
||||
var engine = Everything2EverythingBootstrap.CreateDefault();
|
||||
var providers = engine.Providers.All.ToList();
|
||||
|
||||
_output.WriteLine($"=== Total Registered Providers: {providers.Count} ===");
|
||||
foreach (var p in providers)
|
||||
{
|
||||
var cap = p.Capability;
|
||||
_output.WriteLine($"Provider [{cap.Id}] {cap.DisplayName} | Status: {cap.Status} | Pairs: {cap.SupportedConversions.Count}");
|
||||
var missingDeps = cap.ExternalDependencies.Where(d => d.IsRequired).Select(d => d.Name).ToList();
|
||||
if (missingDeps.Any())
|
||||
{
|
||||
_output.WriteLine($" Required deps: {string.Join(", ", missingDeps)}");
|
||||
}
|
||||
}
|
||||
Assert.NotEmpty(providers);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Audit_HtmlReachability_InGraph()
|
||||
{
|
||||
var engine = Everything2EverythingBootstrap.CreateDefault();
|
||||
var outputs = engine.Providers.OutputsForInput(".html");
|
||||
_output.WriteLine($"HTML Reachable Outputs ({outputs.Count}): {string.Join(", ", outputs)}");
|
||||
|
||||
Assert.Contains(".pdf", outputs);
|
||||
Assert.Contains(".png", outputs);
|
||||
Assert.Contains(".jpg", outputs);
|
||||
Assert.Contains(".webp", outputs);
|
||||
Assert.Contains(".md", outputs);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue