Пример #1
0
        public void ReadFromStreamAsyncCallsOnReadFromStreamInTask()
        {
            Type               calledType    = null;
            Stream             calledStream  = null;
            HttpContentHeaders calledHeaders = null;

            SMediaTypeFormatter formatter = new SMediaTypeFormatter()
            {
                CallBase = true
            };

            formatter.OnReadFromStreamTypeStreamHttpContentHeaders = (type, stream, headers) =>
            {
                calledType    = type;
                calledStream  = stream;
                calledHeaders = headers;
                return(5);
            };

            SHttpContent       content        = new SHttpContent();
            HttpContentHeaders contentHeaders = content.Headers;

            Task <object> createdTask =
                StreamAssert.WriteAndReadResult <Task <object> >(
                    (stream) => { },
                    (stream) => formatter.ReadFromStreamAsync(typeof(int), stream, contentHeaders));

            object readObject = TaskAssert.SucceedsWithResult(createdTask);

            Assert.AreEqual(5, readObject, "ReadFromStreamAsync should have returned this value from stub.");
            Assert.AreEqual(typeof(int), calledType, "OnReadFromStreamAsync was not called or did not pass Type.");
            Assert.IsNotNull(calledStream, "OnReadFromStreamAsync was not called or did not pass Type.");
            Assert.AreSame(contentHeaders, calledHeaders, "OnReadFromStreamAsync was not called or did not pass ContentHeaders.");
        }
Пример #2
0
        public void ReadFromStreamAsyncCallsOnReadFromStreamAsync()
        {
            Type               calledType    = null;
            Stream             calledStream  = null;
            HttpContentHeaders calledHeaders = null;

            SMediaTypeFormatter formatter = new SMediaTypeFormatter()
            {
                CallBase = true
            };

            formatter.OnReadFromStreamAsyncTypeStreamHttpContentHeaders = (type, stream, headers) =>
            {
                calledType    = type;
                calledStream  = stream;
                calledHeaders = headers;
                return(null);
            };
            SHttpContent       content        = new SHttpContent();
            HttpContentHeaders contentHeaders = content.Headers;

            StreamAssert.WriteAndRead(
                (stream) => { },
                (stream) => formatter.ReadFromStreamAsync(typeof(int), stream, contentHeaders));

            Assert.AreEqual(typeof(int), calledType, "OnReadFromStreamAsync was not called or did not pass Type.");
            Assert.IsNotNull(calledStream, "OnReadFromStreamAsync was not called or did not pass Type.");
            Assert.AreSame(contentHeaders, calledHeaders, "OnReadFromStreamAsync was not called or did not pass ContentHeaders.");
        }
Пример #3
0
        public void TestRecreatePKCompressed()
        {
            const string inputArchivePath = @"TestArchives\PKCompressed.w3x";

            using var inputArchive     = MpqArchive.Open(inputArchivePath);
            using var recreatedArchive = MpqArchive.Create(
                      (Stream?)null,
                      inputArchive.GetMpqFiles().ToArray(),
                      (ushort)inputArchive.Header.HashTableSize,
                      inputArchive.Header.BlockSize);

            for (var i = 0; i < inputArchive.Header.BlockTableSize; i++)
            {
                inputArchive.BaseStream.Position     = inputArchive[i].FilePosition;
                recreatedArchive.BaseStream.Position = recreatedArchive[i].FilePosition;

                var size1 = inputArchive[i].CompressedSize;
                var size2 = recreatedArchive[i].CompressedSize;
                StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, size1 > size2 ? size1 : size2);
            }

            inputArchive.BaseStream.Position     = 0;
            recreatedArchive.BaseStream.Position = 0;
            StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, MpqHeader.Size);
        }
