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
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,41 @@ The first param represent the relative path and second represent the `controller

The `controller` can be created in `app/controllers` and action is method of `controller`.

You can use `Router.all()` to register all routes of `CRUD`.

```python
Router.all("users")
```

The previous command produce this:

```shell
users.create POST /users
users.delete DELETE /users/<id>
users.edit GET /users/<id>/edit
users.index GET /users
users.new GET /users/new
users.show GET /users/<id>
users.update PUT /users/<id>
```

You can also use `only parameter` to controll routes, e.g:

```python
Router.all("messages", only="index show new create")
```

The previous command produce this:

```shell
messages.create POST /messages
messages.index GET /messages
messages.new GET /messages/new
messages.show GET /messages/<id>
```

The paramenter `only` accept `string` or `array`, so, you can use `only=["index", "show", "new", "create"]`

## Controller

Now that configure routes, the `home_controller.py` file must contain the `HomeController` class, registering the `action`, e.g:
Expand Down
20 changes: 19 additions & 1 deletion app/controllers/messages_controller.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
class MessagesController:
def index(self):
return "messages"

def show(self, id):
return f"message {id}"

def new(self):
return "form"

def create(self):
return "message has been created", 201
return "message created", 201

def edit(self, id):
return f"form"

def update(self, id):
return f"updated messages: {id}"

def delete(self, id):
return f"delete message: {id}"
19 changes: 17 additions & 2 deletions app/controllers/users_controller.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
class UsersController:
def index(self):
return "users"

def show(self, id):
return f"user {id}"

def new(self):
return "form"

def create(self):
return "user created", 201

def edit(self, id):
return f"form"

def update(self, id):
return f"user {id} updated successfully"
return f"updated user: {id}"

def delete(self, id):
return f"user {id} has been destroyed"
return f"delete user: {id}"
7 changes: 4 additions & 3 deletions app/routes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from mvc_flask import Router


Router.get("/", "home#index")
Router.get("/hello", "home#hello")
Router.post("/messages", "messages#create")
Router.put("/users/<id>", "users#update")
Router.delete("/users/<id>", "users#delete")

Router.all("users")
Router.all("messages", only="index show new create")
2 changes: 1 addition & 1 deletion mvc_flask/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.0.0"
__version__ = "2.1.0"
44 changes: 44 additions & 0 deletions mvc_flask/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,47 @@ def delete(path: str, resource: str):
Router.ROUTES.append(
{controller: Model("DELETE", path, controller, action)}
)

@staticmethod
def all(resource: str, only=None):
group = [
"index",
"show",
"new",
"create",
"edit",
"update",
"delete",
]
actions = only.split() if isinstance(only, str) else only
Router._add_routes(resource, actions if actions else group)

@staticmethod
def _add_routes(name, actions):
groups = {
"index": "get",
"new": "get",
"create": "post",
}
parameters = {
"show": "get",
"edit": "get",
"update": "put",
"delete": "delete",
}
urls = {
"new": "/new",
"edit": "/<id>/edit",
"show": "/<id>",
"update": "/<id>",
"delete": "/<id>",
}

for action in actions:
path = f"/{name}{urls[action]}" if action in urls else f"/{name}"

if action in parameters:
getattr(Router, parameters[action])(path, f"{name}#{action}")
continue

getattr(Router, groups[action])(path, f"{name}#{action}")
199 changes: 86 additions & 113 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[tool.poetry]
name = "mvc-flask"
version = "2.0.0"
description = "turn standard flask into mvc"
authors = ["Marcus Pereira <oi@negros.dev>"]
version = "2.1.0"
description = "turn standard Flask into mvc"
authors = ["Marcus Pereira <marcus@negros.dev>"]

readme = "README.md"
license = "MIT"
Expand Down
36 changes: 36 additions & 0 deletions tests/messages_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from flask import url_for
from ward import test

from tests.fixtures import test_client


@test("GET /messages")
def _(client=test_client):
resp = client.get(url_for("messages.index", id=1))

assert resp.status_code == 200
assert "messages" in resp.get_data(as_text=True)


@test("GET /messages/1")
def _(client=test_client):
resp = client.get(url_for("messages.show", id=1))

assert resp.status_code == 200
assert "message 1" in resp.get_data(as_text=True)


@test("GET /messages/new")
def _(client=test_client):
resp = client.get(url_for("messages.new"))

assert resp.status_code == 200
assert "form" in resp.get_data(as_text=True)


@test("POST /messages")
def _(client=test_client):
resp = client.post(url_for("messages.create"))

assert resp.status_code == 201
assert "message created" in resp.get_data(as_text=True)
38 changes: 0 additions & 38 deletions tests/request_test.py

This file was deleted.

38 changes: 35 additions & 3 deletions tests/routes_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from collections import Counter

from flask import url_for
from ward import test

from tests.fixtures import test_client
Expand Down Expand Up @@ -38,12 +37,45 @@ def _(client=test_client):
assert "home.hello" in endpoints


@test("count GET routes")
@test("count GET")
def _(client=test_client):
methods = [
route
for routes in client.application.url_map.iter_rules()
for route in routes.methods
]

assert methods.count("GET") == 3
assert methods.count("GET") == 10


@test("count POST")
def _(client=test_client):
methods = [
route
for routes in client.application.url_map.iter_rules()
for route in routes.methods
]

assert methods.count("POST") == 2


@test("count PUT")
def _(client=test_client):
methods = [
route
for routes in client.application.url_map.iter_rules()
for route in routes.methods
]

assert methods.count("PUT") == 1


@test("count DELETE")
def _(client=test_client):
methods = [
route
for routes in client.application.url_map.iter_rules()
for route in routes.methods
]

assert methods.count("DELETE") == 1
2 changes: 1 addition & 1 deletion tests/test_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

@test("check version")
def _():
expect.assert_equal(__version__, "2.0.0", None)
expect.assert_equal(__version__, "2.1.0", None)
60 changes: 60 additions & 0 deletions tests/users_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from flask import url_for
from ward import test

from tests.fixtures import test_client


@test("GET /users")
def _(client=test_client):
resp = client.get(url_for("users.index", id=1))

assert resp.status_code == 200
assert "users" in resp.get_data(as_text=True)


@test("GET /users/1")
def _(client=test_client):
resp = client.get(url_for("users.show", id=1))

assert resp.status_code == 200
assert "user 1" in resp.get_data(as_text=True)


@test("GET /users/new")
def _(client=test_client):
resp = client.get(url_for("users.new"))

assert resp.status_code == 200
assert "form" in resp.get_data(as_text=True)


@test("POST /users")
def _(client=test_client):
resp = client.post(url_for("users.create"))

assert resp.status_code == 201
assert "user created" in resp.get_data(as_text=True)


@test("GET /users/1/edit")
def _(client=test_client):
resp = client.get(url_for("users.edit", id=1))

assert resp.status_code == 200
assert "form" in resp.get_data(as_text=True)


@test("PUT /users/1")
def _(client=test_client):
resp = client.put(url_for("users.update", id=1))

assert resp.status_code == 200
assert "updated user: 1" in resp.get_data(as_text=True)


@test("DELETE /users/1")
def _(client=test_client):
resp = client.delete(url_for("users.delete", id=1))

assert resp.status_code == 200
assert "delete user: 1" in resp.get_data(as_text=True)