def test_bigint_conversions(selenium_module_scope, n): with selenium_context_manager(selenium_module_scope) as selenium: h = hex(n) selenium.run_js(f"window.h = {h!r};") selenium.run_js(""" let negative = false; let h2 = h; if(h2.startsWith('-')){ h2 = h2.slice(1); negative = true; } window.n = BigInt(h2); if(negative){ window.n = -n; } pyodide.runPython(` from js import n, h n2 = int(h, 16) assert n == n2 `); let n2 = pyodide.globals.get("n2"); let n3 = Number(n2); if(Number.isSafeInteger(n3)){ assert(() => typeof n2 === "number"); assert(() => n2 === Number(n)); } else { assert(() => typeof n2 === "bigint"); assert(() => n2 === n); } """)
def test_hyp_py2js2py(selenium_module_scope, obj): with selenium_context_manager(selenium_module_scope) as selenium: import pickle from zoneinfo import ZoneInfo assume(not isinstance(obj, ZoneInfo)) # When we compare x == x, there are three possible outcomes: # 1. returns True # 2. returns False (e.g., nan) # 3. raises an exception # # Hypothesis *will* test this function on objects in case 2 and 3, so we # have to defend against them here. try: assume(obj == obj) except: assume(False) try: obj_bytes = list(pickle.dumps(obj)) except: assume(False) selenium.run(f""" import pickle x1 = pickle.loads(bytes({obj_bytes!r})) """) selenium.run_js(""" window.x2 = pyodide.globals.get("x1"); pyodide.runPython(` from js import x2 if x1 != x2: print(f"Assertion Error: {x1!r} != {x2!r}") assert False `); """)
def test_hyp_tojs_no_crash(selenium_module_scope, obj): with selenium_context_manager(selenium_module_scope) as selenium: import pickle from zoneinfo import ZoneInfo assume(not isinstance(obj, ZoneInfo)) try: obj_bytes = list(pickle.dumps(obj)) except: assume(False) selenium.run( f""" import pickle x = pickle.loads(bytes({obj_bytes!r})) """ ) selenium.run_js( """ let x = pyodide.globals.get("x"); if(x && x.toJs){ x.toJs(); } """ )
def test_string_conversion(selenium_module_scope, s): with selenium_context_manager(selenium_module_scope) as selenium: # careful string escaping here -- hypothesis will fuzz it. sbytes = list(s.encode()) selenium.run_js(f""" window.sjs = (new TextDecoder("utf8")).decode(new Uint8Array({sbytes})); pyodide.runPython('spy = bytes({sbytes}).decode()'); """) assert selenium.run_js(f"""return pyodide.runPython('spy') === sjs;""") assert selenium.run(""" from js import sjs sjs == spy """)
def test_fernet(selenium_module_scope, data): sbytes = list(data) with selenium_context_manager(selenium_module_scope) as selenium: selenium.load_package("cryptography") selenium.run( f""" from cryptography.fernet import Fernet data = bytes({sbytes}) f = Fernet(Fernet.generate_key()) ct = f.encrypt(data) assert f.decrypt(ct) == data """ )
def test_logistic_regression(selenium_module_scope): if selenium_module_scope.browser == "chrome": pytest.xfail("Times out in chrome") with selenium_context_manager(selenium_module_scope) as selenium: selenium.load_package("scikit-learn") selenium.run(""" from sklearn.datasets import load_iris from sklearn.linear_model import LogisticRegression X, y = load_iris(return_X_y=True) clf = LogisticRegression(random_state=0).fit(X, y) print(clf.predict(X[:2, :])) print(clf.predict_proba(X[:2, :])) print(clf.score(X, y)) """)
def test_number_conversions(selenium_module_scope, n): with selenium_context_manager(selenium_module_scope) as selenium: import json s = json.dumps(n) selenium.run_js(f""" window.x_js = eval({s!r}); // JSON.parse apparently doesn't work pyodide.runPython(` import json x_py = json.loads({s!r}) `); """) assert selenium.run_js( f"""return pyodide.runPython('x_py') === x_js;""") assert selenium.run(""" from js import x_js x_js == x_py """)
def test_ansix923(selenium_module_scope, block_size, data): sbytes = list(data) with selenium_context_manager(selenium_module_scope) as selenium: selenium.load_package("cryptography") selenium.run( f""" from cryptography.hazmat.primitives.padding import ANSIX923, PKCS7 block_size = {block_size} data = bytes({sbytes}) a = ANSIX923(block_size=block_size * 8) padder = a.padder() unpadder = a.unpadder() padded = padder.update(data) + padder.finalize() assert unpadder.update(padded) + unpadder.finalize() == data """ )
def test_scikit_learn(selenium_module_scope): if selenium_module_scope.browser == "chrome": pytest.xfail("Times out in chrome") with selenium_context_manager(selenium_module_scope) as selenium: selenium.load_package("scikit-learn") assert (selenium.run(""" import numpy as np import sklearn from sklearn.linear_model import LogisticRegression rng = np.random.RandomState(42) X = rng.rand(100, 20) y = rng.randint(5, size=100) estimator = LogisticRegression(solver='liblinear') estimator.fit(X, y) print(estimator.predict(X)) estimator.score(X, y) """) > 0)
def test_pkcs7(selenium_module_scope, block_size, data): sbytes = list(data) with selenium_context_manager(selenium_module_scope) as selenium: selenium.load_package("cryptography") selenium.run( f""" from cryptography.hazmat.primitives.padding import ANSIX923, PKCS7 block_size = {block_size} data = bytes({sbytes}) # Generate in [1, 31] so we can easily get block_size in bits by # multiplying by 8. p = PKCS7(block_size=block_size * 8) padder = p.padder() unpadder = p.unpadder() padded = padder.update(data) + padder.finalize() assert unpadder.update(padded) + unpadder.finalize() == data """ )