mirror of
https://github.com/pyscript/pyscript.git
synced 2026-02-13 07:01:00 -05:00
Remove deprecated elements and adds deprecation banner to pys-on (#1084)
* Show deprecation banner * Add test for deprecation warning * Remove deprecated elements * Add entry in changelog * Update test_style * Remove random color rule * Add PR link to changelog
This commit is contained in:
@@ -14,3 +14,9 @@ Documentation
|
||||
-------------
|
||||
|
||||
- Fixed 'Direct usage of document is deprecated' warning in the getting started guide. ([#1052](https://github.com/pyscript/pyscript/pull/1052))
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- The attributes `pys-onClick` and `pys-onKeyDown` have been deprecated, but the warning was only shown in the console. An alert banner will now be shown on the page if the attributes are used. They will be removed in the next release. ([#1084](https://github.com/pyscript/pyscript/pull/1084))
|
||||
- The pyscript elements `py-button`, `py-inputbox`, `py-box` and `py-title` have now completed their deprecation cycle and have been removed. ([#1084](https://github.com/pyscript/pyscript/pull/1084))
|
||||
|
||||
@@ -1,24 +1,14 @@
|
||||
import type { Runtime } from '../runtime';
|
||||
import { make_PyRepl } from './pyrepl';
|
||||
import { PyBox } from './pybox';
|
||||
import { make_PyButton } from './pybutton';
|
||||
import { PyTitle } from './pytitle';
|
||||
import { make_PyInputBox } from './pyinputbox';
|
||||
import { make_PyWidget } from './pywidget';
|
||||
|
||||
function createCustomElements(runtime: Runtime) {
|
||||
const PyInputBox = make_PyInputBox(runtime);
|
||||
const PyButton = make_PyButton(runtime);
|
||||
const PyWidget = make_PyWidget(runtime);
|
||||
const PyRepl = make_PyRepl(runtime);
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
const xPyRepl = customElements.define('py-repl', PyRepl);
|
||||
const xPyBox = customElements.define('py-box', PyBox);
|
||||
const xPyTitle = customElements.define('py-title', PyTitle);
|
||||
const xPyWidget = customElements.define('py-register-widget', PyWidget);
|
||||
const xPyInputBox = customElements.define('py-inputbox', PyInputBox);
|
||||
const xPyButton = customElements.define('py-button', PyButton);
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
}
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
import { getAttribute, addClasses, createDeprecationWarning } from '../utils';
|
||||
import { getLogger } from '../logger';
|
||||
|
||||
const logger = getLogger('py-box');
|
||||
|
||||
export class PyBox extends HTMLElement {
|
||||
shadow: ShadowRoot;
|
||||
wrapper: HTMLElement;
|
||||
theme: string;
|
||||
widths: string[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// attach shadow so we can preserve the element original innerHtml content
|
||||
this.shadow = this.attachShadow({ mode: 'open' });
|
||||
|
||||
this.wrapper = document.createElement('slot');
|
||||
this.shadow.appendChild(this.wrapper);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const deprecationMessage =
|
||||
'The element <py-box> is deprecated, you should create a ' +
|
||||
'div with "py-box" class name instead. For example: <div class="py-box">';
|
||||
createDeprecationWarning(deprecationMessage, 'py-box');
|
||||
const mainDiv = document.createElement('div');
|
||||
addClasses(mainDiv, ['py-box']);
|
||||
|
||||
// Hack: for some reason when moving children, the editor box duplicates children
|
||||
// meaning that we end up with 2 editors, if there's a <py-repl> inside the <py-box>
|
||||
// so, if we have more than 2 children with the cm-editor class, we remove one of them
|
||||
while (this.childNodes.length > 0) {
|
||||
if (this.firstChild.nodeName == 'PY-REPL') {
|
||||
// in this case we need to remove the child and create a new one from scratch
|
||||
const replDiv = document.createElement('div');
|
||||
// we need to put the new repl inside a div so that if the repl has auto-generate true
|
||||
// it can replicate itself inside that constrained div
|
||||
replDiv.appendChild(this.firstChild.cloneNode());
|
||||
mainDiv.appendChild(replDiv);
|
||||
this.firstChild.remove();
|
||||
} else {
|
||||
if (this.firstChild.nodeName != '#text') {
|
||||
mainDiv.appendChild(this.firstChild);
|
||||
} else {
|
||||
this.firstChild.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now we need to set widths
|
||||
this.widths = [];
|
||||
|
||||
const widthsAttr = getAttribute(this, 'widths');
|
||||
if (widthsAttr) {
|
||||
for (const w of widthsAttr.split(';')) {
|
||||
if (w.includes('/')) {
|
||||
this.widths.push(w.split('/')[0]);
|
||||
} else {
|
||||
this.widths.push(w);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.widths = Array<string>(mainDiv.children.length).fill('1 1 0');
|
||||
}
|
||||
|
||||
this.widths.forEach((width, index) => {
|
||||
const node: ChildNode = mainDiv.childNodes[index];
|
||||
(<HTMLElement>node).style.flex = width;
|
||||
addClasses(<HTMLElement>node, ['py-box-child']);
|
||||
});
|
||||
|
||||
this.appendChild(mainDiv);
|
||||
logger.info('py-box connected');
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
import { getAttribute, addClasses, htmlDecode, ensureUniqueId, createDeprecationWarning } from '../utils';
|
||||
import { getLogger } from '../logger';
|
||||
import type { Runtime } from '../runtime';
|
||||
|
||||
const logger = getLogger('py-button');
|
||||
|
||||
export function make_PyButton(runtime: Runtime) {
|
||||
class PyButton extends HTMLElement {
|
||||
widths: string[] = [];
|
||||
label: string | undefined = undefined;
|
||||
class: string[];
|
||||
defaultClass: string[];
|
||||
mount_name: string | undefined = undefined;
|
||||
code: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.defaultClass = ['py-button'];
|
||||
|
||||
const label = getAttribute(this, 'label');
|
||||
if (label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
// Styling does the same thing as class in normal HTML. Using the name "class" makes the style to malfunction
|
||||
const styling = getAttribute(this, 'styling');
|
||||
if (styling) {
|
||||
const klass = styling.trim();
|
||||
if (klass === '') {
|
||||
this.class = this.defaultClass;
|
||||
} else {
|
||||
// trim each element to remove unnecessary spaces which makes the button style to malfunction
|
||||
this.class = klass
|
||||
.split(' ')
|
||||
.map(x => x.trim())
|
||||
.filter(x => x !== '');
|
||||
}
|
||||
} else {
|
||||
this.class = this.defaultClass;
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const deprecationMessage =
|
||||
'The element <py-button> is deprecated, create a function with your ' +
|
||||
'inline code and use <button py-click="function()" class="py-button"> instead.';
|
||||
createDeprecationWarning(deprecationMessage, 'py-button');
|
||||
|
||||
ensureUniqueId(this);
|
||||
this.code = htmlDecode(this.innerHTML) || '';
|
||||
this.mount_name = this.id.split('-').join('_');
|
||||
this.innerHTML = '';
|
||||
|
||||
const mainDiv = document.createElement('button');
|
||||
mainDiv.innerHTML = this.label;
|
||||
addClasses(mainDiv, this.class);
|
||||
|
||||
mainDiv.id = this.id;
|
||||
this.id = `${this.id}-container`;
|
||||
|
||||
this.appendChild(mainDiv);
|
||||
this.code = this.code.split('self').join(this.mount_name);
|
||||
let registrationCode = `from pyodide.ffi import create_proxy`;
|
||||
registrationCode += `\n${this.mount_name} = Element("${mainDiv.id}")`;
|
||||
if (this.code.includes('def on_focus')) {
|
||||
this.code = this.code.replace('def on_focus', `def on_focus_${this.mount_name}`);
|
||||
registrationCode += `\n${this.mount_name}.element.addEventListener('focus', create_proxy(on_focus_${this.mount_name}))`;
|
||||
}
|
||||
|
||||
if (this.code.includes('def on_click')) {
|
||||
this.code = this.code.replace('def on_click', `def on_click_${this.mount_name}`);
|
||||
registrationCode += `\n${this.mount_name}.element.addEventListener('click', create_proxy(on_click_${this.mount_name}))`;
|
||||
}
|
||||
|
||||
// now that we appended and the element is attached, lets connect with the event handlers
|
||||
// defined for this widget
|
||||
runtime.runButDontRaise(this.code);
|
||||
runtime.runButDontRaise(registrationCode);
|
||||
logger.debug('py-button connected');
|
||||
}
|
||||
}
|
||||
|
||||
return PyButton;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import { getAttribute, addClasses, htmlDecode, ensureUniqueId, createDeprecationWarning } from '../utils';
|
||||
import { getLogger } from '../logger';
|
||||
import type { Runtime } from '../runtime';
|
||||
|
||||
const logger = getLogger('py-inputbox');
|
||||
|
||||
export function make_PyInputBox(runtime: Runtime) {
|
||||
class PyInputBox extends HTMLElement {
|
||||
widths: string[] = [];
|
||||
label: string | undefined = undefined;
|
||||
mount_name: string | undefined = undefined;
|
||||
code: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const label = getAttribute(this, 'label');
|
||||
if (label) {
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const deprecationMessage =
|
||||
'The element <py-input> is deprecated, ' + 'use <input class="py-input"> instead.';
|
||||
createDeprecationWarning(deprecationMessage, 'py-input');
|
||||
ensureUniqueId(this);
|
||||
this.code = htmlDecode(this.innerHTML);
|
||||
this.mount_name = this.id.split('-').join('_');
|
||||
this.innerHTML = '';
|
||||
|
||||
const mainDiv = document.createElement('input');
|
||||
mainDiv.type = 'text';
|
||||
addClasses(mainDiv, ['py-input']);
|
||||
|
||||
mainDiv.id = this.id;
|
||||
this.id = `${this.id}-container`;
|
||||
this.appendChild(mainDiv);
|
||||
|
||||
// now that we appended and the element is attached, lets connect with the event handlers
|
||||
// defined for this widget
|
||||
this.appendChild(mainDiv);
|
||||
this.code = this.code.split('self').join(this.mount_name);
|
||||
let registrationCode = `from pyodide.ffi import create_proxy`;
|
||||
registrationCode += `\n${this.mount_name} = Element("${mainDiv.id}")`;
|
||||
if (this.code.includes('def on_keypress')) {
|
||||
this.code = this.code.replace('def on_keypress', `def on_keypress_${this.mount_name}`);
|
||||
registrationCode += `\n${this.mount_name}.element.addEventListener('keypress', create_proxy(on_keypress_${this.mount_name}))`;
|
||||
}
|
||||
|
||||
runtime.runButDontRaise(this.code);
|
||||
runtime.runButDontRaise(registrationCode);
|
||||
logger.debug('py-inputbox connected');
|
||||
}
|
||||
}
|
||||
|
||||
return PyInputBox;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { htmlDecode, ensureUniqueId, showWarning } from '../utils';
|
||||
import { htmlDecode, ensureUniqueId, showWarning, createDeprecationWarning } from '../utils';
|
||||
import type { Runtime } from '../runtime';
|
||||
import { getLogger } from '../logger';
|
||||
import { pyExec } from '../pyexec';
|
||||
@@ -165,9 +165,10 @@ function createElementsWithEventListeners(runtime: Runtime, pyAttribute: string)
|
||||
const event = pyAttributeToEvent.get(pyAttribute);
|
||||
|
||||
if (pyAttribute === 'pys-onClick' || pyAttribute === 'pys-onKeyDown') {
|
||||
console.warn(
|
||||
'Use of pys-onClick and pys-onKeyDown attributes is deprecated in favor of py-onClick() and py-onKeyDown(). pys-on* attributes will be deprecated in a future version of PyScript.',
|
||||
);
|
||||
const msg =
|
||||
`The attribute 'pys-onClick' and 'pys-onKeyDown' are deprecated. Please 'py-click="myFunction()"' ` +
|
||||
` or 'py-keydown="myFunction()"' instead.`;
|
||||
createDeprecationWarning(msg, msg);
|
||||
const source = `
|
||||
from pyodide.ffi import create_proxy
|
||||
Element("${el.id}").element.addEventListener("${event}", create_proxy(${handlerCode}))
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { addClasses, htmlDecode, createDeprecationWarning } from '../utils';
|
||||
|
||||
export class PyTitle extends HTMLElement {
|
||||
widths: string[];
|
||||
label: string;
|
||||
mount_name: string;
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const deprecationMessage = 'The element <py-title> is deprecated, please use an <h1> tag instead.';
|
||||
createDeprecationWarning(deprecationMessage, 'py-title');
|
||||
this.label = htmlDecode(this.innerHTML);
|
||||
this.mount_name = this.id.split('-').join('_');
|
||||
this.innerHTML = '';
|
||||
|
||||
const mainDiv = document.createElement('div');
|
||||
const divContent = document.createElement('h1');
|
||||
|
||||
addClasses(mainDiv, ['py-title']);
|
||||
divContent.innerHTML = this.label;
|
||||
|
||||
mainDiv.id = this.id;
|
||||
this.id = `${this.id}-container`;
|
||||
mainDiv.appendChild(divContent);
|
||||
this.appendChild(mainDiv);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,6 @@ html {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
color: #0f172a;
|
||||
.py-pop-up {
|
||||
text-align: center;
|
||||
width: 600px;
|
||||
|
||||
@@ -292,3 +292,22 @@ class TestBasic(PyScriptTest):
|
||||
pyscript_tag.evaluate("node => node.getPySrc()")
|
||||
== 'print("hello world!")\n'
|
||||
)
|
||||
|
||||
def test_pys_onClick_shows_deprecation_warning(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<button id="1" pys-onClick="myfunc()">Click me</button>
|
||||
<py-script>
|
||||
def myfunc():
|
||||
print("hello world")
|
||||
|
||||
</py-script>
|
||||
"""
|
||||
)
|
||||
banner = self.page.locator(".alert-banner")
|
||||
expected_message = (
|
||||
"The attribute 'pys-onClick' and 'pys-onKeyDown' are "
|
||||
"deprecated. Please 'py-click=\"myFunction()\"' or "
|
||||
"'py-keydown=\"myFunction()\"' instead."
|
||||
)
|
||||
assert banner.inner_text() == expected_message
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
from .support import PyScriptTest
|
||||
|
||||
|
||||
class TestPyButton(PyScriptTest):
|
||||
def test_box(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-box>
|
||||
<py-box>
|
||||
</py-box>
|
||||
</py-box>
|
||||
"""
|
||||
)
|
||||
|
||||
pybox_element = self.page.query_selector_all("py-box")
|
||||
|
||||
assert len(pybox_element) == 2
|
||||
assert pybox_element[1].get_attribute("class") == "py-box-child"
|
||||
|
||||
def test_deprecated_element(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-box>
|
||||
</py-box>
|
||||
"""
|
||||
)
|
||||
banner = self.page.locator(".py-warning")
|
||||
banner_content = banner.inner_text()
|
||||
expected = (
|
||||
"The element <py-box> is deprecated, you should create a div "
|
||||
'with "py-box" class name instead. For example: <div class="py-box">'
|
||||
)
|
||||
|
||||
assert banner_content == expected
|
||||
@@ -1,60 +0,0 @@
|
||||
from .support import PyScriptTest
|
||||
|
||||
|
||||
class TestPyButton(PyScriptTest):
|
||||
def test_on_click(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-button label="my button">
|
||||
import js
|
||||
def on_click(evt):
|
||||
js.console.log('clicked!')
|
||||
</py-button>
|
||||
"""
|
||||
)
|
||||
assert self.console.log.lines[0] == self.PY_COMPLETE
|
||||
self.page.locator("text=my button").click()
|
||||
self.page.locator("text=my button").click()
|
||||
|
||||
assert self.console.log.lines[-2:] == ["clicked!", "clicked!"]
|
||||
|
||||
def test_deprecated_element(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-button label="my button">
|
||||
import js
|
||||
def on_click(evt):
|
||||
js.console.log('clicked!')
|
||||
</py-button>
|
||||
"""
|
||||
)
|
||||
banner = self.page.locator(".py-warning")
|
||||
banner_content = banner.inner_text()
|
||||
expected = (
|
||||
"The element <py-button> is deprecated, create a function with your "
|
||||
'inline code and use <button py-click="function()" class="py-button"> instead.'
|
||||
)
|
||||
|
||||
assert banner_content == expected
|
||||
|
||||
def test_creates_single_deprecation_banner(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-button label="my button">
|
||||
import js
|
||||
def on_click(evt):
|
||||
js.console.log('clicked!')
|
||||
</py-button>
|
||||
<py-button label="another button!">
|
||||
</py-button>
|
||||
"""
|
||||
)
|
||||
banner = self.page.query_selector_all(".py-warning")
|
||||
assert len(banner) == 1
|
||||
banner_content = banner[0].inner_text()
|
||||
expected = (
|
||||
"The element <py-button> is deprecated, create a function with your "
|
||||
'inline code and use <button py-click="function()" class="py-button"> instead.'
|
||||
)
|
||||
|
||||
assert banner_content == expected
|
||||
@@ -1,42 +0,0 @@
|
||||
from .support import PyScriptTest
|
||||
|
||||
|
||||
class TestPyInputBox(PyScriptTest):
|
||||
def test_input_box_typing(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-inputbox label="my input">
|
||||
import js
|
||||
def on_keypress(evt):
|
||||
if evt.key == "Enter":
|
||||
js.console.log(evt.target.value)
|
||||
</py-inputbox>
|
||||
"""
|
||||
)
|
||||
assert self.console.log.lines[0] == self.PY_COMPLETE
|
||||
input = self.page.locator("input")
|
||||
|
||||
input.type("Hello")
|
||||
input.press("Enter")
|
||||
|
||||
assert self.console.log.lines[-1] == "Hello"
|
||||
|
||||
def test_deprecated_element(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-inputbox label="my input">
|
||||
import js
|
||||
def on_keypress(evt):
|
||||
if evt.key == "Enter":
|
||||
js.console.log(evt.target.value)
|
||||
</py-inputbox>
|
||||
"""
|
||||
)
|
||||
banner = self.page.locator(".py-warning")
|
||||
banner_content = banner.inner_text()
|
||||
expected = (
|
||||
"The element <py-input> is deprecated, "
|
||||
'use <input class="py-input"> instead.'
|
||||
)
|
||||
|
||||
assert banner_content == expected
|
||||
@@ -1,30 +0,0 @@
|
||||
from .support import PyScriptTest
|
||||
|
||||
|
||||
class TestPyTitle(PyScriptTest):
|
||||
def test_title_shows_on_page(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-title>Hello, World!</py-title>
|
||||
"""
|
||||
)
|
||||
|
||||
py_title = self.page.query_selector("py-title")
|
||||
# check that we do have py-title in the page, if not
|
||||
# py_title will be none
|
||||
assert py_title
|
||||
assert py_title.text_content() == "Hello, World!"
|
||||
|
||||
def test_deprecated_element(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<py-title>Hello, world!</py-title>
|
||||
"""
|
||||
)
|
||||
banner = self.page.locator(".py-warning")
|
||||
banner_content = banner.inner_text()
|
||||
expected = (
|
||||
"The element <py-title> is deprecated, please use an <h1> tag instead."
|
||||
)
|
||||
|
||||
assert banner_content == expected
|
||||
@@ -15,10 +15,6 @@ class TestStyle(PyScriptTest):
|
||||
<py-config>hello</py-config>
|
||||
<py-script>hello</py-script>
|
||||
<py-repl>hello</py-repl>
|
||||
<py-title>hello</py-title>
|
||||
<py-inputbox>hello</py-inputbox>
|
||||
<py-button>hello</py-button>
|
||||
<py-box>hello</py-box>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
@@ -27,10 +23,6 @@ class TestStyle(PyScriptTest):
|
||||
expect(self.page.locator("py-config")).to_be_hidden()
|
||||
expect(self.page.locator("py-script")).to_be_hidden()
|
||||
expect(self.page.locator("py-repl")).to_be_hidden()
|
||||
expect(self.page.locator("py-title")).to_be_hidden()
|
||||
expect(self.page.locator("py-inputbox")).to_be_hidden()
|
||||
expect(self.page.locator("py-button")).to_be_hidden()
|
||||
expect(self.page.locator("py-box")).to_be_hidden()
|
||||
|
||||
def test_pyscript_defined(self):
|
||||
"""Test elements have visibility that should"""
|
||||
@@ -41,26 +33,8 @@ class TestStyle(PyScriptTest):
|
||||
</py-config>
|
||||
<py-script>display("hello")</py-script>
|
||||
<py-repl>display("hello")</py-repl>
|
||||
<py-title>hello</py-title>
|
||||
<py-inputbox label="my input">
|
||||
import js
|
||||
def on_keypress(evt):
|
||||
if evt.key == "Enter":
|
||||
js.console.log(evt.target.value)
|
||||
</py-inputbox>
|
||||
<py-box>
|
||||
<py-button label="my button">
|
||||
import js
|
||||
def on_click(evt):
|
||||
js.console.log('clicked!')
|
||||
</py-button>
|
||||
</py-box>
|
||||
"""
|
||||
)
|
||||
expect(self.page.locator("py-config")).to_be_hidden()
|
||||
expect(self.page.locator("py-script")).to_be_visible()
|
||||
expect(self.page.locator("py-repl")).to_be_visible()
|
||||
expect(self.page.locator("py-title")).to_be_visible()
|
||||
expect(self.page.locator("py-inputbox")).to_be_visible()
|
||||
expect(self.page.locator("py-button")).to_be_visible()
|
||||
expect(self.page.locator("py-box")).to_be_visible()
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { PyBox } from "../../src/components/pybox"
|
||||
|
||||
customElements.define('py-box', PyBox)
|
||||
|
||||
describe('PyBox', () => {
|
||||
let instance: PyBox;
|
||||
|
||||
beforeEach(() => {
|
||||
instance = new PyBox();
|
||||
})
|
||||
|
||||
it('PyBox instantiates correctly', async () => {
|
||||
expect(instance).toBeInstanceOf(PyBox)
|
||||
})
|
||||
|
||||
it("test connectedCallback creates pybox div", async () => {
|
||||
expect(instance.innerHTML).toBe("")
|
||||
instance.connectedCallback()
|
||||
|
||||
expect(instance.innerHTML).toBe('<div class=\"py-box\"></div>')
|
||||
})
|
||||
|
||||
})
|
||||
@@ -1,88 +0,0 @@
|
||||
import type { Runtime } from "../../src/runtime"
|
||||
import { FakeRuntime } from "./fakeruntime"
|
||||
import { make_PyButton } from '../../src/components/pybutton';
|
||||
import { ensureUniqueId } from '../../src/utils';
|
||||
|
||||
const runtime: Runtime = new FakeRuntime();
|
||||
const PyButton = make_PyButton(runtime);
|
||||
customElements.define('py-button', PyButton);
|
||||
|
||||
describe('PyButton', () => {
|
||||
let instance;
|
||||
beforeEach(() => {
|
||||
instance = new PyButton();
|
||||
// Remove all the alert banners created when calling `connectedCallback`
|
||||
const banners = document.getElementsByClassName("alert-banner")
|
||||
for (const banner of banners) {
|
||||
banner.remove()
|
||||
}
|
||||
});
|
||||
|
||||
it('should get the Button to just instantiate', async () => {
|
||||
expect(instance).toBeInstanceOf(PyButton);
|
||||
});
|
||||
|
||||
it('onCallback gets or sets a new id', async () => {
|
||||
expect(instance.id).toBe('');
|
||||
|
||||
instance.connectedCallback();
|
||||
const instanceId = instance.id;
|
||||
// id should be similar to py-4850c8c3-d70d-d9e0-03c1-3cfeb0bcec0d-container
|
||||
expect(instanceId).toMatch(/py-(\w+-){1,5}container/);
|
||||
|
||||
// ensureUniqueId doesn't change the ID
|
||||
ensureUniqueId(instance);
|
||||
expect(instance.id).toEqual(instanceId);
|
||||
});
|
||||
|
||||
it('onCallback updates on_click code and function name ', async () => {
|
||||
expect(instance.code).toBe(undefined);
|
||||
expect(instance.innerHTML).toBe('');
|
||||
|
||||
instance.innerHTML = '\ndef on_click(e):\n';
|
||||
|
||||
instance.connectedCallback();
|
||||
|
||||
expect(instance.code).toMatch(/def\son_click_py_(\w+)\(e\)/);
|
||||
expect(instance.innerHTML).toContain('<button class="py-button"');
|
||||
});
|
||||
|
||||
it('onCallback updates on_focus code and function name', async () => {
|
||||
expect(instance.code).toBe(undefined);
|
||||
expect(instance.innerHTML).toBe('');
|
||||
|
||||
instance.innerHTML = '\ndef on_focus(e):\n';
|
||||
|
||||
instance.connectedCallback();
|
||||
|
||||
expect(instance.code).toMatch(/def\son_focus_py_(\w+)\(e\)/);
|
||||
expect(instance.innerHTML).toContain('<button class="py-button"');
|
||||
});
|
||||
|
||||
it('onCallback sets mount_name based on id', async () => {
|
||||
expect(instance.id).toBe('');
|
||||
expect(instance.mount_name).toBe(undefined);
|
||||
|
||||
instance.connectedCallback();
|
||||
|
||||
const instanceId = instance.id;
|
||||
|
||||
expect(instanceId).toMatch(/py-(\w+-){1,5}container/);
|
||||
expect(instance.mount_name).toBe(instanceId.replace('-container', '').split('-').join('_'));
|
||||
});
|
||||
|
||||
it('should create a single deprecation banner', async () => {
|
||||
document.body.innerHTML = ""
|
||||
let alertBanners = document.getElementsByClassName('alert-banner');
|
||||
expect(alertBanners.length).toBe(0);
|
||||
|
||||
instance.connectedCallback();
|
||||
expect(alertBanners.length).toBe(1);
|
||||
expect(alertBanners[0].innerHTML).toContain("<py-button> is deprecated");
|
||||
|
||||
// Calling `connectedCallback` again should not create a new banner
|
||||
instance.connectedCallback();
|
||||
alertBanners = document.getElementsByClassName('alert-banner');
|
||||
expect(alertBanners.length).toBe(1);
|
||||
})
|
||||
});
|
||||
@@ -1,62 +0,0 @@
|
||||
import { jest } from "@jest/globals"
|
||||
import type { Runtime } from "../../src/runtime"
|
||||
import { FakeRuntime } from "./fakeruntime"
|
||||
import { make_PyInputBox } from "../../src/components/pyinputbox"
|
||||
import { ensureUniqueId } from '../../src/utils';
|
||||
|
||||
const runtime: Runtime = new FakeRuntime();
|
||||
const PyInputBox = make_PyInputBox(runtime);
|
||||
|
||||
customElements.define('py-inputbox', PyInputBox)
|
||||
|
||||
describe("PyInputBox", () => {
|
||||
|
||||
let instance;
|
||||
|
||||
beforeEach(() => {
|
||||
instance = new PyInputBox()
|
||||
instance.runAfterRuntimeInitialized = jest.fn();
|
||||
})
|
||||
|
||||
it("PyInputBox instantiates correctly", async () => {
|
||||
expect(instance).toBeInstanceOf(PyInputBox)
|
||||
})
|
||||
|
||||
it('connectedCallback gets or sets a new id', async () => {
|
||||
expect(instance.id).toBe('');
|
||||
|
||||
instance.connectedCallback();
|
||||
const instanceId = instance.id;
|
||||
// id should be similar to py-4850c8c3-d70d-d9e0-03c1-3cfeb0bcec0d-container
|
||||
expect(instanceId).toMatch(/py-(\w+-){1,5}container/);
|
||||
|
||||
// ensureUniqueId doesn't change the ID
|
||||
ensureUniqueId(instance);
|
||||
expect(instance.id).toEqual(instanceId);
|
||||
});
|
||||
|
||||
it('onCallback sets mount_name based on id', async () => {
|
||||
expect(instance.id).toBe('');
|
||||
expect(instance.mount_name).toBe(undefined);
|
||||
|
||||
instance.connectedCallback();
|
||||
|
||||
const instanceId = instance.id;
|
||||
|
||||
expect(instanceId).toMatch(/py-(\w+-){1,5}container/);
|
||||
expect(instance.mount_name).toBe(instanceId.replace('-container', '').split('-').join('_'));
|
||||
});
|
||||
|
||||
it('onCallback updates on_keypress code and function name ', async () => {
|
||||
expect(instance.code).toBe(undefined);
|
||||
expect(instance.innerHTML).toBe('');
|
||||
|
||||
instance.innerHTML = '\ndef on_keypress(e):\n';
|
||||
|
||||
instance.connectedCallback();
|
||||
|
||||
expect(instance.code).toMatch(/def\son_keypress_py_(\w+)\(e\)/);
|
||||
expect(instance.innerHTML).toContain('<input type="text" class="py-input"');
|
||||
});
|
||||
|
||||
})
|
||||
@@ -1,35 +0,0 @@
|
||||
import { PyTitle } from "../../src/components/pytitle"
|
||||
|
||||
|
||||
customElements.define("py-title", PyTitle);
|
||||
|
||||
|
||||
describe("PyTitle", () => {
|
||||
let instance: PyTitle;
|
||||
|
||||
beforeEach(() => {
|
||||
instance = new PyTitle();
|
||||
})
|
||||
|
||||
it("PyTitle instantiates correctly", async () => {
|
||||
expect(instance).toBeInstanceOf(PyTitle);
|
||||
})
|
||||
|
||||
it("test connectedCallback defaults", async () => {
|
||||
instance.connectedCallback();
|
||||
expect(instance.label).toBe("")
|
||||
expect(instance.mount_name).toBe("")
|
||||
expect(instance.innerHTML).toBe(`<div class=\"py-title\" id=\"\"><h1></h1></div>`)
|
||||
})
|
||||
|
||||
it("label renders correctly on the page and updates id", async () => {
|
||||
instance.innerHTML = "Hello, world!";
|
||||
instance.id = "my-fancy-title";
|
||||
|
||||
instance.connectedCallback();
|
||||
|
||||
expect(instance.label).toBe("Hello, world!")
|
||||
expect(instance.mount_name).toMatch("my_fancy_title");
|
||||
expect(instance.innerHTML).toContain("<h1>Hello, world!</h1>")
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user