def test_lazy_value_by_parameter__faker(faker, seed, result):
    parameter = {'faker': faker, 'name': 'foo'}
    if hasattr(result, '__traceback__'):
        with pytest.raises(result):
            lazy_value_by_parameter(parameter, seed=seed)
    elif isinstance(result, (list, tuple)):
        assert lazy_value_by_parameter(parameter, seed=seed) in result
    else:
        assert lazy_value_by_parameter(parameter, seed=seed) == result
def test_lazy_value_by_parameter__values(values, seed, result):
    parameter = {'values': values, 'name': 'foo'}
    if hasattr(result, '__traceback__'):
        with pytest.raises(result):
            lazy_value_by_parameter(parameter, seed=seed)
    elif isinstance(result, Iterable):
        assert lazy_value_by_parameter(parameter, seed=seed) in result
    else:
        assert lazy_value_by_parameter(parameter, seed=seed) == result
def test_lazy_value_by_parameter__type(_type, seed, result, kwargs):
    parameter = {'name': 'foo'}
    if _type is not None:
        parameter['type'] = _type
    parameter.update(kwargs)

    if hasattr(result, '__traceback__'):
        with pytest.raises(result):
            lazy_value_by_parameter(parameter, seed=seed)
    elif isinstance(result, (list, tuple, range)):
        assert lazy_value_by_parameter(parameter, seed=seed) in result
    elif isinstance(result, LambdaType):
        assert result(lazy_value_by_parameter(parameter, seed=seed))
    else:
        assert lazy_value_by_parameter(parameter, seed=seed) == result
