• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

collective / sphinxcontrib-httpexample / 7956692684

pending completion
7956692684

push

github

datakurre
ci: Install sphinxcontrib-httpexample in readthedocs

418 of 445 relevant lines covered (93.93%)

0.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/sphinxcontrib/httpexample/directives.py
1
# -*- coding: utf-8 -*-
2
from docutils import nodes
4✔
3
from docutils.parsers.rst import directives
4✔
4
from docutils.statemachine import StringList
4✔
5
from sphinx.directives.code import CodeBlock
4✔
6
from sphinxcontrib.httpexample import builders
4✔
7
from sphinxcontrib.httpexample import parsers
4✔
8
from sphinxcontrib.httpexample import utils
4✔
9

10
import os
4✔
11
import re
4✔
12

13

14
AVAILABLE_BUILDERS = {
4✔
15
    'curl': (builders.build_curl_command, 'bash'),
16
    'wget': (builders.build_wget_command, 'bash'),
17
    'httpie': (builders.build_httpie_command, 'bash'),
18
    'requests': (builders.build_requests_command, 'python'),
19
    'python-requests': (builders.build_requests_command, 'python'),
20
    'plone-javascript': (builders.build_plone_javascript_command,
21
                         'javascript'),
22
}
23

24
AVAILABLE_FIELDS = [
4✔
25
    'query'
26
]
27

28

29
def choose_builders(arguments):
4✔
30
    return [directives.choice(argument, AVAILABLE_BUILDERS)
4✔
31
            for argument in (arguments or [])]
32

33

34
class HTTPExample(CodeBlock):
4✔
35

36
    required_arguments = 0
4✔
37
    optional_arguments = len(AVAILABLE_BUILDERS)
4✔
38

39
    option_spec = utils.merge_dicts(CodeBlock.option_spec, {
4✔
40
        'request': directives.unchanged,
41
        'response': directives.unchanged,
42
    })
43

44
    def run(self):
4✔
45
        config = self.state.document.settings.env.config
4✔
46

47
        # Read enabled builders; Defaults to None
48
        chosen_builders = choose_builders(self.arguments)
4✔
49

50
        # Enable 'http' language for http part
51
        self.arguments = ['http']
4✔
52

53
        # process 'query' reST fields
54
        if self.content:
4✔
55
            raw = ('\r\n'.join(self.content)).encode('utf-8')
4✔
56
            request = parsers.parse_request(raw)
4✔
57
            params, _ = request.extract_fields('query')
4✔
58
            params = [(p[1], p[2]) for p in params]
4✔
59
            new_path = utils.add_url_params(request.path, params)
4✔
60
            self.content[0] = ' '.join(
4✔
61
                [request.command, new_path, request.request_version])
62

63
        # split the request and optional response in the content.
64
        # The separator is two empty lines followed by a line starting with
65
        # 'HTTP/' or 'HTTP '
66
        request_content = StringList()
4✔
67
        request_content_no_fields = StringList()
4✔
68
        response_content = None
4✔
69
        emptylines_count = 0
4✔
70
        in_response = False
4✔
71
        is_field = r':({}) (.+): (.+)'.format('|'.join(AVAILABLE_FIELDS))
4✔
72
        for i, line in enumerate(self.content):
4✔
73
            source = self.content.source(i)
4✔
74
            if in_response:
4✔
75
                response_content.append(line, source)
4✔
76
            else:
77
                if emptylines_count >= 2 and \
4✔
78
                        (line.startswith('HTTP/') or line.startswith('HTTP ')):
79
                    in_response = True
4✔
80
                    response_content = StringList()
4✔
81
                    response_content.append(line, source)
4✔
82
                elif line == '':
4✔
83
                    emptylines_count += 1
4✔
84
                else:
85
                    request_content.extend(
4✔
86
                        StringList([''] * emptylines_count, source))
87
                    request_content.append(line, source)
4✔
88

