Wei-Chih Chen

56 papers A* 2A 3B 1C 4Misc 2Journal 26Unranked 18
YearRankTypeTitle / Venue / Authors
2026 conf
ISSCC
Wei-Chih Chen, Mu-Shan Lin, Chien-Chun Tsai, Shenggao Li, Wei-Shuo Lin, Yu-Jie Huang, Nai-Chen Cheng, Yu-Chi Chen, Wen-Hung Huang, Chin-Hua Wen, Hsin-Hung Kuo, Han-Tzung Ke, Jie-Ren Huang, Chang-Yi Li, Sheng-Tsung Lai, Shu-Chun Yang, Kuan-Ting Chou, Pei-Chen Chiou, Tsung-Hsien Tsai, Yi-Ting Chen, Yen-Ming Chen, Kenny Cheng-Hsiang Hsieh
2026 J jnl
CoRR
Wei-Chih Chen, Chien-yu Huang, Hung-yi Lee
2026 J jnl
CoRR
Kai-Wei Chang, Wei-Chih Chen, En-Pei Hu, Hung-yi Lee, James R. Glass
2025 conf
ISSCC
Mu-Shan Lin, Chien-Chun Tsai, Shenggao Li, Wei-Chih Chen, Wen-Hung Huang, Yu-Chi Chen, Yu-Jie Huang, Alan J. Drake, Chin-Hua Wen, Paul Ranucci, Hsin-Hung Kuo, Aidong Yin, Shu-Chun Yang, Farsheed Mahmoudi, Han-Tzung Ke, Chao-Chieh Li, Nai-Chen Cheng, Jimmy Wang, Kevin Lin, Harry Liao, Jie-Ren Huang, Meng-Hsuan Wu, Kenny Cheng-Hsiang Hsieh, Nicholas Amatruda, William Polanco, David King, Todd Basso, Anwar Kashem
2025 J jnl
CoRR
Yu-Xiang Lin, Chih-Kai Yang, Wei-Chih Chen, Chen-An Li, Chien-yu Huang, Xuanjun Chen, Hung-yi Lee
2025 A conf
INTERSPEECH
Chi-Yuan Hsiao, Ke-Han Lu, Kai-Wei Chang, Chih-Kai Yang, Wei-Chih Chen, Hung-yi Lee
2025 J jnl
CoRR
Chi-Yuan Hsiao, Ke-Han Lu, Kai-Wei Chang, Chih-Kai Yang, Wei-Chih Chen, Hung-yi Lee
2025 conf
EMNLP (Findings)
Tzu-Ling Lin, Wei-Chih Chen, Teng-Fang Hsiao, Hou-I Liu, Ya-Hsin Yeh, Yu Kai Chan, Wen-Sheng Lien, Po-Yen Kuo, Philip S. Yu, Hong-Han Shuai
2025 J jnl
CoRR
Tzu-Ling Lin, Wei-Chih Chen, Teng-Fang Hsiao, Hou-I Liu, Ya-Hsin Yeh, Yu Kai Chan, Wen-Sheng Lien, Po-Yen Kuo, Philip S. Yu, Hong-Han Shuai
2025 J jnl
CoRR
Chan-Jan Hsu, Yi-Cheng Lin, Chia-Chun Lin, Wei-Chih Chen, Ho-Lam Chung, Chen-An Li, Yi-Chang Chen, Chien-Yu Yu, Ming-Ji Lee, Chien-Cheng Chen, Ru-Heng Huang, Hung-yi Lee, Da-Shan Shiu
2025 J jnl
CoRR
Ke-Han Lu, Zhehuai Chen, Szu-Wei Fu, Chao-Han Huck Yang, Sung-Feng Huang, Chih-Kai Yang, Chee-En Yu, Chun-Wei Chen, Wei-Chih Chen, Chien-yu Huang, Yi-Cheng Lin, Yu-Xiang Lin, Chi-An Fu, Chun-Yi Kuan, Wenze Ren, Xuanjun Chen, Wei-Ping Huang, En-Pei Hu, Tzu-Quan Lin, Yuan-Kuei Wu, Kuan-Po Huang, Hsiao-Ying Huang, Huang-Cheng Chou, Kai-Wei Chang, Cheng-Han Chiang, Boris Ginsburg, Yu-Chiang Frank Wang, Hung-yi Lee
2025 A* conf
ICLR
Chien-yu Huang, Wei-Chih Chen, Shu-Wen Yang, Andy T. Liu, Chen-An Li, Yu-Xiang Lin, Wei-Cheng Tseng, Anuj Diwan, Yi-Jen Shih, Jiatong Shi, William Chen, Chih-Kai Yang, Xuanjun Chen, Chi-Yuan Hsiao, Puyuan Peng, Shih-Heng Wang, Chun-Yi Kuan, Ke-Han Lu, Kai-Wei Chang, Fabian Alejandro Ritter Gutierrez, et al.
2025 J jnl
CoRR
Kai-Wei Chang, En-Pei Hu, Chun-Yi Kuan, Wenze Ren, Wei-Chih Chen, Guan-Ting Lin, Yu Tsao, Shao-Hua Sun, Hung-yi Lee, James Glass
2025 conf
CICC
Yu-Jie Huang, Mu-Shan Lin, Chien-Chun Tsai, Wei-Chih Chen, Hsin-Hung Kuo, Shu-Chun Yang, Shenggao Li
2024 conf
VLSI Technology and Circuits
Mu-Shan Lin, Chien-Chun Tsai, Shenggao Li, Tze-Chiang Huang, Wen-Hung Huang, Kate Huang, Yu-Chi Chen, Alex Liu, Yu-Jie Huang, Jimmy Wang, Shu-Chun Yang, Nai-Chen Cheng, Chao-Chieh Li, Hsin-Hung Kuo, Wei-Chih Chen, Chin-Hua Wen, Kevin Lin, Po-Yi Huang, Kenny Cheng-Hsiang Hsieh, Frank Lee
2024 J jnl
CoRR
Chih-Kai Yang, Yu-Kuan Fu, Chen-An Li, Yi-Cheng Lin, Yu-Xiang Lin, Wei-Chih Chen, Ho-Lam Chung, Chun-Yi Kuan, Wei-Ping Huang, Ke-Han Lu, Tzu-Quan Lin, Hsiu-Hsuan Wang, En-Pei Hu, Chan-Jan Hsu, Liang-Hsuan Tseng, I-Hsiang Chiu, Ulin Sanga, Xuanjun Chen, Po-Chun Hsu, Shu-Wen Yang, Hung-yi Lee
2024 J jnl
CoRR
Chien-yu Huang, Wei-Chih Chen, Shu-Wen Yang, Andy T. Liu, Chen-An Li, Yu-Xiang Lin, Wei-Cheng Tseng, Anuj Diwan, Yi-Jen Shih, Jiatong Shi, William Chen, Xuanjun Chen, Chi-Yuan Hsiao, Puyuan Peng, Shih-Heng Wang, Chun-Yi Kuan, Ke-Han Lu, Kai-Wei Chang, Chih-Kai Yang, Fabian Ritter Gutierrez, Ming To Chuang, Kuan-Po Huang, Siddhant Arora, You-Kuan Lin, Eunjung Yeo, Kalvin Chang, Chung-Ming Chien, Kwanghee Choi, Cheng-Hsiu Hsieh, Yi-Cheng Lin, Chee-En Yu, I-Hsiang Chiu, Heitor R. Guimarães, Jionghao Han, Tzu-Quan Lin, Tzu-Yuan Lin, Homu Chang, Ting-Wu Chang, Chun Wei Chen, Shou-Jen Chen, Yu-Hua Chen, Hsi-Chun Cheng, Kunal Dhawan, Jia-Lin Fang, Shi-Xin Fang, Kuan-Yu Fang Chiang, Chi An Fu, Hsien-Fu Hsiao, Ching Yu Hsu, Shao-Syuan Huang, Lee Chen Wei, Hsi-Che Lin, Hsuan-Hao Lin, Hsuan-Ting Lin, Jian-Ren Lin, Ting-Chun Liu, Li-Chun Lu, Tsung-Min Pai, Ankita Pasad, Shih-Yun Shan Kuan, Suwon Shon, Yuxun Tang, Yun-Shao Tsai, Jui-Chiang Wei, Tzu-Chieh Wei, Chengxi Wu, Dien-Ruei Wu, Chao-Han Huck Yang, Chieh-Chi Yang, Jia Qi Yip, Shao-Xiang Yuan, Vahid Noroozi, Zhehuai Chen, Haibin Wu, Karen Livescu, David Harwath, Shinji Watanabe, Hung-yi Lee
2024 A* conf
EMNLP
Cheng-Han Chiang, Wei-Chih Chen, Chun-Yi Kuan, Chienchou Yang, Hung-yi Lee
2024 J jnl
CoRR
Cheng-Han Chiang, Wei-Chih Chen, Chun-Yi Kuan, Chienchou Yang, Hung-yi Lee
2024 J jnl
CoRR
Yi-Cheng Lin, Tzu-Quan Lin, Chih-Kai Yang, Ke-Han Lu, Wei-Chih Chen, Chun-Yi Kuan, Hung-yi Lee
2024 conf
SLT
Yi-Cheng Lin, Tzu-Quan Lin, Chih-Kai Yang, Ke-Han Lu, Wei-Chih Chen, Chun-Yi Kuan, Hung-yi Lee
2024 J jnl
CoRR
Yi-Cheng Lin, Wei-Chih Chen, Hung-yi Lee
2024 conf
SLT
Yi-Cheng Lin, Wei-Chih Chen, Hung-yi Lee
2022 conf
TREC
Jia-Huei Ju, Wei-Chih Chen, Heng-Ta Chang, Cheng-Wei Lin, Ming-Feng Tsai, Chuan-Ju Wang
2022 conf
CICC
Shenggao Li, Mu-Shan Lin, Wei-Chih Chen, Chien-Chun Tsai
2021 J jnl
IEICE Trans. Electron.
Robert Chen-Hao Chang, Wei-Chih Chen, Shao-Che Su
2020 conf
VLSI Circuits
Wei-Chih Chen, Chin-Hua Wen, Chin-Ming Fu, Tsung-Hsien Tsai, Yu-Chi Chen, Wen-Hung Huang, Chien-Chun Tsai, Alvin Leng Sun Loke, C. H. Kenny
2020 J jnl
IEEE Trans. Circuits Syst. II Express Briefs
Robert Chen-Hao Chang, Wei-Chih Chen, Jerry Kuei-Shou Huang
2020 C conf
ISCAS
Robert Chen-Hao Chang, Wei-Chih Chen, Lin Liu, Sheng-Hung Cheng
2020 J jnl
IEEE Trans. Circuits Syst. II Express Briefs
Robert Chen-Hao Chang, Wei-Chih Chen, Lin Liu, Sheng-Hung Cheng
2020 conf
ISOCC
Robert Chen-Hao Chang, Pui-Sun Lei, Jerry Kuei-Shou Huang, Wei-Chih Chen
2020 Misc conf
ICASSP
Shih-Yao Huang, Wei-Chih Chen, Chao-Tsung Huang
2019 conf
VLSI Circuits
Wei-Chih Chen, Shu-Chun Yang, Yu-Nan Shih, Wen-Hung Huang, Chien-Chun Tsai, Kenny Cheng-Hsiang Hsieh
2019 Misc conf
ICASSP
Han-Chih Huang, Yu-Chih Wang, Wei-Chih Chen, Ping-Yen Lin, Chao-Tsung Huang
2018 J jnl
Frontiers Digit. Humanit.
Yi-Sheng Chao, Hsing-Chien Wu, Chao-Jung Wu, Wei-Chih Chen
2017 J jnl
IEEE Trans. Circuits Syst. I Regul. Pap.
Hou-Ming Chen, Chang-Chi Lee, Shih-Han Jheng, Wei-Chih Chen, Bo-Yi Lee
2017 J jnl
IEEE Trans. Commun.
Wei-Chih Chen, Guu-Chang Yang, Min-Kuan Chang, Wing C. Kwong
2017 conf
PACIS
Ling-Chieh Kung, Wei-Chih Chen
2016 C conf
ISCAS
Robert Chen-Hao Chang, Chi-Hua Siao, Wei-Chih Chen, Wei-Min Hong
2016 C conf
ISCAS
Robert Chen-Hao Chang, Wei-Chih Chen, Chi-Hua Siao, Hong-Wen Wu
2014 A conf
ICS
Wen-Cheng Lai, Jhin-Fang Huang, Wei-Chih Chen, Ta Chen Chiu
2012 J jnl
EURASIP J. Adv. Signal Process.
Guo-Shiang Lin, Hsiang-Yun Huang, Wei-Chih Chen, Cheng-Ying Yeh, Kai-Che Liu, Wen-Nung Lie
2011 conf
PSIVT (2)
Guo-Shiang Lin, Han-Wen Liu, Wei-Chih Chen, Wen-Nung Lie, Sheng-Yen Huang
2011 J jnl
IEEE J. Sel. Top. Signal Process.
Jui-Chiu Chiang, Wei-Chih Chen, Lien-Ming Liu, Kuo-Feng Hsu, Wen-Nung Lie
2011 J jnl
J. Glob. Optim.
Yi-Feng Hung, Wei-Chih Chen
2011 conf
ICGEC
Churng-Jou Tsai, Wei-Chih Chen, Chia-Hsun Lin, Jinn-Kwei Guo, Chun-Lin Lu
2011 J jnl
J. Inf. Sci. Eng.
Wei-Chih Chen, Jyh-Horng Jeng
2011 B conf
ICPADS
Wei-Chih Chen, Chi-Sheng Shih
2010 conf
CICC
Wei-Chih Chen, Chien-Chun Tsai, Chih-Hsien Chang, Yung-Chow Peng, Fu-Lung Hsueh, Tsung-Hsin Yu, Jinn-Yeh Chien, Wen-Hung Huang, Chi-Chang Lu, Mu-Shan Lin, Chin-Ming Fu, Shu-Chun Yang, Chung-Wing Wong, Wan-Te Chen, Chin-Hua Wen, Li Yueh Wang, Chiang Pu
2010 A conf
ICME
Guo-Shiang Lin, Cheng-Ying Yeh, Wei-Chih Chen, Wen-Nung Lie
2010 J jnl
IEEE Trans. Ind. Informatics
Shi-Jinn Horng, Yuan-Hsin Chen, Ray-Shine Run, Jui-Lin Lai, Rong-Jian Chen, Wei-Chih Chen, Yi Pan, Takao Terano
2010 J jnl
IEEE Trans. Circuits Syst. I Regul. Pap.
Chih-Wen Lu, Chien-Chih Shen, Wei-Chih Chen
2010 J jnl
J. Softw.
Wei-Chih Chen, Jyh-Horng Jeng
2009 conf
ICSAP
Wei-Chih Chen, Jyh-Horng Jeng
2007 conf
ICSNC
Wei-Chih Chen, Shi-Jinn Horng, Pingzhi Fan
2006 C conf
PSIVT
Wen-Nung Lie, Zhi-Wei Gao, Wei-Chih Chen, Ping-Chang Jui
tests/unit/test_database_exporters.py
← Index tests/unit/test_database_exporters.py python
"""
Unit tests for database exporters.
"""
import pytest
import json
from dataclasses import dataclass, asdict
from datetime import datetime, timezone
from unittest.mock import Mock, patch, MagicMock

