Files
pyscript/pyscriptjs/tests/unit/runtime.test.ts
Antonio Cuni c75f885cb4 Refactor py-config and the general initialization logic of the page (#806)
This PR is the first step to improve and rationalize the life-cycle of a pyscript app along the lines of what I described in #763 .
It is not a complete solution, more PRs will follow.
Highlights:

- py-config is no longer a web component: the old code relied on PyConfig.connectedCallback to do some logic, but then if no <py-config> tag was present, we had to introduce a dummy one with the sole goal of activating the callback. Now the logic is much more linear.

- the new pyconfig.ts only contains the code which is needed to parse the config; I also moved some relevant code from utils.ts because it didn't really belong to it

- the old PyConfig class did much more than dealing with the config: in particular, it contained the code to initialize the env and the runtime. Now this logic has been moved directly into main.ts, inside the new PyScriptApp class. I plan to refactor the initialization code in further PRs

- the current code relies too much on global state and global variables, they are everywhere. This PR is a first step to solve the problem by introducing a PyScriptApp class, which will hold all the mutable state of the page. Currently only config is stored there, but eventually I will migrate more state to it, until we will have only one global singleton, globalApp

- thanks to what I described above, I could kill the appConfig svelte store: one less store to kill :).
2022-10-04 14:26:12 +02:00

53 lines
1.9 KiB
TypeScript

import type { AppConfig } from '../../src/pyconfig';
import { Runtime } from '../../src/runtime';
import { PyodideRuntime } from '../../src/pyodide';
import { TextEncoder, TextDecoder } from 'util'
global.TextEncoder = TextEncoder
global.TextDecoder = TextDecoder
describe('PyodideRuntime', () => {
let runtime: PyodideRuntime;
beforeAll(async () => {
const config: AppConfig = {};
runtime = new PyodideRuntime(config);
/**
* 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();
});
it('should check if runtime is an instance of abstract Runtime', async () => {
expect(runtime).toBeInstanceOf(Runtime);
});
it('should check if runtime is an instance of PyodideRuntime', async () => {
expect(runtime).toBeInstanceOf(PyodideRuntime);
});
it('should check if runtime can run python code asynchronously', async () => {
expect(await runtime.run("2+3")).toBe(5);
});
it('should check if runtime is able to load a package', async () => {
await runtime.loadPackage("numpy");
await runtime.run("import numpy as np");
await runtime.run("x = np.ones((10,))");
expect(runtime.globals.get('x').toJs()).toBeInstanceOf(Float64Array);
});
});