Пример #4
0
        public void WriteToStreamAsyncCallsOnWriteToStreamInTask()
        {
            Type               calledType    = null;
            object             calledObj     = null;
            Stream             calledStream  = null;
            HttpContentHeaders calledHeaders = null;
            Task               createdTask   = null;

            SMediaTypeFormatter formatter = new SMediaTypeFormatter()
            {
                CallBase = true
            };

            formatter.OnWriteToStreamTypeObjectStreamHttpContentHeadersTransportContext = (type, obj, stream, headers, context) =>
            {
                calledType    = type;
                calledObj     = obj;
                calledStream  = stream;
                calledHeaders = headers;
            };

            SHttpContent       content        = new SHttpContent();
            HttpContentHeaders contentHeaders = content.Headers;

            StreamAssert.WriteAndRead(
                (stream) => createdTask = formatter.WriteToStreamAsync(typeof(int), 5, stream, contentHeaders, /*transportContext*/ null),
                (stream) => { });

            TaskAssert.Succeeds(createdTask);
            Assert.AreEqual(typeof(int), calledType, "OnWriteToStream was not called or did not pass Type.");
            Assert.AreEqual(5, calledObj, "OnWriteToStream was not called or did not pass the object value.");
            Assert.IsNotNull(calledStream, "OnWriteToStream was not called or did not pass Type.");
            Assert.AreSame(contentHeaders, calledHeaders, "OnWriteToStream was not called or did not pass ContentHeaders.");
        }
Пример #5
0
        internal static void RunStreamRWTest(
            string filePath,
            Type type,
            Encoding?encoding      = null,
            string?readMethodName  = null,
            string writeMethodName = nameof(StreamWriter.Write),
            params object[] additionalReadParameters)
        {
            var readMethod = typeof(StreamReaderExtensions).GetMethod(readMethodName ?? $"Read{type.Name}");

            Assert.IsNotNull(readMethod, $"Could not find extension method to read {type.Name}.");

            var writeMethod = typeof(StreamWriterExtensions).GetMethod(writeMethodName, new[] { typeof(StreamWriter), type });

            Assert.IsNotNull(writeMethod, $"Could not find extension method to write {type.Name}.");

            using var expectedStream = FileProvider.GetFile(filePath);
            using var reader         = new StreamReader(expectedStream, encoding ?? new UTF8Encoding(false, true));
            var parsedFile = readMethod !.Invoke(null, new[] { reader }.Concat(additionalReadParameters).ToArray());

            Assert.AreEqual(type, parsedFile.GetType());

            using var actualStream = new MemoryStream();
            using var writer       = new StreamWriter(actualStream, reader.CurrentEncoding);
            writeMethod !.Invoke(null, new[] { writer, parsedFile });
            writer.Flush();

            StreamAssert.AreEqualText(expectedStream, actualStream, true);
        }
Пример #6
0
        public void TestDefaultMapInfo()
        {
            // Get World Editor default info file.
            using var defaultInfoStream = File.OpenRead(TestDataProvider.GetFile(@"MapFiles\DefaultMapFiles\war3map.w3i"));
            var defaultMapInfo = MapInfo.Parse(defaultInfoStream, true);

            defaultInfoStream.Position = 0;

            // Get War3Net default info file.
            var mapInfo = MapInfo.Default;

            // Update defaults that are different.
            mapInfo.EditorVersion  = 6072;
            mapInfo.ScriptLanguage = ScriptLanguage.Jass;

            var player0 = mapInfo.GetPlayerData(0);

            player0.PlayerName    = "TRIGSTR_001";
            player0.StartPosition = defaultMapInfo.GetPlayerData(0).StartPosition;
            mapInfo.SetPlayerData(player0);

            var team0 = mapInfo.GetForceData(0);

            team0.ForceName = "TRIGSTR_002";
            team0.IncludeAllPlayers();
            mapInfo.SetForceData(team0);

            // Compare files.
            using var mapInfoStream = new MemoryStream();
            mapInfo.SerializeTo(mapInfoStream, true);
            mapInfoStream.Position = 0;

            StreamAssert.AreEqual(defaultInfoStream, mapInfoStream);
        }
