initializeApplicationMock();
        $this->initializeWidgetMocks();
    }
    /**
     * @throws Exception
     */
    public function testWidgetIsRunWhenCacheIsEmpty(): void
    {
        $this->simpleWidget
            ->expects($this->once())
            ->method('run');
        $contents = $this->simpleWidget->test();
        $this->assertEquals('contents', $contents);
    }
    /**
     * @throws Exception
     */
    public function testWidgetIsNotRunWhenCacheIsNotEmpty(): void
    {
        $this->simpleWidget->cacheDuration = 0;
        $this->simpleWidget
            ->expects($this->once())
            ->method('run');
        for ($counter = 0; $counter <= 1; $counter++) {
            $this->assertEquals('contents', $this->simpleWidget->test());
        }
    }
    /**
     * @throws Exception
     */
    public function testDynamicContent(): void
    {
        $this->dynamicWidget->cacheDuration = 0;
        $this->dynamicWidget
            ->expects($this->once())
            ->method('run');
        for ($counter = 0; $counter <= 1; $counter++) {
            $expectedContents = sprintf('
dynamic contents: %d
', $counter);
            $this->assertEquals($expectedContents, $this->dynamicWidget->test());
        }
    }
    /**
     * Initializes a mock application.
     *
     */
    private function initializeApplicationMock(): void
    {
        $this->mockApplication([
            'components' => [
                'cache' => [
                    'class' => '\yii\caching\ArrayCache',
                ],
            ],
            'params' => [
                // Counter for dynamic contents testing.
                'counter' => 0,
            ],
        ]);
    }
    /**
     * Initializes mock widgets.
     *
     */
    private function initializeWidgetMocks(): void
    {
        $this->simpleWidget = $this->getWidgetMock(SimpleCacheableWidget::class);
        $this->dynamicWidget = $this->getWidgetMock(DynamicCacheableWidget::class);
    }
    /**
     * Returns a widget mock.
     * @param $widgetClass
     * @return PHPUnit_Framework_MockObject_MockObject
     */
    private function getWidgetMock($widgetClass)
    {
        return $this->getMockBuilder($widgetClass)
            ->onlyMethods(['run'])
            ->enableOriginalConstructor()
            ->enableProxyingToOriginalMethods()
            ->getMock();
    }
}
class BaseCacheableWidget extends Widget
{
    /**
     * {@inheritdoc}
     */
    public function test()
    {
        ob_start();
        ob_implicit_flush(false);
        try {
            $out = '';
            if ($this->beforeRun()) {
                $result = $this->run();
                $out = $this->afterRun($result);
            }
        } catch (Exception $exception) {
            if (ob_get_level() > 0) {
                ob_end_clean();
            }
            throw $exception;
        }
        return ob_get_clean() . $out;
    }
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'cacheable' => 'yii\behaviors\CacheableWidgetBehavior',
        ];
    }
}
class SimpleCacheableWidget extends BaseCacheableWidget
{
    /**
     * {@inheritdoc}
     */
    public function run()
    {
        $content = 'contents';
        return $content;
    }
}
class DynamicCacheableWidget extends BaseCacheableWidget
{
    /**
     * {@inheritdoc}
     */
    public function run()
    {
        $dynamicContentsExpression = 'return "dynamic contents: " . \Yii::$app->params["counter"]++;';
        $dynamicContents = $this->view->renderDynamic($dynamicContentsExpression);
        $content = '' . $dynamicContents . '
';
        return $content;
    }
}