Use multi-line code snippets in tests

This commit is contained in:
Roman Yurchak 2018-09-07 14:01:58 +02:00
parent 8c27b0b44b
commit d869ac5bfc
3 changed files with 184 additions and 134 deletions

View File

@ -4,6 +4,7 @@ Various common utilities for testing.
import atexit
import multiprocessing
import textwrap
import os
import pathlib
import queue
@ -73,10 +74,16 @@ class SeleniumWrapper:
self.driver.execute_script("window.logs = []")
def run(self, code):
if isinstance(code, str) and code.startswith('\n'):
# we have a multiline string, fix indentation
code = textwrap.dedent(code)
return self.run_js(
'return pyodide.runPython({!r})'.format(code))
def run_js(self, code):
if isinstance(code, str) and code.startswith('\n'):
# we have a multiline string, fix indentation
code = textwrap.dedent(code)
catch = f"""
Error.stackTraceLimit = Infinity;
try {{ {code} }}

View File

@ -43,16 +43,21 @@ def test_python2js(selenium):
'(x.length === 5) && '
'(x[0] === 98)')
assert selenium.run_js(
'let x = pyodide.runPython("[1, 2, 3]");\n'
'return (x instanceof window.Array) && (x.length === 3) && '
'(x[0] == 1) && (x[1] == 2) && (x[2] == 3)')
"""
let x = pyodide.runPython("[1, 2, 3]");
return ((x instanceof window.Array) && (x.length === 3) &&
(x[0] == 1) && (x[1] == 2) && (x[2] == 3))
""")
assert selenium.run_js(
'let x = pyodide.runPython("{42: 64}");\n'
'return (typeof x === "object") && '
'(x[42] === 64)')
"""
let x = pyodide.runPython("{42: 64}");
return (typeof x === "object") && (x[42] === 64)
""")
assert selenium.run_js(
'let x = pyodide.runPython("open(\'/foo.txt\', \'wb\')")\n'
'return (x.tell() === 0)\n')
"""
let x = pyodide.runPython("open('/foo.txt', 'wb')")
return (x.tell() === 0)
""")
def test_pythonexc2js(selenium):
@ -66,17 +71,19 @@ def test_pythonexc2js(selenium):
def test_js2python(selenium):
selenium.run_js(
'window.jsstring = "碘化物";\n'
'window.jsnumber0 = 42;\n'
'window.jsnumber1 = 42.5;\n'
'window.jsundefined = undefined;\n'
'window.jsnull = null;\n'
'window.jstrue = true;\n'
'window.jsfalse = false;\n'
'window.jspython = pyodide.pyimport("open");\n'
'window.jsbytes = new Uint8Array([1, 2, 3]);\n'
'window.jsfloats = new Float32Array([1, 2, 3]);\n'
'window.jsobject = new XMLHttpRequest();\n'
"""
window.jsstring = "碘化物";
window.jsnumber0 = 42;
window.jsnumber1 = 42.5;
window.jsundefined = undefined;
window.jsnull = null;
window.jstrue = true;
window.jsfalse = false;
window.jspython = pyodide.pyimport("open");
window.jsbytes = new Uint8Array([1, 2, 3]);
window.jsfloats = new Float32Array([1, 2, 3]);
window.jsobject = new XMLHttpRequest();
"""
)
assert selenium.run(
'from js import jsstring\n'
@ -100,70 +107,84 @@ def test_js2python(selenium):
'from js import jspython\n'
'jspython is open')
assert selenium.run(
'from js import jsbytes\n'
'(jsbytes.tolist() == [1, 2, 3]) '
'and (jsbytes.tobytes() == b"\x01\x02\x03")')
"""
from js import jsbytes
((jsbytes.tolist() == [1, 2, 3])
and (jsbytes.tobytes() == b"\x01\x02\x03"))
""")
assert selenium.run(
'from js import jsfloats\n'
'import struct\n'
'expected = struct.pack("fff", 1, 2, 3)\n'
'(jsfloats.tolist() == [1, 2, 3]) '
'and (jsfloats.tobytes() == expected)')
"""
from js import jsfloats
import struct
expected = struct.pack("fff", 1, 2, 3)
(jsfloats.tolist() == [1, 2, 3]) and (jsfloats.tobytes() == expected)
""")
assert selenium.run(
'from js import jsobject\n'
'str(jsobject) == "[object XMLHttpRequest]"')
def test_typed_arrays(selenium):
for wasm_heap in (False, True):
for (jstype, pytype) in (
('Int8Array', 'b'),
('Uint8Array', 'B'),
('Uint8ClampedArray', 'B'),
('Int16Array', 'h'),
('Uint16Array', 'H'),
('Int32Array', 'i'),
('Uint32Array', 'I'),
('Float32Array', 'f'),
('Float64Array', 'd')):
print(wasm_heap, jstype, pytype)
if not wasm_heap:
selenium.run_js(
f'window.array = new {jstype}([1, 2, 3, 4]);\n')
else:
selenium.run_js(
'var buffer = pyodide._malloc('
f'4 * {jstype}.BYTES_PER_ELEMENT);\n'
f'window.array = new {jstype}('
'pyodide.HEAPU8.buffer, buffer, 4);\n'
'window.array[0] = 1;\n'
'window.array[1] = 2;\n'
'window.array[2] = 3;\n'
'window.array[3] = 4;\n')
assert selenium.run(
'from js import array\n'
'import struct\n'
f'expected = struct.pack("{pytype*4}", 1, 2, 3, 4)\n'
'print(array.format, array.tolist(), array.tobytes())\n'
f'array.format == "{pytype}" '
'and array.tolist() == [1, 2, 3, 4] '
'and array.tobytes() == expected '
f'and array.obj._has_bytes() is {not wasm_heap}')
@pytest.mark.parametrize('wasm_heap', (False, True))
@pytest.mark.parametrize(
'jstype, pytype',
(
('Int8Array', 'b'),
('Uint8Array', 'B'),
('Uint8ClampedArray', 'B'),
('Int16Array', 'h'),
('Uint16Array', 'H'),
('Int32Array', 'i'),
('Uint32Array', 'I'),
('Float32Array', 'f'),
('Float64Array', 'd')))
def test_typed_arrays(selenium, wasm_heap, jstype, pytype):
if not wasm_heap:
selenium.run_js(
f'window.array = new {jstype}([1, 2, 3, 4]);\n')
else:
selenium.run_js(
f"""
var buffer = pyodide._malloc(
4 * {jstype}.BYTES_PER_ELEMENT);
window.array = new {jstype}(
pyodide.HEAPU8.buffer, buffer, 4);
window.array[0] = 1;
window.array[1] = 2;
window.array[2] = 3;
window.array[3] = 4;
""")
assert selenium.run(
f"""
from js import array
import struct
expected = struct.pack("{pytype*4}", 1, 2, 3, 4)
print(array.format, array.tolist(), array.tobytes())
((array.format == "{pytype}")
and array.tolist() == [1, 2, 3, 4]
and array.tobytes() == expected
and array.obj._has_bytes() is {not wasm_heap})
""")
def test_import_js(selenium):
result = selenium.run(
"from js import window\nwindow.title = 'Foo'\nwindow.title")
"""
from js import window
window.title = 'Foo'
window.title
""")
assert result == 'Foo'
def test_pyproxy(selenium):
selenium.run(
"class Foo:\n"
" bar = 42\n"
" def get_value(self, value):\n"
" return value * 64\n"
"f = Foo()\n"
"""
class Foo:
bar = 42
def get_value(self, value):
return value * 64
f = Foo()
"""
)
assert selenium.run_js("return pyodide.pyimport('f').get_value(2)") == 128
assert selenium.run_js("return pyodide.pyimport('f').bar") == 42
@ -188,18 +209,22 @@ def test_pyproxy(selenium):
def test_pyproxy_destroy(selenium):
selenium.run(
"class Foo:\n"
" bar = 42\n"
" def get_value(self, value):\n"
" return value * 64\n"
"f = Foo()\n"
"""
class Foo:
bar = 42
def get_value(self, value):
return value * 64
f = Foo()
"""
)
try:
selenium.run_js(
"let f = pyodide.pyimport('f');\n"
"console.assert(f.get_value(1) === 64);\n"
"f.destroy();\n"
"f.get_value();\n")
"""
let f = pyodide.pyimport('f');
console.assert(f.get_value(1) === 64);
f.destroy();
f.get_value();
""")
except selenium.JavascriptException as e:
assert 'Object has already been destroyed' in str(e)
else:
@ -208,10 +233,11 @@ def test_pyproxy_destroy(selenium):
def test_jsproxy(selenium):
assert selenium.run(
"from js import document\n"
"el = document.createElement('div')\n"
"document.body.appendChild(el)\n"
"document.body.children.length\n"
"""
from js import document
el = document.createElement('div')
document.body.appendChild(el)
document.body.children.length"""
) == 1
assert selenium.run(
"document.body.children[0].tagName") == 'DIV'
@ -229,50 +255,59 @@ def test_jsproxy(selenium):
"from js import ImageData\n"
"ImageData.typeof") == 'function'
selenium.run_js(
"class Point {\n"
" constructor(x, y) {\n"
" this.x = x;\n"
" this.y = y;\n"
" }\n"
"}\n"
"window.TEST = new Point(42, 43);")
"""
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
window.TEST = new Point(42, 43);""")
assert selenium.run(
"from js import TEST\n"
"del TEST.y\n"
"TEST.y\n") is None
"""
from js import TEST
del TEST.y
TEST.y""") is None
selenium.run_js(
"class Point {\n"
" constructor(x, y) {\n"
" this.x = x;\n"
" this.y = y;\n"
" }\n"
"}\n"
"window.TEST = new Point(42, 43);")
"""
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
window.TEST = new Point(42, 43);""")
assert selenium.run(
"from js import TEST\n"
"del TEST['y']\n"
"TEST['y']\n") is None
"""
from js import TEST
del TEST['y']
TEST['y']""") is None
assert selenium.run(
"from js import TEST\n"
"TEST == TEST\n")
"""
from js import TEST
TEST == TEST
""")
assert selenium.run(
"from js import TEST\n"
"TEST != 'foo'\n")
"""
from js import TEST
TEST != 'foo'
""")
def test_jsproxy_iter(selenium):
selenium.run_js(
"function makeIterator(array) {\n"
" var nextIndex = 0;\n"
" return {\n"
" next: function() {\n"
" return nextIndex < array.length ?\n"
" {value: array[nextIndex++], done: false} :\n"
" {done: true};\n"
" }\n"
" };\n"
"}\n"
"window.ITER = makeIterator([1, 2, 3]);")
"""
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
};
}
window.ITER = makeIterator([1, 2, 3]);""")
assert selenium.run(
"from js import ITER\n"
"list(ITER)") == [1, 2, 3]
@ -280,8 +315,10 @@ def test_jsproxy_iter(selenium):
def test_open_url(selenium):
assert selenium.run(
"import pyodide\n"
"pyodide.open_url('test_data.txt').read()\n") == 'HELLO\n'
"""
import pyodide
pyodide.open_url('test_data.txt').read()
""") == 'HELLO\n'
def test_run_core_python_test(python_test, selenium, request):
@ -296,13 +333,14 @@ def test_run_core_python_test(python_test, selenium, request):
selenium.load_package('test')
try:
selenium.run(
"from test.libregrtest import main\n"
"try:\n"
" main(['{}'], verbose=True, verbose3=True)\n"
"except SystemExit as e:\n"
" if e.code != 0:\n"
" raise RuntimeError(f'Failed with code: {{e.code}}')\n"
.format(name))
"""
from test.libregrtest import main
try:
main(['{}'], verbose=True, verbose3=True)
except SystemExit as e:
if e.code != 0:
raise RuntimeError(f'Failed with code: {{e.code}}')
""".format(name))
except selenium.JavascriptException as e:
print(selenium.logs)
raise

View File

@ -1,12 +1,17 @@
def test_pytest(selenium):
selenium.load_package('pytest')
selenium.load_package('numpy')
selenium.load_package('nose')
selenium.run('from pathlib import Path')
selenium.run('import os')
selenium.run('import numpy')
selenium.run('base_dir = Path(numpy.__file__).parent / "core" / "tests"')
selenium.run("import pytest;"
"pytest.main([base_dir / 'test_api.py'])")
selenium.load_package(['pytest', 'numpy', 'nose'])
selenium.run(
"""
from pathlib import Path
import os
import numpy
import pytest
base_dir = Path(numpy.__file__).parent / "core" / "tests"
""")
selenium.run("pytest.main([base_dir / 'test_api.py'])")
logs = '\n'.join(selenium.logs)
assert 'INTERNALERROR' not in logs