def sample_test_case(function_mock): test_case = dtc.DefaultTestCase() float_prim = prim.FloatPrimitiveStatement(test_case, 5.0) float_prim2 = prim.FloatPrimitiveStatement(test_case, 5.0) float_function1 = par_stmt.FunctionStatement(test_case, function_mock, [float_prim.return_value]) float_function2 = par_stmt.FunctionStatement( test_case, function_mock, [float_function1.return_value]) test_case.add_statement(float_prim) test_case.add_statement(float_prim2) test_case.add_statement(float_function1) test_case.add_statement(float_function2) return test_case
def test_get_dependencies_chained(default_test_case, function_mock): unused_float = prim.FloatPrimitiveStatement(default_test_case, 5.5) default_test_case.add_statement(unused_float) float0 = prim.FloatPrimitiveStatement(default_test_case, 5.5) default_test_case.add_statement(float0) func0 = ps.FunctionStatement(default_test_case, function_mock, {"a": float0.ret_val}) default_test_case.add_statement(func0) func1 = ps.FunctionStatement(default_test_case, function_mock, {"a": func0.ret_val}) default_test_case.add_statement(func1) dependencies = default_test_case.get_dependencies(func1.ret_val) assert dependencies == {float0.ret_val, func0.ret_val, func1.ret_val}
def test_statement_to_ast_function_args(statement_to_ast_visitor, test_case_mock, function_mock): function_stmt = param_stmt.FunctionStatement( test_case_mock, function_mock, [MagicMock(vr.VariableReference)]) statement_to_ast_visitor.visit_function_statement(function_stmt) assert (astor.to_source(Module(body=statement_to_ast_visitor.ast_nodes)) == "var1 = module0.simple_function(var0)\n")
def test_delete_statement_gracefully_no_alternatives(function_mock): test_case = dtc.DefaultTestCase() float_prim = prim.FloatPrimitiveStatement(test_case, 5.0) float_function1 = par_stmt.FunctionStatement(test_case, function_mock, [float_prim.return_value]) test_case.add_statement(float_prim) test_case.add_statement(float_function1) assert tf.TestFactory.delete_statement_gracefully(test_case, 0) assert test_case.size() == 0
def test_statement_to_ast_function_no_args( statement_to_ast_visitor, test_case_mock, function_mock ): function_stmt = param_stmt.FunctionStatement(test_case_mock, function_mock) statement_to_ast_visitor.visit_function_statement(function_stmt) assert ( astor.to_source(Module(body=statement_to_ast_visitor.ast_nodes)) == "var0 = module0.simple_function()\n" )
def test_select_random_variable_for_call_none(constructor_mock, function_mock): test_case = dtc.DefaultTestCase() test_case.add_statement(prim.NoneStatement(test_case, MagicMock)) test_case.add_statement(prim.FloatPrimitiveStatement(test_case, 5.0)) function_mock.inferred_signature.update_return_type(None) test_case.add_statement( par_stmt.FunctionStatement(test_case, function_mock)) assert (tf.TestFactory._select_random_variable_for_call( test_case, test_case.size()) is None)
def add_function( self, test_case: tc.TestCase, function: gao.GenericFunction, position: int = -1, recursion_depth: int = 0, allow_none: bool = True, ) -> vr.VariableReference: """Adds a function call to a test case at a given position. If the position is not given, the function 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. Args: test_case: The test case function: The function call to add to the test case position: the position where to put the statement in the test case, defaults to the end of the test case recursion_depth: A recursion limit for the search of parameter values allow_none: Whether or not a variable can hold a None value Returns: A variable reference to the function call's result Raises: ConstructionFailedException: if construction of an object failed """ self._logger.debug("Adding function %s", function) 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 = function.inferred_signature length = test_case.size() 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.FunctionStatement( test_case=test_case, generic_callable=function, args=parameters, ) return test_case.add_statement(statement, position)
def test_delete_statement_gracefully_success(function_mock): test_case = dtc.DefaultTestCase() float_prim = prim.FloatPrimitiveStatement(test_case, 5.0) float_prim2 = prim.FloatPrimitiveStatement(test_case, 5.0) float_function1 = par_stmt.FunctionStatement(test_case, function_mock, [float_prim2.return_value]) test_case.add_statement(float_prim) test_case.add_statement(float_prim2) test_case.add_statement(float_function1) assert tf.TestFactory.delete_statement_gracefully(test_case, 1) assert test_case.statements[1].references(float_prim.return_value) assert test_case.size() == 2
def test_change_random_call_no_calls(function_mock): test_case = dtc.DefaultTestCase() float_prim = prim.FloatPrimitiveStatement(test_case, 5.0) float_function1 = par_stmt.FunctionStatement(test_case, function_mock, [float_prim.return_value]) test_case.add_statement(float_prim) test_case.add_statement(float_function1) test_cluster = MagicMock(TestCluster) test_cluster.get_generators_for.return_value = {function_mock} test_factory = tf.TestFactory(test_cluster) assert not test_factory.change_random_call(test_case, float_function1)
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 simple_test_case(function_mock) -> dtc.DefaultTestCase: test_case = dtc.DefaultTestCase() int_prim = prim.IntPrimitiveStatement(test_case, 5) int_prim2 = prim.IntPrimitiveStatement(test_case, 5) float_prim = prim.FloatPrimitiveStatement(test_case, 5.5) func = ps.FunctionStatement(test_case, function_mock, [float_prim.return_value]) string_prim = prim.StringPrimitiveStatement(test_case, "Test") string_prim.return_value.variable_type = type(None) test_case.add_statement(int_prim) test_case.add_statement(int_prim2) test_case.add_statement(float_prim) test_case.add_statement(func) test_case.add_statement(string_prim) return test_case
def simple_test_case(function_mock) -> dtc.DefaultTestCase: test_case = dtc.DefaultTestCase() int_prim = prim.IntPrimitiveStatement(test_case, 5) int_prim2 = prim.IntPrimitiveStatement(test_case, 5) float_prim = prim.FloatPrimitiveStatement(test_case, 5.5) func = ps.FunctionStatement(test_case, function_mock, {"z": float_prim.ret_val}) func.add_assertion(pas.PrimitiveAssertion(func.ret_val, 3.1415)) string_prim = prim.StringPrimitiveStatement(test_case, "Test") string_prim.ret_val.variable_type = type(None) test_case.add_statement(int_prim) test_case.add_statement(int_prim2) test_case.add_statement(float_prim) test_case.add_statement(func) test_case.add_statement(string_prim) return test_case
def _get_test_for_nested_branch_fixture(module) -> tcc.TestCaseChromosome: test_case = dtc.DefaultTestCase() int_stmt = prim_stmt.IntPrimitiveStatement(test_case, -50) function_call = param_stmt.FunctionStatement( test_case, gao.GenericFunction( module.nested_branches, InferredSignature(signature=MagicMock(), parameters={}, return_type=int), ), [int_stmt.ret_val], ) test_case.add_statement(int_stmt) test_case.add_statement(function_call) return tcc.TestCaseChromosome(test_case=test_case)
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 test_change_random_call_success(function_mock, method_mock, constructor_mock): test_case = dtc.DefaultTestCase() float_prim = prim.FloatPrimitiveStatement(test_case, 5.0) int0 = prim.IntPrimitiveStatement(test_case, 2) float_function1 = par_stmt.FunctionStatement(test_case, function_mock, [float_prim.return_value]) const = par_stmt.ConstructorStatement(test_case, constructor_mock) test_case.add_statement(float_prim) test_case.add_statement(int0) test_case.add_statement(const) test_case.add_statement(float_function1) test_cluster = MagicMock(TestCluster) test_cluster.get_generators_for.return_value = {function_mock, method_mock} test_factory = tf.TestFactory(test_cluster) with mock.patch.object(test_factory, "change_call") as change_mock: assert test_factory.change_random_call(test_case, float_function1) change_mock.assert_called_with(test_case, float_function1, method_mock)
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 _get_test_for_single_branch_else_branch_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.first, InferredSignature( signature=inspect.signature(module.first), parameters={"a": int}, return_type=int, ), ), {"a": int_stmt.ret_val}, ) test_case.add_statement(int_stmt) test_case.add_statement(function_call) return tcc.TestCaseChromosome(test_case=test_case)
def test_function_accessible_object(test_case_mock, function_mock): func = ps.FunctionStatement(test_case_mock, function_mock) assert func.accessible_object() == function_mock