diff --git a/.gitignore b/.gitignore index e2519ed..b7b9fb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,22 @@ +var/ xblock_google_drive.egg-info *.log *.pyc *~ + +# Unit test / coverage reports +.cache/ +.pytest_cache/ +.coverage +.coverage.* +.tox +coverage.xml +htmlcov/ + +# IDEs and text editors +*~ +*.swp +.idea/ +.project +.pycharm_helpers/ +.pydevproject diff --git a/.pep8 b/.pep8 deleted file mode 100644 index f32cb5a..0000000 --- a/.pep8 +++ /dev/null @@ -1,4 +0,0 @@ -[pep8] -ignore=E501 -max_line_length=119 -exclude=settings diff --git a/.travis.yml b/.travis.yml index 57058d1..9d5548e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,31 @@ language: python +sudo: false python: - "2.7" +env: + - TOXENV=django18 + - TOXENV=django110 + - TOXENV=django111 + - TOXENV=quality + before_install: - - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - sleep 3 # give xvfb some time to start + - wget https://github.com/mozilla/geckodriver/releases/download/v0.19.1/geckodriver-v0.19.1-linux64.tar.gz + - mkdir geckodriver + - tar -xzf geckodriver-v0.19.1-linux64.tar.gz -C geckodriver + - export PATH=$PATH:$PWD/geckodriver + +addons: + firefox: '58.0.2' install: - - "pip install -r requirements.txt" - - "pip uninstall -y xblock-google-drive && python setup.py sdist && pip install dist/xblock-google-drive-0.1.tar.gz" + - pip install -r requirements/travis.txt script: - - DJANGO_SETTINGS_MODULE="settings" nosetests --with-coverage --cover-package="google_drive" --with-django - - pep8 --config=.pep8 google_drive - - pylint --rcfile=.pylintrc google_drive --report=no + - tox after_success: coveralls diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8e55851 --- /dev/null +++ b/Makefile @@ -0,0 +1,67 @@ +.PHONY: clean coverage docs help quality requirements selfcheck test test-all upgrade validate + +.DEFAULT_GOAL := help + +define BROWSER_PYSCRIPT +import os, webbrowser, sys +try: + from urllib import pathname2url +except: + from urllib.request import pathname2url + +webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) +endef +export BROWSER_PYSCRIPT +BROWSER := python -c "$$BROWSER_PYSCRIPT" + +help: ## display this help message + @echo "Please use \`make ' where is one of" + @perl -nle'print $& if m{^[a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}' + +clean: ## remove generated byte code, coverage reports, and build artifacts + find . -name '__pycache__' -exec rm -rf {} + + find . -name '*.pyc' -exec rm -f {} + + find . -name '*.pyo' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + + coverage erase + rm -fr build/ + rm -fr dist/ + rm -fr *.egg-info + +coverage: clean ## generate and view HTML coverage report + pytest --cov-report html + $(BROWSER) htmlcov/index.html + +upgrade: ## update the requirements/*.txt files with the latest packages satisfying requirements/*.in + pip install -q pip-tools + pip-compile --upgrade -o requirements/dev.txt requirements/base.in requirements/dev.in requirements/quality.in requirements/test.in requirements/travis.in + pip-compile --upgrade -o requirements/quality.txt requirements/base.in requirements/quality.in requirements/test.in + pip-compile --upgrade -o requirements/test.txt requirements/base.in requirements/test.in + pip-compile --upgrade -o requirements/travis.txt requirements/travis.in + # Let tox control the Django version for tests + sed '/^django==/d' requirements/test.txt > requirements/test.tmp + mv requirements/test.tmp requirements/test.txt + +quality: ## check coding style with pycodestyle and pylint + tox -e quality + +requirements: ## install development environment requirements + pip install -qr requirements/dev.txt --exists-action w + pip-sync requirements/dev.txt requirements/private.* + +test: clean ## run tests in the current virtualenv + mkdir -p var + pip install -e . + pytest + +diff_cover: test ## find diff lines that need test coverage + diff-cover coverage.xml + +test-all: ## run tests on every supported Python/Django combination + tox -e quality + tox + +validate: quality test ## run tests and quality checks + +selfcheck: ## check that the Makefile is well-formed + @echo "The Makefile is well-formed." diff --git a/README.rst b/README.rst index e8f7efe..7c7f5a8 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ root folder: .. code:: bash - $ pip install -r requirements.txt + $ make requirements Enabling in Studio ------------------ @@ -36,7 +36,8 @@ form the google-drive repo root: .. code:: bash - pip install -r requirements.txt + pip install -r requirements/base.in + pip install -e . Running the workbench --------------------- @@ -54,7 +55,7 @@ From google-drive directory, run the tests with the following command: .. code:: bash - $ DJANGO_SETTINGS_MODULE="settings" nosetests --with-django tests/* + $ pytest If you want to run only the integration or the unit tests, append the directory to the command. You can also run separate modules in this @@ -62,13 +63,14 @@ manner. .. code:: bash - $ DJANGO_SETTINGS_MODULE="settings" nosetests --with-django tests/unit + $ pytest tests/unit -To see the coverage, run the tests using the following command: +To see the coverage report in HTML format, run the tests using the +following command: .. code:: bash - $ DJANGO_SETTINGS_MODULE="settings" nosetests --with-coverage --cover-package="google_drive" --with-django + $ make coverage If you have not installed the xblock-sdk in the active virtualenv, you might also have to prepend ``PYTHONPATH=".:/path/to/xblock"`` to the @@ -139,17 +141,5 @@ License The Google Drive & Calendar XBlocks are available under the GNU Affero General Public License (AGPLv3). -Installation Troubleshooting ----------------------------- - -On a Mac, some people have received errors when installing lxml, trying -to find a specific header file for the compiler - -Try the following if you encounter a problem: - -:: - - CPATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2 CFLAGS=-Qunused-arguments CPPFLAGS=-Qunused-arguments pip install lxml - .. |Build Status| image:: https://travis-ci.org/edx-solutions/xblock-google-drive.svg?branch=master :target: https://travis-ci.org/edx-solutions/xblock-google-drive diff --git a/google_drive/google_calendar.py b/google_drive/google_calendar.py index 1c83b56..344c617 100644 --- a/google_drive/google_calendar.py +++ b/google_drive/google_calendar.py @@ -77,10 +77,11 @@ def studio_view(self, context): # pylint: disable=unused-argument """ fragment = Fragment() # Need to access protected members of fields to get their default value + default_name = self.fields['display_name']._default # pylint: disable=protected-access,unsubscriptable-object fragment.add_content(RESOURCE_LOADER.render_template(CALENDAR_EDIT_TEMPLATE, { 'self': self, - 'defaultName': self.fields['display_name']._default, # pylint: disable=protected-access - 'defaultID': self.fields['calendar_id']._default # pylint: disable=protected-access + 'defaultName': default_name, + 'defaultID': self.fields['calendar_id']._default # pylint: disable=protected-access,unsubscriptable-object })) fragment.add_javascript(RESOURCE_LOADER.load_unicode('public/js/google_calendar_edit.js')) fragment.add_css(RESOURCE_LOADER.load_unicode('public/css/google_edit.css')) diff --git a/google_drive/google_docs.py b/google_drive/google_docs.py index 92d03c9..df21f18 100644 --- a/google_drive/google_docs.py +++ b/google_drive/google_docs.py @@ -87,9 +87,10 @@ def studio_view(self, context): # pylint: disable=unused-argument """ fragment = Fragment() # Need to access protected members of fields to get their default value + default_name = self.fields['display_name']._default # pylint: disable=protected-access,unsubscriptable-object fragment.add_content(RESOURCE_LOADER.render_template(DOCUMENT_EDIT_TEMPLATE, { 'self': self, - 'defaultName': self.fields['display_name']._default # pylint: disable=protected-access + 'defaultName': default_name, })) fragment.add_javascript(RESOURCE_LOADER.load_unicode('public/js/google_docs_edit.js')) fragment.add_css(RESOURCE_LOADER.load_unicode('public/css/google_edit.css')) diff --git a/google_drive/tests/integration/test_publish.py b/google_drive/tests/integration/test_publish.py index 5bbd014..d1af2c7 100644 --- a/google_drive/tests/integration/test_publish.py +++ b/google_drive/tests/integration/test_publish.py @@ -7,7 +7,7 @@ # Classes ########################################################### -class GoogleCalendarPublishTestCase(GoogleCalendarBaseTest): # pylint: disable=too-few-public-methods, too-many-ancestors +class GoogleCalendarPublishTestCase(GoogleCalendarBaseTest): # pylint: disable=too-many-ancestors """ Tests for Google Calendar event publishing functionality. """ diff --git a/google_drive/tests/integration/test_studio.py b/google_drive/tests/integration/test_studio.py index fe54187..2857a0b 100644 --- a/google_drive/tests/integration/test_studio.py +++ b/google_drive/tests/integration/test_studio.py @@ -4,12 +4,14 @@ # Imports ########################################################### from ddt import ddt, unpack, data -from .base_test import GoogleCalendarBaseTest, GoogleDocumentBaseTest -from .studio_scenarios import CALENDAR_SCENARIOS, DOCUMENT_SCENARIOS, IMAGE_SCENARIOS + from google_drive.google_calendar import DEFAULT_CALENDAR_URL from google_drive.google_docs import DEFAULT_DOCUMENT_URL from google_drive.tests.test_const import TEST_IMAGE_URL +from .base_test import GoogleCalendarBaseTest, GoogleDocumentBaseTest +from .studio_scenarios import CALENDAR_SCENARIOS, DOCUMENT_SCENARIOS, IMAGE_SCENARIOS + # Classes ########################################################### @ddt # pylint: disable=too-many-ancestors @@ -23,7 +25,7 @@ def studio_save(self): """ Save changes made in studio for Google Calendar """ self.browser.find_element_by_css_selector('#calendar-submit-options').click() - @data(*CALENDAR_SCENARIOS) # pylint: disable=star-args + @data(*CALENDAR_SCENARIOS) @unpack def test_save_calendar(self, page_name): """ @@ -74,7 +76,7 @@ def studio_save(self): """ Save changes made in studio for Google Document """ self.browser.find_element_by_css_selector('#document-submit-options').click() - @data(*DOCUMENT_SCENARIOS) # pylint: disable=star-args + @data(*DOCUMENT_SCENARIOS) @unpack def test_save_document(self, page_name): """ @@ -99,7 +101,7 @@ def test_save_document(self, page_name): # Expecting that the new display name is the title of the IFrame self.assertEqual(document_iframe.get_attribute("title"), 'My Document') - @data(*IMAGE_SCENARIOS) # pylint: disable=star-args + @data(*IMAGE_SCENARIOS) @unpack def test_save_image(self, page_name): """ diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index b78dffd..0000000 --- a/requirements.txt +++ /dev/null @@ -1,18 +0,0 @@ -# May need to do this on a Mac - CPATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2 CFLAGS=-Qunused-arguments CPPFLAGS=-Qunused-arguments pip install lxml -ddt -lxml -mock -selenium -pep8 -pylint -coverage==3.7 -coveralls -django==1.4.18 --e git+https://github.com/nosedjango/nosedjango.git@ed7d7f9aa969252ff799ec159f828eaa8c1cbc5a#egg=nosedjango-dev --e git+https://github.com/edx-solutions/xblock-utils.git#egg=xblock-utils -# Normally we'd use no specific hash here, but master appears to have a defect, a proposed solution appears in the git hash below --e git+https://github.com/edx/xblock-sdk.git@c251b8924ef5bf89fb59a0a5df2723114cdf4154#egg=xblock-sdk --e git+https://github.com/edx/XBlock.git#egg=XBlock --e git+https://github.com/edx/bok-choy.git#egg=bok-choy --e git+https://github.com/pmitros/django-pyfs.git@d175715e0fe3367ec0f1ee429c242d603f6e8b10#egg=djpyfs --e . diff --git a/requirements/base.in b/requirements/base.in new file mode 100644 index 0000000..38ef7fa --- /dev/null +++ b/requirements/base.in @@ -0,0 +1,6 @@ +# Core requirements for using this application + +Django>=1.8,<2 # Web application framework +mako # Used by xblock-utils.resources, but not declared as a requirement for it +XBlock[django] # Courseware component architecture +-e git+https://github.com/edx/xblock-utils.git@v1.0.5#egg=xblock-utils==1.0.5 # Utility functions shared by many XBlocks diff --git a/requirements/dev.in b/requirements/dev.in new file mode 100644 index 0000000..4d6b1d0 --- /dev/null +++ b/requirements/dev.in @@ -0,0 +1,4 @@ +# Additional requirements for development of this application + +diff-cover # Changeset diff test coverage +pip-tools # Requirements file management diff --git a/requirements/dev.txt b/requirements/dev.txt new file mode 100644 index 0000000..0af9292 --- /dev/null +++ b/requirements/dev.txt @@ -0,0 +1,98 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile --output-file requirements/dev.txt requirements/base.in requirements/dev.in requirements/quality.in requirements/test.in requirements/travis.in +# +-e git+https://github.com/edx/xblock-sdk.git@v0.1.4#egg=xblock-sdk==0.1.4 +-e git+https://github.com/edx/xblock-utils.git@v1.0.5#egg=xblock-utils==1.0.5 +appdirs==1.4.3 # via fs +argparse==1.4.0 # via caniusepython3 +asn1crypto==0.24.0 # via cryptography +astroid==1.5.2 # via edx-lint, pylint, pylint-celery, pylint-plugin-utils +attrs==17.4.0 # via pytest +backports.functools-lru-cache==1.5 # via astroid, caniusepython3, pylint +binaryornot==0.4.4 # via cookiecutter +bok-choy==0.7.1 +boto3==1.6.3 # via fs-s3fs +botocore==1.9.3 # via boto3, s3transfer +caniusepython3==6.0.0 +certifi==2018.1.18 # via requests, urllib3 +cffi==1.11.5 # via cryptography +chardet==3.0.4 # via binaryornot, requests +click-log==0.1.8 # via edx-lint +click==6.7 # via click-log, edx-lint, pip-tools +configparser==3.5.0 # via pylint +cookiecutter==0.9.0 +coverage==4.5.1 # via coveralls, pytest-cov +coveralls==1.3.0 +cryptography==2.1.4 # via pyopenssl, urllib3 +ddt==1.1.1 +diff-cover==1.0.2 +distlib==0.2.6 # via caniusepython3 +django-nose==1.4.5 +django-pyfs==2.0 # via xblock +django==1.11.10 +docopt==0.6.2 # via coveralls +docutils==0.14 # via botocore +edx-lint==0.5.5 +enum34==1.1.6 # via astroid, cryptography, fs +first==2.0.1 # via pip-tools +fs-s3fs==0.1.7 # via django-pyfs +fs==2.0.18 # via django-pyfs, fs-s3fs, xblock +funcsigs==1.0.2 # via mock, pytest +futures==3.2.0 # via caniusepython3, isort, s3transfer +idna==2.6 # via cryptography, requests, urllib3 +inflect==0.2.5 # via jinja2-pluralize +ipaddress==1.0.19 # via cryptography, urllib3 +isort==4.3.4 +jinja2-pluralize==0.3.0 # via diff-cover +jinja2==2.10 # via cookiecutter, diff-cover, jinja2-pluralize +jmespath==0.9.3 # via boto3, botocore +lazy-object-proxy==1.3.1 # via astroid +lazy==1.3 # via bok-choy +lxml==4.1.1 # via xblock +mako==1.0.7 +markupsafe==1.0 # via jinja2, mako, xblock +mccabe==0.6.1 # via pylint +mock==2.0.0 +needle==0.5.0 # via bok-choy +nose==1.3.7 # via django-nose, needle +packaging==17.1 # via caniusepython3 +pbr==3.1.1 # via mock +pillow==5.0.0 # via needle +pip-tools==1.11.0 +pluggy==0.6.0 # via pytest, tox +py==1.5.2 # via pytest, tox +pycodestyle==2.3.1 +pycparser==2.18 # via cffi +pydocstyle==2.1.1 +pygments==2.2.0 # via diff-cover +pylint-celery==0.3 # via edx-lint +pylint-django==0.7.2 # via edx-lint +pylint-plugin-utils==0.2.6 # via pylint-celery, pylint-django +pylint==1.7.1 # via edx-lint, pylint-celery, pylint-django, pylint-plugin-utils +pyopenssl==17.5.0 # via urllib3 +pyparsing==2.2.0 # via packaging +pypng==0.0.18 +pytest-cov==2.5.1 +pytest-django==3.1.2 +pytest==3.4.1 +python-dateutil==2.6.1 # via botocore, xblock +pytz==2018.3 # via django, fs, xblock +pyyaml==3.12 # via cookiecutter, xblock +requests==2.18.4 # via caniusepython3, coveralls +s3transfer==0.1.13 # via boto3 +selenium==3.10.0 # via bok-choy, needle +simplejson==3.13.2 +singledispatch==3.4.0.3 # via astroid, pylint +six==1.10.0 # via astroid, bok-choy, cryptography, diff-cover, django-pyfs, edx-lint, fs, fs-s3fs, mock, packaging, pip-tools, pydocstyle, pylint, pyopenssl, pytest, python-dateutil, singledispatch, tox, xblock +snowballstemmer==1.2.1 # via pydocstyle +tox-battery==0.5 +tox==2.9.1 +urllib3[secure]==1.22 # via coveralls, requests +virtualenv==15.1.0 # via tox +web-fragments==0.2.2 # via xblock +webob==1.7.4 # via xblock +wrapt==1.10.11 # via astroid +xblock[django]==1.1.1 diff --git a/requirements/private.readme b/requirements/private.readme new file mode 100644 index 0000000..5600a10 --- /dev/null +++ b/requirements/private.readme @@ -0,0 +1,15 @@ +# If there are any Python packages you want to keep in your virtualenv beyond +# those listed in the official requirements files, create a "private.in" file +# and list them there. Generate the corresponding "private.txt" file pinning +# all of their indirect dependencies to specific versions as follows: + +# pip-compile private.in + +# This allows you to use "pip-sync" without removing these packages: + +# pip-sync requirements/*.txt + +# "private.in" and "private.txt" aren't checked into git to avoid merge +# conflicts, and the presence of this file allows "private.*" to be +# included in scripted pip-sync usage without requiring that those files be +# created first. diff --git a/requirements/quality.in b/requirements/quality.in new file mode 100644 index 0000000..b19fff0 --- /dev/null +++ b/requirements/quality.in @@ -0,0 +1,7 @@ +# Requirements for code quality checks + +caniusepython3 # Additional Python 3 compatibility pylint checks +edx-lint # edX pylint rules and plugins +isort # to standardize order of imports +pycodestyle # PEP 8 compliance validation +pydocstyle # PEP 257 compliance validation diff --git a/requirements/quality.txt b/requirements/quality.txt new file mode 100644 index 0000000..cfa0b7a --- /dev/null +++ b/requirements/quality.txt @@ -0,0 +1,81 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile --output-file requirements/quality.txt requirements/base.in requirements/quality.in requirements/test.in +# +-e git+https://github.com/edx/xblock-sdk.git@v0.1.4#egg=xblock-sdk==0.1.4 +-e git+https://github.com/edx/xblock-utils.git@v1.0.5#egg=xblock-utils==1.0.5 +appdirs==1.4.3 # via fs +argparse==1.4.0 # via caniusepython3 +astroid==1.5.2 # via edx-lint, pylint, pylint-celery, pylint-plugin-utils +attrs==17.4.0 # via pytest +backports.functools-lru-cache==1.5 # via astroid, caniusepython3, pylint +binaryornot==0.4.4 # via cookiecutter +bok-choy==0.7.1 +boto3==1.6.3 # via fs-s3fs +botocore==1.9.3 # via boto3, s3transfer +caniusepython3==6.0.0 +certifi==2018.1.18 # via requests +chardet==3.0.4 # via binaryornot, requests +click-log==0.1.8 # via edx-lint +click==6.7 # via click-log, edx-lint +configparser==3.5.0 # via pylint +cookiecutter==0.9.0 +coverage==4.5.1 # via pytest-cov +ddt==1.1.1 +distlib==0.2.6 # via caniusepython3 +django-nose==1.4.5 +django-pyfs==2.0 # via xblock +django==1.11.10 +docutils==0.14 # via botocore +edx-lint==0.5.5 +enum34==1.1.6 # via astroid, fs +fs-s3fs==0.1.7 # via django-pyfs +fs==2.0.18 # via django-pyfs, fs-s3fs, xblock +funcsigs==1.0.2 # via mock, pytest +futures==3.2.0 # via caniusepython3, isort, s3transfer +idna==2.6 # via requests +isort==4.3.4 +jinja2==2.10 # via cookiecutter +jmespath==0.9.3 # via boto3, botocore +lazy-object-proxy==1.3.1 # via astroid +lazy==1.3 # via bok-choy +lxml==4.1.1 # via xblock +mako==1.0.7 +markupsafe==1.0 # via jinja2, mako, xblock +mccabe==0.6.1 # via pylint +mock==2.0.0 +needle==0.5.0 # via bok-choy +nose==1.3.7 # via django-nose, needle +packaging==17.1 # via caniusepython3 +pbr==3.1.1 # via mock +pillow==5.0.0 # via needle +pluggy==0.6.0 # via pytest +py==1.5.2 # via pytest +pycodestyle==2.3.1 +pydocstyle==2.1.1 +pylint-celery==0.3 # via edx-lint +pylint-django==0.7.2 # via edx-lint +pylint-plugin-utils==0.2.6 # via pylint-celery, pylint-django +pylint==1.7.1 # via edx-lint, pylint-celery, pylint-django, pylint-plugin-utils +pyparsing==2.2.0 # via packaging +pypng==0.0.18 +pytest-cov==2.5.1 +pytest-django==3.1.2 +pytest==3.4.1 +python-dateutil==2.6.1 # via botocore, xblock +pytz==2018.3 # via django, fs, xblock +pyyaml==3.12 # via cookiecutter, xblock +requests==2.18.4 # via caniusepython3 +s3transfer==0.1.13 # via boto3 +selenium==3.10.0 # via bok-choy, needle +simplejson==3.13.2 +singledispatch==3.4.0.3 # via astroid, pylint +six==1.10.0 # via astroid, bok-choy, django-pyfs, edx-lint, fs, fs-s3fs, mock, packaging, pydocstyle, pylint, pytest, python-dateutil, singledispatch, xblock +snowballstemmer==1.2.1 # via pydocstyle +urllib3==1.22 # via requests +web-fragments==0.2.2 # via xblock +webob==1.7.4 # via xblock +wrapt==1.10.11 # via astroid +xblock[django]==1.1.1 diff --git a/requirements/test.in b/requirements/test.in new file mode 100644 index 0000000..3f9df24 --- /dev/null +++ b/requirements/test.in @@ -0,0 +1,9 @@ +# Requirements for test runs. + +bok-choy +ddt +mock +pytest +pytest-cov +pytest-django +-e git+https://github.com/edx/xblock-sdk.git@v0.1.4#egg=xblock-sdk==0.1.4 diff --git a/requirements/test.txt b/requirements/test.txt new file mode 100644 index 0000000..92f5304 --- /dev/null +++ b/requirements/test.txt @@ -0,0 +1,57 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile --output-file requirements/test.txt requirements/base.in requirements/test.in +# +-e git+https://github.com/edx/xblock-sdk.git@v0.1.4#egg=xblock-sdk==0.1.4 +-e git+https://github.com/edx/xblock-utils.git@v1.0.5#egg=xblock-utils==1.0.5 +appdirs==1.4.3 # via fs +attrs==17.4.0 # via pytest +binaryornot==0.4.4 # via cookiecutter +bok-choy==0.7.1 +boto3==1.6.3 # via fs-s3fs +botocore==1.9.3 # via boto3, s3transfer +certifi==2018.1.18 # via requests +chardet==3.0.4 # via binaryornot, requests +cookiecutter==0.9.0 +coverage==4.5.1 # via pytest-cov +ddt==1.1.1 +django-nose==1.4.5 +django-pyfs==2.0 # via xblock +docutils==0.14 # via botocore +enum34==1.1.6 # via fs +fs-s3fs==0.1.7 # via django-pyfs +fs==2.0.18 # via django-pyfs, fs-s3fs, xblock +funcsigs==1.0.2 # via mock, pytest +futures==3.2.0 # via s3transfer +idna==2.6 # via requests +jinja2==2.10 # via cookiecutter +jmespath==0.9.3 # via boto3, botocore +lazy==1.3 # via bok-choy +lxml==4.1.1 # via xblock +mako==1.0.7 +markupsafe==1.0 # via jinja2, mako, xblock +mock==2.0.0 +needle==0.5.0 # via bok-choy +nose==1.3.7 # via django-nose, needle +pbr==3.1.1 # via mock +pillow==5.0.0 # via needle +pluggy==0.6.0 # via pytest +py==1.5.2 # via pytest +pypng==0.0.18 +pytest-cov==2.5.1 +pytest-django==3.1.2 +pytest==3.4.1 +python-dateutil==2.6.1 # via botocore, xblock +pytz==2018.3 # via django, fs, xblock +pyyaml==3.12 # via cookiecutter, xblock +requests==2.18.4 +s3transfer==0.1.13 # via boto3 +selenium==3.10.0 # via bok-choy, needle +simplejson==3.13.2 +six==1.10.0 # via bok-choy, django-pyfs, fs, fs-s3fs, mock, pytest, python-dateutil, xblock +urllib3==1.22 # via requests +web-fragments==0.2.2 # via xblock +webob==1.7.4 # via xblock +xblock[django]==1.1.1 diff --git a/requirements/travis.in b/requirements/travis.in new file mode 100644 index 0000000..5d7ce03 --- /dev/null +++ b/requirements/travis.in @@ -0,0 +1,5 @@ +# Requirements for running tests in Travis + +coveralls # Code coverage reporting +tox # Virtualenv management for tests +tox-battery # Makes tox aware of requirements file changes diff --git a/requirements/travis.txt b/requirements/travis.txt new file mode 100644 index 0000000..bb4ae4e --- /dev/null +++ b/requirements/travis.txt @@ -0,0 +1,27 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile --output-file requirements/travis.txt requirements/travis.in +# +asn1crypto==0.24.0 # via cryptography +certifi==2018.1.18 # via requests, urllib3 +cffi==1.11.5 # via cryptography +chardet==3.0.4 # via requests +coverage==4.5.1 # via coveralls +coveralls==1.3.0 +cryptography==2.1.4 # via pyopenssl, urllib3 +docopt==0.6.2 # via coveralls +enum34==1.1.6 # via cryptography +idna==2.6 # via cryptography, requests, urllib3 +ipaddress==1.0.19 # via cryptography, urllib3 +pluggy==0.6.0 # via tox +py==1.5.2 # via tox +pycparser==2.18 # via cffi +pyopenssl==17.5.0 # via urllib3 +requests==2.18.4 # via coveralls +six==1.11.0 # via cryptography, pyopenssl, tox +tox-battery==0.5 +tox==2.9.1 +urllib3[secure]==1.22 # via coveralls, requests +virtualenv==15.1.0 # via tox diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..c33c949 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,8 @@ +[isort] +indent=' ' +line_length = 120 +multi_line_output=3 +known_first_party = google_drive + +[wheel] +universal = 1 diff --git a/setup.py b/setup.py index ece6081..543c9b2 100644 --- a/setup.py +++ b/setup.py @@ -23,11 +23,12 @@ def package_data(pkg, roots): setup( name='xblock-google-drive', version='0.1', - description='my_google_drive XBlock', # TODO: write a better description. + description='An XBlock which allows embedding of Google documents and calendar within an edX course', packages=[ 'google_drive', ], install_requires=[ + 'mako', 'XBlock', 'xblock-utils', ], diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..52370bc --- /dev/null +++ b/tox.ini @@ -0,0 +1,46 @@ +[tox] +envlist = py27-django{18,19,110,111} + +[pycodestyle] +exclude = .git,.tox +max-line-length = 120 + +[pydocstyle] +ignore = D200,D203,D212 + +[pytest] +DJANGO_SETTINGS_MODULE = settings +addopts = --cov google_drive --cov-report term-missing --durations=10 +norecursedirs = .* requirements + +[testenv] +whitelist_externals = + mkdir + rm +deps = + django18: Django>=1.8,<1.9 + django19: Django>=1.9,<1.10 + django110: Django>=1.10,<1.11 + django111: Django>=1.11,<2 + -r{toxinidir}/requirements/test.txt +passenv = + DISPLAY +setenv = + SCREENSHOT_DIR={toxinidir}/var/logs + SELENIUM_DRIVER_LOG_DIR={toxinidir}/var/logs +commands = + mkdir -p {toxinidir}/var/logs + rm -rf {toxinidir}/var/logs/* + pytest {posargs} + +[testenv:quality] +whitelist_externals = + make +deps = + -r{toxinidir}/requirements/quality.txt +commands = + pylint google_drive setup.py + # pylint --py3k google_drive setup.py + pycodestyle google_drive setup.py + # isort --diff --recursive google_drive setup.py + make selfcheck