Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add view controllers #407

Merged
merged 8 commits into from
Feb 19, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
test: add integration tests for views
  • Loading branch information
sansyrox committed Feb 18, 2023
commit c347963e8251ee5fb30611d2938714807952ab0f
Empty file added integration_tests/__init__.py
Empty file.
25 changes: 25 additions & 0 deletions integration_tests/base_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from robyn.robyn import Response
from robyn.templating import JinjaTemplate

from integration_tests.views import SyncView, AsyncView

app = Robyn(__file__)
websocket = WS(app, "/web_socket")

Expand Down Expand Up @@ -482,6 +484,27 @@ async def async_raise():
raise Exception()


# ===== Views =====

@app.view("/sync_decorator_view")
def sync_decorator_view():
def get():
return "Hello, world!"

def post(request):
body = bytearray(request["body"]).decode("utf-8")
return {"status_code": 200, "body": body}


@app.view("/async_decorator_view")
def async_decorator_view():
async def get():
return "Hello, world!"

async def post(request):
body = bytearray(request["body"]).decode("utf-8")
return {"status_code": 200, "body": body}

# ===== Main =====


Expand All @@ -493,4 +516,6 @@ async def async_raise():
index_file="index.html",
)
app.startup_handler(startup_handler)
app.add_view("/sync_view", SyncView)
app.add_view("/async_view", AsyncView)
sansyrox marked this conversation as resolved.
Show resolved Hide resolved
app.start(port=8080)
2 changes: 1 addition & 1 deletion integration_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import platform

import pytest
from helpers.network_helpers import get_network_host
from integration_tests.helpers.network_helpers import get_network_host


def spawn_process(command: List[str]) -> subprocess.Popen:
Expand Down
25 changes: 25 additions & 0 deletions integration_tests/test_async_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from integration_tests.helpers.http_methods_helpers import get, post


def test_get_async_view(session):
r = get("/async_view")
assert r.status_code == 200
assert r.text == "Hello, world!"


def test_post_async_view(session):
r = post("/async_view", data={"name": "John"})
assert r.status_code == 200
assert "John" in r.text


def test_get_async_decorator_view(session):
r = get("/async_decorator_view")
assert r.status_code == 200
assert r.text == "Hello, world!"


def test_post_async_decorator_view(session):
r = post("/async_decorator_view", data={"name": "John"})
assert r.status_code == 200
assert "John" in r.text
2 changes: 1 addition & 1 deletion integration_tests/test_base_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import requests

from helpers.network_helpers import get_network_host
from integration_tests.helpers.network_helpers import get_network_host
sansyrox marked this conversation as resolved.
Show resolved Hide resolved


def test_default_url_index_request(default_session):
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_basic_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import pytest

from helpers.http_methods_helpers import get
from integration_tests.helpers.http_methods_helpers import get