Пример #7
0
        public void TestDefaultMapEnvironment()
        {
            // Get World Editor default environment file.
            using var defaultEnvironmentStream = File.OpenRead(TestDataProvider.GetFile(@"MapFiles\DefaultMapFiles\war3map.w3e"));
            var defaultMapEnvironment = MapEnvironment.Parse(defaultEnvironmentStream, true);

            defaultEnvironmentStream.Position = 0;

            // Get War3Net default environment file.
            var mapEnvironment = MapEnvironment.Default;

            // Update defaults that are different.
            var tileEnumerator = defaultMapEnvironment.GetEnumerator();

            foreach (var tile in mapEnvironment)
            {
                tileEnumerator.MoveNext();
                tile.Variation      = tileEnumerator.Current.Variation;
                tile.CliffVariation = tileEnumerator.Current.CliffVariation;
            }

            // Compare files.
            using var mapEnvironmentStream = new MemoryStream();
            mapEnvironment.SerializeTo(mapEnvironmentStream, true);
            mapEnvironmentStream.Position = 0;

            StreamAssert.AreEqual(defaultEnvironmentStream, mapEnvironmentStream);
        }
Пример #8
0
        internal static void RunStreamRWTest(
            string filePath,
            Type type,
            string writeMethodName)
        {
            var readMethod = typeof(StreamReaderExtensions).GetMethod($"Read{type.Name}");

            Assert.IsNotNull(readMethod, $"Could not find extension method to read {type.Name}.");

            var writeMethod = typeof(StreamWriterExtensions).GetMethod(writeMethodName, new[] { typeof(StreamWriter), type });

            Assert.IsNotNull(writeMethod, $"Could not find extension method to write {type.Name}.");

            using var expectedStream = MpqFile.OpenRead(filePath);
            using var reader         = new StreamReader(expectedStream, new UTF8Encoding(false, true));
            var parsedFile = readMethod !.Invoke(null, new[] { reader });

            Assert.AreEqual(type, parsedFile !.GetType());

            using var actualStream = new MemoryStream();
            using var writer       = new StreamWriter(actualStream, reader.CurrentEncoding);
            writeMethod !.Invoke(null, new[] { writer, parsedFile });
            writer.Flush();

            StreamAssert.AreEqualText(expectedStream, actualStream, true);
        }
        public void NewToOld()
        {
            var oldMsg = new OldRemoveSubscription("the message", new Uri("http://bob/phil"));
            var oldold = Factory.ConvertToOldRemoveSubscription(oldMsg);

            using (var newStream = new MemoryStream())
            {
                PlainFormatter.Serialize(newStream, oldold);

                newStream.Position = 0;

                using (var oldStream = new MemoryStream())
                {
                    using (var str = File.OpenRead(_pathToFile))
                    {
                        var buff = new byte[str.Length];
                        str.Read(buff, 0, buff.Length);
                        oldStream.Write(buff, 0, buff.Length);
                    }

                    var newFileName = ".\\new-{0}.txt".FormatWith(oldMsg.GetType().Name);
                    if (File.Exists(newFileName))
                    {
                        File.Delete(newFileName);
                    }
                    using (var fs = File.OpenWrite(newFileName))
                    {
                        fs.Write(newStream.ToArray(), 0, newStream.ToArray().Length);
                    }

                    StreamAssert.AreEqual(oldStream, newStream);
                }
            }
        }
        private static void TestParseMapCustomTextTriggers(string mapCustomTextTriggersFilePath)
        {
            using var original  = FileProvider.GetFile(mapCustomTextTriggersFilePath);
            using var recreated = new MemoryStream();

            MapCustomTextTriggers.Parse(original, true).SerializeTo(recreated, true);
            StreamAssert.AreEqual(original, recreated, true);
        }
Пример #11
0
        public void TestParseMapDoodads(string mapDoodadsFilePath)
        {
            using var original  = FileProvider.GetFile(mapDoodadsFilePath);
            using var recreated = new MemoryStream();

            MapDoodads.Parse(original, true).SerializeTo(recreated, true);
            StreamAssert.AreEqual(original, recreated, true);
        }
