import unittest

from connectome.analysis import (AnalysisBuilder, InOutDegreeCorrelation,
                                 ConnectivityEstimator, RelativeReciprocityEstimator,
                                 RelativeCycleAnalysis)
from connectome.model import ER


class TestAnalysisBuilder(unittest.TestCase):
    def setUp(self):
        analysis_builder = AnalysisBuilder()
        analysis_builder.add(ConnectivityEstimator)
        analysis_builder.add(RelativeReciprocityEstimator)
        analysis_builder.add(RelativeCycleAnalysis, length=5)
        analysis_builder.add(InOutDegreeCorrelation)
        self.analysis = analysis_builder.get_result()
        self.er = ER(nr_neurons=500, inh_ratio=2/5, p_exc=.3, p_inh=.5)

    def test_analysis_builder(self):
        network = self.er()
        actual_result = self.analysis(network=network)
        analysis_list = [ConnectivityEstimator(),
        RelativeReciprocityEstimator(),
        RelativeCycleAnalysis(length=5),
        InOutDegreeCorrelation()]
        analysis_results_list = [analysis(network=network) for analysis in analysis_list]
        expected_result = {key: val for result in analysis_results_list for key, val in result.items()}
        self.assertEqual(expected_result, actual_result)

    def test_analysis_builder_repeated(self):
        network = self.er()
        actual_result = self.analysis(network=network)
        analysis_list = [ConnectivityEstimator(),
        RelativeReciprocityEstimator(),
        RelativeCycleAnalysis(length=5),
        InOutDegreeCorrelation()]
        analysis_results_list = [analysis(network=network) for analysis in analysis_list]
        expected_result = {key: val for result in analysis_results_list for key, val in result.items()}
        self.assertEqual(expected_result, actual_result)

        er = ER(nr_neurons=250, inh_ratio=100/250, p_exc=.3, p_inh=.5)
        network = er()
        actual_result = self.analysis(network=network)
        analysis_list = [ConnectivityEstimator(),
        RelativeReciprocityEstimator(),
        RelativeCycleAnalysis(length=5),
        InOutDegreeCorrelation()]
        analysis_results_list = [analysis(network=network) for analysis in analysis_list]
        expected_result = {key: val for result in analysis_results_list for key, val in result.items()}
        self.assertEqual(expected_result, actual_result)


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