Add test coverage for bool(JsProxy) and fix some cases (#2803)

Resolves #2802 and several other oddities in the behavior of bool.
This commit is contained in:
Hood Chatham 2022-06-29 20:30:24 -07:00 committed by GitHub
parent 9b7693a95a
commit a7d7cd51b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 4 deletions

View File

@ -102,6 +102,11 @@ substitutions:
`ERRNO_CODES` APIs.
{pr}`2582`
- {{ Fix }} The `bool` operator on a `JsProxy` now behaves more consistently: it
returns `False` if JavaScript would say that `!!x` is `false`, or if `x` is an
empty container. Otherwise it returns `True`.
{pr}`2803`
### REPL
- {{ Enhancement }} Add a spinner while the REPL is loading

View File

@ -724,11 +724,20 @@ EM_JS_BOOL(bool, hiwire_get_bool, (JsRef idobj), {
if (!val) {
return false;
}
// We want to return false on container types with size 0.
if (val.size === 0) {
// I think things with a size are all container types.
if(/HTML[A-Za-z]*Element/.test(Object.prototype.toString.call(val))){
// HTMLSelectElement and HTMLInputElement can have size 0 but we still
// want to return true.
return true;
}
// I think other things with a size are container types.
return false;
}
if (Array.isArray(val) && val.length === 0) {
if (val.length === 0 && JsArray_Check(idobj)) {
return false;
}
if (val.byteLength === 0) {
return false;
}
return true;

View File

@ -87,15 +87,66 @@ def test_jsproxy_document(selenium):
from js import document
el = document.createElement("div")
assert el.tagName == "DIV"
assert bool(el)
assert not document.body.children
document.body.appendChild(el)
assert document.body.children
assert document.body.children.length == 1
assert document.body.children[0].tagName == "DIV"
assert document.body.children[0] == el
assert repr(document) == "[object HTMLDocument]"
el = document.createElement("div")
assert len(dir(el)) >= 200
assert "appendChild" in dir(el)
@pytest.mark.parametrize(
"js,result",
[
("{}", False),
("{a:1}", True),
("[]", False),
("[1]", True),
("new Map()", False),
("new Map([[0, 0]])", True),
("new Set()", False),
("new Set([0])", True),
("class T {}; T", True),
("class T {}; new T()", True),
("new Uint8Array(0)", False),
("new Uint8Array(1)", True),
("new ArrayBuffer(0)", False),
("new ArrayBuffer(1)", True),
],
)
@run_in_pyodide
def test_jsproxy_bool(selenium, js, result):
from pyodide.code import run_js
assert bool(run_js(js)) == result
@pytest.mark.xfail_browsers(node="No document in node")
@pytest.mark.parametrize(
"js,result",
[
("document.createElement('div')", True),
("document.createElement('select')", True),
("document.createElement('p')", True),
("document.createElement('style')", True),
("document.createElement('ul')", True),
("document.createElement('ul').style", True),
("document.querySelectorAll('x')", False),
("document.querySelectorAll('body')", True),
("document.all", False),
],
)
@run_in_pyodide
def test_jsproxy_bool_html(selenium, js, result):
from pyodide.code import run_js
assert bool(run_js(js)) == result
@pytest.mark.xfail_browsers(node="No ImageData in node")
@run_in_pyodide
def test_jsproxy_imagedata(selenium):