##// END OF EJS Templates
Reverse hscrollbar min-height hack on OS X...
Reverse hscrollbar min-height hack on OS X OS X has optional behavior to only draw scrollbars during scroll, which causes problems for CodeMirror's scrollbars. CodeMirror's solution is to set a minimum size for their scrollbars, which is always present. The trade is that the container overlays most of the last line, swallowing click events when there is scrolling to do, even when no scrollbar is visible. This reverses the trade, recovering the click events at the expense of never showing the horizontal scrollbar on OS X when this option is enabled.

File last commit:

r19160:f22c8070
r20298:2907e856
Show More
test_loader.py
404 lines | 11.5 KiB | text/x-python | PythonLexer
# encoding: utf-8
"""Tests for IPython.config.loader"""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
import os
import pickle
import sys
from tempfile import mkstemp
from unittest import TestCase
from nose import SkipTest
import nose.tools as nt
from IPython.config.loader import (
Config,
LazyConfigValue,
PyFileConfigLoader,
JSONFileConfigLoader,
KeyValueConfigLoader,
ArgParseConfigLoader,
KVArgParseConfigLoader,
ConfigError,
)
pyfile = """
c = get_config()
c.a=10
c.b=20
c.Foo.Bar.value=10
c.Foo.Bam.value=list(range(10)) # list() is just so it's the same on Python 3
c.D.C.value='hi there'
"""
json1file = """
{
"version": 1,
"a": 10,
"b": 20,
"Foo": {
"Bam": {
"value": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
},
"Bar": {
"value": 10
}
},
"D": {
"C": {
"value": "hi there"
}
}
}
"""
# should not load
json2file = """
{
"version": 2
}
"""
import logging
log = logging.getLogger('devnull')
log.setLevel(0)
class TestFileCL(TestCase):
def _check_conf(self, config):
self.assertEqual(config.a, 10)
self.assertEqual(config.b, 20)
self.assertEqual(config.Foo.Bar.value, 10)
self.assertEqual(config.Foo.Bam.value, list(range(10)))
self.assertEqual(config.D.C.value, 'hi there')
def test_python(self):
fd, fname = mkstemp('.py')
f = os.fdopen(fd, 'w')
f.write(pyfile)
f.close()
# Unlink the file
cl = PyFileConfigLoader(fname, log=log)
config = cl.load_config()
self._check_conf(config)
def test_json(self):
fd, fname = mkstemp('.json')
f = os.fdopen(fd, 'w')
f.write(json1file)
f.close()
# Unlink the file
cl = JSONFileConfigLoader(fname, log=log)
config = cl.load_config()
self._check_conf(config)
def test_collision(self):
a = Config()
b = Config()
self.assertEqual(a.collisions(b), {})
a.A.trait1 = 1
b.A.trait2 = 2
self.assertEqual(a.collisions(b), {})
b.A.trait1 = 1
self.assertEqual(a.collisions(b), {})
b.A.trait1 = 0
self.assertEqual(a.collisions(b), {
'A': {
'trait1': "1 ignored, using 0",
}
})
self.assertEqual(b.collisions(a), {
'A': {
'trait1': "0 ignored, using 1",
}
})
a.A.trait2 = 3
self.assertEqual(b.collisions(a), {
'A': {
'trait1': "0 ignored, using 1",
'trait2': "2 ignored, using 3",
}
})
def test_v2raise(self):
fd, fname = mkstemp('.json')
f = os.fdopen(fd, 'w')
f.write(json2file)
f.close()
# Unlink the file
cl = JSONFileConfigLoader(fname, log=log)
with nt.assert_raises(ValueError):
cl.load_config()
class MyLoader1(ArgParseConfigLoader):
def _add_arguments(self, aliases=None, flags=None):
p = self.parser
p.add_argument('-f', '--foo', dest='Global.foo', type=str)
p.add_argument('-b', dest='MyClass.bar', type=int)
p.add_argument('-n', dest='n', action='store_true')
p.add_argument('Global.bam', type=str)
class MyLoader2(ArgParseConfigLoader):
def _add_arguments(self, aliases=None, flags=None):
subparsers = self.parser.add_subparsers(dest='subparser_name')
subparser1 = subparsers.add_parser('1')
subparser1.add_argument('-x',dest='Global.x')
subparser2 = subparsers.add_parser('2')
subparser2.add_argument('y')
class TestArgParseCL(TestCase):
def test_basic(self):
cl = MyLoader1()
config = cl.load_config('-f hi -b 10 -n wow'.split())
self.assertEqual(config.Global.foo, 'hi')
self.assertEqual(config.MyClass.bar, 10)
self.assertEqual(config.n, True)
self.assertEqual(config.Global.bam, 'wow')
config = cl.load_config(['wow'])
self.assertEqual(list(config.keys()), ['Global'])
self.assertEqual(list(config.Global.keys()), ['bam'])
self.assertEqual(config.Global.bam, 'wow')
def test_add_arguments(self):
cl = MyLoader2()
config = cl.load_config('2 frobble'.split())
self.assertEqual(config.subparser_name, '2')
self.assertEqual(config.y, 'frobble')
config = cl.load_config('1 -x frobble'.split())
self.assertEqual(config.subparser_name, '1')
self.assertEqual(config.Global.x, 'frobble')
def test_argv(self):
cl = MyLoader1(argv='-f hi -b 10 -n wow'.split())
config = cl.load_config()
self.assertEqual(config.Global.foo, 'hi')
self.assertEqual(config.MyClass.bar, 10)
self.assertEqual(config.n, True)
self.assertEqual(config.Global.bam, 'wow')
class TestKeyValueCL(TestCase):
klass = KeyValueConfigLoader
def test_basic(self):
cl = self.klass(log=log)
argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]]
config = cl.load_config(argv)
self.assertEqual(config.a, 10)
self.assertEqual(config.b, 20)
self.assertEqual(config.Foo.Bar.value, 10)
self.assertEqual(config.Foo.Bam.value, list(range(10)))
self.assertEqual(config.D.C.value, 'hi there')
def test_expanduser(self):
cl = self.klass(log=log)
argv = ['--a=~/1/2/3', '--b=~', '--c=~/', '--d="~/"']
config = cl.load_config(argv)
self.assertEqual(config.a, os.path.expanduser('~/1/2/3'))
self.assertEqual(config.b, os.path.expanduser('~'))
self.assertEqual(config.c, os.path.expanduser('~/'))
self.assertEqual(config.d, '~/')
def test_extra_args(self):
cl = self.klass(log=log)
config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
self.assertEqual(cl.extra_args, ['b', 'd'])
self.assertEqual(config.a, 5)
self.assertEqual(config.c, 10)
config = cl.load_config(['--', '--a=5', '--c=10'])
self.assertEqual(cl.extra_args, ['--a=5', '--c=10'])
def test_unicode_args(self):
cl = self.klass(log=log)
argv = [u'--a=épsîlön']
config = cl.load_config(argv)
self.assertEqual(config.a, u'épsîlön')
def test_unicode_bytes_args(self):
uarg = u'--a=é'
try:
barg = uarg.encode(sys.stdin.encoding)
except (TypeError, UnicodeEncodeError):
raise SkipTest("sys.stdin.encoding can't handle 'é'")
cl = self.klass(log=log)
config = cl.load_config([barg])
self.assertEqual(config.a, u'é')
def test_unicode_alias(self):
cl = self.klass(log=log)
argv = [u'--a=épsîlön']
config = cl.load_config(argv, aliases=dict(a='A.a'))
self.assertEqual(config.A.a, u'épsîlön')
class TestArgParseKVCL(TestKeyValueCL):
klass = KVArgParseConfigLoader
def test_expanduser2(self):
cl = self.klass(log=log)
argv = ['-a', '~/1/2/3', '--b', "'~/1/2/3'"]
config = cl.load_config(argv, aliases=dict(a='A.a', b='A.b'))
self.assertEqual(config.A.a, os.path.expanduser('~/1/2/3'))
self.assertEqual(config.A.b, '~/1/2/3')
def test_eval(self):
cl = self.klass(log=log)
argv = ['-c', 'a=5']
config = cl.load_config(argv, aliases=dict(c='A.c'))
self.assertEqual(config.A.c, u"a=5")
class TestConfig(TestCase):
def test_setget(self):
c = Config()
c.a = 10
self.assertEqual(c.a, 10)
self.assertEqual('b' in c, False)
def test_auto_section(self):
c = Config()
self.assertNotIn('A', c)
assert not c._has_section('A')
A = c.A
A.foo = 'hi there'
self.assertIn('A', c)
assert c._has_section('A')
self.assertEqual(c.A.foo, 'hi there')
del c.A
self.assertEqual(c.A, Config())
def test_merge_doesnt_exist(self):
c1 = Config()
c2 = Config()
c2.bar = 10
c2.Foo.bar = 10
c1.merge(c2)
self.assertEqual(c1.Foo.bar, 10)
self.assertEqual(c1.bar, 10)
c2.Bar.bar = 10
c1.merge(c2)
self.assertEqual(c1.Bar.bar, 10)
def test_merge_exists(self):
c1 = Config()
c2 = Config()
c1.Foo.bar = 10
c1.Foo.bam = 30
c2.Foo.bar = 20
c2.Foo.wow = 40
c1.merge(c2)
self.assertEqual(c1.Foo.bam, 30)
self.assertEqual(c1.Foo.bar, 20)
self.assertEqual(c1.Foo.wow, 40)
c2.Foo.Bam.bam = 10
c1.merge(c2)
self.assertEqual(c1.Foo.Bam.bam, 10)
def test_deepcopy(self):
c1 = Config()
c1.Foo.bar = 10
c1.Foo.bam = 30
c1.a = 'asdf'
c1.b = range(10)
import copy
c2 = copy.deepcopy(c1)
self.assertEqual(c1, c2)
self.assertTrue(c1 is not c2)
self.assertTrue(c1.Foo is not c2.Foo)
def test_builtin(self):
c1 = Config()
c1.format = "json"
def test_fromdict(self):
c1 = Config({'Foo' : {'bar' : 1}})
self.assertEqual(c1.Foo.__class__, Config)
self.assertEqual(c1.Foo.bar, 1)
def test_fromdictmerge(self):
c1 = Config()
c2 = Config({'Foo' : {'bar' : 1}})
c1.merge(c2)
self.assertEqual(c1.Foo.__class__, Config)
self.assertEqual(c1.Foo.bar, 1)
def test_fromdictmerge2(self):
c1 = Config({'Foo' : {'baz' : 2}})
c2 = Config({'Foo' : {'bar' : 1}})
c1.merge(c2)
self.assertEqual(c1.Foo.__class__, Config)
self.assertEqual(c1.Foo.bar, 1)
self.assertEqual(c1.Foo.baz, 2)
self.assertNotIn('baz', c2.Foo)
def test_contains(self):
c1 = Config({'Foo' : {'baz' : 2}})
c2 = Config({'Foo' : {'bar' : 1}})
self.assertIn('Foo', c1)
self.assertIn('Foo.baz', c1)
self.assertIn('Foo.bar', c2)
self.assertNotIn('Foo.bar', c1)
def test_pickle_config(self):
cfg = Config()
cfg.Foo.bar = 1
pcfg = pickle.dumps(cfg)
cfg2 = pickle.loads(pcfg)
self.assertEqual(cfg2, cfg)
def test_getattr_section(self):
cfg = Config()
self.assertNotIn('Foo', cfg)
Foo = cfg.Foo
assert isinstance(Foo, Config)
self.assertIn('Foo', cfg)
def test_getitem_section(self):
cfg = Config()
self.assertNotIn('Foo', cfg)
Foo = cfg['Foo']
assert isinstance(Foo, Config)
self.assertIn('Foo', cfg)
def test_getattr_not_section(self):
cfg = Config()
self.assertNotIn('foo', cfg)
foo = cfg.foo
assert isinstance(foo, LazyConfigValue)
self.assertIn('foo', cfg)
def test_getattr_private_missing(self):
cfg = Config()
self.assertNotIn('_repr_html_', cfg)
with self.assertRaises(AttributeError):
_ = cfg._repr_html_
self.assertNotIn('_repr_html_', cfg)
self.assertEqual(len(cfg), 0)
def test_getitem_not_section(self):
cfg = Config()
self.assertNotIn('foo', cfg)
foo = cfg['foo']
assert isinstance(foo, LazyConfigValue)
self.assertIn('foo', cfg)
def test_merge_copies(self):
c = Config()
c2 = Config()
c2.Foo.trait = []
c.merge(c2)
c2.Foo.trait.append(1)
self.assertIsNot(c.Foo, c2.Foo)
self.assertEqual(c.Foo.trait, [])
self.assertEqual(c2.Foo.trait, [1])