Beispiel #1
0
 def test_annotations_bad_tag(self):
     """Replace a good tag with a bad one and get a syntax error."""
     docstring = self.sample_api_annotated_docstring
     api_docstring_parser = APIDocstringParser()
     api_docstring_parser.parse(docstring.replace("@param", "@bad"))
     d = api_docstring_parser.get_dict()
     self.assert_has_syntax_error(d)
Beispiel #2
0
 def test_annotations_present(self):
     """Tests to ensure annotations-present is functioning."""
     docstring_no_annotations = self.sample_api_docstring
     self.assertFalse(APIDocstringParser.is_annotated_docstring(
         docstring_no_annotations))
     docstring_annotations = self.sample_api_annotated_docstring
     self.assertTrue(APIDocstringParser.is_annotated_docstring(
         docstring_annotations))
Beispiel #3
0
    def test_parse_annotations_indent_descriptions(self):
        """Indentation should be kept when present in descriptions."""
        docstring = self.sample_api_annotated_docstring
        ref_string = "Longer description with\n" "    multiple lines.\n\n    "
        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(docstring, uri=self.test_uri_singular)
        d = api_docstring_parser.get_dict()

        # Note that we only test one description here because the
        # same code is used to gather all description areas of the
        # tags. E.g. @tag (type) "name" [options] description
        self.assertEqual(d["description"], ref_string)
Beispiel #4
0
    def test_warn_on_missing_example_db_entry(self):
        """Ensure we see a warning if there is a missing examples db entry."""
        ds_orig = self.sample_api_annotated_docstring

        ds_bad_exkey = ds_orig.replace('"success_with_exdb" [exkey=key1]',
                                       '"success_with_exdb" [exkey=badkey]')

        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(ds_bad_exkey, uri=self.test_uri_singular)
        d = api_docstring_parser.get_dict()

        self.assert_has_api_warning(d)
Beispiel #5
0
    def test_parse_annotations(self):
        """Tests whether we can parse the sample."""

        docstring = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(docstring, "method", "uri", "operation")
        d = api_docstring_parser.get_dict()

        params = d['params']
        successes = d['successes']
        errors = d['errors']

        self.assertEqual(d['http_method'], "method")
        self.assertEqual(d['uri'], "uri")
        self.assertEqual(d['operation'], "operation")
        self.assertEqual(d['description_title'], "Docstring title")
        self.assertEqual(" ".join(d['description'].split()),
                         "Longer description with multiple lines.")

        p = params[0]
        self.assertEqual(p['type'], "String")
        self.assertEqual(p['name'], "param_name")
        self.assertEqual(" ".join(p['description'].split()),
                         "param description")
        self.assertEqual(" ".join(p['example'].split()), "param-ex")

        p = params[1]
        self.assertEqual(p['type'], "Int")
        self.assertEqual(p['name'], "param_name2")
        self.assertEqual(" ".join(p['description'].split()),
                         "param2 description")
        self.assertEqual(" ".join(p['example'].split()), "param2-ex")

        p = params[2]
        self.assertEqual(p['type'], "URL String")
        self.assertEqual(p['name'], "param_name3")
        self.assertEqual(" ".join(p['description'].split()),
                         "param3 description")
        self.assertEqual(" ".join(p['example'].split()), "param3-ex")

        s = successes[0]
        self.assertEqual(s['type'], "Content")
        self.assertEqual(s['name'], "success_name")
        self.assertEqual(" ".join(s['description'].split()),
                         "success description")
        self.assertEqual(" ".join(s['example'].split()), "success content")

        e = errors[0]
        self.assertEqual(e['type'], "HTTP Status Code")
        self.assertEqual(e['name'], "error_name")
        self.assertEqual(" ".join(e['description'].split()),
                         "error description")
        self.assertEqual(" ".join(e['example'].split()), "error content")
Beispiel #6
0
    def test_template_renders_with_no_warnings(self):
        """The Tempita tmpl-api.rst template should render for the sample
        annotated API docstring with no errors.
        """
        ds = self.sample_api_annotated_docstring
        template = APITemplateRenderer()
        template_path = (
            "%s/../%s" %
            (os.path.dirname(__file__), self.api_tempita_template))

        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(ds, uri=self.test_uri_plural)

        result = template.apply_template(template_path, api_docstring_parser)

        self.assertThat(result, Not(Contains("API_WARNING")))
