import unittest2 as unittest

import ROOT

from monitoring_app import tasks

class TestPages(unittest.TestCase):
    def setUp(self):
        self.fextension = 'root'
        # The fname and keys match those of the data generated by
        # `generate_histograms.py`
        self.dummy_fname = 'histograms.root'
        self.dummy_keys = ['histogram_{0}'.format(i) for i in range(4)]
        self.dummy_th1 = ROOT.TH1F('dummy:xtitle:ytitle', 'dummy', 10, 0, 1)
        self.dummy_th1.FillRandom('gaus', 1000)

    def tearDown(self):
        # Delete TH1 so we don't create multiple instances with the same name
        del self.dummy_th1

    def test_add_file_extension(self):
        """Extension is added to a filename when not present."""
        fname = 'filename'
        fname_expected = '{0}.{1}'.format(fname, self.fextension)
        assert tasks.add_file_extension(fname) == fname_expected

    def test_dont_add_file_extension_again(self):
        """Extension is not added to a filename if already present."""
        fname = 'filename.{0}'.format(self.fextension)
        assert tasks.add_file_extension(fname) == fname

    def test_data_for_th1f(self):
        """Appropriate information is provided on TH1F ROOT objects."""
        data = tasks.data_for_object(self.dummy_th1)
        for key in ('binning', 'values', 'uncertainties', 'axis_titles'):
            assert key in data
        nbins = self.dummy_th1.GetNbinsX()
        assert len(data['binning']) == nbins
        assert len(data['values']) == nbins
        assert len(data['uncertainties']) == nbins
        assert len(data['axis_titles']) == 2
        assert data['axis_titles'][0] == self.dummy_th1.GetXaxis().GetTitle()
        assert data['axis_titles'][1] == self.dummy_th1.GetYaxis().GetTitle()

    def test_data_for_unknown_tobject(self):
        """No information should be returned for unsupported ROOT objects."""
        # Use a child of TObject that we don't support
        obj = ROOT.TH3D()
        data = tasks.data_for_object(obj)
        assert not data

    def test_get_key_from_file(self):
        """Dictionary describing key in file is returned."""
        data = tasks.get_key_from_file(self.dummy_fname, self.dummy_keys[0])
        for k in ('success', 'data'):
            assert k in data
        data_data = data['data']
        assert data['success'] == True
        assert data_data
        for k in ('filename', 'key_name', 'key_title', 'key_class', 'key_data'):
            assert k in data_data
        assert data_data['filename'].endswith(self.dummy_fname)
        assert data_data['key_name'] == self.dummy_keys[0]
        assert data_data['key_title'] == 'Gaussian'
        assert data_data['key_class'] == 'TH1F'

    def test_get_key_from_file_invalid_filename(self):
        """Error dictionary is returned with message."""
        # As this test intentionally tries to open a non-existent file, which
        # ROOT would by default print an error about, temporarily change the
        # logging level to suppress such a message
        originalErrorIgnoreLevel = ROOT.gErrorIgnoreLevel
        ROOT.gErrorIgnoreLevel = ROOT.kFatal
        data = tasks.get_key_from_file('fake_file.root', self.dummy_keys[0])
        ROOT.gErrorIgnoreLevel = originalErrorIgnoreLevel
        for k in ('success', 'message'):
            assert k in data
        assert 'data' not in data
        assert data['success'] == False
        assert data['message'].startswith('Could not open')

    def test_get_key_from_file_invalid_key_name(self):
        """Error dictionary is returned with message."""
        data = tasks.get_key_from_file(self.dummy_fname, 'fake_key')
        for k in ('success', 'message'):
            assert k in data
        assert 'data' not in data
        assert data['success'] == False
        assert data['message'].startswith('Could not find')

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