Пример #12
0
        public void TestParseMapEnvironment(string environmentFilePath)
        {
            using var original  = FileProvider.GetFile(environmentFilePath);
            using var recreated = new MemoryStream();

            MapEnvironment.Parse(original, true).SerializeTo(recreated, true);
            StreamAssert.AreEqual(original, recreated, true);
        }
Пример #13
0
        public void TestParseMapInfo(string mapInfoFilePath)
        {
            using var recreated = new MemoryStream();
            using var original  = File.OpenRead(mapInfoFilePath);

            MapInfo.Parse(original, true).SerializeTo(recreated, true);
            StreamAssert.AreEqual(original, recreated, true);
        }
Пример #14
0
        public void TestParsePathingMap(string pathingMapFile)
        {
            using var original  = FileProvider.GetFile(pathingMapFile);
            using var recreated = new MemoryStream();

            PathingMap.Parse(original, true).SerializeTo(recreated, true);
            StreamAssert.AreEqual(original, recreated, true);
        }
Пример #15
0
        public void TestParseCampaignUnitObjectData(string campaignUnitObjectDataFilePath)
        {
            using var original  = FileProvider.GetFile(campaignUnitObjectDataFilePath);
            using var recreated = new MemoryStream();

            CampaignUnitObjectData.Parse(original, true).SerializeTo(recreated, true);
            StreamAssert.AreEqual(original, recreated, true, true);
        }
Пример #16
0
        public void TestPathingMap(string pathingMapFile)
        {
            using var fileStream = File.OpenRead(pathingMapFile);
            var pathingMap = PathingMap.Parse(fileStream, true);

            using var memoryStream = new MemoryStream();
            pathingMap.SerializeTo(memoryStream, true);

            StreamAssert.AreEqual(fileStream, memoryStream, true);
        }
Пример #17
0
        public void TestParseMapUnits(string mapUnitsFilePath)
        {
            using var recreated = new MemoryStream();
            using var original  = File.OpenRead(mapUnitsFilePath);

            var data = MapUnits.Parse(original, true);

            Assert.AreEqual(original.Length, original.Position);

            data.SerializeTo(recreated, true);

            StreamAssert.AreEqual(original, recreated, true);
        }
Пример #18
0
        private void TestParseObjectDataInternal(string objectDataFilePath, bool fromCampaign)
        {
            using var original  = MpqFile.OpenRead(objectDataFilePath);
            using var recreated = new MemoryStream();

            using var objectDataReader = new BinaryReader(original);
            var objectData = objectDataReader.ReadObjectData(fromCampaign);

            using var objectDataWriter = new BinaryWriter(recreated);
            objectDataWriter.Write(objectData);

            StreamAssert.AreEqual(original, recreated, true, true);
        }
Пример #19
0
        public void TestStoreThenRetrieveFile(string filename)
        {
            var fileStream = File.OpenRead(filename);
            var mpqFile    = MpqFile.New(fileStream, filename, true);
            var archive    = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            });

            var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream  = openedArchive.OpenFile(filename);

            StreamAssert.AreEqual(fileStream, openedStream, true);
        }
Пример #20
0
        public void TestStoreThenRetrieveFileWithFlags(string fileName, MpqFileFlags flags)
        {
            using var fileStream = File.OpenRead(fileName);
            var mpqFile = MpqFile.New(fileStream, fileName, true);

            mpqFile.TargetFlags = flags;
            using var archive   = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            }, new MpqArchiveCreateOptions { BlockSize = BlockSize });

            using var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream = openedArchive.OpenFile(fileName);

            StreamAssert.AreEqual(fileStream, openedStream, true);
        }
Пример #21
0
        public void TestParseMapDoodads(string mapDoodadsFilePath)
        {
            using var recreated = new MemoryStream();
            using var original  = File.OpenRead(mapDoodadsFilePath);

            var data = MapDoodads.Parse(original, true);

            Assert.AreEqual(original.Length, original.Position);

            data.SerializeTo(recreated, true);

            // TODO: skip header, since it's ignored in SerializeTo method (so always saves as TFT version)
            //if (data.)

            StreamAssert.AreEqual(original, recreated, true);
        }