Beispiel #7
0
    def test_parse_annotations_indent_example(self):
        """Indentation should be kept when present in examples."""
        docstring = self.sample_api_annotated_docstring
        ref_string = ("{\n"
                      "            \"id\": 1,\n"
                      "            \"foo\": \"bar\"\n"
                      "        }\n\n    ")
        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(docstring, uri=self.test_uri_singular)
        d = api_docstring_parser.get_dict()

        # Note that we only test one example here because the
        # same code is used to gather all description areas of the
        # tags. E.g. @tag-example (type) "name" [options] description
        params = d['params']
        self.assertEqual(params[3]['example'], ref_string)
Beispiel #8
0
    def test_missing_error_example_annotation_pieces(self):
        """Test for missing pieces of error-example tag.

        Take a known good docstring and remove pieces inline
        to make sure a warning is raised.
        """
        ds_orig = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()

        # All of these should issue warnings
        # @error-example "error_name" error content

        ds_missing_name = ds_orig.replace('@error-example "error_name"',
                                          '@error-example')
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_name))

        ds_missing_desc = ds_orig.replace(
            '@error-example "error_name" error content',
            '@error-example "error_name"')
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_desc))

        ds_empty_name = ds_orig.replace('@error-example "error_name"',
                                        '@error-example ""')
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_empty_name))
Beispiel #9
0
    def test_empty_description1(self):
        """Test for empty description field in description-title tag."""
        ds_md = self.sample_api_annotated_docstring.replace(
            "Docstring title", "")
        api_docstring_parser = APIDocstringParser()

        self.assert_has_api_warning(self.do_parse(api_docstring_parser, ds_md))
Beispiel #10
0
    def test_empty_description2(self):
        """Test for empty description field in description tag."""
        ds_md = self.sample_api_annotated_docstring.replace(
            "Longer description with\n    multiple lines.", "")
        api_docstring_parser = APIDocstringParser()

        self.assert_has_api_warning(self.do_parse(api_docstring_parser, ds_md))
Beispiel #11
0
    def test_param_formatting_type_has_correct_value(self):
        """'formatting' option should only allow true and false.

        Take a known good docstring and replace the 'required'
        option values inline to make sure only true and false
        are accepted (regardless of capitalization).
        """
        ds_orig = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()

        ds_req = ds_orig.replace("formatting=true", "formatting=false")
        self.assert_has_no_api_warning(
            self.do_parse(api_docstring_parser, ds_req))

        ds_req = ds_orig.replace("formatting=true", "formatting=True")
        self.assert_has_no_api_warning(
            self.do_parse(api_docstring_parser, ds_req))

        ds_req = ds_orig.replace("formatting=true", "formatting=False")
        self.assert_has_no_api_warning(
            self.do_parse(api_docstring_parser, ds_req))

        ds_req = ds_orig.replace("formatting=true", "formatting=yes")
        self.assert_has_api_warning(self.do_parse(api_docstring_parser,
                                                  ds_req))
Beispiel #12
0
    def test_missing_success_annotation_pieces(self):
        """Test for missing pieces of success tag.

        Take a known good docstring and remove pieces inline
        to make sure a warning is raised.
        """
        ds_orig = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()

        # All of these should issue warnings
        # @success (content) "success_name" success description
        ds_missing_type = ds_orig.replace('@success (content)', '@success')
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_type))

        ds_missing_name = ds_orig.replace('@success (content) "success_name"',
                                          '@success (content)')
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_name))

        ds_missing_desc = ds_orig.replace(
            '@success (content) "success_name" success description',
            '@success (content) "success_name"')
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_desc))

        ds_empty_name = ds_orig.replace('@success (content) "success_name"',
                                        '@success (content) ""')
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_empty_name))
Beispiel #13
0
    def test_whether_name_in_single_quotes_works(self):
        """Single quotes should be allowed in annotations."""
        ds_orig = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()

        ds_single_quotes = ds_orig.replace('"', '\'')
        self.assert_has_no_api_warning(
            self.do_parse(api_docstring_parser, ds_single_quotes))