pytestmark = [pytest.mark.unit, pytest.mark.exporters]


# ============================================================================
# Sample Dataclass for Testing
# ============================================================================

@dataclass
class SampleData:
    """Sample dataclass for export testing."""
    sha256: str = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    name: str = "test_sample"
    value: int = 42
    _id: str = "test_id"


# ============================================================================
# PrintExporter Tests
# ============================================================================

class TestPrintExporter:
    """Tests for PrintExporter class."""

    def test_initialization(self, mock_logger):
        """Test PrintExporter initialization."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        assert exporter.index_prefix == "test_index"
        assert exporter.log is mock_logger

    def test_export_dataclass(self, mock_logger, capsys):
        """Test exporting a dataclass."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        sample = SampleData()

        result = exporter.export(sample)

        assert result is True
        captured = capsys.readouterr()
        assert "test_sample" in captured.out

    def test_export_list_of_dataclasses(self, mock_logger, capsys):
        """Test exporting a list of dataclasses."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        samples = [SampleData(name="sample1"), SampleData(name="sample2")]

        result = exporter.export(samples)

        assert result is True
        captured = capsys.readouterr()
        assert "sample1" in captured.out
        assert "sample2" in captured.out

    def test_export_dict(self, mock_logger, capsys):
        """Test exporting a dictionary."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        data = {"key": "value", "number": 42}

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "key" in captured.out
        assert "value" in captured.out

    def test_export_none(self, mock_logger):
        """Test exporting None."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        result = exporter.export(None)

        assert result is True

    def test_export_empty_list(self, mock_logger):
        """Test exporting empty list."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        result = exporter.export([])

        assert result is True


