load code from the attr src of py-repl (#1292)

* load code from the attr src of py-repl

* load code from the attr src of py-repl

* load code from the attr src of py-repl

* load code from the attr src of py-repl

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Mike Chen
2023-04-03 17:06:30 +08:00
committed by GitHub
parent b53ddd401f
commit d7e80ad51b
3 changed files with 102 additions and 1 deletions

View File

@@ -12,6 +12,8 @@ import { getLogger } from '../logger';
import { InterpreterClient } from '../interpreter_client';
import type { PyScriptApp } from '../main';
import { Stdio } from '../stdio';
import { robustFetch } from '../fetch';
import { _createAlertBanner } from '../exceptions';
const logger = getLogger('py-repl');
const RUNBUTTON = `<svg style="height:20px;width:20px;vertical-align:-.125em;transform-origin:center;overflow:visible;color:green" viewBox="0 0 384 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(192 256)" transform-origin="96 0"><g transform="translate(0,0) scale(1,1)"><path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" fill="currentColor" transform="translate(-192 -256)"></path></g></g></svg>`;
@@ -31,7 +33,7 @@ export function make_PyRepl(interpreter: InterpreterClient, app: PyScriptApp) {
editor: EditorView;
stdout_manager: Stdio | null;
stderr_manager: Stdio | null;
static observedAttributes = ['src'];
connectedCallback() {
ensureUniqueId(this);
@@ -51,6 +53,42 @@ export function make_PyRepl(interpreter: InterpreterClient, app: PyScriptApp) {
logger.debug(`element ${this.id} successfully connected`);
}
get src() {
return this.getAttribute('src');
}
set src(value) {
this.setAttribute('src', value);
}
attributeChangedCallback(name: string, oldVal: string, newVal: string) {
if (name === 'src' && newVal !== oldVal) {
void this.loadReplSrc();
}
}
/**
* Fetch url from src attribute of py-repl tags and
* preload the code from fetch response into the Corresponding py-repl tag,
* but please note that they will not be pre-run unless you click the runbotton.
*/
async loadReplSrc() {
try {
const response = await robustFetch(this.src);
if (!response.ok) {
return;
}
const cmcontentElement = this.querySelector("div[class='cm-content']");
const { lastElementChild } = cmcontentElement;
cmcontentElement.replaceChildren(lastElementChild);
lastElementChild.textContent = await response.text();
logger.info(`loading code from ${this.src} to repl...success`);
} catch (err) {
const e = err as Error;
_createAlertBanner(e.message);
}
}
/** Create and configure the codemirror editor
*/
makeEditor(pySrc: string): EditorView {

View File

@@ -575,3 +575,65 @@ class TestPyRepl(PyScriptTest):
)
alert_banner = self.page.wait_for_selector(".alert-banner")
assert expected_alert_banner_msg in alert_banner.inner_text()
def test_repl_load_content_from_src(self):
self.writefile("loadReplSrc1.py", "print('1')")
self.pyscript_run(
"""
<py-repl id="py-repl1" output="replOutput1" src="./loadReplSrc1.py"></py-repl>
<div id="replOutput1"></div>
"""
)
successMsg = "[py-repl] loading code from ./loadReplSrc1.py to repl...success"
assert self.console.log.lines[0] == self.PY_COMPLETE
assert self.console.info.lines[-1] == successMsg
py_repl = self.page.locator("py-repl")
code = py_repl.inner_text()
assert "print('1')" in code
def test_repl_src_change(self):
self.writefile("loadReplSrc2.py", "2")
self.writefile("loadReplSrc3.py", "print('3')")
self.pyscript_run(
"""
<py-repl id="py-repl2" output="replOutput2" src="./loadReplSrc2.py"></py-repl>
<div id="replOutput2"></div>
<py-repl id="py-repl3" output="replOutput3">
import js
target_tag = js.document.getElementById("py-repl2")
target_tag.setAttribute("src", "./loadReplSrc3.py")
</py-repl>
<div id="replOutput3"></div>
"""
)
successMsg1 = "[py-repl] loading code from ./loadReplSrc2.py to repl...success"
assert self.console.log.lines[0] == self.PY_COMPLETE
assert self.console.info.lines[-1] == successMsg1
py_repl3 = self.page.locator("py-repl#py-repl3")
py_repl3.locator("button").click()
py_repl2 = self.page.locator("py-repl#py-repl2")
py_repl2.locator("button").click()
self.page.wait_for_selector("py-terminal")
assert self.console.log.lines[-1] == "3"
successMsg2 = "[py-repl] loading code from ./loadReplSrc3.py to repl...success"
assert self.console.info.lines[-1] == successMsg2
def test_repl_src_path_that_do_not_exist(self):
self.pyscript_run(
"""
<py-repl id="py-repl4" output="replOutput4" src="./loadReplSrc4.py"></py-repl>
<div id="replOutput4"></div>
"""
)
errorMsg = (
"(PY0404): Fetching from URL ./loadReplSrc4.py "
"failed with error 404 (Not Found). "
"Are your filename and path correct?"
)
assert self.console.log.lines[0] == self.PY_COMPLETE
assert self.console.error.lines[-1] == errorMsg