8000 Update test suite by ntoll · Pull Request #2181 · pyscript/pyscript · GitHub
[go: up one dir, main page]

Skip to content

Update test suite #2181

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

Merged
merged 31 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6650809
WiP pyscript.web tests pass with upytest.
ntoll Sep 10, 2024
ec20298
Test refactoring. WiP
ntoll Sep 13, 2024
762ae19
Completed refactor of old integration tests to new Python tests.
ntoll Sep 17, 2024
b35fb8f
Added comprehensive test suite for Python based pyodide module.
ntoll Sep 19, 2024
806e574
Black.
ntoll Sep 19, 2024
177cbb9
Rebuld and check websocket attribute assignment via init and as attri…
ntoll Sep 23, 2024
091da6e
Update when tests to allow for worker round trips.
ntoll Sep 23, 2024
4a6c5fa
Post build
ntoll Sep 23, 2024
790fd26
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 23, 2024
ae66d13
Fixed config issue via polyscript update (#2182)
WebReflection Sep 24, 2024
e3c572d
WiP pyscript.web tests pass with upytest.
ntoll Sep 10, 2024
aa83e6c
Test refactoring. WiP
ntoll Sep 13, 2024
263f1fc
Completed refactor of old integration tests to new Python tests.
ntoll Sep 17, 2024
0eb8c43
Added comprehensive test suite for Python based pyodide module.
ntoll Sep 19, 2024
6c81b5f
Black.
ntoll Sep 19, 2024
43f25fd
Rebuld and check websocket attribute assignment via init and as attri…
ntoll Sep 23, 2024
344e54a
Update when tests to allow for worker round trips.
ntoll Sep 23, 2024
f24a2cf
Post build
ntoll Sep 23, 2024
6e52918
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 23, 2024
06216ac
Merge branch 'update-test-suite' of github.com:pyscript/pyscript into…
ntoll Sep 24, 2024
abc3a3b
Fix a couple of timing issues in display and web tests.
ntoll Sep 24, 2024
0d7ef9d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 24, 2024
57e023e
Black
ntoll Sep 24, 2024
58d905d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 24, 2024
7da2ba6
Add integration tests to Makefile (and CI)
ntoll Sep 24, 2024
f826d0b
Remove un-needed upload action.
ntoll Sep 24, 2024
af6cc2b
Ensure fails are properly logged as an array. Remove the explicit tes…
ntoll Sep 24, 2024
aa70295
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 24, 2024
19bc612
Directory reorg/refactor. Updated docs.
ntoll Sep 25, 2024
60622c9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 25, 2024
c52a695
Bump polyscript.
ntoll Sep 25, 2024
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
Prev Previous commit
Next Next commit
Test refactoring. WiP
  • Loading branch information
ntoll committed Sep 24, 2024
commit aa83e6c3aecc826d2ecd3321ceebdfa73fd2508b
7 changes: 5 additions & 2 deletions pyscript.core/tests/integration/python/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import upytest
from pyscript import window
from pyscript.ffi import to_js

import upytest

await upytest.run("./tests")
result = await upytest.run("./tests")
window.console.log(to_js(result))
7 changes: 4 additions & 3 deletions pyscript.core/tests/integration/python/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"files": {
"https://raw.githubusercontent.com/ntoll/upytest/1.0.1/upytest.py": "",
"https://raw.githubusercontent.com/ntoll/umock/1.0.0/umock.py": "",
"./tests/test_web.py": "tests/test_web.py"
"https://raw.githubusercontent.com/ntoll/upytest/1.0.4/upytest.py": "",
"./tests/test_web.py": "tests/test_web.py",
"./tests/test_display.py": "tests/test_display.py",
"./tests/test_when.py": "tests/test_when.py"
}
}
288 changes: 288 additions & 0 deletions pyscript.core/tests/integration/python/tests/test_display.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
"""
Tests for the display function in PyScript.
"""
import re
import upytest


from pyscript import display, web, HTML, RUNNING_IN_WORKER, py_import


