示例#1
0
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
示例#2
0
    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()
示例#3
0
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
示例#4
0
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'
示例#5
0
文件: test_fs.py 项目: jodli/pyp5js
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()
示例#6
0
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
示例#7
0
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
示例#8
0
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())
示例#9
0
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
示例#11
0
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)
示例#12
0
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)
示例#14
0
def files():
    files = SketchFiles('foo')
    files.create_sketch_dir()
    yield files
    shutil.rmtree(SKETCHBOOK_DIR)
示例#15
0
 def test_raise_exception_when_name_starts_with_numbers(self):
     files = SketchFiles('123name')
     with pytest.raises(InvalidName):
         files.validate_name()
示例#16
0
 def setUp(self):
     self.base_dir = SKETCHBOOK_DIR
     self.sketch_name = 'foo'
     self.files = SketchFiles(self.sketch_name)
示例#17
0
 def test_name_should_accept_underscore_in_the_middle(self):
     file = SketchFiles('na_me')
     assert file.sketch_name == 'na_me'
示例#18
0
 def test_name_should_accept_underscore_in_the_beginning(self):
     file = SketchFiles('__name__')
     assert file.sketch_name == '__name__'
示例#19
0
 def test_raise_exception_when_name_creating_dir_with_invalid_name(self):
     files = SketchFiles('name&')
     with pytest.raises(InvalidName):
         files.create_sketch_dir()
示例#20
0
 def setUp(self):
     self.sketch_name = 'foo'
     self.sketch_files = SketchFiles(self.sketch_name)
示例#21
0
 def test_raise_exception_when_name_contains_non_alphanumeric_chars(self):
     files = SketchFiles('name&')
     with pytest.raises(InvalidName):
         files.validate_name()