summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Dennis <rdennis@gmail.com>2014-03-12 22:19:40 -0400
committerRob Dennis <rdennis@gmail.com>2014-03-12 22:19:40 -0400
commite67de2f163eb17f664f661ad76069dbafddead7e (patch)
tree1c208973ce966ce83cd7c50ca0e5c9080ada02f7
parent2d16e07d766958fb11c21e3274ed7022ccedb9f9 (diff)
parent715b26cac0623a510bf1afe478857487aab861a1 (diff)
downloadconfigobj-git-e67de2f163eb17f664f661ad76069dbafddead7e.tar.gz
Merge pull request #41 from robdennis/master
#14 - moved over a bunch more tests
-rw-r--r--test_configobj.py202
-rw-r--r--tests/conftest.py14
-rw-r--r--tests/test_configobj.py88
-rw-r--r--tests/test_validate.py163
-rw-r--r--tox.ini3
5 files changed, 240 insertions, 230 deletions
diff --git a/test_configobj.py b/test_configobj.py
index 00279ab..96d19b7 100644
--- a/test_configobj.py
+++ b/test_configobj.py
@@ -30,204 +30,16 @@ INTP_VER = sys.version_info[:2]
if INTP_VER < (2, 2):
raise RuntimeError("Python v.2.2 or later needed")
-try:
- from codecs import BOM_UTF8
-except ImportError:
- # Python 2.2 does not have this
- # UTF-8
- BOM_UTF8 = '\xef\xbb\xbf'
+from codecs import BOM_UTF8
from configobj import *
from validate import Validator, VdtValueTooSmallError
-def _test_configobj():
- """
- Testing ConfigObj
-
- Test indentation handling
-
- >>> ConfigObj({'sect': {'sect': {'foo': 'bar'}}}).write()
- ['[sect]', ' [[sect]]', ' foo = bar']
- >>> cfg = ['[sect]', '[[sect]]', 'foo = bar']
- >>> ConfigObj(cfg).write() == cfg
- 1
- >>> cfg = ['[sect]', ' [[sect]]', ' foo = bar']
- >>> ConfigObj(cfg).write() == cfg
- 1
- >>> cfg = ['[sect]', ' [[sect]]', ' foo = bar']
- >>> assert ConfigObj(cfg).write() == cfg
- >>> assert ConfigObj(oneTabCfg).write() == oneTabCfg
- >>> assert ConfigObj(twoTabsCfg).write() == twoTabsCfg
- >>> assert ConfigObj(tabsAndSpacesCfg).write() == [s.decode('utf-8') for s in tabsAndSpacesCfg]
- >>> assert ConfigObj(cfg, indent_type=chr(9)).write() == oneTabCfg
- >>> assert ConfigObj(oneTabCfg, indent_type=' ').write() == cfg
- """
-
-
def _test_validate():
"""
- >>> config = '''
- ... test1=40
- ... test2=hello
- ... test3=3
- ... test4=5.0
- ... [section]
- ... test1=40
- ... test2=hello
- ... test3=3
- ... test4=5.0
- ... [[sub section]]
- ... test1=40
- ... test2=hello
- ... test3=3
- ... test4=5.0
- ... '''.split('\\n')
- >>> configspec = '''
- ... test1= integer(30,50)
- ... test2= string
- ... test3=integer
- ... test4=float(6.0)
- ... [section ]
- ... test1=integer(30,50)
- ... test2=string
- ... test3=integer
- ... test4=float(6.0)
- ... [[sub section]]
- ... test1=integer(30,50)
- ... test2=string
- ... test3=integer
- ... test4=float(6.0)
- ... '''.split('\\n')
>>> val = Validator()
- >>> c1 = ConfigObj(config, configspec=configspec)
- >>> test = c1.validate(val)
- >>> test == {
- ... 'test1': True,
- ... 'test2': True,
- ... 'test3': True,
- ... 'test4': False,
- ... 'section': {
- ... 'test1': True,
- ... 'test2': True,
- ... 'test3': True,
- ... 'test4': False,
- ... 'sub section': {
- ... 'test1': True,
- ... 'test2': True,
- ... 'test3': True,
- ... 'test4': False,
- ... },
- ... },
- ... }
- 1
- >>> val.check(c1.configspec['test4'], c1['test4'])
- Traceback (most recent call last):
- VdtValueTooSmallError: the value "5.0" is too small.
-
- >>> val_test_config = '''
- ... key = 0
- ... key2 = 1.1
- ... [section]
- ... key = some text
- ... key2 = 1.1, 3.0, 17, 6.8
- ... [[sub-section]]
- ... key = option1
- ... key2 = True'''.split('\\n')
- >>> val_test_configspec = '''
- ... key = integer
- ... key2 = float
- ... [section]
- ... key = string
- ... key2 = float_list(4)
- ... [[sub-section]]
- ... key = option(option1, option2)
- ... key2 = boolean'''.split('\\n')
- >>> val_test = ConfigObj(val_test_config, configspec=val_test_configspec)
- >>> val_test.validate(val)
- 1
- >>> val_test['key'] = 'text not a digit'
- >>> val_res = val_test.validate(val)
- >>> val_res == {'key2': True, 'section': True, 'key': False}
- 1
- >>> configspec = '''
- ... test1=integer(30,50, default=40)
- ... test2=string(default="hello")
- ... test3=integer(default=3)
- ... test4=float(6.0, default=6.0)
- ... [section ]
- ... test1=integer(30,50, default=40)
- ... test2=string(default="hello")
- ... test3=integer(default=3)
- ... test4=float(6.0, default=6.0)
- ... [[sub section]]
- ... test1=integer(30,50, default=40)
- ... test2=string(default="hello")
- ... test3=integer(default=3)
- ... test4=float(6.0, default=6.0)
- ... '''.split('\\n')
- >>> default_test = ConfigObj(['test1=30'], configspec=configspec)
- >>> default_test
- ConfigObj({'test1': '30'})
- >>> default_test.defaults
- []
- >>> default_test.default_values
- {}
- >>> default_test.validate(val)
- 1
- >>> default_test == {
- ... 'test1': 30,
- ... 'test2': 'hello',
- ... 'test3': 3,
- ... 'test4': 6.0,
- ... 'section': {
- ... 'test1': 40,
- ... 'test2': 'hello',
- ... 'test3': 3,
- ... 'test4': 6.0,
- ... 'sub section': {
- ... 'test1': 40,
- ... 'test3': 3,
- ... 'test2': 'hello',
- ... 'test4': 6.0,
- ... },
- ... },
- ... }
- 1
- >>> default_test.defaults
- ['test2', 'test3', 'test4']
- >>> default_test.default_values == {'test1': 40, 'test2': 'hello',
- ... 'test3': 3, 'test4': 6.0}
- 1
- >>> default_test.restore_default('test1')
- 40
- >>> default_test['test1']
- 40
- >>> 'test1' in default_test.defaults
- 1
- >>> def change(section, key):
- ... section[key] = 3
- >>> _ = default_test.walk(change)
- >>> default_test['section']['sub section']['test4']
- 3
- >>> default_test.restore_defaults()
- >>> default_test == {
- ... 'test1': 40,
- ... 'test2': "hello",
- ... 'test3': 3,
- ... 'test4': 6.0,
- ... 'section': {
- ... 'test1': 40,
- ... 'test2': "hello",
- ... 'test3': 3,
- ... 'test4': 6.0,
- ... 'sub section': {
- ... 'test1': 40,
- ... 'test2': "hello",
- ... 'test3': 3,
- ... 'test4': 6.0
- ... }}}
- 1
+
>>> a = ['foo = fish']
>>> b = ['foo = integer(default=3)']
>>> c = ConfigObj(a, configspec=b)
@@ -1230,9 +1042,9 @@ if __name__ == '__main__':
#
# these cannot be put among the doctests, because the doctest module
# does a string.expandtabs() on all of them, sigh
- oneTabCfg = ['[sect]', '\t[[sect]]', '\t\tfoo = bar']
- twoTabsCfg = ['[sect]', '\t\t[[sect]]', '\t\t\t\tfoo = bar']
- tabsAndSpacesCfg = [b'[sect]', b'\t \t [[sect]]', b'\t \t \t \t foo = bar']
+ # oneTabCfg = ['[sect]', '\t[[sect]]', '\t\tfoo = bar']
+ # twoTabsCfg = ['[sect]', '\t\t[[sect]]', '\t\t\t\tfoo = bar']
+ # tabsAndSpacesCfg = [b'[sect]', b'\t \t [[sect]]', b'\t \t \t \t foo = bar']
#
import doctest
m = sys.modules.get('__main__')
@@ -1240,9 +1052,7 @@ if __name__ == '__main__':
a = ConfigObj(testconfig1.split('\n'), raise_errors=True)
b = ConfigObj(testconfig2.split(b'\n'), raise_errors=True)
i = ConfigObj(testconfig6.split(b'\n'), raise_errors=True)
- globs.update({'INTP_VER': INTP_VER, 'a': a, 'b': b, 'i': i,
- 'oneTabCfg': oneTabCfg, 'twoTabsCfg': twoTabsCfg,
- 'tabsAndSpacesCfg': tabsAndSpacesCfg})
+ globs.update({'INTP_VER': INTP_VER, 'a': a, 'b': b, 'i': i})
pre_failures, pre_tests = doctest.testmod(
m, globs=globs,
optionflags=doctest.IGNORE_EXCEPTION_DETAIL | doctest.ELLIPSIS)
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..e11ad40
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,14 @@
+# coding=utf-8
+import pytest
+
+from configobj import ConfigObj
+from validate import Validator
+
+@pytest.fixture
+def empty_cfg():
+ return ConfigObj()
+
+
+@pytest.fixture
+def val():
+ return Validator()
diff --git a/tests/test_configobj.py b/tests/test_configobj.py
index d8a1140..f4f9a31 100644
--- a/tests/test_configobj.py
+++ b/tests/test_configobj.py
@@ -1,3 +1,4 @@
+# coding=utf-8
import os
from codecs import BOM_UTF8
from warnings import catch_warnings
@@ -131,16 +132,6 @@ test = some string
@pytest.fixture
-def cfg():
- return ConfigObj()
-
-
-@pytest.fixture
-def val():
- return Validator()
-
-
-@pytest.fixture
def testconfig1():
"""
copied from the main doctest
@@ -218,7 +209,6 @@ def testconfig6():
'''
-
@pytest.fixture
def a(testconfig1):
"""
@@ -528,36 +518,36 @@ class TestUnrepr(object):
class TestValueErrors(object):
- def test_bool(self, cfg):
- cfg['a'] = 'fish'
+ def test_bool(self, empty_cfg):
+ empty_cfg['a'] = 'fish'
with pytest.raises(ValueError) as excinfo:
- cfg.as_bool('a')
+ empty_cfg.as_bool('a')
assert str(excinfo.value) == 'Value "fish" is neither True nor False'
- cfg['b'] = 'True'
- assert cfg.as_bool('b') is True
- cfg['b'] = 'off'
- assert cfg.as_bool('b') is False
+ empty_cfg['b'] = 'True'
+ assert empty_cfg.as_bool('b') is True
+ empty_cfg['b'] = 'off'
+ assert empty_cfg.as_bool('b') is False
- def test_int(self, cfg):
+ def test_int(self, empty_cfg):
for bad in ('fish', '3.2'):
- cfg['a'] = bad
+ empty_cfg['a'] = bad
with pytest.raises(ValueError) as excinfo:
- cfg.as_int('a')
+ empty_cfg.as_int('a')
assert str(excinfo.value).startswith('invalid literal for int()')
- cfg['b'] = '1'
- assert cfg.as_bool('b') is True
- cfg['b'] = '3.2'
+ empty_cfg['b'] = '1'
+ assert empty_cfg.as_bool('b') is True
+ empty_cfg['b'] = '3.2'
- def test_float(self, cfg):
- cfg['a'] = 'fish'
+ def test_float(self, empty_cfg):
+ empty_cfg['a'] = 'fish'
with pytest.raises(ValueError):
- cfg.as_float('a')
+ empty_cfg.as_float('a')
- cfg['b'] = '1'
- assert cfg.as_float('b') == 1
- cfg['b'] = '3.2'
- assert cfg.as_float('b') == 3.2
+ empty_cfg['b'] = '1'
+ assert empty_cfg.as_float('b') == 1
+ empty_cfg['b'] = '3.2'
+ assert empty_cfg.as_float('b') == 3.2
@@ -886,11 +876,11 @@ class TestQuotes(object):
"""
tests what happens whn dealing with quotes
"""
- def assert_bad_quote_message(self, cfg, to_quote, **kwargs):
+ def assert_bad_quote_message(self, empty_cfg, to_quote, **kwargs):
#TODO: this should be use repr instead of str
message = 'Value "{0}" cannot be safely quoted.'
with pytest.raises(ConfigObjError) as excinfo:
- cfg._quote(to_quote, **kwargs)
+ empty_cfg._quote(to_quote, **kwargs)
assert str(excinfo.value) == message.format(to_quote)
def test_handle_unbalanced(self, i):
@@ -1084,3 +1074,35 @@ def test_interpolation_using_default_sections():
c['DEFAULT'] = {'a' : 'fish'}
c['a'] = '%(a)s'
assert c.write() == ['a = %(a)s', '[DEFAULT]', 'a = fish']
+
+
+class TestIndentation(object):
+ @pytest.fixture
+ def max_tabbed_cfg(self):
+ return ['[sect]', ' [[sect]]', ' foo = bar']
+
+ def test_write_dictionary(self):
+ assert ConfigObj({'sect': {'sect': {'foo': 'bar'}}}).write() == [
+ '[sect]', ' [[sect]]', ' foo = bar'
+ ]
+
+ def test_indentation_preserved(self, max_tabbed_cfg):
+ for cfg_content in (
+ ['[sect]', '[[sect]]', 'foo = bar'],
+ ['[sect]', ' [[sect]]', ' foo = bar'],
+ max_tabbed_cfg
+ ):
+ assert ConfigObj(cfg_content).write() == cfg_content
+
+ def test_handle_tabs_vs_spaces(self, max_tabbed_cfg):
+ one_tab = ['[sect]', '\t[[sect]]', '\t\tfoo = bar']
+ two_tabs = ['[sect]', '\t\t[[sect]]', '\t\t\t\tfoo = bar']
+ tabs_and_spaces = [b'[sect]', b'\t \t [[sect]]',
+ b'\t \t \t \t foo = bar']
+
+ assert ConfigObj(one_tab).write() == one_tab
+ assert ConfigObj(two_tabs).write() == two_tabs
+ assert ConfigObj(tabs_and_spaces).write() == [s.decode('utf-8') for s in tabs_and_spaces]
+ assert ConfigObj(max_tabbed_cfg, indent_type=chr(9)).write() == one_tab
+ assert ConfigObj(one_tab, indent_type=' ').write() == max_tabbed_cfg
+
diff --git a/tests/test_validate.py b/tests/test_validate.py
new file mode 100644
index 0000000..bffb0dc
--- /dev/null
+++ b/tests/test_validate.py
@@ -0,0 +1,163 @@
+# coding=utf-8
+
+from configobj import ConfigObj
+import pytest
+from validate import Validator, VdtValueTooSmallError
+
+
+class TestBasic(object):
+ def test_values_too_small(self, val):
+ config = '''
+ test1=40
+ test2=hello
+ test3=3
+ test4=5.0
+ [section]
+ test1=40
+ test2=hello
+ test3=3
+ test4=5.0
+ [[sub section]]
+ test1=40
+ test2=hello
+ test3=3
+ test4=5.0
+ '''.splitlines()
+ configspec = '''
+ test1= integer(30,50)
+ test2= string
+ test3=integer
+ test4=float(6.0)
+ [section ]
+ test1=integer(30,50)
+ test2=string
+ test3=integer
+ test4=float(6.0)
+ [[sub section]]
+ test1=integer(30,50)
+ test2=string
+ test3=integer
+ test4=float(6.0)
+ '''.splitlines()
+ c1 = ConfigObj(config, configspec=configspec)
+ test = c1.validate(val)
+ assert test == {
+ 'test1': True,
+ 'test2': True,
+ 'test3': True,
+ 'test4': False,
+ 'section': {
+ 'test1': True,
+ 'test2': True,
+ 'test3': True,
+ 'test4': False,
+ 'sub section': {
+ 'test1': True,
+ 'test2': True,
+ 'test3': True,
+ 'test4': False,
+ },
+ },
+ }
+
+ with pytest.raises(VdtValueTooSmallError) as excinfo:
+ val.check(c1.configspec['test4'], c1['test4'])
+ assert str(excinfo.value) == 'the value "5.0" is too small.'
+
+ def test_values(self, val):
+ val_test_config = '''
+ key = 0
+ key2 = 1.1
+ [section]
+ key = some text
+ key2 = 1.1, 3.0, 17, 6.8
+ [[sub-section]]
+ key = option1
+ key2 = True'''.splitlines()
+ val_test_configspec = '''
+ key = integer
+ key2 = float
+ [section]
+ key = string
+ key2 = float_list(4)
+ [[sub-section]]
+ key = option(option1, option2)
+ key2 = boolean'''.splitlines()
+ val_test = ConfigObj(val_test_config, configspec=val_test_configspec)
+ assert val_test.validate(val)
+ val_test['key'] = 'text not a digit'
+ val_res = val_test.validate(val)
+ assert val_res == {'key2': True, 'section': True, 'key': False}
+
+ def test_defaults(self, val):
+ configspec = '''
+ test1=integer(30,50, default=40)
+ test2=string(default="hello")
+ test3=integer(default=3)
+ test4=float(6.0, default=6.0)
+ [section ]
+ test1=integer(30,50, default=40)
+ test2=string(default="hello")
+ test3=integer(default=3)
+ test4=float(6.0, default=6.0)
+ [[sub section]]
+ test1=integer(30,50, default=40)
+ test2=string(default="hello")
+ test3=integer(default=3)
+ test4=float(6.0, default=6.0)
+ '''.splitlines()
+ default_test = ConfigObj(['test1=30'], configspec=configspec)
+ assert repr(default_test) == "ConfigObj({'test1': '30'})"
+ assert default_test.defaults == []
+ assert default_test.default_values == {}
+ assert default_test.validate(val)
+ assert default_test == {
+ 'test1': 30,
+ 'test2': 'hello',
+ 'test3': 3,
+ 'test4': 6.0,
+ 'section': {
+ 'test1': 40,
+ 'test2': 'hello',
+ 'test3': 3,
+ 'test4': 6.0,
+ 'sub section': {
+ 'test1': 40,
+ 'test3': 3,
+ 'test2': 'hello',
+ 'test4': 6.0,
+ },
+ },
+ }
+
+ assert default_test.defaults == ['test2', 'test3', 'test4']
+ assert default_test.default_values == {
+ 'test1': 40, 'test2': 'hello',
+ 'test3': 3, 'test4': 6.0
+ }
+ assert default_test.restore_default('test1') == 40
+ assert default_test['test1'] == 40
+ assert 'test1' in default_test.defaults
+
+ def change(section, key):
+ section[key] = 3
+ default_test.walk(change)
+ assert default_test['section']['sub section']['test4'] == 3
+
+ default_test.restore_defaults()
+ assert default_test == {
+ 'test1': 40,
+ 'test2': "hello",
+ 'test3': 3,
+ 'test4': 6.0,
+ 'section': {
+ 'test1': 40,
+ 'test2': "hello",
+ 'test3': 3,
+ 'test4': 6.0,
+ 'sub section': {
+ 'test1': 40,
+ 'test2': "hello",
+ 'test3': 3,
+ 'test4': 6.0
+ }}}
diff --git a/tox.ini b/tox.ini
index 0453810..1d71631 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,4 +8,5 @@ setenv =
PYTHONWARNINGS = always
commands=python test_configobj.py
python validate.py
- py.test tests --cov-report term-missing --cov configobj.py --cov validate.py
+ coverage run --source=configobj.py,validate.py -m py.test tests
+ coverage report