Beispiel #14
0
    def test_valid_types(self):
        """Ensure that non-valid types raise warnings."""
        ds_orig = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()

        ds_bad_type = ds_orig.replace("(int)", "(badtype)")

        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_bad_type))
Beispiel #15
0
    def test_warn_on_missing_example_db_when_entry_referenced(self):
        """Missing examples db.

        If an examples db does not exist for some given URI (like when it
        simply hasn't been created yet) and a key from that missing DB is
        referenced by the API, we should see a warning.

        Note that _not_ having an examples db for a particular operation is a
        normal and acceptable condition (it takes a while to create one). It
        only becomes an error condition when the API tries to reference
        something inside a non-existent examples database.
        """
        ds = self.sample_api_annotated_docstring

        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(ds, uri="bad_uri")
        d = api_docstring_parser.get_dict()

        self.assert_has_api_warning(d)
Beispiel #16
0
    def test_load_nodes_examples_by_default(self):
        """Nodes examples should be loading by default.

        Some API objects like machines and devices inherit operations from
        nodes, so when we load the examples database, we always start with
        nodes and add on object-specific examples.
        """
        ds = self.sample_api_annotated_docstring

        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(ds, uri=self.test_uri_plural)
        d = api_docstring_parser.get_dict()

        # index=2 contains the example with inherited examples from
        # example/nodes.json
        s = d['successes'][2]

        # The presence of the 'resource-uri' string is a good indicator
        # that the 'read-node' key has picked up the JSON object and
        # converted it to a string for output in API docs.
        self.assertTrue(s['example'].find("resource_uri") != -1)
Beispiel #17
0
def describe_actions(handler):
    """Describe the actions that `handler` supports.

    For each action, which could be a CRUD operation or a custom (piggybacked)
    operation, a dict with the following entries is generated:

      method: string, HTTP method.
      name: string, a human-friendly name for the action.
      doc: string, documentation about the action.
      op: string or None, the op parameter to pass in requests for
          non-CRUD/ReSTful requests.
      restful: Indicates if this is a CRUD/ReSTful action.

    """
    from maasserver.api import support  # Circular import.
    getname = support.OperationsResource.crudmap.get
    for signature, function in handler.exports.items():
        http_method, operation = signature
        name = getname(http_method) if operation is None else operation

        ap = APIDocstringParser()
        doc = getdoc(function)

        if doc is not None:
            if APIDocstringParser.is_annotated_docstring(doc):
                # Because the docstring contains annotations, we
                # need to construct a string suitable for output
                # to stdout that matches the style used for
                # non-annotated docstrings in the CLI.
                ap.parse(doc)
                d = ap.get_dict()
                if d['description_title'] != "":
                    doc = d['description_title'] + "\n\n"
                    doc += d['description'] + "\n\n"
                else:
                    doc = d['description'] + "\n\n"

                # Here, we add the params, but we skip params
                # surrounded by curly brackets (e.g. {foo})
                # because these indicate params that appear in
                # the URI (e.g. /zone/{name}/). I.e. positional
                # arguments. These already appear in the CLI
                # help command output so we don't want duplicates.
                for p in d['params']:
                    if p['name'].find("{") == -1 and p['name'].find("}") == -1:
                        required = "Required. "
                        if p['options']['required'] == "false":
                            required = "Optional. "

                        doc += (":param %s: %s%s" %
                                (p['name'], required, p['description']))
                        doc += (":type %s: %s\n " % (p['name'], p['type']))

        yield dict(
            method=http_method, name=name, doc=doc,
            op=operation, restful=(operation is None))
Beispiel #18
0
    def test_find_examples_db(self):
        """Ensure parser correctly finds example databases."""
        ds = self.sample_api_annotated_docstring

        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(ds, uri=self.test_uri_singular)
        d = api_docstring_parser.get_dict()

        s = d['successes'][1]

        self.assertEqual(" ".join(s['example'].split()), '{ "name": "value" }')

        api_docstring_parser.parse(ds, uri=self.test_uri_plural)
        d = api_docstring_parser.get_dict()

        s = d['successes'][1]

        self.assertEqual(" ".join(s['example'].split()), '{ "name": "value" }')