def get_display_container():
"& 10000 quot;"
Get the element that contains the output of the display function.
"""
py_display = web.page.find("script-py")
if len(py_display) == 1:
return py_display[0]
mpy_display = web.page.find("script-mpy")
if len(mpy_display) == 1:
return mpy_display[0]
return None


def setup():
"""
Setup function for the test_display.py module. Remove all references to the
display output in the DOM so we always start from a clean state.
"""
container = get_display_container()
container.replaceChildren()
target_container = web.page.find("#test-element-container")[0]
target_container.innerHTML = ""

def teardown():
"""
Like setup.
"""
container = get_display_container()
container.replaceChildren()
target_container = web.page.find("#test-element-container")[0]
target_container.innerHTML = ""

def test_simple_display():
"""
Test the display function with a simple string.
"""
display("Hello, world")
container = get_display_container()
assert len(container.children) == 1, "Expected one child in the display container."
assert container.children[0].tagName == "DIV", "Expected a div element in the display container."
assert container.children[0].innerHTML == "Hello, world"

def test_consecutive_display():
"""
Display order should be preserved.
"""
display("hello 1")
display("hello 2")
container = get_display_container()
assert len(container.children) == 2, "Expected two children in the display container."
assert container.children[0].innerHTML == "hello 1"
assert container.children[1].innerHTML == "hello 2"

def test_target_parameter():
"""
The output from display is placed in the target element.
"""
display("hello world", target="test-element-container")
target = web.page.find("#test-element-container")[0]
assert target.innerText == "hello world"

def test_target_parameter_with_hash():
"""
The target parameter can have a hash in front of it.
"""
display("hello world", target="#test-element-container")
target = web.page.find("#test-element-container")[0]
assert target.innerText == "hello world"

def test_non_existing_id_target_raises_value_error():
"""
If the target parameter is set to a non-existing element, a ValueError should be raised.
"""
with upytest.raises(ValueError):
display("hello world", target="non-existing")

def test_empty_string_target_raises_value_error():
"""
If the target parameter is an empty string, a ValueError should be raised.
"""
with upytest.raises(ValueError) as exc:
display("hello world", target="")
assert str(exc.exception) == "Cannot have an empty target"

def test_non_string_target_values_raise_typerror():
"""
The target parameter must be a string.
"""
with upytest.raises(TypeError) as exc:
display("hello world", target=True)
assert str(exc.exception) == "target must be str or None, not bool"

with upytest.raises(TypeError) as exc:
display("hello world", target=123)
assert str(exc.exception) == "target must be str or None, not int"

def test_tag_target_attribute():
"""
The order and arrangement of the display calls (including targets) should be preserved.
"""
display("item 1")
display("item 2", target="test-element-container")
display("item 3")
container = get_display_container()
assert len(container.children) == 2, "Expected two children in the display container."
assert container.children[0].innerHTML == "item 1"
assert container.children[1].innerHTML == "item 3"
target = web.page.find("#test-element-container")[0]
assert target.innerText == "item 2"

@upytest.skip("CHECK: test consecutive script tags with display in JS")
def test_consecutive_display_target():
self.pyscript_run(
"""
<script type="py" id="first" async="false">
from pyscript import display
display('hello 1')
</script>
<p>hello in between 1 and 2</p>
<script type="py" id="second" async="false">
from pyscript import display
display('hello 2', target="second")
</script>
<script type="py" id="third" async="false">
from pyscript import display
display('hello 3')
</script>
"""
)
inner_text = self.page.inner_text("body")
lines = inner_text.splitlines()
lines = [line for line in filter_page_content(lines)] # remove empty lines
assert lines == ["hello 1", "hello in between 1 and 2", "hello 2", "hello 3"]

def test_multiple_display_calls_same_tag():
"""
Multiple display calls in the same script tag should be displayed in order.
"""
display("item 1")
display("item 2")
container = get_display_container()
assert len(container.children) == 2, "Expected two children in the display container."
assert container.children[0].innerHTML == "item 1"
assert container.children[1].innerHTML == "item 2"

@upytest.skip("CHECK: test implicit target from a different tag, both main and in worker in JS?")
def test_implicit_target_from_a_different_tag():
self.pyscript_run(
"""
<script type="py">
from pyscript import display
def say_hello():
display('hello')
</script>