Esempio n. 4
0
def post(
    url,
    parameters=[],
    files={},
    headers={},
    indent=DEFAULT_INDENT,
    quote_char=DEFAULT_QUOTE_CHAR,
    setup=True,
    teardown=None,
    oneline=False,
    wrap=DEFAULT_WRAP,
    seed=None,
    locale=None,
    **kwargs,
):
    '''POST method code generator for Python requests library.'''
    # There are 4 possibilities of arguments build since we allow 4 forms
    #   of doing POST requests, depends on 'Content-Type' header content
    #   and the definition of 'files' optional argument. As default,
    #   'application/x-www-form-urlencoded'
    #   - len(files) > 0 -> files={}
    #   - Content-Type: 'multipart/form-data; boundary=-----...' -> files={}
    #   - Content-Type: 'application/x-www-form-urlencoded' -> data={}
    #   - Content-Type: 'text/plain' -> data=''
    #   - Content-Type: 'application/json' -> json={}
    _oneline = oneline
    response = ''

    # initialization
    setup_length = 0
    if setup:
        if isinstance(setup, str):
            response += setup
        else:
            response += ('import requests%(separator)s'
                         '%(newline)s%(newline)s') % {
                             'separator': ';' if oneline else '',
                             'newline': '\n' if not oneline else '',
                         }
        if oneline:
            setup_length += len(response)

    # url length
    url_length = len(url) + 22  # 'req = requests.post(' (20) + '' (2)

    # headers length and content-type discovering
    if files:
        content_type = 'multipart/form-data'
        _content_type_found = True
    else:
        content_type = 'application/x-www-form-urlencoded'
        _content_type_found = False

    headers_line_length = 0
    if headers:
        headers_keys = {} if not isinstance(headers, OrderedDict) \
            else OrderedDict({})
        headers_line_length += 10  # headers={}
        for key, value in headers.items():
            escaped_key = escape_by_quote(key, quote_char)
            escaped_value = escape_by_quote(value, quote_char)
            headers_keys[escaped_key] = escaped_value
            # 2 is ': '
            headers_line_length += \
                len(quote_char) * 4 + 2 + len(escaped_key) + len(escaped_value)
            if not _content_type_found:
                _key_lower = str(key).lower()
                if _key_lower == 'content-type':
                    if 'text/plain' in value:
                        content_type = 'text/plain'
                        _content_type_found = True
                    elif 'application/json' in value:
                        content_type = 'application/json'
                        _content_type_found = True
        headers_line_length += len(headers) - 1  # commas except last
        if kwargs:
            headers_line_length += 2  # ', '

    if content_type == 'text/plain' and len(parameters) != 1:
        raise_post_text_plain_n_parameters_not_1(len(parameters))

    # data/json length
    parameters_line_length = 0
    if parameters:
        parameters_keys = OrderedDict({})

        # length depends on kwarg used in the request
        parameters_line_length = {
            'multipart/form-data': 0,  # files={}
            'application/json': 7,  # json={}
            'application/x-www-form-urlencoded': 7,  # data={}
        }.get(content_type, 5)  # (text/*)             data=

        for parameter in parameters:
            if content_type == 'text/plain':
                name = ''
            else:
                name = escape_by_quote(
                    lazy_name_by_parameter(parameter, seed=seed),
                    quote_char,
                )

            # JSON must accepts other data types than string
            _param_value = parameter.get('value')
            if content_type == 'application/json' and isinstance(
                    _param_value,
                (int, float, bool),
            ):
                value = _param_value
                parameters_line_length += len(name) + 4 + len(str(value))
            else:
                if content_type == 'text/plain':
                    _param_value_def_indent = indent + (' ' * 5)
                else:
                    _param_value_def_indent = indent + (' ' * (8 + len(name)))
                value = str_definition(
                    lazy_value_by_parameter(
                        parameter,
                        seed=seed,
                        locale=locale,
                    ),
                    quote_char=quote_char,
                    indent=_param_value_def_indent,
                    wrap=wrap,
                )
                parameters_line_length += len(name) + 4 + len(value)

            if content_type == 'text/plain':
                parameters_line_length += len(value) + 2
            elif content_type != 'application/json':
                parameters_line_length += len(name) + 4 + len(value)
            parameters_keys[name] = value
        parameters_line_length += len(parameters) - 1  # commas except last
        if files or headers or kwargs:
            parameters_line_length += 2  # ', '

    # files length
    files_line_length = 0
    if files:
        files_line_length = 8  # files={}
        files_keys = {} if not isinstance(files, OrderedDict) \
            else OrderedDict({})
        for key, value in files.items():
            escaped_key = escape_by_quote(key, quote_char)
            files_line_length += len(escaped_key) + 4

            files_keys[escaped_key] = []

            if isinstance(value, str) or value is None:
                # random filepath
                if value is None:
                    value = lazy_value_by_parameter(
                        {
                            'name': '',
                            'faker': 'faker.providers.file::file_path',
                        },
                        seed=seed,
                        locale=locale,
                    )

                escaped_value = escape_by_quote(value, quote_char)
                files_keys[escaped_key].append(escaped_value)

            else:  # iterable
                if len(value) > 2:
                    # file headers
                    _fheaders = {}
                    for hkey, hvalue in value[2].items():
                        _escaped_key = escape_by_quote(hkey, quote_char)
                        files_line_length += len(_escaped_key) + 4

                        _escaped_value = escape_by_quote(hvalue, quote_char)
                        files_line_length += len(_escaped_value) + 2

                        _fheaders[_escaped_key] = _escaped_value
                    # commas except last + prev ', '
                    files_line_length += len(value[2]) + 2
                    files_keys[escaped_key].append(_fheaders)
                if len(value) > 1:
                    # file content type
                    _escaped_value = escape_by_quote(value[1], quote_char)
                    files_line_length += len(_escaped_value) + 4  # prev ', '
                    files_keys[escaped_key].insert(0, _escaped_value)

                # random filepath
                if value[0] is None:
                    value = list(value)
                    value[0] = lazy_value_by_parameter(
                        {
                            'name': '',
                            'faker': 'faker.providers.file::file_path',
                        },
                        seed=seed,
                        locale=locale,
                    )
                escaped_value = escape_by_quote(value[0], quote_char)
                files_keys[escaped_key].insert(0, escaped_value)

            _filepath = value if isinstance(value, str) else value[0]
            _indent = indent * 4
            _filepath_def = str_definition(
                _filepath,
                indent=_indent,
                quote_char=quote_char,
                wrap=wrap,
            )
            _open_file_multiline = len(_filepath_def) + len(_indent) > wrap
            _open_file_string = (
                'open(%(newline)s%(indent1)s%(value)s,'
                '%(newline)s%(indent2)s%(quote_char)srb'
                '%(quote_char)s%(newline)s%(indent3)s)') % {
                    'quote_char': quote_char,
                    'value': _filepath_def,
                    'newline': '\n' if _open_file_multiline else '',
                    'indent1': _indent if _open_file_multiline else '',
                    'indent2': _indent if _open_file_multiline else ' ',
                    'indent3': indent * 3 if _open_file_multiline else '',
                }
            files_keys[escaped_key].insert(1, _open_file_string)

            # 2 filename quotes + () of tuple + , open('', 'rb')
            files_line_length += len(escaped_value) * 2 + 20

        files_line_length += len(parameters) - 1  # commas except last

    kwargs_line_length = 0
    if kwargs:
        kwargs_line_length = 2
        for key, value in kwargs.items():
            kwargs_line_length += len(key) + len(str(value))
            if isinstance(value, str):
                kwargs_line_length += 2
        kwargs_line_length += len(kwargs) - 1  # commas except last

    # oneliner by wrapping
    #   here + 1 is function call end ')' and - 1 is the character wrapping,
    #   so both are negated
    if setup_length + url_length + parameters_line_length + \
            headers_line_length + files_line_length + \
            kwargs_line_length < wrap:
        oneline = True

    # url
    response += ('req = requests.post(%(newline)s%(indent)s%(url)s%(newline2)s'
                 '%(comma)s%(space)s%(newline3)s') % {
                     'url': ('{quote_char}{url}{quote_char}'.format(
                         url=url,
                         quote_char=quote_char,
                     )) if oneline else str_definition(
                         url,
                         indent=indent,
                         quote_char=quote_char,
                         wrap=wrap,
                     ),
                     'indent':
                     indent if not oneline else '',
                     'newline':
                     '\n' if not oneline else '',
                     'newline2':
                     '\n' if not oneline and
                     (not headers and not files and not parameters
                      and not kwargs) else '',
                     'comma':
                     ',' if (files or headers or parameters or kwargs) else '',
                     'space':
                     ' ' if oneline and
                     (files or parameters or headers or kwargs) else '',
                     'newline3':
                     '\n' if not oneline and
                     (files or parameters or headers or kwargs) else '',
                 }

    # parameters render
    if parameters:
        response += '{indent}{kwarg_name}='.format(
            indent=indent if not oneline else '',
            kwarg_name='json'
            if content_type == 'application/json' else 'data',
        )
        if content_type == 'text/plain':
            response += '{value}{comma}{newline}'.format(
                value=parameters_keys[''],
                comma=',' if
                (not oneline or files or headers or kwargs) else '',
                newline='\n' if not oneline else ' ',
            )
        else:
            response += '{{{newline}'.format(
                newline='\n' if not oneline else '', )
            for i, (pname, pvalue) in enumerate(parameters_keys.items()):
                response += ('%(indent)s%(quote_char)s%(parameter_name)s'
                             '%(quote_char)s: %(value)s%(comma)s') % {
                                 'parameter_name': pname,
                                 'indent': indent * 2 if not oneline else '',
                                 'quote_char': quote_char,
                                 'value': pvalue,
                                 'comma':
                                 ',' if i < len(parameters) - 1 else '',
                             }
                response += '\n' if not oneline else ''

            response += '{indent}}}{comma}{newline}'.format(
                indent=indent if not oneline else '',
                comma=',' if (files or headers or kwargs) else '',
                newline='\n' if not oneline else
                ('' if (not headers and not files and not kwargs) else ' '),
            )

    # files render
    if files:
        response += '{indent}files={{{newline}'.format(
            indent=indent if not oneline else '',
            newline='\n' if not oneline else '',
        )

        for i, (fkey, fvalue) in enumerate(files_keys.items()):
            _value = ('(%(newline1)s%(indent)s%(fpath)s,%(newline2)s'
                      '%(indent)s%(open_file_string)s') % {
                          'newline1':
                          '\n' if not oneline else '',
                          'newline2':
                          '\n' if not oneline else ' ',
                          'indent':
                          indent * 3 if not oneline else '',
                          'fpath':
                          str_definition(
                              fvalue[0],
                              quote_char=quote_char,
                              indent=indent * 3,
                              wrap=wrap,
                          ),
                          'open_file_string':
                          fvalue[1],
                      }
            if len(fvalue) > 2:
                _value += ',{newline}{indent}{content_type}'.format(
                    content_type=str_definition(
                        fvalue[2],
                        quote_char=quote_char,
                        indent=indent * 3,
                        wrap=wrap,
                    ),
                    newline='\n' if not oneline else '',
                    indent=indent * 3 if not oneline else ' ',
                )
            if len(fvalue) > 3:
                _value += ',{newline}{indent}{headers}'.format(
                    headers=dict_definition(
                        fvalue[3],
                        indent=indent if not oneline else '',
                        indent_depth=3,
                        quote_char=quote_char,
                        newline='\n' if not oneline else '',
                        _escape_keys=False,
                        _escape_values=False,
                    ),
                    newline='\n' if not oneline else '',
                    indent=indent * 3 if not oneline else ' ',
                )
            _value += '{newline}{indent})'.format(
                newline='' if oneline else '\n',
                indent='' if oneline else indent * 2,
            )
            response += ('%(indent)s%(quote_char)s%(key)s'
                         '%(quote_char)s: %(value)s%(comma)s') % {
                             'key': fkey,
                             'indent': indent * 2 if not oneline else '',
                             'quote_char': quote_char,
                             'value': _value,
                             'comma': ',' if i < len(files_keys) - 1 else '',
                         }
            response += '\n' if not oneline else ''

        response += '{indent}}}{comma}{newline}'.format(
            indent=indent if not oneline else '',
            comma=',' if (headers or kwargs) else '',
            newline='\n' if not oneline else (' ' if
                                              (headers or kwargs) else ''),
        )

    if headers:
        response += '{headers}{comma}{newline}'.format(
            headers=kwarg_definition_dict_valued(
                'headers',
                headers_keys,
                indent=indent if not oneline else '',
                quote_char=quote_char,
                newline='\n' if not oneline else '',
                _escape_keys=False,
                _escape_values=False,
            ),
            newline='\n' if not oneline else ('' if not kwargs else ' '),
            comma=',' if kwargs else '',
        )

    # kwargs render
    if kwargs:
        for i, (key, value) in enumerate(kwargs.items()):
            response += '{indent}{repr_kwarg}{comma}{newline}'.format(
                indent='' if oneline or isinstance(value, dict) else indent,
                repr_kwarg=kwarg_definition(
                    key,
                    value,
                    indent='' if oneline else indent,
                    indent_depth=1,
                    quote_char=quote_char,
                    wrap=wrap,
                ),
                comma=',' if i < len(kwargs) - 1 else '',
                newline='\n' if not oneline else
                (' ' if i < len(kwargs) - 1 else ''),
            )

    response += '){separator}'.format(separator=';' if _oneline else '')

    if teardown:
        response += str(teardown)
    return response
Esempio n. 5
0
def get(
    url,
    parameters=[],
    headers={},
    indent=DEFAULT_INDENT,
    quote_char=DEFAULT_QUOTE_CHAR,
    setup=True,
    teardown=None,
    oneline=False,
    wrap=DEFAULT_WRAP,
    seed=None,
    locale=None,
    **kwargs,
):
    '''Parameters are passed using
    [``requests.get``](https://requests.readthedocs.io/en/api/#requests.get)
    function ``params`` parameter, not by appending ``?foo=bar&...`` to the
    URL. If you want this behaviour, build the passed URL using
    [``lazy_name_by_parameter``](/reference#lazy_name_by_parameter) and
    [``lazy_value_by_parameter``](/reference#lazy_value_by_parameter) functions
    instead of use the ``parameters`` argument.

    If you want to import more modules in the initialization snippet, keep
    in mind that you must provide ``import requests`` line also in the
    ``setup`` argument. For example,
    ``setup=\'import requests\\nimport foo\\n\\n\'`` will render as:

    ```python
    import requests
    import foo

    requests.get('<url>'...
    ```
    '''
    _oneline = oneline
    response = ''

    # initialization
    setup_length = 0
    if setup:
        if isinstance(setup, str):
            response += setup
        else:
            response += ('import requests%(separator)s'
                         '%(newline)s%(newline)s') % {
                             'separator': ';' if oneline else '',
                             'newline': '\n' if not oneline else '',
                         }
        if oneline:
            setup_length += len(response)

    # url length
    url_length = len(url) + 21  # 'req = requests.get(' (19) + '' (2)

    # parameters length
    parameters_line_length = 0
    if parameters:
        parameters_keys = OrderedDict({})
        parameters_line_length = 9  # 'params={}'
        for parameter in parameters:
            name = escape_by_quote(
                lazy_name_by_parameter(parameter, seed=seed),
                quote_char,
            )
            value = str_definition(
                lazy_value_by_parameter(parameter, seed=seed, locale=locale),
                quote_char=quote_char,
                indent=indent + (' ' * (8 + len(name))),
                wrap=wrap,
            )
            parameters_keys[name] = value
            parameters_line_length += len(name) + 4 + len(value)
        parameters_line_length += len(parameters) - 1  # commas except last
        if headers or kwargs:
            parameters_line_length += 2  # ', '

    headers_line_length = 0
    if headers:
        headers_keys = {} if not isinstance(headers, OrderedDict) \
            else OrderedDict({})
        headers_line_length += 10  # headers={}
        for key, value in headers.items():
            escaped_key = escape_by_quote(key, quote_char)
            escaped_value = escape_by_quote(value, quote_char)
            headers_keys[escaped_key] = escaped_value
            # 2 is ': '
            headers_line_length += \
                len(quote_char) * 4 + 2 + len(escaped_key) + len(escaped_value)
        headers_line_length += len(headers) - 1  # commas except last
        if kwargs:
            headers_line_length += 2  # ', '

    kwargs_line_length = 0
    if kwargs:
        kwargs_line_length = 2
        for key, value in kwargs.items():
            kwargs_line_length += len(key) + len(str(value))
            if isinstance(value, str):
                kwargs_line_length += 2
        kwargs_line_length += len(kwargs) - 1  # commas except last

    # oneliner by wrapping
    #   here + 1 is function call end ')' and - 1 is the character wrapping,
    #   so both are negated
    if setup_length + url_length + parameters_line_length + \
            headers_line_length + kwargs_line_length < wrap:
        oneline = True

    # url
    response += ('req = requests.get(%(newline)s%(indent)s%(url)s%(newline2)s'
                 '%(comma)s%(space)s%(newline3)s') % {
                     'url': ('{quote_char}{url}{quote_char}'.format(
                         url=url,
                         quote_char=quote_char,
                     )) if oneline else str_definition(
                         url,
                         indent=indent,
                         quote_char=quote_char,
                         wrap=wrap,
                     ),
                     'indent':
                     indent if not oneline else '',
                     'newline':
                     '\n' if not oneline else '',
                     'newline2':
                     '\n' if not oneline and
                     (not headers and not parameters and not kwargs) else '',
                     'comma':
                     ',' if headers or parameters or kwargs else '',
                     'space':
                     ' ' if oneline and
                     (parameters or headers or kwargs) else '',
                     'newline3':
                     '\n' if not oneline and
                     (headers or parameters or kwargs) else '',
                 }

    # parameters render
    if parameters:
        response += '{indent}params={{{newline}'.format(
            indent=indent if not oneline else '',
            newline='\n' if not oneline else '',
        )
        for i, (pname, pvalue) in enumerate(parameters_keys.items()):
            response += ('%(indent)s%(quote_char)s%(parameter_name)s'
                         '%(quote_char)s: %(value)s%(comma)s') % {
                             'parameter_name': pname,
                             'indent': indent * 2 if not oneline else '',
                             'quote_char': quote_char,
                             'value': pvalue,
                             'comma': ',' if i < len(parameters) - 1 else '',
                         }
            response += '\n' if not oneline else ''

        response += '{indent}}}{comma}{newline}'.format(
            indent=indent if not oneline else '',
            comma=',' if (headers or kwargs) else '',
            newline='\n' if not oneline else
            ('' if (not headers and not kwargs) else ' '),
        )

    # headers render
    if headers:
        response += '{header}{comma}{newline}'.format(
            header=kwarg_definition_dict_valued(
                'headers',
                headers_keys,
                indent=indent if not oneline else '',
                quote_char=quote_char,
                newline='\n' if not oneline else '',
                _escape_keys=False,
                _escape_values=False,
            ),
            newline='\n' if not oneline else ('' if not kwargs else ' '),
            comma=',' if kwargs else '',
        )

    # kwargs render
    if kwargs:
        for i, (key, value) in enumerate(kwargs.items()):
            response += '{indent}{repr_kwarg}{comma}{newline}'.format(
                indent='' if oneline or isinstance(value, dict) else indent,
                repr_kwarg=kwarg_definition(
                    key,
                    value,
                    indent='' if oneline else indent,
                    quote_char=quote_char,
                    wrap=wrap,
                ),
                comma=',' if i < len(kwargs) - 1 else '',
                newline='\n' if not oneline else
                (' ' if i < len(kwargs) - 1 else ''),
            )

    response += '){separator}'.format(separator=';' if _oneline else '')

    if teardown:
        response += str(teardown)
    return response
def test_lazy_value_by_parameter__value(value):
    '''Passing the attribute 'value', will be casted to string.'''
    assert lazy_value_by_parameter({'value': value}) == str(value)
Esempio n. 7
0
def get(
    url,
    parameters=[],
    headers={},
    indent=DEFAULT_INDENT,
    quote_char=DEFAULT_QUOTE_CHAR,
    setup=False,
    teardown=None,
    oneline=False,
    wrap=DEFAULT_WRAP,
    seed=None,
    locale=None,
    **kwargs,
):
    '''Pass extra options to 'curl' command in ``kwargs`` parameter. For
    example, to save the response in a file, pass
    ``kwargs={'-o': 'filename.ext'}``:

    ```bash
    curl -o "filename.ext"
    ```
    '''
    '''In this implementation, options values and URLs are not wrapped in
    multiples lines if these values exceed the wrap length.
    '''
    response = ''

    if setup:
        response += str(setup)

    response += 'curl'

    options_string = ''
    options_map = []
    if kwargs or parameters:
        _d_option_included = False
        for option_name, option_value in kwargs.items():
            options_string += f' {option_name}'
            if option_value:
                option_value_string = escape_by_quote(
                    str(option_value),
                    quote_char,
                )
                options_string += ' ' + option_value_string
            else:
                option_value_string = None
            options_map.append([option_name, option_value_string])

            if option_name == '-X' and option_value != 'GET':
                raise ValueError('\'-X\' option, if defined, must be \'GET\'')

            if option_name == '-d':
                _d_option_included = True

        if parameters:
            if _d_option_included:
                raise ValueError(
                    'You can\'t pass the option \'-d\' and parameters with'
                    ' \'parameters\' value.', )

            parameters_dict = OrderedDict({})
            for parameter in parameters:
                parameter_name = lazy_name_by_parameter(parameter, seed=seed)
                parameter_value = lazy_value_by_parameter(
                    parameter,
                    seed=seed,
                    locale=locale,
                )
                parameters_dict[parameter_name] = parameter_value

            params_string = escape_by_quote(
                urlencode(parameters_dict),
                quote_char,
            )
            options_string += ' -d {quote_char}{params}{quote_char}'.format(
                quote_char=quote_char,
                params=params_string,
            )
            options_map.append(['-d', params_string])

    if headers:
        headers_map, headers_string, _ = _build_headers(
            headers,
            quote_char=quote_char,
        )
        options_map.extend(headers_map)
        options_string += headers_string

    # 1 here is a space
    if len(options_string) + len(url) + len(response) + 1 < wrap:
        oneline = True
    response += ' '

    response += _render_options_map(
        options_map,
        options_string,
        url,
        oneline=oneline,
        indent=indent,
        quote_char=quote_char,
    )

    if teardown:
        response += str(teardown)

    return response
