def test_normalize_symbol_works_with_parent_symbol(symbol, parent_symbol): source = inspect.getsource(symbol) normalized_parent = NormalizedSymbol(parent_symbol, None, None) normalized_symbol = NormalizedSymbol(symbol, normalized_parent, symbol.__name__) assert normalized_symbol.normalized_source.rstrip() == source.strip() assert normalized_symbol.original_symbol == symbol
def test_symbol_object_gives_correct_source_for_annotated_symbol( self, symbol, arg_specs, annotated_symbol): normalized_symbol = NormalizedSymbol(symbol, None, None) module_qualname = get_module_qualname(symbol, project_root_path) module_annotated_data_items = { create_data_item_id(module_qualname, normalized_symbol.qualname): arg_specs[normalized_symbol.qualname] } queue = collections.deque() annotated_symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, NormalizedSymbol(symbol, None, None), is_non_annotated_symbol_of_interest) queue.appendleft(annotated_symbol_object) while queue: current = queue.pop() for nested_symbol in current.nested_symbols: queue.appendleft(nested_symbol) data_item_id = create_data_item_id(module_qualname, nested_symbol.qualname) module_annotated_data_items[data_item_id] = arg_specs[ nested_symbol.qualname] symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, NormalizedSymbol(symbol, None, None), is_non_annotated_symbol_of_interest) symbol_object.module = module_qualname symbol_object.qualname = normalized_symbol.qualname annotated_source = symbol_object.get_annotated_source( module_annotated_data_items) assert annotated_source == pavo_cristatus_get_source(annotated_symbol)
def test_symbol_object_gives_correct_source_for_non_annotated_symbol( self, symbol): symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, NormalizedSymbol(symbol, None, None), is_annotated_symbol_of_interest) non_annotated_source = symbol_object.get_non_annotated_source() assert non_annotated_source == pavo_cristatus_get_source(symbol)
def test_read_interaction(self, symbol): symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, NormalizedSymbol(symbol, None, None), is_annotated_symbol_of_interest) gen = symbols_object_generator(symbol_object) def lazy_result(): try: return next(gen) except StopIteration: return None python_file = get_python_file_from_symbol_object(symbol_object) module_symbols = ModuleSymbols(inspect.getmodule(symbol_object), python_file, symbol_object.module, {symbol_object}) sqlite_query_result_spy = SQLiteQueryResultSpy( len(symbol_object.nested_symbols) + 1, lazy_result) sqlite_cursor_spy = SQLiteCursorSpy(sqlite_query_result_spy) sqlite_repository = SQLiteRepository(sqlite_cursor_spy) result = sql_repository_read_interaction(sqlite_repository).interact( {module_symbols}) assert result.status == PavoCristatusStatus.SUCCESS assert len(result.result) >= len(symbol_object.nested_symbols) assert sqlite_cursor_spy.execute_calls >= len( symbol_object.nested_symbols) + 2
def test_normalized_symbol_raises_exception_if_normalized_parent_is_provided_without_normalized_child_name( ): try: NormalizedSymbol(ClassToNormalize2.x, ClassToNormalize2, None) except ValueError: pass else: pytest.fail("Value Error was expected")
def test_symbol_object_gives_correct_source_annotated_symbol(self, symbol): symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, NormalizedSymbol(symbol, None, None), is_annotated_symbol_of_interest) non_annotated_source = symbol_object.get_non_annotated_source() annotated_source_lines = pavo_cristatus_split( pavo_cristatus_get_source(symbol)) non_annotated_source_lines = pavo_cristatus_split(non_annotated_source) assert len(non_annotated_source_lines) == len(annotated_source_lines) assert self.get_count_of_mismatched_lines( annotated_source_lines, non_annotated_source_lines) == 1
def test_normalized_symbol_works_with_nested_symbols(parent_symbol, nested_source): normalized_parent = NormalizedSymbol(parent_symbol, None, None) parent_symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, normalized_parent, is_non_annotated_symbol_of_interest) nested_symbol_object = next(iter(parent_symbol_object.nested_symbols), None) assert nested_symbol_object is not None assert nested_symbol_object.normalized_symbol.normalized_source == nested_source
def test_symbol_object_gives_correct_source_for_non_annotated_symbol( self, symbols): non_annotated_symbol, annotated_symbol = symbols non_annotated_normalized_symbol = NormalizedSymbol( non_annotated_symbol, None, None) annotated_normalized_symbol = NormalizedSymbol(annotated_symbol, None, None) module_qualname = get_module_qualname(non_annotated_symbol, project_root_path) module_annotated_data_items = { create_data_item_id(module_qualname, non_annotated_normalized_symbol.qualname): inspect.getfullargspec(annotated_normalized_symbol.symbol) } queue = collections.deque() queue.appendleft(annotated_normalized_symbol) while queue: current = queue.pop() for nested_symbol in symbol_collector.convert_to_symbol_object( project_root_path, current, is_annotated_symbol_of_interest).nested_symbols: queue.appendleft(nested_symbol.normalized_symbol) module_annotated_data_items[create_data_item_id( module_qualname, nested_symbol.qualname)] = inspect.getfullargspec( nested_symbol.normalized_symbol.symbol) symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, non_annotated_normalized_symbol, is_non_annotated_symbol_of_interest) annotated_source = symbol_object.get_annotated_source( module_annotated_data_items) expected_source_lines = pavo_cristatus_split( pavo_cristatus_get_source(annotated_symbol)) annotated_source_lines = pavo_cristatus_split(annotated_source) assert len(annotated_source_lines) == len(expected_source_lines) assert self.get_count_of_mismatched_lines(expected_source_lines, annotated_source_lines) == 0
def collect_nested_symbols_in_object_dict(normalized_symbol): """ from a symbol object, get its values list :param normalized_symbol: used to find nested symbols in a a symbols object dict :return: generator of NormalizedSymbol """ for nested_symbol_name, nested_symbol in normalized_symbol.symbol.__dict__.items( ): if nested_symbol is None: continue # there is potential in the case of a decorator where the symbol's name does not match its name in the namespace try: yield NormalizedSymbol(nested_symbol, normalized_symbol, nested_symbol_name) except ValueError: continue
def test_write_interaction(self, symbol): symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, NormalizedSymbol(symbol, None, None), is_annotated_symbol_of_interest) python_file = get_python_file_from_symbol_object(symbol_object) module_symbols = ModuleSymbols(inspect.getmodule(symbol_object), python_file, symbol_object.module, {symbol_object}) sqlite_query_result_spy = SQLiteQueryResultSpy( 1, lambda: {module_symbols}) sqlite_cursor_spy = SQLiteCursorSpy(sqlite_query_result_spy) sqlite_repository = SQLiteRepository(sqlite_cursor_spy) assert sql_repository_write_interaction(sqlite_repository).interact( {module_symbols}).status == PavoCristatusStatus.SUCCESS assert sqlite_cursor_spy.execute_calls == len( symbol_object.nested_symbols) + 3
def collect_nested_symbols_in_object_source(normalized_symbol): """ from a symbol object, get its values list :param normalized_symbol: used to find nested symbols in a a symbols object dict :return: generator of NormalizedSymbol """ code_object = getattr(normalized_symbol.symbol, "__code__", tuple()) nested_const = getattr(code_object, "co_consts", tuple()) nested_code_objects = interoperable_filter( lambda x: code_object is not None and type(x) is type(code_object) and code_object.co_name != LAMBDA_STRING, nested_const) for nested_code_object in nested_code_objects: if nested_code_object is None: continue try: yield NormalizedSymbol.from_context_with_no_symbol( normalized_symbol, nested_code_object.co_name) except ValueError: continue
def test_symbol_signature_replacer_interaction(monkeypatch, symbol): monkeypatch.setattr(utilities, pavo_cristatus_open.__name__, safe_open_hook) symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, NormalizedSymbol(symbol, None, None), is_annotated_symbol_of_interest) python_file = get_python_file_from_symbol_object(symbol_object) module = sys.modules[symbol_object.normalized_symbol.module] module_symbols = ModuleSymbols( module, python_file, get_module_qualname_from_source(symbol_object.normalized_symbol.source, project_root_path), {symbol_object}) project_symbols = {module_symbols} file_write_verifier.reset(module_symbols.get_non_annotated_source()) # Due to file_write_verifier's structure, there can only be one ModuleSymbols per test result = interact(project_symbols) assert result.status == PavoCristatusStatus.SUCCESS and result.result file_write_verifier.verify()
def test_symbol_signature_restorer_interaction(monkeypatch, symbol, arg_specs, annotated_symbol): monkeypatch.setattr(utilities, pavo_cristatus_open.__name__, safe_open_hook) normalized_symbol = NormalizedSymbol(symbol, None, None) module_qualname = get_module_qualname_from_source(normalized_symbol.source, project_root_path) module_annotated_data_items = { create_data_item_id(module_qualname, normalized_symbol.qualname): arg_specs[normalized_symbol.qualname] } queue = collections.deque() symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, normalized_symbol, is_non_annotated_symbol_of_interest) queue.appendleft(symbol_object) while queue: current = queue.pop() for nested_symbol in current.nested_symbols: queue.appendleft(nested_symbol) data_item_id = create_data_item_id(module_qualname, nested_symbol.qualname) module_annotated_data_items[data_item_id] = arg_specs[ nested_symbol.qualname] python_file = get_python_file_from_symbol_object(symbol_object) module_symbols = ModuleSymbols( inspect.getmodule(symbol_object.normalized_symbol), python_file, symbol_object.normalized_symbol.qualname, {symbol_object}) write_verifier.reset( module_symbols.get_annotated_source(module_annotated_data_items)) # Due to file_write_verifier's structure, there can only be one ModuleSymbols per test result = interact({module_symbols: module_annotated_data_items}) assert result.status == PavoCristatusStatus.SUCCESS and result.result write_verifier.verify()
def test_annotated_symbol_presenter_interaction(monkeypatch, symbol, arg_specs, annotated_symbol): monkeypatch.setattr(console_presenter, pavo_cristatus_print.__name__, print_hook) module_qualname = get_module_qualname(symbol, project_root_path) module_annotated_data_items = { create_data_item_id(module_qualname, symbol.__qualname__): arg_specs[symbol.__qualname__] } queue = collections.deque() normalized_symbol = NormalizedSymbol(symbol, None, None) symbol_object = symbol_collector.convert_to_symbol_object( project_root_path, normalized_symbol, is_non_annotated_symbol_of_interest) queue.appendleft(symbol_object) while queue: current = queue.pop() for nested_symbol in current.nested_symbols: queue.appendleft(nested_symbol) data_item_id = create_data_item_id(module_qualname, nested_symbol.qualname) module_annotated_data_items[data_item_id] = arg_specs[ nested_symbol.qualname] python_file = get_python_file_from_symbol_object(symbol_object) module = sys.modules[symbol_object.normalized_symbol.module] module_symbols = ModuleSymbols(module, python_file, module_qualname, {symbol_object}) write_verifier.reset( module_symbols.get_annotated_source(module_annotated_data_items)) result = interact({module_symbols: module_annotated_data_items}, present_annotated_symbols) assert result.status == PavoCristatusStatus.SUCCESS write_verifier.verify()
def test_normalized_symbol_works_with_no_parent_symbol(symbol): source = inspect.getsource(symbol) normalized_symbol = NormalizedSymbol(symbol, None, None) assert normalized_symbol.source == source assert normalized_symbol.original_symbol == symbol
pass symbol_of_interest.__qualname__ = ModuleFakeClassWithNestedAnnotatedFunction.symbol_of_interest.__qualname__ write_verifier = WriteVerifier() def safe_open_hook(*args, **kwargs): return write_verifier symbols_under_test = [ (AnnotatedModuleFakeClassWithCallables.non_symbol_of_interest, get_nested_arg_specs( NormalizedSymbol(ModuleFakeClassWithCallables.non_symbol_of_interest, None, None)), ModuleFakeClassWithCallables.non_symbol_of_interest), (AnnotatedModuleFakeClassWithClasses.NonSymbolOfInterest, get_nested_arg_specs( NormalizedSymbol(ModuleFakeClassWithClasses.NonSymbolOfInterest, None, None)), ModuleFakeClassWithClasses.NonSymbolOfInterest), (AnnotatedModuleFakeClassWithInheritedAnnotatedMethod.SymbolOfInterest, get_nested_arg_specs( NormalizedSymbol( ModuleFakeClassWithInheritedAnnotatedCallables.SymbolOfInterest, None, None)), ModuleFakeClassWithInheritedAnnotatedCallables.SymbolOfInterest), (AnnotatedModuleFakeClassWithInheritedAnnotatedMethod.NonSymbolOfInterest, get_nested_arg_specs( NormalizedSymbol(
def normalize_symbol_with_name_as_qualname(symbol): normalized_symbol = NormalizedSymbol(symbol, None, None) normalized_symbol._qualname = normalized_symbol._name return normalized_symbol