@pytest.mark.parametrize(
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_delete_requests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from helpers.http_methods_helpers import delete
from integration_tests.helpers.http_methods_helpers import delete


@pytest.mark.parametrize("function_type", ["sync", "async"])
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_file_download.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from helpers.http_methods_helpers import get
from integration_tests.helpers.http_methods_helpers import get


@pytest.mark.parametrize("function_type", ["sync", "async"])
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_get_requests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from requests import Response

from helpers.http_methods_helpers import get
from integration_tests.helpers.http_methods_helpers import get


@pytest.mark.parametrize("function_type", ["sync", "async"])
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_middlewares.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from helpers.http_methods_helpers import get
from integration_tests.helpers.http_methods_helpers import get


@pytest.mark.skip(reason="Fix middleware request headers modification")
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_patch_requests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from helpers.http_methods_helpers import patch
from integration_tests.helpers.http_methods_helpers import patch


@pytest.mark.parametrize("function_type", ["sync", "async"])
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_post_requests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from helpers.http_methods_helpers import post
from integration_tests.helpers.http_methods_helpers import post


@pytest.mark.parametrize("function_type", ["sync", "async"])
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_put_requests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from helpers.http_methods_helpers import put
from integration_tests.helpers.http_methods_helpers import put


@pytest.mark.parametrize("function_type", ["sync", "async"])
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/test_status_code.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from helpers.http_methods_helpers import get
from integration_tests.helpers.http_methods_helpers import get


def test_404_status_code(session):
Expand Down
25 changes: 25 additions & 0 deletions integration_tests/test_sync_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from integration_tests.helpers.http_methods_helpers import get, post


def test_get_async_view(session):
r = get("/sync_view")
assert r.status_code == 200
sansyrox marked this conversation as resolved.
Show resolved Hide resolved
assert r.text == "Hello, world!"


def test_post_async_view(session):
r = post("/sync_view", data={"name": "John"})
assert r.status_code == 200
assert "John" in r.text


def test_get_async_decorator_view(session):
r = get("/sync_decorator_view")
assert r.status_code == 200
assert r.text == "Hello, world!"


def test_post_async_decorator_view(session):
r = post("/sync_decorator_view", data={"name": "John"})
assert r.status_code == 200
assert "John" in r.text
4 changes: 4 additions & 0 deletions integration_tests/views/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .test_view import SyncView
from .async_view import AsyncView

__all__ = ["SyncView", "AsyncView"]
11 changes: 11 additions & 0 deletions integration_tests/views/async_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def AsyncView():
sansyrox marked this conversation as resolved.
Show resolved Hide resolved
async def get():
return "Hello, world!"

async def post(request):
body = bytes(request["body"]).decode("utf-8")
return {
"status": 200,
"body": body,
"headers": {"Content-Type": "text/json"},
}
11 changes: 11 additions & 0 deletions integration_tests/views/test_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def SyncView():
def get():
return "Hello, world!"

def post(request):
body = bytes(request["body"]).decode("utf-8")
return {
"status": 200,
"body": body,
"headers": {"Content-Type": "text/json"},
}
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ name = "robyn"
dependencies = [
'watchdog == 2.2.1',
'multiprocess == 0.70.14',
'nestd==0.3.1',
# conditional
'uvloop == 0.17.0; sys_platform == "darwin"',
'uvloop == 0.17.0; platform_machine == "x86_64"',
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ uvloop; platform_system!="Windows"
watchdog==2.2.1
multiprocess==0.70.14
jinja2==3.1.2
nestd==0.3.0
nestd==0.3.1
19 changes: 4 additions & 15 deletions robyn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from robyn.ws import WS



class Robyn:
"""This is the python wrapper for the Robyn binaries."""

Expand Down Expand Up @@ -167,44 +166,34 @@ def terminating_signal_handler(_sig, _frame):
observer.stop()
observer.join()

def add_view(self, endpoint: str, view, const: bool = False):
def add_view(self, endpoint: str, view: Callable, const: bool = False):
"""
[This is base handler for the view decorators]

:param endpoint [str]: [endpoint for the route added]
:param handler [function]: [represents the function passed as a parent handler for single route with different route types]
"""
http_methods = {"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"}
AntoineRR marked this conversation as resolved.
Show resolved Hide resolved

def get_functions(view):
functions = get_all_nested(view)
output = []
for name, handler in functions:
route_type = name.upper()
if route_type in [
"GET",
"POST",
"PUT",
"DELETE",
"PATCH",
"HEAD",
"OPTIONS",
]:
if route_type in http_methods:
output.append((route_type.upper(), handler))
sansyrox marked this conversation as resolved.
Show resolved Hide resolved
return output

handlers = get_functions(view)
routes = []
for route_type, handler in handlers:
routes.append(self._add_route(route_type, endpoint, handler, const))
return routes
self._add_route(route_type, endpoint, handler, const)

def view(self, endpoint: str, const: bool = False):
"""
The @app.view decorator to add a view with the GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS method

:param endpoint str: endpoint to server the route
"""

def inner(handler):
return self.add_view(endpoint, handler, const)

Expand Down