Beispiel #19
0
    def test_missing_param_annotation_pieces(self):
        """Tests that missing annotation pieces raises warning.

        Starts with a known good docstring and modifies it inline
        to remove various parts, which should raise warnings.
        """
        ds_orig = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()

        # @param (string) "param_name" [required=true] param description

        # All of these should issue warnings
        ds_missing_type = ds_orig.replace("@param (string)", "@param")
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_type)
        )

        ds_missing_name = ds_orig.replace(
            '@param (string) "param_name"', "@param (string)"
        )
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_name)
        )

        ds_missing_required = ds_orig.replace(
            '@param (string) "param_name" [required=true]',
            '@param (string) "param_name"',
        )
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_required)
        )

        ds_missing_desc = ds_orig.replace(
            '@param (string) "param_name" [required=true] param description',
            '@param (string) "param_name" [required=true]',
        )
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_desc)
        )

        ds_empty_name = ds_orig.replace(
            '@param (string) "param_name"', '@param (string) ""'
        )
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_empty_name)
        )
Beispiel #20
0
    def test_missing_error_annotation_pieces(self):
        """Test for missing pieces of error tag.

        Take a known good docstring and remove pieces inline
        to make sure a warning is raised.
        """
        ds_orig = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()

        # All of these should issue warnings
        # @error (http-status-code) "error_name" error description
        ds_missing_type = ds_orig.replace(
            "@error (http-status-code)", "@error"
        )
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_type)
        )

        ds_missing_name = ds_orig.replace(
            '@error (http-status-code) "error_name"',
            "@error (http-status-code)",
        )
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_name)
        )

        ds_missing_desc = ds_orig.replace(
            '@error (http-status-code) "error_name" error description',
            '@error (http-status-code) "error_name"',
        )
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_missing_desc)
        )

        ds_empty_name = ds_orig.replace(
            '@error (http-status-code) "error_name"',
            '@error (http-status-code) ""',
        )
        self.assert_has_api_warning(
            self.do_parse(api_docstring_parser, ds_empty_name)
        )
Beispiel #21
0
    def test_parse_annotations(self):
        """Tests whether we can parse the sample."""

        docstring = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(
            docstring,
            http_method="mymethod",
            uri=self.test_uri_singular,
            operation="myoperation",
        )
        d = api_docstring_parser.get_dict()

        params = d["params"]
        successes = d["successes"]
        errors = d["errors"]

        self.assertEqual(d["http_method"], "mymethod")
        self.assertEqual(d["uri"], self.test_uri_singular)
        self.assertEqual(d["operation"], "myoperation")
        self.assertEqual(d["description_title"], "Docstring title")
        self.assertEqual(
            " ".join(d["description"].split()),
            "Longer description with multiple lines.",
        )

        p = params[0]
        self.assertEqual(p["type"], "String")
        self.assertEqual(p["name"], "param_name")
        self.assertEqual(
            " ".join(p["description"].split()), "param description"
        )
        self.assertEqual(" ".join(p["example"].split()), "param-ex")

        p = params[1]
        self.assertEqual(p["type"], "Int")
        self.assertEqual(p["name"], "param_name2")
        self.assertEqual(
            " ".join(p["description"].split()), "param2 description"
        )
        self.assertEqual(" ".join(p["example"].split()), "param2-ex")

        p = params[2]
        self.assertEqual(p["type"], "URL String")
        self.assertEqual(p["name"], "param_name3")
        self.assertEqual(
            " ".join(p["description"].split()), "param3 description"
        )
        self.assertEqual(" ".join(p["example"].split()), "param3-ex")

        p = params[3]
        self.assertEqual(p["type"], "JSON")
        self.assertEqual(p["name"], "param_name4")
        self.assertEqual(
            " ".join(p["description"].split()), "param4 description"
        )
        self.assertEqual(
            " ".join(p["example"].split()), '{ "id": 1, "foo": "bar" }'
        )

        p = params[4]
        self.assertEqual(p["type"], "Boolean")
        self.assertEqual(p["name"], "param_name5")
        self.assertEqual(
            " ".join(p["description"].split()), "param5 description"
        )
        self.assertEqual(" ".join(p["example"].split()), "True")

        p = params[5]
        self.assertEqual(p["type"], "Float")
        self.assertEqual(p["name"], "param_name6")
        self.assertEqual(
            " ".join(p["description"].split()), "param6 description"
        )
        self.assertEqual(" ".join(p["example"].split()), "1.5")

        s = successes[0]
        self.assertEqual(s["type"], "Content")
        self.assertEqual(s["name"], "success_name")
        self.assertEqual(
            " ".join(s["description"].split()), "success description"
        )
        self.assertEqual(" ".join(s["example"].split()), "success content")

        e = errors[0]
        self.assertEqual(e["type"], "HTTP Status Code")
        self.assertEqual(e["name"], "error_name")
        self.assertEqual(
            " ".join(e["description"].split()), "error description"
        )
        self.assertEqual(" ".join(e["example"].split()), "error content")
