mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
This MR shows errors and exit in these conditions: * multiple `<py-config>` or `<mpy-config>` found on the page * both `<py-config>` and `<script type="py" config="file.toml">` found on main * different `<script type="py" config="a.toml">` and `<script type="py" config="b.toml">` configs found on main
This commit is contained in:
committed by
GitHub
parent
96e671b55f
commit
b0377cc7ab
4
pyscript.core/package-lock.json
generated
4
pyscript.core/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@pyscript/core",
|
"name": "@pyscript/core",
|
||||||
"version": "0.3.7",
|
"version": "0.3.8",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@pyscript/core",
|
"name": "@pyscript/core",
|
||||||
"version": "0.3.7",
|
"version": "0.3.8",
|
||||||
"license": "APACHE-2.0",
|
"license": "APACHE-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ungap/with-resolvers": "^0.1.0",
|
"@ungap/with-resolvers": "^0.1.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@pyscript/core",
|
"name": "@pyscript/core",
|
||||||
"version": "0.3.7",
|
"version": "0.3.8",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "PyScript",
|
"description": "PyScript",
|
||||||
"module": "./index.js",
|
"module": "./index.js",
|
||||||
|
|||||||
@@ -3,15 +3,17 @@
|
|||||||
* to use as base config for all py-script elements, importing
|
* to use as base config for all py-script elements, importing
|
||||||
* also a queue of plugins *before* the interpreter (if any) resolves.
|
* also a queue of plugins *before* the interpreter (if any) resolves.
|
||||||
*/
|
*/
|
||||||
import { $ } from "basic-devtools";
|
import { $$ } from "basic-devtools";
|
||||||
|
|
||||||
import TYPES from "./types.js";
|
import TYPES from "./types.js";
|
||||||
import allPlugins from "./plugins.js";
|
import allPlugins from "./plugins.js";
|
||||||
import { robustFetch as fetch, getText } from "./fetch.js";
|
import { robustFetch as fetch, getText } from "./fetch.js";
|
||||||
import { ErrorCode } from "./exceptions.js";
|
import { ErrorCode } from "./exceptions.js";
|
||||||
|
|
||||||
|
const { BAD_CONFIG, CONFLICTING_CODE } = ErrorCode;
|
||||||
|
|
||||||
const badURL = (url, expected = "") => {
|
const badURL = (url, expected = "") => {
|
||||||
let message = `(${ErrorCode.BAD_CONFIG}): Invalid URL: ${url}`;
|
let message = `(${BAD_CONFIG}): Invalid URL: ${url}`;
|
||||||
if (expected) message += `\nexpected ${expected} content`;
|
if (expected) message += `\nexpected ${expected} content`;
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
};
|
};
|
||||||
@@ -41,8 +43,10 @@ const configDetails = async (config, type) => {
|
|||||||
return { json, toml: toml || (!json && !!text), text, url };
|
return { json, toml: toml || (!json && !!text), text, url };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const conflictError = (reason) => new Error(`(${CONFLICTING_CODE}): ${reason}`);
|
||||||
|
|
||||||
const syntaxError = (type, url, { message }) => {
|
const syntaxError = (type, url, { message }) => {
|
||||||
let str = `(${ErrorCode.BAD_CONFIG}): Invalid ${type}`;
|
let str = `(${BAD_CONFIG}): Invalid ${type}`;
|
||||||
if (url) str += ` @ ${url}`;
|
if (url) str += ` @ ${url}`;
|
||||||
return new SyntaxError(`${str}\n${message}`);
|
return new SyntaxError(`${str}\n${message}`);
|
||||||
};
|
};
|
||||||
@@ -56,27 +60,49 @@ for (const [TYPE] of TYPES) {
|
|||||||
/** @type {any} The PyScript configuration parsed from the JSON or TOML object*. May be any of the return types of JSON.parse() or toml-j0.4's parse() ( {number | string | boolean | null | object | Array} ) */
|
/** @type {any} The PyScript configuration parsed from the JSON or TOML object*. May be any of the return types of JSON.parse() or toml-j0.4's parse() ( {number | string | boolean | null | object | Array} ) */
|
||||||
let parsed;
|
let parsed;
|
||||||
|
|
||||||
/** @type {SyntaxError | undefined} The error thrown when parsing the PyScript config, if any.*/
|
/** @type {Error | undefined} The error thrown when parsing the PyScript config, if any.*/
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
let config,
|
let config,
|
||||||
type,
|
type,
|
||||||
pyConfig = $(`${TYPE}-config`);
|
pyElement,
|
||||||
if (pyConfig) {
|
pyConfigs = $$(`${TYPE}-config`),
|
||||||
config = pyConfig.getAttribute("src") || pyConfig.textContent;
|
attrConfigs = $$(
|
||||||
type = pyConfig.getAttribute("type");
|
|
||||||
} else {
|
|
||||||
pyConfig = $(
|
|
||||||
[
|
[
|
||||||
`script[type="${TYPE}"][config]:not([worker])`,
|
`script[type="${TYPE}"][config]:not([worker])`,
|
||||||
`${TYPE}-script[config]:not([worker])`,
|
`${TYPE}-script[config]:not([worker])`,
|
||||||
].join(","),
|
].join(","),
|
||||||
);
|
);
|
||||||
if (pyConfig) config = pyConfig.getAttribute("config");
|
|
||||||
|
// throw an error if there are multiple <py-config> or <mpy-config>
|
||||||
|
if (pyConfigs.length > 1) {
|
||||||
|
error = conflictError(`Too many ${TYPE}-config`);
|
||||||
|
} else {
|
||||||
|
// throw an error if there are <x-config> and config="x" attributes
|
||||||
|
if (pyConfigs.length && attrConfigs.length) {
|
||||||
|
error = conflictError(
|
||||||
|
`Ambiguous ${TYPE}-config VS config attribute`,
|
||||||
|
);
|
||||||
|
} else if (pyConfigs.length) {
|
||||||
|
[pyElement] = pyConfigs;
|
||||||
|
config = pyElement.getAttribute("src") || pyElement.textContent;
|
||||||
|
type = pyElement.getAttribute("type");
|
||||||
|
} else if (attrConfigs.length) {
|
||||||
|
[pyElement, ...attrConfigs] = attrConfigs;
|
||||||
|
config = pyElement.getAttribute("config");
|
||||||
|
// throw an error if dirrent scripts use different configs
|
||||||
|
if (
|
||||||
|
attrConfigs.some((el) => el.getAttribute("config") !== config)
|
||||||
|
) {
|
||||||
|
error = conflictError(
|
||||||
|
"Unable to use different configs on main",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// catch possible fetch errors
|
// catch possible fetch errors
|
||||||
if (config) {
|
if (!error && config) {
|
||||||
try {
|
try {
|
||||||
const { json, toml, text, url } = await configDetails(config, type);
|
const { json, toml, text, url } = await configDetails(config, type);
|
||||||
config = text;
|
config = text;
|
||||||
|
|||||||
19
pyscript.core/test/config/ambiguous-config.html
Normal file
19
pyscript.core/test/config/ambiguous-config.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>PyScript Next</title>
|
||||||
|
<script>
|
||||||
|
addEventListener("error", ({ message }) => {
|
||||||
|
document.body.innerHTML += `<p>${message}</p>`;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<link rel="stylesheet" href="../../dist/core.css">
|
||||||
|
<script type="module" src="../../dist/core.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<py-config>name = "first"</py-config>
|
||||||
|
<script type="py" config="second.toml"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
16
pyscript.core/test/config/index.html
Normal file
16
pyscript.core/test/config/index.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li><a href="./ambiguous-config.html">ambiguous py-config VS config attribute</a></li>
|
||||||
|
<li><a href="./too-many-config.html">too many config attributes</a></li>
|
||||||
|
<li><a href="./too-many-py-config.html">too many <py-config></a></li>
|
||||||
|
<li><a href="./same-config.html">same config attributes</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
20
pyscript.core/test/config/same-config.html
Normal file
20
pyscript.core/test/config/same-config.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>PyScript Next</title>
|
||||||
|
<script>
|
||||||
|
addEventListener("error", ({ message }) => {
|
||||||
|
document.body.innerHTML += `<p>${message}</p>`;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<link rel="stylesheet" href="../../dist/core.css">
|
||||||
|
<script type="module" src="../../dist/core.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
OK
|
||||||
|
<script type="py" config='{"name":"OK"}'></script>
|
||||||
|
<script type="py" config='{"name":"OK"}'></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
19
pyscript.core/test/config/too-many-config.html
Normal file
19
pyscript.core/test/config/too-many-config.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>PyScript Next</title>
|
||||||
|
<script>
|
||||||
|
addEventListener("error", ({ message }) => {
|
||||||
|
document.body.innerHTML += `<p>${message}</p>`;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<link rel="stylesheet" href="../../dist/core.css">
|
||||||
|
<script type="module" src="../../dist/core.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="py" config="first.toml"></script>
|
||||||
|
<script type="py" config="second.toml"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
19
pyscript.core/test/config/too-many-py-config.html
Normal file
19
pyscript.core/test/config/too-many-py-config.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>PyScript Next</title>
|
||||||
|
<script>
|
||||||
|
addEventListener("error", ({ message }) => {
|
||||||
|
document.body.innerHTML += `<p>${message}</p>`;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<link rel="stylesheet" href="../../dist/core.css">
|
||||||
|
<script type="module" src="../../dist/core.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<py-config>name = "first"</py-config>
|
||||||
|
<py-config>name = "second"</py-config>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -100,7 +100,31 @@ class TestConfig(PyScriptTest):
|
|||||||
)
|
)
|
||||||
assert banner.inner_text() == expected
|
assert banner.inner_text() == expected
|
||||||
|
|
||||||
@pytest.mark.skip("NEXT: emit a warning in case of multiple py-config")
|
def test_ambiguous_py_config(self):
|
||||||
|
self.pyscript_run(
|
||||||
|
"""
|
||||||
|
<py-config>name = "first"</py-config>
|
||||||
|
|
||||||
|
<script type="py" config="second.toml"></script>
|
||||||
|
""",
|
||||||
|
wait_for_pyscript=False,
|
||||||
|
)
|
||||||
|
banner = self.page.wait_for_selector(".py-error")
|
||||||
|
expected = "(PY0409): Ambiguous py-config VS config attribute"
|
||||||
|
assert banner.text_content() == expected
|
||||||
|
|
||||||
|
def test_multiple_attributes_py_config(self):
|
||||||
|
self.pyscript_run(
|
||||||
|
"""
|
||||||
|
<script type="py" config="first.toml"></script>
|
||||||
|
<script type="py" config="second.toml"></script>
|
||||||
|
""",
|
||||||
|
wait_for_pyscript=False,
|
||||||
|
)
|
||||||
|
banner = self.page.wait_for_selector(".py-error")
|
||||||
|
expected = "(PY0409): Unable to use different configs on main"
|
||||||
|
assert banner.text_content() == expected
|
||||||
|
|
||||||
def test_multiple_py_config(self):
|
def test_multiple_py_config(self):
|
||||||
self.pyscript_run(
|
self.pyscript_run(
|
||||||
"""
|
"""
|
||||||
@@ -117,13 +141,11 @@ class TestConfig(PyScriptTest):
|
|||||||
#config = js.pyscript_get_config()
|
#config = js.pyscript_get_config()
|
||||||
#js.console.log("config name:", config.name)
|
#js.console.log("config name:", config.name)
|
||||||
</script>
|
</script>
|
||||||
"""
|
""",
|
||||||
)
|
wait_for_pyscript=False,
|
||||||
banner = self.page.wait_for_selector(".py-warning")
|
|
||||||
expected = (
|
|
||||||
"Multiple <py-config> tags detected. Only the first "
|
|
||||||
"is going to be parsed, all the others will be ignored"
|
|
||||||
)
|
)
|
||||||
|
banner = self.page.wait_for_selector(".py-error")
|
||||||
|
expected = "(PY0409): Too many py-config"
|
||||||
assert banner.text_content() == expected
|
assert banner.text_content() == expected
|
||||||
|
|
||||||
def test_paths(self):
|
def test_paths(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user