Skip to content

Commit 93920b7

Browse files
committed
Add more tests known from PHP
1 parent 0a35a5b commit 93920b7

20 files changed

+613
-9
lines changed

README.md

+43-2
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,57 @@ You can use `break` with a number to break out of multiple loops, just like in P
9292

9393
While you can often circumvent the usage of `break` and `continue` in twig, it sometimes leads to additional nesting and more complicated code. Just one `break` or `continue` can clarify behavior and intent in these instances. Yet I would advise to use `break` and `continue` sparingly.
9494

95-
### is true / is false tests
95+
### Variable type tests (string, array, true, callable, etc.)
9696

97-
Adds a strict true/false test, so expressions become a bit more readable:
97+
Adds tests known from PHP, so you can test a value for being:
98+
99+
- an array (like `is_array`)
100+
- a boolean (like `is_bool`)
101+
- a callable (like `is_callable`)
102+
- a float (like `is_float`)
103+
- an integer (like `is_int`)
104+
- an object (like `is_object`)
105+
- a scalar (integer, float, string or boolean, like `is_scalar`)
106+
- a string (like `is_string`)
107+
- true (like `=== true`)
108+
- false (like `=== false`)
109+
110+
It uses the mentioned PHP functions / comparisons internally, so you have the same behavior as in PHP.
98111

99112
```twig
100113
{% if someflag is true %} {# instead of {% if someflag is same as(true) %} #}
101114
{% endif %}
102115
103116
{% if someflag is false %} {# instead of {% if someflag is same as(false) %} #}
104117
{% endif %}
118+
119+
{% if somevar is string %} {# no equivalent in twig %} #}
120+
{% endif %}
121+
122+
{% if somevar is scalar %} {# no equivalent in twig %} #}
123+
{% endif %}
124+
125+
{% if somevar is object %} {# no equivalent in twig %} #}
126+
{% endif %}
127+
128+
{% if somevar is integer %} {# no equivalent in twig %} #}
129+
{% endif %}
130+
{% if somevar is int %} {# same as integer test above, alternate way to write it %} #}
131+
{% endif %}
132+
133+
{% if somevar is float %} {# no equivalent in twig %} #}
134+
{% endif %}
135+
136+
{% if somevar is callable %} {# no equivalent in twig %} #}
137+
{% endif %}
138+
139+
{% if somevar is boolean %} {# no equivalent in twig %} #}
140+
{% endif %}
141+
{% if somevar is bool %} {# same as boolean test above, alternate way to write it %} #}
142+
{% endif %}
143+
144+
{% if somevar is array %} {# no equivalent in twig %} #}
145+
{% endif %}
105146
```
106147

107148
### && and ||

src/PhpSyntaxExtension.php

+26
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44

