Skip to content

Commit

Permalink
Merge branch 'master' into testing-download
Browse files Browse the repository at this point in the history
  • Loading branch information
byronz authored Jul 12, 2019
2 parents 9983466 + 03c3474 commit 28fee35
Show file tree
Hide file tree
Showing 3 changed files with 382 additions and 310 deletions.
146 changes: 146 additions & 0 deletions tests/integration/callbacks/state_path.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
{
"chapter1": {
"toc": ["props", "children", 0],
"body": ["props", "children", 1],
"chapter1-header": [
"props",
"children",
1,
"props",
"children",
"props",
"children",
0
],
"chapter1-controls": [
"props",
"children",
1,
"props",
"children",
"props",
"children",
1
],
"chapter1-label": [
"props",
"children",
1,
"props",
"children",
"props",
"children",
2
],
"chapter1-graph": [
"props",
"children",
1,
"props",
"children",
"props",
"children",
3
]
},
"chapter2": {
"toc": ["props", "children", 0],
"body": ["props", "children", 1],
"chapter2-header": [
"props",
"children",
1,
"props",
"children",
"props",
"children",
0
],
"chapter2-controls": [
"props",
"children",
1,
"props",
"children",
"props",
"children",
1
],
"chapter2-label": [
"props",
"children",
1,
"props",
"children",
"props",
"children",
2
],
"chapter2-graph": [
"props",
"children",
1,
"props",
"children",
"props",
"children",
3
]
},
"chapter3": {
"toc": ["props", "children", 0],
"body": ["props", "children", 1],
"chapter3-header": [
"props",
"children",
1,
"props",
"children",
0,
"props",
"children",
"props",
"children",
0
],
"chapter3-label": [
"props",
"children",
1,
"props",
"children",
0,
"props",
"children",
"props",
"children",
1
],
"chapter3-graph": [
"props",
"children",
1,
"props",
"children",
0,
"props",
"children",
"props",
"children",
2
],
"chapter3-controls": [
"props",
"children",
1,
"props",
"children",
0,
"props",
"children",
"props",
"children",
3
]
}
}
236 changes: 236 additions & 0 deletions tests/integration/callbacks/test_layout_paths_with_callbacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
import os
import json
from multiprocessing import Value
import dash_core_components as dcc
import dash_html_components as html
from dash import Dash
from dash.dependencies import Input, Output
import dash.testing.wait as wait


def test_cblp001_radio_buttons_callbacks_generating_children(dash_duo):
TIMEOUT = 2
with open(
os.path.join(os.path.dirname(__file__), "state_path.json")
) as fp:
EXPECTED_PATHS = json.load(fp)

app = Dash(__name__)
app.layout = html.Div(
[
dcc.RadioItems(
options=[
{"label": "Chapter 1", "value": "chapter1"},
{"label": "Chapter 2", "value": "chapter2"},
{"label": "Chapter 3", "value": "chapter3"},
{"label": "Chapter 4", "value": "chapter4"},
{"label": "Chapter 5", "value": "chapter5"},
],
value="chapter1",
id="toc",
),
html.Div(id="body"),
]
)
for script in dcc._js_dist:
app.scripts.append_script(script)

chapters = {
"chapter1": html.Div(
[
html.H1("Chapter 1", id="chapter1-header"),
dcc.Dropdown(
options=[
{"label": i, "value": i} for i in ["NYC", "MTL", "SF"]
],
value="NYC",
id="chapter1-controls",
),
html.Label(id="chapter1-label"),
dcc.Graph(id="chapter1-graph"),
]
),
# Chapter 2 has the some of the same components in the same order
# as Chapter 1. This means that they won't get remounted
# unless they set their own keys are differently.
# Switching back and forth between 1 and 2 implicitly
# tests how components update when they aren't remounted.
"chapter2": html.Div(
[
html.H1("Chapter 2", id="chapter2-header"),
dcc.RadioItems(
options=[
{"label": i, "value": i} for i in ["USA", "Canada"]
],
value="USA",
id="chapter2-controls",
),
html.Label(id="chapter2-label"),
dcc.Graph(id="chapter2-graph"),
]
),
# Chapter 3 has a different layout and so the components
# should get rewritten
"chapter3": [
html.Div(
html.Div(
[
html.H3("Chapter 3", id="chapter3-header"),
html.Label(id="chapter3-label"),
dcc.Graph(id="chapter3-graph"),
dcc.RadioItems(
options=[
{"label": i, "value": i}
for i in ["Summer", "Winter"]
],
value="Winter",
id="chapter3-controls",
),
]
)
)
],
# Chapter 4 doesn't have an object to recursively traverse
"chapter4": "Just a string",
}

