mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
add tests for runtime config inside py-config and remove usage of indexURL (#734)
* add integration test for py-config * fix bug * fix test * remove indexURL altogether * make jest happy * fix create_proxy import * check that py-config loads an older version * add unit test * suggested changes * don't use /tmp because of bandit
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { Runtime, RuntimeConfig } from './runtime';
|
||||
import { getLastPath, inJest } from './utils';
|
||||
import { getLastPath } from './utils';
|
||||
import type { PyodideInterface } from 'pyodide';
|
||||
import { loadPyodide } from 'pyodide';
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
import pyscript from './python/pyscript.py';
|
||||
@@ -30,17 +29,30 @@ export class PyodideRuntime extends Runtime {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Although `loadPyodide` is used below,
|
||||
* notice that it is not imported i.e.
|
||||
* import { loadPyodide } from 'pyodide';
|
||||
* is not used at the top of this file.
|
||||
*
|
||||
* This is because, if it's used, loadPyodide
|
||||
* behaves mischievously i.e. it tries to load
|
||||
* `pyodide.asm.js` and `pyodide_py.tar` but
|
||||
* with paths that are wrong such as:
|
||||
*
|
||||
* http://127.0.0.1:8080/build/pyodide_py.tar
|
||||
* which results in a 404 since `build` doesn't
|
||||
* contain these files and is clearly the wrong
|
||||
* path.
|
||||
*/
|
||||
async loadInterpreter(): Promise<void> {
|
||||
console.log('creating pyodide runtime');
|
||||
let indexURL: string = this.src.substring(0, this.src.length - '/pyodide.js'.length);
|
||||
if (typeof process === 'object' && inJest()) {
|
||||
indexURL = [process.cwd(), 'node_modules', 'pyodide'].join('/');
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
this.interpreter = await loadPyodide({
|
||||
stdout: console.log,
|
||||
stderr: console.log,
|
||||
fullStdLib: false,
|
||||
indexURL,
|
||||
});
|
||||
|
||||
this.globals = this.interpreter.globals;
|
||||
|
||||
@@ -84,11 +84,4 @@ function handleFetchError(e: Error, singleFile: string) {
|
||||
showError(errorContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* determines if the process is running inside the testing suite i.e. jest
|
||||
*/
|
||||
function inJest(): boolean {
|
||||
return process.env.JEST_WORKER_ID !== undefined;
|
||||
}
|
||||
|
||||
export { addClasses, removeClasses, getLastPath, ltrim, htmlDecode, guidGenerator, showError, handleFetchError, inJest };
|
||||
export { addClasses, removeClasses, getLastPath, ltrim, htmlDecode, guidGenerator, showError, handleFetchError };
|
||||
|
||||
@@ -178,7 +178,7 @@ class PyScriptTest:
|
||||
check_errors=check_errors,
|
||||
)
|
||||
|
||||
def pyscript_run(self, snippet):
|
||||
def pyscript_run(self, snippet, *, extra_head=""):
|
||||
"""
|
||||
Main entry point for pyscript tests.
|
||||
|
||||
@@ -197,6 +197,7 @@ class PyScriptTest:
|
||||
<head>
|
||||
<link rel="stylesheet" href="{self.http_server}/build/pyscript.css" />
|
||||
<script defer src="{self.http_server}/build/pyscript.js"></script>
|
||||
{extra_head}
|
||||
</head>
|
||||
<body>
|
||||
{snippet}
|
||||
|
||||
68
pyscriptjs/tests/integration/test_py_runtime_config.py
Normal file
68
pyscriptjs/tests/integration/test_py_runtime_config.py
Normal file
@@ -0,0 +1,68 @@
|
||||
import os
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
from .support import PyScriptTest
|
||||
|
||||
URL = "https://github.com/pyodide/pyodide/releases/download/0.20.0/pyodide-build-0.20.0.tar.bz2"
|
||||
TAR_NAME = "pyodide-build-0.20.0.tar.bz2"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tar_location(request):
|
||||
val = request.config.cache.get("pyodide-0.20-tar", None)
|
||||
if val is None:
|
||||
response = requests.get(URL, stream=True)
|
||||
TMP_DIR = tempfile.mkdtemp()
|
||||
TMP_TAR_LOCATION = os.path.join(TMP_DIR, TAR_NAME)
|
||||
with open(TMP_TAR_LOCATION, "wb") as f:
|
||||
f.write(response.raw.read())
|
||||
val = TMP_TAR_LOCATION
|
||||
request.config.cache.set("pyodide-0.20-tar", val)
|
||||
return val
|
||||
|
||||
|
||||
def unzip(location, extract_to="."):
|
||||
file = tarfile.open(name=location, mode="r:bz2")
|
||||
file.extractall(path=extract_to)
|
||||
|
||||
|
||||
class TestRuntimeConfig(PyScriptTest):
|
||||
# The default pyodide version is 0.21.2 as of writing
|
||||
# this test which is newer than the one we are loading below
|
||||
# (after downloading locally) -- which is 0.20.0
|
||||
|
||||
# The test checks if loading a different runtime is possible
|
||||
# and that too from a locally downloaded file without needing
|
||||
# the use of explicit `indexURL` calculation.
|
||||
def test_runtime_config(self, tar_location):
|
||||
unzip(
|
||||
location=tar_location,
|
||||
extract_to=self.tmpdir,
|
||||
)
|
||||
|
||||
self.pyscript_run(
|
||||
snippet="""
|
||||
<py-script>
|
||||
import sys, js
|
||||
pyodide_version = sys.modules["pyodide"].__version__
|
||||
js.console.info("version", pyodide_version)
|
||||
pyodide_version
|
||||
</py-script>
|
||||
""",
|
||||
extra_head="""
|
||||
<py-config>
|
||||
runtimes:
|
||||
- src: "/pyodide/pyodide.js"
|
||||
name: pyodide-0.20.0
|
||||
lang: python
|
||||
</py-config>
|
||||
""",
|
||||
)
|
||||
|
||||
assert self.console.info.lines == ["version 0.20.0"]
|
||||
version = self.page.locator("py-script").inner_text()
|
||||
assert version == "0.20.0"
|
||||
23
pyscriptjs/tests/unit/pyconfig.test.ts
Normal file
23
pyscriptjs/tests/unit/pyconfig.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { AppConfig, RuntimeConfig } from '../../src/runtime';
|
||||
import { PyConfig } from '../../src/components/pyconfig';
|
||||
|
||||
customElements.define('py-config', PyConfig);
|
||||
|
||||
describe('PyConfig', () => {
|
||||
let instance: PyConfig;
|
||||
beforeEach(() => {
|
||||
instance = new PyConfig();
|
||||
let runtime_config: RuntimeConfig = {src: "/demo/covfefe.js", name: "covfefe", lang: "covfefe"};
|
||||
let app_config: AppConfig = {autoclose_loader: true, runtimes: [runtime_config]};
|
||||
instance.values = app_config;
|
||||
});
|
||||
|
||||
it('should get the Config to just instantiate', async () => {
|
||||
expect(instance).toBeInstanceOf(PyConfig);
|
||||
});
|
||||
|
||||
it('should load runtime from config and set as script src', () => {
|
||||
instance.loadRuntimes();
|
||||
expect(document.scripts[0].src).toBe("http://localhost/demo/covfefe.js");
|
||||
});
|
||||
});
|
||||
@@ -9,6 +9,22 @@ describe('PyodideRuntime', () => {
|
||||
let runtime: PyodideRuntime;
|
||||
beforeAll(async () => {
|
||||
runtime = new PyodideRuntime();
|
||||
/**
|
||||
* Since import { loadPyodide } from 'pyodide';
|
||||
* is not used inside `src/pyodide.ts`, the function
|
||||
* `runtime.initialize();` below which calls
|
||||
* `loadInterpreter` and thus `loadPyodide` results
|
||||
* in an expected issue of:
|
||||
* ReferenceError: loadPyodide is not defined
|
||||
*
|
||||
* To make jest happy, while also not importing
|
||||
* explicitly inside `src/pyodide.ts`, the
|
||||
* following lines - so as to dynamically import
|
||||
* and make it available in the global namespace
|
||||
* - are used.
|
||||
*/
|
||||
const pyodideSpec = await import('pyodide');
|
||||
global.loadPyodide = pyodideSpec.loadPyodide;
|
||||
await runtime.initialize();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user