Files
OpenNest/OpenNest.IO.Tests/NestArchiveJson.cs
T
ajandClaude Opus 5.5 9d6d5fa4b2 test(io): write test archives through NestArchiveJson
Nine persistence test classes turned a nest or a single drawing into
archive bytes with their own Write helpers, and one kept a private copy
of NestJson. They now use NestArchiveJson.ArchiveBytes and NestJson.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:23:01 -05:00

114 lines
4.2 KiB
C#

using System.IO.Compression;
using System.Text;
using System.Text.Json.Nodes;
namespace OpenNest.IO.Tests;
/// <summary>
/// Reads and rewrites the <c>nest.json</c> entry of a .nest archive, for tests that check or
/// corrupt the stored shape. Import with <c>using static</c>.
/// </summary>
internal static class NestArchiveJson
{
public static (Nest Nest, IReadOnlyList<string> Warnings) RoundTrip(byte[] archive)
{
var reader = new NestReader(new MemoryStream(archive));
return (reader.Read(), reader.Warnings);
}
public static MemoryStream Write(Nest nest)
{
var stream = new MemoryStream();
Assert.True(new NestWriter(nest).Write(stream));
stream.Position = 0;
return stream;
}
/// <summary>The archive bytes <see cref="NestWriter"/> writes for the nest.</summary>
public static byte[] ArchiveBytes(Nest nest) => Write(nest).ToArray();
/// <summary>The archive bytes of an inch nest that holds only the drawing.</summary>
public static byte[] ArchiveBytes(Drawing drawing)
{
var nest = new Nest(drawing.Name) { Units = Units.Inches };
nest.Drawings.Add(drawing);
return ArchiveBytes(nest);
}
/// <summary>The archive's nest.json, leaving <paramref name="zip"/> ready to read again.</summary>
public static JsonObject NestJson(MemoryStream zip)
{
var json = NestJson(zip.ToArray());
zip.Position = 0;
return json;
}
/// <summary>A copy of the archive whose nest.json was changed by <paramref name="edit"/>.</summary>
public static MemoryStream Rewrite(MemoryStream zip, Action<JsonObject> edit)
{
var json = NestJson(zip);
edit(json);
return new MemoryStream(ReplaceNestJson(zip.ToArray(), json));
}
public static JsonObject NestJson(byte[] archive)
{
using var zip = new ZipArchive(new MemoryStream(archive), ZipArchiveMode.Read);
using var reader = new StreamReader(zip.GetEntry("nest.json")!.Open(), Encoding.UTF8);
return JsonNode.Parse(reader.ReadToEnd())!.AsObject();
}
public static byte[] ReplaceNestJson(byte[] archive, JsonObject json)
{
using var output = new MemoryStream();
output.Write(archive);
using (var zip = new ZipArchive(output, ZipArchiveMode.Update, leaveOpen: true))
{
zip.GetEntry("nest.json")!.Delete();
using var writer = new StreamWriter(zip.CreateEntry("nest.json").Open(), new UTF8Encoding(false));
writer.Write(json.ToJsonString());
}
return output.ToArray();
}
public static string ReadNestJson(MemoryStream zipBytes)
{
zipBytes.Position = 0;
using var archive = new ZipArchive(zipBytes, ZipArchiveMode.Read, leaveOpen: true);
var entry = archive.GetEntry("nest.json");
Assert.NotNull(entry);
using var reader = new StreamReader(entry.Open(), Encoding.UTF8);
return reader.ReadToEnd();
}
/// <summary>A copy of the archive whose nest.json text passed through <paramref name="rewrite"/>.</summary>
public static MemoryStream RewriteNestJson(MemoryStream zipBytes, Func<string, string> rewrite)
{
zipBytes.Position = 0;
var output = new MemoryStream();
using (var source = new ZipArchive(zipBytes, ZipArchiveMode.Read, leaveOpen: true))
using (var target = new ZipArchive(output, ZipArchiveMode.Create, leaveOpen: true))
{
foreach (var entry in source.Entries)
{
var newEntry = target.CreateEntry(entry.FullName);
using var input = entry.Open();
using var outStream = newEntry.Open();
if (entry.FullName == "nest.json")
{
using var text = new StreamReader(input, Encoding.UTF8);
using var writer = new StreamWriter(outStream, new UTF8Encoding(false));
writer.Write(rewrite(text.ReadToEnd()));
}
else
{
input.CopyTo(outStream);
}
}
}
output.Position = 0;
return output;
}
}