Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions lib/docs/filters/pytest/clean_html.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module Docs
class Pytest
class CleanHtmlFilter < Filter
def call
# Removed here rather than by sphinx/clean_html because the entries
# filter reads the headings' text content
css('.headerlink').remove

# "[source]" links pointing to the highlighted sources, which aren't scraped
css('.viewcode-link').each do |node|
node.parent.remove
end

# Tab sets (e.g. the configuration file formats) are made of hidden radio
# inputs and labels, which don't work without the theme's stylesheet. The
# tabs are turned into consecutive sections instead.
css('.tab-input').remove

css('.tab-label').each do |node|
node.name = 'h4'
node.remove_attribute('class')
node.remove_attribute('for')
end

css('.tab-content', '.tab-set').each do |node|
node.before(node.children).remove
end

doc
end
end
end
end
71 changes: 71 additions & 0 deletions lib/docs/filters/pytest/entries.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
module Docs
class Pytest
class EntriesFilter < Docs::EntriesFilter
# The documentation follows the Diátaxis framework, which its URLs mirror
TYPE_BY_DIRECTORY = {
'how-to' => 'How-to guides',
'reference' => 'Reference',
'explanation' => 'Explanation',
'example' => 'Examples'
}

# The only page documenting objects; its second-level sections (Functions,
# Marks, Fixtures, Hooks, ...) are used as the types of those objects
API_REFERENCE_SLUG = 'reference/reference'

# Objects are documented under the module implementing them, which is part
# of neither pytest's public API nor of the names shown in the signatures
PRIVATE_MODULE = /\Apytest\.(?:capture|doctest|fixtures|hookspec|junitxml|logging|monkeypatch|nodes|python|recwarn|tmpdir)\./

CALLABLE = /\b(?:function|method|classmethod|staticmethod)\b/

def get_name
at_css('h1').content.strip
end

def get_type
TYPE_BY_DIRECTORY[slug.split('/').first] || 'Get Started'
end

def additional_entries
return [] unless slug == API_REFERENCE_SLUG

entries = []

css('> section').each do |section|
next unless heading = section.at_css('> h2')
type = heading.content.strip

section.css('dl.py > dt[id], dl.std > dt[id]').each do |node|
entries << [object_name(node), node['id'], type]
end

# Constants and a few other objects (e.g. custom marks) are documented
# as plain sections rather than as Sphinx objects
section.css('> section').each do |subsection|
next if subsection.at_css('dl.py > dt[id], dl.std > dt[id]')
next unless subheading = subsection.at_css('> h3')
entries << [subheading.content.strip, subsection['id'], type]
end
end

entries
end

private

def object_name(node)
classes = node.parent['class']

# Configuration options, command-line flags, environment variables and
# global variables have prefixed ids (e.g. "confval-addopts"), the
# signature is the only place where they appear as one writes them
return node.at_css('.descname').content.strip if classes.include?('std')

name = node['id'].sub(PRIVATE_MODULE, '')
name << '()' if classes =~ CALLABLE
name
end
end
end
end
43 changes: 43 additions & 0 deletions lib/docs/scrapers/pytest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module Docs
class Pytest < UrlScraper
self.name = 'pytest'
self.type = 'sphinx'
self.release = '9.1.1'
self.base_url = 'https://docs.pytest.org/en/stable/'
self.root_path = 'index.html'
self.links = {
home: 'https://pytest.org/',
code: 'https://github.com/pytest-dev/pytest'
}

# The navigation lives in the Furo sidebar, i.e. outside of the scraped
# container, and the toctrees on the home page are hidden ones. The section
# indexes, whose toctrees are part of the content, are used as entry points
# instead.
self.initial_paths = %w(
getting-started.html
how-to/index.html
reference/index.html
explanation/index.html
example/index.html)

html_filters.push 'pytest/clean_html', 'pytest/entries', 'sphinx/clean_html'

options[:container] = 'article[role="main"] > section'

# Restrict the scraper to the documentation itself, leaving out the project's
# meta pages (changelog, contributing, sponsors, announcements, ...) and the
# highlighted sources under _modules/.
options[:only] = %w(index.html getting-started.html)
options[:only_patterns] = [/\Ahow-to\//, /\Areference\//, /\Aexplanation\//, /\Aexample\//]

options[:attribution] = <<-HTML
&copy; 2015&ndash;2026 Holger Krekel and pytest-dev team<br>
Licensed under the MIT License.
HTML

def get_latest_version(opts)
get_latest_github_release('pytest-dev', 'pytest', opts)
end
end
end
Binary file added public/icons/docs/pytest/16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/docs/pytest/16@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/icons/docs/pytest/SOURCE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/pytest-dev/pytest/blob/main/doc/en/_static/pytest1.png
Loading