Beispiel #22
0
def render_api_docs():
    """Render ReST documentation for the REST API.


    This module's docstring forms the head of the documentation; details of
    the API methods follow.

    :return: Documentation, in ReST, for the API.
    :rtype: :class:`unicode`
    """
    from maasserver import urls_api as urlconf

    module = sys.modules[__name__]
    output = StringIO()
    line = partial(print, file=output)

    line(getdoc(module))
    line()
    line()
    line("Operations")
    line("``````````")
    line()

    def export_key(export):
        """Return a sortable key for an export.

        `op` is often `None`, which cannot be compared to non-`None`
        operations.
        """
        (http_method, op), function = export
        if op is None:
            return http_method, "", function
        else:
            return http_method, op, function

    annotation_parser = APIDocstringParser()
    templates = APITemplateRenderer()
    resources = find_api_resources(urlconf)
    for doc in generate_api_docs(resources):
        uri_template = doc.resource_uri_template
        exports = doc.handler.exports.items()
        # Derive a section title from the name of the handler class.
        section_name = doc.handler.api_doc_section_name
        line(section_name)
        line("=" * len(section_name))
        # Note:
        # The following dedent is useless in the following situation:
        #
        # def somefunc(foo)
        #     """No indent here
        #
        #     Here, there is an indent, so dedent doesn't do
        #     anything.
        #    """
        #
        # This fixes the problem:
        #
        # def somefunc(foo)
        #     """
        #     Indent here
        #
        #     Now dedent works because the entire docstring appears
        #     to be indented.
        #    """
        #
        # This also works because the dedent version is the same
        # as the non-dented version:
        #
        # def somefunc(foo)
        #     """No indent here"""
        #
        line(dedent(doc.handler.__doc__).strip())
        line()
        line()
        for (http_method, op), function in sorted(exports, key=export_key):
            operation = " op=%s" % op if op is not None else ""
            subsection = "``%s %s%s``" % (http_method, uri_template, operation)
            docstring = getdoc(function)
            if docstring is not None:
                if APIDocstringParser.is_annotated_docstring(docstring):
                    operation = "op=%s" % op if op is not None else ""
                    annotation_parser.parse(
                        docstring, http_method, uri_template, operation
                    )
                    line(
                        templates.apply_template(
                            os.path.dirname(__file__) + "/tmpl-apidoc.rst",
                            annotation_parser,
                        )
                    )
                else:
                    line("%s\n%s\n" % (subsection, "#" * len(subsection)))
                    line()
                    for docline in dedent(docstring).splitlines():
                        if docline.strip() == "":
                            # Blank line.  Don't indent.
                            line()
                        else:
                            # Print documentation line, indented.
                            line(docline)
                line()
            else:
                line("%s\n%s\n" % (subsection, "#" * len(subsection)))
                line()

    line()
    line()
    line(generate_power_types_doc())
    line()
    line()
    line(generate_pod_types_doc())

    return output.getvalue()
