def test_bool_len():
    """Test length and boolean values of Versions and .branches/.tags."""
    versions = Versions(REMOTES)
    versions.context.update(
        dict(pagename='contents', scv_is_root=True, current_version='master'))
    assert bool(versions) is True
    assert bool(versions.branches) is True
    assert bool(versions.tags) is True
    assert len(versions) == 7

    versions = Versions(r for r in REMOTES if r[2] == 'heads')
    versions.context.update(
        dict(pagename='contents', scv_is_root=True, current_version='master'))
    assert bool(versions) is True
    assert bool(versions.branches) is True
    assert bool(versions.tags) is False
    assert len(versions) == 2

    versions = Versions(r for r in REMOTES if r[2] == 'tags')
    versions.context.update(
        dict(pagename='contents', scv_is_root=True, current_version='master'))
    assert bool(versions) is True
    assert bool(versions.branches) is False
    assert bool(versions.tags) is True
    assert len(versions) == 5

    versions = Versions([])
    assert bool(versions) is False
    assert bool(versions.branches) is False
    assert bool(versions.tags) is False
    assert len(versions) == 0
def test_no_sort(remotes):
    """Test without sorting.

    :param iter remotes: Passed to class.
    """
    versions = Versions(remotes)
    versions.context.update(
        dict(pagename='contents', scv_is_root=False, current_version='other'))
    actual_all = [i for i in versions]
    actual_branches = [i for i in versions.branches]
    actual_tags = [i for i in versions.tags]

    expected_all = [(r[1], '../{}/contents.html'.format(r[1]))
                    for r in remotes]
    expected_branches = [(r[1], '../{}/contents.html'.format(r[1]))
                         for r in remotes if r[2] == 'heads']
    expected_tags = [(r[1], '../{}/contents.html'.format(r[1]))
                     for r in remotes if r[2] == 'tags']

    assert actual_all == expected_all
    assert actual_branches == expected_branches
    assert actual_tags == expected_tags
    assert versions.greatest_tag_remote == versions['v10.0.0']
    assert versions.recent_branch_remote == versions['zh-pages']
    assert versions.recent_remote == versions['v2.0.0']
    assert versions.recent_tag_remote == versions['v2.0.0']
예제 #3
0
def test_dual(local_docs):
    """With two versions, one with master_doc defined.

    :param local_docs: conftest fixture.
    """
    pytest.run(local_docs, ['git', 'checkout', 'feature'])
    local_docs.join('conf.py').write('master_doc = "index"\n')
    local_docs.join('index.rst').write('Test\n'
                                       '====\n'
                                       '\n'
                                       'Sample documentation.\n')
    pytest.run(local_docs, ['git', 'add', 'conf.py', 'index.rst'])
    pytest.run(local_docs,
               ['git', 'commit', '-m', 'Adding docs with master_doc'])
    pytest.run(local_docs, ['git', 'push', 'origin', 'feature'])

    versions = Versions(
        gather_git_info(str(local_docs), ['conf.py'], tuple(), tuple()))
    assert len(versions) == 2

    # Run and verify directory.
    exported_root = py.path.local(pre_build(str(local_docs), versions))
    assert len(exported_root.listdir()) == 2
    assert exported_root.join(versions['master']['sha'],
                              'conf.py').read() == ''
    assert exported_root.join(versions['feature']['sha'],
                              'conf.py').read() == 'master_doc = "index"\n'

    # Verify versions root_dirs and master_docs.
    expected = ['feature/index', 'master/contents']
    assert sorted(
        posixpath.join(r['root_dir'], r['master_doc'])
        for r in versions.remotes) == expected
def test_sort_semver_invalid(sort):
    """Test sorting logic with nothing but invalid versions.

    :param str sort: Passed to function after splitting by comma.
    """
    items = ['master', 'gh-pages', 'a', 'z']
    remotes = [('', item, 'tags', i, 'README') for i, item in enumerate(items)]
    versions = Versions(remotes, sort=sort.split(','))
    versions.context.update(
        dict(pagename='contents', scv_is_root=True, current_version='master'))
    actual = [i[0] for i in versions]

    if sort == 'alpha':
        expected = ['a', 'gh-pages', 'master', 'z']
    elif sort == 'time':
        expected = list(reversed(items))
    elif sort == 'semver':
        expected = ['master', 'gh-pages', 'a', 'z']
    elif sort == 'semver,alpha':
        expected = ['a', 'gh-pages', 'master', 'z']
    elif sort == 'semver,time':
        expected = ['z', 'a', 'gh-pages', 'master']
    else:
        expected = items

    assert actual == expected
