class Pyp5jsCompilerTests(TestCase): def setUp(self): self.pyp5js_files = LibFiles() self.files = SketchFiles('foo') self.compiler = Pyp5jsCompiler(self.files) self.files.create_sketch_dir() self.files.sketch_py.touch() def tearDown(self): if SKETCHBOOK_DIR.exists(): shutil.rmtree(SKETCHBOOK_DIR) def test_transcrypt_target_dir_path(self): assert self.files.sketch_dir.joinpath( '__target__') == self.compiler.target_dir def test_command_line_string(self): pyp5_dir = self.pyp5js_files.install expected = ' '.join([ str(c) for c in [ 'transcrypt', '-xp', pyp5_dir, '-k', '-ks', '-b', '-m', '-n', self.files.target_sketch ] ]) assert expected == self.compiler.command_line @patch('pyp5js.compiler.subprocess.Popen') def test_run_compiler_as_expected(self, MockedPopen): proc = Mock(spec=Popen) MockedPopen.return_value = proc self.compiler.run_compiler() expected_command_line = shlex.split(self.compiler.command_line) MockedPopen.assert_called_once_with(expected_command_line) proc.wait.assert_called_once_with() def test_clean_up(self): self.compiler.target_dir.mkdir() self.files.target_sketch.touch() self.compiler.clean_up() assert not self.compiler.target_dir.exists() assert self.files.target_dir.exists() assert not self.files.target_sketch.exists() def test_prepare_sketch(self): expected_content = get_target_sketch_content(self.files) assert not self.files.target_sketch.exists() self.compiler.prepare() assert self.files.target_sketch.exists() with self.files.target_sketch.open('r') as fd: content = fd.read() assert expected_content == content
def setUp(self): self.pyp5js_files = LibFiles() self.files = SketchFiles('foo') self.compiler = Pyp5jsCompiler(self.files) self.files.create_sketch_dir() self.files.sketch_py.touch()
def new_sketch(sketch_name): """ Creates a new sketch with the required assets and a index.html file, based on pyp5js's templates :param sketch_name: name for new sketch :type sketch_name: string :return: file names :rtype: list of strings """ sketch_files = SketchFiles(sketch_name) sketch_files.create_sketch_dir() templates_files = [ (sketch_files.from_lib.base_sketch, sketch_files.sketch_py), (sketch_files.from_lib.p5js, sketch_files.p5js), (sketch_files.from_lib.p5_dom_js, sketch_files.p5_dom_js), ] for src, dest in templates_files: shutil.copyfile(src, dest) index_contet = get_sketch_index_content(sketch_files) with open(sketch_files.index_html, "w") as fd: fd.write(index_contet) return sketch_files
class SketchFilesTests(TestCase): def setUp(self): self.base_dir = SKETCHBOOK_DIR self.sketch_name = 'foo' self.files = SketchFiles(self.sketch_name) def tearDown(self): if self.base_dir.exists(): shutil.rmtree(self.base_dir) def test_sketch_dirs(self): assert self.base_dir.joinpath(self.sketch_name) == self.files.sketch_dir assert self.base_dir.joinpath(self.sketch_name, 'static') == self.files.static_dir assert self.base_dir.joinpath(self.sketch_name, 'target') == self.files.target_dir assert self.files.TARGET_NAME == 'target' def test_sketch_files(self): self.files.check_sketch_dir = False assert self.base_dir.joinpath(self.sketch_name, 'index.html') == self.files.index_html assert self.base_dir.joinpath(self.sketch_name, 'static', 'p5.js') == self.files.p5js assert self.base_dir.joinpath(self.sketch_name, 'static', 'p5.dom.js') == self.files.p5_dom_js assert self.base_dir.joinpath(self.sketch_name, 'foo.py') == self.files.sketch_py assert self.base_dir.joinpath(self.sketch_name, 'target_sketch.py') == self.files.target_sketch def test_sketch_files_holds_reference_to_lib_files(self): lib_files = LibFiles() assert isinstance(self.files.from_lib, LibFiles) assert self.files.from_lib.install == lib_files.install def test_create_dirs(self): assert self.files.sketch_dir.exists() is False assert self.files.static_dir.exists() is False assert self.files.target_dir.exists() is False self.files.create_sketch_dir() assert self.files.sketch_dir.exists() is True assert self.files.static_dir.exists() is True assert self.files.target_dir.exists() is True with pytest.raises(SketchDirAlreadyExistException): self.files.create_sketch_dir() def test_raise_exception_when_name_starts_with_numbers(self): with pytest.raises(InvalidName): SketchFiles('123name') def test_raise_exception_when_name_contains_non_alphanumeric_chars(self): with pytest.raises(InvalidName): SketchFiles('name&') def test_name_should_accept_underscore_in_the_beginning(self): file = SketchFiles('__name__') assert file.sketch_name == '__name__' def test_name_should_accept_underscore_in_the_middle(self): file = SketchFiles('na_me') assert file.sketch_name == 'na_me'
class SketchFilesTests(TestCase): def setUp(self): self.base_dir = SKETCHBOOK_DIR self.sketch_name = 'foo' self.files = SketchFiles(self.sketch_name) def tearDown(self): if self.base_dir.exists(): shutil.rmtree(self.base_dir) def test_sketch_dirs(self): assert self.base_dir.joinpath( self.sketch_name) == self.files.sketch_dir assert self.base_dir.joinpath(self.sketch_name, 'static') == self.files.static_dir assert self.base_dir.joinpath(self.sketch_name, 'target') == self.files.target_dir assert self.files.TARGET_NAME == 'target' def test_sketch_files(self): self.files.check_sketch_dir = False assert self.base_dir.joinpath(self.sketch_name, 'index.html') == self.files.index_html assert self.base_dir.joinpath(self.sketch_name, 'static', 'p5.js') == self.files.p5js assert self.base_dir.joinpath(self.sketch_name, 'static', 'p5.dom.js') == self.files.p5_dom_js assert self.base_dir.joinpath(self.sketch_name, 'foo.py') == self.files.sketch_py assert self.base_dir.joinpath( self.sketch_name, 'target_sketch.py') == self.files.target_sketch def test_sketch_files_holds_reference_to_lib_files(self): lib_files = LibFiles() assert isinstance(self.files.from_lib, LibFiles) assert self.files.from_lib.install == lib_files.install def test_create_dirs(self): assert self.files.sketch_dir.exists() is False assert self.files.static_dir.exists() is False assert self.files.target_dir.exists() is False self.files.create_sketch_dir() assert self.files.sketch_dir.exists() is True assert self.files.static_dir.exists() is True assert self.files.target_dir.exists() is True with pytest.raises(SketchDirAlreadyExistException): self.files.create_sketch_dir()
def render_sketch_view(sketch_name, static_path): sketch_files = SketchFiles(sketch_name) content_file = sketch_files.index_html if static_path: content_file = sketch_files.sketch_dir.joinpath(static_path).resolve() if not str(content_file).startswith( str(sketch_files.sketch_dir.resolve())): # User tried something not allowed (as "/root/something" or "../xxx") return '', 403 elif not content_file.exists(): return '', 404 else: try: commands.transcrypt_sketch(sketch_name) except PythonSketchDoesNotExist: return f"There's no sketch in {sketch_files.sketch_dir.resolve()}", 404 with content_file.open() as fd: response = Response(fd.read()) if static_path.endswith('js'): # To avoid MIME type errors # More can be found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options response.headers['Content-Type'] = 'application/javascript' return response
def transcrypt_sketch(sketch_name): """ Transcrypt the sketch python code to javascript. :param sketch_name: name for new sketch :type sketch_name: string :return: file names :rtype: list of strings """ sketch_files = SketchFiles(sketch_name) sketch_files.validate_name() if not sketch_files.sketch_exists: raise PythonSketchDoesNotExist(sketch_files.sketch_py.resolve()) compile_sketch_js(sketch_files) return sketch_files
def sketches_list_view(): sketches = [] for sketch_dir in (p for p in SKETCHBOOK_DIR.iterdir() if p.is_dir()): name = sketch_dir.name sketch_files = SketchFiles(name) if sketch_files.has_all_files: sketches.append({'name': name, 'url': f'/sketch/{name}'}) return render_template('index.html', sketches=sketches, sketches_dir=SKETCHBOOK_DIR.resolve())
class TestNewSketchCommand(TestCase): def setUp(self): self.sketch_name = 'foo' self.sketch_files = SketchFiles(self.sketch_name) def tearDown(self): if SKETCHBOOK_DIR.exists(): shutil.rmtree(SKETCHBOOK_DIR) def test_create_new_sketch_with_all_required_files(self): commands.new_sketch(self.sketch_name) assert self.sketch_files.index_html.exists() assert self.sketch_files.sketch_py.exists() assert self.sketch_files.p5js.exists() assert self.sketch_files.p5_dom_js.exists() def test_raise_exception_if_dir_already_exist(self): self.sketch_files.create_sketch_dir() with pytest.raises(SketchDirAlreadyExistException): commands.new_sketch(self.sketch_name)
def test_get_target_sketch_content(): sketch_files = SketchFiles('foo') expected_template = renderers.templates.get_template( sketch_files.from_lib.target_sketch_template.name) expected_content = expected_template.render({ 'sketch_name': sketch_files.sketch_name, }) content = renderers.get_target_sketch_content(sketch_files) assert expected_content == content assert "import foo as source_sketch" in content
def render_sketch_view(sketch_name, static_path): sketch_files = SketchFiles(sketch_name) error = '' content_file = sketch_files.index_html if static_path: content_file = sketch_files.sketch_dir.joinpath(static_path).resolve() if not str(content_file).startswith( str(sketch_files.sketch_dir.resolve())): # User tried something not allowed (as "/root/something" or "../xxx") return '', 403 elif not content_file.exists(): return '', 404 with content_file.open() as fd: response = Response(fd.read()) if static_path.endswith('js'): # To avoid MIME type errors # More can be found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options response.headers['Content-Type'] = 'application/javascript' return response elif request.method == 'POST': py_code = request.form.get('py_code', '') if not py_code.strip(): error = 'You have to input the Python code.' elif not 'def setup():' in py_code: error = 'You have to define a setup function.' elif not 'def draw():' in py_code: error = 'You have to define a draw function.' else: try: ast.parse(py_code, sketch_files.sketch_py.name) sketch_files.sketch_py.write_text(py_code) except SyntaxError as exc: error = f'SyntaxError: {exc}' if not error: try: commands.transcrypt_sketch(sketch_name) except PythonSketchDoesNotExist: return f"There's no sketch in {sketch_files.sketch_dir.resolve()}", 404 context = { 'p5_js_url': sketch_files.urls.p5_js_url, 'sketch_js_url': sketch_files.urls.sketch_js_url, 'sketch_name': sketch_files.sketch_name, 'py_code': sketch_files.sketch_py.read_text(), 'error': error, } return render_template('view_sketch.html', **context)
def monitor_sketch(sketch_name): """ Monitor for any change in any .py inside the sketch dir. For every new change, runs the transcrypt to update the js files. :param sketch_name: name for new sketch :type sketch_name: string :return: file names :rtype: list of strings """ sketch_files = SketchFiles(sketch_name) sketch_files.validate_name() if not sketch_files.sketch_exists: raise PythonSketchDoesNotExist(sketch_files.sketch_py.resolve()) cprint(f"Monitoring for changes in {sketch_files.sketch_dir.resolve()}...") try: monitor_sketch_service(sketch_files) except KeyboardInterrupt: cprint.info("Exiting monitor...")
def test_get_sketch_index_content(): sketch_files = SketchFiles('foo') expected_template = renderers.templates.get_template( sketch_files.from_lib.index_html.name) expected_content = expected_template.render({ 'sketch_name': sketch_files.sketch_name, "p5_js_url": sketch_files.STATIC_NAME + "/p5.js", "sketch_js_url": sketch_files.TARGET_NAME + "/target_sketch.js", }) assert expected_content == renderers.get_sketch_index_content(sketch_files)
def files(): files = SketchFiles('foo') files.create_sketch_dir() yield files shutil.rmtree(SKETCHBOOK_DIR)
def test_raise_exception_when_name_starts_with_numbers(self): files = SketchFiles('123name') with pytest.raises(InvalidName): files.validate_name()
def setUp(self): self.base_dir = SKETCHBOOK_DIR self.sketch_name = 'foo' self.files = SketchFiles(self.sketch_name)
def test_name_should_accept_underscore_in_the_middle(self): file = SketchFiles('na_me') assert file.sketch_name == 'na_me'
def test_name_should_accept_underscore_in_the_beginning(self): file = SketchFiles('__name__') assert file.sketch_name == '__name__'
def test_raise_exception_when_name_creating_dir_with_invalid_name(self): files = SketchFiles('name&') with pytest.raises(InvalidName): files.create_sketch_dir()
def setUp(self): self.sketch_name = 'foo' self.sketch_files = SketchFiles(self.sketch_name)
def test_raise_exception_when_name_contains_non_alphanumeric_chars(self): files = SketchFiles('name&') with pytest.raises(InvalidName): files.validate_name()