Skip to content

Commit

Permalink
Form Directives
Browse files Browse the repository at this point in the history
  • Loading branch information
soysudhanshu authored Aug 15, 2024
2 parents 4182eda + 820a83c commit 28fecb6
Show file tree
Hide file tree
Showing 3 changed files with 297 additions and 4 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,11 @@ Template inheritance allows you to create layouts by defining a master template
| `@env` | ||
| `@include` | ||
| `@session` | ||
| `@checked` | ||
| `@disabled` | ||
| `@readonly` | ||
| `@required` | ||
| `@selected` | ||
| `@checked` | ||
| `@disabled` | ||
| `@readonly` | ||
| `@required` | ||
| `@includeIf` | ||
| `@includeWhen` | ||
| `@includeUnless` | ||
Expand Down
45 changes: 45 additions & 0 deletions src/CompileAtRules.php
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,49 @@ protected function compileIncludeFirst(string $expression): string
return "<?php echo \$template_renderer->withDefault(get_defined_vars())" .
"->includeFirst{$expression}; ?>";
}

public function compileRequired(string $expression): string
{
if (empty($expression)) {
return "required";
}

return "<?php echo ($expression) ? 'required' : ''; ?>";
}

public function compileDisabled(string $expression): string
{
if (empty($expression)) {
return "disabled";
}

return "<?php echo ($expression) ? 'disabled' : ''; ?>";
}

public function compileChecked(string $expression): string
{
if (empty($expression)) {
return "checked";
}

return "<?php echo ($expression) ? 'checked' : ''; ?>";
}

public function compileSelected(string $expression): string
{
if (empty($expression)) {
return "selected";
}

return "<?php echo ($expression) ? 'selected' : ''; ?>";
}

public function compileReadonly(string $expression): string
{
if (empty($expression)) {
return "readonly";
}

return "<?php echo ($expression) ? 'readonly' : ''; ?>";
}
}
247 changes: 247 additions & 0 deletions tests/FormDirectiveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
<?php

namespace Tests;

use PHPUnit\Framework\TestCase;

class FormDirectiveTest extends TestCase
{
use VerifiesOutputTrait;

public function testRequiredDirective(): void
{
$this->assertSame(
'<input type="text" name="name" required>',
$this->renderBlade('<input type="text" name="name" @required>')
);
}

public function testRequiredWithConditionals(): void
{
$cases = [
[
'condition' => 'true',
'expected' => '<input type="text" name="name" required>',
'message' => 'The input should be required when the condition is true',
],
[
'condition' => 'false',
'expected' => '<input type="text" name="name" >',
'message' => 'The input should not be required when the condition is false',
],
[
'condition' => 'null',
'expected' => '<input type="text" name="name" >',
'message' => 'The input should not be required when the condition is null',
],
[
'condition' => 'fn() => true',
'expected' => '<input type="text" name="name" required>',
'message' => 'The input should be required when the condition is a string that evaluates to true',
],
[
'condition' => '1 == "1"',
'expected' => '<input type="text" name="name" required>',
'message' => 'The input should be required when the condition is a string that evaluates to true',
]
];

foreach ($cases as $case) {
$this->assertSame(
$case['expected'],
$this->renderBlade(
'<input type="text" name="name" @required(' . $case['condition'] . ')>',
),
$case['message']
);
}
}

public function testDisabledDirective(): void
{
$this->assertSame(
'<input type="text" name="name" disabled>',
$this->renderBlade('<input type="text" name="name" @disabled>')
);
}

public function testDisabledDirectiveWithConditionals(): void
{
$cases = [
[
'expected' => '<input type="text" name="name" disabled>',
'blade' => '<input type="text" name="name" @disabled(true)>',
'message' => 'The input should be disabled when the condition is true',
],
[
'expected' => '<input type="text" name="name" >',
'blade' => '<input type="text" name="name" @disabled(false)>',
'message' => 'The input should not be disabled when the condition is false',
],
[
'expected' => '<input type="text" name="name" >',
'blade' => '<input type="text" name="name" @disabled(null)>',
'message' => 'The input should not be disabled when the condition is null',
],
[
'expected' => '<input type="text" name="name" disabled>',
'blade' => '<input type="text" name="name" @disabled(fn() => true)>',
'message' => 'The input should be disabled when the condition is a string that evaluates to true',
],
[
'expected' => '<input type="text" name="name" disabled>',
'blade' => '<input type="text" name="name" @disabled(1 == "1")>',
'message' => 'The input should be disabled when the condition is a string that evaluates to true',
]
];

foreach ($cases as $case) {
$this->assertSame(
$case['expected'],
$this->renderBlade($case['blade']),
$case['message']
);
}
}

public function testCheckedDirective(): void
{
$this->assertSame(
'<input type="checkbox" name="name" checked>',
$this->renderBlade('<input type="checkbox" name="name" @checked>')
);
}

public function testCheckedDirectiveWithConditionals(): void
{
$cases = [
[
'expected' => '<input type="checkbox" name="name" checked>',
'blade' => '<input type="checkbox" name="name" @checked(true)>',
'message' => 'The input should be checked when the condition is true',
],
[
'expected' => '<input type="checkbox" name="name" >',
'blade' => '<input type="checkbox" name="name" @checked(false)>',
'message' => 'The input should not be checked when the condition is false',
],
[
'expected' => '<input type="checkbox" name="name" >',
'blade' => '<input type="checkbox" name="name" @checked(null)>',
'message' => 'The input should not be checked when the condition is null',
],
[
'expected' => '<input type="checkbox" name="name" checked>',
'blade' => '<input type="checkbox" name="name" @checked(fn() => true)>',
'message' => 'The input should be checked when the condition is a string that evaluates to true',
],
[
'expected' => '<input type="checkbox" name="name" checked>',
'blade' => '<input type="checkbox" name="name" @checked(1 == "1")>',
'message' => 'The input should be checked when the condition is a string that evaluates to true',
]
];

foreach ($cases as $case) {
$this->assertSame(
$case['expected'],
$this->renderBlade($case['blade']),
$case['message']
);
}
}

public function testSelectedDirective(): void
{
$this->assertSame(
'<option value="1" selected>One</option>',
$this->renderBlade('<option value="1" @selected>One</option>')
);
}

public function testSelectedDirectiveWithConditionals(): void
{
$cases = [
[
'expected' => '<option value="1" selected>One</option>',
'blade' => '<option value="1" @selected(true)>One</option>',
'message' => 'The option should be selected when the condition is true',
],
[
'expected' => '<option value="1" >One</option>',
'blade' => '<option value="1" @selected(false)>One</option>',
'message' => 'The option should not be selected when the condition is false',
],
[
'expected' => '<option value="1" >One</option>',
'blade' => '<option value="1" @selected(null)>One</option>',
'message' => 'The option should not be selected when the condition is null',
],
[
'expected' => '<option value="1" selected>One</option>',
'blade' => '<option value="1" @selected(fn() => true)>One</option>',
'message' => 'The option should be selected when the condition is a string that evaluates to true',
],
[
'expected' => '<option value="1" selected>One</option>',
'blade' => '<option value="1" @selected(1 == "1")>One</option>',
'message' => 'The option should be selected when the condition is a string that evaluates to true',
]
];

foreach ($cases as $case) {
$this->assertSame(
$case['expected'],
$this->renderBlade($case['blade']),
$case['message']
);
}
}

public function testReadOnlyDirective(): void
{
$this->assertSame(
'<input type="text" name="name" readonly>',
$this->renderBlade('<input type="text" name="name" @readonly>')
);
}

public function testReadOnlyDirectiveWithConditionals(): void
{
$cases = [
[
'expected' => '<input type="text" name="name" readonly>',
'blade' => '<input type="text" name="name" @readonly(true)>',
'message' => 'The input should be readonly when the condition is true',
],
[
'expected' => '<input type="text" name="name" >',
'blade' => '<input type="text" name="name" @readonly(false)>',
'message' => 'The input should not be readonly when the condition is false',
],
[
'expected' => '<input type="text" name="name" >',
'blade' => '<input type="text" name="name" @readonly(null)>',
'message' => 'The input should not be readonly when the condition is null',
],
[
'expected' => '<input type="text" name="name" readonly>',
'blade' => '<input type="text" name="name" @readonly(fn() => true)>',
'message' => 'The input should be readonly when the condition is a string that evaluates to true',
],
[
'expected' => '<input type="text" name="name" readonly>',
'blade' => '<input type="text" name="name" @readonly(1 == "1")>',
'message' => 'The input should be readonly when the condition is a string that evaluates to true',
]
];

foreach ($cases as $case) {
$this->assertSame(
$case['expected'],
$this->renderBlade($case['blade']),
$case['message']
);
}
}
}

0 comments on commit 28fecb6

Please sign in to comment.