Пример #22
0
        public void TestStoreThenRetrieveFile(string filename)
        {
            var fileStream = File.OpenRead(filename);
            // var mpqFile = new MpqKnownFile(filename, fileStream, MpqFileFlags.Exists, MpqLocale.Neutral, true);
            var mpqFile = MpqFile.New(fileStream, filename);
            var archive = MpqArchive.Create(new MemoryStream(), new List <MpqFile>()
            {
                mpqFile
            });

            var openedArchive = MpqArchive.Open(archive.BaseStream);
            var openedStream  = openedArchive.OpenFile(filename);

            fileStream.Position = 0;
            StreamAssert.AreEqual(fileStream, openedStream);
        }
Пример #23
0
        internal static void RunBinaryRWTest(
            string filePath,
            Type type,
            string?readMethodName = null,
            object?[]?additionalReadParameters  = null,
            object?[]?additionalWriteParameters = null)
        {
            var expectedReadTypes = new[] { typeof(BinaryReader) };

            if (additionalReadParameters is not null)
            {
                expectedReadTypes = expectedReadTypes.Concat(additionalReadParameters.Select(p => p.GetType())).ToArray();
            }

            var readMethod = typeof(BinaryReaderExtensions).GetMethod(readMethodName ?? $"Read{type.Name}", expectedReadTypes);

            Assert.IsNotNull(readMethod, $"Could not find extension method to read {type.Name}.");

            var expectedWriteTypes = new[] { typeof(BinaryWriter), type };

            if (additionalWriteParameters is not null)
            {
                expectedWriteTypes = expectedWriteTypes.Concat(additionalWriteParameters.Select(p => p.GetType())).ToArray();
            }

            var writeMethod = typeof(BinaryWriterExtensions).GetMethod(nameof(BinaryWriter.Write), expectedWriteTypes);

            Assert.IsNotNull(writeMethod, $"Could not find extension method to write {type.Name}.");

            using var expectedStream = FileProvider.GetFile(filePath);
            using var reader         = new BinaryReader(expectedStream);
            var parsedFile = readMethod !.Invoke(null, new object?[] { reader }.Concat(additionalReadParameters ?? Array.Empty <object?[]>()).ToArray());

            Assert.AreEqual(type, parsedFile.GetType());

            using var actualStream = new MemoryStream();
            using var writer       = new BinaryWriter(actualStream);
            writeMethod !.Invoke(null, new object?[] { writer, parsedFile }.Concat(additionalWriteParameters ?? Array.Empty <object?[]>()).ToArray());
            writer.Flush();

            StreamAssert.AreEqual(expectedStream, actualStream, true);
        }
Пример #24
0
        public void ReadFromStreamAsyncRoundTripsWriteToStreamAsync()
        {
            TestJsonMediaTypeFormatter formatter      = new TestJsonMediaTypeFormatter();
            HttpContentHeaders         contentHeaders = new StringContent(string.Empty).Headers;

            TestDataAssert.Execute(
                TestData.RepresentativeValueAndRefTypeTestDataCollection,
                (type, obj) =>
            {
                bool canSerialize = IsTypeSerializableWithJsonSerializer(type, obj) && HttpTestData.CanRoundTrip(type);
                if (canSerialize)
                {
                    object readObj = null;
                    StreamAssert.WriteAndRead(
                        (stream) => TaskAssert.Succeeds(formatter.WriteToStreamAsync(type, obj, stream, contentHeaders, /*transportContext*/ null)),
                        (stream) => readObj = TaskAssert.SucceedsWithResult(formatter.ReadFromStreamAsync(type, stream, contentHeaders)));
                    TestDataAssert.AreEqual(obj, readObj, "Failed to round trip object.");
                }
            });
        }
