<commit_before>import types
from functools import cmp_to_key

from .enumeration import PDecoratorType, TestFixtureStatus, TestCaseCountItem, TestClassRunMode

SECOND_MICROSECOND_CONVERSION_FACTOR = 1000000.0


class TestContainer:
    def __init__(self):
        self.start_time = None
        self.end_time = None
        self.test_cases = []

    @property
    def elapsed_time(self):
        time_delta = self.end_time - self.start_time
        return time_delta.seconds + time_delta.microseconds / SECOND_MICROSECOND_CONVERSION_FACTOR

    @property
    def status_count(self):
        status_count_dict = {
            TestCaseCountItem.TOTAL: 0,
            TestCaseCountItem.PASSED: 0,
            TestCaseCountItem.FAILED: 0,
            TestCaseCountItem.SKIPPED: 0,
            TestCaseCountItem.NOT_RUN: 0
        }
        for test_case in self.test_cases:
            status_count_dict[TestCaseCountItem.TOTAL] += 1
            status_count_dict[test_case.status] += 1
        return status_count_dict

    @property
    def pass_rate(self):
        status_count = self.status_count
        return float(status_count[TestCaseCountItem.PASSED]) * 100 / status_count[TestCaseCountItem.TOTAL]


class TestSuite(TestContainer):
    def __init__(self, name):
        TestContainer.__init__(self)
        self.test_classes = []
        self.test_class_run_groups = []
        self.name = name
        self.full_name = name
        self.before_suite = BeforeSuite(self, None)
        self.after_suite = AfterSuite(self, None)

    def init(self):
        self.init_test_fixtures()
        self.init_test_class_run_groups()
        self.sort_test_class_run_groups()

    def init_test_fixtures(self):
        # reflect the before suite and after suite
        for test_class in self.test_classes:
            test_class_ref = test_class.test_class_ref.__class__()
            for element in dir(test_class_ref):
                attr = getattr(test_class_ref, element)
                if hasattr(attr, "__enabled__") and attr.__enabled__ \
                        and hasattr(attr, "__pd_type__"):
                    if attr.__pd_type__ == PDecoratorType.BeforeSuite:
                        self.before_suite = BeforeSuite(self, attr)
                    elif attr.__pd_type__ == PDecoratorType.AfterSuite:
                        self.after_suite = AfterSuite(self, attr)

    def init_test_class_run_groups(self):
        run_groups = {}
        run_group_index = 0
        for test_class in self.test_classes:
            if test_class.run_group is None:
                run_groups[run_group_index] = [test_class]
                run_group_index += 1
            elif test_class.run_group in run_groups:
                run_groups[test_class.run_group].append(test_class)
            else:
                run_groups[test_class.run_group] = [test_class]
        self.test_class_run_groups = run_groups.values()

    def sort_test_class_run_groups(self):
        run_groups = []
        # sort the test classes in run group by its run mode
        for run_group in self.test_class_run_groups:
            run_groups.append(sorted(run_group, key=lambda test_class: test_class.run_mode, reverse=True))

        # sort the test class run groups by its size and number of singleline test classes
        def cmp_run_group(run_group_a, run_group_b):
            if not len(run_group_a) == len(run_group_b):
                return len(run_group_a) - len(run_group_b)
            else:
                return len([test_class for test_class in run_group_a if test_class.run_mode == TestClassRunMode.SingleLine]) - \
                       len([test_class for test_class in run_group_b if test_class.run_mode == TestClassRunMode.SingleLine])<commit_msg>Sort the test class run groups by its number of singleline test cases<commit_after>import types
from functools import cmp_to_key

from .enumeration import PDecoratorType, TestFixtureStatus, TestCaseCountItem, TestClassRunMode

SECOND_MICROSECOND_CONVERSION_FACTOR = 1000000.0


class TestContainer:
    def __init__(self):
        self.start_time = None
        self.end_time = None
        self.test_cases = []

    @property
    def elapsed_time(self):
        time_delta = self.end_time - self.start_time
        return time_delta.seconds + time_delta.microseconds / SECOND_MICROSECOND_CONVERSION_FACTOR

    @property
    def status_count(self):
        status_count_dict = {
            TestCaseCountItem.TOTAL: 0,
            TestCaseCountItem.PASSED: 0,
            TestCaseCountItem.FAILED: 0,
            TestCaseCountItem.SKIPPED: 0,
            TestCaseCountItem.NOT_RUN: 0
        }
        for test_case in self.test_cases:
            status_count_dict[TestCaseCountItem.TOTAL] += 1
            status_count_dict[test_case.status] += 1
        return status_count_dict

    @property
    def pass_rate(self):
        status_count = self.status_count
        return float(status_count[TestCaseCountItem.PASSED]) * 100 / status_count[TestCaseCountItem.TOTAL]


class TestSuite(TestContainer):
    def __init__(self, name):
        TestContainer.__init__(self)
        self.test_classes = []
        self.test_class_run_groups = []
        self.name = name
        self.full_name = name
        self.before_suite = BeforeSuite(self, None)
        self.after_suite = AfterSuite(self, None)

    def init(self):
        self.init_test_fixtures()
        self.init_test_class_run_groups()
        self.sort_test_class_run_groups()

    def init_test_fixtures(self):
        # reflect the before suite and after suite
        for test_class in self.test_classes:
            test_class_ref = test_class.test_class_ref.__class__()
            for element in dir(test_class_ref):
                attr = getattr(test_class_ref, element)
                if hasattr(attr, "__enabled__") and attr.__enabled__ \
                        and hasattr(attr, "__pd_type__"):
                    if attr.__pd_type__ == PDecoratorType.BeforeSuite:
                        self.before_suite = BeforeSuite(self, attr)
                    elif attr.__pd_type__ == PDecoratorType.AfterSuite:
                        self.after_suite = AfterSuite(self, attr)

    def init_test_class_run_groups(self):
        run_groups = {}
        run_group_index = 0
        for test_class in self.test_classes:
            if test_class.run_group is None:
                run_groups[run_group_index] = [test_class]
                run_group_index += 1
            elif test_class.run_group in run_groups:
                run_groups[test_class.run_group].append(test_class)
            else:
                run_groups[test_class.run_group] = [test_class]
        self.test_class_run_groups = run_groups.values()

    def sort_test_class_run_groups(self):
        run_groups = []
        # sort the test classes in run group by its run mode
        for run_group in self.test_class_run_groups:
            run_groups.append(sorted(run_group, key=lambda test_class: test_class.run_mode, reverse=True))

        # sort the test class run groups by its number of singleline test cases
        def cmp_run_group(run_group_a, run_group_b):
            single_line_count_a = single_line_count_b = parallel_count_a = parallel_count_b = 0
            for test_class in run_group_a:
                if test_class.run_mode == TestClassRunMode.SingleLine:
                    single_line_count_a += len(test_class.test_cases)
                else:
                    parallel_count_a += len(test_class.test_cases)

            for test_class in run_group_b:
                if test_class.run_mode == TestClassRunMode.SingleLine:
                    single_line_count_b += len(test_class.test_cases)
                else:
                    parallel_count_b += len(test_class.test_cases)

            if single_line_count_a == single_line_count_b:
                return parallel_count_a - parallel_count_b
            else:
                return single_line_count_a - single_line_count_b
{'fraction_non_alphanumeric': 0.06932300774419185, 'fraction_numerical': 0.005121159130652011, 'mean_word_length': 2.3530150753768844, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7178462', 'n_tokens_mistral': 2432, 'n_tokens_neox': 2317, 'n_words': 473}