<script type="py">
from pyscript import display
say_hello()
</script>
"""
)
elems = self.page.locator("script-py")
py0 = elems.nth(0)
py1 = elems.nth(1)
assert py0.inner_text() == ""
assert py1.inner_text() == "hello"

def test_append_true():
"""
Explicit append flag as true should append to the expected container element.
"""
display("item 1", append=True)
display("item 2", append=True)
container = get_display_container()
assert len(container.children) == 2, "Expected two children in the display container."
assert container.children[0].innerHTML == "item 1"
assert container.children[1].innerHTML == "item 2"

def test_append_false():
"""
Explicit append flag as false should replace the expected container element.
"""
display("item 1", append=False)
display("item 2", append=False)
container = get_display_container()
assert container.innerText == "item 2"

def test_display_multiple_values():
"""
Display multiple values in the same call.
"""
display("hello", "world")
container = get_display_container()
assert container.innerText == "hello\nworld"

def test_display_multiple_append_false():
display("hello", "world", append=False)
container = get_display_container()
assert container.innerText == "world"

# TODO: this is a display.py issue to fix when append=False is used
# do not use the first element, just clean up and then append
# remove the # display comment once that's done
def test_display_multiple_append_false_with_target():
"""

"""
class Circle:
r = 0
def _repr_svg_(self):
return (
f'<svg height="{self.r*2}" width="{self.r*2}">'
f'<circle cx="{self.r}" cy="{self.r}" r="{self.r}" fill="red"></circle></svg>'
)

circle = Circle()
circle.r += 5
display(circle, circle, target="test-element-container", append=False)
target = web.page.find("#test-element-container")[0]
assert target.innerHTML == circle._repr_svg_()

def test_display_list_dict_tuple():
"""
Display a list, dictionary, and tuple with the expected __repr__.

NOTE: MicroPython doesn't (yet) have ordered dicts. Hence the rather odd
check that the dictionary is displayed as a string.
"""
l = ['A', 1, '!']
d = {'B': 2, 'List': l}
t = ('C', 3, '!')
display(l, d, t)
container = get_display_container()
l2, d2, t2 = container.innerText.split('\n')
assert l == eval(l2)
assert d == eval(d2)
assert t == eval(t2)

def test_display_should_escape():
display("<p>hello world</p>")
container = get_display_container()
assert container[0].innerHTML == "&lt;p&gt;hello world&lt;/p&gt;"
assert container.innerText == "<p>hello world</p>"

def test_display_HTML():
display(HTML("<p>hello world</p>"))
container = get_display_container()
assert container[0].innerHTML == "<p>hello world</p>"
assert container.innerText == "hello world"

@upytest.skip("Pyodide main thread only", skip_when=upytest.is_micropython or RUNNING_IN_WORKER)
async def test_image_display():
"""
Check an image is displayed correctly.
"""
mpl = await py_import("matplotlib")
import matplotlib.pyplot as plt
xpoints = [3, 6, 9]
ypoints = [1, 2, 3]
plt.plot(xpoints, ypoints)
display(plt)
container = get_display_container()
img = container.find("img")[0]
img_src = img.getAttribute("src").replace("data:image/png;charset=utf-8;base64,", "")
assert len(img_src) > 0

@upytest.skip("Pyodide main thread only", skip_when=upytest.is_micropython or RUNNING_IN_WORKER)
async def test_image_renders_correctly():
"""
This is just a sanity check to make sure that images are rendered
in a reasonable way.
"""
from PIL import Image
img = Image.new("RGB", (4, 4), color=(0, 0, 0))
display(img, target="test-element-container", append=False)
target = web.page.find("#test-element-container")[0]
img = target.find("img")[0]
assert img.src.startswith("data:image/png;charset=utf-8;base64")
Loading
0