Skip to content

Commit 187a39b

Browse files
committed
Feat: add tests to remaining useful funcs and make read_last_n_lines pass tests
1 parent b775dac commit 187a39b

2 files changed

Lines changed: 99 additions & 7 deletions

File tree

‎helpful_modules/threads_or_useful_funcs.py‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,18 @@ async def read_last_n_lines(filename, n):
341341
position = await f.tell()
342342
lines = []
343343
current_line = []
344-
345344
# Read backwards until we find the last n lines
346345
while position >= 0 and len(lines) < n:
347346
await f.seek(position)
348-
char = await f.read(1)
349-
347+
char = (await f.read(1)).decode()
348+
#print(char, end='')
350349
# Check for newline character
351-
if char == b"\n" and current_line:
352-
# Store the completed line
353-
lines.append(current_line[::-1].decode())
350+
#print(f"{current_line=} {char=} {lines=} ")
351+
if char == "\n":
352+
if len("".join(current_line)) > 0:
353+
# Store the completed line
354+
355+
lines.append("".join(current_line[::-1]))
354356
current_line = []
355357
else:
356358
current_line.append(char)
@@ -359,7 +361,7 @@ async def read_last_n_lines(filename, n):
359361

360362
# Capture the last line if it does not end with a newline
361363
if current_line:
362-
lines.append(current_line[::-1].decode())
364+
lines.append("".join(current_line[::-1]))
363365

364366
# Reverse the lines to get them in the correct order
365367
return lines[::-1][:n]

‎tests/test_helpful_modules/test_threads_or_useful_funcs.py‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import aiofiles
2929
import pyfakefs.fake_filesystem_unittest
3030

31+
from pyfakefs.fake_filesystem_unittest import TestCase
32+
33+
from helpful_modules.threads_or_useful_funcs import read_last_n_lines
3134
from helpful_modules import threads_or_useful_funcs
3235
from tests.mockable_aiofiles import MockableAioFiles
3336
from tests.utils import generate_many_randoms
@@ -354,7 +357,94 @@ def test_secure_fisher_yates_shuffle(self, mock_randbelow):
354357
self.assertNotEqual(my_list, shuffled_list)
355358
self.assertCountEqual(my_list, shuffled_list)
356359
mock_randbelow.assert_called_with(2)
360+
import asyncio
361+
import concurrent.futures
362+
import unittest
363+
364+
from helpful_modules.threads_or_useful_funcs import async_wait_for_future
365+
366+
367+
class TestAsyncWaitForFuture(unittest.IsolatedAsyncioTestCase):
368+
369+
async def test_asyncio_future_returns_result(self):
370+
future = asyncio.Future()
371+
future.set_result("hello")
372+
373+
result = await async_wait_for_future(future)
374+
375+
self.assertEqual(result, "hello")
376+
377+
async def test_asyncio_future_timeout(self):
378+
future = asyncio.Future()
379+
380+
with self.assertRaises(asyncio.TimeoutError):
381+
await async_wait_for_future(future, timeout=0.01)
382+
383+
async def test_concurrent_future_returns_result(self):
384+
future = concurrent.futures.Future()
385+
future.set_result(123)
386+
387+
result = await async_wait_for_future(future, interval=0.001)
388+
389+
self.assertEqual(result, 123)
390+
391+
async def test_invalid_future_type(self):
392+
with self.assertRaises(TypeError):
393+
await async_wait_for_future("not a future")
394+
import asyncio
395+
import concurrent.futures
396+
import unittest
397+
398+
from helpful_modules.threads_or_useful_funcs import async_wait_for_future
399+
400+
401+
class TestAsyncWaitForFuture(unittest.IsolatedAsyncioTestCase):
357402

403+
async def test_asyncio_future_returns_result(self):
404+
future = asyncio.Future()
405+
future.set_result("hello")
406+
407+
result = await async_wait_for_future(future)
408+
409+
self.assertEqual(result, "hello")
410+
411+
async def test_asyncio_future_timeout(self):
412+
future = asyncio.Future()
413+
414+
with self.assertRaises(asyncio.TimeoutError):
415+
await async_wait_for_future(future, timeout=0.01)
416+
417+
async def test_concurrent_future_returns_result(self):
418+
future = concurrent.futures.Future()
419+
future.set_result(123)
420+
421+
result = await async_wait_for_future(future, interval=0.001)
422+
423+
self.assertEqual(result, 123)
424+
425+
async def test_invalid_future_type(self):
426+
with self.assertRaises(TypeError):
427+
await async_wait_for_future("not a future")
428+
429+
430+
431+
class TestReadLastNLines(TestCase, unittest.IsolatedAsyncioTestCase):
432+
433+
def setUp(self):
434+
self.setUpPyfakefs()
435+
436+
async def test_reads_last_lines(self):
437+
self.fs.create_file(
438+
"/tmp/test.txt",
439+
contents="line1\nline2\nline3\nline4\n"
440+
)
441+
442+
result = await read_last_n_lines("/tmp/test.txt", 2)
443+
444+
self.assertEqual(
445+
result,
446+
["line3", "line4"]
447+
)
358448

359449
if __name__ == "__main__":
360450
unittest.main()

0 commit comments

Comments
 (0)