예제 #5
0
def test_all_errors(tmpdir, local_docs, urls):
    """Test good root ref with all bad non-root refs.

    :param tmpdir: pytest fixture.
    :param local_docs: conftest fixture.
    :param urls: conftest fixture.
    """
    pytest.run(local_docs, ['git', 'checkout', '-b', 'a_broken', 'master'])
    local_docs.join('conf.py').write('master_doc = exception\n')
    pytest.run(local_docs, ['git', 'commit', '-am', 'Broken version.'])
    pytest.run(local_docs, ['git', 'checkout', '-b', 'b_broken', 'a_broken'])
    pytest.run(local_docs, ['git', 'push', 'origin', 'a_broken', 'b_broken'])

    versions = Versions(
        gather_git_info(str(local_docs), ['conf.py'], tuple(), tuple()))

    exported_root = tmpdir.ensure_dir('exported_root')
    export(str(local_docs), versions['master']['sha'],
           str(exported_root.join(versions['master']['sha'])))
    export(str(local_docs), versions['b_broken']['sha'],
           str(exported_root.join(versions['b_broken']['sha'])))

    # Run.
    destination = tmpdir.ensure_dir('destination')
    build_all(str(exported_root), str(destination), versions)
    assert [r['name'] for r in versions.remotes] == ['master']

    # Verify root HTML links.
    urls(destination.join('contents.html'),
         ['<li><a href="master/contents.html">master</a></li>'])
    urls(destination.join('master', 'contents.html'),
         ['<li><a href="contents.html">master</a></li>'])
def test_getitem():
    """Test Versions.__getitem__ with integer and string keys/indices."""
    versions = Versions(REMOTES)

    # Test SHA.
    assert versions['0772e5ff32af52115a809d97cd506837fa209f7f'][
        'name'] == 'zh-pages'
    assert versions['abaaa358379408d99725']['name'] == 'master'
    assert versions['3b7987d8f']['name'] == 'v1.2.0'
    assert versions['c4f19']['name'] == 'v2.0.0'

    # Test name and date.
    for name, date in (r[1::2] for r in REMOTES):
        assert versions[name]['name'] == name
        assert versions[date]['name'] == name

    # Indexes.
    for i, name in enumerate(r[1] for r in REMOTES):
        assert versions[i]['name'] == name

    # Test IndexError.
    with pytest.raises(IndexError):
        assert versions[100]

    # Test KeyError.
    with pytest.raises(KeyError):
        assert versions['unknown']
예제 #7
0
def test_versions_override(tmpdir, local_docs):
    """Verify GitHub/BitBucket versions are overridden.

    :param tmpdir: pytest fixture.
    :param local_docs: conftest fixture.
    """
    versions = Versions([('', 'master', 'heads', 1, 'conf.py'), ('', 'feature', 'heads', 2, 'conf.py')])

    local_docs.join('conf.py').write(
        'templates_path = ["_templates"]\n'
        'html_sidebars = {"**": ["custom.html"]}\n'
        'html_context = dict(github_version="replace_me", bitbucket_version="replace_me")\n'
    )
    local_docs.ensure('_templates', 'custom.html').write(
        '<h3>Custom Sidebar</h3>\n'
        '<ul>\n'
        '<li>GitHub: {{ github_version }}</li>\n'
        '<li>BitBucket: {{ bitbucket_version }}</li>\n'
        '</ul>\n'
    )

    target = tmpdir.ensure_dir('target_master')
    build(str(local_docs), str(target), versions, 'master', True)
    contents = target.join('contents.html').read()
    assert '<li>GitHub: master</li>' in contents
    assert '<li>BitBucket: master</li>' in contents

    target = tmpdir.ensure_dir('target_feature')
    build(str(local_docs), str(target), versions, 'feature', False)
    contents = target.join('contents.html').read()
    assert '<li>GitHub: feature</li>' in contents
    assert '<li>BitBucket: feature</li>' in contents
