IOTests.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. using Lua.IO;
  2. using System.Text;
  3. using NUnit.Framework;
  4. namespace Lua.Tests;
  5. public class IOTests : IDisposable
  6. {
  7. readonly string testDirectory;
  8. readonly FileSystem fileSystem;
  9. public IOTests()
  10. {
  11. testDirectory = Path.Combine(Path.GetTempPath(), $"LuaIOTests_{Guid.NewGuid()}");
  12. Directory.CreateDirectory(testDirectory);
  13. fileSystem = new();
  14. }
  15. public void Dispose()
  16. {
  17. if (Directory.Exists(testDirectory))
  18. {
  19. Directory.Delete(testDirectory, true);
  20. }
  21. }
  22. string GetTestFilePath(string filename)
  23. {
  24. return Path.Combine(testDirectory, filename);
  25. }
  26. [Test]
  27. public async Task TextStream_Write_And_Read_Text()
  28. {
  29. var testFile = GetTestFilePath("text_test.txt");
  30. var testContent = "Hello, World!\nThis is a test.";
  31. // Write text
  32. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Write, CancellationToken.None))
  33. {
  34. await stream.WriteAsync(testContent, CancellationToken.None);
  35. }
  36. // Read text
  37. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Read, CancellationToken.None))
  38. {
  39. var content = await stream.ReadAllAsync(CancellationToken.None);
  40. Assert.That(content, Is.EqualTo(testContent));
  41. }
  42. }
  43. [Test]
  44. public async Task TextStream_ReadLine_Works()
  45. {
  46. var testFile = GetTestFilePath("multiline.txt");
  47. var lines = new[] { "Line 1", "Line 2", "Line 3" };
  48. // Write multiple lines
  49. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Write, CancellationToken.None))
  50. {
  51. await stream.WriteAsync(string.Join("\n", lines), CancellationToken.None);
  52. }
  53. // Read lines one by one
  54. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Read, CancellationToken.None))
  55. {
  56. for (var i = 0; i < lines.Length; i++)
  57. {
  58. var line = await stream.ReadLineAsync(false, CancellationToken.None);
  59. Assert.That(line, Is.EqualTo(lines[i]));
  60. }
  61. // EOF should return null
  62. var eofLine = await stream.ReadLineAsync(false, CancellationToken.None);
  63. Assert.That(eofLine, Is.Null);
  64. }
  65. }
  66. [Test]
  67. public async Task TextStream_ReadString_Works()
  68. {
  69. var testFile = GetTestFilePath("read_string.txt");
  70. var testContent = "Hello, World!";
  71. // Write content
  72. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Write, CancellationToken.None))
  73. {
  74. await stream.WriteAsync(testContent, CancellationToken.None);
  75. }
  76. // Read partial strings
  77. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Read, CancellationToken.None))
  78. {
  79. var part1 = await stream.ReadAsync(5, CancellationToken.None);
  80. Assert.That(part1, Is.EqualTo("Hello"));
  81. var part2 = await stream.ReadAsync(7, CancellationToken.None);
  82. Assert.That(part2, Is.EqualTo(", World"));
  83. var part3 = await stream.ReadAsync(1, CancellationToken.None);
  84. Assert.That(part3, Is.EqualTo("!")); // Only 1 char left
  85. var eof = await stream.ReadAsync(10, CancellationToken.None);
  86. Assert.That(eof, Is.Null);
  87. }
  88. }
  89. [Test]
  90. public async Task Append_Mode_Appends_Content()
  91. {
  92. var testFile = GetTestFilePath("append_test.txt");
  93. // Write initial content
  94. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Write, CancellationToken.None))
  95. {
  96. await stream.WriteAsync("Hello", CancellationToken.None);
  97. }
  98. // Append content
  99. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Append, CancellationToken.None))
  100. {
  101. await stream.WriteAsync(" World", CancellationToken.None);
  102. }
  103. // Read and verify
  104. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Read, CancellationToken.None))
  105. {
  106. var content = await stream.ReadAllAsync(CancellationToken.None);
  107. Assert.That(content, Is.EqualTo("Hello World"));
  108. }
  109. }
  110. [Test]
  111. public async Task Seek_Works_Correctly()
  112. {
  113. var testFile = GetTestFilePath("seek_test.txt");
  114. var testContent = "0123456789";
  115. // Write content
  116. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Write, CancellationToken.None))
  117. {
  118. await stream.WriteAsync(testContent, CancellationToken.None);
  119. }
  120. // Test seeking
  121. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Read, CancellationToken.None))
  122. {
  123. // Seek from beginning
  124. stream.Seek(SeekOrigin.Begin, 5);
  125. var afterBegin = await stream.ReadAsync(3, CancellationToken.None);
  126. Assert.That(afterBegin, Is.EqualTo("567"));
  127. // Seek from current
  128. stream.Seek(SeekOrigin.Current, -2);
  129. var afterCurrent = await stream.ReadAsync(2, CancellationToken.None);
  130. Assert.That(afterCurrent, Is.EqualTo("67"));
  131. // Seek from end
  132. stream.Seek(SeekOrigin.End, -3);
  133. var afterEnd = await stream.ReadAsync(3, CancellationToken.None);
  134. Assert.That(afterEnd, Is.EqualTo("789"));
  135. }
  136. }
  137. [Test]
  138. public async Task FileSystem_Rename_Works()
  139. {
  140. var oldPath = GetTestFilePath("old_name.txt");
  141. var newPath = GetTestFilePath("new_name.txt");
  142. File.WriteAllText(oldPath, "test content");
  143. await fileSystem.Rename(oldPath, newPath, CancellationToken.None);
  144. Assert.That(File.Exists(oldPath), Is.False);
  145. Assert.That(File.Exists(newPath), Is.True);
  146. Assert.That(File.ReadAllText(newPath), Is.EqualTo("test content"));
  147. }
  148. [Test]
  149. public async Task FileSystem_Remove_Works()
  150. {
  151. var testFile = GetTestFilePath("remove_test.txt");
  152. File.WriteAllText(testFile, "test content");
  153. Assert.That(File.Exists(testFile), Is.True);
  154. await fileSystem.Remove(testFile, CancellationToken.None);
  155. Assert.That(File.Exists(testFile), Is.False);
  156. }
  157. [Test]
  158. public void FileSystem_IsReadable_Works()
  159. {
  160. var existingFile = GetTestFilePath("readable.txt");
  161. var nonExistentFile = GetTestFilePath("non_existent.txt");
  162. File.WriteAllText(existingFile, "test");
  163. Assert.That(fileSystem.IsReadable(existingFile), Is.True);
  164. Assert.That(fileSystem.IsReadable(nonExistentFile), Is.False);
  165. }
  166. [Test]
  167. public async Task FileSystem_TempFile_Works()
  168. {
  169. string? tempPath = null;
  170. try
  171. {
  172. using (var tempStream = await fileSystem.OpenTempFileStream(CancellationToken.None))
  173. {
  174. await tempStream.WriteAsync("temp content".AsMemory(), CancellationToken.None);
  175. // Seek and read
  176. tempStream.Seek(SeekOrigin.Begin, 0);
  177. var content = await tempStream.ReadAllAsync(CancellationToken.None);
  178. Assert.That(content, Is.EqualTo("temp content"));
  179. }
  180. }
  181. finally
  182. {
  183. if (tempPath != null && File.Exists(tempPath))
  184. {
  185. File.Delete(tempPath);
  186. }
  187. }
  188. }
  189. [Test]
  190. public void FileSystem_DirectorySeparator_IsValid()
  191. {
  192. var separator = fileSystem.DirectorySeparator;
  193. Assert.That(separator, Is.Not.Null);
  194. Assert.That(separator, Is.Not.Empty);
  195. Assert.That(separator, Is.EqualTo(Path.DirectorySeparatorChar.ToString()));
  196. }
  197. [Test]
  198. public async Task Buffering_Modes_Work()
  199. {
  200. var testFile = GetTestFilePath("buffer_test.txt");
  201. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Write, CancellationToken.None))
  202. {
  203. // Set no buffering
  204. stream.SetVBuf(LuaFileBufferingMode.NoBuffering, 0);
  205. await stream.WriteAsync("No buffer", CancellationToken.None);
  206. // Set line buffering
  207. stream.SetVBuf(LuaFileBufferingMode.LineBuffering, 1024);
  208. await stream.WriteAsync("\nLine buffer", CancellationToken.None);
  209. // Set full buffering
  210. stream.SetVBuf(LuaFileBufferingMode.FullBuffering, 4096);
  211. await stream.WriteAsync("\nFull buffer", CancellationToken.None);
  212. // Explicit flush
  213. await stream.FlushAsync(CancellationToken.None);
  214. }
  215. // Verify content was written
  216. var writtenContent = File.ReadAllText(testFile);
  217. Assert.That(writtenContent, Does.Contain("No buffer"));
  218. Assert.That(writtenContent, Does.Contain("Line buffer"));
  219. Assert.That(writtenContent, Does.Contain("Full buffer"));
  220. }
  221. [Test]
  222. public async Task LuaFileContent_Memory_Variations()
  223. {
  224. var testFile = GetTestFilePath("memory_test.txt");
  225. // Test with char array
  226. var charArray = "Hello from char array".ToCharArray();
  227. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Write, CancellationToken.None))
  228. {
  229. await stream.WriteAsync(charArray, CancellationToken.None);
  230. }
  231. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Read, CancellationToken.None))
  232. {
  233. var content = await stream.ReadAllAsync(CancellationToken.None);
  234. Assert.That(content, Is.EqualTo("Hello from char array"));
  235. }
  236. // Test with partial char array
  237. var longCharArray = "Hello World!!!".ToCharArray();
  238. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Write, CancellationToken.None))
  239. {
  240. await stream.WriteAsync(longCharArray.AsMemory(0, 11), CancellationToken.None); // Only "Hello World"
  241. }
  242. using (var stream = await fileSystem.Open(testFile, LuaFileOpenMode.Read, CancellationToken.None))
  243. {
  244. var content = await stream.ReadAllAsync(CancellationToken.None);
  245. Assert.That(content, Is.EqualTo("Hello World"));
  246. }
  247. }
  248. }