feat: rebrand to MMD PDF, single corporate theme, and remove original text under an edit
- Services/PdfRedactText.cs: strip text whose origin falls inside a CoverAnnotation from the page content stream at save time, hooked into PdfBurn.DrawAnnotationsIntoDoc. Fixes edited values staying recoverable by text extraction. - Themes/MMD.xaml replaces all thirteen themes; picker and accent strip removed; no dark mode. - Rename KillerPDF -> MMD PDF across code, resources, packaging and locale strings; new icon. - Remove the upstream author credit and the in-app install button.
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MmdPdf.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace MmdPdf.Tests;
|
||||
|
||||
// The rule this file exists to enforce: OCR LANGUAGES TRACK INTERFACE LANGUAGES.
|
||||
// If MmdPdf's UI is offered in a language, OCR is offered in it too. There is no such thing as
|
||||
// an interface language whose text the app cannot read.
|
||||
//
|
||||
// Nothing enforced it before, so it drifted: the UI shipped hu-HU while the catalog stayed at
|
||||
// eleven entries, and baobab-ts.com went on telling people OCR covered ten languages and that
|
||||
// Polish and Hungarian "do not require OCR models".
|
||||
//
|
||||
// These read the real Strings folder instead of a second hardcoded list, so adding a locale fails
|
||||
// the build until its model is registered. release.ps1 runs the suite, so it cannot ship broken.
|
||||
public sealed class OcrCatalogTests
|
||||
{
|
||||
// The test binary sits at MmdPdf.Tests\bin\<cfg>\net48; the repo root is the ancestor that
|
||||
// holds Strings\. Walking up beats a pile of ..\..\.. that breaks whenever the layout moves.
|
||||
private static string StringsDir()
|
||||
{
|
||||
var dir = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (dir != null && !Directory.Exists(Path.Combine(dir.FullName, "Strings")))
|
||||
dir = dir.Parent;
|
||||
Assert.True(dir != null, "could not locate the repo's Strings folder from " + AppContext.BaseDirectory);
|
||||
return Path.Combine(dir!.FullName, "Strings");
|
||||
}
|
||||
|
||||
private static string[] ShippedLocales() =>
|
||||
Directory.GetFiles(StringsDir(), "*.xaml")
|
||||
.Select(f => Path.GetFileNameWithoutExtension(f)!)
|
||||
.OrderBy(n => n, StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
|
||||
[Fact]
|
||||
public void TheStringsFolderIsActuallyFound()
|
||||
{
|
||||
// Guards the guard: if the walk-up ever failed silently, every other test here would
|
||||
// compare against an empty list and pass while checking nothing.
|
||||
Assert.NotEmpty(ShippedLocales());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EveryShippedLocaleHasAnOcrModel()
|
||||
{
|
||||
var mapped = OcrCatalog.LocaleToCode.Select(x => x.Locale).ToArray();
|
||||
var missing = ShippedLocales()
|
||||
.Where(l => !mapped.Contains(l, StringComparer.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
|
||||
Assert.True(missing.Length == 0,
|
||||
"These locales ship an interface but have no OCR model in OcrCatalog.LocaleToCode: " +
|
||||
string.Join(", ", missing));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NoModelIsRegisteredForALocaleThatIsNotShipped()
|
||||
{
|
||||
var locales = ShippedLocales();
|
||||
var stale = OcrCatalog.LocaleToCode
|
||||
.Where(x => !locales.Contains(x.Locale, StringComparer.OrdinalIgnoreCase))
|
||||
.Select(x => x.Locale + " -> " + x.Code)
|
||||
.ToArray();
|
||||
|
||||
Assert.True(stale.Length == 0,
|
||||
"These OCR entries point at locales no longer in Strings\\: " + string.Join(", ", stale));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CatalogAndLocaleMapAgree()
|
||||
{
|
||||
var catalog = OcrCatalog.Languages.Select(x => x.Code).OrderBy(c => c, StringComparer.Ordinal).ToArray();
|
||||
var mapped = OcrCatalog.LocaleToCode.Select(x => x.Code).OrderBy(c => c, StringComparer.Ordinal).ToArray();
|
||||
Assert.Equal(mapped, catalog);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CatalogHasNoDuplicatesAndNoBlanks()
|
||||
{
|
||||
var codes = OcrCatalog.Languages.Select(x => x.Code).ToArray();
|
||||
Assert.Equal(codes.Length, codes.Distinct(StringComparer.Ordinal).Count());
|
||||
Assert.All(OcrCatalog.Languages, e =>
|
||||
{
|
||||
Assert.False(string.IsNullOrWhiteSpace(e.Code));
|
||||
Assert.False(string.IsNullOrWhiteSpace(e.Name));
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OcrLanguageCountEqualsInterfaceLanguageCount()
|
||||
{
|
||||
// The number baobab-ts.com quotes in prose. Pinning it here is what stops the site and
|
||||
// the app from disagreeing again.
|
||||
Assert.Equal(ShippedLocales().Length, OcrCatalog.Languages.Length);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("hu-HU", "hun")]
|
||||
[InlineData("pl-PL", "pol")]
|
||||
public void TheOnesThatWereMissingAreRegistered(string locale, string code)
|
||||
{
|
||||
Assert.Contains(OcrCatalog.LocaleToCode, x =>
|
||||
string.Equals(x.Locale, locale, StringComparison.OrdinalIgnoreCase) && x.Code == code);
|
||||
Assert.Contains(OcrCatalog.Languages, x => x.Code == code);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user