Skip to content

Commit

Permalink
Feature/test doc snippets (#40)
Browse files Browse the repository at this point in the history
* test(ci): add readme snippet test runner

 - gather up and execute the python snippets in the Readme to make sure they work.

* chore: update docs and mathy_pydoc version

* chore: update docs
  • Loading branch information
justindujardin authored Nov 22, 2020
1 parent e322083 commit 97f51a1
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 27 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ matrix:
- sh tools/setup.sh
script:
- sh tools/lint.sh
- sh tools/test_readme.sh
- sh tools/test.sh
after_success:
- sh tools/codecov.sh
Expand Down
52 changes: 26 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,23 @@ pathy>=0.1.37,<0.2.0

# Pathy <kbd>class</kbd>

```python
```python (doc)
Pathy(self, args, kwargs)
```

Subclass of `pathlib.Path` that works with bucket APIs.

## exists <kbd>method</kbd>

```python
```python (doc)
Pathy.exists(self) -> bool
```

Returns True if the path points to an existing bucket, blob, or prefix.

## fluid <kbd>classmethod</kbd>

```python
```python (doc)
Pathy.fluid(
path_candidate: Union[str, Pathy, pathlib.Path],
) -> Union[Pathy, pathlib.Path]
Expand All @@ -108,7 +108,7 @@ assert fluid_path.prefix == "foo.txt/"

## from_bucket <kbd>classmethod</kbd>

```python
```python (doc)
Pathy.from_bucket(bucket_name: str) -> 'Pathy'
```

Expand All @@ -124,7 +124,7 @@ assert str(Pathy.from_bucket("two")) == "gs://two/"

## glob <kbd>method</kbd>

```python
```python (doc)
Pathy.glob(
self: 'Pathy',
pattern: str,
Expand All @@ -136,7 +136,7 @@ blobs.

## is_dir <kbd>method</kbd>

```python
```python (doc)
Pathy.is_dir(self: 'Pathy') -> bool
```

Expand All @@ -148,7 +148,7 @@ Returns False if it points to a blob or the path doesn't exist.

## is_file <kbd>method</kbd>

```python
```python (doc)
Pathy.is_file(self: 'Pathy') -> bool
```

Expand All @@ -160,7 +160,7 @@ exist.

## iterdir <kbd>method</kbd>

```python
```python (doc)
Pathy.iterdir(
self: 'Pathy',
) -> Generator[Pathy, NoneType, NoneType]
Expand All @@ -170,7 +170,7 @@ Iterate over the blobs found in the given bucket or blob prefix path.

## mkdir <kbd>method</kbd>

```python
```python (doc)
Pathy.mkdir(
self,
mode: int = 511,
Expand All @@ -193,7 +193,7 @@ Raises FileExistsError if exist_ok is false and the bucket already exists.

## open <kbd>method</kbd>

```python
```python (doc)
Pathy.open(
self: 'Pathy',
mode: str = 'r',
Expand All @@ -210,7 +210,7 @@ providers.

## owner <kbd>method</kbd>

```python
```python (doc)
Pathy.owner(self: 'Pathy') -> Optional[str]
```

Expand All @@ -220,7 +220,7 @@ not supported by the bucket API provider.

## rename <kbd>method</kbd>

```python
```python (doc)
Pathy.rename(self: 'Pathy', target: Union[str, pathlib.PurePath]) -> None
```

Expand All @@ -234,7 +234,7 @@ to match the target prefix.

## replace <kbd>method</kbd>

```python
```python (doc)
Pathy.replace(self: 'Pathy', target: Union[str, pathlib.PurePath]) -> None
```

Expand All @@ -244,7 +244,7 @@ If target points to an existing path, it will be replaced.

## resolve <kbd>method</kbd>

```python
```python (doc)
Pathy.resolve(self, strict: bool = False) -> 'Pathy'
```

Expand All @@ -259,7 +259,7 @@ assert path.resolve() == Pathy("gs://my_bucket/blob")

## rglob <kbd>method</kbd>

```python
```python (doc)
Pathy.rglob(
self: 'Pathy',
pattern: str,
Expand All @@ -271,15 +271,15 @@ all matched blobs. Imagine adding "\*\*/" before a call to glob.

## rmdir <kbd>method</kbd>

```python
```python (doc)
Pathy.rmdir(self: 'Pathy') -> None
```

Removes this bucket or blob prefix. It must be empty.

## samefile <kbd>method</kbd>

```python
```python (doc)
Pathy.samefile(
self: 'Pathy',
other_path: Union[str, bytes, int, pathlib.Path],
Expand All @@ -290,15 +290,15 @@ Determine if this path points to the same location as other_path.

## stat <kbd>method</kbd>

```python
```python (doc)
Pathy.stat(self: 'Pathy') -> pathy.base.BlobStat
```

Returns information about this bucket path.

## to_local <kbd>classmethod</kbd>

```python
```python (doc)
Pathy.to_local(
blob_path: Union[Pathy, str],
recurse: bool = True,
Expand All @@ -312,7 +312,7 @@ as their updated timestamps change.

## touch <kbd>method</kbd>

```python
```python (doc)
Pathy.touch(self: 'Pathy', mode: int = 438, exist_ok: bool = True) -> None
```

Expand All @@ -324,7 +324,7 @@ FileExistsError is raised.

# BlobStat <kbd>dataclass</kbd>

```python
```python (doc)
BlobStat(
self,
size: Optional[int],
Expand All @@ -336,7 +336,7 @@ Stat for a bucket item

# use_fs <kbd>function</kbd>

```python
```python (doc)
use_fs(
root: Optional[str, pathlib.Path, bool] = None,
) -> Optional[pathy.file.BucketClientFS]
Expand All @@ -349,15 +349,15 @@ applications.

# get_fs_client <kbd>function</kbd>

```python
```python (doc)
get_fs_client() -> Optional[pathy.file.BucketClientFS]
```

Get the file-system client (or None)

# use_fs_cache <kbd>function</kbd>

```python
```python (doc)
use_fs_cache(
root: Optional[str, pathlib.Path, bool] = None,
) -> Optional[pathlib.Path]
Expand All @@ -370,15 +370,15 @@ times, or need to pass a local file path to a third-party library.

# get_fs_cache <kbd>function</kbd>

```python
```python (doc)
get_fs_cache() -> Optional[pathlib.Path]
```

Get the folder that holds file-system cached blobs and timestamps.

# set_client_params <kbd>function</kbd>

```python
```python (doc)
set_client_params(scheme: str, kwargs: Any) -> None
```

Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ black
pytest-coverage
tox
mock
mathy_pydoc
mathy_pydoc>=0.7.22,<0.8.0
typer-cli

# test serializing spacy models using Pathy in place of Path
Expand Down
48 changes: 48 additions & 0 deletions tools/test_readme.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import re
from pathlib import Path
from typing import List

import typer


def extract_code_snippets(lines: List[str]) -> List[str]:
inside_codeblock = False
blocks = []
current_block: List[str] = []
while len(lines) > 0:
line = lines.pop(0)
if not inside_codeblock:
inside_codeblock = re.match(r"```(p|P)ython$", line.strip())
else:
end_block = re.match(r"```", line.strip())
if end_block:
blocks.append("\n".join(current_block))
current_block = []
inside_codeblock = False
else:
current_block.append(line)

return blocks


def exec_snippet(text: str):
try:
exec(text)
except BaseException as identifier:
typer.echo(f"TEST Failed! == ERROR: {identifier}")
typer.echo("SNIPPET")
typer.echo(text)
typer.Exit(1)
raise identifier


def main(readme_file: Path):
readme_lines = readme_file.read_text().split("\n")
snippets = extract_code_snippets(readme_lines)
for snip in snippets:
exec_snippet(snip)
typer.echo("All snippets in readme executed without error!")


if __name__ == "__main__":
typer.run(main)
4 changes: 4 additions & 0 deletions tools/test_readme.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
set -e
. .env/bin/activate
python tools/test_readme.py README.md

0 comments on commit 97f51a1

Please sign in to comment.