ViewBladeCompilerTest.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. namespace Illuminate\Tests\View;
  3. use Illuminate\Filesystem\Filesystem;
  4. use Illuminate\View\Compilers\BladeCompiler;
  5. use InvalidArgumentException;
  6. use Mockery as m;
  7. use PHPUnit\Framework\TestCase;
  8. class ViewBladeCompilerTest extends TestCase
  9. {
  10. protected function tearDown(): void
  11. {
  12. m::close();
  13. }
  14. public function testIsExpiredReturnsTrueIfCompiledFileDoesntExist()
  15. {
  16. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  17. $files->shouldReceive('exists')->once()->with(__DIR__.'/'.sha1('v2foo').'.php')->andReturn(false);
  18. $this->assertTrue($compiler->isExpired('foo'));
  19. }
  20. public function testCannotConstructWithBadCachePath()
  21. {
  22. $this->expectException(InvalidArgumentException::class);
  23. $this->expectExceptionMessage('Please provide a valid cache path.');
  24. new BladeCompiler($this->getFiles(), null);
  25. }
  26. public function testIsExpiredReturnsTrueWhenModificationTimesWarrant()
  27. {
  28. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  29. $files->shouldReceive('exists')->once()->with(__DIR__.'/'.sha1('v2foo').'.php')->andReturn(true);
  30. $files->shouldReceive('lastModified')->once()->with('foo')->andReturn(100);
  31. $files->shouldReceive('lastModified')->once()->with(__DIR__.'/'.sha1('v2foo').'.php')->andReturn(0);
  32. $this->assertTrue($compiler->isExpired('foo'));
  33. }
  34. public function testCompilePathIsProperlyCreated()
  35. {
  36. $compiler = new BladeCompiler($this->getFiles(), __DIR__);
  37. $this->assertEquals(__DIR__.'/'.sha1('v2foo').'.php', $compiler->getCompiledPath('foo'));
  38. }
  39. public function testCompileCompilesFileAndReturnsContents()
  40. {
  41. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  42. $files->shouldReceive('get')->once()->with('foo')->andReturn('Hello World');
  43. $files->shouldReceive('exists')->once()->with(__DIR__)->andReturn(true);
  44. $files->shouldReceive('put')->once()->with(__DIR__.'/'.sha1('v2foo').'.php', 'Hello World<?php /**PATH foo ENDPATH**/ ?>');
  45. $compiler->compile('foo');
  46. }
  47. public function testCompileCompilesFileAndReturnsContentsCreatingDirectory()
  48. {
  49. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  50. $files->shouldReceive('get')->once()->with('foo')->andReturn('Hello World');
  51. $files->shouldReceive('exists')->once()->with(__DIR__)->andReturn(false);
  52. $files->shouldReceive('makeDirectory')->once()->with(__DIR__, 0777, true, true);
  53. $files->shouldReceive('put')->once()->with(__DIR__.'/'.sha1('v2foo').'.php', 'Hello World<?php /**PATH foo ENDPATH**/ ?>');
  54. $compiler->compile('foo');
  55. }
  56. public function testCompileCompilesAndGetThePath()
  57. {
  58. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  59. $files->shouldReceive('get')->once()->with('foo')->andReturn('Hello World');
  60. $files->shouldReceive('exists')->once()->with(__DIR__)->andReturn(true);
  61. $files->shouldReceive('put')->once()->with(__DIR__.'/'.sha1('v2foo').'.php', 'Hello World<?php /**PATH foo ENDPATH**/ ?>');
  62. $compiler->compile('foo');
  63. $this->assertSame('foo', $compiler->getPath());
  64. }
  65. public function testCompileSetAndGetThePath()
  66. {
  67. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  68. $compiler->setPath('foo');
  69. $this->assertSame('foo', $compiler->getPath());
  70. }
  71. public function testCompileWithPathSetBefore()
  72. {
  73. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  74. $files->shouldReceive('get')->once()->with('foo')->andReturn('Hello World');
  75. $files->shouldReceive('exists')->once()->with(__DIR__)->andReturn(true);
  76. $files->shouldReceive('put')->once()->with(__DIR__.'/'.sha1('v2foo').'.php', 'Hello World<?php /**PATH foo ENDPATH**/ ?>');
  77. // set path before compilation
  78. $compiler->setPath('foo');
  79. // trigger compilation with $path
  80. $compiler->compile();
  81. $this->assertSame('foo', $compiler->getPath());
  82. }
  83. public function testRawTagsCanBeSetToLegacyValues()
  84. {
  85. $compiler = new BladeCompiler($this->getFiles(), __DIR__);
  86. $compiler->setEchoFormat('%s');
  87. $this->assertSame('<?php echo e($name); ?>', $compiler->compileString('{{{ $name }}}'));
  88. $this->assertSame('<?php echo $name; ?>', $compiler->compileString('{{ $name }}'));
  89. $this->assertSame('<?php echo $name; ?>', $compiler->compileString('{{
  90. $name
  91. }}'));
  92. }
  93. /**
  94. * @dataProvider appendViewPathDataProvider
  95. *
  96. * @param string $content
  97. * @param string $compiled
  98. */
  99. public function testIncludePathToTemplate($content, $compiled)
  100. {
  101. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  102. $files->shouldReceive('get')->once()->with('foo')->andReturn($content);
  103. $files->shouldReceive('exists')->once()->with(__DIR__)->andReturn(true);
  104. $files->shouldReceive('put')->once()->with(__DIR__.'/'.sha1('v2foo').'.php', $compiled);
  105. $compiler->compile('foo');
  106. }
  107. /**
  108. * @return array
  109. */
  110. public function appendViewPathDataProvider()
  111. {
  112. return [
  113. 'No PHP blocks' => [
  114. 'Hello World',
  115. 'Hello World<?php /**PATH foo ENDPATH**/ ?>',
  116. ],
  117. 'Single PHP block without closing ?>' => [
  118. '<?php echo $path',
  119. '<?php echo $path ?><?php /**PATH foo ENDPATH**/ ?>',
  120. ],
  121. 'Ending PHP block.' => [
  122. 'Hello world<?php echo $path ?>',
  123. 'Hello world<?php echo $path ?><?php /**PATH foo ENDPATH**/ ?>',
  124. ],
  125. 'Ending PHP block without closing ?>' => [
  126. 'Hello world<?php echo $path',
  127. 'Hello world<?php echo $path ?><?php /**PATH foo ENDPATH**/ ?>',
  128. ],
  129. 'PHP block between content.' => [
  130. 'Hello world<?php echo $path ?>Hi There',
  131. 'Hello world<?php echo $path ?>Hi There<?php /**PATH foo ENDPATH**/ ?>',
  132. ],
  133. 'Multiple PHP blocks.' => [
  134. 'Hello world<?php echo $path ?>Hi There<?php echo $path ?>Hello Again',
  135. 'Hello world<?php echo $path ?>Hi There<?php echo $path ?>Hello Again<?php /**PATH foo ENDPATH**/ ?>',
  136. ],
  137. 'Multiple PHP blocks without closing ?>' => [
  138. 'Hello world<?php echo $path ?>Hi There<?php echo $path',
  139. 'Hello world<?php echo $path ?>Hi There<?php echo $path ?><?php /**PATH foo ENDPATH**/ ?>',
  140. ],
  141. 'Short open echo tag' => [
  142. 'Hello world<?= echo $path',
  143. 'Hello world<?= echo $path ?><?php /**PATH foo ENDPATH**/ ?>',
  144. ],
  145. 'Echo XML declaration' => [
  146. '<?php echo \'<?xml version="1.0" encoding="UTF-8"?>\';',
  147. '<?php echo \'<?xml version="1.0" encoding="UTF-8"?>\'; ?><?php /**PATH foo ENDPATH**/ ?>',
  148. ],
  149. ];
  150. }
  151. public function testDontIncludeEmptyPath()
  152. {
  153. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  154. $files->shouldReceive('get')->once()->with('')->andReturn('Hello World');
  155. $files->shouldReceive('exists')->once()->with(__DIR__)->andReturn(true);
  156. $files->shouldReceive('put')->once()->with(__DIR__.'/'.sha1('v2').'.php', 'Hello World');
  157. $compiler->setPath('');
  158. $compiler->compile();
  159. }
  160. public function testDontIncludeNullPath()
  161. {
  162. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  163. $files->shouldReceive('get')->once()->with(null)->andReturn('Hello World');
  164. $files->shouldReceive('exists')->once()->with(__DIR__)->andReturn(true);
  165. $files->shouldReceive('put')->once()->with(__DIR__.'/'.sha1('v2').'.php', 'Hello World');
  166. $compiler->setPath(null);
  167. $compiler->compile();
  168. }
  169. public function testShouldStartFromStrictTypesDeclaration()
  170. {
  171. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  172. $strictTypeDecl = "<?php\ndeclare(strict_types = 1);";
  173. $this->assertSame(substr($compiler->compileString("<?php\ndeclare(strict_types = 1);\nHello World"),
  174. 0, strlen($strictTypeDecl)), $strictTypeDecl);
  175. }
  176. public function testComponentAliasesCanBeConventionallyDetermined()
  177. {
  178. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  179. $compiler->component('App\Foo\Bar');
  180. $this->assertEquals(['bar' => 'App\Foo\Bar'], $compiler->getClassComponentAliases());
  181. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  182. $compiler->component('App\Foo\Bar', null, 'prefix');
  183. $this->assertEquals(['prefix-bar' => 'App\Foo\Bar'], $compiler->getClassComponentAliases());
  184. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  185. $compiler->component('App\View\Components\Forms\Input');
  186. $this->assertEquals(['forms:input' => 'App\View\Components\Forms\Input'], $compiler->getClassComponentAliases());
  187. $compiler = new BladeCompiler($files = $this->getFiles(), __DIR__);
  188. $compiler->component('App\View\Components\Forms\Input', null, 'prefix');
  189. $this->assertEquals(['prefix-forms:input' => 'App\View\Components\Forms\Input'], $compiler->getClassComponentAliases());
  190. }
  191. protected function getFiles()
  192. {
  193. return m::mock(Filesystem::class);
  194. }
  195. }