89
                    if not re.match(is_field, line):
4✔
90
                        request_content_no_fields.extend(
4✔
91
                            StringList([''] * emptylines_count, source))
92
                        request_content_no_fields.append(line, source)
4✔
93

94
                    emptylines_count = 0
4✔
95

96
        # Load optional external request
97
        cwd = os.path.dirname(self.state.document.current_source)
4✔
98
        if 'request' in self.options:
4✔
99
            request = utils.resolve_path(self.options['request'], cwd)
4✔
100
            with open(request) as fp:
4✔
101
                request_content = request_content_no_fields = StringList(
4✔
102
                    list(map(str.rstrip, fp.readlines())), request)
103

104
        # Load optional external response
105
        if 'response' in self.options:
4✔
106
            response = utils.resolve_path(self.options['response'], cwd)
4✔
107
            with open(response) as fp:
4✔
108
                response_content = StringList(
4✔
109
                    list(map(str.rstrip, fp.readlines())), response)
110

111
        # reset the content to the request, stripped of the reST fields
112
        self.content = request_content_no_fields
4✔
113

114
        # Wrap and render main directive as 'http-example-http'
115
        klass = 'http-example-http'
4✔
116
        container = nodes.container('', classes=[klass])
4✔
117
        container.append(nodes.caption('', 'http'))
4✔
118
        container.extend(super(HTTPExample, self).run())
4✔
119

120
        # Init result node list
121
        result = [container]
4✔
122

123
        # reset the content to just the request
124
        self.content = request_content
4✔
125

126
        # Append builder responses
127
        if request_content_no_fields:
4✔
128
            raw = ('\r\n'.join(request_content_no_fields)).encode('utf-8')
4✔
129
            for name in chosen_builders:
4✔
130
                request = parsers.parse_request(raw, config.httpexample_scheme)
4✔
131
                builder_, language = AVAILABLE_BUILDERS[name]
4✔
132

133
                # Setting plone JavaScript tab name
134
                name = 'JavaScript' if name == 'plone-javascript' else name
4✔
135

136
                command = builder_(request)
4✔
137

138
                content = StringList(
4✔
139
                    [command], request_content_no_fields.source(0))
140
                options = self.options.copy()
4✔
141
                options.pop('name', None)
4✔
142
                options.pop('caption', None)
4✔
143

144
                block = CodeBlock(
4✔
145
                    'code-block',
146
                    [language],
147
                    options,
148
                    content,
149
                    self.lineno,
150
                    self.content_offset,
151
                    self.block_text,
152
                    self.state,
153
                    self.state_machine
154
                )
155

156
                # Wrap and render main directive as 'http-example-{name}'
157
                klass = 'http-example-{}'.format(name)
4✔
158
                container = nodes.container('', classes=[klass])
4✔
159
                container.append(nodes.caption('', name))
4✔
160
                container.extend(block.run())
4✔
161

162
                # Append to result nodes
163
                result.append(container)
4✔
164

165
        # Append optional response
166
        if response_content:
4✔
167
            options = self.options.copy()
4✔
168
            options.pop('name', None)
4✔
169
            options.pop('caption', None)
4✔
170

171
            block = CodeBlock(
4✔
172
                'code-block',
173
                ['http'],
174
                options,
175
                response_content,
176
                self.lineno,
177
                self.content_offset,
178
                self.block_text,
179
                self.state,
180
                self.state_machine
181
            )
182

183
            # Wrap and render main directive as 'http-example-response'
184
            klass = 'http-example-response'
4✔
185
            container = nodes.container('', classes=[klass])
4✔
186
            container.append(nodes.caption('', 'response'))
4✔
187
            container.extend(block.run())
4✔
188

189
            # Append to result nodes
190
            result.append(container)
4✔
191

192
        # Final wrap
193
        container_node = nodes.container('', classes=['http-example'])
4✔
194
        container_node.extend(result)
4✔
195

196
        return [container_node]
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc