You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/helpers.md
+1-3Lines changed: 1 addition & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,8 +4,6 @@ title: Helpers
4
4
5
5
If you've made it this far, you probably want to know some of the superpowers that _Fraction_ has, right? From here on, things get more interesting, in terms of features. Before diving into the reading, keep in mind that everything you'll see here is directly associated with the Laravel Way, but without resorting to nonsense.
6
6
7
-
First, _"WHY do we need helpers?"_ The answer is simple: **to make your life easier**. _Fraction_ provides a set of helpers that allow you to create and manage actions in a more straightforward way. Let's explore some of these helpers.
8
-
9
7
## Deferred Actions
10
8
11
9
As part of Laravel 11, you can trigger deferred actions simply by using the `deferred` method following the action declaration:
@@ -79,7 +77,7 @@ execute('create user', function () {
79
77
Behind the scenes, this will write a log to the requested `channel` to help you understand the exact moment the action was performed. The log output will be written as follows:
Keep in mind the log is written right after the process is dispatched, which means the log output does not represent the exact moment the action logic was executed. For situations where you are interacting with `deferred` or `queued` actions, you might see a difference between the log time and the actual execution time of the action logic, due to the way these actions are processed.
Copy file name to clipboardExpand all lines: docs/index.md
+10-7Lines changed: 10 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ title: About
6
6
7
7
There's no denying that the "Action Pattern" in the Laravel ecosystem is extremely useful and widely used. However, action classes require "too much content" to do basic things. Let's review a basic action class:
8
8
9
-
```php
9
+
```php {9}
10
10
namespace App\Actions;
11
11
12
12
use App\Models\User;
@@ -15,16 +15,18 @@ class CreateUser
15
15
{
16
16
public function handle(array $data): User
17
17
{
18
-
return User::create($data);
18
+
return User::create($data); // [!code focus]
19
19
}
20
20
}
21
21
```
22
22
23
-
We have a namespace, a class, a method, a return type, a model import, an array as arguments... all of this to create a user. It's overkill for such a simple task, isn't it? For this reason, the _Fraction_ solution is revolutionary in the context of Actions. _Fraction_ allows you to write actions in a simpler and more direct way, without the need for all this structure, **similar to what _PestPHP_ proposes.**
23
+
We have a namespace, a class, a method, a return type, a model import, an array as arguments... **all of this to create a user.** It's overkill for such a simple task, isn't it?
24
+
25
+
For this reason, the _Fraction_ solution is revolutionary in the context of Actions. _Fraction_ allows you to write actions in a simpler and more direct way, without the need for all this structure, **similar to what _PestPHP_ proposes.**
24
26
25
27
See what the same example would look like with _Fraction_:
26
28
27
-
```php
29
+
```php {3}
28
30
// app/Actions/Users.php
29
31
30
32
execute('create user', function (array $data) {
@@ -34,17 +36,18 @@ execute('create user', function (array $data) {
34
36
35
37
Then, anywhere in your application, you can `run` this action like this:
Copy file name to clipboardExpand all lines: docs/testing.md
+90-8Lines changed: 90 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,9 @@
2
2
title: Testing
3
3
---
4
4
5
-
There is nothing "special" about _Fraction_ regarding tests. This means that you can call your actions using `run` inside tests as normal. For example, if you have an action that `creates new user`, you can test it like this:
5
+
There is nothing "special" about _Fraction_ regarding tests. This means that you can call your actions using `run` inside tests as normal.
6
+
7
+
For example, if you have an action that `creates new user`:
6
8
7
9
```php
8
10
// app/Actions/CreateUser.php
@@ -14,11 +16,18 @@ execute('create new user', function (array $data) {
14
16
});
15
17
```
16
18
17
-
```php {2}
19
+
Then test your action like this:
20
+
21
+
::: code-group
22
+
23
+
```php {5} [PestPHP]
18
24
test('should be able to create new user', function () {
25
+
$name = fake()->name();
26
+
$email = fake()->email();
27
+
19
28
$user = run('create new user', [
20
-
'name' => $name = fake()->name(),
21
-
'email' => $email = fake()->email(),
29
+
'name' => $name,
30
+
'email' => $email,
22
31
'password' => bcrypt('password'),
23
32
]);
24
33
@@ -28,22 +37,95 @@ test('should be able to create new user', function () {
28
37
});
29
38
```
30
39
40
+
```php {16} [PhpUnit]
41
+
namespace Tests\Unit;
42
+
43
+
use Tests\TestCase;
44
+
use App\Models\User;
45
+
use Illuminate\Foundation\Testing\RefreshDatabase;
46
+
47
+
class CreateUserTest extends TestCase
48
+
{
49
+
use RefreshDatabase;
50
+
51
+
public function test_it_should_be_able_to_create_new_user(): void
52
+
{
53
+
$name = fake()->name();
54
+
$email = fake()->email();
55
+
56
+
$user = run('create new user', [
57
+
'name' => $name,
58
+
'email' => $email,
59
+
'password' => bcrypt('password'),
60
+
]);
61
+
62
+
$this->assertInstanceOf(User::class, $user);
63
+
64
+
$this->assertSame($name, $user->name);
65
+
$this->assertSame($email, $user->email);
66
+
}
67
+
}
68
+
```
69
+
70
+
:::
71
+
31
72
## Handle Unregistered Actions
32
73
33
-
Since _Fraction_ is all about fundamentally defining and usingactions based on string names, you might accidentally make mistakes that throw exceptions — when an action in use has not been registered an exception `\Fraction\Exceptions\ActionNotRegistered` will be thrown.
74
+
While you can define actions using `UnitEnum` - [as demonstrated on the using](/using#problem-solution) page, fundamentally _Fraction_ is about defining actions based on string names. For this reason, you can accidentally make typos that throw exceptions, because when an action in use has not been registered, a `\Fraction\Exceptions\ActionNotRegistered`exception will be thrown.
34
75
35
-
To prevent this, we provide the `actions:unregistered` Artisan command that lists all actions in use in the `app/` namespace and lists the action and the file it was detected in. **This way, you can include this command in a basic test to make sure that everything is ok with defining and using string-based actions**:
76
+
To prevent this, we provide the `actions:unregistered` Artisan command that lists all actions in use in the `base_path('app/')` namespace and lists the action and the file it was detected in. This way, you can include this command in a basic test to make sure that everything is ok with defining and using string-based actions:
77
+
78
+
::: code-group
79
+
80
+
```php {4} [PestPHP]
81
+
use Illuminate\Support\Facades\Artisan;
36
82
37
-
```php {2}
38
83
test('ensure all actions name are correctly applied', function () {
39
84
$output = Artisan::call('actions:unregistered');
40
85
41
86
expect($output)->toBe(0);
42
87
});
43
88
```
44
89
45
-
If this test fails, it means that there are actions in your code that are not registered. You can use the command to see which actions are not registered and where they are used in your codebase.
90
+
```php {13} [PhpUnit]
91
+
namespace Tests\Unit;
92
+
93
+
use Tests\TestCase;
94
+
use Illuminate\Support\Facades\Artisan;
95
+
use Illuminate\Foundation\Testing\RefreshDatabase;
96
+
97
+
class UnregisteredActionsTest extends TestCase
98
+
{
99
+
use RefreshDatabase;
100
+
101
+
public function test_ensure_all_actions_names_are_correctly_applied(): void
102
+
{
103
+
$output = Artisan::call('actions:unregistered');
104
+
105
+
$this->assertSame(0, $output);
106
+
}
107
+
}
108
+
```
109
+
110
+
:::
111
+
112
+
If this test fails - _the `$output` is different from 0_, **it means that there are actions in your code that are not registered.** You can use the command via terminal to see which actions are not registered and where they are used in your codebase.
> Behind the scenes, the `actions:unregistered` command will apply a `grep` command using a regular expression that aims to identify the use of the `run` function. For this reason, the command does not differentiate the usage of `run` functions that are commented.
Copy file name to clipboardExpand all lines: docs/using.md
+2-3Lines changed: 2 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,8 +2,6 @@
2
2
title: Using
3
3
---
4
4
5
-
## Creating and Using
6
-
7
5
While you can create actions manually, there is a `make:action` command that can be used to make it easier to create actions via the terminal. The output of the command is like this:
8
6
9
7
```bash
@@ -47,6 +45,7 @@ The execution of the action in this case would be like this:
47
45
48
46
```php
49
47
namespace App\Http\Controllers;
48
+
50
49
use Illuminate\Http\Request\CreateUserRequest;
51
50
52
51
class UserController extends Controller
@@ -64,7 +63,7 @@ And yes, you can return anything from an action. The returned value will be rece
64
63
65
64
## Problem & Solution
66
65
67
-
One of the problems that was initially noticed when Fraction was created was that we interacted with strings. This is bad because if we forget a single letter, creating or executing the action can become a problem. For this reason you have two easy solutions - _one we will mention now and the other we will mention in the testing section._ You can also use `UnitEnum` to define your actions through cases, which can be useful to avoid writing errors.
66
+
One of the problems that was initially noticed when Fraction was created was that we interacted with strings. This is bad because if we forget a single letter, creating or executing the action can become a problem. For this reason you have two easy solutions - [one we will mention now and the other we will mention in the testing section](/testing#handle-unregistered-actions). Your first option is use `UnitEnum` to define your actions through cases, which can be useful to avoid writing errors.
0 commit comments