Commit 01c43cba authored by carlosperate's avatar carlosperate

Decouple SketchCreator from ServerCompilerSettings and fix unicode.

The SketchCreator should now be able to deal properly with unicode sketch directories and unicode in the sketch code itself when run in Python 2 (was not an issue in Python 3).
parent c29ce872
......@@ -139,11 +139,16 @@ def load_arduino_cli(sketch_path=None):
def create_sketch_default():
return SketchCreator().create_sketch()
settings = ServerCompilerSettings()
return SketchCreator().create_sketch(
settings.sketch_dir, sketch_name=settings.sketch_name)
def create_sketch_from_string(sketch_code):
return SketchCreator().create_sketch(sketch_code)
settings = ServerCompilerSettings()
return SketchCreator().create_sketch(
settings.sketch_dir, sketch_name=settings.sketch_name,
sketch_code=sketch_code)
#
......
......@@ -7,10 +7,10 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
from __future__ import unicode_literals, absolute_import
import codecs
import os
from ardublocklyserver.six import six
from ardublocklyserver.compilersettings import ServerCompilerSettings
class SketchCreator(object):
......@@ -21,9 +21,9 @@ class SketchCreator(object):
#
# Metaclass methods
#
def __init__(self):
def __init__(self, sketch_name=None):
# Default sketch, blink builtin LED
self._sketch_default_code = \
self._default_sketch_code = \
'int led = 13;\n' \
'void setup() {\n' \
' pinMode(led, OUTPUT);\n' \
......@@ -34,58 +34,68 @@ class SketchCreator(object):
' digitalWrite(led, LOW);\n' \
' delay(1000);\n' \
'}\n'
# Default sketch name
self._default_sketch_name = 'ArdublocklySketch'
#
# Creating files
#
def create_sketch(self, sketch_code=None):
def create_sketch(self, sketch_dir, sketch_name=None, sketch_code=None):
"""
Creates the Arduino sketch with either the default blinky
code or the code defined in the input parameter.
:param sketch_code: Unicode string with the code for the sketch.
Creates the Arduino sketch with either the default blinky code or the
code defined in the input parameter.
:param sketch_dir: Location for the sketch.
:param sketch_name: Optional name for the sketch.
:param sketch_code: Optional unicode string with the code for the
sketch.
:return: Unicode string with full path to the sketch file
Return None indicates an error has occurred.
"""
sketch_path = self.build_sketch_path()
if isinstance(sketch_code, six.string_types)\
and sketch_code:
code_to_write = sketch_code
# Check the code first, to not create sketch file if invalid
if sketch_code is None:
code_to_write = self._default_sketch_code
else:
code_to_write = self._sketch_default_code
if isinstance(sketch_code, six.string_types):
code_to_write = sketch_code
else:
print('The sketch code given is not a valid string !!!')
return None
# Check validity and create the sketch path
if sketch_name is None:
sketch_name = self._default_sketch_name
sketch_path = self.build_sketch_path(sketch_dir, sketch_name)
if sketch_path is None:
return None
try:
arduino_sketch = open(sketch_path, 'w')
arduino_sketch.write(code_to_write)
arduino_sketch.close()
arduino_sketch = codecs.open(sketch_path, 'wb+', encoding='utf-8')
try:
arduino_sketch.write(code_to_write)
finally:
arduino_sketch.close()
except Exception as e:
sketch_path = None
print(e)
print('Arduino sketch could not be created!!!')
print('Arduino sketch could not be created !!!')
return None
return sketch_path
#
# File and directories settings
#
def build_sketch_path(self):
@staticmethod
def build_sketch_path(sketch_dir, sketch_name):
"""
If a valid directory is saved in the settings, it creates the Arduino
folder (if it does not exists already) and returns a string pointing
to the sketch path
:return: unicode string with full path to the sketch file
Return None indicates an error has occurred
If a valid directory is provided, it creates the Arduino sketch folder
(if it does not exists already) and returns a string pointing to the
sketch file path.
:return: unicode string with full path to the sketch file.
Returns None indicates an error has occurred.
"""
sketch_name = ServerCompilerSettings().sketch_name
sketch_directory = ServerCompilerSettings().sketch_dir
sketch_path = None
if os.path.isdir(sketch_directory):
sketch_path = os.path.join(sketch_directory, sketch_name)
if os.path.isdir(sketch_dir):
sketch_path = os.path.join(sketch_dir, sketch_name)
if not os.path.exists(sketch_path):
os.makedirs(sketch_path)
sketch_path = os.path.join(sketch_path, sketch_name + '.ino')
else:
print('The sketch directory in the settings does not exists!')
print('The sketch directory "%s" does not exists !!!' % sketch_dir)
return sketch_path
......@@ -9,6 +9,8 @@
from __future__ import unicode_literals, absolute_import
import os
import time
import codecs
import shutil
import unittest
try:
......@@ -27,40 +29,99 @@ class SketchCreatorTestCase(unittest.TestCase):
"""
Tests for SketchCreator class
"""
#
# File creation
# File creation without input code
#
def test_create_sketch(self):
""" Tests to see if an Arduino Sketch is created in a new location """
test_sketch_name = 'TestTemp_Sketch'
ServerCompilerSettings().sketch_dir = os.getcwd()
ServerCompilerSettings().sketch_name = test_sketch_name
test_path = os.path.join(os.getcwd(),
test_sketch_name,
test_sketch_name + '.ino')
# It should be save to create and delete in test folder
if os.path.exists(test_path):
os.remove(test_path)
self.assertFalse(os.path.isfile(test_path))
""" Tests to see if an Arduino Sketch is created in a new location. """
# First test with the default name
sketch_creator = SketchCreator()
sketch_dir = os.getcwd()
final_ino_path = os.path.join(
sketch_dir,
sketch_creator._default_sketch_name,
'%s.ino' % sketch_creator._default_sketch_name)
# It should be save to create and delete the ino file in the test folder
if os.path.exists(final_ino_path):
os.remove(final_ino_path)
self.assertFalse(os.path.isfile(final_ino_path))
# Checks the file is saved, and saved to the right location
created_sketch_path = sketch_creator.create_sketch(sketch_dir)
self.assertEqual(final_ino_path, created_sketch_path)
self.assertTrue(os.path.isfile(final_ino_path))
# Now test with a given sketch name and a unicode path
sketch_name = 'TestTemp_Sketch'
sketch_dir_unicode = os.path.join(os.getcwd(), 'TestTemp_ろΓαζςÂé')
final_ino_path = os.path.join(sketch_dir_unicode,
sketch_name,
sketch_name + '.ino')
# Test directory should be a safe place to create this unicode folder
if not os.path.exists(sketch_dir_unicode):
os.mkdir(sketch_dir_unicode)
else:
# We count on this specific folder name to be too unlikely
# created by a user and not this unit test, so remove contents
shutil.rmtree(sketch_dir_unicode)
os.mkdir(sketch_dir_unicode)
self.assertFalse(os.path.isfile(final_ino_path))
# Checks the file is saved, and saved to the right location
created_sketch_path = sketch_creator.create_sketch()
self.assertEqual(test_path, created_sketch_path)
self.assertTrue(os.path.isfile(test_path))
created_sketch_path = sketch_creator.create_sketch(
sketch_dir_unicode, sketch_name=sketch_name)
self.assertEqual(final_ino_path, created_sketch_path)
self.assertTrue(os.path.isfile(final_ino_path))
# Remove created unicode dir
shutil.rmtree(sketch_dir_unicode)
def test_create_sketch_invalid(self):
"""
Test for invalid inputs in the create_sketch method.
"""
# Test for failure on invalid sketch path
random_invalid_path = os.path.join(os.getcwd(), 'raNd_dIr')
self.assertFalse(os.path.isdir(random_invalid_path))
sketch_creator = SketchCreator()
created_sketch_path = sketch_creator.create_sketch(random_invalid_path)
self.assertIsNone(created_sketch_path)
self.assertFalse(os.path.isdir(random_invalid_path))
# Test for failure on invalid sketch code
sketch_path = os.getcwd()
sketch_folder_path = os.path.join(
sketch_path, sketch_creator._default_sketch_name)
if os.path.isdir(sketch_folder_path):
shutil.rmtree(sketch_folder_path)
self.assertFalse(os.path.isdir(sketch_folder_path))
invalid_sketch_code = True
created_sketch_path = sketch_creator.create_sketch(
sketch_path, sketch_code=invalid_sketch_code)
self.assertIsNone(created_sketch_path)
self.assertFalse(os.path.isdir(sketch_folder_path))
#
# File creation with code
#
def test_create_sketch_with_code(self):
sketch_code_write = 'Test on: %s' % time.strftime("%Y-%m-%d %H:%M:%S")
sketch_creator = SketchCreator()
sketch_location = sketch_creator.create_sketch(sketch_code_write)
sketch_dir = os.getcwd()
sketch_ino_location = os.path.join(
sketch_dir,
sketch_creator._default_sketch_name,
'%s.ino' % sketch_creator._default_sketch_name)
sketch_code_write = 'Unicode test (ろΓαζςÂaé) on: %s' % \
time.strftime("%Y-%m-%d %H:%M:%S")
sketch_return_location = sketch_creator.create_sketch(
sketch_dir, sketch_code=sketch_code_write)
self.assertEqual(sketch_return_location, sketch_ino_location)
arduino_sketch = open(sketch_location, 'r')
arduino_sketch = codecs.open(
sketch_return_location, 'r', encoding='utf-8')
sketch_code_read = arduino_sketch.read()
arduino_sketch.close()
self.assertEqual(sketch_code_write, sketch_code_read)
......
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