# ============================================================================
# ElasticsearchExporter Tests
# ============================================================================

class TestElasticsearchExporter:
    """Tests for ElasticsearchExporter class."""

    def test_initialization(self, mock_logger):
        """Test ElasticsearchExporter initialization."""
        with patch('redb.settings.get_elasticsearch_client') as mock_client:
            mock_client.return_value = Mock()
            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")

            assert exporter.index_prefix == "test_index"
            assert exporter.log is mock_logger
            assert exporter.client is not None

    def test_export_dataclass(self, mock_logger):
        """Test exporting a dataclass to Elasticsearch."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData()

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is True
            mock_client.index.assert_called()

    def test_export_list(self, mock_logger):
        """Test exporting a list to Elasticsearch."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            samples = [SampleData(name="sample1"), SampleData(name="sample2")]

            result = exporter.export(
                samples,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": "test_hash"}
            )

            assert result is True
            # Should be called twice (once per sample)
            assert mock_client.index.call_count == 2

    def test_export_failure(self, mock_logger):
        """Test handling export failure."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_client.index.side_effect = Exception("Connection failed")
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData()

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is False
            mock_logger.error.assert_called()

    def test_export_with_custom_id(self, mock_logger):
        """Test exporting with custom _id field."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData(_id="custom_id")

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is True


