Files
pyscript/pyscriptjs/tests/integration/test_01_basic.py
Antonio Cuni c75f885cb4 Refactor py-config and the general initialization logic of the page (#806)
This PR is the first step to improve and rationalize the life-cycle of a pyscript app along the lines of what I described in #763 .
It is not a complete solution, more PRs will follow.
Highlights:

- py-config is no longer a web component: the old code relied on PyConfig.connectedCallback to do some logic, but then if no <py-config> tag was present, we had to introduce a dummy one with the sole goal of activating the callback. Now the logic is much more linear.

- the new pyconfig.ts only contains the code which is needed to parse the config; I also moved some relevant code from utils.ts because it didn't really belong to it

- the old PyConfig class did much more than dealing with the config: in particular, it contained the code to initialize the env and the runtime. Now this logic has been moved directly into main.ts, inside the new PyScriptApp class. I plan to refactor the initialization code in further PRs

- the current code relies too much on global state and global variables, they are everywhere. This PR is a first step to solve the problem by introducing a PyScriptApp class, which will hold all the mutable state of the page. Currently only config is stored there, but eventually I will migrate more state to it, until we will have only one global singleton, globalApp

- thanks to what I described above, I could kill the appConfig svelte store: one less store to kill :).
2022-10-04 14:26:12 +02:00

101 lines
3.0 KiB
Python

import re
from .support import PyScriptTest
class TestBasic(PyScriptTest):
def test_pyscript_hello(self):
self.pyscript_run(
"""
<py-script>
print('hello pyscript')
</py-script>
"""
)
# this is a very ugly way of checking the content of the DOM. If we
# find ourselves to write a lot of code in this style, we will
# probably want to write a nicer API for it.
inner_html = self.page.locator("py-script").inner_html()
pattern = r'<div id="py-.*">hello pyscript</div>'
assert re.search(pattern, inner_html)
def test_execution_in_order(self):
"""
Check that they py-script tags are executed in the same order they are
defined
"""
self.pyscript_run(
"""
<py-script>import js; js.console.log('one')</py-script>
<py-script>js.console.log('two')</py-script>
<py-script>js.console.log('three')</py-script>
<py-script>js.console.log('four')</py-script>
"""
)
assert self.console.log.lines == [
self.PY_COMPLETE,
"one",
"two",
"three",
"four",
]
def test_escaping_of_angle_brackets(self):
"""
Check that py-script tags escape angle brackets
"""
self.pyscript_run(
"""
<py-script>import js; js.console.log(1<2, 1>2)</py-script>
<py-script>js.console.log("<div></div>")</py-script>
"""
)
assert self.console.log.lines == [self.PY_COMPLETE, "true false", "<div></div>"]
def test_paths(self):
self.writefile("a.py", "x = 'hello from A'")
self.writefile("b.py", "x = 'hello from B'")
self.pyscript_run(
"""
<py-config>
paths = ["./a.py", "./b.py"]
</py-config>
<py-script>
import js
import a, b
js.console.log(a.x)
js.console.log(b.x)
</py-script>
"""
)
assert self.console.log.lines == [
self.PY_COMPLETE,
"hello from A",
"hello from B",
]
def test_packages(self):
self.pyscript_run(
"""
<py-config>
# we use asciitree because it's one of the smallest packages
# which are built and distributed with pyodide
packages = ["asciitree"]
</py-config>
<py-script>
import js
import asciitree
js.console.log('hello', asciitree.__name__)
</py-script>
<py-repl></py-repl>
"""
)
assert self.console.log.lines == [
self.PY_COMPLETE,
"Loading asciitree", # printed by pyodide
"Loaded asciitree", # printed by pyodide
"hello asciitree", # printed by us
]