55
use Squirrel\TwigPhpSyntax\Operator\NotSameAsBinary;
66
use Squirrel\TwigPhpSyntax\Operator\SameAsBinary;
7+
use Squirrel\TwigPhpSyntax\Test\ArrayTest;
8+
use Squirrel\TwigPhpSyntax\Test\BooleanTest;
9+
use Squirrel\TwigPhpSyntax\Test\CallableTest;
710
use Squirrel\TwigPhpSyntax\Test\FalseTest;
11+
use Squirrel\TwigPhpSyntax\Test\FloatTest;
12+
use Squirrel\TwigPhpSyntax\Test\IntegerTest;
13+
use Squirrel\TwigPhpSyntax\Test\ObjectTest;
14+
use Squirrel\TwigPhpSyntax\Test\ScalarTest;
15+
use Squirrel\TwigPhpSyntax\Test\StringTest;
816
use Squirrel\TwigPhpSyntax\Test\TrueTest;
917
use Squirrel\TwigPhpSyntax\TokenParser\BreakTokenParser;
1018
use Squirrel\TwigPhpSyntax\TokenParser\ContinueTokenParser;
@@ -33,6 +41,24 @@ public function getTests(): array
3341
new TwigTest('true', null, ['node_class' => TrueTest::class]),
3442
// adds test: "var is false"
3543
new TwigTest('false', null, ['node_class' => FalseTest::class]),
44+
// adds test: "var is array"
45+
new TwigTest('array', null, ['node_class' => ArrayTest::class]),
46+
// adds test: "var is bool" / "var is boolean"
47+
new TwigTest('bool', null, ['node_class' => BooleanTest::class]),
48+
new TwigTest('boolean', null, ['node_class' => BooleanTest::class]),
49+
// adds test: "var is callable"
50+
new TwigTest('callable', null, ['node_class' => CallableTest::class]),
51+
// adds test: "var is float"
52+
new TwigTest('float', null, ['node_class' => FloatTest::class]),
53+
// adds test: "var is int" / "var is integer"
54+
new TwigTest('int', null, ['node_class' => IntegerTest::class]),
55+
new TwigTest('integer', null, ['node_class' => IntegerTest::class]),
56+
// adds test: "var is object"
57+
new TwigTest('object', null, ['node_class' => ObjectTest::class]),
58+
// adds test: "var is scalar"
59+
new TwigTest('scalar', null, ['node_class' => ScalarTest::class]),
60+
// adds test: "var is string"
61+
new TwigTest('string', null, ['node_class' => StringTest::class]),
3662
];
3763
}
3864

src/Test/ArrayTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Squirrel\TwigPhpSyntax\Test;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Expression\TestExpression;
7+
8+
/**
9+
* Checks that a variable is an array.
10+
*
11+
* {{ var is array }}
12+
*/
13+
class ArrayTest extends TestExpression
14+
{
15+
public function compile(Compiler $compiler): void
16+
{
17+
$compiler
18+
->raw('(true === \\is_array(')
19+
->subcompile($this->getNode('node'))
20+
->raw('))')
21+
;
22+
}
23+
}

src/Test/BooleanTest.php

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Squirrel\TwigPhpSyntax\Test;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Expression\TestExpression;
7+
8+
/**
9+
* Checks that a variable is a boolean.
10+
*
11+
* {{ var is boolean }}
12+
* {{ var is bool }}
13+
*/
14+
class BooleanTest extends TestExpression
15+
{
16+
public function compile(Compiler $compiler): void
17+
{
18+
$compiler
19+
->raw('(true === \\is_bool(')
20+
->subcompile($this->getNode('node'))
21+
->raw('))')
22+
;
23+
}
24+
}

src/Test/CallableTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Squirrel\TwigPhpSyntax\Test;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Expression\TestExpression;
7+
8+
/**
9+
* Checks that a variable is a callable.
10+
*
11+
* {{ var is callable }}
12+
*/
13+
class CallableTest extends TestExpression
14+
{
15+
public function compile(Compiler $compiler): void
16+
{
17+
$compiler
18+
->raw('(true === \\is_callable(')
19+
->subcompile($this->getNode('node'))
20+
->raw('))')
21+
;
22+
}
23+
}

src/Test/FloatTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Squirrel\TwigPhpSyntax\Test;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Expression\TestExpression;
7+
8+
/**
9+
* Checks that a variable is a float.
10+
*
11+
* {{ var is float }}
12+
*/
13+
class FloatTest extends TestExpression
14+
{
15+
public function compile(Compiler $compiler): void
16+
{
17+
$compiler
18+
->raw('(true === \\is_float(')
19+
->subcompile($this->getNode('node'))
20+
->raw('))')
21+
;
22+
}
23+
}

src/Test/IntegerTest.php

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Squirrel\TwigPhpSyntax\Test;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Expression\TestExpression;
7+
8+
/**
9+
* Checks that a variable is an integer.
10+
*
11+
* {{ var is int }}
12+
* {{ var is integer }}
13+
*/
14+
class IntegerTest extends TestExpression
15+
{
16+
public function compile(Compiler $compiler): void
17+
{
18+
$compiler
19+
->raw('(true === \\is_int(')
20+
->subcompile($this->getNode('node'))
21+
->raw('))')
22+
;
23+
}
24+
}

