2009-09-09 14:56:53 -05:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
test_intersphinx
|
|
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Test the intersphinx extension.
|
|
|
|
|
2017-03-22 06:21:12 -05:00
|
|
|
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
|
2009-09-09 14:56:53 -05:00
|
|
|
:license: BSD, see LICENSE for details.
|
|
|
|
"""
|
|
|
|
|
2015-10-15 16:37:55 -05:00
|
|
|
import unittest
|
2009-09-09 14:56:53 -05:00
|
|
|
|
|
|
|
from docutils import nodes
|
2016-10-15 02:22:27 -05:00
|
|
|
import mock
|
2017-03-21 10:03:05 -05:00
|
|
|
import pytest
|
|
|
|
import requests
|
|
|
|
from io import BytesIO
|
2017-06-14 13:26:15 -05:00
|
|
|
import os
|
2009-09-09 14:56:53 -05:00
|
|
|
|
|
|
|
from sphinx import addnodes
|
2016-09-01 09:30:04 -05:00
|
|
|
from sphinx.ext.intersphinx import setup as intersphinx_setup
|
2017-03-02 07:51:42 -06:00
|
|
|
from sphinx.ext.intersphinx import (
|
|
|
|
load_mappings, missing_reference, _strip_basic_auth,
|
2017-03-21 19:49:48 -05:00
|
|
|
_get_safe_url, fetch_inventory, INVENTORY_FILENAME, debug
|
2017-03-02 07:51:42 -06:00
|
|
|
)
|
|
|
|
from test_util_inventory import inventory_v2
|
2009-09-09 14:56:53 -05:00
|
|
|
|
|
|
|
|
2017-04-22 10:21:22 -05:00
|
|
|
def fake_node(domain, type, target, content, **attrs):
|
|
|
|
contnode = nodes.emphasis(content, content)
|
|
|
|
node = addnodes.pending_xref('')
|
|
|
|
node['reftarget'] = target
|
|
|
|
node['reftype'] = type
|
|
|
|
node['refdomain'] = domain
|
|
|
|
node.attributes.update(attrs)
|
|
|
|
node += contnode
|
|
|
|
return node, contnode
|
|
|
|
|
|
|
|
|
|
|
|
def reference_check(app, *args, **kwds):
|
|
|
|
node, contnode = fake_node(*args, **kwds)
|
|
|
|
return missing_reference(app, app.env, node, contnode)
|
|
|
|
|
|
|
|
|
2017-03-02 02:26:07 -06:00
|
|
|
@mock.patch('sphinx.ext.intersphinx.InventoryFile')
|
2016-08-10 21:19:42 -05:00
|
|
|
@mock.patch('sphinx.ext.intersphinx._read_from_url')
|
2017-03-02 02:26:07 -06:00
|
|
|
def test_fetch_inventory_redirection(_read_from_url, InventoryFile, app, status, warning):
|
2016-09-01 09:30:04 -05:00
|
|
|
intersphinx_setup(app)
|
2016-08-10 23:58:21 -05:00
|
|
|
_read_from_url().readline.return_value = '# Sphinx inventory version 2'.encode('utf-8')
|
2016-08-10 21:19:42 -05:00
|
|
|
|
|
|
|
# same uri and inv, not redirected
|
2016-08-17 22:33:28 -05:00
|
|
|
_read_from_url().url = 'http://hostname/' + INVENTORY_FILENAME
|
2016-08-10 21:19:42 -05:00
|
|
|
fetch_inventory(app, 'http://hostname/', 'http://hostname/' + INVENTORY_FILENAME)
|
|
|
|
assert 'intersphinx inventory has moved' not in status.getvalue()
|
2017-03-02 02:26:07 -06:00
|
|
|
assert InventoryFile.load.call_args[0][1] == 'http://hostname/'
|
2016-08-10 21:19:42 -05:00
|
|
|
|
|
|
|
# same uri and inv, redirected
|
2016-08-10 23:58:21 -05:00
|
|
|
status.seek(0)
|
2016-08-10 21:19:42 -05:00
|
|
|
status.truncate(0)
|
2016-08-17 22:33:28 -05:00
|
|
|
_read_from_url().url = 'http://hostname/new/' + INVENTORY_FILENAME
|
2016-08-10 21:19:42 -05:00
|
|
|
|
|
|
|
fetch_inventory(app, 'http://hostname/', 'http://hostname/' + INVENTORY_FILENAME)
|
|
|
|
assert status.getvalue() == ('intersphinx inventory has moved: '
|
|
|
|
'http://hostname/%s -> http://hostname/new/%s\n' %
|
|
|
|
(INVENTORY_FILENAME, INVENTORY_FILENAME))
|
2017-03-02 02:26:07 -06:00
|
|
|
assert InventoryFile.load.call_args[0][1] == 'http://hostname/new'
|
2016-08-10 21:19:42 -05:00
|
|
|
|
|
|
|
# different uri and inv, not redirected
|
2016-08-10 23:58:21 -05:00
|
|
|
status.seek(0)
|
2016-08-10 21:19:42 -05:00
|
|
|
status.truncate(0)
|
2016-08-17 22:33:28 -05:00
|
|
|
_read_from_url().url = 'http://hostname/new/' + INVENTORY_FILENAME
|
2016-08-10 21:19:42 -05:00
|
|
|
|
|
|
|
fetch_inventory(app, 'http://hostname/', 'http://hostname/new/' + INVENTORY_FILENAME)
|
|
|
|
assert 'intersphinx inventory has moved' not in status.getvalue()
|
2017-03-02 02:26:07 -06:00
|
|
|
assert InventoryFile.load.call_args[0][1] == 'http://hostname/'
|
2016-08-10 21:19:42 -05:00
|
|
|
|
|
|
|
# different uri and inv, redirected
|
2016-08-10 23:58:21 -05:00
|
|
|
status.seek(0)
|
2016-08-10 21:19:42 -05:00
|
|
|
status.truncate(0)
|
2016-08-17 22:33:28 -05:00
|
|
|
_read_from_url().url = 'http://hostname/other/' + INVENTORY_FILENAME
|
2016-08-10 21:19:42 -05:00
|
|
|
|
|
|
|
fetch_inventory(app, 'http://hostname/', 'http://hostname/new/' + INVENTORY_FILENAME)
|
|
|
|
assert status.getvalue() == ('intersphinx inventory has moved: '
|
|
|
|
'http://hostname/new/%s -> http://hostname/other/%s\n' %
|
|
|
|
(INVENTORY_FILENAME, INVENTORY_FILENAME))
|
2017-03-02 02:26:07 -06:00
|
|
|
assert InventoryFile.load.call_args[0][1] == 'http://hostname/'
|
2016-08-10 21:19:42 -05:00
|
|
|
|
|
|
|
|
2017-06-14 13:26:15 -05:00
|
|
|
@pytest.mark.xfail(os.name != 'posix', reason="Path separator mismatch issue")
|
2014-09-21 10:17:02 -05:00
|
|
|
def test_missing_reference(tempdir, app, status, warning):
|
2009-09-09 14:56:53 -05:00
|
|
|
inv_file = tempdir / 'inventory'
|
2014-04-28 05:58:26 -05:00
|
|
|
inv_file.write_bytes(inventory_v2)
|
2010-07-27 06:20:58 -05:00
|
|
|
app.config.intersphinx_mapping = {
|
2015-02-22 22:20:35 -06:00
|
|
|
'https://docs.python.org/': inv_file,
|
|
|
|
'py3k': ('https://docs.python.org/py3k/', inv_file),
|
2015-09-28 15:29:46 -05:00
|
|
|
'py3krel': ('py3k', inv_file), # relative path
|
|
|
|
'py3krelparent': ('../../py3k', inv_file), # relative path, parent dir
|
2010-07-27 06:20:58 -05:00
|
|
|
}
|
2009-09-09 14:56:53 -05:00
|
|
|
app.config.intersphinx_cache_limit = 0
|
|
|
|
|
|
|
|
# load the inventory and check if it's done correctly
|
|
|
|
load_mappings(app)
|
|
|
|
inv = app.env.intersphinx_inventory
|
|
|
|
|
|
|
|
assert inv['py:module']['module2'] == \
|
2015-02-22 22:20:35 -06:00
|
|
|
('foo', '2.0', 'https://docs.python.org/foo.html#module-module2', '-')
|
2009-09-09 14:56:53 -05:00
|
|
|
|
2010-08-05 04:58:43 -05:00
|
|
|
# check resolution when a target is found
|
2017-04-22 10:21:22 -05:00
|
|
|
rn = reference_check(app, 'py', 'func', 'module1.func', 'foo')
|
2009-09-09 14:56:53 -05:00
|
|
|
assert isinstance(rn, nodes.reference)
|
2015-02-22 22:20:35 -06:00
|
|
|
assert rn['refuri'] == 'https://docs.python.org/sub/foo.html#module1.func'
|
2009-09-09 14:56:53 -05:00
|
|
|
assert rn['reftitle'] == '(in foo v2.0)'
|
2010-08-05 04:58:43 -05:00
|
|
|
assert rn[0].astext() == 'foo'
|
2009-09-09 14:56:53 -05:00
|
|
|
|
|
|
|
# create unresolvable nodes and check None return value
|
2017-04-22 10:21:22 -05:00
|
|
|
assert reference_check(app, 'py', 'foo', 'module1.func', 'foo') is None
|
|
|
|
assert reference_check(app, 'py', 'func', 'foo', 'foo') is None
|
|
|
|
assert reference_check(app, 'py', 'func', 'foo', 'foo') is None
|
2010-07-27 06:20:58 -05:00
|
|
|
|
|
|
|
# check handling of prefixes
|
|
|
|
|
|
|
|
# prefix given, target found: prefix is stripped
|
2017-04-22 10:21:22 -05:00
|
|
|
rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'py3k:module2')
|
2010-08-05 04:58:43 -05:00
|
|
|
assert rn[0].astext() == 'module2'
|
|
|
|
|
|
|
|
# prefix given, but not in title: nothing stripped
|
2017-04-22 10:21:22 -05:00
|
|
|
rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'module2')
|
2010-07-27 06:20:58 -05:00
|
|
|
assert rn[0].astext() == 'module2'
|
|
|
|
|
2010-08-05 04:58:43 -05:00
|
|
|
# prefix given, but explicit: nothing stripped
|
2017-04-22 10:21:22 -05:00
|
|
|
rn = reference_check(app, 'py', 'mod', 'py3k:module2', 'py3k:module2',
|
2010-08-05 04:58:43 -05:00
|
|
|
refexplicit=True)
|
|
|
|
assert rn[0].astext() == 'py3k:module2'
|
|
|
|
|
2010-07-27 06:20:58 -05:00
|
|
|
# prefix given, target not found and nonexplicit title: prefix is stripped
|
2010-08-05 04:58:43 -05:00
|
|
|
node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown',
|
|
|
|
refexplicit=False)
|
|
|
|
rn = missing_reference(app, app.env, node, contnode)
|
2010-07-27 06:20:58 -05:00
|
|
|
assert rn is None
|
|
|
|
assert contnode[0].astext() == 'unknown'
|
|
|
|
|
|
|
|
# prefix given, target not found and explicit title: nothing is changed
|
2010-08-05 04:58:43 -05:00
|
|
|
node, contnode = fake_node('py', 'mod', 'py3k:unknown', 'py3k:unknown',
|
|
|
|
refexplicit=True)
|
|
|
|
rn = missing_reference(app, app.env, node, contnode)
|
2010-07-27 06:20:58 -05:00
|
|
|
assert rn is None
|
|
|
|
assert contnode[0].astext() == 'py3k:unknown'
|
2011-09-03 14:41:26 -05:00
|
|
|
|
2017-04-22 10:21:22 -05:00
|
|
|
# check relative paths
|
|
|
|
rn = reference_check(app, 'py', 'mod', 'py3krel:module1', 'foo')
|
|
|
|
assert rn['refuri'] == 'py3k/foo.html#module-module1'
|
|
|
|
|
|
|
|
rn = reference_check(app, 'py', 'mod', 'py3krelparent:module1', 'foo')
|
|
|
|
assert rn['refuri'] == '../../py3k/foo.html#module-module1'
|
|
|
|
|
|
|
|
rn = reference_check(app, 'py', 'mod', 'py3krel:module1', 'foo', refdoc='sub/dir/test')
|
|
|
|
assert rn['refuri'] == '../../py3k/foo.html#module-module1'
|
|
|
|
|
|
|
|
rn = reference_check(app, 'py', 'mod', 'py3krelparent:module1', 'foo',
|
|
|
|
refdoc='sub/dir/test')
|
|
|
|
assert rn['refuri'] == '../../../../py3k/foo.html#module-module1'
|
|
|
|
|
|
|
|
# check refs of standard domain
|
|
|
|
rn = reference_check(app, 'std', 'doc', 'docname', 'docname')
|
|
|
|
assert rn['refuri'] == 'https://docs.python.org/docname.html'
|
|
|
|
|
|
|
|
|
|
|
|
def test_missing_reference_pydomain(tempdir, app, status, warning):
|
|
|
|
inv_file = tempdir / 'inventory'
|
|
|
|
inv_file.write_bytes(inventory_v2)
|
|
|
|
app.config.intersphinx_mapping = {
|
|
|
|
'https://docs.python.org/': inv_file,
|
|
|
|
}
|
|
|
|
app.config.intersphinx_cache_limit = 0
|
|
|
|
|
|
|
|
# load the inventory and check if it's done correctly
|
|
|
|
load_mappings(app)
|
|
|
|
|
2017-01-29 10:16:10 -06:00
|
|
|
# no context data
|
|
|
|
kwargs = {}
|
|
|
|
node, contnode = fake_node('py', 'func', 'func', 'func()', **kwargs)
|
|
|
|
rn = missing_reference(app, app.env, node, contnode)
|
|
|
|
assert rn is None
|
|
|
|
|
2017-04-22 10:21:22 -05:00
|
|
|
# py:module context helps to search objects
|
2017-01-29 10:16:10 -06:00
|
|
|
kwargs = {'py:module': 'module1'}
|
|
|
|
node, contnode = fake_node('py', 'func', 'func', 'func()', **kwargs)
|
|
|
|
rn = missing_reference(app, app.env, node, contnode)
|
2017-04-22 10:21:22 -05:00
|
|
|
assert rn.astext() == 'func()'
|
2017-01-29 10:16:10 -06:00
|
|
|
|
2015-09-28 15:29:46 -05:00
|
|
|
|
2017-04-22 10:21:22 -05:00
|
|
|
def test_missing_reference_stddomain(tempdir, app, status, warning):
|
|
|
|
inv_file = tempdir / 'inventory'
|
|
|
|
inv_file.write_bytes(inventory_v2)
|
|
|
|
app.config.intersphinx_mapping = {
|
|
|
|
'https://docs.python.org/': inv_file,
|
|
|
|
}
|
|
|
|
app.config.intersphinx_cache_limit = 0
|
2015-09-28 15:29:46 -05:00
|
|
|
|
2017-04-22 10:21:22 -05:00
|
|
|
# load the inventory and check if it's done correctly
|
|
|
|
load_mappings(app)
|
2015-09-28 15:29:46 -05:00
|
|
|
|
2017-04-22 10:21:22 -05:00
|
|
|
# no context data
|
|
|
|
kwargs = {}
|
|
|
|
node, contnode = fake_node('std', 'option', '-l', '-l', **kwargs)
|
|
|
|
rn = missing_reference(app, app.env, node, contnode)
|
|
|
|
assert rn is None
|
2015-09-28 15:29:46 -05:00
|
|
|
|
2017-04-22 10:21:22 -05:00
|
|
|
# std:program context helps to search objects
|
|
|
|
kwargs = {'std:program': 'ls'}
|
|
|
|
node, contnode = fake_node('std', 'option', '-l', 'ls -l', **kwargs)
|
|
|
|
rn = missing_reference(app, app.env, node, contnode)
|
|
|
|
assert rn.astext() == 'ls -l'
|
2017-01-29 03:10:49 -06:00
|
|
|
|
2011-09-03 14:41:26 -05:00
|
|
|
|
2017-04-22 21:33:49 -05:00
|
|
|
@pytest.mark.sphinx('html', testroot='ext-intersphinx-cppdomain')
|
|
|
|
def test_missing_reference_cppdomain(tempdir, app, status, warning):
|
|
|
|
inv_file = tempdir / 'inventory'
|
|
|
|
inv_file.write_bytes(inventory_v2)
|
|
|
|
app.config.intersphinx_mapping = {
|
|
|
|
'https://docs.python.org/': inv_file,
|
|
|
|
}
|
|
|
|
app.config.intersphinx_cache_limit = 0
|
|
|
|
|
|
|
|
# load the inventory and check if it's done correctly
|
|
|
|
load_mappings(app)
|
|
|
|
|
|
|
|
app.build()
|
|
|
|
html = (app.outdir / 'index.html').text()
|
|
|
|
assert ('<a class="reference external"'
|
|
|
|
' href="https://docs.python.org/index.html#cpp_foo_bar"'
|
|
|
|
' title="(in foo v2.0)"><code class="xref cpp cpp-class docutils literal">'
|
|
|
|
'<span class="pre">Bar</span></code></a>' in html)
|
|
|
|
|
|
|
|
|
2017-04-22 11:02:29 -05:00
|
|
|
def test_missing_reference_jsdomain(tempdir, app, status, warning):
|
|
|
|
inv_file = tempdir / 'inventory'
|
|
|
|
inv_file.write_bytes(inventory_v2)
|
|
|
|
app.config.intersphinx_mapping = {
|
|
|
|
'https://docs.python.org/': inv_file,
|
|
|
|
}
|
|
|
|
app.config.intersphinx_cache_limit = 0
|
|
|
|
|
|
|
|
# load the inventory and check if it's done correctly
|
|
|
|
load_mappings(app)
|
|
|
|
|
|
|
|
# no context data
|
|
|
|
kwargs = {}
|
|
|
|
node, contnode = fake_node('js', 'meth', 'baz', 'baz()', **kwargs)
|
|
|
|
rn = missing_reference(app, app.env, node, contnode)
|
|
|
|
assert rn is None
|
|
|
|
|
|
|
|
# js:module and js:object context helps to search objects
|
|
|
|
kwargs = {'js:module': 'foo', 'js:object': 'bar'}
|
|
|
|
node, contnode = fake_node('js', 'meth', 'baz', 'baz()', **kwargs)
|
|
|
|
rn = missing_reference(app, app.env, node, contnode)
|
|
|
|
assert rn.astext() == 'baz()'
|
|
|
|
|
|
|
|
|
2014-09-21 10:17:02 -05:00
|
|
|
def test_load_mappings_warnings(tempdir, app, status, warning):
|
2011-09-03 14:41:26 -05:00
|
|
|
"""
|
|
|
|
load_mappings issues a warning if new-style mapping
|
2016-05-22 22:14:56 -05:00
|
|
|
identifiers are not string
|
2011-09-03 14:41:26 -05:00
|
|
|
"""
|
|
|
|
inv_file = tempdir / 'inventory'
|
2014-04-28 05:58:26 -05:00
|
|
|
inv_file.write_bytes(inventory_v2)
|
2011-09-03 14:41:26 -05:00
|
|
|
app.config.intersphinx_mapping = {
|
2015-02-22 22:20:35 -06:00
|
|
|
'https://docs.python.org/': inv_file,
|
|
|
|
'py3k': ('https://docs.python.org/py3k/', inv_file),
|
2011-09-03 14:41:26 -05:00
|
|
|
'repoze.workflow': ('http://docs.repoze.org/workflow/', inv_file),
|
2011-10-09 16:09:57 -05:00
|
|
|
'django-taggit': ('http://django-taggit.readthedocs.org/en/latest/',
|
2016-05-22 22:11:10 -05:00
|
|
|
inv_file),
|
|
|
|
12345: ('http://www.sphinx-doc.org/en/stable/', inv_file),
|
2011-09-03 14:41:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
app.config.intersphinx_cache_limit = 0
|
|
|
|
# load the inventory and check if it's done correctly
|
|
|
|
load_mappings(app)
|
2016-05-22 22:14:56 -05:00
|
|
|
assert warning.getvalue().count('\n') == 1
|
2015-10-15 16:37:55 -05:00
|
|
|
|
|
|
|
|
|
|
|
class TestStripBasicAuth(unittest.TestCase):
|
|
|
|
"""Tests for sphinx.ext.intersphinx._strip_basic_auth()"""
|
|
|
|
def test_auth_stripped(self):
|
|
|
|
"""basic auth creds stripped from URL containing creds"""
|
|
|
|
url = 'https://user:12345@domain.com/project/objects.inv'
|
|
|
|
expected = 'https://domain.com/project/objects.inv'
|
2016-08-17 22:41:38 -05:00
|
|
|
actual = _strip_basic_auth(url)
|
|
|
|
self.assertEqual(expected, actual)
|
2015-10-15 16:37:55 -05:00
|
|
|
|
|
|
|
def test_no_auth(self):
|
|
|
|
"""url unchanged if param doesn't contain basic auth creds"""
|
|
|
|
url = 'https://domain.com/project/objects.inv'
|
|
|
|
expected = 'https://domain.com/project/objects.inv'
|
2016-08-17 22:41:38 -05:00
|
|
|
actual = _strip_basic_auth(url)
|
|
|
|
self.assertEqual(expected, actual)
|
2015-10-15 16:37:55 -05:00
|
|
|
|
2016-04-24 21:08:03 -05:00
|
|
|
def test_having_port(self):
|
|
|
|
"""basic auth creds correctly stripped from URL containing creds even if URL
|
|
|
|
contains port"""
|
|
|
|
url = 'https://user:12345@domain.com:8080/project/objects.inv'
|
|
|
|
expected = 'https://domain.com:8080/project/objects.inv'
|
2016-08-17 22:41:38 -05:00
|
|
|
actual = _strip_basic_auth(url)
|
|
|
|
self.assertEqual(expected, actual)
|
2016-04-24 21:08:03 -05:00
|
|
|
|
2015-10-15 16:37:55 -05:00
|
|
|
|
2015-10-22 01:09:16 -05:00
|
|
|
def test_getsafeurl_authed():
|
|
|
|
"""_get_safe_url() with a url with basic auth"""
|
|
|
|
url = 'https://user:12345@domain.com/project/objects.inv'
|
|
|
|
expected = 'https://user@domain.com/project/objects.inv'
|
|
|
|
actual = _get_safe_url(url)
|
|
|
|
assert expected == actual
|
|
|
|
|
|
|
|
|
2016-08-17 11:25:29 -05:00
|
|
|
def test_getsafeurl_authed_having_port():
|
|
|
|
"""_get_safe_url() with a url with basic auth having port"""
|
|
|
|
url = 'https://user:12345@domain.com:8080/project/objects.inv'
|
|
|
|
expected = 'https://user@domain.com:8080/project/objects.inv'
|
|
|
|
actual = _get_safe_url(url)
|
|
|
|
assert expected == actual
|
|
|
|
|
|
|
|
|
2015-10-22 01:09:16 -05:00
|
|
|
def test_getsafeurl_unauthed():
|
|
|
|
"""_get_safe_url() with a url without basic auth"""
|
|
|
|
url = 'https://domain.com/project/objects.inv'
|
|
|
|
expected = 'https://domain.com/project/objects.inv'
|
|
|
|
actual = _get_safe_url(url)
|
|
|
|
assert expected == actual
|
2017-03-21 10:03:05 -05:00
|
|
|
|
|
|
|
|
|
|
|
def test_debug_noargs(capsys):
|
|
|
|
"""debug interface, without arguments"""
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
debug(['sphinx/ext/intersphinx.py'])
|
|
|
|
|
|
|
|
expected = (
|
|
|
|
"Print out an inventory file.\n"
|
|
|
|
"Error: must specify local path or URL to an inventory file."
|
|
|
|
)
|
|
|
|
stdout, stderr = capsys.readouterr()
|
|
|
|
assert stdout == ""
|
|
|
|
assert stderr == expected + "\n"
|
|
|
|
|
|
|
|
|
|
|
|
def test_debug_file(capsys, tempdir):
|
|
|
|
"""debug interface, with file argument"""
|
|
|
|
inv_file = tempdir / 'inventory'
|
|
|
|
inv_file.write_bytes(inventory_v2)
|
|
|
|
|
|
|
|
debug(['sphinx/ext/intersphinx.py', str(inv_file)])
|
|
|
|
|
|
|
|
stdout, stderr = capsys.readouterr()
|
|
|
|
assert stdout.startswith("c:function\n")
|
|
|
|
assert stderr == ""
|
|
|
|
|
|
|
|
|
|
|
|
@mock.patch('requests.get')
|
|
|
|
def test_debug_url(fake_get, capsys):
|
|
|
|
"""debug interface, with url argument"""
|
|
|
|
raw = BytesIO(inventory_v2)
|
|
|
|
real_read = raw.read
|
|
|
|
|
|
|
|
def fake_read(*args, **kwargs):
|
|
|
|
return real_read()
|
|
|
|
|
|
|
|
raw.read = fake_read
|
|
|
|
url = 'http://hostname/' + INVENTORY_FILENAME
|
|
|
|
resp = requests.Response()
|
|
|
|
resp.status_code = 200
|
|
|
|
resp.url = url
|
|
|
|
resp.raw = raw
|
|
|
|
fake_get.return_value = resp
|
|
|
|
|
|
|
|
debug(['sphinx/ext/intersphinx.py', url])
|
|
|
|
|
|
|
|
stdout, stderr = capsys.readouterr()
|
|
|
|
assert stdout.startswith("c:function\n")
|
|
|
|
assert stderr == ""
|