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): ...@@ -70,7 +70,7 @@ def tutor(**kwargs):
lines = code.split('\n') lines = code.split('\n')
# listing tutor import lines then remove # 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) import_lines = [i for i, line in enumerate(lines)
if line in ('import tutor', if line in ('import tutor',
'from tutor import tutor', 'from tutor import tutor',
...@@ -79,7 +79,7 @@ def tutor(**kwargs): ...@@ -79,7 +79,7 @@ def tutor(**kwargs):
del lines[index] del lines[index]
# listing tutor() call lines # 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) tutor_lines = [i for i, line in enumerate(lines)
if line.startswith('tutor.tutor(') if line.startswith('tutor.tutor(')
or line.startswith('tutor(')] or line.startswith('tutor(')]
...@@ -102,7 +102,7 @@ def tutor(**kwargs): ...@@ -102,7 +102,7 @@ def tutor(**kwargs):
# building pytutor visualizer # building pytutor visualizer
iframe = iframe_template.format( iframe = iframe_template.format(
json_trace=trace, json_trace=trace,
extern_tutor_url=js.Basthon.basthonModulesRoot() + '/extern', extern_tutor_url=f"{js.Basthon.basthonModulesRoot()}/extern",
iframe_id=id) 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>' 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 ...@@ -59,32 +59,32 @@ _stat fractions poplib tracemalloc
_string freesasa posix traits _string freesasa posix traits
_strptime ftplib posixpath tty _strptime ftplib posixpath tty
_struct functools pprint turtle _struct functools pprint turtle
_symtable future profile types _symtable future profile tutor
_sysconfigdata__emscripten_ gc proj4py typing _sysconfigdata__emscripten_ gc proj4py types
_testcapi genericpath pstats uncertainties _testcapi genericpath pstats typing
_thread getopt pty unicodedata _thread getopt pty uncertainties
_threading_local getpass pwd unittest _threading_local getpass pwd unicodedata
_tracemalloc gettext py urllib _tracemalloc gettext py unittest
_warnings glob py_compile uu _warnings glob py_compile urllib
_weakref graphviz pyclbr uuid _weakref graphviz pyclbr uu
_weakrefset gzip pydoc warnings _weakrefset gzip pydoc uuid
abc hashlib pydoc_data wave abc hashlib pydoc_data warnings
aifc heapq pyexpat weakref aifc heapq pyexpat wave
antigravity hmac pygments webbrowser antigravity hmac pygments weakref
argparse html pyodide webencodings argparse html pyodide webbrowser
array html5lib pyodide_interrupts wsgiref array html5lib pyodide_interrupts webencodings
asciitree http pyparsing xdrlib asciitree http pyparsing wsgiref
ast imageio pysat xlrd ast imageio pysat xdrlib
astropy imaplib pystone xml astropy imaplib pystone xlrd
asynchat imghdr pytest xmlrpc asynchat imghdr pytest xml
asyncio imp pytz xxsubtype asyncio imp pytz xmlrpc
asyncore importlib pywt yt asyncore importlib pywt xxsubtype
atexit inspect queue zarr atexit inspect queue yt
atomicwrites io quopri zipapp atomicwrites io quopri zarr
attr ipaddress random zipfile attr ipaddress random zipapp
autograd itertools re zipimport autograd itertools re zipfile
base64 jedi regex zlib base64 jedi regex zipimport
basthon jinja2 reprlib basthon jinja2 reprlib zlib
bdb joblib requests bdb joblib requests
binascii js rlcompleter 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 from pathlib import Path
import base64 import base64
import time import time
import re
_test_data = Path(__file__).parent / "data" _test_data = Path(__file__).parent / "data"
...@@ -125,3 +127,25 @@ def test_p5(selenium): ...@@ -125,3 +127,25 @@ def test_p5(selenium):
assert png == target assert png == target
selenium.run_basthon("stop()") 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