Esempio n. 8
0
def post(
    url,
    parameters=[],
    files={},
    headers={},
    indent=DEFAULT_INDENT,
    quote_char=DEFAULT_QUOTE_CHAR,
    setup=False,
    teardown=None,
    oneline=False,
    wrap=DEFAULT_WRAP,
    seed=None,
    locale=None,
    **kwargs,
):
    response = ''

    if setup:
        response += str(setup)

    response += 'curl'

    options_string = ''
    options_map = []

    # Build headers and discover content type
    headers_map, headers_string, content_type = _build_headers(
        headers,
        quote_char=quote_char,
        content_type='application/x-www-form-urlencoded'
        if not files else 'multipart/form-data',
    )

    _x_post_defined = False
    if kwargs:
        for option_name, option_value in kwargs.items():
            options_string += f' {option_name}'
            if option_value:
                option_value_str = str(option_value)
                options_string += (' %(quote_char)s%(value)s'
                                   '%(quote_char)s') % {
                                       'quote_char': quote_char,
                                       'value': option_value_str,
                                   }
            else:
                option_value_str = None
            options_map.append([option_name, option_value_str])

            if option_name == '-X':
                if option_value != 'POST':
                    raise ValueError(
                        '\'-X\' option, if defined, must be \'POST\'', )
                else:
                    _x_post_defined = True

    # Add method option
    if not _x_post_defined:
        options_string += ' -X POST'
        options_map.append(['-X', 'POST'])

    # Add parameters
    if parameters:
        parameters_dict = OrderedDict({})
        for parameter in parameters:
            parameter_name = lazy_name_by_parameter(parameter, seed=seed)
            parameter_value = lazy_value_by_parameter(
                parameter,
                seed=seed,
                locale=locale,
            )
            parameters_dict[parameter_name] = parameter_value

        # parameters codification
        if content_type == 'multipart/form-data':
            for param_name, param_value in parameters_dict.items():
                option_value = '{name}={value}'.format(
                    name=param_name,
                    value=param_value,
                )
                options_map.append(['-F', option_value])
                options_string += f' -F {option_value}'
        else:
            encode_func = json.dumps if content_type == 'application/json' \
                else urlencode

            option_value = encode_func(parameters_dict)
            options_map.append(['-d', option_value])
            options_string += ' -d {quote_char}{params}{quote_char}'.format(
                quote_char=quote_char,
                params=option_value,
            )
    else:
        parameters_dict = {}

    # Add files
    if files:
        for file_param_name, file_data in files.items():
            if file_data is None:
                file_data = lazy_value_by_parameter(
                    {
                        'name': '',
                        'faker': 'faker.providers.file::file_path',
                    },
                    seed=seed,
                    locale=locale,
                )
            elif isinstance(file_data, str):
                file_data = file_data
            else:  # Iterable
                if file_data[0] is None:
                    file_data = lazy_value_by_parameter(
                        {
                            'name': '',
                            'faker': 'faker.providers.file::file_path',
                        },
                        seed=seed,
                        locale=locale,
                    )
                else:
                    file_data = file_data[0]
            option_value = f'{file_param_name}=@'
            option_value += file_data
            options_string += f' -F {option_value}'
            options_map.append(['-F', option_value])

    # Add headers
    options_string += headers_string
    options_map.extend(headers_map)

    # 1 here is a space
    _current_length = len(options_string) + len(url) + len(response) + 1 \
        + len(headers) * 2 * len(quote_char)
    if _current_length < wrap:
        oneline = True

    # Renderize options
    response += ' '
    response += _render_options_map(
        options_map,
        options_string,
        url,
        oneline=oneline,
        indent=indent,
        quote_char=quote_char,
    )

    if teardown:
        response += str(teardown)

    return response
