From d9bf5cae12de6806ce9e04f2455440e7a1b8e157 Mon Sep 17 00:00:00 2001 From: Andrea Giammarchi Date: Fri, 27 Oct 2023 15:30:21 +0200 Subject: [PATCH] Fix #1814 - Basic mpy integration (#1815) --- Makefile | 2 +- pyscript.core/package-lock.json | 60 +++++++++++++++++++++++++++++++++ pyscript.core/package.json | 4 ++- pyscript.core/src/stdlib.js | 11 ++++-- pyscript.core/test/hooks.html | 46 ++++++++++++++----------- pyscript.core/test/mpy.html | 12 +++++-- pyscript.core/test/mpy.spec.js | 37 ++++++++++++++++++++ 7 files changed, 146 insertions(+), 26 deletions(-) create mode 100644 pyscript.core/test/mpy.spec.js diff --git a/Makefile b/Makefile index 408dc31d..90a975a8 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ clean: # Build PyScript. build: - cd pyscript.core && npm run build + cd pyscript.core && npx playwright install && npm run build # Run the precommit checks (run eslint). precommit-check: diff --git a/pyscript.core/package-lock.json b/pyscript.core/package-lock.json index 26f8dabc..42e754ae 100644 --- a/pyscript.core/package-lock.json +++ b/pyscript.core/package-lock.json @@ -17,6 +17,7 @@ "type-checked-collections": "^0.1.7" }, "devDependencies": { + "@playwright/test": "^1.39.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", "@webreflection/toml-j0.4": "^1.1.3", @@ -220,6 +221,21 @@ "node": ">= 8" } }, + "node_modules/@playwright/test": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", + "dev": true, + "dependencies": { + "playwright": "1.39.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.2.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", @@ -2060,6 +2076,50 @@ "resolved": "https://registry.npmjs.org/plain-tag/-/plain-tag-0.1.3.tgz", "integrity": "sha512-yyVAOFKTAElc7KdLt2+UKGExNYwYb/Y/WE9i+1ezCQsJE8gbKSjewfpRqK2nQgZ4d4hhAAGgDCOcIZVilqE5UA==" }, + "node_modules/playwright": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", + "dev": true, + "dependencies": { + "playwright-core": "1.39.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/polyscript": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/polyscript/-/polyscript-0.5.1.tgz", diff --git a/pyscript.core/package.json b/pyscript.core/package.json index afe82225..a84ecd0f 100644 --- a/pyscript.core/package.json +++ b/pyscript.core/package.json @@ -20,11 +20,12 @@ }, "scripts": { "server": "npx static-handler --coi .", - "build": "npm run build:toml && npm run build:stdlib && npm run build:plugins && npm run build:core && eslint src/ && npm run ts", + "build": "npm run build:toml && npm run build:stdlib && npm run build:plugins && npm run build:core && eslint src/ && npm run ts && npm run test:mpy", "build:core": "rm -rf dist && rollup --config rollup/core.config.js", "build:plugins": "node rollup/plugins.cjs", "build:stdlib": "node rollup/stdlib.cjs", "build:toml": "node rollup/toml.cjs", + "test:mpy": "static-handler --coi . 2>/dev/null & SH_PID=$!; EXIT_CODE=0; playwright test --fully-parallel test/ || EXIT_CODE=$?; kill $SH_PID 2>/dev/null; exit $EXIT_CODE", "dev": "node dev.cjs", "release": "npm run build && npm run zip", "size": "echo -e \"\\033[1mdist/*.js file size\\033[0m\"; for js in $(ls dist/*.js); do echo -e \"\\033[2m$js:\\033[0m $(cat $js | brotli | wc -c) bytes\"; done", @@ -46,6 +47,7 @@ "type-checked-collections": "^0.1.7" }, "devDependencies": { + "@playwright/test": "^1.39.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", "@webreflection/toml-j0.4": "^1.1.3", diff --git a/pyscript.core/src/stdlib.js b/pyscript.core/src/stdlib.js index 2abfe304..0bdf2545 100644 --- a/pyscript.core/src/stdlib.js +++ b/pyscript.core/src/stdlib.js @@ -10,7 +10,11 @@ import pyscript from "./stdlib/pyscript.js"; const { entries } = Object; -const python = ["from pathlib import Path as _Path", "_path = None"]; +const python = [ + "import os as _os", + "from pathlib import Path as _Path", + "_path = None", +]; const write = (base, literal) => { for (const [key, value] of entries(literal)) { @@ -19,7 +23,9 @@ const write = (base, literal) => { const code = JSON.stringify(value); python.push(`_path.write_text(${code})`); } else { - python.push("_path.mkdir(parents=True, exist_ok=True)"); + // @see https://github.com/pyscript/pyscript/pull/1813#issuecomment-1781502909 + python.push(`if not _os.path.exists("${base}/${key}"):`); + python.push(" _path.mkdir(parents=True, exist_ok=True)"); write(`${base}/${key}`, value); } } @@ -29,6 +35,7 @@ write(".", pyscript); python.push("del _Path"); python.push("del _path"); +python.push("del _os"); python.push("\n"); export default python.join("\n"); diff --git a/pyscript.core/test/hooks.html b/pyscript.core/test/hooks.html index a369b1ec..c614dbd0 100644 --- a/pyscript.core/test/hooks.html +++ b/pyscript.core/test/hooks.html @@ -6,28 +6,19 @@ PyScript Next Plugin Bug? - - diff --git a/pyscript.core/test/mpy.html b/pyscript.core/test/mpy.html index f98e58b6..f6e54650 100644 --- a/pyscript.core/test/mpy.html +++ b/pyscript.core/test/mpy.html @@ -5,7 +5,9 @@ PyScript Next @@ -13,11 +15,15 @@ + + from pyscript import display + display("Hello", "M-PyScript Main 2", append=False) + from pyscript import display - display("Hello", "M-PyScript Next Worker", append=False) + display("Hello", "M-PyScript Worker", append=False) diff --git a/pyscript.core/test/mpy.spec.js b/pyscript.core/test/mpy.spec.js new file mode 100644 index 00000000..aee7bc8e --- /dev/null +++ b/pyscript.core/test/mpy.spec.js @@ -0,0 +1,37 @@ +import { test, expect } from '@playwright/test'; + +test('MicroPython display', async ({ page }) => { + await page.goto('http://localhost:8080/test/mpy.html'); + await page.waitForSelector('html.done'); + const body = await page.evaluate(() => document.body.innerText); + await expect(body.trim()).toBe([ + 'M-PyScript Main 1', + 'M-PyScript Main 2', + 'M-PyScript Worker', + ].join('\n')); +}); + +test('MicroPython hooks', async ({ page }) => { + const logs = []; + page.on('console', msg => { + const text = msg.text(); + if (!text.startsWith('[')) + logs.push(text); + }); + await page.goto('http://localhost:8080/test/hooks.html'); + await page.waitForSelector('html.done'); + await expect(logs.join('\n')).toBe([ + 'main onReady', + 'main onBeforeRun', + 'main codeBeforeRun', + 'actual code in main', + 'main codeAfterRun', + 'main onAfterRun', + 'worker onReady', + 'worker onBeforeRun', + 'worker codeBeforeRun', + 'actual code in worker', + 'worker codeAfterRun', + 'worker onAfterRun', + ].join('\n')); +});