Beispiel #23
0
    def test_parse_annotations(self):
        """Tests whether we can parse the sample."""

        docstring = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()
        api_docstring_parser.parse(docstring,
                                   http_method="mymethod",
                                   uri=self.test_uri_singular,
                                   operation="myoperation")
        d = api_docstring_parser.get_dict()

        params = d['params']
        successes = d['successes']
        errors = d['errors']

        self.assertEqual(d['http_method'], "mymethod")
        self.assertEqual(d['uri'], self.test_uri_singular)
        self.assertEqual(d['operation'], "myoperation")
        self.assertEqual(d['description_title'], "Docstring title")
        self.assertEqual(" ".join(d['description'].split()),
                         "Longer description with multiple lines.")

        p = params[0]
        self.assertEqual(p['type'], "String")
        self.assertEqual(p['name'], "param_name")
        self.assertEqual(" ".join(p['description'].split()),
                         "param description")
        self.assertEqual(" ".join(p['example'].split()), "param-ex")

        p = params[1]
        self.assertEqual(p['type'], "Int")
        self.assertEqual(p['name'], "param_name2")
        self.assertEqual(" ".join(p['description'].split()),
                         "param2 description")
        self.assertEqual(" ".join(p['example'].split()), "param2-ex")

        p = params[2]
        self.assertEqual(p['type'], "URL String")
        self.assertEqual(p['name'], "param_name3")
        self.assertEqual(" ".join(p['description'].split()),
                         "param3 description")
        self.assertEqual(" ".join(p['example'].split()), "param3-ex")

        p = params[3]
        self.assertEqual(p['type'], "JSON")
        self.assertEqual(p['name'], "param_name4")
        self.assertEqual(" ".join(p['description'].split()),
                         "param4 description")
        self.assertEqual(" ".join(p['example'].split()),
                         "{ \"id\": 1, \"foo\": \"bar\" }")

        p = params[4]
        self.assertEqual(p['type'], "Boolean")
        self.assertEqual(p['name'], "param_name5")
        self.assertEqual(" ".join(p['description'].split()),
                         "param5 description")
        self.assertEqual(" ".join(p['example'].split()), "True")

        p = params[5]
        self.assertEqual(p['type'], "Float")
        self.assertEqual(p['name'], "param_name6")
        self.assertEqual(" ".join(p['description'].split()),
                         "param6 description")
        self.assertEqual(" ".join(p['example'].split()), "1.5")

        s = successes[0]
        self.assertEqual(s['type'], "Content")
        self.assertEqual(s['name'], "success_name")
        self.assertEqual(" ".join(s['description'].split()),
                         "success description")
        self.assertEqual(" ".join(s['example'].split()), "success content")

        e = errors[0]
        self.assertEqual(e['type'], "HTTP Status Code")
        self.assertEqual(e['name'], "error_name")
        self.assertEqual(" ".join(e['description'].split()),
                         "error description")
        self.assertEqual(" ".join(e['example'].split()), "error content")
Beispiel #24
0
    def test_annotations_orphaned_example_tags(self):
        """Tests to ensure orphaned examples are found.

        Orphaned examples are example tags that have no matching
        non-example tag: E.g. param/param-example. The name field
        is used to determine matches.
        """
        docstring = self.sample_api_annotated_docstring
        api_docstring_parser = APIDocstringParser()
        docstring = docstring.replace("@param-example \"param_name\"",
                                      "@param-example \"param_name_bad\"")
        api_docstring_parser.parse(docstring, uri=self.test_uri_singular)
        d = api_docstring_parser.get_dict()
        self.assert_has_api_warning(d)

        docstring = docstring.replace("@error-example \"error_name\"",
                                      "@error-example \"error_name_bad\"")
        api_docstring_parser.parse(docstring, uri=self.test_uri_singular)
        d = api_docstring_parser.get_dict()
        self.assert_has_api_warning(d)

        docstring = docstring.replace("@success-example \"success_name\"",
                                      "@success-example \"success_name_bad\"")
        api_docstring_parser.parse(docstring, uri=self.test_uri_singular)
        d = api_docstring_parser.get_dict()
        self.assert_has_api_warning(d)