"""
test_analyse.py - 单元测试分析模块的功能。
"""
import unittest
from unittest.mock import patch
import pandas as pd
from analyse import (
    read_danmakus,
    filter_danmakus,
    count_danmakus,
    get_top_danmakus,
    save_top_danmakus_to_excel
)

class TestAnalyse(unittest.TestCase):
    """
    测试分析模块的单元测试类。
    """

    @patch('pandas.read_excel')
    def test_read_danmakus(self, mock_read_excel):
        """
        测试从 Excel 文件中读取弹幕内容的功能。
        """
        # 模拟 Excel 数据
        mock_data = pd.DataFrame({'弹幕内容': ['弹幕1', '弹幕2', '弹幕3']})
        mock_read_excel.return_value = mock_data

        # 调用读取函数
        result = read_danmakus("dummy_filename.xlsx")
        # 期望返回弹幕内容列表
        self.assertEqual(result, ['弹幕1', '弹幕2', '弹幕3'])

    def test_filter_danmakus(self):
        """
        测试根据关键词筛选弹幕内容的功能。
        """
        danmakus = ['这是AI技术的未来', '普通弹幕', '智能应用']
        keywords = ['AI技术', '智能']

        # 调用筛选函数
        result = filter_danmakus(danmakus, keywords)
        # 期望返回包含关键词的弹幕
        self.assertEqual(result, ['这是AI技术的未来', '智能应用'])

    def test_filter_danmakus_no_match(self):
        """
        测试没有匹配关键词时的筛选结果。
        """
        danmakus = ['普通弹幕1', '普通弹幕2']
        keywords = ['AI技术', '智能']

        # 调用筛选函数
        result = filter_danmakus(danmakus, keywords)
        # 期望返回空列表
        self.assertEqual(result, [])

    def test_count_danmakus(self):
        """
        测试统计弹幕出现频率的功能。
        """
        danmakus = ['弹幕1', '弹幕2', '弹幕1']

        # 调用统计函数
        result = count_danmakus(danmakus)
        # 期望返回正确的频率计数器
        self.assertEqual(result['弹幕1'], 2)
        self.assertEqual(result['弹幕2'], 1)

    def test_get_top_danmakus(self):
        """
        测试获取出现频率最高的 N 条弹幕。
        """
        counter = count_danmakus(['弹幕1', '弹幕2', '弹幕1', '弹幕3', '弹幕1'])

        # 调用获取最高频率弹幕的函数
        result = get_top_danmakus(counter, top_n=2)
        # 期望返回频率最高的弹幕及其计数
        self.assertEqual(result, [('弹幕1', 3), ('弹幕2', 1)])

    def test_get_top_danmakus_less_than_n(self):
        """
        测试获取的弹幕数量少于请求的 N 条时的情况。
        """
        counter = count_danmakus(['弹幕1', '弹幕2'])

        # 调用获取最高频率弹幕的函数
        result = get_top_danmakus(counter, top_n=5)
        # 期望返回现有的弹幕及其计数
        self.assertEqual(result, [('弹幕1', 1), ('弹幕2', 1)])

    @patch('pandas.DataFrame.to_excel')
    def test_save_top_danmakus_to_excel(self, mock_to_excel):
        """
        测试将频率最高的弹幕保存到 Excel 文件的功能。
        """
        top_danmakus = [('弹幕1', 3), ('弹幕2', 1)]

        # 调用保存函数
        save_top_danmakus_to_excel(top_danmakus, "output.xlsx")
        # 确保 to_excel 被调用一次
        mock_to_excel.assert_called_once()

    @patch('pandas.DataFrame.to_excel')
    def test_save_top_danmakus_to_excel_empty(self, mock_to_excel):
        """
        测试保存空的弹幕列表到 Excel 文件的功能。
        """
        top_danmakus = []

        # 调用保存函数
        save_top_danmakus_to_excel(top_danmakus, "output.xlsx")
        # 确保 to_excel 被调用一次
        mock_to_excel.assert_called_once()

if __name__ == '__main__':
    unittest.main()  # 执行测试
