tmpFile = sys_get_temp_dir() . '/bicycle_view_' . uniqid() . '.html'; } protected function tearDown(): void { if (file_exists($this->tmpFile)) { unlink($this->tmpFile); } } public function testRenderStaticContent(): void { file_put_contents($this->tmpFile, 'hello world'); $view = new View(); $view->_file = $this->tmpFile; $this->assertSame('hello world', $view->render()); } public function testRenderWithData(): void { file_put_contents($this->tmpFile, ''); $view = new View(); $view->_file = $this->tmpFile; $view->_data = ['name' => 'bicycle']; $this->assertSame('bicycle', $view->render()); } public function testRenderMultipleVars(): void { file_put_contents($this->tmpFile, ''); $view = new View(); $view->_file = $this->tmpFile; $view->_data = ['a' => 'foo', 'b' => 'bar']; $this->assertSame('foo-bar', $view->render()); } public function testRenderThrowsWhenFileNotSet(): void { $this->expectException(MyException::class); (new View())->render(); } public function testSetFilenameFindsFileInAppPath(): void { $view = new View(); $view->setFilename('index', 'view/Index'); $this->assertStringContainsString('App', $view->_file); $this->assertStringEndsWith('index.html', $view->_file); $this->assertFileExists($view->_file); } public function testSetFilenameFindsFileInSysPath(): void { $view = new View(); $view->setFilename('404', 'view/errors'); $this->assertStringContainsString('System', $view->_file); $this->assertFileExists($view->_file); } public function testSetFilenameThrowsWhenNotFound(): void { $this->expectException(MyException::class); (new View())->setFilename('nonexistent_xyz', 'view/Index'); } public function testSetFilenameThrowsWhenDirEmpty(): void { $this->expectException(MyException::class); (new View())->setFilename('index', ''); } public function testConstructorWithFileAndDir(): void { $view = new View('index', 'view/Index'); $this->assertNotEmpty($view->_file); $this->assertFileExists($view->_file); } public function testConstructorWithData(): void { file_put_contents($this->tmpFile, ''); $view = new View(); $view->_file = $this->tmpFile; $view->_data = ['val' => 'test_value']; $this->assertSame('test_value', $view->render()); } public function testExtractSkipDoesNotOverrideLocalVar(): void { // EXTR_SKIP не перезаписывает уже существующие переменные в шаблоне file_put_contents($this->tmpFile, ''); $view = new View(); $view->_file = $this->tmpFile; $view->_data = ['x' => 'from_data']; // Здесь x уже определена в шаблоне ДО extract — EXTR_SKIP не перезапишет // Но View делает extract ДО include, поэтому $x = 'from_data' попадёт в шаблон $this->assertSame('local', $view->render()); } public function testSetFilenameReturnsSelf(): void { $view = new View(); $result = $view->setFilename('index', 'view/Index'); $this->assertSame($view, $result); } }