20 | Expected result: JS (ES5) file generated and JS console output: 21 |
22 |
23 | > Framework v1.0 initialized
24 | > Framework v1.0.1 initialized
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/tests/test_project/test_project/app/templates/app/template-with-es6-inline.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% load static %}
4 | {% load compress %}
5 |
6 |
7 |
8 |
9 | 23 | Expected result: inline JS (ES5) code generated and JS console output: 24 |
25 |
26 | > Square of 2: 4
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/test_project/test_project/app/templates/app/template-with-scss-file.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% load static %}
4 | {% load compress %}
5 |
6 |
7 |
8 |
9 | 20 | Expected result: CSS file created and styles applied to the title above 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/test_project/test_project/app/templates/app/template-with-scss-inline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% load static %} 4 | {% load compress %} 5 | 6 | 7 | 8 | 9 |26 | Expected result: inline CSS code generated and styles applied to the title above 27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/test_project/test_project/base/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kottenator/django-compressor-toolkit/e7bfdaa354e9c9189db0e4ba4fa049045adad91b/tests/test_project/test_project/base/__init__.py -------------------------------------------------------------------------------- /tests/test_project/test_project/base/static/base/framework.js: -------------------------------------------------------------------------------- 1 | export let version = '1.0'; 2 | 3 | export default class { 4 | constructor(customVersion) { 5 | console.log(`Framework v${customVersion || version} initialized`); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/test_project/test_project/base/static/base/utils.js: -------------------------------------------------------------------------------- 1 | define(['exports'], function(exports) { 2 | exports.key = 'abc123'; 3 | }); 4 | -------------------------------------------------------------------------------- /tests/test_project/test_project/base/static/base/variables.scss: -------------------------------------------------------------------------------- 1 | $title-size: 30px; 2 | -------------------------------------------------------------------------------- /tests/test_project/test_project/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import django 4 | 5 | 6 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 7 | DEBUG = True 8 | SECRET_KEY = '*****' 9 | INSTALLED_APPS = ( 10 | 'django.contrib.staticfiles', 11 | 'compressor', 12 | 'compressor_toolkit', 13 | 'test_project.base', 14 | 'test_project.app' 15 | ) 16 | ROOT_URLCONF = 'test_project.urls' 17 | STATIC_URL = '/static/' 18 | STATICFILES_FINDERS = ( 19 | 'django.contrib.staticfiles.finders.FileSystemFinder', 20 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 21 | 'compressor.finders.CompressorFinder' 22 | ) 23 | 24 | if django.VERSION < (1, 8): 25 | TEMPLATE_CONTEXT_PROCESSORS = [ 26 | 'django.template.context_processors.static' 27 | ] 28 | else: 29 | TEMPLATES = [{ 30 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 31 | 'APP_DIRS': True, 32 | 'OPTIONS': { 33 | 'context_processors': [ 34 | 'django.template.context_processors.static' 35 | ] 36 | } 37 | }] 38 | 39 | if django.VERSION < (1, 10): 40 | MIDDLEWARE_CLASSES = [] 41 | else: 42 | MIDDLEWARE = [] 43 | 44 | # django-compressor settings 45 | COMPRESS_ROOT = os.path.join(BASE_DIR, 'compressor') 46 | COMPRESS_PRECOMPILERS = ( 47 | ('text/x-scss', 'compressor_toolkit.precompilers.SCSSCompiler'), 48 | ('module', 'compressor_toolkit.precompilers.ES6Compiler') 49 | ) 50 | COMPRESS_ENABLED = False 51 | 52 | # django-compressor-toolkit settings; see compressor_toolkit/apps.py for details 53 | if 'COMPRESS_NODE_MODULES' in os.environ: 54 | COMPRESS_NODE_MODULES = os.getenv('COMPRESS_NODE_MODULES') 55 | -------------------------------------------------------------------------------- /tests/test_project/test_project/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from django.views.generic.base import TemplateView 3 | 4 | 5 | urlpatterns = [ 6 | url( 7 | '^scss-file/$', 8 | TemplateView.as_view(template_name='app/template-with-scss-file.html'), 9 | name='scss-file' 10 | ), 11 | url( 12 | '^scss-inline/$', 13 | TemplateView.as_view(template_name='app/template-with-scss-inline.html'), 14 | name='scss-inline' 15 | ), 16 | url( 17 | '^es6-file/$', 18 | TemplateView.as_view(template_name='app/template-with-es6-file.html'), 19 | name='es6-file' 20 | ), 21 | url( 22 | '^es6-inline/$', 23 | TemplateView.as_view(template_name='app/template-with-es6-inline.html'), 24 | name='es6-inline' 25 | ) 26 | ] 27 | -------------------------------------------------------------------------------- /tests/unit_tests/test_filters.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import os 3 | import pytest 4 | 5 | from compressor_toolkit.filters import CssRelativeFilter, CssDataUriFilter 6 | 7 | from tests.utils import TESTS_DIR 8 | 9 | 10 | @pytest.mark.parametrize('original_url, processed_url', [ 11 | ('images/icon.svg', '../../app/images/icon.svg'), 12 | ('./images/icon.svg', '../../app/images/icon.svg'), 13 | ('../images/icon.svg', '../../images/icon.svg'), 14 | ('/images/icon.svg', '/images/icon.svg') 15 | ], ids=['letter', 'one dot', 'two dots', 'slash']) 16 | def test_css_relative_url_filter(original_url, processed_url): 17 | """ 18 | Test ``compressor_toolkit.filters.CssRelativeFilter``. 19 | 20 | :param original_url: Test function parameter: URL in the original CSS file 21 | which is located in '$PROJECT_ROOT/app/static/app/style.css' 22 | and will be collected to '$STATIC_ROOT/app/style.css' 23 | :param processed_url: Test function parameter: URL in the processed CSS file 24 | which is located in '$STATIC_ROOT/CACHE/css/abcd1234.css' 25 | """ 26 | template = ''' 27 | .a {{ 28 | background: url('{}'); 29 | }} 30 | ''' 31 | input_css = template.format(original_url) 32 | output_css = template.format(processed_url) 33 | 34 | # ``filename`` and ``basename`` are fakes - file existence doesn't matter for this test 35 | # ``filename`` must be not empty to make the filter work 36 | # ``basename`` contains Django app name 'app', which will be a part of the output URL 37 | assert CssRelativeFilter(input_css).input( 38 | filename='...', 39 | basename='app/style.css' 40 | ) == output_css 41 | 42 | 43 | @pytest.mark.parametrize('image_path, is_processed', [ 44 | ('images/icon.svg', True), 45 | ('images/icon.png', True), 46 | ('images/icon.jpg', False), 47 | ('images/skip/icon.svg', False), 48 | ('images/large.svg', False) 49 | ], ids=['ok svg', 'ok png', 'skip jpg', 'skip folder', 'skip large']) 50 | def test_css_data_uri_filter(settings, image_path, is_processed): 51 | """ 52 | Test ``compressor_toolkit.filters.CssRelativeFilter``. 53 | 54 | :param settings: ``pytest-django`` fixture: mutable Django settings 55 | :param image_path: Test function parameter: relative path to the image file 56 | :param is_processed: Test function parameter: is data URI transformation applied? 57 | """ 58 | # configure related settings 59 | settings.COMPRESS_DATA_URI_MAX_SIZE = 5 * 1024 60 | settings.COMPRESS_DATA_URI_INCLUDE_PATHS = '.+\.(svg|png)$' 61 | settings.COMPRESS_DATA_URI_EXCLUDE_PATHS = '/skip/' 62 | 63 | file_dir = os.path.join(TESTS_DIR, 'resources') 64 | file_path = os.path.join(file_dir, 'style.css') 65 | 66 | if is_processed: 67 | with open(os.path.join(file_dir, image_path), 'rb') as image_file: 68 | processed_image = 'data:image/{};base64,{}'.format( 69 | 'svg+xml' if image_path.endswith('.svg') else 'png', 70 | base64.b64encode(image_file.read()).decode() 71 | ) 72 | else: 73 | processed_image = image_path 74 | 75 | template = ''' 76 | .a {{ 77 | background: url("{}"); 78 | }} 79 | ''' 80 | input_css = template.format(image_path) 81 | output_css = template.format(processed_image) 82 | 83 | assert CssDataUriFilter(input_css).input(filename=file_path) == output_css 84 | -------------------------------------------------------------------------------- /tests/unit_tests/test_precompilers.py: -------------------------------------------------------------------------------- 1 | from compressor_toolkit.precompilers import SCSSCompiler, ES6Compiler 2 | 3 | 4 | def test_scss_compiler(): 5 | """ 6 | Test ``compressor_toolkit.precompilers.SCSSCompiler`` on simple SCSS input. 7 | """ 8 | input_scss = ''' 9 | .a { 10 | .b { 11 | padding: { 12 | left: 5px; 13 | right: 6px; 14 | } 15 | } 16 | } 17 | ''' 18 | output_css = '.a .b {\n padding-left: 5px;\n padding-right: 6px;\n}' 19 | assert SCSSCompiler(input_scss, {}).input().strip() == output_css 20 | 21 | 22 | def test_es6_compiler(): 23 | """ 24 | Test ``compressor_toolkit.precompilers.ES6Compiler`` on simple ES6 input. 25 | """ 26 | input_es6 = 'export let CONST = 1' 27 | output_es5 = ( 28 | '"use strict";\n' 29 | '\n' 30 | 'Object.defineProperty(exports, "__esModule", {\n' 31 | ' value: true\n' 32 | '});\n' 33 | 'var CONST = exports.CONST = 1;\n' 34 | ) 35 | assert output_es5 in ES6Compiler(input_es6, {}).input() 36 | -------------------------------------------------------------------------------- /tests/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | TESTS_DIR = os.path.dirname(__file__) 5 | --------------------------------------------------------------------------------