예제 #8
0
def test_custom_sidebar(tmpdir, local_docs, urls, pre_existing_versions):
    """Make sure user's sidebar item is kept intact.

    :param tmpdir: pytest fixture.
    :param local_docs: conftest fixture.
    :param urls: conftest fixture.
    :param bool pre_existing_versions: Test if user already has versions.html in conf.py.
    """
    target = tmpdir.ensure_dir('target')
    versions = Versions([('', 'master', 'heads', 1, 'conf.py')])

    if pre_existing_versions:
        local_docs.join('conf.py').write(
            'templates_path = ["_templates"]\n'
            'html_sidebars = {"**": ["versions.html", "localtoc.html", "custom.html"]}\n'
        )
    else:
        local_docs.join('conf.py').write(
            'templates_path = ["_templates"]\n'
            'html_sidebars = {"**": ["localtoc.html", "custom.html"]}\n'
        )
    local_docs.ensure('_templates', 'custom.html').write('<h3>Custom Sidebar</h3><ul><li>Test</li></ul>')

    build(str(local_docs), str(target), versions, 'master', True)

    contents = urls(target.join('contents.html'), ['<li><a href="master/contents.html">master</a></li>'])
    assert '<h3>Custom Sidebar</h3>' in contents
예제 #9
0
def test_error(config, local_docs):
    """Test with a bad root ref. Also test skipping bad non-root refs.

    :param config: conftest fixture.
    :param local_docs: conftest fixture.
    """
    pytest.run(local_docs, ['git', 'checkout', '-b', 'a_good', 'master'])
    pytest.run(local_docs, ['git', 'checkout', '-b', 'c_good', 'master'])
    pytest.run(local_docs, ['git', 'checkout', '-b', 'b_broken', 'master'])
    local_docs.join('conf.py').write('master_doc = exception\n')
    pytest.run(local_docs, ['git', 'commit', '-am', 'Broken version.'])
    pytest.run(local_docs, ['git', 'checkout', '-b', 'd_broken', 'b_broken'])
    pytest.run(
        local_docs,
        ['git', 'push', 'origin', 'a_good', 'b_broken', 'c_good', 'd_broken'])

    versions = Versions(gather_git_info(str(local_docs), ['conf.py'], tuple(),
                                        tuple()),
                        sort=['alpha'])
    assert [r['name'] for r in versions.remotes
            ] == ['a_good', 'b_broken', 'c_good', 'd_broken', 'master']

    # Bad root ref.
    config.root_ref = 'b_broken'
    with pytest.raises(HandledError):
        pre_build(str(local_docs), versions)

    # Remove bad non-root refs.
    config.root_ref = 'master'
    pre_build(str(local_docs), versions)
    assert [r['name']
            for r in versions.remotes] == ['a_good', 'c_good', 'master']
def test_nothing_significant_to_commit(caplog, local, subdirs):
    """Test ignoring of always-changing generated Sphinx files.

    :param caplog: pytest extension fixture.
    :param local: conftest fixture.
    :param bool subdirs: Test these files from sub directories.
    """
    local.ensure('sub' if subdirs else '', '.doctrees', 'file.bin').write('data')
    local.ensure('sub' if subdirs else '', 'searchindex.js').write('data')
    old_sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip()
    actual = commit_and_push(str(local), 'origin', Versions(REMOTES))
    assert actual is True
    sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip()
    assert sha != old_sha
    pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--'])  # Exit 0 if nothing changed.
    records = [(r.levelname, r.message) for r in caplog.records]
    assert ('INFO', 'No changes to commit.') not in records
    assert ('INFO', 'No significant changes to commit.') not in records

    local.ensure('sub' if subdirs else '', '.doctrees', 'file.bin').write('changed')
    local.ensure('sub' if subdirs else '', 'searchindex.js').write('changed')
    old_sha = sha
    records_seek = len(caplog.records)
    actual = commit_and_push(str(local), 'origin', Versions(REMOTES))
    assert actual is True
    sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip()
    assert sha == old_sha
    with pytest.raises(CalledProcessError):
        pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--'])
    records = [(r.levelname, r.message) for r in caplog.records][records_seek:]
    assert ('INFO', 'No changes to commit.') not in records
    assert ('INFO', 'No significant changes to commit.') in records

    local.join('README').write('changed')  # Should cause other two to be committed.
    old_sha = sha
    records_seek = len(caplog.records)
    actual = commit_and_push(str(local), 'origin', Versions(REMOTES))
    assert actual is True
    sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip()
    assert sha != old_sha
    pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--'])  # Exit 0 if nothing changed.
    records = [(r.levelname, r.message) for r in caplog.records][records_seek:]
    assert ('INFO', 'No changes to commit.') not in records
    assert ('INFO', 'No significant changes to commit.') not in records
