Merge pull request #1124 from bukzor/unit-test-config-fromdictargs
tests of (and fixes for) Config.fromdictargs (2)
This commit is contained in:
commit
cee828130c
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
* New `pytest.mark.skip` mark, which unconditional skips marked tests.
|
* New `pytest.mark.skip` mark, which unconditional skips marked tests.
|
||||||
Thanks Michael Aquilina for the complete PR.
|
Thanks Michael Aquilina for the complete PR.
|
||||||
|
* fix issue #680: the -s and -c options should now work under xdist;
|
||||||
|
`Config.fromdictargs` now represents its input much more faithfully.
|
||||||
|
Thanks to Buck Evan for the complete PR.
|
||||||
|
|
||||||
2.8.2.dev
|
2.8.2.dev
|
||||||
---------
|
---------
|
||||||
|
|
|
@ -455,11 +455,11 @@ class Parser:
|
||||||
"""
|
"""
|
||||||
self._anonymous.addoption(*opts, **attrs)
|
self._anonymous.addoption(*opts, **attrs)
|
||||||
|
|
||||||
def parse(self, args):
|
def parse(self, args, namespace=None):
|
||||||
from _pytest._argcomplete import try_argcomplete
|
from _pytest._argcomplete import try_argcomplete
|
||||||
self.optparser = self._getparser()
|
self.optparser = self._getparser()
|
||||||
try_argcomplete(self.optparser)
|
try_argcomplete(self.optparser)
|
||||||
return self.optparser.parse_args([str(x) for x in args])
|
return self.optparser.parse_args([str(x) for x in args], namespace=namespace)
|
||||||
|
|
||||||
def _getparser(self):
|
def _getparser(self):
|
||||||
from _pytest._argcomplete import filescompleter
|
from _pytest._argcomplete import filescompleter
|
||||||
|
@ -477,25 +477,25 @@ class Parser:
|
||||||
optparser.add_argument(FILE_OR_DIR, nargs='*').completer=filescompleter
|
optparser.add_argument(FILE_OR_DIR, nargs='*').completer=filescompleter
|
||||||
return optparser
|
return optparser
|
||||||
|
|
||||||
def parse_setoption(self, args, option):
|
def parse_setoption(self, args, option, namespace=None):
|
||||||
parsedoption = self.parse(args)
|
parsedoption = self.parse(args, namespace=namespace)
|
||||||
for name, value in parsedoption.__dict__.items():
|
for name, value in parsedoption.__dict__.items():
|
||||||
setattr(option, name, value)
|
setattr(option, name, value)
|
||||||
return getattr(parsedoption, FILE_OR_DIR)
|
return getattr(parsedoption, FILE_OR_DIR)
|
||||||
|
|
||||||
def parse_known_args(self, args):
|
def parse_known_args(self, args, namespace=None):
|
||||||
"""parses and returns a namespace object with known arguments at this
|
"""parses and returns a namespace object with known arguments at this
|
||||||
point.
|
point.
|
||||||
"""
|
"""
|
||||||
return self.parse_known_and_unknown_args(args)[0]
|
return self.parse_known_and_unknown_args(args, namespace=namespace)[0]
|
||||||
|
|
||||||
def parse_known_and_unknown_args(self, args):
|
def parse_known_and_unknown_args(self, args, namespace=None):
|
||||||
"""parses and returns a namespace object with known arguments, and
|
"""parses and returns a namespace object with known arguments, and
|
||||||
the remaining arguments unknown at this point.
|
the remaining arguments unknown at this point.
|
||||||
"""
|
"""
|
||||||
optparser = self._getparser()
|
optparser = self._getparser()
|
||||||
args = [str(x) for x in args]
|
args = [str(x) for x in args]
|
||||||
return optparser.parse_known_args(args)
|
return optparser.parse_known_args(args, namespace=namespace)
|
||||||
|
|
||||||
def addini(self, name, help, type=None, default=None):
|
def addini(self, name, help, type=None, default=None):
|
||||||
""" register an ini-file option.
|
""" register an ini-file option.
|
||||||
|
@ -779,10 +779,12 @@ def _ensure_removed_sysmodule(modname):
|
||||||
|
|
||||||
class CmdOptions(object):
|
class CmdOptions(object):
|
||||||
""" holds cmdline options as attributes."""
|
""" holds cmdline options as attributes."""
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, values=()):
|
||||||
self.__dict__.update(kwargs)
|
self.__dict__.update(values)
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<CmdOptions %r>" %(self.__dict__,)
|
return "<CmdOptions %r>" %(self.__dict__,)
|
||||||
|
def copy(self):
|
||||||
|
return CmdOptions(self.__dict__)
|
||||||
|
|
||||||
class Notset:
|
class Notset:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -879,8 +881,8 @@ class Config(object):
|
||||||
def fromdictargs(cls, option_dict, args):
|
def fromdictargs(cls, option_dict, args):
|
||||||
""" constructor useable for subprocesses. """
|
""" constructor useable for subprocesses. """
|
||||||
config = get_config()
|
config = get_config()
|
||||||
config._preparse(args, addopts=False)
|
|
||||||
config.option.__dict__.update(option_dict)
|
config.option.__dict__.update(option_dict)
|
||||||
|
config.parse(args, addopts=False)
|
||||||
for x in config.option.plugins:
|
for x in config.option.plugins:
|
||||||
config.pluginmanager.consider_pluginarg(x)
|
config.pluginmanager.consider_pluginarg(x)
|
||||||
return config
|
return config
|
||||||
|
@ -898,7 +900,7 @@ class Config(object):
|
||||||
self.pluginmanager._set_initial_conftests(early_config.known_args_namespace)
|
self.pluginmanager._set_initial_conftests(early_config.known_args_namespace)
|
||||||
|
|
||||||
def _initini(self, args):
|
def _initini(self, args):
|
||||||
ns, unknown_args = self._parser.parse_known_and_unknown_args(args)
|
ns, unknown_args = self._parser.parse_known_and_unknown_args(args, namespace=self.option.copy())
|
||||||
r = determine_setup(ns.inifilename, ns.file_or_dir + unknown_args)
|
r = determine_setup(ns.inifilename, ns.file_or_dir + unknown_args)
|
||||||
self.rootdir, self.inifile, self.inicfg = r
|
self.rootdir, self.inifile, self.inicfg = r
|
||||||
self._parser.extra_info['rootdir'] = self.rootdir
|
self._parser.extra_info['rootdir'] = self.rootdir
|
||||||
|
@ -919,7 +921,7 @@ class Config(object):
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
self.warn("I2", "could not load setuptools entry import: %s" % (e,))
|
self.warn("I2", "could not load setuptools entry import: %s" % (e,))
|
||||||
self.pluginmanager.consider_env()
|
self.pluginmanager.consider_env()
|
||||||
self.known_args_namespace = ns = self._parser.parse_known_args(args)
|
self.known_args_namespace = ns = self._parser.parse_known_args(args, namespace=self.option.copy())
|
||||||
if self.known_args_namespace.confcutdir is None and self.inifile:
|
if self.known_args_namespace.confcutdir is None and self.inifile:
|
||||||
confcutdir = py.path.local(self.inifile).dirname
|
confcutdir = py.path.local(self.inifile).dirname
|
||||||
self.known_args_namespace.confcutdir = confcutdir
|
self.known_args_namespace.confcutdir = confcutdir
|
||||||
|
@ -947,17 +949,17 @@ class Config(object):
|
||||||
self.inicfg.config.path, self.inicfg.lineof('minversion'),
|
self.inicfg.config.path, self.inicfg.lineof('minversion'),
|
||||||
minver, pytest.__version__))
|
minver, pytest.__version__))
|
||||||
|
|
||||||
def parse(self, args):
|
def parse(self, args, addopts=True):
|
||||||
# parse given cmdline arguments into this config object.
|
# parse given cmdline arguments into this config object.
|
||||||
assert not hasattr(self, 'args'), (
|
assert not hasattr(self, 'args'), (
|
||||||
"can only parse cmdline args at most once per Config object")
|
"can only parse cmdline args at most once per Config object")
|
||||||
self._origargs = args
|
self._origargs = args
|
||||||
self.hook.pytest_addhooks.call_historic(
|
self.hook.pytest_addhooks.call_historic(
|
||||||
kwargs=dict(pluginmanager=self.pluginmanager))
|
kwargs=dict(pluginmanager=self.pluginmanager))
|
||||||
self._preparse(args)
|
self._preparse(args, addopts=addopts)
|
||||||
# XXX deprecated hook:
|
# XXX deprecated hook:
|
||||||
self.hook.pytest_cmdline_preparse(config=self, args=args)
|
self.hook.pytest_cmdline_preparse(config=self, args=args)
|
||||||
args = self._parser.parse_setoption(args, self.option)
|
args = self._parser.parse_setoption(args, self.option, namespace=self.option)
|
||||||
if not args:
|
if not args:
|
||||||
cwd = os.getcwd()
|
cwd = os.getcwd()
|
||||||
if cwd == self.rootdir:
|
if cwd == self.rootdir:
|
||||||
|
|
|
@ -264,6 +264,69 @@ class TestConfigAPI:
|
||||||
assert len(l) == 2
|
assert len(l) == 2
|
||||||
assert l == ["456", "123"]
|
assert l == ["456", "123"]
|
||||||
|
|
||||||
|
|
||||||
|
class TestConfigFromdictargs:
|
||||||
|
def test_basic_behavior(self):
|
||||||
|
from _pytest.config import Config
|
||||||
|
option_dict = {
|
||||||
|
'verbose': 444,
|
||||||
|
'foo': 'bar',
|
||||||
|
'capture': 'no',
|
||||||
|
}
|
||||||
|
args = ['a', 'b']
|
||||||
|
|
||||||
|
config = Config.fromdictargs(option_dict, args)
|
||||||
|
with pytest.raises(AssertionError):
|
||||||
|
config.parse(['should refuse to parse again'])
|
||||||
|
assert config.option.verbose == 444
|
||||||
|
assert config.option.foo == 'bar'
|
||||||
|
assert config.option.capture == 'no'
|
||||||
|
assert config.args == args
|
||||||
|
|
||||||
|
def test_origargs(self):
|
||||||
|
"""Show that fromdictargs can handle args in their "orig" format"""
|
||||||
|
from _pytest.config import Config
|
||||||
|
option_dict = {}
|
||||||
|
args = ['-vvvv', '-s', 'a', 'b']
|
||||||
|
|
||||||
|
config = Config.fromdictargs(option_dict, args)
|
||||||
|
assert config.args == ['a', 'b']
|
||||||
|
assert config._origargs == args
|
||||||
|
assert config.option.verbose == 4
|
||||||
|
assert config.option.capture == 'no'
|
||||||
|
|
||||||
|
def test_inifilename(self, tmpdir):
|
||||||
|
tmpdir.join("foo/bar.ini").ensure().write(py.code.Source("""
|
||||||
|
[pytest]
|
||||||
|
name = value
|
||||||
|
"""))
|
||||||
|
|
||||||
|
from _pytest.config import Config
|
||||||
|
inifile = '../../foo/bar.ini'
|
||||||
|
option_dict = {
|
||||||
|
'inifilename': inifile,
|
||||||
|
'capture': 'no',
|
||||||
|
}
|
||||||
|
|
||||||
|
cwd = tmpdir.join('a/b')
|
||||||
|
cwd.join('pytest.ini').ensure().write(py.code.Source("""
|
||||||
|
[pytest]
|
||||||
|
name = wrong-value
|
||||||
|
should_not_be_set = true
|
||||||
|
"""))
|
||||||
|
with cwd.ensure(dir=True).as_cwd():
|
||||||
|
config = Config.fromdictargs(option_dict, ())
|
||||||
|
|
||||||
|
assert config.args == [str(cwd)]
|
||||||
|
assert config.option.inifilename == inifile
|
||||||
|
assert config.option.capture == 'no'
|
||||||
|
|
||||||
|
# this indicates this is the file used for getting configuration values
|
||||||
|
assert config.inifile == inifile
|
||||||
|
assert config.inicfg.get('name') == 'value'
|
||||||
|
assert config.inicfg.get('should_not_be_set') is None
|
||||||
|
|
||||||
|
|
||||||
def test_options_on_small_file_do_not_blow_up(testdir):
|
def test_options_on_small_file_do_not_blow_up(testdir):
|
||||||
def runfiletest(opts):
|
def runfiletest(opts):
|
||||||
reprec = testdir.inline_run(*opts)
|
reprec = testdir.inline_run(*opts)
|
||||||
|
|
Loading…
Reference in New Issue