def test_fail_module_load(self, sphinx_state): """ Test that a warning is raised when unable to find the module to document """ directive = AutodocDirective( "autocmodule", ["non_existent.c"], {"members": None}, None, 10, None, None, sphinx_state, None, ) output = directive.run() assert output == [] warnings = sphinx_state.env.app._warning.getvalue() messages = ("Unable to find", "non_existent.c") for message in messages: assert message in warnings
def test_incorrectly_specified_variable_causes_warning(self, sphinx_state): """ Test that when a directive string is for an unparsable variable name a warning is thrown. """ directive = AutodocDirective( "autocdata", ["example.c::unparseable-kabab"], {"members": None}, None, None, None, None, sphinx_state, None, ) output = directive.run() warnings = sphinx_state.env.app._warning.getvalue() messages = ("invalid signature for autocdata", ) for message in messages: assert message in warnings assert [] == output
def test_custom_napoleon_section(self, sphinx_state): """ Tests the restructured text output returned by the directive. """ custom_napoleon_section = """\ void *custom_napoleon_section(char first_param, int second_param) A function using a custom napoleon section that doesn't exist in this package. Parameters first_param -- A parameter to document second_param -- Why not""" sphinx_state.env.app.connect("autodoc-process-docstring", process_autodoc_docstring) directive = AutodocDirective( "autocfunction", ["functions.c::custom_napoleon_section"], {"members": None}, None, None, None, None, sphinx_state, None, ) output = directive.run() # First item is the index entry assert 2 == len(output) body = output[1] # For whatever reason the as text comes back with double spacing, so we # knock it down to single spacing to make the expected string smaller. assert body.astext().replace("\n\n", "\n") == dedent(custom_napoleon_section)
def test_doc(self, struct, expected_doc, sphinx_state): """ Tests the restructured text output returned by the directive. """ directive = AutodocDirective( "autocstruct", [struct], # Members of structs should be visible even with no private members. # I.e. if the struct is visible all of it is. { "members": None, "no-private-members": None }, None, None, None, None, sphinx_state, None, ) output = directive.run() # First item is the index entry assert 2 == len(output) body = output[1] # For whatever reason the as text comes back with double spacing, so we # knock it down to single spacing to make the expected string smaller. assert body.astext().replace("\n\n", "\n") == dedent(expected_doc)
def test_pre_parsing(sphinx_state): """ Tests the restructured text output returned by the directive. """ sphinx_state.env.app.connect("c-autodoc-pre-process", pre_parser) directive = AutodocDirective( "autocdata", ["variables.c::compilation_db_define"], {"members": None}, None, None, None, None, sphinx_state, None, ) output = directive.run() # First item is the index entry assert 2 == len(output) body = output[1] # For whatever reason the as text comes back with double spacing, so we # knock it down to single spacing to make the expected string smaller. assert dedent(new_contents_int) == body.astext().replace("\n\n", "\n")
def test_no_private_members_option(self, sphinx_state): file_with_no_private_members = """\ float a_public_var Non static variables are not private void function1(int a) Non static functions are not private""" directive = AutodocDirective( "autocmodule", ["file_with_private_members.c"], { "members": None, "no-private-members": None }, None, None, None, None, sphinx_state, None, ) output = self.get_directive_output(directive) assert output == dedent(file_with_no_private_members)
def test_no_undoc_members(self, sphinx_state): header_with_undocumented_members = """\ This header file as some undocumented contents struct struct_with_undocumented_member The structure member bar is undocumented. It will still show in the documentation, only file level constructs will be filtered with this option. int bar """ directive = AutodocDirective( "autocmodule", ["header_with_undocumented_members.h"], { "members": None, "no-undoc-members": None }, None, None, None, None, sphinx_state, None, ) output = self.get_directive_output(directive) assert output == dedent(header_with_undocumented_members)
def test_no_members_option(self, sphinx_state): """ Test that when no members is provided that the members don't get documented. """ just_file_doc = """\ This is a file comment""" directive = AutodocDirective("autocmodule", ["module.c"], {}, None, None, None, None, sphinx_state, None) assert self.get_directive_output(directive) == dedent(just_file_doc)
def run(self): """Run method for the directive""" options_save = self.options.copy() doc_nodes = AutodocDirective.run(self) self.options.update(options_save) if 'autosummary' not in self.options: return doc_nodes try: self.env = self.state.document.settings.env except AttributeError: pass # is set automatically with sphinx >= 1.8.0 if sphinx_version < [2, 0]: self.warnings = [] self.result = ViewList() documenter = self.autosummary_documenter grouped_documenters = documenter.get_grouped_documenters() nested = 'autosummary-no-nesting' not in self.options summ_nodes = self.autosumm_nodes(documenter, grouped_documenters, nested) dn = summ_nodes.pop(documenter.fullname) if self.name == 'automodule': doc_nodes = self.inject_summ_nodes(doc_nodes, summ_nodes) # insert the nodes directly after the paragraphs if self.name == 'autoclass': for node in dn[::-1]: self._insert_after_paragraphs(doc_nodes[1], node) dn = [] elif self.name == 'automodule': # insert table before the documentation of the members istart = 2 if 'noindex' not in self.options else 0 # if we have a title in the module, we look for the section if (len(doc_nodes) >= istart + 1 and isinstance(doc_nodes[istart], nodes.section)): others = doc_nodes[istart] istart = 2 # skip the title else: others = doc_nodes found = False if len(others[istart:]) >= 2: for i in range(istart, len(others)): if isinstance(others[i], sphinx.addnodes.index): found = True break if found: for node in dn[::-1]: others.insert(i, node) dn = [] if sphinx_version < [2, 0]: return self.warnings + dn + doc_nodes else: return dn + doc_nodes
def test_undoc_members_specified(self, sphinx_state): header_with_undocumented_members = """\ This header file as some undocumented contents _MY_HEADER_GUARD struct struct_with_undocumented_member The structure member bar is undocumented. It will still show in the documentation, only file level constructs will be filtered with this option. int bar struct undocumented_struct int foo float what """ directive = AutodocDirective( "autocmodule", ["header_with_undocumented_members.h"], # Note: The undoc-members option is actually in the common conf.py # file. And it is an autodoc specific feature, this just tests # that the extension obeys that. {"members": None}, None, None, None, None, sphinx_state, None, ) output = self.get_directive_output(directive) assert output == dedent(header_with_undocumented_members)
def test_doc(self, type_, expected_doc, sphinx_state): """ Tests the restructured text output returned by the directive. """ directive = AutodocDirective( "autoctype", [type_], {"members": None}, None, None, None, None, sphinx_state, None, ) output = directive.run() # First item is the index entry assert 2 == len(output) body = output[1] # For whatever reason the as text comes back with double spacing, so we # knock it down to single spacing to make the expected string smaller. assert body.astext().replace("\n\n", "\n") == dedent(expected_doc)
def test_no_compilation_database(self, file_, expected_doc, sphinx_state): """ Tests the restructured text output returned by the directive. """ directive = AutodocDirective( "autocmodule", [file_], {"members": None}, None, None, None, None, sphinx_state, None, ) output = self.get_directive_output(directive) assert output == dedent(expected_doc) assert "" == sphinx_state.env.app._warning.getvalue()
def test_non_existent_member_causes_warning(self, sphinx_state): """ Test that when specific a specific member is called out and it doesn't exist a warning is emitted. """ example_c = """\ This is a file comment. The first comment in the file will be grabbed. Often times people put the copyright in these. If that is the case then you may want to utilize the pre processing hook, c-autodoc-pre-process. One may notice that this comment block has a string of *** along the top and the bottom. For the file comment these will get stripped out, however for comments on other c constructs like macros, functions, etc. clang is often utilized and it does not understand this pattern, so the c-autodoc-pre-process hook may be something to use to sanitize these kind of comments. TOO_SIMPLE A simple macro definition int some_flag_variable File level variables can also be documented""" directive = AutodocDirective( "autocmodule", ["example.c"], {"members": "TOO_SIMPLE, not_here, some_flag_variable"}, None, None, None, None, sphinx_state, None, ) assert self.get_directive_output(directive) == dedent(example_c) warnings = sphinx_state.env.app._warning.getvalue() messages = ('Missing member "not_here"', ) for message in messages: assert message in warnings
def test_doc(self, file_, expected_doc, sphinx_state): """ Tests the restructured text output returned by the directive. """ directive = AutodocDirective( "autocmodule", [file_], { "members": None, "private-members": True, "member-order": "bysource" }, None, None, None, None, sphinx_state, None, ) assert self.get_directive_output(directive) == dedent(expected_doc)
def test_file_not_found_in_compilation_database(self, file_, expected_doc, sphinx_state, tmp_path): compilation_db = tmp_path / "compile_commands.json" compilation_db.write_text(json.dumps([])) sphinx_state.env.config.c_autodoc_compilation_database = str( compilation_db) directive = AutodocDirective( "autocmodule", [file_], {"members": None}, None, None, None, None, sphinx_state, None, ) output = self.get_directive_output(directive) assert output == dedent(expected_doc) assert "" == sphinx_state.env.app._warning.getvalue()
def test_use_compilation_args(self, file_, expected_doc, sphinx_state, tmp_path): include_path = os.path.join(ROOT_DIR, "include") sphinx_state.env.config.c_autodoc_compilation_args = [ "-DSOME_DEFINE=1", f"-I{include_path}", ] directive = AutodocDirective( "autocmodule", [file_], {"members": None}, None, None, None, None, sphinx_state, None, ) output = self.get_directive_output(directive) assert output == dedent(expected_doc) assert "" == sphinx_state.env.app._warning.getvalue()
def test_non_existent_compilation_database(self, file_, expected_doc, sphinx_state, tmp_path): compilation_db = tmp_path / "compile_commands.json" sphinx_state.env.config.c_autodoc_compilation_database = str( compilation_db) directive = AutodocDirective( "autocmodule", [file_], {"members": None}, None, None, None, None, sphinx_state, None, ) output = self.get_directive_output(directive) assert output == dedent(expected_doc) warnings = sphinx_state.env.app._warning.getvalue() db_name = str(compilation_db) message = f'Compilation database "{db_name}" not found.' assert message in warnings
def test_no_private_members_on_header_file(self, sphinx_state): header_with_no_private_members = """\ typedef float header_type This should always be visible, even if no-private-members is in use.""" directive = AutodocDirective( "autocmodule", ["header_with_types.h"], { "members": None, "no-private-members": None }, None, None, None, None, sphinx_state, None, ) output = self.get_directive_output(directive) assert output == dedent(header_with_no_private_members)