Skip to content
This repository has been archived by the owner on Jul 24, 2018. It is now read-only.

py3 support is fixed, test infrastructure is added #9

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.py]
indent_style = space
indent_size = 4

[*.md]
trim_trailing_whitespace = false
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@ nosetests.xml
.mr.developer.cfg
.project
.pydevproject

# Virtual env
venv

# IDE
.idea
20 changes: 14 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ language: python
python:
- "2.6"
- "2.7"
- "3.2"
- "pypy"
- "3.3"
# command to install dependencies
install: "pip install -r requirements.txt"
# command to run tests
- "3.4"

install:
- pip install tox

# thx to jinja for this
script:
- python setup.py install
- python setup.py test
- tox -e \
$(echo py$TRAVIS_PYTHON_VERSION | tr -d . | sed -e 's/pypypy/pypy/')

notifications:
email:
on_success: change
on_failure: always
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include README.md
4 changes: 4 additions & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
tox
pytest
responses
-e .
2 changes: 1 addition & 1 deletion moves/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from _moves import *
from ._moves import *
42 changes: 18 additions & 24 deletions moves/_moves.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ class MovesClient(object):
token_url = "https://api.moves-app.com/oauth/v1/access_token"
tokeninfo_url = "https://api.moves-app.com/oauth/v1/tokeninfo"
refresh_url = "https://api.moves-app.com/oauth/v1/access_token"



def __init__(self, client_id=None, client_secret=None,
access_token=None, use_app=False):

Expand Down Expand Up @@ -93,7 +93,7 @@ def refresh_oauth_token(self, refresh_token, **kwargs):
raise MovesAPIError(error)

def tokeninfo(self):

params = {
'access_token': self.access_token
}
Expand Down Expand Up @@ -129,7 +129,7 @@ def api(self, path, method='GET', **kwargs):
if 'etag' in params:
headers['If-None-Match'] = params['etag']
del(params['etag'])

resp = requests.request(method, url,
data=data,
params=params,
Expand All @@ -139,7 +139,7 @@ def api(self, path, method='GET', **kwargs):
resp.status_code, resp.text)
if resp.status_code == 304:
raise MovesAPINotModifed("Unmodified")

self._last_headers = resp.headers
return resp

Expand All @@ -157,34 +157,28 @@ def set_first_date(self):
self.first_date = response['profile']['firstDate']

def __getattr__(self, name):
'''\
Turns method calls such as "moves.foo_bar(...)" into
a call to "moves.api('/foo/bar', 'GET', params={...})"
and then parses the response.
'''
"""
Turns method calls such as "moves.foo_bar(...)" into
a call to "moves.api('/foo/bar', 'GET', params={...})"
and then parses the response.
"""
base_path = name.replace('_', '/')

# Define a function that does what we want.
# Define a function that does what we want.
def closure(*path, **params):
'Accesses the /%s API endpoints.'
"""Accesses the /%s API endpoints."""
path = list(path)
path.insert(0, base_path)
return self.parse_response(
self.api('/'.join(path), 'GET', params=params)
)

# Clone a new method with the correct name and doc string.
retval = types.FunctionType(
closure.func_code,
closure.func_globals,
name,
closure.func_defaults,
closure.func_closure)
retval.func_doc = closure.func_doc % base_path
closure.__name__ = name
closure.__doc__ = closure.__doc__ % base_path

# Cache it to avoid additional calls to __getattr__.
setattr(self, name, retval)
return retval
setattr(self, name, closure)
return closure

# Give Access to last attribute
_move_client_status = ['etag', 'x-ratelimit-hourlimit', 'x-ratelimit-hourremaining',
Expand All @@ -193,4 +187,4 @@ def closure(*path, **params):
att = att.replace('-', '_')
setattr(MovesClient, att, property(lambda self,att=att: self._last_headers.get(att, None)
if self._last_headers else att))

1 change: 0 additions & 1 deletion requirements.txt

This file was deleted.

9 changes: 8 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,22 @@
url='https://github.com/lysol/moves',
download_url='http://github.com/lysol/moves/archive/v0.1.tar.gz',
packages=['moves'],
install_requires=open('requirements.txt').read(),
install_requires=[
'requests>=0.11'
],
long_description=open('README.md').read(),
include_package_data=True,
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Topic :: Software Development :: Libraries :: Python Modules',
],
license='MIT'
Expand Down
45 changes: 45 additions & 0 deletions tests/test_moves.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# coding: utf-8


import pytest
import responses

import moves


class TestMovesClient(object):
def test_raises_if_no_acess_token_is_provided(self):
client = moves.MovesClient()
with pytest.raises(moves.MovesAPIError) as err:
client.api('/user')

assert 'provide a valid access token' in str(err.value)

@responses.activate
def test_performs_call_to_api_if_access_token_is_provided(self):
responses.add(responses.GET,
url='https://api.moves-app.com/api/1.1/user/profile',
status=200, body='{"success": true, "id": 1}',
content_type='application/json')

client = moves.MovesClient(access_token='secret')

resp = client.user_profile()

assert resp == dict(success=True, id=1)
assert (responses.calls[0].request.headers.get('authorization')
== 'Bearer secret')

@responses.activate
def test_performs_call_to_api_with_overriden_token(self):
responses.add(responses.GET,
url='https://api.moves-app.com/api/1.1/user/profile',
status=200, body='{"success": true}',
content_type='application/json')

client = moves.MovesClient(access_token='secret')

client.user_profile(access_token='new-secret')

assert (responses.calls[0].request.headers.get('authorization')
== 'Bearer new-secret')
13 changes: 13 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[tox]
envlist = py26, py27, pypy, py33, py34

[testenv]
deps =
pytest
responses

commands =
py.test []

[pytest]
norecursedirs = venv .tox examples *.egg-info