def test_sphinx_rtd_theme(tmpdir, config, local_docs):
    """Test sphinx_rtd_theme features.

    :param tmpdir: pytest fixture.
    :param config: conftest fixture.
    :param local_docs: conftest fixture.
    """
    local_docs.join('conf.py').write('html_theme="sphinx_rtd_theme"')

    # Build branches only.
    target_b = tmpdir.ensure_dir('target_b')
    versions = Versions([('', 'master', 'heads', 1, 'conf.py'),
                         ('', 'feature', 'heads', 2, 'conf.py')], ['semver'])
    build(str(local_docs), str(target_b), versions, 'master', True)
    contents = target_b.join('contents.html').read()
    assert '<dt>Branches</dt>' in contents
    assert '<dt>Tags</dt>' not in contents

    # Build tags only.
    target_t = tmpdir.ensure_dir('target_t')
    versions = Versions([('', 'v1.0.0', 'tags', 3, 'conf.py'),
                         ('', 'v1.2.0', 'tags', 4, 'conf.py')],
                        sort=['semver'])
    config.root_ref = config.banner_main_ref = 'v1.2.0'
    build(str(local_docs), str(target_t), versions, 'v1.2.0', True)
    contents = target_t.join('contents.html').read()
    assert '<dt>Branches</dt>' not in contents
    assert '<dt>Tags</dt>' in contents

    # Build both.
    target_bt = tmpdir.ensure_dir('target_bt')
    versions = Versions([('', 'master', 'heads', 1, 'conf.py'),
                         ('', 'feature', 'heads', 2, 'conf.py'),
                         ('', 'v1.0.0', 'tags', 3, 'conf.py'),
                         ('', 'v1.2.0', 'tags', 4, 'conf.py')],
                        sort=['semver'])
    config.root_ref = 'master'
    build(str(local_docs), str(target_bt), versions, 'master', True)
    contents = target_bt.join('contents.html').read()
    assert '<dt>Branches</dt>' in contents
    assert '<dt>Tags</dt>' in contents
def test_origin_deleted(local, remote):
    """Test scenario where the remote repo is unavailable (e.g. repo deleted from GitHub).

    :param local: conftest fixture.
    :param remote: conftest fixture.
    """
    local.join('README').write('Changed by local.')
    remote.remove()

    with pytest.raises(GitError) as exc:
        commit_and_push(str(local), 'origin', Versions(REMOTES))
    assert 'Could not read from remote repository' in exc.value.output
def test_supported(tmpdir, config, local_docs, theme):
    """Test with different themes. Verify not much changed between sphinx-build and sphinx-versioning.

    :param tmpdir: pytest fixture.
    :param sphinxcontrib.versioning.lib.Config config: conftest fixture.
    :param local_docs: conftest fixture.
    :param str theme: Theme name to use.
    """
    config.overflow = ('-D', 'html_theme=' + theme)
    target_n = tmpdir.ensure_dir('target_n')
    target_y = tmpdir.ensure_dir('target_y')
    versions = Versions([
        ('', 'master', 'heads', 1, 'conf.py'),
        ('', 'feature', 'heads', 2, 'conf.py'),
        ('', 'v1.0.0', 'tags', 3, 'conf.py'),
        ('', 'v1.2.0', 'tags', 4, 'conf.py'),
        ('', 'v2.0.0', 'tags', 5, 'conf.py'),
        ('', 'v2.1.0', 'tags', 6, 'conf.py'),
        ('', 'v2.2.0', 'tags', 7, 'conf.py'),
        ('', 'v2.3.0', 'tags', 8, 'conf.py'),
        ('', 'v2.4.0', 'tags', 9, 'conf.py'),
        ('', 'v2.5.0', 'tags', 10, 'conf.py'),
        ('', 'v2.6.0', 'tags', 11, 'conf.py'),
        ('', 'v2.7.0', 'tags', 12, 'conf.py'),
        ('', 'testing_branch', 'heads', 13, 'conf.py'),
    ],
                        sort=['semver'])

    # Build with normal sphinx-build.
    pytest.run(
        local_docs,
        ['sphinx-build', '.',
         str(target_n), '-D', 'html_theme=' + theme])
    contents_n = target_n.join('contents.html').read()
    assert 'master' not in contents_n

    # Build with versions.
    build(str(local_docs), str(target_y), versions, 'master', True)
    contents_y = target_y.join('contents.html').read()
    assert 'master' in contents_y

    # Verify nothing removed.
    diff = list(
        difflib.unified_diff(contents_n.splitlines(True),
                             contents_y.splitlines(True)))[2:]
    assert diff
    for line in diff:
        assert not line.startswith('-')

    # Verify added.
    for name in (r['name'] for r in versions.remotes):
        assert any(name in line for line in diff if line.startswith('+'))