Пример #25
0
        public void ReadFromStreamRoundTripsWriteToStreamUsingDataContractSerializer()
        {
            TestXmlMediaTypeFormatter formatter      = new TestXmlMediaTypeFormatter();
            HttpContentHeaders        contentHeaders = new StringContent(string.Empty).Headers;

            TestDataAssert.Execute(
                TestData.ValueAndRefTypeTestDataCollection,
                (type, obj) =>
            {
                bool canSerialize = IsSerializableWithDataContractSerializer(type, obj) && HttpTestData.CanRoundTrip(type);
                if (canSerialize)
                {
                    formatter.SetSerializer(type, new DataContractSerializer(type));

                    object readObj = null;
                    StreamAssert.WriteAndRead(
                        (stream) => formatter.WriteToStream(type, obj, stream, contentHeaders, /*transportContext*/ null),
                        (stream) => readObj = formatter.ReadFromStream(type, stream, contentHeaders));
                    TestDataAssert.AreEqual(obj, readObj, "Failed to round trip object");
                }
            });
        }
Пример #26
0
        public void TestRecreatePKCompressed()
        {
            var inputArchivePath = TestDataProvider.GetPath(@"Maps\PKCompressed.w3x");

            using var inputArchive     = MpqArchive.Open(inputArchivePath);
            using var recreatedArchive = MpqArchive.Create((Stream?)null, inputArchive.GetMpqFiles().ToArray(), new MpqArchiveCreateOptions { BlockSize = inputArchive.Header.BlockSize, HashTableSize = (ushort)inputArchive.Header.HashTableSize, ListFileCreateMode = MpqFileCreateMode.None, AttributesCreateMode = MpqFileCreateMode.None });

            for (var i = 0; i < inputArchive.Header.BlockTableSize; i++)
            {
                inputArchive.BaseStream.Position     = inputArchive[i].FilePosition;
                recreatedArchive.BaseStream.Position = recreatedArchive[i].FilePosition;

                // var size1 = inputArchive[i].CompressedSize;
                // var size2 = recreatedArchive[i].CompressedSize;
                // StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, size1 > size2 ? size1 : size2);
                StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream);
            }

            inputArchive.BaseStream.Position     = 0;
            recreatedArchive.BaseStream.Position = 0;
            StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, MpqHeader.Size);
        }
Пример #27
0
        public void TestParseMapUnits(string mapUnitsFilePath)
        {
            using var recreated = new MemoryStream();
            using var original  = File.OpenRead(mapUnitsFilePath);

            var data = MapUnits.Parse(original, true);

            Assert.AreEqual(original.Length, original.Position);

            data.SerializeTo(recreated, true);

            original.Position = 4;
            using (var reader = new BinaryReader(original, new UTF8Encoding(false, true), true))
            {
                var version = (MapWidgetsVersion)reader.ReadUInt32();
                if (version != MapWidgetsVersion.TFT)
                {
                    // Can't compare streams, because serialize always saves as TFT, which sets header version to 8 and has additional data per unit.
                    return;
                }
            }

            StreamAssert.AreEqual(original, recreated, true);
        }
Пример #28
0
        public void ReadFromStreamRoundTripsWriteToStreamUsingXmlSerializer()
        {
            TestXmlMediaTypeFormatter formatter      = new TestXmlMediaTypeFormatter();
            HttpContentHeaders        contentHeaders = new StringContent(string.Empty).Headers;

            // Excludes ReferenceDataContractType tests because XmlSerializer cannot handle circular references
            TestDataAssert.Execute(
                TestData.ValueAndRefTypeTestDataCollection.Where((td) => !(typeof(RefTypeTestData <ReferenceDataContractType>).IsAssignableFrom(td.GetType()))),
                (type, obj) =>
            {
                bool canSerialize = IsSerializableWithXmlSerializer(type, obj) && HttpTestData.CanRoundTrip(type);

                if (canSerialize)
                {
                    formatter.SetSerializer(type, new XmlSerializer(type));

                    object readObj = null;
                    StreamAssert.WriteAndRead(
                        (stream) => formatter.WriteToStream(type, obj, stream, contentHeaders, /*transportContext*/ null),
                        (stream) => readObj = formatter.ReadFromStream(type, stream, contentHeaders));
                    TestDataAssert.AreEqual(obj, readObj, "Failed to round trip object");
                }
            });
        }
