Author: jprantan
Date: Wed May 20 03:49:40 2009
New Revision: 64
Added:
trunk/utest/test_settings_utils.py
Modified:
trunk/src/mabot/settings/__init__.py
trunk/src/mabot/settings/utils.py
trunk/utest/test_settings.py
Log:
Improved writing settings. Now it supports also i.e. unicode.
Modified: trunk/src/mabot/settings/__init__.py
==============================================================================
--- trunk/src/mabot/settings/__init__.py (original)
+++ trunk/src/mabot/settings/__init__.py Wed May 20 03:49:40 2009
@@ -19,16 +19,14 @@
from types import ListType
from types import StringType
-from utils import get_settings_file
-
-USER_SETTINGS_FILE = get_settings_path('mabotsettings.py')
-COMPILED_USER_SETTINGS_FILE = USER_SETTINGS_FILE + 'c'
-sys.path.append(os.path.dirname(USER_SETTINGS_FILE))
+import utils
+USER_SETTINGS_FILE = utils.get_settings_path('mabotsettings.py')
class Settings:
def __init__(self):
+ self._user_settings = utils.SettingsIO(USER_SETTINGS_FILE)
self.load_settings()
def update(self, new_settings, suite):
@@ -41,34 +39,14 @@
self.save_settings()
def save_settings(self):
- self._remove_user_settings()
- try:
- settings_file = open(USER_SETTINGS_FILE, 'w')
- settings_file.write(str(self))
- finally:
- settings_file.close()
-
- def __str__(self):
- data = 'settings = {\n'
- for key, value in self.settings.items():
- data += ' "%s": %s,\n' % (key,
self._value_to_str(value))
- return data + ' }\n'
-
- def _value_to_str(self, value):
- if type(value) is StringType:
- return '"""%s"""' % (value)
- elif type(value) is ListType:
- string_values = [self._value_to_str(item) for item in value ]
- return "[ %s ]" % (', '.join(string_values))
- return value
-
+ self._user_settings.write_settings(self.settings)
+
def __getitem__(self, name):
return self.settings[name]
def __setitem__(self, name, value):
self.settings[name] = value
-
def load_settings(self):
from defaultsettings import default_settings
self.settings = default_settings.copy()
@@ -79,21 +57,17 @@
except (ImportError, KeyError):
pass
try:
- import mabotsettings
- reload(mabotsettings)
- for key in mabotsettings.settings.keys():
- self.settings[key] = mabotsettings.settings[key]
- except (ImportError, KeyError):
+ user_settings = self._user_settings.read_settings()
+ except (utils.MissingSettings, utils.InvalidSettings):
pass
+ else:
+ for key in user_settings.keys():
+ self.settings[key] = user_settings[key]
+
def restore_settings(self):
- self._remove_user_settings()
+ self._user_settings.remove_settings()
self.load_settings()
- def _remove_user_settings(self):
- if os.path.exists(USER_SETTINGS_FILE):
- os.remove(USER_SETTINGS_FILE)
- if os.path.exists(COMPILED_USER_SETTINGS_FILE):
- os.remove(COMPILED_USER_SETTINGS_FILE)
SETTINGS = Settings()
Modified: trunk/src/mabot/settings/utils.py
==============================================================================
--- trunk/src/mabot/settings/utils.py (original)
+++ trunk/src/mabot/settings/utils.py Wed May 20 03:49:40 2009
@@ -1,4 +1,8 @@
import os
+from pprint import pprint
+import sys
+
+
if os.name == 'nt':
SETTINGS_DIRECTORY =
os.path.join(os.environ['APPDATA'], 'RobotFramework')
else:
@@ -12,3 +16,66 @@
if not file_name:
return SETTINGS_DIRECTORY
return os.path.join(SETTINGS_DIRECTORY, file_name)
+
+
+class MissingSettings(Exception):
+ """ Used when setting file does not exist."""
+
+
+class InvalidSettings(Exception):
+ """ Used when setting file exists, but it is not a valid Python
file."""
+
+
+class SettingsIO:
+
+ def __init__(self, path):
+ self.path = path
+ sys.path.insert(0, os.path.dirname(self.path))
+ self._settings_module_name = os.path.basename(self.path)[:-3]
+
+
+ def write_settings(self, settings_dict):
+ """ Writes given settings dict to settings file.
+
+ Setting names (keys) should not contain spaces.
+ """
+ self._validate_setting_names(settings_dict)
+ # settings can be read from old pyc if reading happens in the same
second
+ self.remove_settings()
+ out = open(self.path, 'w')
+ for key in settings_dict.keys():
+ out.write('%s = ' % key)
+ pprint(settings_dict[key], out)
+ out.close()
+
+ def remove_settings(self):
+ for path in [self.path, '%sc' % self.path]:
+ if os.path.exists(path):
+ os.remove(path)
+
+ def _validate_setting_names(self, settings_dict):
+ for name in settings_dict.keys():
+ if ' ' in name:
+ msg = "Setting name '%s' contains space." % (name)
+ raise InvalidSettings(msg)
+
+ def read_settings(self):
+ settings_module = self._load_settings_module()
+ settings = {}
+ for item in dir(settings_module):
+ if not item.startswith('_'):
+ settings[item] = getattr(settings_module, item)
+ return settings
+
+ def _load_settings_module(self):
+ try:
+ settings_module = __import__(self._settings_module_name)
+ settings_module = reload(settings_module)
+ except ImportError:
+ message = "Could not import settings file '%s'" % self.path
+ raise MissingSettings(message)
+ except SyntaxError, e:
+ message = "Settings file '%s' is not a valid Python file.\n%s"
+ message = message % (self.path, e)
+ raise InvalidSettings(message)
+ return settings_module
Modified: trunk/utest/test_settings.py
==============================================================================
--- trunk/utest/test_settings.py (original)
+++ trunk/utest/test_settings.py Wed May 20 03:49:40 2009
@@ -19,7 +19,6 @@
from mabot.settings import Settings
from mabot.settings.defaultsettings import default_settings
from mabot.settings import USER_SETTINGS_FILE
-from mabot.settings import COMPILED_USER_SETTINGS_FILE
class TestSettings(unittest.TestCase):
@@ -29,10 +28,9 @@
self.settings = Settings()
def _remove_settings(self):
- if os.path.exists(USER_SETTINGS_FILE):
- os.remove(USER_SETTINGS_FILE)
- if os.path.exists(COMPILED_USER_SETTINGS_FILE):
- os.remove(COMPILED_USER_SETTINGS_FILE)
+ for path in [USER_SETTINGS_FILE, '%sc' % USER_SETTINGS_FILE ]:
+ if os.path.exists(path):
+ os.remove(path)
def tearDown(self):
self._remove_settings()
@@ -47,23 +45,21 @@
def test_saving_with_default_settings(self):
self.settings.save_settings()
- settings = self._import_settings()
- reload(settings)
- self.assertEquals(self.settings.settings, settings.settings)
+ self.assertEquals(self.settings.settings,
+ self._read_settings_from_file())
def test_saving_with_modified_settings(self):
self.settings.save_settings()
- settings = self._import_settings()
- reload(settings)
- self.assertEquals(self.settings.settings, settings.settings)
+ settings = self._read_settings_from_file()
+ self.assertEquals(self.settings.settings, settings)
self.settings.settings["default_message"] = "My message"
self.settings.settings["exclude"] = ["a", "b", "c"]
self.settings.save_settings()
- reload(settings)
- self.assertEquals(self.settings.settings, settings.settings)
+ settings = self._read_settings_from_file()
+ self.assertEquals(self.settings.settings, settings)
self.assertEquals(self.settings.settings["exclude"],
["a", "b", "c"])
self.settings.load_settings()
- self.assertEquals(self.settings.settings, settings.settings)
+ self.assertEquals(self.settings.settings, settings)
def test_reverting_default_settings(self):
defaults = self.settings.settings.copy()
@@ -76,13 +72,14 @@
self.assertEquals(self.settings.settings, defaults)
self.assertFalse(os.path.exists(USER_SETTINGS_FILE))
- def _import_settings(self):
- if os.sep == '\\':
- from mabot.settings import settings
- else:
- import settings
- return settings
-
+ def _read_settings_from_file(self):
+ import mabotsettings
+ reload(mabotsettings)
+ settings = {}
+ for item in dir(mabotsettings):
+ if not item.startswith('_'):
+ settings[item] = getattr(mabotsettings, item)
+ return settings
if __name__ == "__main__":
unittest.main()
Added: trunk/utest/test_settings_utils.py
==============================================================================
--- (empty file)
+++ trunk/utest/test_settings_utils.py Wed May 20 03:49:40 2009
@@ -0,0 +1,100 @@
+# Copyright 2008 Nokia Siemens Networks Oyj
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import sys
+import unittest
+
+from mabot.settings.utils import SettingsIO, MissingSettings,
InvalidSettings
+
+
+class TestSettingsIO(unittest.TestCase):
+
+ def setUp(self):
+ self.settings_file =
os.path.join(os.path.dirname(__file__), 'data',
+ 'testsettings.py')
+ self.settings = SettingsIO(self.settings_file)
+
+ def tearDown(self):
+ sys.path.pop(0)
+ self.settings.remove_settings()
+
+ # Note: This tests needs to be first (aaa) before setting module is
imported.
+ def test_aaa_no_settings_exists(self):
+ self.assertRaises(MissingSettings, self.settings.read_settings)
+
+ def test_settings_does_not_exist_anymore(self):
+ self._test_settings_io({'string':'value'})
+ self.settings.remove_settings()
+ self.assertRaises(MissingSettings, self.settings.read_settings)
+
+ def test_invalid_settings_exists(self):
+ f = open(self.settings_file, 'w')
+ f.write('foo = invalid syntax::')
+ f.close()
+ self.assertRaises(InvalidSettings, self.settings.read_settings)
+
+ def test_setting_name_with_spaces(self):
+ self.assertRaises(InvalidSettings, self._test_settings_io,
+ {'setting name spaces': 'value'})
+
+ def test_writing_string_setting(self):
+ self._test_settings_io({'string':'value'})
+
+ def test_writing_unicode_setting(self):
+ self._test_settings_io({'unicode_string':u'non-ascii character
\xe4'})
+
+ def test_writing_list_setting(self):
+ self._test_settings_io({'unicode_string': [1, 'string',
+ u'non-ascii character
\xe4']})
+
+ def test_writing_dictionary_setting(self):
+ self._test_settings_io({'dictionary': {'a': 1, 'b': 2, 'c': 3}})
+
+ def test_writing_none_setting(self):
+ self._test_settings_io({'none': None})
+
+ def test_writing_boolean_setting(self):
+ self._test_settings_io({'boolean': True})
+
+ def test_writing_multiline_string_setting(self):
+ multiline = u"""Multi line string
+with non-ascii chars \xe4
+and quotes "foo" 'bar'
+and even triple quotes \"\"\" '''
+"""
+ self._test_settings_io({'multiline': multiline})
+
+ def test_multiple_settings(self):
+ multiline = u"""Multi line string
+with non-ascii chars \xe4
+and quotes "foo" 'bar'
+and even triple quotes \"\"\" '''
+"""
+ self._test_settings_io({'multiline': multiline, 'string': u'some',
+ 'bool': False, 'int':1, 'float':2.4})
+
+ def test_updating_setting(self):
+ self._test_settings_io({'string': u'some', 'bool': False, 'int':1})
+ self.settings.write_settings({'string': u'new', 'bool':
True, 'int':1})
+ self._test_settings_io({'string': u'new', 'bool': False, 'int':4})
+
+ def _test_settings_io(self, expected):
+ self.settings.write_settings(expected)
+ actual = self.settings.read_settings()
+ for key in expected.keys():
+ self.assertEqual(expected[key], actual[key])
+
+if __name__ == "__main__":
+ unittest.main()
\ No newline at end of file