Commit 6da9eeea authored by carlosperate's avatar carlosperate

Updating state of unit tests.

Still a lot of work to do in this area, but at least the scope of work is more clear now.
parent d332588e
...@@ -276,7 +276,7 @@ def get_serial_ports(): ...@@ -276,7 +276,7 @@ def get_serial_ports():
# #
# Launch IDE settings # Load IDE settings
# #
def set_load_ide_only(new_value): def set_load_ide_only(new_value):
ServerCompilerSettings().load_ide_option = new_value ServerCompilerSettings().load_ide_option = new_value
......
...@@ -59,10 +59,10 @@ class ServerCompilerSettings(object): ...@@ -59,10 +59,10 @@ class ServerCompilerSettings(object):
'arduino:avr:diecimila:cpu=atmega168'} 'arduino:avr:diecimila:cpu=atmega168'}
# Class dictionary to contain the computer COM ports, dynamic content # Class dictionary to contain the computer COM ports, dynamic content
__serial_ports = {'port1': 'COM1'} __serial_ports = {'port0': 'COM1'}
# Class dictionary to define IDE load options, static content # Class dictionary to define IDE load options, static content
__ide_load_options = {'open': 'Open sketch in IDE ', __ide_load_options = {'open': 'Open sketch in IDE',
'verify': 'Verify sketch', 'verify': 'Verify sketch',
'upload': 'Compile and Upload sketch'} 'upload': 'Compile and Upload sketch'}
...@@ -392,7 +392,7 @@ class ServerCompilerSettings(object): ...@@ -392,7 +392,7 @@ class ServerCompilerSettings(object):
Checks available Serial Ports and populates the serial port dictionary. Checks available Serial Ports and populates the serial port dictionary.
If the new serial port is not in the dictionary or the dictionary is If the new serial port is not in the dictionary or the dictionary is
empty it prints an error in the console. empty it prints an error in the console.
:param new_port: the new port to set :param new_port_value: the new port to set
""" """
# Check if the settings file value is present in available ports list # Check if the settings file value is present in available ports list
set_default = True set_default = True
...@@ -457,7 +457,7 @@ class ServerCompilerSettings(object): ...@@ -457,7 +457,7 @@ class ServerCompilerSettings(object):
port_id += 1 port_id += 1
# #
# Load the IDE only accessors # Load the IDE accessors
# #
def get_load_ide(self): def get_load_ide(self):
return self.__load_ide_option return self.__load_ide_option
...@@ -617,34 +617,3 @@ class ServerCompilerSettings(object): ...@@ -617,34 +617,3 @@ class ServerCompilerSettings(object):
def delete_settings_file(self): def delete_settings_file(self):
if os.path.exists(self.__settings_path): if os.path.exists(self.__settings_path):
os.remove(self.__settings_path) os.remove(self.__settings_path)
def get_board_value_from_key(self, string_key):
"""
As the board types are stored in a dictionary, the key and value for
the selected board are stored independently in 2 strings. This method
gets the dictionary value from a given key.
:param string_key: String representing the board_types dictionary key
:return: A string representation of board_types dictionary value from
the key.
"""
string_value = None
for key in self.__arduino_types:
if string_key is key:
string_value = self.__arduino_types[key]
return string_value
def get_board_key_from_value(self, string_value):
"""
As the board types are stored in a dictionary, the key and value for
the selected board are stored independently in 2 strings. This method
gets the dictionary key from a given value.
:param string_value: String representing the board_types dictionary
value to be found.
:return: A string representation of board_types dictionary key for
the given value.
"""
string_key = None
for key in self.__arduino_types:
if string_value is self.__arduino_types[key]:
string_key = key
return string_key
# -*- coding: utf-8 -*-
#
# Unit test for the actions module.
#
# Copyright (c) 2015 carlosperate https://github.com/carlosperate/
# Licensed under the Apache License, Version 2.0 (the "License"):
# http://www.apache.org/licenses/LICENSE-2.0
#
from __future__ import unicode_literals, absolute_import
import os
import sys
import mock
import codecs
import unittest
try:
import ardublocklyserver.actions as actions
from ardublocklyserver.compilersettings import ServerCompilerSettings
except ImportError:
import sys
file_dir = os.path.dirname(os.path.realpath(__file__))
package_dir = os.path.dirname(os.path.dirname(file_dir))
sys.path.insert(0, package_dir)
import ardublocklyserver.actions as actions
from ardublocklyserver.compilersettings import ServerCompilerSettings
class ActionsTestCase(unittest.TestCase):
"""
Tests for actions module
"""
#
# Helper functions
#
def delete_default_settings_file(self):
"""
Checks if there is a settings file in the default location and deletes
it if it finds it.
This will DELETE a file from the directory this script is called !!!
"""
default_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
# Accessing the class static variable does not initialise the singleton
settings_file = os.path.normpath(os.path.join(
default_dir,
ServerCompilerSettings._ServerCompilerSettings__settings_filename))
if os.path.exists(settings_file):
print('Removing settings file from %s' % settings_file)
os.remove(settings_file)
#
# Command line tests
#
@mock.patch('ardublocklyserver.actions.subprocess.Popen', autospec=True)
#@mock.patch.object(
# actions.ServerCompilerSettings, 'get_compiler_dir', autospec=True)
def test_load_arduino_cli_valid(self, mock_popen):
"""
Tests that a compiler path and arduino sketch path can be set
and that a command line can be launched to open the sketch in the
Arduino IDE.
"""
sketch_path = actions.create_sketch_default()
ServerCompilerSettings().load_ide_option = 'open'
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.compiler_dir',
new_callable=mock.PropertyMock) as mock_compiler_dir:
mock_compiler_dir.return_value = 'true' # do nothing command
expected_command = ['true', sketch_path]
success, conclusion, out, error, exit_code = \
actions.load_arduino_cli(sketch_path)
mock_popen.assert_called_with(expected_command, shell=False)
self.assertTrue(success)
ServerCompilerSettings().load_ide_option = 'verify'
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.compiler_dir',
new_callable=mock.PropertyMock) as mock_compiler_dir:
mock_compiler_dir.return_value = 'true' # do nothing command
mock_popen.return_value.communicate.return_value = ('test', 'test')
mock_popen.return_value.returncode = 0
expected_command = ['true', '--verify', sketch_path]
success, conclusion, out, error, exit_code = \
actions.load_arduino_cli(sketch_path)
mock_popen.assert_called_with(expected_command, shell=False,
stderr=-1, stdout=-1)
self.assertTrue(success)
ServerCompilerSettings().load_ide_option = 'upload'
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.compiler_dir',
new_callable=mock.PropertyMock) as mock_compiler_dir:
mock_compiler_dir.return_value = 'true' # do nothing command
mock_popen.return_value.communicate.return_value = ('test', 'test')
mock_popen.return_value.returncode = 0
expected_command = [
'true', '--upload', '--port',
ServerCompilerSettings().get_serial_port_flag(), '--board',
ServerCompilerSettings().get_arduino_board_flag(), sketch_path]
success, conclusion, out, error, exit_code = \
actions.load_arduino_cli(sketch_path)
mock_popen.assert_called_with(expected_command, shell=False,
stderr=-1, stdout=-1)
self.assertTrue(success)
# Test for unicode strings as Py2 can be susceptible to fail there
ServerCompilerSettings().load_ide_option = 'upload'
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.compiler_dir',
new_callable=mock.PropertyMock) as mock_compiler_dir:
mock_compiler_dir.return_value = 'いろはにほへとちり' # unicode
mock_popen.return_value.communicate.return_value = (
'Γαζέες καὶ μυρτιὲς', 'Âne ex aéquo au whist')
mock_popen.return_value.returncode = 0
expected_command = [
mock_compiler_dir.return_value, '--upload', '--port',
ServerCompilerSettings().get_serial_port_flag(), '--board',
ServerCompilerSettings().get_arduino_board_flag(), sketch_path]
success, conclusion, out, error, exit_code = \
actions.load_arduino_cli(sketch_path)
mock_popen.assert_called_with(expected_command, shell=False,
stderr=-1, stdout=-1)
self.assertTrue(success)
def test_load_arduino_cli_invalid(self):
# Test that an path that is not a file returns error
success, conclusion, out, error, exit_code =\
actions.load_arduino_cli(os.getcwd())
self.assertFalse(success)
self.assertTrue('Provided sketch path is not a valid' in conclusion)
# Test for error if compiler dir is not set, default is None
self.delete_default_settings_file()
success, conclusion, out, error, exit_code = actions.load_arduino_cli()
self.assertFalse(success)
self.assertEqual(conclusion, 'Unable to find Arduino IDE')
# Test for error if compiler dir is not set
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.compiler_dir',
new_callable=mock.PropertyMock) as mock_compiler_dir:
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.'
'load_ide_option', new_callable=mock.PropertyMock) as \
mock_load_ide_option:
mock_compiler_dir.return_value = 'true' # do nothing command
mock_load_ide_option.return_value = None
success, conclusion, out, error, exit_code = \
actions.load_arduino_cli()
self.assertFalse(success)
self.assertEqual(conclusion,
'What should we do with the Sketch?')
# Test for error if serial port unset, only required when set to upload
ServerCompilerSettings().load_ide_option = 'upload'
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.compiler_dir',
new_callable=mock.PropertyMock) as mock_compiler_dir:
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.'
'get_serial_port_flag') as mock_get_serial_port_flag:
mock_compiler_dir.return_value = 'true' # do nothing command
mock_get_serial_port_flag.return_value = None
success, conclusion, out, error, exit_code = \
actions.load_arduino_cli()
self.assertFalse(success)
self.assertEqual(conclusion, 'Serial Port unavailable')
# Test for error if board type unset, only required when set to upload
ServerCompilerSettings().load_ide_option = 'upload'
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.compiler_dir',
new_callable=mock.PropertyMock) as mock_compiler_dir:
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.'
'get_arduino_board_flag') as mock_get_arduino_board_flag:
mock_compiler_dir.return_value = 'true' # do nothing command
mock_get_arduino_board_flag.return_value = None
success, conclusion, out, error, exit_code = \
actions.load_arduino_cli()
self.assertFalse(success)
self.assertEqual(conclusion, 'Unknown Arduino Board')
#
# Tests sketch creation
#
def test_create_sketch_default(self):
sketch_dir = actions.create_sketch_default()
self.assertTrue(os.path.isfile(sketch_dir))
def test_create_sketch_from_string(self):
sketch_content = 'test string sketch'
sketch_dir = actions.create_sketch_from_string(sketch_content)
self.assertTrue(os.path.isfile(sketch_dir))
f = codecs.open(sketch_dir, "r", "utf-8")
self.assertEqual(f.read(), sketch_content)
# Test for unicode file
sketch_content = 'いろはにほへとちり Γαζέες καὶ μυρτς Âne aéquo au whist'
sketch_dir = actions.create_sketch_from_string(sketch_content)
self.assertTrue(os.path.isfile(sketch_dir))
f = codecs.open(sketch_dir, "r", "utf-8")
self.assertEqual(f.read(), sketch_content)
#
# Tests sketch creation
#
@mock.patch('ardublocklyserver.gui.browse_file_dialog')
@mock.patch('ardublocklyserver.compilersettings.os.path.isfile')
def test_load_arduino_cli_valid(self, mock_isfile, mock_file_dialog):
"""
Tests that the set_compiler_path method edits the settings based on the
output from the gui.browse_file_dialog() function only if it has not
been cancelled.
The return value is not tested as it is a direct call to the
actions.get_compiler_path() function and will be tested individually.
"""
self.delete_default_settings_file()
settings = ServerCompilerSettings()
new_compiler_dir = os.path.join(os.getcwd(), 'arduino_debug.exe')
mock_file_dialog.return_value = new_compiler_dir
# The settings.compiler_dir checks for file validity
mock_isfile.return_value = True
old_compiler_dir = settings.compiler_dir
actions.set_compiler_path()
self.assertNotEqual(old_compiler_dir, settings.compiler_dir)
# Using in as each OSs will dealt with compiler path differently
self.assertTrue(new_compiler_dir in settings.compiler_dir)
# If the dialog is cancelled, the ServerCompilerSettings class should
# not be invoked at all
with mock.patch(
'ardublocklyserver.actions.ServerCompilerSettings.__new__') \
as mock_settings:
# Avoid call to ServerCompilerSettings() in get_compiler_path
with mock.patch('ardublocklyserver.actions.get_compiler_path') \
as mock_get_compiler_path:
mock_file_dialog.return_value = '' # Dialog cancel return value
mock_get_compiler_path.return_vale = None # Don't care
old_compiler_dir = settings.compiler_dir
actions.set_compiler_path()
self.assertEqual(old_compiler_dir, settings.compiler_dir)
self.assertFalse(mock_settings.called)
def test_get_compiler_path(self):
#TODO: This test method
pass
#
# Test sketch setting functions
#
def test_set_sketch_path(self):
#TODO: This test method
pass
def test_get_sketch_path(self):
#TODO: This test method
pass
#
# Test arduino Board setting functions
#
def test_set_arduino_board(self):
#TODO: This test method
pass
def test_get_arduino_boards(self):
#TODO: This test method
pass
#
# Test serial Port setting functions
#
def test_set_serial_port(self):
#TODO: This test method
pass
def test_get_serial_ports(self):
#TODO: This test method
pass
#
# Test load IDE setting functions
#
def test_set_load_ide_only(self):
#TODO: This test method
pass
def test_get_load_ide_only(self):
#TODO: This test method
pass
if __name__ == '__main__':
unittest.main()
...@@ -162,6 +162,66 @@ class ServerCompilerSettingsTestCase(unittest.TestCase): ...@@ -162,6 +162,66 @@ class ServerCompilerSettingsTestCase(unittest.TestCase):
'JavaApplicationStub') 'JavaApplicationStub')
self.assertEqual(final_dir, ServerCompilerSettings().compiler_dir) self.assertEqual(final_dir, ServerCompilerSettings().compiler_dir)
#
# Test the sketch name accessors
#
def test_sketch_name_valid_accesor(self):
#TODO: This test
pass
def test_sketch_name_invalid_accesor(self):
#TODO: This test
pass
#
# Test the sketch directory accessors
#
def test_sketch_dir_valid_accesor(self):
#TODO: This test
pass
def test_sketch_dir_invalid_accesor(self):
#TODO: This test
pass
#
# Test the Arduino boards accessors
#
def test_arduino_board_valid_accesor(self):
#TODO: This test
pass
def test_arduino_board_invalid_accesor(self):
#TODO: This test
pass
def test_get_arduino_board_flag(self):
#TODO: This test
pass
def test_get_arduino_board_types(self):
#TODO: This test
pass
#
# Test the serial port accessors
#
def test_serial_port_valid_accesor(self):
#TODO: This test
pass
def test_serial_port_invalid_accesor(self):
#TODO: This test
pass
def test_get_serial_port_flag(self):
#TODO: This test
pass
def test_get_serial_ports(self):
#TODO: This test
pass
# #
# Testing the launch_IDE_option accessors # Testing the launch_IDE_option accessors
# #
...@@ -202,7 +262,23 @@ class ServerCompilerSettingsTestCase(unittest.TestCase): ...@@ -202,7 +262,23 @@ class ServerCompilerSettingsTestCase(unittest.TestCase):
self.assertEqual(instance.load_ide_option, old_load_ide_option) self.assertEqual(instance.load_ide_option, old_load_ide_option)
# #
# Testing the settings file # Test the default values function
#
def test_set_default_settings(self):
#TODO: This test
pass
def test_new_settings_file_defaults(self):
"""
Tests that a newly created instance without an already existing settings
file contains the default settings.
:return:
"""
#TODO: This test
pass
#
# Testing the save and read settings file functionality
# #
def test_settings_file_creation(self): def test_settings_file_creation(self):
""" """
...@@ -214,7 +290,16 @@ class ServerCompilerSettingsTestCase(unittest.TestCase): ...@@ -214,7 +290,16 @@ class ServerCompilerSettingsTestCase(unittest.TestCase):
ServerCompilerSettings().save_settings() ServerCompilerSettings().save_settings()
self.assertTrue(os.path.exists(settings_file)) self.assertTrue(os.path.exists(settings_file))
def test_settings_file_read(self): def test_settings_file_deletion(self):
self.delete_default_settings_file()
settings_file = self.get_default_settings_file_dir()
self.assertFalse(os.path.exists(settings_file))
ServerCompilerSettings().save_settings()
self.assertTrue(os.path.exists(settings_file))
ServerCompilerSettings().delete_settings_file()
self.assertFalse(os.path.exists(settings_file))
def test_settings_file_simple_read(self):
""" """
Simple test that checks for no exceptions happening while creating Simple test that checks for no exceptions happening while creating
and loading the created file. and loading the created file.
...@@ -224,6 +309,22 @@ class ServerCompilerSettingsTestCase(unittest.TestCase): ...@@ -224,6 +309,22 @@ class ServerCompilerSettingsTestCase(unittest.TestCase):
ServerCompilerSettings().get_settings_file_data() ServerCompilerSettings().get_settings_file_data()
ServerCompilerSettings().save_settings() ServerCompilerSettings().save_settings()
def test_settings_file_read(self):
"""
Tests that the settings are saved into a file and read correctly.
Checks that all saved settings are retrieved.
"""
#TODO: This test
pass
def test_save_file_unicode(self):
#TODO: This test
pass
def test_read_file_unicode(self):
#TODO: This test
pass
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -23,7 +23,7 @@ except ImportError: ...@@ -23,7 +23,7 @@ except ImportError:
class GuiTestCase(unittest.TestCase): class GuiTestCase(unittest.TestCase):
""" """
Tests for gu i module Tests for gui module
""" """
# #
......
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