Spaces:
Sleeping
Sleeping
| import json | |
| import os | |
| from unittest.mock import patch | |
| import openai | |
| import pytest | |
| from dotenv import load_dotenv | |
| # from translation_agent.utils import find_sentence_starts | |
| from translation_agent.utils import get_completion | |
| from translation_agent.utils import num_tokens_in_string | |
| from translation_agent.utils import one_chunk_improve_translation | |
| from translation_agent.utils import one_chunk_initial_translation | |
| from translation_agent.utils import one_chunk_reflect_on_translation | |
| from translation_agent.utils import one_chunk_translate_text | |
| load_dotenv() | |
| client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
| def test_get_completion_json_mode_api_call(): | |
| # Set up the test data | |
| prompt = "What is the capital of France in json?" | |
| system_message = "You are a helpful assistant." | |
| model = "gpt-4-turbo" | |
| temperature = 0.3 | |
| json_mode = True | |
| # Call the function with JSON_mode=True | |
| result = get_completion( | |
| prompt, system_message, model, temperature, json_mode | |
| ) | |
| # Assert that the result is not None | |
| assert result is not None | |
| # Assert that it can be transformed to dictionary (json) | |
| assert isinstance(json.loads(result), dict) | |
| def test_get_completion_non_json_mode_api_call(): | |
| # Set up the test data | |
| prompt = "What is the capital of France?" | |
| system_message = "You are a helpful assistant." | |
| model = "gpt-4-turbo" | |
| temperature = 0.3 | |
| json_mode = False | |
| # Call the function with JSON_mode=False | |
| result = get_completion( | |
| prompt, system_message, model, temperature, json_mode | |
| ) | |
| # Assert that the result is not None | |
| assert result is not None | |
| # Assert that the result has the expected response format | |
| assert isinstance(result, str) | |
| def test_one_chunk_initial_translation(): | |
| # Define test data | |
| source_lang = "English" | |
| target_lang = "Spanish" | |
| source_text = "Hello, how are you?" | |
| expected_translation = "Hola, ¿cómo estás?" | |
| # Mock the get_completion_content function | |
| with patch( | |
| "translation_agent.utils.get_completion" | |
| ) as mock_get_completion: | |
| mock_get_completion.return_value = expected_translation | |
| # Call the function with test data | |
| translation = one_chunk_initial_translation( | |
| source_lang, target_lang, source_text | |
| ) | |
| # Assert the expected translation is returned | |
| assert translation == expected_translation | |
| # Assert the get_completion_content function was called with the correct arguments | |
| expected_system_message = f"You are an expert linguist, specializing in translation from {source_lang} to {target_lang}." | |
| expected_prompt = f"""This is an {source_lang} to {target_lang} translation, please provide the {target_lang} translation for this text. \ | |
| Do not provide any explanations or text apart from the translation. | |
| {source_lang}: {source_text} | |
| {target_lang}:""" | |
| mock_get_completion.assert_called_once_with( | |
| expected_prompt, system_message=expected_system_message | |
| ) | |
| def test_one_chunk_reflect_on_translation(): | |
| # Define test data | |
| source_lang = "English" | |
| target_lang = "Spanish" | |
| country = "Mexico" | |
| source_text = "This is a sample source text." | |
| translation_1 = "Este es un texto de origen de muestra." | |
| # Define the expected reflection | |
| expected_reflection = "The translation is accurate and conveys the meaning of the source text well. However, here are a few suggestions for improvement:\n\n1. Consider using 'texto fuente' instead of 'texto de origen' for a more natural translation of 'source text'.\n2. Add a definite article before 'texto fuente' to improve fluency: 'Este es un texto fuente de muestra.'\n3. If the context allows, you could also use 'texto de ejemplo' as an alternative translation for 'sample text'." | |
| # Mock the get_completion_content function | |
| with patch( | |
| "translation_agent.utils.get_completion" | |
| ) as mock_get_completion: | |
| mock_get_completion.return_value = expected_reflection | |
| # Call the function with test data | |
| reflection = one_chunk_reflect_on_translation( | |
| source_lang, target_lang, source_text, translation_1, country | |
| ) | |
| # Assert that the reflection matches the expected reflection | |
| assert reflection == expected_reflection | |
| # Assert that the get_completion_content function was called with the correct arguments | |
| expected_prompt = f"""Your task is to carefully read a source text and a translation from {source_lang} to {target_lang}, and then give constructive criticism and helpful suggestions to improve the translation. \ | |
| The final style and tone of the translation should match the style of {target_lang} colloquially spoken in {country}. | |
| The source text and initial translation, delimited by XML tags <SOURCE_TEXT></SOURCE_TEXT> and <TRANSLATION></TRANSLATION>, are as follows: | |
| <SOURCE_TEXT> | |
| {source_text} | |
| </SOURCE_TEXT> | |
| <TRANSLATION> | |
| {translation_1} | |
| </TRANSLATION> | |
| When writing suggestions, pay attention to whether there are ways to improve the translation's \n\ | |
| (i) accuracy (by correcting errors of addition, mistranslation, omission, or untranslated text),\n\ | |
| (ii) fluency (by applying {target_lang} grammar, spelling and punctuation rules, and ensuring there are no unnecessary repetitions),\n\ | |
| (iii) style (by ensuring the translations reflect the style of the source text and takes into account any cultural context),\n\ | |
| (iv) terminology (by ensuring terminology use is consistent and reflects the source text domain; and by only ensuring you use equivalent idioms {target_lang}).\n\ | |
| Write a list of specific, helpful and constructive suggestions for improving the translation. | |
| Each suggestion should address one specific part of the translation. | |
| Output only the suggestions and nothing else.""" | |
| expected_system_message = f"You are an expert linguist specializing in translation from {source_lang} to {target_lang}. \ | |
| You will be provided with a source text and its translation and your goal is to improve the translation." | |
| mock_get_completion.assert_called_once_with( | |
| expected_prompt, system_message=expected_system_message | |
| ) | |
| def example_data(): | |
| return { | |
| "source_lang": "English", | |
| "target_lang": "Spanish", | |
| "source_text": "This is a sample source text.", | |
| "translation_1": "Esta es una traducción de ejemplo.", | |
| "reflection": "The translation is accurate but could be more fluent.", | |
| } | |
| def test_one_chunk_improve_translation(mock_get_completion, example_data): | |
| # Set up the mock return value for get_completion_content | |
| mock_get_completion.return_value = ( | |
| "Esta es una traducción de ejemplo mejorada." | |
| ) | |
| # Call the function with the example data | |
| result = one_chunk_improve_translation( | |
| example_data["source_lang"], | |
| example_data["target_lang"], | |
| example_data["source_text"], | |
| example_data["translation_1"], | |
| example_data["reflection"], | |
| ) | |
| # Assert that the function returns the expected translation | |
| assert result == "Esta es una traducción de ejemplo mejorada." | |
| # Assert that get_completion was called with the expected arguments | |
| expected_prompt = f"""Your task is to carefully read, then edit, a translation from {example_data["source_lang"]} to {example_data["target_lang"]}, taking into | |
| account a list of expert suggestions and constructive criticisms. | |
| The source text, the initial translation, and the expert linguist suggestions are delimited by XML tags <SOURCE_TEXT></SOURCE_TEXT>, <TRANSLATION></TRANSLATION> and <EXPERT_SUGGESTIONS></EXPERT_SUGGESTIONS> \ | |
| as follows: | |
| <SOURCE_TEXT> | |
| {example_data["source_text"]} | |
| </SOURCE_TEXT> | |
| <TRANSLATION> | |
| {example_data["translation_1"]} | |
| </TRANSLATION> | |
| <EXPERT_SUGGESTIONS> | |
| {example_data["reflection"]} | |
| </EXPERT_SUGGESTIONS> | |
| Please take into account the expert suggestions when editing the translation. Edit the translation by ensuring: | |
| (i) accuracy (by correcting errors of addition, mistranslation, omission, or untranslated text), | |
| (ii) fluency (by applying Spanish grammar, spelling and punctuation rules and ensuring there are no unnecessary repetitions), \ | |
| (iii) style (by ensuring the translations reflect the style of the source text) | |
| (iv) terminology (inappropriate for context, inconsistent use), or | |
| (v) other errors. | |
| Output only the new translation and nothing else.""" | |
| expected_system_message = f"You are an expert linguist, specializing in translation editing from English to Spanish." | |
| mock_get_completion.assert_called_once_with( | |
| expected_prompt, expected_system_message | |
| ) | |
| def test_one_chunk_translate_text(mocker): | |
| # Define test data | |
| source_lang = "English" | |
| target_lang = "Spanish" | |
| country = "Mexico" | |
| source_text = "Hello, how are you?" | |
| translation_1 = "Hola, ¿cómo estás?" | |
| reflection = "The translation looks good, but it could be more formal." | |
| translation2 = "Hola, ¿cómo está usted?" | |
| # Mock the helper functions | |
| mock_initial_translation = mocker.patch( | |
| "translation_agent.utils.one_chunk_initial_translation", | |
| return_value=translation_1, | |
| ) | |
| mock_reflect_on_translation = mocker.patch( | |
| "translation_agent.utils.one_chunk_reflect_on_translation", | |
| return_value=reflection, | |
| ) | |
| mock_improve_translation = mocker.patch( | |
| "translation_agent.utils.one_chunk_improve_translation", | |
| return_value=translation2, | |
| ) | |
| # Call the function being tested | |
| result = one_chunk_translate_text( | |
| source_lang, target_lang, source_text, country | |
| ) | |
| # Assert the expected result | |
| assert result == translation2 | |
| # Assert that the helper functions were called with the correct arguments | |
| mock_initial_translation.assert_called_once_with( | |
| source_lang, target_lang, source_text | |
| ) | |
| mock_reflect_on_translation.assert_called_once_with( | |
| source_lang, target_lang, source_text, translation_1, country | |
| ) | |
| mock_improve_translation.assert_called_once_with( | |
| source_lang, target_lang, source_text, translation_1, reflection | |
| ) | |
| def test_num_tokens_in_string(): | |
| # Test case 1: Empty string | |
| assert num_tokens_in_string("") == 0 | |
| # Test case 2: Simple string | |
| assert num_tokens_in_string("Hello, world!") == 4 | |
| # Test case 3: String with special characters | |
| assert ( | |
| num_tokens_in_string( | |
| "This is a test string with special characters: !@#$%^&*()" | |
| ) | |
| == 16 | |
| ) | |
| # Test case 4: String with non-ASCII characters | |
| assert num_tokens_in_string("Héllò, wörld! 你好,世界!") == 17 | |
| # Test case 5: Long string | |
| long_string = ( | |
| "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " * 10 | |
| ) | |
| assert num_tokens_in_string(long_string) == 101 | |
| # Test case 6: Different encoding | |
| assert ( | |
| num_tokens_in_string("Hello, world!", encoding_name="p50k_base") == 4 | |
| ) | |