From 124427c20a19f7e7fd2f37a4821a59f3cc41b569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20O=2E=20S=C3=B8rensen?= Date: Wed, 5 Aug 2026 12:24:07 +0200 Subject: [PATCH 1/2] test: Separate Nota's tables from the upstream set LibLouis.NET.Test/tables held thirty of Nota's Danish tables while LibLouis.NET.Tables copies the upstream set into the same output directory. Twenty two of the thirty share a file name with an upstream table and differ from it, so which copy a test got depended on MSBuild item ordering, and nothing said so anywhere. Moves them to nota-tables/, kept separate in the output, and points every test at that path. Each test now states which set it means, and the upstream tables are no longer shadowed, which is what lets upstream's braille specs be checked against them. Nota's tables include seven general upstream tables, and liblouis resolves an include relative to the directory of the table doing the including, so those are copied in alongside. They come from the staged upstream set rather than being committed, so they cannot drift from it. NotaTablesAreSelfContained asserts that list stays complete, since an explicit list goes stale the moment a table gains an include. The second guard checks that none of Nota's tables reach tables/. Sharing a file name across the two directories is expected - most of Nota's are forks of an upstream table of the same name - so the tables that exist nowhere upstream are the canary: if one appears in tables/, the two sets are being copied to the same place again. No table content changes. Twenty three of the thirty are reachable from no test - they are a stale copy of the set the application ships - but they are kept and documented rather than deleted, because deciding what is canonical is not this change's business. Co-Authored-By: Claude Opus 5 --- LibLouis.NET.Test/HyphenateTests.cs | 2 +- LibLouis.NET.Test/IndexTablesTests.cs | 2 +- LibLouis.NET.Test/InputLengthTests.cs | 2 +- LibLouis.NET.Test/LibLouis.NET.Test.csproj | 26 ++++- LibLouis.NET.Test/LiblouisHeapTests.cs | 2 +- LibLouis.NET.Test/NativeLockTests.cs | 2 +- LibLouis.NET.Test/NativeMethodsTests.cs | 8 +- LibLouis.NET.Test/NonBmpTests.cs | 2 +- LibLouis.NET.Test/NotaTablesTests.cs | 98 +++++++++++++++++++ LibLouis.NET.Test/OutputDotsTests.cs | 2 +- LibLouis.NET.Test/PositionMappingTests.cs | 2 +- LibLouis.NET.Test/ShutdownTests.cs | 2 +- LibLouis.NET.Test/SpacingTests.cs | 2 +- LibLouis.NET.Test/TypeFormBufferTests.cs | 2 +- .../UTF8StringNoFreeMarshallerTests.cs | 2 +- LibLouis.NET.Test/nota-tables/README.md | 31 ++++++ .../da-dk-6miscChars.cti | 0 .../da-dk-6miscChars_1993.cti | 0 .../da-dk-8miscChars.cti | 0 .../da-dk-8miscChars_1993.cti | 0 .../{tables => nota-tables}/da-dk-braillo.dis | 0 .../{tables => nota-tables}/da-dk-g08.ctb | 0 .../da-dk-g08_1993.ctb | 0 .../da-dk-g16-crossword.ctb | 0 .../da-dk-g16-lit_1993.ctb | 0 .../da-dk-g16-markers.ctb | 0 .../{tables => nota-tables}/da-dk-g16.ctb | 0 .../da-dk-g16_1993-markers.ctb | 0 .../da-dk-g16_1993.ctb | 0 .../{tables => nota-tables}/da-dk-g18.ctb | 0 .../da-dk-g18_1993.ctb | 0 .../{tables => nota-tables}/da-dk-g2.dic | 0 .../da-dk-g26-lit_1993.ctb | 0 .../{tables => nota-tables}/da-dk-g26.ctb | 0 .../da-dk-g26_1993.ctb | 0 .../da-dk-g26l-lit.ctb | 0 .../da-dk-g26l-lit_1993.ctb | 0 .../{tables => nota-tables}/da-dk-g26l.ctb | 0 .../da-dk-g26l_1993.ctb | 0 .../{tables => nota-tables}/da-dk-g28.ctb | 0 .../da-dk-g28_1993.ctb | 0 .../{tables => nota-tables}/da-dk-g28l.ctb | 0 .../da-dk-g28l_1993.ctb | 0 .../{tables => nota-tables}/da-dk-g2_1993.dic | 0 .../da-dk-octobraille.dis | 0 .../da-dk-octobraille_1993.dis | 0 46 files changed, 170 insertions(+), 17 deletions(-) create mode 100644 LibLouis.NET.Test/NotaTablesTests.cs create mode 100644 LibLouis.NET.Test/nota-tables/README.md rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-6miscChars.cti (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-6miscChars_1993.cti (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-8miscChars.cti (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-8miscChars_1993.cti (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-braillo.dis (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g08.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g08_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g16-crossword.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g16-lit_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g16-markers.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g16.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g16_1993-markers.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g16_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g18.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g18_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g2.dic (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g26-lit_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g26.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g26_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g26l-lit.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g26l-lit_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g26l.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g26l_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g28.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g28_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g28l.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g28l_1993.ctb (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-g2_1993.dic (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-octobraille.dis (100%) rename LibLouis.NET.Test/{tables => nota-tables}/da-dk-octobraille_1993.dis (100%) diff --git a/LibLouis.NET.Test/HyphenateTests.cs b/LibLouis.NET.Test/HyphenateTests.cs index a9b022e..2da22eb 100644 --- a/LibLouis.NET.Test/HyphenateTests.cs +++ b/LibLouis.NET.Test/HyphenateTests.cs @@ -18,7 +18,7 @@ public class HyphenateTests private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; [Fact] public void Hyphenate_ReturnsOneHyphenationFlagPerCharacter() diff --git a/LibLouis.NET.Test/IndexTablesTests.cs b/LibLouis.NET.Test/IndexTablesTests.cs index 8f0f8fa..7bfac4e 100644 --- a/LibLouis.NET.Test/IndexTablesTests.cs +++ b/LibLouis.NET.Test/IndexTablesTests.cs @@ -19,7 +19,7 @@ public class IndexTablesTests private static readonly string[] Tables = ["da-dk-g26.ctb", "da-dk-g16-markers.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; /// /// liblouis logs one "Analyzing table <name>" line per array entry it walks, so the number diff --git a/LibLouis.NET.Test/InputLengthTests.cs b/LibLouis.NET.Test/InputLengthTests.cs index 731ddfb..0707f49 100644 --- a/LibLouis.NET.Test/InputLengthTests.cs +++ b/LibLouis.NET.Test/InputLengthTests.cs @@ -29,7 +29,7 @@ public class InputLengthTests private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; /// /// Translate() only requires outputPosition to hold input.Length entries, so liblouis must diff --git a/LibLouis.NET.Test/LibLouis.NET.Test.csproj b/LibLouis.NET.Test/LibLouis.NET.Test.csproj index 48af52f..493c031 100644 --- a/LibLouis.NET.Test/LibLouis.NET.Test.csproj +++ b/LibLouis.NET.Test/LibLouis.NET.Test.csproj @@ -30,7 +30,31 @@ - + + + PreserveNewest + + + + PreserveNewest diff --git a/LibLouis.NET.Test/LiblouisHeapTests.cs b/LibLouis.NET.Test/LiblouisHeapTests.cs index aaa7509..5976252 100644 --- a/LibLouis.NET.Test/LiblouisHeapTests.cs +++ b/LibLouis.NET.Test/LiblouisHeapTests.cs @@ -18,7 +18,7 @@ public unsafe class LiblouisHeapTests private static readonly string[] Tables = ["da-dk-g26.ctb", "da-dk-g16-markers.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; // RVAs in the synthetic image. private const int ImportTable = 0x200; diff --git a/LibLouis.NET.Test/NativeLockTests.cs b/LibLouis.NET.Test/NativeLockTests.cs index 27f82cf..595eb02 100644 --- a/LibLouis.NET.Test/NativeLockTests.cs +++ b/LibLouis.NET.Test/NativeLockTests.cs @@ -27,7 +27,7 @@ public class NativeLockTests private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; [Fact] public void VersionIsReported() diff --git a/LibLouis.NET.Test/NativeMethodsTests.cs b/LibLouis.NET.Test/NativeMethodsTests.cs index 8cb572e..56b5323 100644 --- a/LibLouis.NET.Test/NativeMethodsTests.cs +++ b/LibLouis.NET.Test/NativeMethodsTests.cs @@ -23,7 +23,7 @@ public void SingleMode() Array.Fill(modes, TypeForm.ForeignLanguage); string resultString = LibLouis.Instance.Translate( - tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t)), + tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t)), input, outputLength, modes, @@ -47,7 +47,7 @@ public void NestedMode_EmphasisInForeignLanguage() modes[6] = TypeForm.ForeignLanguage | TypeForm.Emphasis; string resultString = LibLouis.Instance.Translate( - tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t)), + tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t)), input, outputLength, modes, @@ -87,7 +87,7 @@ public void NestedMode_ForeignLanguageInEmphasis() Assert.Equal(inputLength, modes.Length); string resultString = LibLouis.Instance.Translate( - tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t)), + tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t)), input, outputLength, modes, @@ -102,7 +102,7 @@ public void TestPositionResults() const string input = "Første linje. Anden linje, med kursiveret tekst. Tredje linje."; const string expected = "@fze linje. @anç linje, m kursi#rò ükz. @tàdje linje."; - string[] tables = ["tables/da-dk-braillo.dis", "tables/da-dk-g26.ctb"]; + string[] tables = ["nota-tables/da-dk-braillo.dis", "nota-tables/da-dk-g26.ctb"]; int outputLength = input.Length * 4; int cursorPosition = 0; diff --git a/LibLouis.NET.Test/NonBmpTests.cs b/LibLouis.NET.Test/NonBmpTests.cs index 261417e..18a5999 100644 --- a/LibLouis.NET.Test/NonBmpTests.cs +++ b/LibLouis.NET.Test/NonBmpTests.cs @@ -23,7 +23,7 @@ public class NonBmpTests private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; /// /// How many widechars liblouis sees for : whole characters on a UCS-4 diff --git a/LibLouis.NET.Test/NotaTablesTests.cs b/LibLouis.NET.Test/NotaTablesTests.cs new file mode 100644 index 0000000..dc9d247 --- /dev/null +++ b/LibLouis.NET.Test/NotaTablesTests.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + +using Xunit; + +namespace LibLouis.NET.Test; + +/// +/// Guards the nota-tables/ directory, which the tests use in place of the upstream set. +/// +public class NotaTablesTests +{ + private static readonly string NotaTableDirectory = + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables"); + + private static readonly string UpstreamTableDirectory = + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables"); + + /// + /// liblouis resolves an include relative to the directory of the table doing the including, so + /// every table nota-tables/ pulls in has to be there too. Most are Nota's own; the handful of + /// general upstream tables they need are copied in by an explicit list in the csproj, and an + /// explicit list is exactly the kind of thing that goes stale the moment a table gains an + /// include. + /// + [Fact] + public void NotaTablesAreSelfContained() + { + var present = TableFilesIn(NotaTableDirectory).ToHashSet(StringComparer.Ordinal); + var missing = new SortedSet(StringComparer.Ordinal); + + foreach (string file in present) + { + foreach (string included in IncludesOf(Path.Combine(NotaTableDirectory, file))) + { + if (!present.Contains(included)) + { + missing.Add($"{included} (included by {file})"); + } + } + } + + Assert.True( + missing.Count == 0, + "nota-tables/ is missing tables it includes, so those cannot be compiled from that " + + "directory alone. Add them to the upstream copy list in the csproj:\n " + + string.Join("\n ", missing)); + } + + /// + /// The separate directory exists so that nothing of Nota's shadows the upstream set. Sharing a + /// file name across the two directories is expected and fine - twenty two of Nota's tables are + /// forks of an upstream table of the same name. What must never happen is Nota's tables being + /// copied into tables/ as well, which is what the old single directory did. + /// + /// The tables that exist nowhere upstream are the reliable canary: if one of them turns up in + /// tables/, the copy is misconfigured, whatever the file names say. + /// + [Fact] + public void NotaTablesDoNotLeakIntoTheUpstreamDirectory() + { + Assert.True(Directory.Exists(UpstreamTableDirectory), "the upstream tables were not staged"); + + string[] notaOnly = + [ + "da-dk-g16-markers.ctb", + "da-dk-g16_1993-markers.ctb", + "da-dk-braillo.dis", + "da-dk-g16-crossword.ctb", + "da-dk-g26l.ctb", + "da-dk-g26l-lit.ctb", + "da-dk-g28l.ctb", + "da-dk-g2_1993.dic", + ]; + + var upstream = TableFilesIn(UpstreamTableDirectory).ToHashSet(StringComparer.Ordinal); + var leaked = notaOnly.Where(upstream.Contains).OrderBy(f => f, StringComparer.Ordinal).ToList(); + + Assert.True( + leaked.Count == 0, + "tables/ should hold only the upstream set, but these tables of Nota's are in it, so " + + "the two are being copied to the same place again:\n " + string.Join("\n ", leaked)); + } + + private static IEnumerable TableFilesIn(string directory) => + Directory.EnumerateFiles(directory) + .Select(Path.GetFileName) + .Where(f => f is not null && !f.EndsWith(".md", StringComparison.OrdinalIgnoreCase))!; + + private static IEnumerable IncludesOf(string path) => + File.ReadLines(path) + .Select(line => Regex.Match(line, @"^\s*include\s+(\S+)")) + .Where(m => m.Success) + .Select(m => m.Groups[1].Value); +} diff --git a/LibLouis.NET.Test/OutputDotsTests.cs b/LibLouis.NET.Test/OutputDotsTests.cs index 00e748f..9bf6704 100644 --- a/LibLouis.NET.Test/OutputDotsTests.cs +++ b/LibLouis.NET.Test/OutputDotsTests.cs @@ -18,7 +18,7 @@ public class OutputDotsTests private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g08.ctb"]; private static string[] EightDotTables() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; private static TranslatedString TranslateWithTypeForm(string input) { diff --git a/LibLouis.NET.Test/PositionMappingTests.cs b/LibLouis.NET.Test/PositionMappingTests.cs index 2140ea0..3cb9324 100644 --- a/LibLouis.NET.Test/PositionMappingTests.cs +++ b/LibLouis.NET.Test/PositionMappingTests.cs @@ -21,7 +21,7 @@ public class PositionMappingTests private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; private static TranslatedString Translate(string input) { diff --git a/LibLouis.NET.Test/ShutdownTests.cs b/LibLouis.NET.Test/ShutdownTests.cs index c6d9f0b..d663c3f 100644 --- a/LibLouis.NET.Test/ShutdownTests.cs +++ b/LibLouis.NET.Test/ShutdownTests.cs @@ -24,7 +24,7 @@ public class ShutdownTests private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g26.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; private static FieldInfo ShutDownField => typeof(LibLouis).GetField("_shutDown", BindingFlags.NonPublic | BindingFlags.Static) diff --git a/LibLouis.NET.Test/SpacingTests.cs b/LibLouis.NET.Test/SpacingTests.cs index f6a007e..b3e9119 100644 --- a/LibLouis.NET.Test/SpacingTests.cs +++ b/LibLouis.NET.Test/SpacingTests.cs @@ -25,7 +25,7 @@ public class SpacingTests private static readonly string[] Tables = new[] { "da-dk-braillo.dis", "da-dk-g26.ctb" } - .Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t)) + .Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t)) .ToArray(); [Fact] diff --git a/LibLouis.NET.Test/TypeFormBufferTests.cs b/LibLouis.NET.Test/TypeFormBufferTests.cs index 38bf26b..fcbf324 100644 --- a/LibLouis.NET.Test/TypeFormBufferTests.cs +++ b/LibLouis.NET.Test/TypeFormBufferTests.cs @@ -24,7 +24,7 @@ public class TypeFormBufferTests private static readonly string[] Tables = ["da-dk-braillo.dis", "da-dk-g16-markers.ctb"]; private static string[] TablePaths() => - [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; + [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nota-tables", t))]; /// /// Documents the native contract that makes the overrun possible, independent of the wrapper: diff --git a/LibLouis.NET.Test/UTF8StringNoFreeMarshallerTests.cs b/LibLouis.NET.Test/UTF8StringNoFreeMarshallerTests.cs index 0373381..eea4522 100644 --- a/LibLouis.NET.Test/UTF8StringNoFreeMarshallerTests.cs +++ b/LibLouis.NET.Test/UTF8StringNoFreeMarshallerTests.cs @@ -16,7 +16,7 @@ public unsafe class UTF8StringNoFreeMarshallerTests [Theory] [InlineData("")] [InlineData("a")] - [InlineData("tables/da-dk-g26.ctb")] + [InlineData("nota-tables/da-dk-g26.ctb")] [InlineData("Første linje")] // multi-byte UTF-8 [InlineData("\U0001D11E")] // non-BMP, surrogate pair on the managed side public void ConvertToManaged_ReadsNulTerminatedUtf8(string value) diff --git a/LibLouis.NET.Test/nota-tables/README.md b/LibLouis.NET.Test/nota-tables/README.md new file mode 100644 index 0000000..da6339e --- /dev/null +++ b/LibLouis.NET.Test/nota-tables/README.md @@ -0,0 +1,31 @@ +# Nota's Danish tables, for the tests + +Kept in their own directory, and copied to `nota-tables/` in the output rather than `tables/`. + +`LibLouis.NET.Tables` copies the upstream table set into `tables/`. Five of the files here share a +name with an upstream table and differ from it, so a single shared directory would make which copy +a test gets depend on MSBuild item ordering. Separate directories mean every test states which set +it means, and the upstream braille specs can be checked against upstream tables without this set +shadowing them. + +## What these are + +A fork of an older upstream, not a patch on the current one. They add things upstream does not +have, such as the `foreign` emphasis class behind `TypeForm.ForeignLanguage`, and they are missing +things upstream has since fixed, such as the rules that remove the space between `§` and a following +number. Do not assume a file here matches the upstream file of the same name in either direction. + +Two of them, `da-dk-g16-markers.ctb` and `da-dk-braillo.dis`, exist nowhere upstream, which is why +the tests cannot simply use the upstream set. + +## These are not canonical + +The canonical Nota tables ship with the application. This is a copy, and a stale one: only seven of +the thirty files are reachable from any test. + +Reachable: `da-dk-g16-markers.ctb`, `da-dk-braillo.dis`, `da-dk-g08.ctb`, `da-dk-g26.ctb`, and the +three they include (`da-dk-6miscChars.cti`, `da-dk-octobraille.dis`, `da-dk-g2.dic`). + +The other twenty three are referenced by nothing. They are kept for now, but nothing keeps them in +step with the application's copy, so treat any of them as evidence of nothing. Prefer adding a test +that needs a file over adding a file that no test needs. diff --git a/LibLouis.NET.Test/tables/da-dk-6miscChars.cti b/LibLouis.NET.Test/nota-tables/da-dk-6miscChars.cti similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-6miscChars.cti rename to LibLouis.NET.Test/nota-tables/da-dk-6miscChars.cti diff --git a/LibLouis.NET.Test/tables/da-dk-6miscChars_1993.cti b/LibLouis.NET.Test/nota-tables/da-dk-6miscChars_1993.cti similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-6miscChars_1993.cti rename to LibLouis.NET.Test/nota-tables/da-dk-6miscChars_1993.cti diff --git a/LibLouis.NET.Test/tables/da-dk-8miscChars.cti b/LibLouis.NET.Test/nota-tables/da-dk-8miscChars.cti similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-8miscChars.cti rename to LibLouis.NET.Test/nota-tables/da-dk-8miscChars.cti diff --git a/LibLouis.NET.Test/tables/da-dk-8miscChars_1993.cti b/LibLouis.NET.Test/nota-tables/da-dk-8miscChars_1993.cti similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-8miscChars_1993.cti rename to LibLouis.NET.Test/nota-tables/da-dk-8miscChars_1993.cti diff --git a/LibLouis.NET.Test/tables/da-dk-braillo.dis b/LibLouis.NET.Test/nota-tables/da-dk-braillo.dis similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-braillo.dis rename to LibLouis.NET.Test/nota-tables/da-dk-braillo.dis diff --git a/LibLouis.NET.Test/tables/da-dk-g08.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g08.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g08.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g08.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g08_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g08_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g08_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g08_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g16-crossword.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16-crossword.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g16-crossword.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g16-crossword.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g16-lit_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16-lit_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g16-lit_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g16-lit_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g16-markers.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16-markers.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g16-markers.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g16-markers.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g16.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g16.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g16.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g16_1993-markers.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16_1993-markers.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g16_1993-markers.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g16_1993-markers.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g16_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g16_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g16_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g16_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g18.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g18.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g18.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g18.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g18_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g18_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g18_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g18_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g2.dic b/LibLouis.NET.Test/nota-tables/da-dk-g2.dic similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g2.dic rename to LibLouis.NET.Test/nota-tables/da-dk-g2.dic diff --git a/LibLouis.NET.Test/tables/da-dk-g26-lit_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26-lit_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g26-lit_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g26-lit_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g26.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g26.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g26.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g26_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g26_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g26_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g26l-lit.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26l-lit.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g26l-lit.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g26l-lit.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g26l-lit_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26l-lit_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g26l-lit_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g26l-lit_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g26l.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26l.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g26l.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g26l.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g26l_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g26l_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g26l_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g26l_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g28.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g28.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g28.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g28.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g28_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g28_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g28_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g28_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g28l.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g28l.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g28l.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g28l.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g28l_1993.ctb b/LibLouis.NET.Test/nota-tables/da-dk-g28l_1993.ctb similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g28l_1993.ctb rename to LibLouis.NET.Test/nota-tables/da-dk-g28l_1993.ctb diff --git a/LibLouis.NET.Test/tables/da-dk-g2_1993.dic b/LibLouis.NET.Test/nota-tables/da-dk-g2_1993.dic similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-g2_1993.dic rename to LibLouis.NET.Test/nota-tables/da-dk-g2_1993.dic diff --git a/LibLouis.NET.Test/tables/da-dk-octobraille.dis b/LibLouis.NET.Test/nota-tables/da-dk-octobraille.dis similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-octobraille.dis rename to LibLouis.NET.Test/nota-tables/da-dk-octobraille.dis diff --git a/LibLouis.NET.Test/tables/da-dk-octobraille_1993.dis b/LibLouis.NET.Test/nota-tables/da-dk-octobraille_1993.dis similarity index 100% rename from LibLouis.NET.Test/tables/da-dk-octobraille_1993.dis rename to LibLouis.NET.Test/nota-tables/da-dk-octobraille_1993.dis From d579446e65b3e56e96183a7a80b7e33f86f91423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Otte=20S=C3=B8rensen?= Date: Fri, 9 Oct 2026 14:11:08 +0200 Subject: [PATCH 2/2] docs: Reconcile the count of Nota tables that shadow upstream ones Review feedback on #20: the PR description said 22 Nota tables share a file name with an upstream table and differ from it, while the csproj comment and nota-tables/README.md said five. Both were true of different sets. Against the liblouis 3.33.0 tables, 22 of the 30 files collide and every one of them differs; five of those are among the seven files the tests actually load (the other two, da-dk-g16-markers.ctb and da-dk-braillo.dis, exist nowhere upstream). Say both, so the numbers stop contradicting each other. Co-Authored-By: Claude Opus 5.5 --- LibLouis.NET.Test/LibLouis.NET.Test.csproj | 5 +++-- LibLouis.NET.Test/nota-tables/README.md | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/LibLouis.NET.Test/LibLouis.NET.Test.csproj b/LibLouis.NET.Test/LibLouis.NET.Test.csproj index 493c031..cae302f 100644 --- a/LibLouis.NET.Test/LibLouis.NET.Test.csproj +++ b/LibLouis.NET.Test/LibLouis.NET.Test.csproj @@ -31,8 +31,9 @@ diff --git a/LibLouis.NET.Test/nota-tables/README.md b/LibLouis.NET.Test/nota-tables/README.md index da6339e..e5611de 100644 --- a/LibLouis.NET.Test/nota-tables/README.md +++ b/LibLouis.NET.Test/nota-tables/README.md @@ -2,9 +2,10 @@ Kept in their own directory, and copied to `nota-tables/` in the output rather than `tables/`. -`LibLouis.NET.Tables` copies the upstream table set into `tables/`. Five of the files here share a -name with an upstream table and differ from it, so a single shared directory would make which copy -a test gets depend on MSBuild item ordering. Separate directories mean every test states which set +`LibLouis.NET.Tables` copies the upstream table set into `tables/`. Twenty two of the thirty files +here share a name with an upstream table and differ from it - five of them among the seven the tests +actually load (see below) - so a single shared directory would make which copy a test gets depend on +MSBuild item ordering. Separate directories mean every test states which set it means, and the upstream braille specs can be checked against upstream tables without this set shadowing them.