src/Test/ObjectTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Squirrel\TwigPhpSyntax\Test;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Expression\TestExpression;
7+
8+
/**
9+
* Checks that a variable is an object.
10+
*
11+
* {{ var is object }}
12+
*/
13+
class ObjectTest extends TestExpression
14+
{
15+
public function compile(Compiler $compiler): void
16+
{
17+
$compiler
18+
->raw('(true === \\is_object(')
19+
->subcompile($this->getNode('node'))
20+
->raw('))')
21+
;
22+
}
23+
}

src/Test/ScalarTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Squirrel\TwigPhpSyntax\Test;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Expression\TestExpression;
7+
8+
/**
9+
* Checks that a variable is a scalar (int, float, string or bool).
10+
*
11+
* {{ var is scalar }}
12+
*/
13+
class ScalarTest extends TestExpression
14+
{
15+
public function compile(Compiler $compiler): void
16+
{
17+
$compiler
18+
->raw('(true === \\is_scalar(')
19+
->subcompile($this->getNode('node'))
20+
->raw('))')
21+
;
22+
}
23+
}

src/Test/StringTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Squirrel\TwigPhpSyntax\Test;
4+
5+
use Twig\Compiler;
6+
use Twig\Node\Expression\TestExpression;
7+
8+
/**
9+
* Checks that a variable is a string.
10+
*
11+
* {{ var is string }}
12+
*/
13+
class StringTest extends TestExpression
14+
{
15+
public function compile(Compiler $compiler): void
16+
{
17+
$compiler
18+
->raw('(true === \\is_string(')
19+
->subcompile($this->getNode('node'))
20+
->raw('))')
21+
;
22+
}
23+
}

tests/Fixtures/is_array.test

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
"is array" test
3+
--TEMPLATE--
4+
{% if [1, 2, 3] is array %}
5+
1
6+
{% endif %}
7+
{% if 1 is array %}
8+
2
9+
{% endif %}
10+
{% if true is array %}
11+
3
12+
{% endif %}
13+
{% if "string" is array %}
14+
4
15+
{% endif %}
16+
{% if {dada: true, other: 5} is array %}
17+
5
18+
{% endif %}
19+
{% if obj is array %}
20+
6
21+
{% endif %}
22+
{% if func is array %}
23+
7
24+
{% endif %}
25+
{% if 3.7 is array %}
26+
8
27+
{% endif %}
28+
{% if false is array %}
29+
9
30+
{% endif %}
31+
--DATA--
32+
return [
33+
'obj' => new \stdClass(),
34+
'func' => function() { return 5; },
35+
];
36+
--EXPECT--
37+
1
38+
5

tests/Fixtures/is_boolean.test

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
"is boolean" test
3+
--TEMPLATE--
4+
{% if [1, 2, 3] is boolean %}
5+
1
6+
{% endif %}
7+
{% if 1 is boolean %}
8+
2
9+
{% endif %}
10+
{% if true is boolean %}
11+
3
12+
{% endif %}
13+
{% if "string" is boolean %}
14+
4
15+
{% endif %}
16+
{% if {dada: true, other: 5} is boolean %}
17+
5
18+
{% endif %}
19+
{% if obj is boolean %}
20+
6
21+
{% endif %}
22+
{% if func is boolean %}
23+
7
24+
{% endif %}
25+
{% if 3.7 is boolean %}
26+
8
27+
{% endif %}
28+
{% if false is boolean %}
29+
9
30+
{% endif %}
31+
--DATA--
32+
return [
33+
'obj' => new \stdClass(),
34+
'func' => function() { return 5; },
35+
];
36+
--EXPECT--
37+
3
38+
9

0 commit comments

Comments
 (0)