summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/idle_test
diff options
context:
space:
mode:
authorLouie Lu <git@louie.lu>2017-07-12 18:05:32 (GMT)
committerterryjreedy <tjreedy@udel.edu>2017-07-12 18:05:32 (GMT)
commit50c9435c9b73b39fcf79cc3e58edc58bb943d0ed (patch)
tree19f695e2fb995e613378bf7fee064cff01c4d6f9 /Lib/idlelib/idle_test
parentd1cc037d1442cc35d1b194ec8e50901514360949 (diff)
downloadcpython-50c9435c9b73b39fcf79cc3e58edc58bb943d0ed.zip
cpython-50c9435c9b73b39fcf79cc3e58edc58bb943d0ed.tar.gz
cpython-50c9435c9b73b39fcf79cc3e58edc58bb943d0ed.tar.bz2
bpo-30899: Add unittests, 100% coverage, for IDLE's two ConfigParser subclasses. (#2662)
Patch by Louie Lu.
Diffstat (limited to 'Lib/idlelib/idle_test')
-rw-r--r--Lib/idlelib/idle_test/test_config.py169
1 files changed, 165 insertions, 4 deletions
diff --git a/Lib/idlelib/idle_test/test_config.py b/Lib/idlelib/idle_test/test_config.py
index a8e3a3b..f5a609f 100644
--- a/Lib/idlelib/idle_test/test_config.py
+++ b/Lib/idlelib/idle_test/test_config.py
@@ -1,9 +1,13 @@
'''Test idlelib.config.
-Much is tested by opening config dialog live or in test_configdialog.
-Coverage: 27%
+Coverage: 46% (100% for IdleConfParser, IdleUserConfParser*, ConfigChanges).
+* Except is OSError clause in Save method.
+Much of IdleConf is exercised by ConfigDialog and test_configdialog,
+but it should be tested here.
'''
-from test.support import captured_stderr
+import os
+import tempfile
+from test.support import captured_stderr, findfile
import unittest
from idlelib import config
@@ -26,6 +30,161 @@ def tearDownModule():
idleConf.userCfg = usercfg
+class IdleConfParserTest(unittest.TestCase):
+ """Test that IdleConfParser works"""
+
+ config = """
+ [one]
+ one = false
+ two = true
+ three = 10
+
+ [two]
+ one = a string
+ two = true
+ three = false
+ """
+
+ def test_get(self):
+ parser = config.IdleConfParser('')
+ parser.read_string(self.config)
+ eq = self.assertEqual
+
+ # Test with type argument.
+ self.assertIs(parser.Get('one', 'one', type='bool'), False)
+ self.assertIs(parser.Get('one', 'two', type='bool'), True)
+ eq(parser.Get('one', 'three', type='int'), 10)
+ eq(parser.Get('two', 'one'), 'a string')
+ self.assertIs(parser.Get('two', 'two', type='bool'), True)
+ self.assertIs(parser.Get('two', 'three', type='bool'), False)
+
+ # Test without type should fallback to string.
+ eq(parser.Get('two', 'two'), 'true')
+ eq(parser.Get('two', 'three'), 'false')
+
+ # If option not exist, should return None, or default.
+ self.assertIsNone(parser.Get('not', 'exist'))
+ eq(parser.Get('not', 'exist', default='DEFAULT'), 'DEFAULT')
+
+ def test_get_option_list(self):
+ parser = config.IdleConfParser('')
+ parser.read_string(self.config)
+ get_list = parser.GetOptionList
+ self.assertCountEqual(get_list('one'), ['one', 'two', 'three'])
+ self.assertCountEqual(get_list('two'), ['one', 'two', 'three'])
+ self.assertEqual(get_list('not exist'), [])
+
+ def test_load_nothing(self):
+ parser = config.IdleConfParser('')
+ parser.Load()
+ self.assertEqual(parser.sections(), [])
+
+ def test_load_file(self):
+ # Borrow test/cfgparser.1 from test_configparser.
+ config_path = findfile('cfgparser.1')
+ parser = config.IdleConfParser(config_path)
+ parser.Load()
+
+ self.assertEqual(parser.Get('Foo Bar', 'foo'), 'newbar')
+ self.assertEqual(parser.GetOptionList('Foo Bar'), ['foo'])
+
+
+class IdleUserConfParserTest(unittest.TestCase):
+ """Test that IdleUserConfParser works"""
+
+ def new_parser(self, path=''):
+ return config.IdleUserConfParser(path)
+
+ def test_set_option(self):
+ parser = self.new_parser()
+ parser.add_section('Foo')
+ # Setting new option in existing section should return True.
+ self.assertTrue(parser.SetOption('Foo', 'bar', 'true'))
+ # Setting existing option with same value should return False.
+ self.assertFalse(parser.SetOption('Foo', 'bar', 'true'))
+ # Setting exiting option with new value should return True.
+ self.assertTrue(parser.SetOption('Foo', 'bar', 'false'))
+ self.assertEqual(parser.Get('Foo', 'bar'), 'false')
+
+ # Setting option in new section should create section and return True.
+ self.assertTrue(parser.SetOption('Bar', 'bar', 'true'))
+ self.assertCountEqual(parser.sections(), ['Bar', 'Foo'])
+ self.assertEqual(parser.Get('Bar', 'bar'), 'true')
+
+ def test_remove_option(self):
+ parser = self.new_parser()
+ parser.AddSection('Foo')
+ parser.SetOption('Foo', 'bar', 'true')
+
+ self.assertTrue(parser.RemoveOption('Foo', 'bar'))
+ self.assertFalse(parser.RemoveOption('Foo', 'bar'))
+ self.assertFalse(parser.RemoveOption('Not', 'Exist'))
+
+ def test_add_section(self):
+ parser = self.new_parser()
+ self.assertEqual(parser.sections(), [])
+
+ # Should not add duplicate section.
+ # Configparser raises DuplicateError, IdleParser not.
+ parser.AddSection('Foo')
+ parser.AddSection('Foo')
+ parser.AddSection('Bar')
+ self.assertCountEqual(parser.sections(), ['Bar', 'Foo'])
+
+ def test_remove_empty_sections(self):
+ parser = self.new_parser()
+
+ parser.AddSection('Foo')
+ parser.AddSection('Bar')
+ parser.SetOption('Idle', 'name', 'val')
+ self.assertCountEqual(parser.sections(), ['Bar', 'Foo', 'Idle'])
+ parser.RemoveEmptySections()
+ self.assertEqual(parser.sections(), ['Idle'])
+
+ def test_is_empty(self):
+ parser = self.new_parser()
+
+ parser.AddSection('Foo')
+ parser.AddSection('Bar')
+ self.assertTrue(parser.IsEmpty())
+ self.assertEqual(parser.sections(), [])
+
+ parser.SetOption('Foo', 'bar', 'false')
+ parser.AddSection('Bar')
+ self.assertFalse(parser.IsEmpty())
+ self.assertCountEqual(parser.sections(), ['Foo'])
+
+ def test_remove_file(self):
+ with tempfile.TemporaryDirectory() as tdir:
+ path = os.path.join(tdir, 'test.cfg')
+ parser = self.new_parser(path)
+ parser.RemoveFile() # Should not raise exception.
+
+ parser.AddSection('Foo')
+ parser.SetOption('Foo', 'bar', 'true')
+ parser.Save()
+ self.assertTrue(os.path.exists(path))
+ parser.RemoveFile()
+ self.assertFalse(os.path.exists(path))
+
+ def test_save(self):
+ with tempfile.TemporaryDirectory() as tdir:
+ path = os.path.join(tdir, 'test.cfg')
+ parser = self.new_parser(path)
+ parser.AddSection('Foo')
+ parser.SetOption('Foo', 'bar', 'true')
+
+ # Should save to path when config is not empty.
+ self.assertFalse(os.path.exists(path))
+ parser.Save()
+ self.assertTrue(os.path.exists(path))
+
+ # Should remove the file from disk when config is empty.
+ parser.remove_section('Foo')
+ parser.Save()
+ self.assertFalse(os.path.exists(path))
+
+
class CurrentColorKeysTest(unittest.TestCase):
""" Test colorkeys function with user config [Theme] and [Keys] patterns.
@@ -179,10 +338,12 @@ class ChangesTest(unittest.TestCase):
def test_save_added(self):
changes = self.load()
- changes.save_all()
+ self.assertTrue(changes.save_all())
self.assertEqual(usermain['Msec']['mitem'], 'mval')
self.assertEqual(userhigh['Hsec']['hitem'], 'hval')
self.assertEqual(userkeys['Ksec']['kitem'], 'kval')
+ changes.add_option('main', 'Msec', 'mitem', 'mval')
+ self.assertFalse(changes.save_all())
usermain.remove_section('Msec')
userhigh.remove_section('Hsec')
userkeys.remove_section('Ksec')