def change_random_call(self, test_case: tc.TestCase, statement: stmt.Statement) -> bool: """Change the call represented by this statement to another one. Args: test_case: The test case statement: The new statement Returns: Whether or not the operation was successful """ if statement.return_value.is_type_unknown(): return False objects = test_case.get_all_objects(statement.get_position()) type_ = statement.return_value.variable_type assert type_, "Cannot change change call, when type is unknown" calls = self._get_possible_calls(type_, objects) acc_object = statement.accessible_object() if acc_object in calls: calls.remove(acc_object) if len(calls) == 0: return False call = randomness.choice(calls) try: self.change_call(test_case, statement, call) return True except ConstructionFailedException: self._logger.info("Failed to change call for statement.") return False
def executable_node_for( self, statement: stmt.Statement, ) -> ast.Module: """Transforms the given statement in an executable ast node. Args: statement: The statement that should be converted. Returns: An executable ast node. """ modules_before = len(self._modules_aliases.known_name_indices) visitor = stmt_to_ast.StatementToAstVisitor( self._modules_aliases, self._variable_names ) statement.accept(visitor) if modules_before != len(self._modules_aliases.known_name_indices): # new module added # TODO(fk) cleaner solution? self._global_namespace = ExecutionContext._create_global_namespace( self._modules_aliases ) assert ( len(visitor.ast_nodes) == 1 ), "Expected statement to produce exactly one ast node" return ExecutionContext._wrap_node_in_module(visitor.ast_nodes[0])
def after_statement_execution( self, statement: st.Statement, exec_ctx: ExecutionContext, exception: Optional[Exception] = None, ) -> None: if exception is not None: return if statement.return_value.is_none_type(): return visitor = NoneAssertionVisitor(exec_ctx, statement.return_value, self._trace) statement.accept(visitor)
def append_statement( self, test_case: tc.TestCase, statement: stmt.Statement, allow_none: bool = True, ) -> None: """Appends a statement to a test case. Args: test_case: The test case statement: The statement to append allow_none: Whether or not parameter variables can hold None values Raises: ConstructionFailedException: if construction of an object failed """ if isinstance(statement, par_stmt.ConstructorStatement): self.add_constructor( test_case, statement.accessible_object(), position=test_case.size(), allow_none=allow_none, ) elif isinstance(statement, par_stmt.MethodStatement): self.add_method( test_case, statement.accessible_object(), position=test_case.size(), allow_none=allow_none, ) elif isinstance(statement, par_stmt.FunctionStatement): self.add_function( test_case, statement.accessible_object(), position=test_case.size(), allow_none=allow_none, ) elif isinstance(statement, f_stmt.FieldStatement): self.add_field( test_case, statement.field, position=test_case.size(), ) elif isinstance(statement, prim.PrimitiveStatement): self.add_primitive(test_case, statement, position=test_case.size()) else: raise ConstructionFailedException( f"Unknown statement type: {statement}")
def handle(self, statement: st.Statement) -> None: """Actually handle the given statement. Args: statement: the statement that is visited. """ value = self._exec_ctx.get_variable_value(self._variable) if is_primitive_type(type(value)): return self._trace.add_entry( statement.get_position(), self._variable, nte.NoneTraceEntry(self._variable, value is None), )
def get_assertions(self, statement: stmt.Statement) -> Set[ass.Assertion]: """Get all assertions contained within this trace for the given statement. Args: statement: the statement for which all recorded assertions should be generated. Returns: All assertions in this trace for the given statement. """ position = statement.get_position() assertions = set() if position in self._trace: for _, entry in self._trace[position].items(): assertions.update(entry.get_assertions()) return assertions