diff --git a/docs/howto.md b/docs/howto.md index ff939d8b..c4a13c43 100644 --- a/docs/howto.md +++ b/docs/howto.md @@ -37,6 +37,50 @@ on Python 3.11: nox -s test-3.11 -- -k simple_search +## Doctests + +[Doctests](https://docs.python.org/3/library/doctest.html) are automatically +enabled for all docstrings in the `tantivy` module. Here is a very basic +introduction. Consider the following hypothetical Rust `struct`: + +```rust +/// Tantivy's Document is the object that can be indexed and then searched for. +/// +/// Documents are fundamentally a collection of unordered tuples +/// (field_name, value). In this list, one field may appear more than once. +/// +/// Example: +/// >>> doc = tantivy.Document() +/// >>> doc.add_text("title", "The Old Man and the Sea") +/// >>> doc.add_text("body", ("He was an old man who fished alone in a " +/// ... "skiff in the Gulf Stream and he had gone " +/// ... "eighty-four days now without taking a fish.")) +/// >>> doc +/// Document(body=[He was an ],title=[The Old Ma]) +/// +#[pyclass(module = "tantivy")] +#[derive(Clone, Default, PartialEq)] +pub(crate) struct Document { + pub(crate) field_values: BTreeMap>, +} +``` + +When the tests are executed, pytest will automatically search all the docstrings +for `>>>` and `...` and execute the code in the docstring. The output of the +code is compared to the text that follows the code. If the output matches, the +test passes. If the output does not match, the test fails. + +In the above example, a Tantivy document object is created, and then the +representation of the document is printed. This representation, and indeed any +output that manual typing would produce, is compared to the text that follows +and this is how doctests work. + +Doctests are a great way to ensure that the documentation is accurate and up to +date, and doctests are therefore encouraged be present on every public +interface that users will interact with. However, doctest are not suitable +for coverage testing and other more advanced testing methods so you must +judge when to use them. + ## Working on tantivy-py documentation Please be aware that this documentation is structured using the [Diátaxis](https://diataxis.fr/) framework. In very simple terms, this framework will suggest the correct location for different kinds of documentation. Please make sure you gain a basic understanding of the goals of the framework before making large pull requests with new documentation. diff --git a/pyproject.toml b/pyproject.toml index d4431985..9383f3e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,3 +13,15 @@ dev = [ [tool.maturin] bindings = "pyo3" + +[tool.pytest.ini_options] +# Set the durations option and doctest modules +# See https://docs.pytest.org/en/latest/usage.html#durations +addopts = "--doctest-modules --durations=10" +# Use the `--ignore-glob` setting to exclude the `noxfile.py` module from the doctests +# See https://docs.pytest.org/en/latest/reference.html#confval-ignore_glob +testpaths = [ + "tests", + "tantivy", + "src", +] diff --git a/src/document.rs b/src/document.rs index f4e2cb7d..ae640d00 100644 --- a/src/document.rs +++ b/src/document.rs @@ -428,8 +428,10 @@ impl<'a> From<&'a Value> for BorrowedSerdeValue<'a> { /// >>> doc = tantivy.Document() /// >>> doc.add_text("title", "The Old Man and the Sea") /// >>> doc.add_text("body", ("He was an old man who fished alone in a " -/// "skiff in the Gulf Stream and he had gone " -/// "eighty-four days now without taking a fish.")) +/// ... "skiff in the Gulf Stream and he had gone " +/// ... "eighty-four days now without taking a fish.")) +/// >>> doc +/// Document(body=[He was an ],title=[The Old Ma]) /// /// For simplicity, it is also possible to build a `Document` by passing the field /// values directly as constructor arguments. @@ -451,16 +453,16 @@ impl<'a> From<&'a Value> for BorrowedSerdeValue<'a> { /// /// Example: /// >>> schema = ( -/// SchemaBuilder() -/// .add_unsigned_field("unsigned") -/// .add_integer_field("signed") -/// .add_float_field("float") -/// .build() -/// ) +/// ... SchemaBuilder() +/// ... .add_unsigned_field("unsigned") +/// ... .add_integer_field("signed") +/// ... .add_float_field("float") +/// ... .build() +/// ... ) /// >>> doc = tantivy.Document.from_dict( -/// {"unsigned": 1000, "signed": -5, "float": 0.4}, -/// schema, -/// ) +/// ... {"unsigned": 1000, "signed": -5, "float": 0.4}, +/// ... schema, +/// ... ) #[pyclass(module = "tantivy")] #[derive(Clone, Default, PartialEq)] pub(crate) struct Document {