예제 #14
0
def test_sphinx_error(tmpdir, local_docs):
    """Test error handling.

    :param tmpdir: pytest fixture.
    :param local_docs: conftest fixture.
    """
    target = tmpdir.ensure_dir('target')
    versions = Versions([('', 'master', 'heads', 1, 'conf.py')])

    local_docs.join('conf.py').write('undefined')

    with pytest.raises(HandledError):
        build(str(local_docs), str(target), versions, 'master', True)
예제 #15
0
def _read_config(argv, config, current_name, queue):
    """Read the Sphinx config via multiprocessing for isolation.

    :param tuple argv: Arguments to pass to Sphinx.
    :param sphinxcontrib.versioning.lib.Config config: Runtime configuration.
    :param str current_name: The ref name of the current version being built.
    :param multiprocessing.queues.Queue queue: Communication channel to parent process.
    """
    # Patch.
    EventHandlers.ABORT_AFTER_READ = queue

    # Run.
    _build(argv, config, Versions(list()), current_name, False)
def test_branch_deleted(local):
    """Test scenario where branch is deleted by someone.

    :param local: conftest fixture.
    """
    pytest.run(local, ['git', 'checkout', 'feature'])
    pytest.run(local, ['git', 'push', 'origin', '--delete', 'feature'])
    local.join('README').write('Changed by local.')

    # Run.
    actual = commit_and_push(str(local), 'origin', Versions(REMOTES))
    assert actual is True
    pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--'])  # Exit 0 if nothing changed.
    assert local.join('README').read() == 'Changed by local.'
예제 #17
0
def test_last_updated(tmpdir, local_docs):
    """Test last updated timestamp derived from git authored time.

    :param tmpdir: pytest fixture.
    :param local_docs: conftest fixture.
    """
    local_docs.join('conf.py').write('html_last_updated_fmt = "%c"\n'
                                     'html_theme="sphinx_rtd_theme"\n')
    local_docs.join('two.rst').write('Changed\n', mode='a')
    pytest.run(local_docs, ['git', 'commit', '-am', 'Changed two.'],
               environ=pytest.author_committer_dates(10))
    pytest.run(local_docs, ['git', 'checkout', '-b', 'other', 'master'])
    local_docs.join('three.rst').write('Changed\n', mode='a')
    pytest.run(local_docs, ['git', 'commit', '-am', 'Changed three.'],
               environ=pytest.author_committer_dates(11))
    pytest.run(local_docs, ['git', 'push', 'origin', 'master', 'other'])

    versions = Versions(
        gather_git_info(str(local_docs), ['conf.py'], tuple(), tuple()))

    # Export.
    exported_root = tmpdir.ensure_dir('exported_root')
    export(str(local_docs), versions['master']['sha'],
           str(exported_root.join(versions['master']['sha'])))
    export(str(local_docs), versions['other']['sha'],
           str(exported_root.join(versions['other']['sha'])))

    # Run.
    destination = tmpdir.ensure_dir('destination')
    build_all(str(exported_root), str(destination), versions)

    # Verify master.
    one = RE_LAST_UPDATED.findall(
        destination.join('master', 'one.html').read())
    two = RE_LAST_UPDATED.findall(
        destination.join('master', 'two.html').read())
    three = RE_LAST_UPDATED.findall(
        destination.join('master', 'three.html').read())
    assert one == ['Last updated on Dec 5, 2016, 3:20:05 AM.\n']
    assert two == ['Last updated on Dec 5, 2016, 3:27:05 AM.\n']
    assert three == ['Last updated on Dec 5, 2016, 3:20:05 AM.\n']

    # Verify other.
    one = RE_LAST_UPDATED.findall(destination.join('other', 'one.html').read())
    two = RE_LAST_UPDATED.findall(destination.join('other', 'two.html').read())
    three = RE_LAST_UPDATED.findall(
        destination.join('other', 'three.html').read())
    assert one == ['Last updated on Dec 5, 2016, 3:20:05 AM.\n']
    assert two == ['Last updated on Dec 5, 2016, 3:27:05 AM.\n']
    assert three == ['Last updated on Dec 5, 2016, 3:28:05 AM.\n']