# ============================================================================
# ClickHouseExporter Tests
# ============================================================================

class TestClickHouseExporter:
    """Tests for ClickHouseExporter class."""

    def test_initialization(self, mock_logger):
        """Test ClickHouseExporter initialization."""
        from redb.extractors.database_exporters import ClickHouseExporter

        mock_client = Mock()
        exporter = ClickHouseExporter(mock_logger, "test_index", client=mock_client)

        assert exporter.index_prefix == "test_index"
        assert exporter.log is mock_logger
        assert exporter.client is mock_client

    def test_export_tuple_data(self, mock_logger):
        """Test exporting tuple data to ClickHouse."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names),
                table="test_table"
            )

            assert result is True

    def test_export_multi_table(self, mock_logger):
        """Test exporting multi-table data to ClickHouse."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table1',
                    'data': [["hash123", "sample.exe"]],
                    'column_names': ["sha256", "name"],
                    'column_type_names': ["String", "String"]
                }
            }

            result = exporter.export(data)

            assert result is True

    def test_export_failure(self, mock_logger):
        """Test handling export failure."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.side_effect = Exception("Connection failed")
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names),
                table="test_table"
            )

            assert result is False

    def test_export_missing_table(self, mock_logger):
        """Test export without table name raises error."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names)
                # Missing table parameter
            )

            assert result is False

    def test_get_client(self, mock_logger):
        """Test get_client method."""
        from redb.extractors.database_exporters import ClickHouseExporter

        mock_client = Mock()
        exporter = ClickHouseExporter(mock_logger, "test_index", client=mock_client)

        result = exporter.get_client()

        assert result is mock_client

    def test_get_client_creates_new(self, mock_logger):
        """Test get_client creates new client if none exists."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_new_client = Mock()
            mock_create.return_value = mock_new_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            result = exporter.get_client()

            assert result is mock_new_client


# ============================================================================
# DatabaseExporter Abstract Base Class Tests
# ============================================================================

class TestDatabaseExporter:
    """Tests for DatabaseExporter abstract base class."""

    def test_cannot_instantiate_abstract(self):
        """Test that DatabaseExporter cannot be instantiated directly."""
        from redb.extractors.database_exporters import DatabaseExporter

        with pytest.raises(TypeError):
            DatabaseExporter()

    def test_subclass_must_implement_export(self):
        """Test that subclasses must implement export method."""
        from redb.extractors.database_exporters import DatabaseExporter

        # Define incomplete subclass
        class IncompleteExporter(DatabaseExporter):
            pass

        with pytest.raises(TypeError):
            IncompleteExporter()


# ============================================================================
# Null/Edge Case Tests
# ============================================================================

class TestExporterEdgeCases:
    """Tests for edge cases in exporters."""

    def test_print_exporter_with_complex_nested_data(self, mock_logger, capsys):
        """Test PrintExporter with complex nested data."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        data = {
            "level1": {
                "level2": {
                    "level3": [1, 2, 3]
                }
            },
            "array": [{"a": 1}, {"b": 2}]
        }

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "level1" in captured.out

    def test_clickhouse_null_handling(self, mock_logger):
        """Test ClickHouse exporter handles null values."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            # Multi-table data with null values
            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [[None, "sample.exe", None]],
                    'column_names': ["sha256", "name", "size"],
                    'column_type_names': ["Nullable(String)", "String", "Nullable(UInt64)"]
                }
            }

            result = exporter.export(data)

            # Should handle nulls appropriately
            assert result is True

    def test_clickhouse_array_handling(self, mock_logger):
        """Test ClickHouse exporter handles array types."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [["hash", ["tag1", "tag2"]]],
                    'column_names': ["sha256", "tags"],
                    'column_type_names': ["String", "Array(String)"]
                }
            }

            result = exporter.export(data)

            assert result is True


