diff --git a/.gitignore b/.gitignore index 591b90a..c85ef1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ /build /dist /*.egg-info -/.idea \ No newline at end of file +*.pyc +__pycache__ +.toxbuild +.idea diff --git a/.travis.yml b/.travis.yml index f675da7..869454e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,8 @@ python: - "pypy" - "3.3" - "3.4" + - "3.5" + - "3.6" install: diff --git a/flask_bower/__init__.py b/flask_bower/__init__.py index 42a7816..aa8adb0 100644 --- a/flask_bower/__init__.py +++ b/flask_bower/__init__.py @@ -18,7 +18,7 @@ def serve(component, filename): root = current_app.config['BOWER_COMPONENTS_ROOT'] - return send_file('/'.join([root, component, filename]), conditional=True) + return send_file(os.path.join(root, component, filename), conditional=True) def bower_url_for(component, filename, **values): @@ -83,10 +83,11 @@ def overlay_url_for(endpoint, filename=None, **values): if endpoint == 'static' or endpoint.endswith('.static'): - if '/' in filename: - filename_parts = filename.split('/') + if os.path.sep in filename: + filename_parts = filename.split(os.path.sep) component = filename_parts[0] - filename = '/'.join(filename_parts[1:]) + # Using * magic here to expand list + filename = os.path.join(*filename_parts[1:]) returned_url = build_url(component, filename, **values) @@ -114,24 +115,24 @@ def build_url(component, filename, **values): package_data = None # check if component exists in bower_components directory - if not os.path.isdir('/'.join([current_app.root_path, root, component])): + if not os.path.isdir(os.path.join(current_app.root_path, root, component)): # FallBack to default url_for flask return None # load bower.json of specified component - bower_file_path = '/'.join([current_app.root_path, root, component, 'bower.json']) + bower_file_path = os.path.join(current_app.root_path, root, component, 'bower.json') if os.path.exists(bower_file_path): with open(bower_file_path, 'r') as bower_file: bower_data = json.load(bower_file) # check if package.json exists and load package.json data - package_file_path = '/'.join([current_app.root_path, root, component, 'package.json']) + package_file_path = os.path.join(current_app.root_path, root, component, 'package.json') if os.path.exists(package_file_path): with open(package_file_path, 'r') as package_file: package_data = json.load(package_file) # check if specified file actually exists - if not os.path.exists('/'.join([current_app.root_path, root, component, filename])): + if not os.path.exists(os.path.join(current_app.root_path, root, component, filename)): return None # check if minified file exists (by pattern .min. @@ -139,9 +140,9 @@ def build_url(component, filename, **values): if current_app.config['BOWER_TRY_MINIFIED']: if '.min.' not in filename: minified_filename = '%s.min.%s' % tuple(filename.rsplit('.', 1)) - minified_path = '/'.join([root, component, minified_filename]) + minified_path = os.path.join(root, component, minified_filename) - if os.path.exists('/'.join([current_app.root_path, minified_path])): + if os.path.exists(os.path.join(current_app.root_path, minified_path)): filename = minified_filename # determine version of component and append as ?version= parameter to allow cache busting @@ -151,7 +152,7 @@ def build_url(component, filename, **values): elif package_data is not None and 'version' in package_data: values['version'] = package_data['version'] else: - values['version'] = os.path.getmtime('/'.join([current_app.root_path, root, component, filename])) + values['version'] = os.path.getmtime(os.path.join(current_app.root_path, root, component, filename)) return url_for('bower.serve', component=component, filename=filename, **values) diff --git a/tests/test_build_url.py b/tests/test_build_url.py index 39315fb..8f7e1ab 100644 --- a/tests/test_build_url.py +++ b/tests/test_build_url.py @@ -1,3 +1,5 @@ +import os +import shutil import unittest from flask import Flask, url_for from werkzeug.routing import BuildError @@ -10,10 +12,19 @@ def additional_build_error_handler(error, endpoint, values): class BowerTestCase(unittest.TestCase): + def clean_alt_dir(self): + alt_dir = os.path.abspath(os.path.join(os.path.curdir, 'tests', 'bower_components_alt')) + if os.path.isdir(alt_dir): + shutil.rmtree(alt_dir) + def setUp(self): + self.clean_alt_dir() self.app = Flask(__name__) self.app.config['SERVER_NAME'] = 'unit.test' + def tearDown(self): + self.clean_alt_dir() + def test_bower_url_for(self): """ Test of the bower_url_for function @@ -79,3 +90,27 @@ def test_build_error_handler_chain(self): self.app.url_build_error_handlers.append(additional_build_error_handler) with self.app.app_context(): self.assertTrue(url_for('bower.static', filename='not_found/not_found.js')) + + def test_absolute_root_path(self): + """ + Test using an absolute path to BOWER_COMPONENT_ROOT + Copies the existing bower_components folder to 'bower_components_alt' + Sets the absolute path to the new directory as BOWER_COMPONENT_ROOT + + Validates that url_for continues to work & tests calling get on the + provided URL. + """ + alt_dir = os.path.abspath(os.path.join(os.path.curdir, 'tests', 'bower_components_alt')) + + shutil.copytree(os.path.abspath(os.path.join(os.path.curdir, 'tests', 'bower_components')), alt_dir) + + self.app.config['BOWER_COMPONENT_ROOT'] = alt_dir + Bower(self.app) + + with self.app.app_context(): + self.assertEqual(bower_url_for('jquery', 'dist/jquery.js'), + "http://unit.test/bower/jquery/dist/jquery.min.js?version=2.1.3") + url = bower_url_for('jquery', 'dist/jquery.js') + client = self.app.test_client() + + self.assertEqual(client.get(url).status_code, 200) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..03b4fd3 --- /dev/null +++ b/tox.ini @@ -0,0 +1,10 @@ +[tox] +toxworkdir=.toxbuild +envlist = py27,py34,py35,py36 + +[testenv] +deps = + nose + -rrequirements.txt +commands=nosetests tests -s +