-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
PersistenceTransforms for date in datePickerRange and datePickerSingle #1376
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
Changes from 11 commits
56f0a0e
4f07812
4479682
6937f1c
65938ac
94b91c7
951a767
b180d00
a5e0874
54f6229
9b60d4a
59bbf30
900af6f
109ea46
fe58b2a
91c5324
5c11477
1f04bc5
424b6dd
0cb4d02
9c5e33d
963031b
4c47006
95af752
738a9ec
0b97608
e541e62
3c3efbf
1586634
b063d60
e2cab41
06d77d3
2b240e2
e4026e6
5601ec3
1596d43
37d454f
f7c04fd
6f2ce30
b5f78b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -265,10 +265,22 @@ const noopTransform = { | |||||
apply: (storedValue, _propValue) => storedValue, | ||||||
}; | ||||||
|
||||||
const getTransform = (element, propName, propPart) => | ||||||
propPart | ||||||
? element.persistenceTransforms[propName][propPart] | ||||||
: noopTransform; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Old logic checks for just |
||||||
const getTransform = (element, propName, propPart) => { | ||||||
if (typeof element.persistenceTransforms !== 'undefined') { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here you can simplify the top level check to:
Suggested change
any truth-y value will pass the test (https://dorey.github.io/JavaScript-Equality-Table/) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
if ( | ||||||
Object.getOwnPropertyNames(element.persistenceTransforms).includes( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can be simplified to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
propName | ||||||
) | ||||||
) { | ||||||
if (propPart) { | ||||||
return element.persistenceTransforms[propName][propPart]; | ||||||
} | ||||||
return element.persistenceTransforms[propName]; | ||||||
} | ||||||
return noopTransform; | ||||||
} | ||||||
return noopTransform; | ||||||
}; | ||||||
|
||||||
const getValsKey = (id, persistedProp, persistence) => | ||||||
`${stringifyId(id)}.${persistedProp}.${JSON.stringify(persistence)}`; | ||||||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -11,6 +11,12 @@ | |||
import dash_html_components as html | ||||
import dash_table as dt | ||||
|
||||
from datetime import datetime | ||||
from datetime import timedelta as td | ||||
|
||||
|
||||
from selenium.webdriver.common.action_chains import ActionChains | ||||
|
||||
|
||||
@pytest.fixture(autouse=True) | ||||
def clear_storage(dash_duo): | ||||
|
@@ -526,3 +532,189 @@ def set_out(val): | |||
dash_duo.wait_for_text_to_equal(".out", "") | ||||
|
||||
dash_duo.find_element("#btn").click() | ||||
|
||||
|
||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test persistence for DatePickerSingle and DatePicker range in callbacks, in conjunction with plotly/dash-core-components#848. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While I think it's good to have at least one test that checks that persistence works as expected with and without a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could create a new test component similar to https://github.com/plotly/dash/tree/dev/%40plotly/dash-generator-test-component-standard that has both (1) prop part, (2) no prop part for two different persisted props, and we can validate the behavior against that component instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||
def test_rdps013_persisted_dps(dash_duo): | ||||
app = dash.Dash(__name__) | ||||
app.layout = html.Div( | ||||
[ | ||||
html.Button("fire callback", id="btn"), | ||||
html.Div( | ||||
children=[ | ||||
dcc.DatePickerSingle( | ||||
id="dps1", | ||||
date=datetime.today(), | ||||
persistence=True, | ||||
persistence_type="session", | ||||
), | ||||
html.P("dps1", id="dps1-p"), | ||||
html.Div(id="container"), | ||||
html.P("dps2", id="dps2-p"), | ||||
] | ||||
), | ||||
] | ||||
) | ||||
|
||||
@app.callback(Output("container", "children"), [Input("btn", "n_clicks")]) | ||||
def update_output(value): | ||||
return dcc.DatePickerSingle( | ||||
id="dps2", | ||||
date=datetime.today(), | ||||
persistence=True, | ||||
persistence_type="session", | ||||
) | ||||
|
||||
@app.callback(Output("dps1-p", "children"), [Input("dps1", "date")]) | ||||
def display_dps1(value): | ||||
print(value) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔪 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||
return value | ||||
|
||||
@app.callback(Output("dps2-p", "children"), [Input("dps2", "date")]) | ||||
def display_dps2(value): | ||||
return value | ||||
|
||||
dash_duo.start_server(app) | ||||
dps1 = dash_duo.find_element("#dps1") | ||||
dps2 = dash_duo.find_element("#dps2") | ||||
|
||||
( | ||||
ActionChains(dash_duo.driver) | ||||
.move_to_element(dps1) | ||||
.pause(0.2) | ||||
.click(dps1) | ||||
.send_keys(Keys.END) | ||||
.key_down(Keys.SHIFT) | ||||
.send_keys(Keys.HOME) | ||||
.key_up(Keys.SHIFT) | ||||
.send_keys(Keys.DELETE) | ||||
.send_keys("01/01/2020") | ||||
.send_keys(Keys.ENTER) | ||||
).perform() | ||||
|
||||
dash_duo.wait_for_text_to_equal("#dps1-p", "2020-01-01") | ||||
|
||||
( | ||||
ActionChains(dash_duo.driver) | ||||
.move_to_element(dps2) | ||||
.pause(0.2) | ||||
.click(dps2) | ||||
.send_keys(Keys.END) | ||||
.key_down(Keys.SHIFT) | ||||
.send_keys(Keys.HOME) | ||||
.key_up(Keys.SHIFT) | ||||
.send_keys(Keys.DELETE) | ||||
.send_keys("01/01/2020") | ||||
.send_keys(Keys.ENTER) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DRY 🌴🐫 def set_date(target, date): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||
).perform() | ||||
|
||||
dash_duo.wait_for_text_to_equal("#dps2-p", "2020-01-01") | ||||
|
||||
dash_duo.find_element("#btn").click() | ||||
|
||||
dash_duo.wait_for_text_to_equal("#dps1-p", "2020-01-01") | ||||
dash_duo.wait_for_text_to_equal("#dps2-p", "2020-01-01") | ||||
|
||||
|
||||
def test_rdps014_persisted_dpr(dash_duo): | ||||
app = dash.Dash(__name__) | ||||
app.layout = html.Div( | ||||
[ | ||||
html.Button("fire callback", id="btn"), | ||||
html.Div( | ||||
children=[ | ||||
dcc.DatePickerRange( | ||||
id="dpr1", | ||||
start_date=datetime.today() - td(days=3), | ||||
end_date=datetime.today(), | ||||
persistence=True, | ||||
persistence_type="session", | ||||
), | ||||
html.P("dpr1", id="dpr1-p-start"), | ||||
html.P("dpr1", id="dpr1-p-end"), | ||||
html.Div(id="container"), | ||||
html.P("dpr2", id="dpr2-p-start"), | ||||
html.P("dpr2", id="dpr2-p-end"), | ||||
] | ||||
), | ||||
] | ||||
) | ||||
|
||||
@app.callback(Output("container", "children"), [Input("btn", "n_clicks")]) | ||||
def update_output(value): | ||||
return dcc.DatePickerRange( | ||||
id="dpr2", | ||||
start_date=datetime.today() - td(days=3), | ||||
end_date=datetime.today(), | ||||
persistence=True, | ||||
persistence_type="session", | ||||
) | ||||
|
||||
@app.callback(Output("dpr1-p-start", "children"), [Input("dpr1", "start_date")]) | ||||
def display_dps1(value): | ||||
print(value) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔪 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||
return value | ||||
|
||||
@app.callback(Output("dpr1-p-end", "children"), [Input("dpr1", "end_date")]) | ||||
def display_dps1(value): | ||||
print(value) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔪 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||
return value | ||||
|
||||
@app.callback(Output("dpr2-p-start", "children"), [Input("dpr2", "start_date")]) | ||||
def display_dps2(value): | ||||
return value | ||||
|
||||
@app.callback(Output("dpr2-p-end", "children"), [Input("dpr2", "end_date")]) | ||||
def display_dps2(value): | ||||
return value | ||||
|
||||
dash_duo.start_server(app) | ||||
dpr1 = dash_duo.find_element("div#dpr1 div div div div .DateInput_input") | ||||
dpr2 = dash_duo.find_element("div#dpr2 div div div div .DateInput_input") | ||||
|
||||
( | ||||
ActionChains(dash_duo.driver) | ||||
.move_to_element(dpr1) | ||||
.click(dpr1) | ||||
.send_keys(Keys.END) | ||||
.key_down(Keys.SHIFT) | ||||
.send_keys(Keys.HOME) | ||||
.key_up(Keys.SHIFT) | ||||
.send_keys("01/01/2020") | ||||
.pause(0.2) | ||||
.send_keys(Keys.END) | ||||
.key_down(Keys.SHIFT) | ||||
.send_keys(Keys.HOME) | ||||
.key_up(Keys.SHIFT) | ||||
.send_keys("01/02/2020") | ||||
).perform() | ||||
|
||||
dash_duo.wait_for_text_to_equal("#dpr1-p-start", "2020-01-01") | ||||
dash_duo.wait_for_text_to_equal("#dpr1-p-end", "2020-01-02") | ||||
|
||||
( | ||||
ActionChains(dash_duo.driver) | ||||
.move_to_element(dpr2) | ||||
.click(dpr2) | ||||
.send_keys(Keys.END) | ||||
.key_down(Keys.SHIFT) | ||||
.send_keys(Keys.HOME) | ||||
.key_up(Keys.SHIFT) | ||||
.send_keys("01/01/2020") | ||||
.pause(0.2) | ||||
# .send_keys("01/02/2020") | ||||
.send_keys(Keys.END) | ||||
.key_down(Keys.SHIFT) | ||||
.send_keys(Keys.HOME) | ||||
.key_up(Keys.SHIFT) | ||||
.send_keys("01/02/2020") | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DRY 🌴🐫 def set_date_range(target, start_date, end_date): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's also
|
||||
).perform() | ||||
|
||||
dash_duo.wait_for_text_to_equal("#dpr2-p-start", "2020-01-01") | ||||
dash_duo.wait_for_text_to_equal("#dpr2-p-end", "2020-01-02") | ||||
|
||||
dash_duo.find_element("#btn").click() | ||||
|
||||
dash_duo.wait_for_text_to_equal("#dpr1-p-start", "2020-01-01") | ||||
dash_duo.wait_for_text_to_equal("#dpr1-p-end", "2020-01-02") | ||||
dash_duo.wait_for_text_to_equal("#dpr2-p-start", "2020-01-01") | ||||
dash_duo.wait_for_text_to_equal("#dpr2-p-end", "2020-01-02") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be unnecessary now that we test against a custom-made component