view = new View(__DIR__ . '/views'); } public function testVariables(): void { $this->view->set('test', 123); self::assertSame(123, $this->view->get('test')); self::assertTrue($this->view->has('test')); self::assertFalse($this->view->has('unknown')); $this->view->clear('test'); self::assertNull($this->view->get('test')); } public function testMultipleVariables(): void { $this->view->set(['test' => 123, 'foo' => 'bar']); self::assertSame(123, $this->view->get('test')); self::assertSame('bar', $this->view->get('foo')); $this->view->clear(); self::assertNull($this->view->get('test')); self::assertNull($this->view->get('foo')); } public function testTemplateExists(): void { self::assertTrue($this->view->exists('hello.php')); self::assertFalse($this->view->exists('unknown.php')); } public function testRender(): void { $this->view->render('hello', ['name' => 'Bob']); self::expectOutputString('Hello, Bob!'); } public function testRenderBadFilePath(): void { $exception_message = sprintf( 'Template file not found: %s%sviews%sbadfile.php', __DIR__, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, ); self::expectException(Exception::class); self::expectExceptionMessage($exception_message); $this->view->render('badfile'); } public function testFetch(): void { $output = $this->view->fetch('hello', ['name' => 'Bob']); self::assertSame('Hello, Bob!', $output); } public function testTemplateWithExtension(): void { $this->view->render('hello.php', ['name' => 'Bob']); self::expectOutputString('Hello, Bob!'); } public function testTemplateWithCustomExtension(): void { self::expectOutputString('Hello world, Bob!'); $this->view->extension = '.html'; $this->view->render('world', ['name' => 'Bob']); } public function testGetTemplateAbsolutePath(): void { $tmpfile = tmpfile(); $this->view->extension = ''; $file_path = stream_get_meta_data($tmpfile)['uri']; self::assertSame($file_path, $this->view->getTemplate($file_path)); } public function testE(): void { $expectedString = '<script>'; self::expectOutputString($expectedString); $result = $this->view->e(' // html, // ], // [ // 'page-with-class-component-that-extends-another-class-component', // <<<'html' // another-class-component extended by my-class-component-that-extends-another-class-component // html, // ], // [ // 'page-with-component-with-one-prop', // <<<'html' // // //

Hello, James

// // // html, // ['name' => 'James'], // ], // [ // 'page-with-component-with-one-prop', // <<<'html' // // //

Hello, Victoria

// // // html, // ['name' => 'Victoria'], // ], // [ // 'page-with-component-with-two-props', // <<<'html' // // //

Hello, Astronaut Victoria

// // // html, // ['name' => 'Victoria', 'occupation' => 'Astronaut'], // ], // [ // 'page-with-three-different-components', // <<<'html' // my-component // my-functional-component // my-class-component // html, // ], // [ // 'page-with-component-with-prop-which-value-contains-spaces-and-numbers', // <<<'html' //

Hello, Constantine 1st the Great

// html, // ['name' => 'Constantine 1st the Great'], // ], [ 'page-two-same-components-with-one-style-and-script-tag', <<<'html' my-class-component-with-styles my-class-component-with-styles my-class-component-with-scripts my-class-component-with-scripts html, ], ]; } /** @dataProvider prefixesDataProvider */ public function testRenderComponentsWithDifferentPrefixes(string $prefix): void { $view = new View(__DIR__ . '/views', $prefix); $view->preserveVars = false; $actual = $view->fetch('pages/page-with-component-with-custom-prefix', compact('prefix')); $expected = 'my-component'; self::assertSame( self::removeIndentation(self::removeLineEndings($expected)), self::removeIndentation(self::removeLineEndings($actual)), ); } public static function prefixesDataProvider(): array { return [ ['x'], ]; } private static function removeLineEndings(string $subject): string { return str_replace(["\r", "\n"], '', $subject); } private static function removeIndentation(string $subject): string { return preg_replace('/\s{2,}/', '', $subject); } }