Merge pull request #21 from octokit/eduardo-pep8

converted style to pep8
This commit is contained in:
Eduardo Ramirez 2015-11-14 19:47:06 -08:00
Родитель fcf6816fc8 5bac79eb68
Коммит 8f7642523c
12 изменённых файлов: 359 добавлений и 345 удалений

Просмотреть файл

@ -7,50 +7,51 @@ octokit.client
This module contains the main Client class for octokit.py
"""
# https://code.google.com/p/uri-templates/wiki/Implementations
import requests
from .exceptions import handle_status
from .pagination import Pagination
from .ratelimit import RateLimit
from .resources import Resource
import requests
class BaseClient(Resource):
"""The main class for using octokit.py.
"""The main class for using octokit.py.
This class accepts as arguments any attributes that can be set on a
Requests.Session() object. After instantiation, the session may be modified
by accessing the `session` attribute.
This class accepts as arguments any attributes that can be set on a
Requests.Session() object. After instantiation, the session may be modified
by accessing the `session` attribute.
Example usage:
Example usage:
>>> client = octokit.Client(auth = ('mastahyeti', 'oauth-token'))
>>> client.session.proxies = {'http': 'foo.bar:3128'}
>>> client.current_user.login
'mastahyeti'
"""
"""
def __init__(self, session=requests.Session(), api_endpoint='https://api.github.com', **kwargs):
self.session = session
self.url = api_endpoint
self.schema = {}
self.name = 'Client'
self.auto_paginate = False
def __init__(self, session=requests.Session(),
api_endpoint='https://api.github.com', **kwargs):
self.session = session
self.url = api_endpoint
self.schema = {}
self.name = 'Client'
self.auto_paginate = False
self.session.hooks = dict(response=self.response_callback)
for key in kwargs:
setattr(self.session, key, kwargs[key])
self.session.hooks = dict(response=self.response_callback)
for key in kwargs:
setattr(self.session, key, kwargs[key])
def __getattr__(self, name):
try:
return super(BaseClient, self).__getattr__(name)
except:
handle_status(404)
def __getattr__(self, name):
try:
return super(BaseClient, self).__getattr__(name)
except AttributeError:
handle_status(404)
def response_callback(self, r, *args, **kwargs):
data = r.json() if r.text != "" else {}
handle_status(r.status_code, data)
def response_callback(self, r, *args, **kwargs):
data = r.json() if r.text != "" else {}
handle_status(r.status_code, data)
class Client(Pagination, RateLimit, BaseClient):
pass
pass

Просмотреть файл

@ -7,56 +7,75 @@ octokit.exceptions
This module contains octokit.py exceptions.
"""
class Error(Exception):
""" Something went wrong. """
def __init__(self, data={'message':'Something went wrong.'}):
self.message = data['message']
def __str__(self):
return repr(self.message)
"""Something went wrong."""
def __init__(self, data={'message': 'Something went wrong.'}):
self.message = data['message']
def __str__(self):
return repr(self.message)
class ClientError(Error):
""" Status 4xx: Client error. """
"""Status 4xx: Client error."""
class BadRequest(ClientError):
""" Status 400: Bad request. """
"""Status 400: Bad request."""
class Unauthorized(ClientError):
""" Status 401/403: Not authorized to view the resource """
"""Status 401/403: Not authorized to view the resource"""
class NotFound(ClientError):
""" Status 404: The resource wasn't found. """
def __init__(self, data={"message": "Not Found"}):
super(NotFound, self).__init__(data)
"""Status 404: The resource wasn't found."""
def __init__(self, data={"message": "Not Found"}):
super(NotFound, self).__init__(data)
class MethodNotAllowed(ClientError):
""" Status 405: The method is not allowed. """
"""Status 405: The method is not allowed."""
class NotAcceptable(ClientError):
""" Status 406: The response is unacceptable. """
"""Status 406: The response is unacceptable."""
class Conflict(ClientError):
""" Status 409: There was a conflict with the current state of the resource. """
"""Status 409: Conflict with the current state of the resource."""
class UnsupportedMediaType(ClientError):
""" Status 415: Unsupported media type. """
"""Status 415: Unsupported media type."""
class UnprocessableEntity(ClientError):
""" Status 422: Unprocessable entity. """
"""Status 422: Unprocessable entity."""
class ServerError(Error):
""" Status 5xx: Server error. """
"""Status 5xx: Server error."""
class InternalServerError(ServerError):
""" Status 500: Internal server error. """
"""Status 500: Internal server error."""
class NotImplemented(ServerError):
""" Status 501: Not implemented. """
"""Status 501: Not implemented."""
class BadGateway(ServerError):
""" Status 502: Bad gateway. """
"""Status 502: Bad gateway."""
class ServiceUnavailable(ServerError):
""" Status 503: Service unavailable. """
"""Status 503: Service unavailable."""
# Mapping of status code to Exception
STATUS_ERRORS = {
@ -77,16 +96,17 @@ STATUS_ERRORS = {
599: ServerError
}
def handle_status(status, data=None):
""" Raise the appropriate error given a status code. """
if status >= 400:
error = STATUS_ERRORS.get(status)
if error is None:
if status <= 499:
error = STATUS_ERRORS.get(499)
elif status <= 599:
error = STATUS_ERRORS.get(599)
else:
error = Error
errorException = error(data) if data else error()
raise errorException
"""Raise the appropriate error given a status code."""
if status >= 400:
error = STATUS_ERRORS.get(status)
if error is None:
if status <= 499:
error = STATUS_ERRORS.get(499)
elif status <= 599:
error = STATUS_ERRORS.get(599)
else:
error = Error
errorException = error(data) if data else error()
raise errorException

Просмотреть файл

@ -1,37 +1,38 @@
from .resources import Resource
class Pagination(object):
def __init__(self, *args, **kwargs):
# TODO (howei): possibly extract auto_paginate from kwargs
# so users can do client = Client(auto_paginate=True)
self.auto_paginate = False
super(Pagination, self).__init__(*args, **kwargs)
def __init__(self, *args, **kwargs):
# TODO (howei): possibly extract auto_paginate from kwargs
# so users can do client = Client(auto_paginate=True)
self.auto_paginate = False
super(Pagination, self).__init__(*args, **kwargs)
def response_callback(self, r, **kwargs):
# TODO (howei): possibly implement auto pagination logic here
return super(Pagination, self).response_callback(r, **kwargs)
def response_callback(self, r, **kwargs):
# TODO (howei): possibly implement auto pagination logic here
return super(Pagination, self).response_callback(r, **kwargs)
def paginate(self, url, *args, **kwargs):
session = self.session
params = {}
if 'per_page' in kwargs:
params['per_page'] = kwargs['per_page']
del kwargs['per_page']
elif self.auto_paginate:
# if per page is not defined, default to 100 per page
params['per_page'] = 100
def paginate(self, *args, **kwargs):
params = {}
if 'per_page' in kwargs:
params['per_page'] = kwargs['per_page']
del kwargs['per_page']
elif self.auto_paginate:
# if per page is not defined, default to 100 per page
params['per_page'] = 100
if 'page' in kwargs:
params['page'] = kwargs['page']
del kwargs['page']
if 'page' in kwargs:
params['page'] = kwargs['page']
del kwargs['page']
kwargs['params'] = params
resource = Resource(session, url=url, name=url).get(*args, **kwargs)
data = list(resource.schema)
kwargs['params'] = params
resource = self.get(*args, **kwargs)
data = list(resource.schema)
if self.auto_paginate:
while 'next' in resource.rels and self.rate_limit.remaining > 0:
resource = resource.rels['next'].get()
data.extend(list(resource.schema))
if self.auto_paginate:
while 'next' in resource.rels and self.rate_limit.remaining > 0:
resource = resource.rels['next'].get()
data.extend(list(resource.schema))
return Resource(session, schema=data, url=self.url, name=self.name)
return Resource(self.session, schema=data,
url=resource.url, name=resource.name)

Просмотреть файл

@ -1,45 +1,42 @@
import calendar
import time
from collections import namedtuple
try:
from urllib.parse import urljoin
except ImportError:
from urlparse import urljoin
class RateLimit(object):
def __init__(self, *args, **kwargs):
self._rate_limit = _RateLimit()
self.last_response = None
super(RateLimit, self).__init__(*args, **kwargs)
def __init__(self, *args, **kwargs):
self._rate_limit = _RateLimit()
self.last_response = None
super(RateLimit, self).__init__(*args, **kwargs)
def response_callback(self, r, **kwargs):
self.last_response = r
return super(RateLimit, self).response_callback(r, **kwargs)
def response_callback(self, r, **kwargs):
self.last_response = r
return super(RateLimit, self).response_callback(r, **kwargs)
@property
def rate_limit(self):
self.update_rate_limit()
return self._rate_limit
@property
def rate_limit(self):
self.update_rate_limit()
return self._rate_limit
def update_rate_limit(self):
if not self.last_response:
self.head()
def update_rate_limit(self):
if not self.last_response:
self.head()
rate_limit = self._rate_limit
response = self.last_response
rate_limit = self._rate_limit
headers = self.last_response.headers
rate_limit.limit = int(headers['X-RateLimit-Limit'])
rate_limit.remaining = int(headers['X-RateLimit-Remaining'])
rate_limit.resets_at = int(headers['X-RateLimit-Reset'])
delta = rate_limit.resets_at - calendar.timegm(time.gmtime())
rate_limit.resets_in = max(delta, 0)
rate_limit.limit = int(response.headers['X-RateLimit-Limit'])
rate_limit.remaining = int(response.headers['X-RateLimit-Remaining'])
rate_limit.resets_at = int(response.headers['X-RateLimit-Reset'])
delta = rate_limit.resets_at - calendar.timegm(time.gmtime())
rate_limit.resets_in = max(delta, 0)
class _RateLimit(object):
__slots__ = ('limit', 'remaining', 'resets_at', 'resets_in')
__slots__ = ('limit', 'remaining', 'resets_at', 'resets_in')
def __repr__(self):
s = ', '.join(
'{}={}'.format(slot, getattr(self, slot))
for slot in self.__slots__
)
return '%s(%s)' % (self.__class__, s)
def __repr__(self):
s = ', '.join(
'{}={}'.format(slot, getattr(self, slot))
for slot in self.__slots__
)
return '%s(%s)' % (self.__class__, s)

Просмотреть файл

@ -7,190 +7,176 @@ octokit.resources
This module contains the workhorse of octokit.py, the Resources.
"""
from inflection import humanize, singularize
import requests
import uritemplate
from inflection import humanize, singularize
class Resource(object):
"""The workhorse of octokit.py, this class makes the API calls and interprets
them into an accessible schema. The API calls and schema parsing are lazy and
only happen when an attribute of the resource is requested.
"""
"""The workhorse of octokit.py, this class makes the API calls and
interprets them into an accessible schema. The API calls and schema parsing
are lazy and only happen when an attribute of the resource is requested.
"""
def __init__(self, session, name=None, url=None, schema=None, response=None):
self.session = session
self.name = name
self.url = url
self.schema = schema
self.response = response
self.rels = {}
def __init__(self, session, name=None, url=None, schema=None,
response=None):
self.session = session
self.name = name
self.url = url
self.schema = schema
self.response = response
self.rels = {}
if response:
self.schema = self.parse_schema(response)
self.rels = self.parse_rels(response)
self.url = response.url
if response:
self.schema = self.parse_schema(response.json())
self.rels = self.parse_rels(response)
self.url = response.url
if type(self.schema) == dict and 'url' in self.schema:
self.url = self.schema['url']
if type(self.schema) == dict and 'url' in self.schema:
self.url = self.schema['url']
def __getattr__(self, name):
self.ensure_schema_loaded()
if name in self.schema:
return self.schema[name]
else:
raise AttributeError
def __getitem__(self, name):
self.ensure_schema_loaded()
return self.schema[name]
def __call__(self, *args, **kwargs):
return self.get(*args, **kwargs)
def __repr__(self):
self.ensure_schema_loaded()
schema_type = type(self.schema)
if schema_type == dict:
subtitle = ', '.join(self.schema.keys())
elif schema_type == list:
subtitle = str(len(self.schema))
else:
subtitle = str(self.schema)
return '<Octokit %s(%s)>' % (self.name, subtitle)
# Returns the variables the URI takes
def variables(self):
return uritemplate.variables(self.url)
# Returns the links this resource can follow
def keys(self):
self.ensure_schema_loaded()
return self.schema.keys()
# Check if the current resources' schema has been loaded, otherwise load it
def ensure_schema_loaded(self):
if self.schema:
return
self.schema = self.get().schema
# Fetch the current request and return its schema
def parse_schema(self, response):
# If content of response is empty, then default to empty dictionary
data = response.json() if response.text != "" else {}
data_type = type(data)
if data_type == dict:
schema = self.parse_schema_dict(data)
elif data_type == list:
schema = self.parse_schema_list(data, self.name)
else:
# TODO (eduardo) -- handle request that don't return anything
raise Exception("Unknown type of response from the API.")
return schema
# Convert the JSON returned by the request into a dictionary of resources
def parse_schema_dict(self, data):
schema = {}
for key in data:
name = key.split('_url')[0]
if key.endswith('_url'):
if data[key]:
schema[name] = Resource(self.session, url=data[key], name=humanize(name))
def __getattr__(self, name):
self.ensure_schema_loaded()
if name in self.schema:
return self.schema[name]
else:
schema[name] = data[key]
else:
data_type = type(data[key])
raise AttributeError
def __getitem__(self, name):
self.ensure_schema_loaded()
return self.schema[name]
def __call__(self, *args, **kwargs):
return self.get(*args, **kwargs)
def __repr__(self):
self.ensure_schema_loaded()
schema_type = type(self.schema)
if schema_type == dict:
subtitle = ', '.join(self.schema.keys())
elif schema_type == list:
subtitle = str(len(self.schema))
else:
subtitle = str(self.schema)
return '<Octokit %s(%s)>' % (self.name, subtitle)
def variables(self):
"""Returns the variables the URI takes"""
return uritemplate.variables(self.url)
def keys(self):
"""Returns the links this resource can follow"""
self.ensure_schema_loaded()
return self.schema.keys()
def ensure_schema_loaded(self):
"""Check if resources' schema has been loaded, otherwise load it"""
if self.schema:
return
elif self.variables():
raise Exception("You need to call this resource with variables %s"
% repr(list(variables)))
self.schema = self.get().schema
def parse_schema(self, response):
"""Parse the response and return its schema"""
data_type = type(response)
if data_type == dict:
schema[name] = Resource(self.session, schema=data[key], name=humanize(name))
schema = self.parse_schema_dict(response)
elif data_type == list:
schema[name] = self.parse_schema_list(data[key], name=name)
schema = self.parse_schema_list(response, self.name)
else:
schema[name] = data[key]
# TODO (eduardo) -- handle request that don't return anything
raise Exception("Unknown type of response from the API.")
return schema
return schema
# Convert the JSON returned by the request into a list of resources
def parse_schema_list(self, data, name):
return [
Resource(self.session, schema=s, name=humanize(singularize(name)))
for s in data
]
def parse_schema_dict(self, data):
"""Convert the responses' JSON into a dictionary of resources"""
schema = {}
for key in data:
name = key.split('_url')[0]
if key.endswith('_url'):
if data[key]:
schema[name] = Resource(self.session, url=data[key],
name=humanize(name))
else:
schema[name] = data[key]
else:
data_type = type(data[key])
if data_type == dict:
schema[name] = Resource(self.session, schema=data[key],
name=humanize(name))
elif data_type == list:
schema[name] = self.parse_schema_list(data[key], name=name)
else:
schema[name] = data[key]
# Parse relation links from the headers
def parse_rels(self, response):
return {
link['rel']: Resource(self.session, url=link['url'], name=self.name)
for link in response.links.values()
}
return schema
# Makes an API request with the resource using HEAD.
#
# *args - Uri template argument
# **kwargs – Uri template arguments
def head(self, *args, **kwargs):
return self.fetch_resource('HEAD', *args, **kwargs)
def parse_schema_list(self, data, name):
"""Convert the responses' JSON into a list of resources"""
return [
Resource(self.session, schema=s, name=humanize(singularize(name)))
for s in data
]
# Makes an API request with the curent resource using GET.
#
# *args - Uri template argument
# **kwargs – Uri template arguments
def get(self, *args, **kwargs):
return self.fetch_resource('GET', *args, **kwargs)
def parse_rels(self, response):
"""Parse relation links from the headers"""
return {
link['rel']: Resource(self.session, url=link['url'], name=self.name)
for link in response.links.values()
}
# Makes an API request with the curent resource using POST.
#
# *args - Uri template argument
# **kwargs – Uri template arguments
def post(self, *args, **kwargs):
return self.fetch_resource('POST', *args, **kwargs)
def head(self, *args, **kwargs):
"""Make a HTTP HEAD request to the endpoint of resource."""
return self.fetch_resource('HEAD', *args, **kwargs)
# Makes an API request with the curent resource using PUT.
#
# *args - Uri template argument
# **kwargs – Uri template arguments
def put(self, *args, **kwargs):
return self.fetch_resource('PUT', *args, **kwargs)
def get(self, *args, **kwargs):
"""Make a HTTP GET request to the endpoint of resource."""
return self.fetch_resource('GET', *args, **kwargs)
# Makes an API request with the curent resource using PATCH.
#
# *args - Uri template argument
# **kwargs – Uri template arguments
def patch(self, *args, **kwargs):
return self.fetch_resource('PATCH', *args, **kwargs)
def post(self, *args, **kwargs):
"""Make a HTTP POST request to the endpoint of resource."""
return self.fetch_resource('POST', *args, **kwargs)
# Makes an API request with the curent resource using DELETE.
#
# *args - Uri template argument
# **kwargs – Uri template arguments
def delete(self, *args, **kwargs):
return self.fetch_resource('DELETE', *args, **kwargs)
def put(self, *args, **kwargs):
"""Make a HTTP PUT request to the endpoint of resource."""
return self.fetch_resource('PUT', *args, **kwargs)
# Makes an API request with the curent resource using OPTIONS.
#
# *args - Uri template argument
# **kwargs – Uri template arguments
def options(self, *args, **kwargs):
return self.fetch_resource('OPTIONS', *args, **kwargs)
def patch(self, *args, **kwargs):
"""Make a HTTP PATCH request to the endpoint of resource."""
return self.fetch_resource('PATCH', *args, **kwargs)
# Public: Makes an API request with the curent resource
#
# method - HTTP method.
# *args - Uri template argument
# **kwargs – Uri template arguments
def fetch_resource(self, method, *args, **kwargs):
variables = self.variables()
if len(args) == 1 and len(variables) == 1:
kwargs[next(iter(variables))] = args[0]
def delete(self, *args, **kwargs):
"""Make a HTTP DELETE request to the endpoint of resource."""
return self.fetch_resource('DELETE', *args, **kwargs)
url_args = {k: kwargs[k] for k in kwargs if k in variables}
req_args = {k: kwargs[k] for k in kwargs if k not in variables}
def options(self, *args, **kwargs):
"""Make a HTTP OPTIONS request to the endpoint of resource."""
return self.fetch_resource('OPTIONS', *args, **kwargs)
url = uritemplate.expand(self.url, url_args)
request = requests.Request(method, url, **req_args)
prepared_req = self.session.prepare_request(request)
response = self.session.send(prepared_req)
def fetch_resource(self, method, *args, **kwargs):
"""Fetch the endpoint from the API and return it as a Resource.
return Resource(self.session, response=response, name=humanize(self.name))
method - HTTP method.
*args - Uri template argument
**kwargs Uri template arguments
"""
variables = self.variables()
if len(args) == 1 and len(variables) == 1:
kwargs[next(iter(variables))] = args[0]
url_args = {k: kwargs[k] for k in kwargs if k in variables}
req_args = {k: kwargs[k] for k in kwargs if k not in variables}
url = uritemplate.expand(self.url, url_args)
request = requests.Request(method, url, **req_args)
prepared_req = self.session.prepare_request(request)
response = self.session.send(prepared_req)
return Resource(self.session, response=response,
name=humanize(self.name))

Просмотреть файл

@ -6,11 +6,14 @@ echo "===> Bootstrapping..."
script/bootstrap --quiet
echo "===> Setting test environment variables..."
export OCTOKIT_TEST_GITHUB_LOGIN="api-padawan"
export OCTOKIT_TEST_GITHUB_PASSWORD="MYSOCRATESNOTE"
export OCTOKIT_TEST_GITHUB_TOKEN="6a21f190e3422bf89afa8b360d923b0c30e8fbfa"
export OCTOKIT_TEST_GITHUB_CLIENT_ID='abcdefabcdefabcdefab'
export OCTOKIT_TEST_GITHUB_CLIENT_SECRET='abcdefabcdefabcdefababcdefabcdefabcdefab'
for testvar in LOGIN PASSWORD TOKEN CLIENT_ID CLIENT_SECRET
do
octokitvar="OCTOKIT_TEST_GITHUB_${testvar}"
if [[ -z "${!octokitvar}" ]]; then
echo "Please export ${octokitvar}";
fi
done
export OCTOKIT_SILENT=true
echo "===> Running tests..."

Просмотреть файл

@ -3,6 +3,7 @@ import unittest
import octokit
from .util import MockOctokitTestCase
class TestApi(MockOctokitTestCase):
def test_current_user(self):
login = self.client.current_user.login

Просмотреть файл

@ -4,6 +4,7 @@ import requests_mock
import octokit
class TestExceptions(unittest.TestCase):
"""Tests the exception handling code in octokit/exceptions.py"""

Просмотреть файл

@ -6,6 +6,7 @@ import uritemplate
import octokit
class TestPagination(unittest.TestCase):
"""Tests the functionality in octokit/pagination.py"""
@ -15,39 +16,39 @@ class TestPagination(unittest.TestCase):
self.client.session.mount('mock', self.adapter)
def test_pagination(self):
self.client.auto_paginate = True
url = uritemplate.expand(self.client.url, {'param':'foo'})
self.client.auto_paginate = True
url = uritemplate.expand(self.client.url, {'param': 'foo'})
headers1 = {
'Link': '<'+url+'?page=2&per_page=100>; rel="next"',
'X-RateLimit-Remaining': '56',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
headers2 = {
'Link': '<'+url+'?page=3&per_page=100>; rel="next"',
'X-RateLimit-Remaining': '56',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
headers3 = {
'X-RateLimit-Remaining': '56',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
data1 = '["a","b"]'
data2 = '["c","d"]'
data3 = '["e","f"]'
h1 = {
'Link': '<'+url+'?page=2&per_page=100>; rel="next"',
'X-RateLimit-Remaining': '56',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
h2 = {
'Link': '<'+url+'?page=3&per_page=100>; rel="next"',
'X-RateLimit-Remaining': '56',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
h3 = {
'X-RateLimit-Remaining': '56',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
res1 = '["a","b"]'
res2 = '["c","d"]'
res3 = '["e","f"]'
self.adapter.register_uri('GET', url, headers=headers1, text=data1)
self.adapter.register_uri('GET', url+'?page=2', headers=headers2, text=data2)
self.adapter.register_uri('GET', url+'?page=3', headers=headers3, text=data3)
self.adapter.register_uri('GET', url, headers=h1, text=res1)
self.adapter.register_uri('GET', url+'?page=2', headers=h2, text=res2)
self.adapter.register_uri('GET', url+'?page=3', headers=h3, text=res3)
response = self.client.paginate(self.client.url, param='foo')
resultSchema = [r.schema for r in response.schema]
expectedSchema = ['a', 'b', 'c', 'd', 'e', 'f']
response = self.client.paginate(param='foo')
resultSchema = [r.schema for r in response.schema]
expectedSchema = ['a', 'b', 'c', 'd', 'e', 'f']
self.assertEqual(resultSchema, expectedSchema)
self.assertEqual(resultSchema, expectedSchema)
if __name__ == '__main__':
unittest.main()

Просмотреть файл

@ -6,6 +6,7 @@ import uritemplate
import octokit
class TestRateLimit(unittest.TestCase):
"""Tests the functionality in octokit/ratelimit.py"""
@ -15,39 +16,39 @@ class TestRateLimit(unittest.TestCase):
self.client.session.mount('mock', self.adapter)
def test_rate_limit(self):
self.client.auto_paginate = True
url = uritemplate.expand(self.client.url, {'param':'foo'})
self.client.auto_paginate = True
url = uritemplate.expand(self.client.url, {'param': 'foo'})
headers1 = {
'Link': '<'+url+'?page=2>; rel="next"',
'X-RateLimit-Remaining': '1',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
headers2 = {
'Link': '<'+url+'?page=3>; rel="next"',
'X-RateLimit-Remaining': '0',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
headers3 = {
'X-RateLimit-Remaining': '0',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
data1 = '["a","b"]'
data2 = '["c","d"]'
data3 = '["e","f"]'
h1 = {
'Link': '<'+url+'?page=2>; rel="next"',
'X-RateLimit-Remaining': '1',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
h2 = {
'Link': '<'+url+'?page=3>; rel="next"',
'X-RateLimit-Remaining': '0',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
h3 = {
'X-RateLimit-Remaining': '0',
'X-RateLimit-Reset': '1446804464',
'X-RateLimit-Limit': '60'
}
res1 = '["a","b"]'
res2 = '["c","d"]'
res3 = '["e","f"]'
self.adapter.register_uri('GET', url, headers=headers1, text=data1)
self.adapter.register_uri('GET', url+'?page=2', headers=headers2, text=data2)
self.adapter.register_uri('GET', url+'?page=3', headers=headers3, text=data3)
self.adapter.register_uri('GET', url, headers=h1, text=res1)
self.adapter.register_uri('GET', url+'?page=2', headers=h2, text=res2)
self.adapter.register_uri('GET', url+'?page=3', headers=h3, text=res3)
response = self.client.paginate(url=self.client.url, param='foo')
resultSchema = [r.schema for r in response.schema]
expectedSchema = ['a', 'b', 'c', 'd']
response = self.client.paginate(param='foo')
resultSchema = [r.schema for r in response.schema]
expectedSchema = ['a', 'b', 'c', 'd']
self.assertEqual(resultSchema, expectedSchema)
self.assertEqual(resultSchema, expectedSchema)
if __name__ == '__main__':
unittest.main()

Просмотреть файл

@ -6,6 +6,7 @@ import uritemplate
import octokit
class TestResources(unittest.TestCase):
"""Tests the functionality in octokit/resources.py"""
@ -27,7 +28,7 @@ class TestResources(unittest.TestCase):
assert response.success
def test_httpverb(self):
"""Test that each HTTP verb functions properly when JSON is returned."""
"""Test that each HTTP verb works properly when JSON is returned."""
verbs_to_methods = [
('GET', self.client.get),
('POST', self.client.post),

Просмотреть файл

@ -7,6 +7,7 @@ from betamax.fixtures import unittest
import octokit
class MockOctokitTestCase(unittest.BetamaxTestCase):
"""unittest test case that wraps and configures betamax for tests that
require mocking HTTP requests in octokit.py