def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.sut = CoverageOperations()

        self.create_operators_mock()
        self.sut.operators = self.all_operators
    def default(randomizer, adding_rule_supervisor):
        factory = Factory({
            CykTypeId.symbol_pair_executor: cyk_executors.CykSymbolPairExecutor,
            CykTypeId.parent_combination_executor: cyk_executors.CykParentCombinationExecutor,
            CykTypeId.cell_executor: cyk_executors.CykCellExecutor,
            CykTypeId.row_executor:
                lambda table_executor, row, executor_factory:
                cyk_executors.CykRowExecutor(table_executor, row, executor_factory) if row > 0
                else cyk_executors.CykFirstRowExecutor(table_executor, row, executor_factory),
            CykTypeId.table_executor: cyk_executors.CykTableExecutor,
            CykTypeId.production_pool: ProductionPool,
            CykTypeId.environment: Environment,
            CykTypeId.cyk_result: cyk_executors.CykResult,
            CykTypeId.terminal_cell_executor: cyk_executors.CykTerminalCellExecutor
        })

        coverage_operations = CoverageOperations.create_default_set()
        traceback_creator = Traceback

        return CykService(
            factory,
            randomizer,
            adding_rule_supervisor,
            coverage_operations,
            traceback_creator
        )
class TestCoverageOperations(CoverageOperatorTestCommon):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.sut = CoverageOperations()

        self.create_operators_mock()
        self.sut.operators = self.all_operators

    def create_operator_mock(self, coverage_type, adding_strategy):
        operator_mock = create_autospec(CoverageOperator)
        operator_mock.configure_mock(coverage_type=coverage_type)
        operator_mock.adding_rule_strategy_type.return_value = adding_strategy
        operator_mock.cover.return_value = EmptyProduction(Detector(self.coordinates))
        return operator_mock

    def create_operators_mock(self):
        self.terminal_operator_1 = self.create_operator_mock(
            CoverageType.unknown_terminal_symbol, AddingRuleStrategyHint.expand_population)
        self.terminal_operator_2 = self.create_operator_mock(
            CoverageType.unknown_terminal_symbol, AddingRuleStrategyHint.expand_population)

        self.effector_operator_1 = self.create_operator_mock(
            CoverageType.no_effector_found, AddingRuleStrategyHint.expand_population)
        self.effector_operator_2 = self.create_operator_mock(
            CoverageType.no_effector_found, AddingRuleStrategyHint.expand_population)

        self.starting_operator_1 = self.create_operator_mock(
            CoverageType.no_starting_symbol, AddingRuleStrategyHint.control_population_size)
        self.starting_operator_2 = self.create_operator_mock(
            CoverageType.no_starting_symbol, AddingRuleStrategyHint.control_population_size)

        self.terminal_operators = [self.terminal_operator_1, self.terminal_operator_2]
        self.effector_operators = [self.effector_operator_1, self.effector_operator_2]
        self.starting_operators = [self.starting_operator_1, self.starting_operator_2]

        self.all_operators = self.terminal_operators + \
                             self.effector_operators + \
                             self.starting_operators
        shuffle(self.all_operators)

    def clean_all_calls(self):
        for operator in self.all_operators:
            operator.reset_mock()

    def assert_called_times(self, *operator_call_pairs):
        for pair in operator_call_pairs:
            assert_that(pair[0].cover.call_count, is_(equal_to(pair[1])))

        self.clean_all_calls()

    def test_only_operators_of_given_type_should_be_called(self):
        self.sut.perform_coverage(
            self.cyk_service_mock,
            CoverageType.unknown_terminal_symbol,
            self.environment_mock,
            self.rule_population_mock,
            self.coordinates)

        self.assert_called_times(
            (self.terminal_operator_1, 1),
            (self.terminal_operator_2, 1),
            (self.effector_operator_1, 0),
            (self.effector_operator_2, 0),
            (self.starting_operator_1, 0),
            (self.starting_operator_2, 0)
        )

        self.sut.perform_coverage(
            self.cyk_service_mock,
            CoverageType.no_effector_found,
            self.environment_mock,
            self.rule_population_mock,
            self.coordinates)

        self.assert_called_times(
            (self.terminal_operator_1, 0),
            (self.terminal_operator_2, 0),
            (self.effector_operator_1, 1),
            (self.effector_operator_2, 1),
            (self.starting_operator_1, 0),
            (self.starting_operator_2, 0)
        )

        self.sut.perform_coverage(
            self.cyk_service_mock,
            CoverageType.no_starting_symbol,
            self.environment_mock,
            self.rule_population_mock,
            self.coordinates)

        self.assert_called_times(
            (self.terminal_operator_1, 0),
            (self.terminal_operator_2, 0),
            (self.effector_operator_1, 0),
            (self.effector_operator_2, 0),
            (self.starting_operator_1, 1),
            (self.starting_operator_2, 1)
        )

        assert_that(self.rule_population_mock.add_rule.called, is_(False))
        assert_that(self.environment_mock.add_production.called, is_(False))

        expected_rule = TerminalRule(Symbol(hash('A')), Symbol(hash('a')))
        expected_production = Production(Detector(self.coordinates), expected_rule)
        self.terminal_operator_1.cover.return_value = expected_production

        self.sut.perform_coverage(
            self.cyk_service_mock,
            CoverageType.unknown_terminal_symbol,
            self.environment_mock,
            self.rule_population_mock,
            self.coordinates)

        self.adding_rule_supervisor_mock.add_rule.assert_called_once_with(
            expected_rule, self.rule_population_mock, self.cyk_service_mock.statistics,
            AddingRuleStrategyHint.expand_population)
        self.environment_mock.add_production.assert_called_once_with(expected_production)