call_counts = {
"body": Value("i", 0),
"chapter1-graph": Value("i", 0),
"chapter1-label": Value("i", 0),
"chapter2-graph": Value("i", 0),
"chapter2-label": Value("i", 0),
"chapter3-graph": Value("i", 0),
"chapter3-label": Value("i", 0),
}

@app.callback(Output("body", "children"), [Input("toc", "value")])
def display_chapter(toc_value):
call_counts["body"].value += 1
return chapters[toc_value]

app.config.suppress_callback_exceptions = True

def generate_graph_callback(counterId):
def callback(value):
call_counts[counterId].value += 1
return {
"data": [
{
"x": ["Call Counter"],
"y": [call_counts[counterId].value],
"type": "bar",
}
],
"layout": {"title": value},
}

return callback

def generate_label_callback(id_):
def update_label(value):
call_counts[id_].value += 1
return value

return update_label

for chapter in ["chapter1", "chapter2", "chapter3"]:
app.callback(
Output("{}-graph".format(chapter), "figure"),
[Input("{}-controls".format(chapter), "value")],
)(generate_graph_callback("{}-graph".format(chapter)))

app.callback(
Output("{}-label".format(chapter), "children"),
[Input("{}-controls".format(chapter), "value")],
)(generate_label_callback("{}-label".format(chapter)))

dash_duo.start_server(app)

def check_chapter(chapter):
for key in dash_duo.redux_state_paths:
assert dash_duo.find_elements(
"#{}".format(key)
), "each element should exist in the dom"

value = (
chapters[chapter][0]["{}-controls".format(chapter)].value
if chapter == "chapter3"
else chapters[chapter]["{}-controls".format(chapter)].value
)
# check the actual values
dash_duo.wait_for_text_to_equal("#{}-label".format(chapter), value)
wait.until(
lambda: (
dash_duo.driver.execute_script(
"return document."
'getElementById("{}-graph").'.format(chapter)
+ "layout.title.text"
)
== value
),
TIMEOUT,
)

rqs = dash_duo.redux_state_rqs
assert rqs, "request queue is not empty"
assert all((rq["status"] == 200 and not rq["rejected"] for rq in rqs))

def check_call_counts(chapters, count):
for chapter in chapters:
assert call_counts[chapter + "-graph"].value == count
assert call_counts[chapter + "-label"].value == count

wait.until(lambda: call_counts["body"].value == 1, TIMEOUT)
wait.until(lambda: call_counts["chapter1-graph"].value == 1, TIMEOUT)
wait.until(lambda: call_counts["chapter1-label"].value == 1, TIMEOUT)
check_call_counts(("chapter2", "chapter3"), 0)

assert dash_duo.redux_state_paths == EXPECTED_PATHS["chapter1"]
check_chapter("chapter1")
dash_duo.percy_snapshot(name="chapter-1")

dash_duo.find_elements('input[type="radio"]')[1].click() # switch chapters

wait.until(lambda: call_counts["body"].value == 2, TIMEOUT)
wait.until(lambda: call_counts["chapter2-graph"].value == 1, TIMEOUT)
wait.until(lambda: call_counts["chapter2-label"].value == 1, TIMEOUT)
check_call_counts(("chapter1",), 1)

assert dash_duo.redux_state_paths == EXPECTED_PATHS["chapter2"]
check_chapter("chapter2")
dash_duo.percy_snapshot(name="chapter-2")

# switch to 3
dash_duo.find_elements('input[type="radio"]')[2].click()

wait.until(lambda: call_counts["body"].value == 3, TIMEOUT)
wait.until(lambda: call_counts["chapter3-graph"].value == 1, TIMEOUT)
wait.until(lambda: call_counts["chapter3-label"].value == 1, TIMEOUT)
check_call_counts(("chapter2", "chapter1"), 1)

assert dash_duo.redux_state_paths == EXPECTED_PATHS["chapter3"]
check_chapter("chapter3")
dash_duo.percy_snapshot(name="chapter-3")

dash_duo.find_elements('input[type="radio"]')[3].click() # switch to 4
dash_duo.wait_for_text_to_equal("#body", "Just a string")
dash_duo.percy_snapshot(name="chapter-4")
for key in dash_duo.redux_state_paths:
assert dash_duo.find_elements(
"#{}".format(key)
), "each element should exist in the dom"

assert dash_duo.redux_state_paths == {
"toc": ["props", "children", 0],
"body": ["props", "children", 1],
}

dash_duo.find_elements('input[type="radio"]')[0].click()

wait.until(
lambda: dash_duo.redux_state_paths == EXPECTED_PATHS["chapter1"],
TIMEOUT,
)
check_chapter("chapter1")
dash_duo.percy_snapshot(name="chapter-1-again")
Loading

0 comments on commit 28fee35

Please sign in to comment.