diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 137dd29..8c4345d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -23,3 +23,6 @@ jobs: - name: Install run: make install + + - name: Test + run: make test diff --git a/.gitignore b/.gitignore index cd17d8a..ea5dc35 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ venv *.egg-info -build \ No newline at end of file +build +__pycache__ \ No newline at end of file diff --git a/Makefile b/Makefile index 9fcce4d..57a6131 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,14 @@ endif python3 -m venv venv $(VENV) pip install -r requirements.txt +install-cli: + pip install . + +test: + python -m unittest discover -s tests + transcribe: install $(VENV) python transcribe_me/main.py transcribe-install: install - $(VENV) python transcribe_me/main.py install - -install-cli: - pip install . \ No newline at end of file + $(VENV) python transcribe_me/main.py install \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_main.py b/tests/test_main.py new file mode 100644 index 0000000..c1742ed --- /dev/null +++ b/tests/test_main.py @@ -0,0 +1,101 @@ +import unittest +from unittest.mock import patch, mock_open +import argparse +from transcribe_me import main + +class MockAudioSegment: + def __init__(self, length): + self.length = length + + def __len__(self): + return self.length + + def __getitem__(self, index): + return self + + def export(self, *args, **kwargs): + pass + +class MockTranscription: + def __init__(self, text): + self.text = text + +class MockAnthropic: + class Messages: + def create(self, *args, **kwargs): + return 'summary' + messages = Messages() + +class TestMain(unittest.TestCase): + + @patch('os.path.splitext') + @patch('transcribe_me.main.AudioSegment.from_file') + def test_split_audio(self, mock_from_file, mock_splitext): + mock_splitext.return_value = ('file', '.mp3') + mock_from_file.return_value = MockAudioSegment(1000) + result = main.split_audio('file.mp3') + self.assertEqual(result, ['file_part1.mp3']) + + @patch('openai.audio.transcriptions.create') + @patch('builtins.open', new_callable=mock_open, read_data="data") + def test_transcribe_chunk(self, mock_open, mock_create): + mock_transcription = MockTranscription('transcription') + mock_create.return_value = mock_transcription + result = main.transcribe_chunk('file.mp3') + self.assertEqual(result, 'transcription') + + @patch('os.remove') + @patch('transcribe_me.main.split_audio') + @patch('transcribe_me.main.transcribe_chunk') + @patch('builtins.open', new_callable=mock_open) + def test_transcribe_audio(self, mock_open, mock_transcribe_chunk, mock_split_audio, mock_remove): + mock_split_audio.return_value = ['file_part1.mp3'] + mock_transcription = MockTranscription('transcription') + mock_transcribe_chunk.return_value = mock_transcription + main.transcribe_audio('file.mp3', 'output.txt') + mock_open.assert_called_with('output.txt', 'w', encoding='utf-8') + mock_remove.assert_called_with('file_part1.mp3') + + # @patch('transcribe_me.main.anthropic.Anthropic', new=MockAnthropic()) + # def test_generate_summary_openai(self): + # model_config = { + # "temperature": 0.1, + # "max_tokens": 2048, + # "model": "gpt-4", + # "system_prompt": "Generate a summary with key points in bold and a Next Steps section, use Markdown, be a concise tech expert but kind to non-technical readers.", + # } + # result = main.generate_summary('transcription', model_config) + # self.assertEqual(result, 'summary') + + # @patch('anthropic.Anthropic') + # def test_generate_summary_anthropic(self, mock_anthropic): + # mock_anthropic.return_value = 'summary' + # model_config = { + # "temperature": 0.1, + # "max_tokens": 2048, + # "model": "claude-3-sonnet-20240229", + # "system_prompt": "Generate a summary with key points in bold and a Next Steps section, use Markdown, be a concise tech expert but kind to non-technical readers.", + # } + # result = main.generate_summary('transcription', model_config) + # self.assertEqual(result, 'summary') + + # @patch('argparse.ArgumentParser.parse_args') + # @patch('os.makedirs') + # @patch('os.listdir') + # @patch('os.path.exists') + # @patch('transcribe_me.main.transcribe_audio') + # @patch('transcribe_me.main.generate_summary') + # @patch('builtins.open', new_callable=mock_open, read_data="data") + # def test_main(self, mock_open, mock_generate_summary, mock_transcribe_audio, mock_exists, mock_listdir, mock_makedirs, mock_parse_args): + # mock_parse_args.return_value = argparse.Namespace(command=None, input='input', output='output') + # mock_listdir.return_value = ['file1', 'file2'] + # mock_exists.side_effect = [False, False, True, True] + # mock_generate_summary.return_value = 'summary' + # main.main() + # mock_makedirs.assert_called() + # mock_transcribe_audio.assert_called() + # mock_generate_summary.assert_called() + # mock_open.assert_called() + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/transcribe_me/main.py b/transcribe_me/main.py index 55446cb..9f1babd 100644 --- a/transcribe_me/main.py +++ b/transcribe_me/main.py @@ -1,8 +1,7 @@ import argparse import os from glob import glob -from typing import Tuple, Dict, Any -import sys +from typing import Dict, Any import anthropic import openai