public void ModelUpdatesWhenViewPortChanges() { var buffer = new byte[0x100]; var model = new PokemonModel(buffer); var viewPort = new ViewPort("file.txt", model); viewPort.Edit("<000020>"); Assert.Equal(0, model.GetNextRun(0).Start); Assert.Equal(0x20, model.GetNextRun(10).Start); }
public void PointerModelFindsSelfReferences() { var buffer = new byte[0x20]; var model = new PokemonModel(buffer); var token = new ModelDelta(); model.WritePointer(token, 0xC, 0xC); model = new PokemonModel(buffer); var run = model.GetNextRun(0); var nextRun = model.GetNextRun(run.Start + run.Length); Assert.NotNull(run); Assert.Equal(NoInfoRun.NullRun, nextRun); }
public void SupportAutomaticallyAddingFormatsBasedOnPointerFormat() { viewPort.Edit("FF"); // have to put the FF first, or trying to create a text run will fail viewPort.MoveSelectionStart.Execute(Direction.Left); viewPort.Edit("^text\"\" Some Text\""); viewPort.SelectionStart = new Point(0, 0); viewPort.Edit("^ "); // remove the anchor. Keeps the data though. viewPort.SelectionStart = new Point(0, 4); viewPort.Edit("00 00 00 08"); viewPort.SelectionStart = new Point(0, 4); viewPort.Edit("^table[description<\"\">]4 "); // adding this should automatically add a format at 000000, since a pointer points there. viewPort.Goto.Execute("000000"); // scroll back to top Assert.IsType <PCSRun>(model.GetNextRun(0)); }
public void CanTruncateString() { var buffer = Enumerable.Repeat((byte)0xFF, 0x100).ToArray(); var model = new PokemonModel(buffer); var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.Edit("^bob\"\" \"Hello World!\""); viewPort.SelectionStart = new Point("Hello".Length, 0); viewPort.Edit("\""); var run = (PCSRun)model.GetNextRun(0); Assert.Equal(6, run.Length); Assert.Equal(0xFF, buffer[7]); Assert.Equal(0xFF, buffer[8]); Assert.Equal(0xFF, buffer[9]); Assert.Equal(0xFF, buffer[10]); Assert.Equal(0xFF, buffer[11]); Assert.Equal(0xFF, buffer[12]); Assert.Equal(0xFF, buffer[13]); }
public void CanUndoFormatChange() { var data = new byte[0x100]; var model = new PokemonModel(data); var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.SelectionStart = new Point(4, 0); viewPort.Edit("<000030>"); Assert.Equal(0x04, model.GetNextRun(0).Start); viewPort.Undo.Execute(); Assert.Equal(int.MaxValue, model.GetNextRun(0).Start); }
public void CanUndoFromToolChange() { var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray(); var model = new PokemonModel(buffer); var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.Edit("^bob\"\" "); var bobRun = model.GetNextRun(0); Assert.Equal(1, bobRun.Length); // move the selection to force a break in the undo history viewPort.SelectionStart = new Point(3, 3); viewPort.SelectionStart = new Point(0, 0); viewPort.Tools.StringTool.Address = 0; viewPort.Tools.StringTool.Content = "Hello World!"; viewPort.Undo.Execute(); // should undo only the tool change, not the name change Assert.Equal(0xFF, model[0]); Assert.True(viewPort.Undo.CanExecute(null)); }
public void CannotAddNewStringAnchorUnlessItEndsBeforeNextKnownAnchor() { var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray(); for (int i = 0; i < 0x10; i++) { buffer[i] = 0x00; } var model = new PokemonModel(buffer); var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 }; var errors = new List <string>(); viewPort.OnError += (sender, e) => errors.Add(e); // add an anchor with some data on the 2nd line viewPort.SelectionStart = new Point(0, 1); viewPort.Edit("^bob\"\" \"Hello World!\""); // but now, try to add a string format in the middle of all the 00 bytes viewPort.SelectionStart = new Point(0, 0); viewPort.Edit("^tom\"\" "); // trying to add a string anchor should've failed Assert.Single(errors); Assert.Equal(0x10, model.GetNextRun(1).Start); Assert.IsType <None>(viewPort[0, 0].Format); }
public void CanAutoMoveWhenHittingData() { var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray(); var model = new PokemonModel(buffer); var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.SelectionStart = new Point(8, 0); viewPort.Edit("A1 B3 64 18 <tom>"); viewPort.SelectionStart = new Point(0, 0); viewPort.Edit("^tom\"\" \"Some really long string\""); // the run was moved var run = model.GetNextRun(0x10); Assert.IsType <PCSRun>(run); Assert.Equal(24, run.Length); // the original data is now cleared Assert.Equal(0xFF, model[0]); Assert.Equal(0xFF, model[1]); Assert.Equal(0xFF, model[2]); Assert.Equal(0xFF, model[3]); // pointer should be updated Assert.Equal(run.Start, model.ReadPointer(0xC)); }
public void TableToolCanExtendTable() { // Arrange var data = Enumerable.Range(0, 0x200).Select(i => (byte)0xFF).ToArray(); var model = new PokemonModel(data); var viewPort = new ViewPort("name.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.Edit("^array[name\"\"16]3 "); viewPort.Tools.SelectedIndex = Enumerable.Range(0, viewPort.Tools.Count).Single(i => viewPort.Tools[i] == viewPort.Tools.TableTool); Assert.True(viewPort.Tools.TableTool.Next.CanExecute(null)); // table has 3 entries // Act: move to end of table while (viewPort.Tools.TableTool.Next.CanExecute(null)) { viewPort.Tools.TableTool.Next.Execute(); } Assert.True(viewPort.Tools.TableTool.Append.CanExecute(null)); viewPort.Tools.TableTool.Append.Execute(); Assert.Contains("3", viewPort.Tools.TableTool.CurrentElementName); Assert.Equal(16 * 4, model.GetNextRun(0).Length); }
public void AnchorFormatAutoCompletesToSingleByte() { viewPort.AnchorText = "^array[data1. b data2.]8"; var array = (ArrayRun)model.GetNextRun(0); Assert.Equal(3, array.ElementLength); Assert.Empty(errors); }
public void WritingOverAnAnchorDeletesThatAnchor() { var buffer = new byte[0x100]; var model = new PokemonModel(buffer); var token = new ModelDelta(); model.WritePointer(token, 16, 32); model.ObserveRunWritten(token, new PointerRun(16)); model.ClearFormat(token, 30, 4); // this format clear removes the anchor that was auto-generated from the pointer. Which means the data from before must not be a pointer. model.WritePointer(token, 30, 64); model.ObserveRunWritten(token, new PointerRun(30)); Assert.Equal(30, model.GetNextRun(10).Start); // original pointer at 16 is no longer there. The new first data is the anchor at 30 Assert.Equal(32, model.ReadPointer(16)); // but the data at 16 still looks like a pointer: only the format is gone Assert.Equal(64, model.GetNextRun(34).Start); // next data is the anchor from the pointer at 30 }
public void ByteRun_CanSerialize() { ViewPort.Edit(".some.counter-2 "); var newModel = new PokemonModel(Model.RawData, Model.ExportMetadata(Singletons.MetadataInfo), Singletons); var run = (WordRun)newModel.GetNextRun(0); Assert.Equal(1, run.Length); Assert.Equal(-2, run.ValueOffset); }
public void WritingAnchorIntoAPointerRemovesThatPointer() { var buffer = new byte[0x100]; var model = new PokemonModel(buffer); var token = new ModelDelta(); model.WritePointer(token, 16, 12); model.ObserveRunWritten(token, new PointerRun(16)); model.ObserveAnchorWritten(token, "bob", new NoInfoRun(18)); Assert.Equal(18, model.GetNextRun(10).Start); }
public void CanWriteString() { var buffer = Enumerable.Repeat((byte)0xFF, 0x100).ToArray(); var model = new PokemonModel(buffer); var viewPort = new ViewPort("test.txt", model); viewPort.Edit("^bob\"\" \"Hello World!\""); var run = (PCSRun)model.GetNextRun(0); Assert.Equal(13, run.Length); }
public void UnnamedStringAnchorAutomaticallySearchesForPointersToAnchor() { var text = "This is the song that never ends."; var bytes = PCSString.Convert(text).ToArray(); var buffer = new byte[0x200]; Array.Copy(bytes, 0, buffer, 0x32, bytes.Length); // the data itself, positioned at x32 (won't be automatically found on load) Array.Copy(new byte[] { 0x32, 0, 0, 0x08 }, 0, buffer, 0x10, 4); // the pointer to the data. Pointer is aligned, but data is not. var model = new PokemonModel(buffer); var viewPort = new ViewPort("test.gba", model) { Width = 0x10, Height = 0x10 }; // the act of dropping an anchor should search for pointers viewPort.SelectionStart = new Point(2, 3); viewPort.Edit("^\"\" "); Assert.Equal(0x32, model.GetNextRun(0x32).Start); Assert.Single(model.GetNextRun(0x32).PointerSources); }
public void CanWriteNullPointer() { var buffer = new byte[0x200]; var model = new PokemonModel(buffer); var token = new ModelDelta(); model.ObserveRunWritten(token, new PointerRun(0x10)); var format = (Pointer)model.GetNextRun(0x10).CreateDataFormat(model, 0x10); Assert.Equal("null", format.DestinationName); }
public void UnmappedPointerInMetadata_Load_NullPointer() { var pointers = new [] { new StoredUnmappedPointer(0x20, "name") }; var metadata = new StoredMetadata(unmappedPointers: pointers); var model = new PokemonModel(new byte[0x200], metadata, Singletons); var run = model.GetNextRun(0x20); Assert.IsType <PointerRun>(run); Assert.Equal(0x20, run.Start); }
public void FormatClearDoesNotClearAnchorIfUnnamedAnchorIsAtStartOfClear() { var buffer = new byte[0x200]; var model = new PokemonModel(buffer); var token = new ModelDelta(); model.WritePointer(token, 0, 0x10); model.ObserveRunWritten(token, new PointerRun(0)); model.ClearFormat(token, 0x10, 1); Assert.Equal(0x10, model.GetNextRun(0x10).Start); }
public void PointerModelFindsPointersInRange() { var rnd = new Random(0xCafe); var buffer = new byte[0x10000]; // 64KB rnd.NextBytes(buffer); for (int i = 0; i < buffer.Length; i++) { if (buffer[i] == 0x08) { buffer[i] = 0x10; } } // write two specific pointers var model = new PokemonModel(buffer); var token = new ModelDelta(); model.WritePointer(token, 0x204, 0x4050); model.WritePointer(token, 0x4070, 0x101C); model = new PokemonModel(buffer); Assert.Equal(0x204, model.GetNextRun(0).Start); Assert.IsType <PointerRun>(model.GetNextRun(0x206)); Assert.IsType <NoInfoRun>(model.GetNextRun(0x208)); Assert.Single(model.GetNextRun(0x400).PointerSources); Assert.Equal(0x4050, model.GetNextRun(0x4050).Start); Assert.Equal(4, model.GetNextRun(0x4071).Length); }
public void CanUndoDataMove() { var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray(); var model = new PokemonModel(buffer); var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.SelectionStart = new Point(8, 0); viewPort.Edit("<000030>"); viewPort.SelectionStart = new Point(0, 0); viewPort.Edit("^bob\"\" \"Hello World!\""); viewPort.Undo.Execute(); // should undo the entire last edit transaction Assert.Equal(0xFF, model[0]); Assert.Equal(8, model.GetNextRun(0).Start); Assert.Equal(0x30, model.GetNextRun(0x10).Start); Assert.Equal(int.MaxValue, model.GetNextRun(0x31).Start); }
public void TypingTwoHexDigitsIntoPointerWithSpaceCanRemoveFormat() { var model = new PokemonModel(new byte[0x200]); var viewModel = new ViewPort(string.Empty, model); viewModel.Edit("<000100>"); viewModel.SelectionStart = new Point(0, 0); viewModel.Edit("20 "); Assert.Equal(0x20, model[0]); Assert.NotInRange(model.GetNextRun(0).Start, 0, 0x200); }
public void PointerModelMergesDuplicates() { var buffer = new byte[0x20]; var model = new PokemonModel(buffer); var token = new ModelDelta(); model.WritePointer(token, 0x0C, 0x14); model.WritePointer(token, 0x1C, 0x14); model = new PokemonModel(buffer); var run = model.GetNextRun(0x14); Assert.Equal(2, run.PointerSources.Count); }
public void AnchorWithNoNameIsNotValidIfNothingPointsToIt() { var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray(); var model = new PokemonModel(buffer); var viewPort = new ViewPort("test.txt", model) { Width = 0x10, Height = 0x10 }; var errors = new List <string>(); viewPort.OnError += (sender, e) => errors.Add(e); viewPort.Edit("^ "); Assert.Equal(NoInfoRun.NullRun, model.GetNextRun(0)); Assert.Single(errors); Assert.IsType <None>(viewPort[0, 0].Format); errors.Clear(); viewPort.Edit("^\"\" "); Assert.Equal(NoInfoRun.NullRun, model.GetNextRun(0)); Assert.Single(errors); }
public void ClearingAPointerAlsoRemovesItsAnchor() { var data = new byte[0x200]; var model = new PokemonModel(data); var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.Edit("<000100>"); model.ClearFormat(new ModelDelta(), 0x00, 4); Assert.NotInRange(model.GetNextRun(0x00).Start, 0, data.Length); }
public void CanRemoveAnchorWithNoReferences() { var buffer = new byte[0x100]; var model = new PokemonModel(buffer); var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.SelectionStart = new Point(0, 2); viewPort.Edit("^bob ^ "); Assert.Equal(NoInfoRun.NullRun, model.GetNextRun(0)); }
public void CanRecognizeString() { var buffer = new byte[0x100]; var model = new PokemonModel(buffer); var token = new ModelDelta(); var data = PCSString.Convert("Hello World!").ToArray(); Array.Copy(data, 0, buffer, 0x10, data.Length); model.ObserveRunWritten(token, new PCSRun(model, 0x10, data.Length)); var run = (PCSRun)model.GetNextRun(0); Assert.Equal(data.Length, run.Length); }
public void EscapeWhileTypingAnchorCancelsChange() { var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray(); var model = new PokemonModel(buffer); var viewPort = new ViewPort("file.txt", model) { Width = 0x10, Height = 0x10 }; viewPort.Edit("^bob"); // no trailing space: still under edit viewPort.Edit(ConsoleKey.Escape); Assert.IsType <None>(viewPort[0, 0].Format); Assert.Equal(NoInfoRun.NullRun, model.GetNextRun(0)); }
public void CanFindStringsInData() { var buffer = Enumerable.Repeat((byte)0xFF, 0x100).ToArray(); var data = PCSString.Convert("Hello World!").ToArray(); Array.Copy(data, 0, buffer, 0x10, data.Length); var model1 = new PokemonModel(buffer); var token = new ModelDelta(); model1.WritePointer(token, 0x00, 0x10); var model = new PokemonModel(buffer); Assert.IsType <PCSRun>(model.GetNextRun(0x10)); }
public void ArrayLengthUpdatesWhenSourceTableLengthChanges() { // Arrange var data = new byte[0x200]; var model = new PokemonModel(data); // Act ArrayRun.TryParse(model, "[a: b:]names", 0, null, out var table); model.ObserveAnchorWritten(new ModelDelta(), "table", table); ArrayRun.TryParse(model, "[name\"\"8]8", 0x30, null, out var names); model.ObserveAnchorWritten(new ModelDelta(), "names", names); // Assert that the table is now longer based on the names table Assert.Equal(8 * 4, model.GetNextRun(0).Length); }
public void PointersPastEndOfDataDoNotCountAsPointers() { var buffer = Enumerable.Repeat((byte)0xFF, 0x200).ToArray(); buffer[4] = 0x20; buffer[5] = 0x20; buffer[6] = 0x20; buffer[7] = 0x08; // it should realize that the data starting at 4 isn't a pointer // because 202020 is after the end of the data var model = new PokemonModel(buffer); Assert.Equal(int.MaxValue, model.GetNextRun(0).Start); }