# ============================================================================
# Type Conversion Tests
# ============================================================================

class TestExporterTypeConversions:
    """Tests for type conversions in exporters."""

    def test_clickhouse_datetime_handling(self, mock_logger):
        """Test ClickHouse exporter handles datetime values."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            now = datetime.now(timezone.utc)
            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [["hash", now]],
                    'column_names': ["sha256", "timestamp"],
                    'column_type_names': ["String", "DateTime64(3, 'UTC')"]
                }
            }

            result = exporter.export(data)

            assert result is True

    def test_print_exporter_datetime_serialization(self, mock_logger, capsys):
        """Test PrintExporter handles datetime serialization."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        now = datetime.now(timezone.utc)
        data = {"timestamp": now, "name": "test"}

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "timestamp" in captured.out


# ============================================================================
# Connection Context Manager Tests
# ============================================================================

class TestClickHouseConnectionManager:
    """Tests for ClickHouse connection context manager."""

    def test_clickhouse_connection_context(self, mock_logger):
        """Test clickhouse_connection context manager."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            with exporter.clickhouse_connection() as client:
                assert client is mock_client

            # Client should be closed after context exits
            mock_client.close.assert_called()

    def test_clickhouse_connection_close_on_error(self, mock_logger):
        """Test client is closed even if operation fails."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            try:
                with exporter.clickhouse_connection() as client:
                    raise ValueError("Test error")
            except ValueError:
                pass

            # Client should still be closed
            mock_client.close.assert_called()