using RioJoy.Core.Plasma; using Xunit; namespace RioJoy.Core.Tests.Plasma; public class PlasmaCommandsTests { [Fact] public void EscSequences_AreCorrect() { Assert.Equal(new byte[] { 27, (byte)'@' }, PlasmaCommands.Clear()); Assert.Equal(new byte[] { 27, (byte)'L' }, PlasmaCommands.CursorHome()); Assert.Equal(new byte[] { 27, (byte)'R', 10 }, PlasmaCommands.CursorX(10)); Assert.Equal(new byte[] { 27, (byte)'Q', 20 }, PlasmaCommands.CursorY(20)); Assert.Equal(new byte[] { 27, (byte)'H', 3 }, PlasmaCommands.FontAttr(3)); Assert.Equal(new byte[] { 27, (byte)'K', 5 }, PlasmaCommands.Font(5)); } [Fact] public void Box_DrawAndFill_HaveExpectedLayout() { Assert.Equal(new byte[] { 27, (byte)'X', 1, 2, 3, 4 }, PlasmaCommands.BoxDraw(1, 2, 3, 4)); // Fill inserts a leading 0 parameter. Assert.Equal(new byte[] { 27, (byte)'x', 0, 1, 2, 3, 4 }, PlasmaCommands.BoxFill(1, 2, 3, 4)); } [Fact] public void Text_EncodesOneBytePerChar() { Assert.Equal(new byte[] { (byte)'A', (byte)'B', (byte)'C' }, PlasmaCommands.Text("ABC")); } [Fact] public void GraphicsWrite_LaysOutHeaderThenData() { // ESC P s y x w h data… (s=0, single-screen hardware). byte[] cmd = PlasmaCommands.GraphicsWrite(5, 2, 2, 2, new byte[] { 0xAA, 0xBB, 0xCC, 0xDD }); Assert.Equal(new byte[] { 27, (byte)'P', 0, 5, 2, 2, 2, 0xAA, 0xBB, 0xCC, 0xDD }, cmd); } [Fact] public void GraphicsRow_IsAWholeRowWrite() { // The native game's shape: x=0, w=16, h=1 — one full 128-px row. var row = new byte[16]; row[0] = 0x80; // leftmost pixel (MSB-first) byte[] cmd = PlasmaCommands.GraphicsRow(31, row); byte[] expected = new byte[] { 27, (byte)'P', 0, 31, 0, 16, 1 }.Concat(row).ToArray(); Assert.Equal(expected, cmd); } [Fact] public void GraphicsWrite_RejectsOutOfPanelSpans() { Assert.Throws(() => PlasmaCommands.GraphicsRow(32, new byte[16])); Assert.Throws( () => PlasmaCommands.GraphicsWrite(0, 15, 2, 1, new byte[2])); // spills past byte column 15 Assert.Throws( () => PlasmaCommands.GraphicsWrite(31, 0, 16, 2, new byte[32])); // spills past row 31 Assert.Throws( () => PlasmaCommands.GraphicsWrite(0, 0, 16, 1, new byte[15])); // data length mismatch } [Theory] [InlineData(0, 5, 7)] [InlineData(3, 5, 7)] [InlineData(4, 10, 14)] [InlineData(5, 10, 14)] [InlineData(7, 5, 7)] public void GetFontSize_MatchesLegacy(int font, int w, int h) { Assert.Equal(new FontSize(w, h), PlasmaCommands.GetFontSize(font)); } [Fact] public void ResolvePosText_ShortText_PicksFont5_AndCenters() { // "HELLO" (5) is non-score and ≤9 → font 5 (10×14). Centered around (56,15). (byte x, byte y, byte font, int len) = PlasmaCommands.ResolvePosText("HELLO", 0, 0, 0); Assert.Equal(5, font); Assert.Equal(5, len); Assert.Equal(31, x); // 56 - (5*10/2) Assert.Equal(8, y); // 15 - (14/2) } [Fact] public void ResolvePosText_LongText_Font2_AndCapsLength() { string text = new string('1', 24); (byte x, byte y, byte font, int len) = PlasmaCommands.ResolvePosText(text, 0, 0, 0); Assert.Equal(2, font); Assert.Equal(20, len); // capped Assert.Equal(6, x); // 56 - (20*5/2) Assert.Equal(12, y); // 15 - (7/2) } [Fact] public void ResolvePosText_ScoreFont_AndExplicitPosition_Unchanged() { // font 2 (score) keeps its font; non-zero position is not re-centered. (byte x, byte y, byte font, int len) = PlasmaCommands.ResolvePosText("AB", 5, 6, 2); Assert.Equal(2, font); Assert.Equal(2, len); Assert.Equal(5, x); Assert.Equal(6, y); } }