Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dynamic resources collection. #518

Merged
merged 8 commits into from
Jan 4, 2019
Merged
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.35.1 - 2018-12-27
### Fixed
- Always skip `dynamic` resources from index resources collection. [#518](https://github.com/plotly/dash/pull/518)

## 0.35.0 - 2018-12-18
## Added
- Experimental `--r-prefix` option to `dash-generate-components`, optionally generates R version of components and corresponding R package. [#483](https://github.com/plotly/dash/pull/483)
Expand Down
11 changes: 6 additions & 5 deletions dash/dash.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,11 +391,12 @@ def _relative_url_path(relative_package_path='', namespace=''):
namespace=resource['namespace']
))
elif 'external_url' in resource:
if isinstance(resource['external_url'], str):
srcs.append(resource['external_url'])
else:
for url in resource['external_url']:
srcs.append(url)
if not is_dynamic_resource:
if isinstance(resource['external_url'], str):
srcs.append(resource['external_url'])
else:
for url in resource['external_url']:
srcs.append(url)
elif 'absolute_path' in resource:
raise Exception(
'Serving files from absolute_path isn\'t supported yet'
Expand Down
2 changes: 1 addition & 1 deletion dash/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.35.0'
__version__ = '0.35.1'
244 changes: 87 additions & 157 deletions tests/test_resources.py
Original file line number Diff line number Diff line change
@@ -1,164 +1,94 @@
import unittest
import warnings
from dash.resources import Scripts, Css
from dash.development._py_components_generation import generate_class


def generate_components():
Div = generate_class('Div', ('children', 'id',), 'dash_html_components')
Span = generate_class('Span', ('children', 'id',), 'dash_html_components')
Input = generate_class(
'Input', ('children', 'id',),
'dash_core_components')
return Div, Span, Input


def external_url(package_name):
return (
'//unpkg.com/{}@0.2.9'
'/{}/bundle.js'.format(
package_name.replace('_', '-'),
package_name
import mock
import dash_core_components as dcc

import dash

_monkey_patched_js_dist = [
{
'external_url': 'https://external_javascript.js',
'relative_package_path': 'external_javascript.js',
'namespace': 'dash_core_components'
},
{
'external_url': 'https://external_css.css',
'relative_package_path': 'external_css.css',
'namespace': 'dash_core_components'
},
{
'relative_package_path': 'fake_dcc.js',
'dev_package_path': 'fake_dcc.dev.js',
'external_url': 'https://component_library.bundle.js',
'namespace': 'dash_core_components'
},
{
'relative_package_path': 'fake_dcc.min.js.map',
'dev_package_path': 'fake_dcc.dev.js.map',
'external_url': 'https://component_library.bundle.js.map',
'namespace': 'dash_core_components',
'dynamic': True
}
]

dcc._js_dist = _monkey_patched_js_dist
dcc.__version__ = 1


class StatMock(object):
st_mtime = 1


class Tests(unittest.TestCase):

def test_external(self):
app = dash.Dash(
__name__,
assets_folder='tests/assets',
assets_ignore='load_after.+.js'
)
)


def rel_path(package_name):
return '{}/bundle.js'.format(package_name)


def abs_path(package_name):
return '/Users/chriddyp/{}/bundle.js'.format(package_name)


class TestResources(unittest.TestCase):

def resource_test(self, css_or_js):
Div, Span, Input = generate_components()

if css_or_js == 'css':
# The CSS URLs and paths will look a little bit differently
# than the JS urls but that doesn't matter for the purposes
# of the test
Div._css_dist = Span._css_dist = [{
'external_url': external_url('dash_html_components'),
'relative_package_path': rel_path('dash_html_components')
}]

Input._css_dist = [{
'external_url': external_url('dash_core_components'),
'relative_package_path': rel_path('dash_core_components')
}]

else:
Div._js_dist = Span._js_dist = [{
'external_url': external_url('dash_html_components'),
'relative_package_path': rel_path('dash_html_components')
}]

Input._js_dist = [{
'external_url': external_url('dash_core_components'),
'relative_package_path': rel_path('dash_core_components')
}]

layout = Div([None, 'string', Span(), Div(Input())])
app.layout = dcc.Markdown()
app.scripts.config.serve_locally = False

if css_or_js == 'css':
resources = Css(layout)
else:
resources = Scripts(layout)

resources._update_layout(layout)

expected_filtered_external_resources = [
{
'external_url': external_url('dash_html_components'),
'namespace': 'dash_html_components'
},
{
'external_url': external_url('dash_core_components'),
'namespace': 'dash_core_components'
}
]
expected_filtered_relative_resources = [
{
'relative_package_path': rel_path('dash_html_components'),
'namespace': 'dash_html_components'
},
{
'relative_package_path': rel_path('dash_core_components'),
'namespace': 'dash_core_components'
}
]

if css_or_js == 'css':
self.assertEqual(
resources.get_all_css(),
expected_filtered_external_resources
)
else:
self.assertEqual(
resources.get_all_scripts(),
expected_filtered_external_resources
)

resources.config.serve_locally = True
if css_or_js == 'css':
self.assertEqual(
resources.get_all_css(),
expected_filtered_relative_resources
)
else:
self.assertEqual(
resources.get_all_scripts(),
expected_filtered_relative_resources
)

resources.config.serve_locally = False
extra_resource = {'external_url': '//cdn.bootstrap.com/min.css'}
expected_resources = expected_filtered_external_resources + [
extra_resource
]
if css_or_js == 'css':
resources.append_css(extra_resource)
self.assertEqual(
resources.get_all_css(),
expected_resources
)
else:
resources.append_script(extra_resource)
self.assertEqual(
resources.get_all_scripts(),
expected_resources
with mock.patch('dash.dash.os.stat', return_value=StatMock()):
resource = app._collect_and_register_resources(
app.scripts.get_all_scripts()
)

resources.config.serve_locally = True
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
if css_or_js == 'css':
self.assertEqual(
resources.get_all_css(),
expected_filtered_relative_resources
)
assert len(w) == 1
assert 'A local version of {} is not available'.format(
extra_resource['external_url']
) in str(w[-1].message)

else:
self.assertEqual(
resources.get_all_scripts(),
expected_filtered_relative_resources
self.assertEqual(resource, [
'https://external_javascript.js',
'https://external_css.css',
'https://component_library.bundle.js'
])

def test_internal(self):
app = dash.Dash(
__name__,
assets_folder='tests/assets',
assets_ignore='load_after.+.js'
)
app.layout = dcc.Markdown()
app.scripts.config.serve_locally = True

with mock.patch('dash.dash.os.stat', return_value=StatMock()):
with mock.patch('dash.dash.importlib.import_module',
return_value=dcc):
resource = app._collect_and_register_resources(
app.scripts.get_all_scripts()
)
assert len(w) == 1
assert 'A local version of {} is not available'.format(
extra_resource['external_url']
) in str(w[-1].message)

def test_js_resources(self):
# self.resource_test('js')
pass

def test_css_resources(self):
# self.resource_test('css')
pass
self.assertEqual(resource, [
'/_dash-component-suites/'
'dash_core_components/external_javascript.js?v=1&m=1',
'/_dash-component-suites/'
'dash_core_components/external_css.css?v=1&m=1',
'/_dash-component-suites/'
'dash_core_components/fake_dcc.js?v=1&m=1',
])

self.assertTrue(
'fake_dcc.min.js.map'
in app.registered_paths['dash_core_components'],
'Dynamic resource not available in registered path {}'.format(
app.registered_paths['dash_core_components']
)
)