def add_method( self, test_case: tc.TestCase, method: gao.GenericMethod, position: int = -1, recursion_depth: int = 0, allow_none: bool = True, callee: Optional[vr.VariableReference] = None, ) -> vr.VariableReference: """Adds a method call to a test case at a given position. If the position is not given, the method call will be appended to the end of the test case. A given recursion depth controls how far the factory searches for suitable parameter values. :param test_case: The test case :param method: The method call to add to the test case :param position: The position where to put the statement in the test case, defaults to the end of the test case :param recursion_depth: A recursion limit for the search of parameter values :param allow_none: Whether or not a variable can hold a None value :param callee: The callee, if it is already known. :return: A variable reference to the method call's result """ self._logger.debug("Adding method %s", method) if recursion_depth > config.INSTANCE.max_recursion: self._logger.debug("Max recursion depth reached") raise ConstructionFailedException("Max recursion depth reached") if position < 0: position = test_case.size() signature = method.inferred_signature length = test_case.size() if callee is None: callee = self._create_or_reuse_variable(test_case, method.owner, position, recursion_depth, allow_none=True) assert callee, "The callee must not be None" parameters: List[vr.VariableReference] = self.satisfy_parameters( test_case=test_case, signature=signature, position=position, recursion_depth=recursion_depth + 1, allow_none=allow_none, ) new_length = test_case.size() position = position + new_length - length statement = par_stmt.MethodStatement( test_case=test_case, generic_callable=method, callee=callee, args=parameters, ) return test_case.add_statement(statement, position)
def test_method_statement_accept(test_case_mock, variable_reference_mock, method_mock): statement = ps.MethodStatement(test_case_mock, method_mock, variable_reference_mock) visitor = MagicMock(sv.StatementVisitor) statement.accept(visitor) visitor.visit_method_statement.assert_called_once_with(statement)
def test_statement_to_ast_method_no_args(statement_to_ast_visitor, test_case_mock, variable_reference_mock, method_mock): method_stmt = param_stmt.MethodStatement(test_case_mock, method_mock, variable_reference_mock) statement_to_ast_visitor.visit_method_statement(method_stmt) assert (astor.to_source(Module(body=statement_to_ast_visitor.ast_nodes)) == "var1 = var0.simple_method()\n")
def test_method_mutable_argument_count(test_case_mock, method_mock, variable_reference_mock): meth = ps.MethodStatement( test_case_mock, method_mock, variable_reference_mock, {"test": variable_reference_mock}, ) assert meth._mutable_argument_count() == 2
def test_method_statement_kwargs(test_case_mock, variable_reference_mock, method_mock): references = { "par1": MagicMock(vri.VariableReferenceImpl), "par2": MagicMock(vri.VariableReferenceImpl), } statement = ps.MethodStatement(test_case_mock, method_mock, variable_reference_mock) statement.kwargs = references assert statement.kwargs == references
def test_method_statement_args(test_case_mock, variable_reference_mock, method_mock): references = [ MagicMock(vri.VariableReferenceImpl), MagicMock(vri.VariableReferenceImpl), ] statement = ps.MethodStatement(test_case_mock, method_mock, variable_reference_mock) statement.args = references assert statement.args == references
def test_statement_to_ast_method_kwargs(statement_to_ast_visitor, test_case_mock, variable_reference_mock, method_mock): method_stmt = param_stmt.MethodStatement( test_case_mock, method_mock, variable_reference_mock, kwargs={"param1": MagicMock(vr.VariableReference)}, ) statement_to_ast_visitor.visit_method_statement(method_stmt) assert (astor.to_source(Module(body=statement_to_ast_visitor.ast_nodes)) == "var2 = var0.simple_method(param1=var1)\n")
def test_illegal_call(method_mock): config.INSTANCE.module_name = "tests.fixtures.accessibles.accessible" test_case = dtc.DefaultTestCase() int_stmt = prim_stmt.IntPrimitiveStatement(test_case, 5) method_stmt = param_stmt.MethodStatement(test_case, method_mock, int_stmt.return_value) test_case.add_statement(int_stmt) test_case.add_statement(method_stmt) tracer = ExecutionTracer() with install_import_hook(config.INSTANCE.module_name, tracer): executor = TestCaseExecutor(tracer) result = executor.execute([test_case]) assert result.has_test_exceptions()
def assemble_stmt_from_gen_callable( testcase: tc.TestCase, gen_callable: GenericCallableAccessibleObject, call: ast.Call, ref_dict: Dict[str, vr.VariableReference], ) -> Optional[param_stmt.ParametrizedStatement]: """Takes a generic callable and assembles the corresponding parametrized statement from it. Args: testcase: the testcase of the statement gen_callable: the corresponding callable of the cluster call: the ast.Call statement ref_dict: a dictionary containing key value pairs of variable ids and variable references. Returns: The corresponding statement. """ for arg in call.args: if not isinstance(arg, (ast.Name, ast.Starred)): return None for keyword in call.keywords: if not isinstance(keyword, ast.keyword): return None var_refs = create_variable_references_from_call_args( call.args, call.keywords, gen_callable, ref_dict # type: ignore ) if var_refs is None: return None if isinstance(gen_callable, GenericFunction): return param_stmt.FunctionStatement( testcase, cast(GenericCallableAccessibleObject, gen_callable), var_refs) if isinstance(gen_callable, GenericMethod): return param_stmt.MethodStatement( testcase, gen_callable, ref_dict[call.func.value.id], # type: ignore var_refs, ) if isinstance(gen_callable, GenericConstructor): return param_stmt.ConstructorStatement( testcase, cast(GenericCallableAccessibleObject, gen_callable), var_refs) return None
def test_illegal_call(method_mock): config.configuration.module_name = "tests.fixtures.accessibles.accessible" test_case = dtc.DefaultTestCase() int_stmt = prim_stmt.IntPrimitiveStatement(test_case, 5) method_stmt = param_stmt.MethodStatement(test_case, method_mock, int_stmt.ret_val) test_case.add_statement(int_stmt) test_case.add_statement(method_stmt) tracer = ExecutionTracer() with install_import_hook(config.configuration.module_name, tracer): module = importlib.import_module(config.configuration.module_name) importlib.reload(module) executor = TestCaseExecutor(tracer) result = executor.execute(test_case) assert result.has_test_exceptions()
def test_method_mutate_special_parameters_none_found(method_mock, constructor_mock): test_case = dtc.DefaultTestCase() float0 = prim.FloatPrimitiveStatement(test_case, 5.0) const0 = ps.ConstructorStatement(test_case, constructor_mock, [float0.return_value]) int0 = prim.IntPrimitiveStatement(test_case, 5) meth = ps.MethodStatement(test_case, method_mock, const0.return_value) test_case.add_statement(float0) test_case.add_statement(const0) test_case.add_statement(int0) test_case.add_statement(meth) with mock.patch.object(meth, "_test_case") as tc: tc.get_objects.return_value = [const0.return_value] assert not meth._mutate_special_parameters(1.0) tc.get_objects.assert_called_with(const0.return_value.variable_type, meth.get_position())
def test_method_statement_clone(method_mock): test_case = dtc.DefaultTestCase() int_prim = prim.IntPrimitiveStatement(test_case, 5) str_prim = prim.StringPrimitiveStatement(test_case, "TestThis") method_stmt = ps.MethodStatement( test_case, method_mock, str_prim.ret_val, {"x": int_prim.ret_val}, ) test_case.add_statement(int_prim) test_case.add_statement(str_prim) test_case.add_statement(method_stmt) cloned = test_case.clone() assert isinstance(cloned.statements[2], ps.MethodStatement) assert cloned.statements[2] is not method_stmt
def test_method_get_variable_replace(method_mock): test_case = dtc.DefaultTestCase() float1 = prim.FloatPrimitiveStatement(test_case, 5.0) float2 = prim.FloatPrimitiveStatement(test_case, 10.0) float3 = prim.FloatPrimitiveStatement(test_case, 10.0) meth = ps.MethodStatement( test_case, method_mock, float2.ret_val, args={"test": float1.ret_val}, ) test_case.add_statement(float1) test_case.add_statement(float2) test_case.add_statement(float3) test_case.add_statement(meth) meth.replace(float2.ret_val, float3.ret_val) meth.replace(float1.ret_val, float3.ret_val) assert meth.callee == float3.ret_val
def test_method_get_variable_references(method_mock): test_case = dtc.DefaultTestCase() float1 = prim.FloatPrimitiveStatement(test_case, 5.0) float2 = prim.FloatPrimitiveStatement(test_case, 10.0) meth = ps.MethodStatement( test_case, method_mock, float2.ret_val, args={"test": float1.ret_val}, ) test_case.add_statement(float1) test_case.add_statement(float2) test_case.add_statement(meth) assert meth.get_variable_references() == { float1.ret_val, float2.ret_val, meth.ret_val, }
def change_call( self, test_case: tc.TestCase, statement: stmt.Statement, call: gao.GenericAccessibleObject, ): """Change the call of the given statement to the one that is given. Args: test_case: The test case statement: The given statement call: The new call """ position = statement.return_value.get_statement_position() return_value = statement.return_value replacement: Optional[stmt.Statement] = None if call.is_method(): method = cast(gao.GenericMethod, call) assert method.owner callee = self._get_random_non_none_object(test_case, method.owner, position) parameters = self._get_reuse_parameters(test_case, method.inferred_signature, position) replacement = par_stmt.MethodStatement(test_case, method, callee, parameters) elif call.is_constructor(): constructor = cast(gao.GenericConstructor, call) parameters = self._get_reuse_parameters( test_case, constructor.inferred_signature, position) replacement = par_stmt.ConstructorStatement( test_case, constructor, parameters) elif call.is_function(): funktion = cast(gao.GenericFunction, call) parameters = self._get_reuse_parameters( test_case, funktion.inferred_signature, position) replacement = par_stmt.FunctionStatement(test_case, funktion, parameters) if replacement is None: assert False, f"Unhandled call type {call}" else: replacement.return_value = return_value test_case.set_statement(replacement, position)
def _get_test_for_no_branches_fixture(module) -> tcc.TestCaseChromosome: test_case = dtc.DefaultTestCase() int_stmt = prim_stmt.IntPrimitiveStatement(test_case, 5) function_call = param_stmt.FunctionStatement( test_case, gao.GenericFunction( module.identity, InferredSignature( signature=inspect.signature(module.identity), parameters={"a": int}, return_type=int, ), ), {"a": int_stmt.ret_val}, ) constructor_call = param_stmt.ConstructorStatement( test_case, gao.GenericConstructor( module.DummyClass, InferredSignature( signature=inspect.signature(module.DummyClass.__init__), parameters={"x": int}, return_type=module.DummyClass, ), ), {"x": function_call.ret_val}, ) method_call = param_stmt.MethodStatement( test_case, gao.GenericMethod( module.DummyClass, module.DummyClass.get_x, InferredSignature(signature=MagicMock(), parameters={}, return_type=int), ), constructor_call.ret_val, ) test_case.add_statement(int_stmt) test_case.add_statement(function_call) test_case.add_statement(constructor_call) test_case.add_statement(method_call) return tcc.TestCaseChromosome(test_case=test_case)
def test_method_statement_no_args(test_case_mock, variable_reference_mock, method_mock): statement = ps.MethodStatement(test_case_mock, method_mock, variable_reference_mock) assert statement.args == [] assert statement.kwargs == {}
def test_method_mutate_special_parameters_no_mutation(test_case_mock, method_mock, variable_reference_mock): meth = ps.MethodStatement(test_case_mock, method_mock, variable_reference_mock) assert not meth._mutate_special_parameters(0.0)
def test_method_get_accessible_object(test_case_mock, method_mock, variable_reference_mock): meth = ps.MethodStatement(test_case_mock, method_mock, variable_reference_mock) assert meth.accessible_object() == method_mock