Skip to content

Commit 27e81f7

Browse files
Expands ProfileManager and profile unit tests
Methods for deleting, creating, and listing profiles. Also modifies get_profile by adding an extra arg to specify whether a non- existing profile should be auto-created. Adds unit tests to test_profile. Methods added: - create - list_profiles - delete Related to Freeseer#632
1 parent 19c85be commit 27e81f7

File tree

2 files changed

+127
-12
lines changed

2 files changed

+127
-12
lines changed

src/freeseer/framework/config/profile.py

+81-6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
# http://wiki.github.com/Freeseer/freeseer/
2424

2525
import os
26+
import shutil
2627

2728
from freeseer.framework.config.persist import ConfigParserStorage
2829
from freeseer.framework.config.persist import JSONConfigStorage
@@ -45,17 +46,79 @@ def _create_if_needed(self, path):
4546
# This is thrown if path already exists.
4647
pass
4748

48-
def get(self, name='default'):
49-
"""Retrieve Profile instances by name.
49+
def get(self, name='default', create_if_needed=True):
50+
"""
51+
Retrieve Profile instances by name. Profiles are cached for future gets.
52+
53+
Args:
54+
name: The name of the profile.
55+
create_if_needed: When True, get creates a new profile instance
56+
if profile for given name doesn't exist.
5057
51-
Profiles are cached for future gets.
58+
Returns:
59+
The instance of Profile for the given name.
60+
61+
Raises:
62+
ProfileDoesNotExist: If create_if_needed==False and
63+
the given profile name doesn't exist.
5264
"""
53-
if name not in self._cache:
65+
if name in self._cache:
66+
return self._cache[name]
67+
else:
5468
full_path = os.path.join(self._base_folder, name)
55-
self._create_if_needed(full_path)
56-
self._cache[name] = Profile(full_path, name)
69+
if os.path.exists(full_path):
70+
self._cache[name] = Profile(full_path, name)
71+
return self._cache[name]
72+
elif create_if_needed:
73+
return self.create(name)
74+
75+
raise ProfileDoesNotExist(name)
76+
77+
def create(self, name):
78+
"""
79+
Creates a new Profile on file and adds it to the cache.
80+
81+
Args:
82+
name: The name of the profile to create.
83+
84+
Returns:
85+
The instance for the created Profile.
86+
87+
Raises:
88+
ProfileAlreadyExists: If a profile by the same name exists.
89+
"""
90+
path = os.path.join(self._base_folder, name)
91+
try:
92+
os.makedirs(path)
93+
except OSError:
94+
raise ProfileAlreadyExists(name)
95+
96+
self._cache[name] = Profile(path, name)
5797
return self._cache[name]
5898

99+
def list_profiles(self):
100+
"""Returns a list of available profiles on file."""
101+
return os.listdir(self._base_folder)
102+
103+
def delete(self, name):
104+
"""
105+
Deletes a profile and its configuration files from disk and cache.
106+
107+
Args:
108+
name: The name of the profile to delete.
109+
110+
Raises:
111+
ProfileDoesNotExist: If no profile exists for give name.
112+
"""
113+
path = os.path.join(self._base_folder, name)
114+
try:
115+
shutil.rmtree(path)
116+
del self._cache[name]
117+
except OSError:
118+
raise ProfileDoesNotExist(name)
119+
except KeyError:
120+
pass
121+
59122

60123
class Profile(object):
61124
"""Represents a profile's config files, databases, and other stuff."""
@@ -129,3 +192,15 @@ def get_database(self, name='presentations.db'):
129192
if name not in self._databases:
130193
self._databases[name] = QtDBConnector(self.get_filepath(name), PluginManager(self))
131194
return self._databases[name]
195+
196+
197+
class ProfileAlreadyExists(Exception):
198+
def __init__(self, value):
199+
message = 'Profile already exists: "{}"'.format(value)
200+
super(Exception, self).__init__(message)
201+
202+
203+
class ProfileDoesNotExist(Exception):
204+
def __init__(self, value):
205+
message = 'Profile does not exist: "{}"'.format(value)
206+
super(Exception, self).__init__(message)

src/freeseer/tests/framework/config/test_profile.py

+46-6
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,10 @@
2626
import tempfile
2727
import unittest
2828

29-
from freeseer.framework.config import Config
30-
from freeseer.framework.config import options
29+
from freeseer.framework.config import Config, options
3130
from freeseer.framework.config.exceptions import StorageNotSetError
32-
from freeseer.framework.config.persist import ConfigParserStorage
33-
from freeseer.framework.config.persist import JSONConfigStorage
34-
from freeseer.framework.config.profile import Profile
35-
from freeseer.framework.config.profile import ProfileManager
31+
from freeseer.framework.config.persist import ConfigParserStorage, JSONConfigStorage
32+
from freeseer.framework.config.profile import Profile, ProfileAlreadyExists, ProfileDoesNotExist, ProfileManager
3633
from freeseer.framework.database import QtDBConnector
3734

3835

@@ -56,12 +53,55 @@ def test_get(self):
5653
profile = self.profile_manager.get('testing')
5754
self.assertIsInstance(profile, Profile)
5855

56+
def test_get_non_existent(self):
57+
"""Test for non-existent profile."""
58+
self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'non-existent_profile', create_if_needed=False)
59+
60+
def test_get_non_existent_creates(self):
61+
"""Test that get creates non-existent profile if create_if_needed=True."""
62+
self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'non-existent_profile', create_if_needed=False)
63+
profile = self.profile_manager.get('non_existent_profile')
64+
self.assertIsInstance(profile, Profile)
65+
5966
def test_get_cache(self):
6067
"""Tests that get caching is working as expected."""
6168
profile1 = self.profile_manager.get('testing')
6269
profile2 = self.profile_manager.get('testing')
6370
self.assertEqual(profile1, profile2)
6471

72+
def test_list_profiles(self):
73+
"""Tests that list_profiles returns all profiles on file."""
74+
self.profile_manager.create('testing1')
75+
self.profile_manager.create('testing2')
76+
profiles = self.profile_manager.list_profiles()
77+
self.assertItemsEqual(['testing1', 'testing2'], profiles)
78+
79+
def test_create_profile(self):
80+
"""Tests that create_profile returns an instance of Profile.."""
81+
profile = self.profile_manager.create('testing1')
82+
self.assertIsInstance(profile, Profile)
83+
84+
def test_create_profile_existing(self):
85+
"""Tests that exception is raised if trying to overwrite existing profile."""
86+
self.profile_manager.create('testing1')
87+
self.assertRaises(ProfileAlreadyExists, self.profile_manager.create, 'testing1')
88+
89+
def test_create_profile_caches(self):
90+
"""Tests that create_profile adds the new Profile instance to cache."""
91+
self.assertNotIn('testing1', self.profile_manager._cache)
92+
self.profile_manager.create('testing1')
93+
self.assertIn('testing1', self.profile_manager._cache)
94+
95+
def test_delete_profile_existing(self):
96+
"""Tests that delete_profile deletes the profile from cache and file."""
97+
self.profile_manager.create('testing1')
98+
self.profile_manager.delete('testing1')
99+
self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'testing1', create_if_needed=False)
100+
101+
def test_delete_profile_non_existing(self):
102+
"""Non-existent profiles can't be deleted."""
103+
self.assertRaises(ProfileDoesNotExist, self.profile_manager.delete, 'testing')
104+
65105

66106
class TestProfile(unittest.TestCase):
67107
"""Tests Profile."""

0 commit comments

Comments
 (0)