예제 #18
0
def test_overflow(tmpdir, config, local_docs):
    """Test sphinx-build overflow feature.

    :param tmpdir: pytest fixture.
    :param sphinxcontrib.versioning.lib.Config config: conftest fixture.
    :param local_docs: conftest fixture.
    """
    config.overflow = ('-D', 'copyright=2016, SCV')
    target = tmpdir.ensure_dir('target')
    versions = Versions([('', 'master', 'heads', 1, 'conf.py')])

    build(str(local_docs), str(target), versions, 'master', True)

    contents = target.join('contents.html').read()
    assert '2016, SCV' in contents
def test_sort_valid(sort):
    """Test sorting logic with valid versions (lifted from 2.7 distutils/version.py:LooseVersion.__doc__).

    :param str sort: Passed to function after splitting by comma.
    """
    items = [
        'v1.5.1', 'V1.5.1b2', '161', '3.10a', '8.02', '3.4j', '1996.07.12',
        '3.2.pl0', '3.1.1.6', '2g6', '11g', '0.960923', '2.2beta29', '1.13++',
        '5.5.kw', '2.0b1pl0', 'master', 'gh-pages', 'a', 'z'
    ]
    remotes = [('', item, 'tags', i, 'README') for i, item in enumerate(items)]
    versions = Versions(remotes, sort=sort.split(','))
    versions.context.update(
        dict(pagename='contents', scv_is_root=True, current_version='master'))
    actual = [i[0] for i in versions]

    if sort == 'alpha':
        expected = [
            '0.960923', '1.13++', '11g', '161', '1996.07.12', '2.0b1pl0',
            '2.2beta29', '2g6', '3.1.1.6', '3.10a', '3.2.pl0', '3.4j',
            '5.5.kw', '8.02', 'V1.5.1b2', 'a', 'gh-pages', 'master', 'v1.5.1',
            'z'
        ]
    elif sort == 'time':
        expected = list(reversed(items))
    elif sort == 'semver':
        expected = [
            '1996.07.12', '161', '11g', '8.02', '5.5.kw', '3.10a', '3.4j',
            '3.2.pl0', '3.1.1.6', '2.2beta29', '2.0b1pl0', '2g6', '1.13++',
            'v1.5.1', 'V1.5.1b2', '0.960923', 'master', 'gh-pages', 'a', 'z'
        ]
    elif sort == 'semver,alpha':
        expected = [
            '1996.07.12', '161', '11g', '8.02', '5.5.kw', '3.10a', '3.4j',
            '3.2.pl0', '3.1.1.6', '2.2beta29', '2.0b1pl0', '2g6', '1.13++',
            'v1.5.1', 'V1.5.1b2', '0.960923', 'a', 'gh-pages', 'master', 'z'
        ]
    elif sort == 'semver,time':
        expected = [
            '1996.07.12', '161', '11g', '8.02', '5.5.kw', '3.10a', '3.4j',
            '3.2.pl0', '3.1.1.6', '2.2beta29', '2.0b1pl0', '2g6', '1.13++',
            'v1.5.1', 'V1.5.1b2', '0.960923', 'z', 'a', 'gh-pages', 'master'
        ]
    else:
        expected = items

    assert actual == expected
예제 #20
0
def test_invalid_name(local_docs):
    """Test handling of branch names with invalid root_dir characters.

    :param local_docs: conftest fixture.
    """
    pytest.run(local_docs, ['git', 'checkout', '-b', 'robpol86/feature'])
    pytest.run(local_docs, ['git', 'push', 'origin', 'robpol86/feature'])

    versions = Versions(
        gather_git_info(str(local_docs), ['conf.py'], tuple(), tuple()))
    assert len(versions) == 2

    # Verify versions root_dirs and master_docs.
    pre_build(str(local_docs), versions)
    expected = ['master/contents', 'robpol86_feature/contents']
    assert sorted(
        posixpath.join(r['root_dir'], r['master_doc'])
        for r in versions.remotes) == expected
