Skip to content
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

add tests for runtime config inside py-config and remove usage of indexURL #734

Merged
merged 10 commits into from
Aug 31, 2022
Merged
2 changes: 1 addition & 1 deletion examples/webgl/raycaster/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
js.document.addEventListener('mousemove', pyodide.create_proxy(onMouseMove))
js.document.addEventListener('mousemove', pyodide.ffi.create_proxy(onMouseMove))
madhur-tandon marked this conversation as resolved.
Show resolved Hide resolved

camera = THREE.PerspectiveCamera.new( 35, window.innerWidth / window.innerHeight, 1, 500 )
scene = THREE.Scene.new()
Expand Down
26 changes: 19 additions & 7 deletions pyscriptjs/src/pyodide.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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.
*/
antocuni marked this conversation as resolved.
Show resolved Hide resolved
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
madhur-tandon marked this conversation as resolved.
Show resolved Hide resolved
this.interpreter = await loadPyodide({
stdout: console.log,
stderr: console.log,
fullStdLib: false,
indexURL,
});

this.globals = this.interpreter.globals;
Expand Down
9 changes: 1 addition & 8 deletions pyscriptjs/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

madhur-tandon marked this conversation as resolved.
Show resolved Hide resolved
export { addClasses, removeClasses, getLastPath, ltrim, htmlDecode, guidGenerator, showError, handleFetchError, inJest };
export { addClasses, removeClasses, getLastPath, ltrim, htmlDecode, guidGenerator, showError, handleFetchError };
3 changes: 2 additions & 1 deletion pyscriptjs/tests/integration/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def wait_for_pyscript(self, *, timeout=None, check_errors=True):
check_errors=check_errors,
)

def pyscript_run(self, snippet):
def pyscript_run(self, snippet, config=""):
"""
Main entry point for pyscript tests.

Expand All @@ -197,6 +197,7 @@ def pyscript_run(self, snippet):
<head>
<link rel="stylesheet" href="{self.http_server}/build/pyscript.css" />
<script defer src="{self.http_server}/build/pyscript.js"></script>
{config}
madhur-tandon marked this conversation as resolved.
Show resolved Hide resolved
</head>
<body>
{snippet}
Expand Down
43 changes: 43 additions & 0 deletions pyscriptjs/tests/integration/test_py_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import tarfile
from io import BytesIO

import requests

from .support import PyScriptTest

URL = "https://github.com/pyodide/pyodide/releases/download/0.20.0/pyodide-build-0.20.0.tar.bz2"


def download_and_unzip(url, extract_to="."):
response = requests.get(url, stream=True)
file = tarfile.open(fileobj=BytesIO(response.raw.read()), mode="r:bz2")
file.extractall(path=extract_to)

madhur-tandon marked this conversation as resolved.
Show resolved Hide resolved

class TestPyConfig(PyScriptTest):
def test_config(self):
download_and_unzip(
url=URL,
extract_to=self.tmpdir,
)

self.pyscript_run(
snippet="""
<py-script>
import sys
sys.modules["pyodide"].__version__
</py-script>
""",
config="""
<py-config>
autoclose_loader: true
runtimes:
- src: "/pyodide/pyodide.js"
name: pyodide-0.20.0
lang: python
</py-config>
""",
)

version = self.page.locator("py-script").inner_text()
assert version == "0.20.0"
madhur-tandon marked this conversation as resolved.
Show resolved Hide resolved
23 changes: 23 additions & 0 deletions pyscriptjs/tests/unit/pyconfig.test.ts
Original file line number Diff line number Diff line change
@@ -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");
});
});
16 changes: 16 additions & 0 deletions pyscriptjs/tests/unit/runtime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});

Expand Down