Esempio n. 9
0
def post(
    url,
    parameters=[],
    files={},
    headers={},
    indent=DEFAULT_INDENT,
    quote_char=DEFAULT_QUOTE_CHAR,
    setup=True,
    teardown=None,
    oneline=False,
    wrap=DEFAULT_WRAP,
    seed=None,
    locale=None,
    **kwargs,
):
    # (no setup -> web / setup -> node)
    response = ''

    # Discover content-type
    content_type = 'application/x-www-form-urlencoded'
    for key, value in headers.items():
        if key.lower() == 'content-type':
            content_type = value
            break
    if content_type.startswith('multipart/form-data') or files:
        content_type = 'multipart/form-data'

    # Initialization will depend on content type
    if setup:
        if isinstance(setup, str):
            response += setup
        else:
            if content_type == 'multipart/form-data':
                response += ('const fs = require(%(quote_char)s'
                             'fs%(quote_char)s);%(newline)s%(newline)s') % {
                                 'quote_char': quote_char,
                                 'newline': '\n' if not oneline else '',
                             }
            response += ('const fetch = require(%(quote_char)s'
                         'node-fetch%(quote_char)s);') % {
                             'quote_char': quote_char,
                         }
            if content_type == 'multipart/form-data':
                response += ('%(newline)sconst FormData = require('
                             '%(quote_char)sform-data%(quote_char)s);') % {
                                 'quote_char': quote_char,
                                 'newline': '\n' if not oneline else '',
                             }
            if not oneline:
                response += '\n\n'

    if content_type == 'multipart/form-data':
        body = 'formData'

        # if we are sending files from the browser, select all files
        if not setup and files:
            response += ('const files = document.querySelector('
                         '%(quote_char)sinput[type=%(other_quote_char)s'
                         'file%(other_quote_char)s]%(quote_char)s);'
                         '%(newline)s%(newline)s') % {
                             'quote_char': quote_char,
                             'other_quote_char':
                             '"' if quote_char == '\'' else '\'',
                             'newline': '\n' if not oneline else '',
                         }

        response += 'const formData = new FormData();{newline}'.format(
            newline='\n' if not oneline else '', )

        # parameters render
        for parameter in parameters:
            name = lazy_name_by_parameter(parameter, seed=seed)
            value = lazy_value_by_parameter(
                parameter,
                seed=seed,
                locale=locale,
            )

            # 20 here is the length of `formData.append(, );`
            _multiline_param = False
            if 20 + len(quote_char) * 4 + len(name) + len(str(value)) > wrap:
                _multiline_param = True

            if _multiline_param:
                _param_name = str_definition(
                    name,
                    indent=indent,
                    quote_char=quote_char,
                    wrap=wrap,
                )
                _param_value = str_definition(
                    value,
                    indent=indent,
                    quote_char=quote_char,
                    wrap=wrap,
                )
            else:
                _value_name_schema = '%(quote_char)s%(string)s%(quote_char)s'
                _param_name = _value_name_schema % {
                    'quote_char': quote_char,
                    'string': escape_by_quote(name, quote_char),
                }
                _param_value = _value_name_schema % {
                    'quote_char': quote_char,
                    'string': escape_by_quote(str(value), quote_char),
                }

            response += ('formData.append(%(newline)s%(indent)s'
                         '%(param_name)s,%(space)s'
                         '%(newline)s%(indent)s%(param_value)s'
                         '%(newline)s);') % {
                             'newline': '\n' if
                             (not oneline and _multiline_param) else '',
                             'indent': indent if
                             (not oneline and _multiline_param) else '',
                             'space': ' ',
                             'param_name': _param_name,
                             'param_value': _param_value,
                         }
            if not oneline:
                response += '\n'

        # files render
        for i, (file_param_name, file_data) in enumerate(files.items()):
            response += 'formData.append('
            if not oneline:
                _file_param_name = str_definition(
                    file_param_name,
                    quote_char=quote_char,
                    wrap=wrap,
                    indent=indent,
                )
            else:
                _file_param_name = ('%(quote_char)s'
                                    '%(file_param_name)s'
                                    '%(quote_char)s') % {
                                        'quote_char':
                                        quote_char,
                                        'file_param_name':
                                        escape_by_quote(
                                            file_param_name,
                                            quote_char,
                                        ),
                                    }

            response += ('%(newline)s%(indent)s%(file_param_name)s,%(space)s'
                         '%(newline)s%(indent)s') % {
                             'newline': '\n' if not oneline else '',
                             'indent': indent if not oneline else '',
                             'file_param_name': _file_param_name,
                             'space': ' ' if oneline else '',
                         }

            if setup:
                response += 'fs.createReadStream('  # length: 20

                if isinstance(file_data, str):
                    filepath = file_data
                else:
                    filepath = file_data[0] if file_data is not None else None
                if filepath is None:
                    filepath = lazy_value_by_parameter(
                        {
                            'name': '',
                            'faker': 'faker.providers.file::file_path',
                        },
                        seed=seed,
                        locale=locale,
                    )

                if not oneline:
                    _filepath = str_definition(
                        filepath,
                        quote_char=quote_char,
                        wrap=wrap,
                        indent=' ' * (len(indent) + 20),
                    )
                    _filename = str_definition(
                        os.path.basename(filepath),
                        quote_char=quote_char,
                        wrap=wrap,
                        indent=' ' * (len(indent) * 2 + 10),
                    )  # 'filename: '
                else:
                    _filepath = '{quote_char}{filepath}{quote_char}'.format(
                        quote_char=quote_char,
                        filepath=escape_by_quote(filepath, quote_char),
                    )
                    _filename = '{quote_char}{filename}{quote_char}'.format(
                        quote_char=quote_char,
                        filename=escape_by_quote(
                            os.path.basename(filepath),
                            quote_char,
                        ),
                    )

                response += ('%(filepath)s),%(space)s%(newline)s%(indent)s{'
                             '%(newline)s%(indent)s%(indent)s'
                             'filename: %(filename)s') % {
                                 'space': ' ' if oneline else '',
                                 'newline': '\n' if not oneline else '',
                                 'indent': indent if not oneline else '',
                                 'filepath': _filepath,
                                 'filename': _filename,
                             }
                if not isinstance(file_data, str) and file_data is not None:
                    if len(file_data) > 1:
                        if not oneline:
                            _content_type = str_definition(
                                file_data[1],
                                quote_char=quote_char,
                                wrap=wrap,
                                indent=' ' * (len(indent) * 2 + 13),
                            )
                        else:
                            _content_type = ('%(quote_char)s%(content_type)s'
                                             '%(quote_char)s') % {
                                                 'quote_char':
                                                 quote_char,
                                                 'content_type':
                                                 escape_by_quote(
                                                     file_data[1],
                                                     quote_char,
                                                 ),
                                             }

                        response += (
                            ',%(newline)s%(indent)s%(indent)s'
                            'contentType: %(content_type)s') % {
                                'content_type': _content_type,
                                'newline': '\n' if not oneline else '',
                                'indent': indent if not oneline else '',
                            }
                response += '{newline}{indent}}}{newline}'.format(
                    newline='\n' if not oneline else '',
                    indent=indent if not oneline else '',
                )
            else:
                # TODO: Manage content_type and filename?
                response += 'inputs[%(input_index)d].files[0]%(newline)s' % {
                    'input_index': i,
                    'newline': '\n' if not oneline else '',
                }
            response += ');{newline}'.format(
                newline='\n' if not oneline else '', )
        response += '\n'
    elif content_type == 'text/plain':
        if len(parameters) != 1:
            raise_post_text_plain_n_parameters_not_1(len(parameters))

        _value = lazy_value_by_parameter(
            parameters[0],
            seed=seed,
            locale=locale,
        )
        body = str_definition(
            _value,
            indent=' ' * (len(indent) * 2 + 6),
            quote_char=quote_char,
            wrap=wrap,
        )
    else:  # 'application/json' or 'application/x-www-form-urlencoded'
        object_content = ''

        for i, parameter in enumerate(parameters):
            name = lazy_name_by_parameter(parameter, seed=seed)
            value = lazy_value_by_parameter(
                parameter,
                seed=seed,
                locale=locale,
            )

            if oneline:
                name_def = '{quote_char}{name}{quote_char}'.format(
                    name=escape_by_quote(name, quote_char),
                    quote_char=quote_char,
                )
                value_def = '{quote_char}{value}{quote_char}'.format(
                    value=escape_by_quote(value, quote_char),
                    quote_char=quote_char,
                )
            else:
                name_def = str_definition(
                    name,
                    indent=indent * 3,
                    quote_char=quote_char,
                    wrap=wrap,
                )
                _value_def_indent = ' ' * (len(indent) * 3 + len(name_def) + 2)
                value_def = str_definition(
                    value,
                    indent=_value_def_indent,
                    quote_char=quote_char,
                    wrap=wrap,
                )

            object_content += ('%(indent)s%(name)s: %(value)s%(comma)s'
                               '%(newline)s') % {
                                   'name':
                                   name_def,
                                   'indent':
                                   indent * 3,
                                   'value':
                                   value_def,
                                   'comma':
                                   ',' if i < (len(parameters) - 1) else '',
                                   'newline':
                                   '\n' if (not oneline and i <
                                            (len(parameters) - 1)) else '',
                               }

        if object_content:
            body = ('%(object_wrapper)s({%(newline)s'
                    '%(object_content)s%(newline)s%(indent)s})') % {
                        'object_wrapper':
                        'JSON.stringify' if content_type == 'application/json'
                        else 'new URLSearchParams',
                        'object_content':
                        object_content,
                        'newline':
                        '\n' if not oneline else '',
                        'indent':
                        indent * 2,
                    }
        else:
            body = ''

    response += ('fetch(%(newline)s%(indent)s%(url)s,%(space)s%(newline)s'
                 '%(indent)s{%(indent)s%(newline)s%(indent)s%(indent)smethod:'
                 ' %(quote_char)sPOST%(quote_char)s%(comma)s%(newline)s') % {
                     'newline':
                     '\n' if not oneline else '',
                     'indent':
                     indent if not oneline else '',
                     'space':
                     ' ' if oneline else '',
                     'quote_char':
                     quote_char,
                     'comma':
                     ',' if (body or kwargs or headers) else '',
                     'url':
                     str_definition(
                         url,
                         quote_char=quote_char,
                         indent=indent,
                         wrap=wrap,
                     ),
                 }

    if body:
        response += ('%(indent)s%(indent)sbody:'
                     ' %(body)s%(comma)s%(newline)s') % {
                         'newline': '\n' if not oneline else '',
                         'indent': indent if not oneline else '',
                         'comma': ',' if (kwargs or headers) else '',
                         'body': body,
                     }

    # headers render
    if headers:
        response += _headers_render(
            headers,
            indent=indent,
            oneline=oneline,
            quote_char=quote_char,
            wrap=wrap,
            _comma_at_end=bool(kwargs),
        )

    # kwargs render
    if kwargs:
        response += _kwargs_render(
            kwargs,
            indent=indent,
            oneline=oneline,
            quote_char=quote_char,
            wrap=wrap,
        )

    response += '{indent}}}{newline}'.format(
        indent=indent if not oneline else '',
        newline='\n' if not oneline else '',
    )

    response += _promises_chain_render(
        quote_char=quote_char,
        indent=indent,
        oneline=oneline,
    )

    if teardown:
        response += teardown

    return response