예제 #21
0
def test_file_collision(local_docs):
    """Test handling of filename collisions between generates files from root and branch names.

    :param local_docs: conftest fixture.
    """
    pytest.run(local_docs, ['git', 'checkout', '-b', '_static'])
    pytest.run(local_docs, ['git', 'push', 'origin', '_static'])

    versions = Versions(
        gather_git_info(str(local_docs), ['conf.py'], tuple(), tuple()))
    assert len(versions) == 2

    # Verify versions root_dirs and master_docs.
    pre_build(str(local_docs), versions)
    expected = ['_static_/contents', 'master/contents']
    assert sorted(
        posixpath.join(r['root_dir'], r['master_doc'])
        for r in versions.remotes) == expected
예제 #22
0
def test_simple(tmpdir, local_docs, urls, no_feature):
    """Verify versions are included in HTML.

    :param tmpdir: pytest fixture.
    :param local_docs: conftest fixture.
    :param urls: conftest fixture.
    :param bool no_feature: Don't include feature branch in versions. Makes sure there are no false positives.
    """
    target = tmpdir.ensure_dir('target')
    versions = Versions(
        [('', 'master', 'heads', 1, 'conf.py')] + ([] if no_feature else [('', 'feature', 'heads', 2, 'conf.py')])
    )

    build(str(local_docs), str(target), versions, 'master', True)

    expected = ['<li><a href="master/contents.html">master</a></li>']
    if not no_feature:
        expected.append('<li><a href="feature/contents.html">feature</a></li>')
    urls(target.join('contents.html'), expected)
def get_versions(context):
    """Create Versions class instance for tests.

    :param dict context: Update context with this.
    """
    versions = Versions([i * 5, i, 'heads', 1465766422, 'README'] for i in ('a', 'b', 'c'))
    versions.context.update(context)

    versions['a']['found_docs'] = ('contents', '1', 'sub/2', 'sub/sub/3', 'sub/sub/sub/4')

    versions['b']['found_docs'] = ('contents', '1', 'sub/2', 'sub/sub/3', 'sub/sub/sub/4')
    versions['b']['master_doc'] = 'contents'
    versions['b']['root_dir'] = 'b'

    versions['c']['found_docs'] = ('contents', 'A', 'sub/B', 'sub/sub/C', 'sub/sub/sub/D')
    versions['c']['master_doc'] = 'contents'
    versions['c']['root_dir'] = 'c_'

    return versions
def test_nothing_to_commit(caplog, local, exclude):
    """Test with no changes to commit.

    :param caplog: pytest extension fixture.
    :param local: conftest fixture.
    :param bool exclude: Test with exclude support (aka files staged for deletion). Else clean repo.
    """
    if exclude:
        contents = local.join('README').read()
        pytest.run(local, ['git', 'rm', 'README'])  # Stages removal of README.
        local.join('README').write(contents)  # Unstaged restore.
    old_sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip()

    actual = commit_and_push(str(local), 'origin', Versions(REMOTES))
    assert actual is True
    sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip()
    assert sha == old_sha

    records = [(r.levelname, r.message) for r in caplog.records]
    assert ('INFO', 'No changes to commit.') in records
예제 #25
0
def test_single(local_docs):
    """With single version.

    :param local_docs: conftest fixture.
    """
    versions = Versions(
        gather_git_info(str(local_docs), ['conf.py'], tuple(), tuple()))
    assert len(versions) == 1

    # Run and verify directory.
    exported_root = py.path.local(pre_build(str(local_docs), versions))
    assert len(exported_root.listdir()) == 1
    assert exported_root.join(versions['master']['sha'],
                              'conf.py').read() == ''

    # Verify root_dir and master_doc..
    expected = ['master/contents']
    assert sorted(
        posixpath.join(r['root_dir'], r['master_doc'])
        for r in versions.remotes) == expected
예제 #26
0
def test_isolation(tmpdir, config, local_docs, project):
    """Make sure Sphinx doesn't alter global state and carry over settings between builds.

    :param tmpdir: pytest fixture.
    :param sphinxcontrib.versioning.lib.Config config: conftest fixture.
    :param local_docs: conftest fixture.
    :param bool project: Set project in conf.py, else set copyright.
    """
    config.overflow = ('-D', 'project=Robpol86' if project else 'copyright="2016, SCV"')
    target = tmpdir.ensure_dir('target')
    versions = Versions([('', 'master', 'heads', 1, 'conf.py')])

    build(str(local_docs), str(target), versions, 'master', True)

    contents = target.join('contents.html').read()
    if project:
        assert 'Robpol86' in contents
        assert '2016, SCV' not in contents
    else:
        assert 'Robpol86' not in contents
        assert '2016, SCV' in contents
