Commit abd10207 authored by Romain Casati's avatar Romain Casati
Browse files

PythonTutor tests.

parent 06da1be0
Pipeline #410439 passed with stage
in 3 minutes and 33 seconds
......@@ -70,7 +70,7 @@ def tutor(**kwargs):
lines = code.split('\n')
# listing tutor import lines then remove
# hacky... should be implemented with inspect
# this is hacky... and should be implemented with inspect
import_lines = [i for i, line in enumerate(lines)
if line in ('import tutor',
'from tutor import tutor',
......@@ -79,7 +79,7 @@ def tutor(**kwargs):
del lines[index]
# listing tutor() call lines
# hacky... should be implemented with inspect
# this is hacky... and should be implemented with inspect
tutor_lines = [i for i, line in enumerate(lines)
if line.startswith('tutor.tutor(')
or line.startswith('tutor(')]
......@@ -102,7 +102,7 @@ def tutor(**kwargs):
# building pytutor visualizer
iframe = iframe_template.format(
json_trace=trace,
extern_tutor_url=js.Basthon.basthonModulesRoot() + '/extern',
extern_tutor_url=f"{js.Basthon.basthonModulesRoot()}/extern",
iframe_id=id)
iframe = f'<iframe id="{id}" style="width: 100%; height: 400px;" frameborder="0" src="data:text/html;charset=utf-8,{quote(iframe)}"></iframe>'
......
["Bio", "IPython", "PIL", "__future__", "__main__", "_abc", "_ast", "_bootlocale", "_codecs", "_collections", "_collections_abc", "_compat_pickle", "_compression", "_contextvars", "_dummy_thread", "_frozen_importlib", "_frozen_importlib_external", "_functools", "_heapq", "_imp", "_io", "_locale", "_markupbase", "_operator", "_posixsubprocess", "_py_abc", "_pydecimal", "_pyio", "_signal", "_sitebuiltins", "_socket", "_sre", "_stat", "_string", "_strptime", "_sysconfigdata__emscripten_", "_testcapi", "_thread", "_threading_local", "_warnings", "_weakref", "_weakrefset", "abc", "aifc", "antigravity", "argparse", "asciitree", "ast", "astropy", "asynchat", "asyncio", "asyncore", "atexit", "atomicwrites", "attr", "autograd", "bar", "base64", "basthon", "bdb", "binhex", "bisect", "bleach", "bs4", "builtins", "bz2", "cProfile", "calendar", "cgi", "cgitb", "chunk", "cloudpickle", "cmd", "code", "codecs", "codeop", "collections", "colorsys", "compileall", "concurrent", "configparser", "contextlib", "contextvars", "copy", "copyreg", "crypt", "cssselect", "csv", "cycler", "cytoolz", "dataclasses", "datetime", "dateutil", "decimal", "decorator", "difflib", "dis", "distlib", "distutils", "doctest", "docutils", "dummy_threading", "easy_install", "email", "encodings", "enum", "errno", "filecmp", "fileinput", "fnmatch", "folium", "foo", "formatter", "fractions", "freesasa", "ftplib", "functools", "future", "genericpath", "getopt", "getpass", "gettext", "glob", "graphviz", "gzip", "hashlib", "heapq", "hmac", "html", "html5lib", "http", "imageio", "imaplib", "imghdr", "imp", "importlib", "inspect", "io", "ipaddress", "itertools", "jedi", "jinja2", "joblib", "js", "json", "keyword", "kiwisolver", "linecache", "locale", "logging", "lxml", "lzma", "mailbox", "mailcap", "markupsafe", "marshal", "math", "matplotlib", "micropip", "mimetypes", "mne", "modulefinder", "more_itertools", "mpl_toolkits", "mpmath", "msgpack", "multiprocessing", "netrc", "networkx", "nltk", "nntplib", "nose", "ntpath", "nturl2path", "numbers", "numcodecs", "numpy", "opcode", "operator", "optparse", "os", "p5", "packaging", "pandas", "parso", "pathlib", "patsy", "pdb", "pickle", "pickletools", "pipes", "pkg_resources", "pkgutil", "platform", "plistlib", "pluggy", "poplib", "posix", "posixpath", "pprint", "profile", "proj4py", "pstats", "pty", "py", "py_compile", "pyclbr", "pydoc", "pydoc_data", "pygments", "pyodide", "pyodide_interrupts", "pyparsing", "pysat", "pystone", "pytest", "pytz", "pywt", "queue", "quopri", "random", "re", "regex", "reprlib", "requests", "rlcompleter", "runpy", "sched", "scipy", "secrets", "select", "selectors", "setuptools", "shelve", "shlex", "shutil", "signal", "site", "sitecustomize", "six", "skimage", "sklearn", "smtpd", "smtplib", "sndhdr", "socket", "socketserver", "soupsieve", "sqlite3", "sre_compile", "sre_constants", "sre_parse", "ssl", "stat", "statistics", "statsmodels", "string", "stringprep", "struct", "subprocess", "sunau", "symbol", "sympy", "symtable", "sys", "sysconfig", "tabnanny", "tarfile", "telnetlib", "tempfile", "textwrap", "this", "threading", "time", "timeit", "token", "tokenize", "toolz", "trace", "traceback", "tracemalloc", "traits", "tty", "turtle", "types", "typing", "uncertainties", "unittest", "urllib", "uu", "uuid", "warnings", "wave", "weakref", "webbrowser", "webencodings", "wsgiref", "xdrlib", "xlrd", "xml", "xmlrpc", "yt", "zarr", "zipapp", "zipfile", "zipimport"]
["Bio", "IPython", "PIL", "__future__", "__main__", "_abc", "_ast", "_bootlocale", "_codecs", "_collections", "_collections_abc", "_compat_pickle", "_compression", "_contextvars", "_dummy_thread", "_frozen_importlib", "_frozen_importlib_external", "_functools", "_heapq", "_imp", "_io", "_locale", "_markupbase", "_operator", "_posixsubprocess", "_py_abc", "_pydecimal", "_pyio", "_signal", "_sitebuiltins", "_socket", "_sre", "_stat", "_string", "_strptime", "_sysconfigdata__emscripten_", "_testcapi", "_thread", "_threading_local", "_warnings", "_weakref", "_weakrefset", "abc", "aifc", "antigravity", "argparse", "asciitree", "ast", "astropy", "asynchat", "asyncio", "asyncore", "atexit", "atomicwrites", "attr", "autograd", "bar", "base64", "basthon", "bdb", "binhex", "bisect", "bleach", "bs4", "builtins", "bz2", "cProfile", "calendar", "cgi", "cgitb", "chunk", "cloudpickle", "cmd", "code", "codecs", "codeop", "collections", "colorsys", "compileall", "concurrent", "configparser", "contextlib", "contextvars", "copy", "copyreg", "crypt", "cssselect", "csv", "cycler", "cytoolz", "dataclasses", "datetime", "dateutil", "decimal", "decorator", "difflib", "dis", "distlib", "distutils", "doctest", "docutils", "dummy_threading", "easy_install", "email", "encodings", "enum", "errno", "filecmp", "fileinput", "fnmatch", "folium", "foo", "formatter", "fractions", "freesasa", "ftplib", "functools", "future", "genericpath", "getopt", "getpass", "gettext", "glob", "graphviz", "gzip", "hashlib", "heapq", "hmac", "html", "html5lib", "http", "imageio", "imaplib", "imghdr", "imp", "importlib", "inspect", "io", "ipaddress", "itertools", "jedi", "jinja2", "joblib", "js", "json", "keyword", "kiwisolver", "linecache", "locale", "logging", "lxml", "lzma", "mailbox", "mailcap", "markupsafe", "marshal", "math", "matplotlib", "micropip", "mimetypes", "mne", "modulefinder", "more_itertools", "mpl_toolkits", "mpmath", "msgpack", "multiprocessing", "netrc", "networkx", "nltk", "nntplib", "nose", "ntpath", "nturl2path", "numbers", "numcodecs", "numpy", "opcode", "operator", "optparse", "os", "p5", "packaging", "pandas", "parso", "pathlib", "patsy", "pdb", "pickle", "pickletools", "pipes", "pkg_resources", "pkgutil", "platform", "plistlib", "pluggy", "poplib", "posix", "posixpath", "pprint", "profile", "proj4py", "pstats", "pty", "py", "py_compile", "pyclbr", "pydoc", "pydoc_data", "pygments", "pyodide", "pyodide_interrupts", "pyparsing", "pysat", "pystone", "pytest", "pytz", "pywt", "queue", "quopri", "random", "re", "regex", "reprlib", "requests", "rlcompleter", "runpy", "sched", "scipy", "secrets", "select", "selectors", "setuptools", "shelve", "shlex", "shutil", "signal", "site", "sitecustomize", "six", "skimage", "sklearn", "smtpd", "smtplib", "sndhdr", "socket", "socketserver", "soupsieve", "sqlite3", "sre_compile", "sre_constants", "sre_parse", "ssl", "stat", "statistics", "statsmodels", "string", "stringprep", "struct", "subprocess", "sunau", "symbol", "sympy", "symtable", "sys", "sysconfig", "tabnanny", "tarfile", "telnetlib", "tempfile", "textwrap", "this", "threading", "time", "timeit", "token", "tokenize", "toolz", "trace", "traceback", "tracemalloc", "traits", "tty", "turtle", "tutor", "types", "typing", "uncertainties", "unittest", "urllib", "uu", "uuid", "warnings", "wave", "weakref", "webbrowser", "webencodings", "wsgiref", "xdrlib", "xlrd", "xml", "xmlrpc", "yt", "zarr", "zipapp", "zipfile", "zipimport"]
......@@ -59,32 +59,32 @@ _stat fractions poplib tracemalloc
_string freesasa posix traits
_strptime ftplib posixpath tty
_struct functools pprint turtle
_symtable future profile types
_sysconfigdata__emscripten_ gc proj4py typing
_testcapi genericpath pstats uncertainties
_thread getopt pty unicodedata
_threading_local getpass pwd unittest
_tracemalloc gettext py urllib
_warnings glob py_compile uu
_weakref graphviz pyclbr uuid
_weakrefset gzip pydoc warnings
abc hashlib pydoc_data wave
aifc heapq pyexpat weakref
antigravity hmac pygments webbrowser
argparse html pyodide webencodings
array html5lib pyodide_interrupts wsgiref
asciitree http pyparsing xdrlib
ast imageio pysat xlrd
astropy imaplib pystone xml
asynchat imghdr pytest xmlrpc
asyncio imp pytz xxsubtype
asyncore importlib pywt yt
atexit inspect queue zarr
atomicwrites io quopri zipapp
attr ipaddress random zipfile
autograd itertools re zipimport
base64 jedi regex zlib
basthon jinja2 reprlib
_symtable future profile tutor
_sysconfigdata__emscripten_ gc proj4py types
_testcapi genericpath pstats typing
_thread getopt pty uncertainties
_threading_local getpass pwd unicodedata
_tracemalloc gettext py unittest
_warnings glob py_compile urllib
_weakref graphviz pyclbr uu
_weakrefset gzip pydoc uuid
abc hashlib pydoc_data warnings
aifc heapq pyexpat wave
antigravity hmac pygments weakref
argparse html pyodide webbrowser
array html5lib pyodide_interrupts webencodings
asciitree http pyparsing wsgiref
ast imageio pysat xdrlib
astropy imaplib pystone xlrd
asynchat imghdr pytest xml
asyncio imp pytz xmlrpc
asyncore importlib pywt xxsubtype
atexit inspect queue yt
atomicwrites io quopri zarr
attr ipaddress random zipapp
autograd itertools re zipfile
base64 jedi regex zipimport
basthon jinja2 reprlib zlib
bdb joblib requests
binascii js rlcompleter
......
<iframe id="basthon-pythontutor-iframe-0" style="width: 100%; height: 400px;" frameborder="0" src="data:text/html;charset=utf-8,%3C%21DOCTYPE%20html%3E%0A%3Chtml%3E%0A%20%20%3Chead%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22/0.30.0/modules/extern/pytutor-main.min.css%22/%3E%0A%20%20%20%20%3Cscript%20src%3D%22/0.30.0/modules/extern/pytutor-main.min.js%22%3E%3C/script%3E%0A%20%20%20%20%3Cscript%3E%0A%20%20%20%20%20%20let%20sent_height%3B%0A%20%20%20%20%20%20%24%28document%29.ready%28function%28%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20//%20managing%20iframe%20resize%0A%20%20%20%20%20%20%20%20%20%20const%20send%20%3D%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20new_height%20%3D%20document.body.offsetHeight%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20%28sent_height%20%3D%3D%3D%20new_height%29%20return%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20sent_height%20%3D%20new_height%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20window.parent.postMessage%28%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type%3A%20%22pytutor-iframe-resize%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20target%3A%20%22basthon-pythontutor-iframe-0%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height%3A%20sent_height%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%20%27%2A%27%29%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20%20%20const%20o%20%3D%20new%20ResizeObserver%28send%29%3B%0A%20%20%20%20%20%20%20%20%20%20o.observe%28document.body%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20const%20t%20%3D%20%7B%22code%22%3A%20%22a%20%3D%205%5Cna%20%3D%20a%20%2B%201%22%2C%20%22trace%22%3A%20%5B%7B%22line%22%3A%201%2C%20%22event%22%3A%20%22step_line%22%2C%20%22func_name%22%3A%20%22%3Cmodule%3E%22%2C%20%22globals%22%3A%20%7B%7D%2C%20%22ordered_globals%22%3A%20%5B%5D%2C%20%22stack_to_render%22%3A%20%5B%5D%2C%20%22heap%22%3A%20%7B%7D%2C%20%22stdout%22%3A%20%22%22%7D%2C%20%7B%22line%22%3A%202%2C%20%22event%22%3A%20%22step_line%22%2C%20%22func_name%22%3A%20%22%3Cmodule%3E%22%2C%20%22globals%22%3A%20%7B%22a%22%3A%205%7D%2C%20%22ordered_globals%22%3A%20%5B%22a%22%5D%2C%20%22stack_to_render%22%3A%20%5B%5D%2C%20%22heap%22%3A%20%7B%7D%2C%20%22stdout%22%3A%20%22%22%7D%2C%20%7B%22line%22%3A%202%2C%20%22event%22%3A%20%22return%22%2C%20%22func_name%22%3A%20%22%3Cmodule%3E%22%2C%20%22globals%22%3A%20%7B%22a%22%3A%206%7D%2C%20%22ordered_globals%22%3A%20%5B%22a%22%5D%2C%20%22stack_to_render%22%3A%20%5B%5D%2C%20%22heap%22%3A%20%7B%7D%2C%20%22stdout%22%3A%20%22%22%7D%5D%7D%3B%0A%20%20%20%20%20%20%20%20%20%20function%20redraw%28%29%20%7B%20if%20%28window.v%29%20window.v.redrawConnectors%28%29%3B%20%7D%0A%20%20%20%20%20%20%20%20%20%20window.v%20%3D%20new%20ExecutionVisualizer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%27main%27%2C%20t%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7BembeddedMode%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20heightChangeCallback%3A%20redraw%7D%0A%20%20%20%20%20%20%20%20%20%20%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20//%20message%20of%20type%20%27redraw%27%20from%20parent%20triggers%20a%20full%20redraw%0A%20%20%20%20%20%20%20%20%20%20//%20%28usefull%20when%20iframe%20is%20added%20to%20a%20non%20visible%20parent%29%0A%20%20%20%20%20%20%20%20%20%20window.addEventListener%28%27message%27%2C%20function%20%28event%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20data%20%3D%20event.data%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%28%20data.type%20%3D%3D%3D%20%27redraw%27%20%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20window.v.updateOutput%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%24%28window%29.resize%28redraw%29%3B%0A%20%20%20%20%20%20%20%20%20%20redraw%28%29%3B%0A%20%20%20%20%20%20%7D%29%3B%0A%20%20%20%20%3C/script%3E%0A%20%20%3C/head%3E%0A%20%20%3Cbody%20style%3D%22overflow-y%3A%20hidden%3B%22%3E%0A%20%20%20%20%3Cdiv%20id%3D%22main%22%3E%3C/div%3E%0A%20%20%3C/body%3E%0A%3C/html%3E%0A"></iframe>
\ No newline at end of file
from pathlib import Path
import base64
import time
import re
_test_data = Path(__file__).parent / "data"
......@@ -125,3 +127,25 @@ def test_p5(selenium):
assert png == target
selenium.run_basthon("stop()")
def test_tutor(selenium):
result = selenium.run_basthon("""
from tutor import tutor
a = 5
a = a + 1
tutor()""")
assert result['stderr'] == ""
assert result['stdout'] == ""
assert result['display']['display_type'] == 'tutor'
assert result['display']['iframe-id'] == 'basthon-pythontutor-iframe-0'
# webserver starts at arbitrary port so this makes absolute paths
# inconsistent between calls...
# we remove the host:port part from URLs
iframe = re.sub(r"http%3A//127.0.0.1%3A\d*",
"", result['display']['content'])
with open(_test_data / "tutor-iframe.html") as f:
target = f.read()
assert target == iframe
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment