diff --git a/.circleci/config.yml b/.circleci/config.yml index 265d628..c179d06 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,6 +47,55 @@ jobs: docker: - image: circleci/python:2.7-stretch-node-browsers + "python-3.7-install-test": + docker: + - image: circleci/python:3.7-stretch-node-browsers + + environment: + PERCY_ENABLE: 0 + + steps: + - checkout + + - run: + name: Write job name. + command: echo $CIRCLE_JOB > circlejob.txt + + - restore_cache: + key: deps1-{{ .Branch }}-{{ checksum "circlejob.txt" }}-{{ checksum "tests/requirements.txt" }}-{{ checksum ".circleci/config.yml" }} + + - run: + name: Create virtualenv + command: | + sudo pip install virtualenv + python -m venv venv || virtualenv venv + + - run: + name: Install requirements + command: | + . venv/bin/activate + pip install -r tests/requirements.txt --quiet + + - save_cache: + key: deps1-{{ .Branch }}-{{ checksum "circlejob.txt" }}-{{ checksum "tests/requirements.txt" }}-{{ checksum ".circleci/config.yml" }} + paths: + - "venv" + + - run: + name: Generate Project & test + command: | + . venv/bin/activate + mkdir test_component + cd test_component + cookiecutter .. --config-file ../tests/test_config.yaml --no-input + cd test_component + python -m venv venv + . venv/bin/activate + pip install -r tests/requirements.txt --quiet + npm install --ignore-scripts + npm run build:all + pytest tests/test_usage.py --driver Chrome + workflows: version: 2 @@ -54,3 +103,4 @@ workflows: jobs: - "python-3.6" - "python-2.7" + - "python-3.7-install-test" diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index d9b8130..3e8d813 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -4,8 +4,6 @@ import sys import os import subprocess -import json -import collections install_deps = '{{cookiecutter.install_dependencies}}' project_shortname = '{{cookiecutter.project_shortname}}' @@ -35,25 +33,6 @@ def _execute_command(cmd): return status -# Patch up the package.json to use the venv python for class generation. -# If install_dependencies is false, the venv must be created manually and -# the requirements installed. -print('Patching build command') - -with open('package.json', 'r+') as package_file: - package_json = json.load(package_file, - object_pairs_hook=collections.OrderedDict) - - package_json['scripts']['build:py'] \ - = package_json['scripts']['build:py'].replace( - '%(python_path)', python_executable) - - package_file.seek(0) - package_file.truncate(0) - - json.dump(package_json, package_file, indent=4) - - if install_deps != 'True': print('`install_dependencies` is false!!', file=sys.stderr) print('Please create a venv in your project root' @@ -91,7 +70,20 @@ def _execute_command(cmd): # Run the first build print('Building initial bundles...') -_execute_command('npm run build:all') + +# Activating the venv and running the command +# doesn't work on linux with subprocess. +# The command need to run in the venv we just created to use the dash cmd. +# But it also needs shell to be true for the command to work. +# And shell doesn't work with `npm run` nor `. venv/bin/activate` +# The command works in a terminal. +_execute_command('{} -m dash.development.component_generator' + ' ./src/lib/components' + ' {{cookiecutter.project_shortname}}' + .format(python_executable)) + +_execute_command('npm run build:js') +_execute_command('npm run build:js-dev') print('\n{} ready!\n'.format(project_shortname)) diff --git a/tests/requirements.txt b/tests/requirements.txt index becc970..46f0f49 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,4 +1,4 @@ -dash +dash>=0.31.0 dash-html-components dash-core-components pytest diff --git a/tests/test_config.yaml b/tests/test_config.yaml new file mode 100644 index 0000000..c53810f --- /dev/null +++ b/tests/test_config.yaml @@ -0,0 +1,9 @@ +default_context: + project_name: Test Component + project_shortname: test_component + component_name: TestComponent + author_name: Test + author_email: Test + license: MIT License + publish_on_npm: false + install_dependencies: false diff --git a/tests/test_generate.py b/tests/test_generate.py index fecf309..550eddd 100644 --- a/tests/test_generate.py +++ b/tests/test_generate.py @@ -16,14 +16,8 @@ def test_package_json(cookies): package_json = json.loads(result.project.join('package.json').read()) - if sys.platform == 'win32': - python = os.path.join('venv', 'Scripts', 'python') - else: - python = os.path.join('venv', 'bin', 'python') - assert package_json['name'] == 'test_component' assert package_json['license'] == 'MIT' - assert python in package_json['scripts']['build:py'] assert package_json['author'] == \ '{} {}'.format(default_context['author_name'], default_context['author_email']) diff --git a/{{cookiecutter.project_shortname}}/package.json b/{{cookiecutter.project_shortname}}/package.json index 9e18ef8..b02b38f 100644 --- a/{{cookiecutter.project_shortname}}/package.json +++ b/{{cookiecutter.project_shortname}}/package.json @@ -9,8 +9,8 @@ "prepublish": "npm run validate-init", "build:js-dev": "webpack --mode development", "build:js": "webpack --mode production", - "build:py": "node ./extract-meta.js src/lib/components > {{cookiecutter.project_shortname}}/metadata.json && copyfiles package.json {{cookiecutter.project_shortname}} && %(python_path) -c \"import dash; dash.development.component_loader.generate_classes('{{cookiecutter.project_shortname}}', '{{cookiecutter.project_shortname}}/metadata.json')\"", - "build:all": "npm run build:js & npm run build:js-dev & npm run build:py" + "build:py": "(. venv/bin/activate || venv\\scripts\\activate) && dash-generate-components ./src/lib/components {{ cookiecutter.project_shortname }}", + "build:all": "npm run build:js && npm run build:js-dev && npm run build:py" }, "author": "{{ cookiecutter.author_name }} {{ cookiecutter.author_email }}", "license": "{% set _license_identifiers = {'MIT License': 'MIT','BSD License': 'BSD','ISC License': 'ISC','Apache Software License 2.0': 'Apache-2.0','GNU General Public License v3': 'GPL-3.0','Not open source': ''} %}{{ _license_identifiers[cookiecutter.license] }}", diff --git a/{{cookiecutter.project_shortname}}/requirements.txt b/{{cookiecutter.project_shortname}}/requirements.txt index 0b7f2dd..4846396 100644 --- a/{{cookiecutter.project_shortname}}/requirements.txt +++ b/{{cookiecutter.project_shortname}}/requirements.txt @@ -1,3 +1,3 @@ # dash is required to call `build:py` -dash +dash>=0.31.0 dash-html-components \ No newline at end of file diff --git a/{{cookiecutter.project_shortname}}/tests/requirements.txt b/{{cookiecutter.project_shortname}}/tests/requirements.txt index 1fcc228..9697089 100644 --- a/{{cookiecutter.project_shortname}}/tests/requirements.txt +++ b/{{cookiecutter.project_shortname}}/tests/requirements.txt @@ -3,7 +3,7 @@ # pip install -r requirements.txt chromedriver-binary -dash +dash>=0.31.0 dash-core-components dash-html-components dash-renderer diff --git a/{{cookiecutter.project_shortname}}/tests/test_usage.py b/{{cookiecutter.project_shortname}}/tests/test_usage.py index b84d650..057b5a7 100644 --- a/{{cookiecutter.project_shortname}}/tests/test_usage.py +++ b/{{cookiecutter.project_shortname}}/tests/test_usage.py @@ -1,3 +1,6 @@ +import time + + # Basic test for the component rendering. def test_render_component(dash_app, selenium): # Start a dash app contained in `usage.py` @@ -6,5 +9,23 @@ def test_render_component(dash_app, selenium): # and start it in a thread. app = dash_app('usage.py') - # Get the generated component with selenium - my_component = selenium.find_element_by_id('input') + # Get the generated component input with selenium + # The html input will be a children of the #input dash component + my_component = selenium.find_element_by_css_selector('#input > input') + + assert 'my-value' == my_component.get_attribute('value') + + # Clear the input + my_component.clear() + + # Send keys to the custom input. + my_component.send_keys('Hello dash') + + # Wait for the output callback to complete. + time.sleep(1) + + # Get the output component. + output = selenium.find_element_by_id('output') + + # assert the text has changed + assert output.text == 'You have entered Hello dash'