def test_banner(tmpdir, banner, config, local_docs, theme):
    """Test banner messages.

    :param tmpdir: pytest fixture.
    :param banner: conftest fixture.
    :param sphinxcontrib.versioning.lib.Config config: conftest fixture.
    :param local_docs: conftest fixture.
    :param str theme: Theme name to use.
    """
    config.overflow = ('-D', 'html_theme=' + theme)
    config.show_banner = True
    target = tmpdir.ensure_dir('target')
    versions = Versions([('', 'master', 'heads', 1, 'conf.py'),
                         ('', 'feature', 'heads', 2, 'conf.py')])
    versions['master']['found_docs'] = ('contents', )
    versions['feature']['found_docs'] = ('contents', )

    build(str(local_docs), str(target), versions, 'feature', False)

    banner(target.join('contents.html'), '../master/contents.html',
           'the development version of Python. The main version is master')
def test_sort(remotes, sort):
    """Test with sorting.

    :param iter remotes: Passed to class.
    :param str sort: Passed to class after splitting by comma.
    """
    versions = Versions(remotes, sort=sort.split(','))
    versions.context.update(
        dict(pagename='contents', scv_is_root=True, current_version='master'))
    actual = [i[0] for i in versions]

    if sort == 'alpha':
        expected = [
            'master', 'v1.2.0', 'v10.0.0', 'v2.0.0', 'v2.1.0', 'v3.0.0',
            'zh-pages'
        ]
    elif sort == 'time':
        expected = [
            'v2.0.0', 'zh-pages', 'master', 'v10.0.0', 'v3.0.0', 'v2.1.0',
            'v1.2.0'
        ]
    elif sort == 'semver':
        expected = [
            'v10.0.0', 'v3.0.0', 'v2.1.0', 'v2.0.0', 'v1.2.0', 'zh-pages',
            'master'
        ]
    elif sort == 'semver,alpha':
        expected = [
            'v10.0.0', 'v3.0.0', 'v2.1.0', 'v2.0.0', 'v1.2.0', 'master',
            'zh-pages'
        ]
    elif sort == 'semver,time':
        expected = [
            'v10.0.0', 'v3.0.0', 'v2.1.0', 'v2.0.0', 'v1.2.0', 'zh-pages',
            'master'
        ]
    else:
        expected = [i[1] for i in remotes]

    assert actual == expected
예제 #29
0
def test_layout_override(tmpdir, local_docs):
    """Verify users can still override layout.html.

    :param tmpdir: pytest fixture.
    :param local_docs: conftest fixture.
    """
    versions = Versions([('', 'master', 'heads', 1, 'conf.py')])

    local_docs.join('conf.py').write(
        'templates_path = ["_templates"]\n'
    )
    local_docs.ensure('_templates', 'layout.html').write(
        '{% extends "!layout.html" %}\n'
        '{% block extrahead %}\n'
        '<!-- Hidden Message -->\n'
        '{% endblock %}\n'
    )

    target = tmpdir.ensure_dir('target_master')
    build(str(local_docs), str(target), versions, 'master', True)
    contents = target.join('contents.html').read()
    assert '<!-- Hidden Message -->' in contents
def test_changes(monkeypatch, local):
    """Test with changes to commit and push successfully.

    :param monkeypatch: pytest fixture.
    :param local: conftest fixture.
    """
    monkeypatch.setenv('LANG', 'en_US.UTF-8')
    monkeypatch.setenv('TRAVIS_BUILD_ID', '12345')
    monkeypatch.setenv('TRAVIS_BRANCH', 'master')
    old_sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip()
    local.ensure('new', 'new.txt')
    local.join('README').write('test\n', mode='a')

    actual = commit_and_push(str(local), 'origin', Versions(REMOTES))
    assert actual is True
    sha = pytest.run(local, ['git', 'rev-parse', 'HEAD']).strip()
    assert sha != old_sha
    pytest.run(local, ['git', 'diff-index', '--quiet', 'HEAD', '--'])  # Exit 0 if nothing changed.

    # Verify commit message.
    subject, body = pytest.run(local, ['git', 'log', '-n1', '--pretty=%B']).strip().split('\n', 2)[::2]
    assert subject == 'AUTO sphinxcontrib-versioning 20160722 0772e5ff32a'
    assert body == 'LANG: en_US.UTF-8\nTRAVIS_BRANCH: master\nTRAVIS_BUILD_ID: 12345'