Create Github Action for pytest (#12)

This commit is contained in:
Nikhil Rao 2022-11-21 18:50:59 -08:00 committed by GitHub
parent 1f817c637f
commit c4b1f2c669
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 101 additions and 39 deletions

39
.github/workflows/python-checks.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Python application
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- uses: snok/install-poetry@v1
with:
version: 1.1.14
virtualenvs-create: true
virtualenvs-in-project: true
- run: poetry install --no-interaction --no-root
- run: poetry install --no-interaction
- run: poetry run pytest tests
- run: poetry run pyright pynecone tests
- run: poetry run pydocstyle pynecone tests
- run: poetry run darglint pynecone tests

View File

@ -1,30 +1,13 @@
"""Create a list of components from an iterable."""
from __future__ import annotations
from typing import Any, List, Protocol, runtime_checkable
from typing import Any, Callable, List
from pynecone.components.component import Component
from pynecone.components.tags import IterTag, Tag
from pynecone.var import BaseVar, Var
@runtime_checkable
class RenderFn(Protocol):
"""A function that renders a component."""
def __call__(self, *args, **kwargs) -> Component:
"""Render a component.
Args:
*args: The positional arguments.
**kwargs: The keyword arguments.
Returns: # noqa: DAR202
The rendered component.
"""
...
class Foreach(Component):
"""Display a foreach."""
@ -32,10 +15,10 @@ class Foreach(Component):
iterable: Var[List]
# A function from the render args to the component.
render_fn: RenderFn
render_fn: Callable
@classmethod
def create(cls, iterable: Var[List], render_fn: RenderFn, **props) -> Foreach:
def create(cls, iterable: Var[List], render_fn: Callable, **props) -> Foreach:
"""Create a foreach component.
Args:

View File

@ -14,7 +14,7 @@ class Markdown(Component):
tag = "ReactMarkdown"
src: Var[str] = "" # type: ignore
src: Var[str]
def _get_custom_code(self) -> str:
return "import 'katex/dist/katex.min.css'"

View File

@ -1,3 +1,5 @@
"""The Pynecone config."""
from typing import Optional
from pynecone import constants

View File

@ -467,7 +467,11 @@ class StateManager(Base):
redis: Any = None
def setup(self, state: Type[State]):
"""Setup the state manager."""
"""Set up the state manager.
Args:
state: The state class to use.
"""
self.state = state
self.redis = utils.get_redis()

View File

@ -15,7 +15,6 @@ import sys
from collections import defaultdict
from subprocess import PIPE
from typing import _GenericAlias # type: ignore
from typing import _UnionGenericAlias # type: ignore
from typing import (
TYPE_CHECKING,
Any,
@ -71,7 +70,7 @@ def get_base_class(cls: Type) -> Type:
"""
# For newer versions of Python.
try:
from types import GenericAlias
from types import GenericAlias # type: ignore
if isinstance(cls, GenericAlias):
return get_base_class(cls.__origin__)
@ -79,11 +78,18 @@ def get_base_class(cls: Type) -> Type:
pass
# Check Union types first.
if isinstance(cls, _UnionGenericAlias):
return tuple(get_base_class(arg) for arg in get_args(cls))
try:
from typing import _UnionGenericAlias # type: ignore
if isinstance(cls, _UnionGenericAlias):
return tuple(get_base_class(arg) for arg in get_args(cls))
except:
pass
# Check other generic aliases.
if isinstance(cls, _GenericAlias):
if cls.__origin__ == Union:
return tuple(get_base_class(arg) for arg in get_args(cls))
return get_base_class(cls.__origin__)
# This is the base class.
@ -105,7 +111,7 @@ def _issubclass(
# Special check for Any.
if cls_check == Any:
return True
if cls == Any:
if cls == Any or cls == Callable:
return False
cls_base = get_base_class(cls)
cls_check_base = get_base_class(cls_check)
@ -240,8 +246,13 @@ def get_config() -> Config:
Returns:
The app config.
"""
from pynecone.config import Config
sys.path.append(os.getcwd())
return __import__(constants.CONFIG_MODULE).config
try:
return __import__(constants.CONFIG_MODULE).config
except:
return Config(app_name="")
def get_bun_path():
@ -694,9 +705,9 @@ def format_string(string: str) -> str:
Returns:
The formatted string.
"""
# Escale backticks.
string = string.replace("\`", "`") # type: ignore
string = string.replace("`", "\`") # type: ignore
# Escape backticks.
string = string.replace(r"\`", "`")
string = string.replace("`", r"\`")
# Wrap the string so it looks like {`string`}.
string = wrap(string, "`")
@ -859,7 +870,7 @@ def get_redis():
The redis client.
"""
try:
import redis
import redis # type: ignore
except:
return None

View File

@ -4,7 +4,7 @@ import pytest
from pynecone.components import Box
from pynecone.components.tags import CondTag, IterTag, Tag
from pynecone.event import EventHandler, EventSpec, EventChain
from pynecone.event import EventChain, EventHandler, EventSpec
from pynecone.var import BaseVar, Var

View File

@ -3,8 +3,8 @@ from typing import Type
import pytest
from pynecone.app import App, DefaultState
from pynecone.middleware import HydrateMiddleware
from pynecone.components import Box
from pynecone.middleware import HydrateMiddleware
from pynecone.state import State
from pynecone.style import Style
@ -21,7 +21,11 @@ def app() -> App:
@pytest.fixture
def index_page():
"""An index page."""
"""An index page.
Returns:
The index page.
"""
def index():
return Box.create("Index")
@ -31,7 +35,11 @@ def index_page():
@pytest.fixture
def about_page():
"""An index page."""
"""An about page.
Returns:
The about page.
"""
def about():
return Box.create("About")
@ -107,7 +115,7 @@ def test_initialize_with_state(TestState: Type[State]):
"""Test setting the state of an app.
Args:
DefaultState: The default state.
TestState: The default state.
"""
app = App(state=TestState)
assert app.state == TestState
@ -123,7 +131,7 @@ def test_set_and_get_state(TestState: Type[State]):
"""Test setting and getting the state of an app with different tokens.
Args:
DefaultState: The default state.
TestState: The default state.
"""
app = App(state=TestState)

View File

@ -1,6 +1,21 @@
import pytest
from pynecone.event import Event, EventHandler, EventSpec
from pynecone.var import Var
def make_var(value) -> Var:
"""Make a variable.
Args:
value: The value of the var.
Returns:
The var.
"""
var = Var.create(value)
assert var is not None
return var
def test_create_event():
@ -28,7 +43,7 @@ def test_call_event_handler():
assert event_spec.args == ()
handler = EventHandler(fn=test_fn_with_args)
event_spec = handler("first", "second")
event_spec = handler(make_var("first"), make_var("second"))
assert event_spec.handler == handler
assert event_spec.local_args == ()