MustacheSpecTest.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. namespace Mustache\Test\Functional;
  3. use Mustache\Mustache;
  4. use Mustache\Loader\StringLoader;
  5. /**
  6. * A PHPUnit test case wrapping the Mustache Spec
  7. *
  8. * @group mustache-spec
  9. * @group functional
  10. */
  11. class MustacheSpecTest extends \PHPUnit_Framework_TestCase {
  12. private static $mustache;
  13. public static function setUpBeforeClass() {
  14. self::$mustache = new Mustache;
  15. }
  16. /**
  17. * For some reason data providers can't mark tests skipped, so this test exists
  18. * simply to provide a 'skipped' test if the `spec` submodule isn't initialized.
  19. */
  20. public function testSpecInitialized() {
  21. if (!file_exists(__DIR__.'/../../../spec/specs/')) {
  22. $this->markTestSkipped('Mustache spec submodule not initialized: run "git submodule update --init"');
  23. }
  24. }
  25. /**
  26. * @group comments
  27. * @dataProvider loadCommentSpec
  28. */
  29. public function testCommentSpec($desc, $source, $partials, $data, $expected) {
  30. $template = self::loadTemplate($source, $partials);
  31. $this->assertEquals($expected, $template($data), $desc);
  32. }
  33. public function loadCommentSpec() {
  34. return $this->loadSpec('comments');
  35. }
  36. /**
  37. * @group delimiters
  38. * @dataProvider loadDelimitersSpec
  39. */
  40. public function testDelimitersSpec($desc, $source, $partials, $data, $expected) {
  41. $template = self::loadTemplate($source, $partials);
  42. $this->assertEquals($expected, $template($data), $desc);
  43. }
  44. public function loadDelimitersSpec() {
  45. return $this->loadSpec('delimiters');
  46. }
  47. /**
  48. * @group interpolation
  49. * @dataProvider loadInterpolationSpec
  50. */
  51. public function testInterpolationSpec($desc, $source, $partials, $data, $expected) {
  52. $template = self::loadTemplate($source, $partials);
  53. $this->assertEquals($expected, $template($data), $desc);
  54. }
  55. public function loadInterpolationSpec() {
  56. return $this->loadSpec('interpolation');
  57. }
  58. /**
  59. * @group inverted
  60. * @group inverted-sections
  61. * @dataProvider loadInvertedSpec
  62. */
  63. public function testInvertedSpec($desc, $source, $partials, $data, $expected) {
  64. $template = self::loadTemplate($source, $partials);
  65. $this->assertEquals($expected, $template($data), $desc);
  66. }
  67. public function loadInvertedSpec() {
  68. return $this->loadSpec('inverted');
  69. }
  70. /**
  71. * @group lambdas
  72. * @dataProvider loadLambdasSpec
  73. */
  74. public function testLambdasSpec($desc, $source, $partials, $data, $expected) {
  75. $template = self::loadTemplate($source, $partials);
  76. $this->assertEquals($expected, $template($this->prepareLambdasSpec($data)), $desc);
  77. }
  78. public function loadLambdasSpec() {
  79. return $this->loadSpec('~lambdas');
  80. }
  81. /**
  82. * Extract and lambdafy any 'lambda' values found in the $data array.
  83. */
  84. private function prepareLambdasSpec($data) {
  85. foreach ($data as $key => $val) {
  86. if ($key === 'lambda') {
  87. if (!isset($val['php'])) {
  88. $this->markTestSkipped(sprintf('PHP lambda test not implemented for this test.'));
  89. }
  90. $func = $val['php'];
  91. $data[$key] = function($text = null) use ($func) { return eval($func); };
  92. } else if (is_array($val)) {
  93. $data[$key] = $this->prepareLambdasSpec($val);
  94. }
  95. }
  96. return $data;
  97. }
  98. /**
  99. * @group partials
  100. * @dataProvider loadPartialsSpec
  101. */
  102. public function testPartialsSpec($desc, $source, $partials, $data, $expected) {
  103. $template = self::loadTemplate($source, $partials);
  104. $this->assertEquals($expected, $template($data), $desc);
  105. }
  106. public function loadPartialsSpec() {
  107. return $this->loadSpec('partials');
  108. }
  109. /**
  110. * @group sections
  111. * @dataProvider loadSectionsSpec
  112. */
  113. public function testSectionsSpec($desc, $source, $partials, $data, $expected) {
  114. $template = self::loadTemplate($source, $partials);
  115. $this->assertEquals($expected, $template($data), $desc);
  116. }
  117. public function loadSectionsSpec() {
  118. return $this->loadSpec('sections');
  119. }
  120. /**
  121. * Data provider for the mustache spec test.
  122. *
  123. * Loads YAML files from the spec and converts them to PHPisms.
  124. *
  125. * @access public
  126. * @return array
  127. */
  128. private function loadSpec($name) {
  129. $filename = __DIR__ . '/../../../spec/specs/' . $name . '.yml';
  130. if (!file_exists($filename)) {
  131. return array();
  132. }
  133. $data = array();
  134. $yaml = new \sfYamlParser;
  135. $file = file_get_contents($filename);
  136. // @hack: pre-process the 'lambdas' spec so the Symfony YAML parser doesn't complain.
  137. if ($name === '~lambdas') {
  138. $file = str_replace(" !code\n", "\n", $file);
  139. }
  140. $spec = $yaml->parse($file);
  141. foreach ($spec['tests'] as $test) {
  142. $data[] = array(
  143. $test['name'] . ': ' . $test['desc'],
  144. $test['template'],
  145. isset($test['partials']) ? $test['partials'] : array(),
  146. $test['data'],
  147. $test['expected'],
  148. );
  149. }
  150. return $data;
  151. }
  152. private static function loadTemplate($source, $partials) {
  153. self::$mustache->setPartials($partials);
  154. return self::$mustache->loadTemplate($source);
  155. }
  156. }