Пример #29
0
        public void TestRecreateArchive(string inputArchivePath, bool loadListFile)
        {
            using var inputArchive = MpqArchive.Open(inputArchivePath, loadListFile);
            if (loadListFile && !inputArchive.FileExists(ListFile.FileName))
            {
                return;
            }

            var mpqFiles = inputArchive.GetMpqFiles().ToArray();

            using var recreatedArchive = MpqArchive.Create((Stream?)null, mpqFiles, new MpqArchiveCreateOptions { BlockSize = inputArchive.Header.BlockSize, ListFileCreateMode = MpqFileCreateMode.None, AttributesCreateMode = MpqFileCreateMode.None });

            // TODO: fix assumption that recreated archive's hashtable cannot be smaller than original
            // TODO: fix assumption of how recreated blocktable's entries are laid out relative to input mpqFiles array? (aka: replace the 'offset' variable)
            var offsetPerUnknownFile  = (recreatedArchive.HashTable.Size / inputArchive.HashTable.Size) - 1;
            var mpqEncryptedFileCount = mpqFiles.Where(mpqFile => mpqFile.IsFilePositionFixed).Count();
            var offset = mpqEncryptedFileCount * (offsetPerUnknownFile + 1);

            mpqEncryptedFileCount = 0;
            for (var index = 0; index < mpqFiles.Length; index++)
            {
                var      mpqFile = mpqFiles[index];
                MpqEntry?inputEntry;
                if (mpqFile is MpqKnownFile knownFile)
                {
                    inputEntry = inputArchive.GetMpqEntries(knownFile.FileName).FirstOrDefault();
                }
                else if (mpqFile is MpqUnknownFile unknownFile)
                {
                    inputArchive.TryGetEntryFromHashTable(mpqFile.HashIndex & inputArchive.HashTable.Mask, out inputEntry);
                }
                else if (mpqFile is MpqOrphanedFile orphanedFile)
                {
                    // TODO
                    throw new NotSupportedException("found orphaned mpqfile");
                }
                else
                {
                    throw new NotImplementedException();
                }

                var blockIndex = index + (int)offset;
                if (mpqFile.IsFilePositionFixed)
                {
                    blockIndex = mpqEncryptedFileCount * ((int)offsetPerUnknownFile + 1);
                    mpqEncryptedFileCount++;
                }

                var recreatedEntry = recreatedArchive[blockIndex];

                if (inputEntry is not null)
                {
                    if (!mpqFile.MpqStream.CanBeDecrypted)
                    {
                        // Check if both files have the same encryption seed.
                        Assert.IsTrue(!mpqFile.TargetFlags.HasFlag(MpqFileFlags.BlockOffsetAdjustedKey) || inputEntry.FileOffset == recreatedEntry.FileOffset);

                        inputArchive.BaseStream.Position     = inputEntry.FilePosition;
                        recreatedArchive.BaseStream.Position = recreatedEntry.FilePosition;

                        var size1 = inputEntry.CompressedSize;
                        var size2 = recreatedEntry.CompressedSize;
                        StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, size1 > size2 ? size1 : size2);
                    }
                    else
                    {
                        using var inputStream     = inputArchive.OpenFile(inputEntry);
                        using var recreatedStream = recreatedArchive.OpenFile(recreatedEntry);

                        StreamAssert.AreEqual(inputStream, recreatedStream, mpqFile is MpqKnownFile known ? known.FileName : "<unknown file>");
                    }
                }
                else
                {
                    Assert.IsFalse(recreatedEntry.Flags.HasFlag(MpqFileFlags.Exists));
                }

                if (mpqFile is MpqUnknownFile && !mpqFile.IsFilePositionFixed)
                {
                    offset += offsetPerUnknownFile;
                }
            }
        }