Esempio n. 10
0
def get(
    url,
    parameters=[],
    headers={},
    indent=DEFAULT_INDENT,
    quote_char=DEFAULT_QUOTE_CHAR,
    setup=False,
    teardown=None,
    oneline=False,
    wrap=DEFAULT_WRAP,
    seed=None,
    locale=None,
    **kwargs,
):
    '''This implementation will emulate browsers\' fetch API by default.
    using Promises-like response processing.

    If you want to simulate a NodeJS environment, pass the parameter ``setup``
    as ``True`` and the next initialization snippet will be prepended to the
    generated code:

    ```javascript
    const fetch = require(\'node-fetch\');
    ```

    For ESM imports emulation, use
    ``setup='import fetch from \\'node-fetch\\';\\n\\n'``, thus the
    initialization snippet will be:

    ```javascript
    import fetch from \'node-fetch\';
    ```

    Of course, you can customize this initialization for other environments.
    For example, polyfill the API using
    [whatwg](https://github.com/github/fetch) as ESM module with
    ``setup='import \\'whatwg-fetch\\';\\n\\n'``:

    ```javascript
    import \'whatwg-fetch\';
    ```
    '''
    '''Implementation details:

    Note that this implementation does not discover the length of the code to
    generate it in multiple lines, like Python requests does. This is because
    in Javascript, promises are chained in multiple lines, thus next structure
    of code would be weird:

    ```javascript
    fetch('<url>').then(function(response) {}, function(err) {});
    ```

    So ``wrap`` argument is used only to wrap strings in multiples lines,
    instead of use it for implement the request in multiples or one line.
    '''

    response = ''

    # initialization
    if setup:
        if isinstance(setup, str):
            response += setup
        else:
            # If `setup == True`, 'node-fetch' for NodeJS is required
            response += ('const fetch = require(%(quote_char)snode-fetch'
                         '%(quote_char)s);%(newline)s%(newline)s') % {
                             'newline': '\n' if not oneline else '',
                             'quote_char': quote_char,
                         }

    if parameters:
        parameters_dict = OrderedDict({})
        for parameter in parameters:
            parameters_dict[lazy_name_by_parameter(parameter, seed=seed)] = \
                lazy_value_by_parameter(parameter, seed=seed, locale=locale)
        url = '?'.join([url, urlencode(parameters_dict)])

    if oneline:
        _url = ('%(quote_char)s%(url)s%(quote_char)s') % {
            'quote_char': quote_char,
            'url': escape_by_quote(url, quote_char),
        }
    else:
        _url = str_definition(
            url,
            indent=indent,
            quote_char=quote_char,
            wrap=wrap,
        )
    response += ('fetch(%(newline)s%(indent)s%(url)s%(comma)s'
                 '%(space)s%(newline)s') % {
                     'newline': '\n' if not oneline else '',
                     'indent': indent if not oneline else '',
                     'url': _url,
                     'comma': ',' if (parameters or headers or kwargs) else '',
                     'space': ' ' if
                     (oneline and (parameters or headers or kwargs)) else '',
                 }

    # options render
    if headers or kwargs:
        response += '{indent}{{{newline}'.format(
            indent=indent if not oneline else '',
            newline='\n' if not oneline else '',
        )

    if headers:
        response += _headers_render(
            headers,
            indent=indent,
            oneline=oneline,
            quote_char=quote_char,
            wrap=wrap,
            _comma_at_end=bool(kwargs),
        )

    if kwargs:
        response += _kwargs_render(
            kwargs,
            indent=indent,
            oneline=oneline,
            quote_char=quote_char,
            wrap=wrap,
        )

    if headers or kwargs:
        response += '{indent}}}{newline}'.format(
            indent=indent if not oneline else '',
            newline='\n' if not oneline else '',
        )

    response += _promises_chain_render(
        quote_char=quote_char,
        indent=indent,
        oneline=oneline,
    )

    if teardown:
        response += teardown

    return response