import os
import warnings
import unittest
from rmtest import ModuleTestCase

class FlowTestsBase(unittest.TestCase):
    def _assert_equalish(self, a, b, e=0.05):
        try:
            delta = a * e
            diff = abs(a-b)
            self.assertLessEqual(diff, delta, 'runtimes differ by more than %f percent' % e)
        except AssertionError as e:
            warnings.warn(e.message)

    def _assert_only_expected_results_are_in_actual_results(self,
                                                           actual_result,
                                                           query_info):
        actual_result_set = []
        if actual_result.result_set is not None:
            actual_result_set = actual_result.result_set[1:]

        # Assert number of results.
        self.assertEqual(len(actual_result_set), len(query_info.expected_result))

        # Assert actual values vs expected values.
        for res in query_info.expected_result:
            self.assertTrue(res in actual_result_set,
                            'The item %s is NOT in the actual result\n'
                            'The actual result: %s\nThe expected result: %s' %
                            (str(res), str(actual_result_set), str(query_info.expected_result)))

    def _assert_actual_results_contained_in_expected_results(self,
                                                             actual_result,
                                                             query_info,
                                                             num_contained_results):
        actual_result_set = actual_result.result_set[1:]

        # Assert num results.
        self.assertEqual(len(actual_result_set), num_contained_results)

        # Assert actual values vs expected values.
        expected_result = query_info.expected_result
        count = len([res for res in expected_result if res in actual_result_set])

        # Assert number of different results is as expected.
        self.assertEqual(count,
                         num_contained_results,
                         'The actual result is: %s\nThe expected result is: %s' %
                         (str(actual_result_set), str(query_info.expected_result)))

    def _assert_run_time(self, actual_result, query_info):

        try:
            self.assertLessEqual(actual_result.run_time_ms,
                             query_info.max_run_time_ms,
                             'Maximum runtime for query \"%s\" was: %s, but shoud be %s' %
                             (query_info.description, str(actual_result.run_time_ms), str(query_info.max_run_time_ms)))
        except AssertionError as e:
            warnings.warn(e.message)