11'''Test idlelib.config.
22
3- Much is tested by opening config dialog live or in test_configdialog.
4- Coverage: 27%
3+ Coverage: 46% (100% for IdleConfParser, IdleUserConfParser*, ConfigChanges).
4+ * Except is OSError clause in Save method.
5+ Much of IdleConf is exercised by ConfigDialog and test_configdialog,
6+ but it should be tested here.
57'''
6- from test .support import captured_stderr
8+ import os
9+ import tempfile
10+ from test .support import captured_stderr , findfile
711import unittest
812from idlelib import config
913
@@ -26,6 +30,161 @@ def tearDownModule():
2630 idleConf .userCfg = usercfg
2731
2832
33+ class IdleConfParserTest (unittest .TestCase ):
34+ """Test that IdleConfParser works"""
35+
36+ config = """
37+ [one]
38+ one = false
39+ two = true
40+ three = 10
41+
42+ [two]
43+ one = a string
44+ two = true
45+ three = false
46+ """
47+
48+ def test_get (self ):
49+ parser = config .IdleConfParser ('' )
50+ parser .read_string (self .config )
51+ eq = self .assertEqual
52+
53+ # Test with type argument.
54+ self .assertIs (parser .Get ('one' , 'one' , type = 'bool' ), False )
55+ self .assertIs (parser .Get ('one' , 'two' , type = 'bool' ), True )
56+ eq (parser .Get ('one' , 'three' , type = 'int' ), 10 )
57+ eq (parser .Get ('two' , 'one' ), 'a string' )
58+ self .assertIs (parser .Get ('two' , 'two' , type = 'bool' ), True )
59+ self .assertIs (parser .Get ('two' , 'three' , type = 'bool' ), False )
60+
61+ # Test without type should fallback to string.
62+ eq (parser .Get ('two' , 'two' ), 'true' )
63+ eq (parser .Get ('two' , 'three' ), 'false' )
64+
65+ # If option not exist, should return None, or default.
66+ self .assertIsNone (parser .Get ('not' , 'exist' ))
67+ eq (parser .Get ('not' , 'exist' , default = 'DEFAULT' ), 'DEFAULT' )
68+
69+ def test_get_option_list (self ):
70+ parser = config .IdleConfParser ('' )
71+ parser .read_string (self .config )
72+ get_list = parser .GetOptionList
73+ self .assertCountEqual (get_list ('one' ), ['one' , 'two' , 'three' ])
74+ self .assertCountEqual (get_list ('two' ), ['one' , 'two' , 'three' ])
75+ self .assertEqual (get_list ('not exist' ), [])
76+
77+ def test_load_nothing (self ):
78+ parser = config .IdleConfParser ('' )
79+ parser .Load ()
80+ self .assertEqual (parser .sections (), [])
81+
82+ def test_load_file (self ):
83+ # Borrow test/cfgparser.1 from test_configparser.
84+ config_path = findfile ('cfgparser.1' )
85+ parser = config .IdleConfParser (config_path )
86+ parser .Load ()
87+
88+ self .assertEqual (parser .Get ('Foo Bar' , 'foo' ), 'newbar' )
89+ self .assertEqual (parser .GetOptionList ('Foo Bar' ), ['foo' ])
90+
91+
92+ class IdleUserConfParserTest (unittest .TestCase ):
93+ """Test that IdleUserConfParser works"""
94+
95+ def new_parser (self , path = '' ):
96+ return config .IdleUserConfParser (path )
97+
98+ def test_set_option (self ):
99+ parser = self .new_parser ()
100+ parser .add_section ('Foo' )
101+ # Setting new option in existing section should return True.
102+ self .assertTrue (parser .SetOption ('Foo' , 'bar' , 'true' ))
103+ # Setting existing option with same value should return False.
104+ self .assertFalse (parser .SetOption ('Foo' , 'bar' , 'true' ))
105+ # Setting exiting option with new value should return True.
106+ self .assertTrue (parser .SetOption ('Foo' , 'bar' , 'false' ))
107+ self .assertEqual (parser .Get ('Foo' , 'bar' ), 'false' )
108+
109+ # Setting option in new section should create section and return True.
110+ self .assertTrue (parser .SetOption ('Bar' , 'bar' , 'true' ))
111+ self .assertCountEqual (parser .sections (), ['Bar' , 'Foo' ])
112+ self .assertEqual (parser .Get ('Bar' , 'bar' ), 'true' )
113+
114+ def test_remove_option (self ):
115+ parser = self .new_parser ()
116+ parser .AddSection ('Foo' )
117+ parser .SetOption ('Foo' , 'bar' , 'true' )
118+
119+ self .assertTrue (parser .RemoveOption ('Foo' , 'bar' ))
120+ self .assertFalse (parser .RemoveOption ('Foo' , 'bar' ))
121+ self .assertFalse (parser .RemoveOption ('Not' , 'Exist' ))
122+
123+ def test_add_section (self ):
124+ parser = self .new_parser ()
125+ self .assertEqual (parser .sections (), [])
126+
127+ # Should not add duplicate section.
128+ # Configparser raises DuplicateError, IdleParser not.
129+ parser .AddSection ('Foo' )
130+ parser .AddSection ('Foo' )
131+ parser .AddSection ('Bar' )
132+ self .assertCountEqual (parser .sections (), ['Bar' , 'Foo' ])
133+
134+ def test_remove_empty_sections (self ):
135+ parser = self .new_parser ()
136+
137+ parser .AddSection ('Foo' )
138+ parser .AddSection ('Bar' )
139+ parser .SetOption ('Idle' , 'name' , 'val' )
140+ self .assertCountEqual (parser .sections (), ['Bar' , 'Foo' , 'Idle' ])
141+ parser .RemoveEmptySections ()
142+ self .assertEqual (parser .sections (), ['Idle' ])
143+
144+ def test_is_empty (self ):
145+ parser = self .new_parser ()
146+
147+ parser .AddSection ('Foo' )
148+ parser .AddSection ('Bar' )
149+ self .assertTrue (parser .IsEmpty ())
150+ self .assertEqual (parser .sections (), [])
151+
152+ parser .SetOption ('Foo' , 'bar' , 'false' )
153+ parser .AddSection ('Bar' )
154+ self .assertFalse (parser .IsEmpty ())
155+ self .assertCountEqual (parser .sections (), ['Foo' ])
156+
157+ def test_remove_file (self ):
158+ with tempfile .TemporaryDirectory () as tdir :
159+ path = os .path .join (tdir , 'test.cfg' )
160+ parser = self .new_parser (path )
161+ parser .RemoveFile () # Should not raise exception.
162+
163+ parser .AddSection ('Foo' )
164+ parser .SetOption ('Foo' , 'bar' , 'true' )
165+ parser .Save ()
166+ self .assertTrue (os .path .exists (path ))
167+ parser .RemoveFile ()
168+ self .assertFalse (os .path .exists (path ))
169+
170+ def test_save (self ):
171+ with tempfile .TemporaryDirectory () as tdir :
172+ path = os .path .join (tdir , 'test.cfg' )
173+ parser = self .new_parser (path )
174+ parser .AddSection ('Foo' )
175+ parser .SetOption ('Foo' , 'bar' , 'true' )
176+
177+ # Should save to path when config is not empty.
178+ self .assertFalse (os .path .exists (path ))
179+ parser .Save ()
180+ self .assertTrue (os .path .exists (path ))
181+
182+ # Should remove the file from disk when config is empty.
183+ parser .remove_section ('Foo' )
184+ parser .Save ()
185+ self .assertFalse (os .path .exists (path ))
186+
187+
29188class CurrentColorKeysTest (unittest .TestCase ):
30189 """ Test colorkeys function with user config [Theme] and [Keys] patterns.
31190
@@ -179,10 +338,12 @@ def test_save_option(self): # Static function does not touch changes.
179338
180339 def test_save_added (self ):
181340 changes = self .load ()
182- changes .save_all ()
341+ self . assertTrue ( changes .save_all () )
183342 self .assertEqual (usermain ['Msec' ]['mitem' ], 'mval' )
184343 self .assertEqual (userhigh ['Hsec' ]['hitem' ], 'hval' )
185344 self .assertEqual (userkeys ['Ksec' ]['kitem' ], 'kval' )
345+ changes .add_option ('main' , 'Msec' , 'mitem' , 'mval' )
346+ self .assertFalse (changes .save_all ())
186347 usermain .remove_section ('Msec' )
187348 userhigh .remove_section ('Hsec' )
188349 userkeys .remove_section ('Ksec' )
0 commit comments