diff --git a/src/DataTableFactoryAwareTrait.php b/src/DataTableFactoryAwareTrait.php index ee8a2576..eba2d5ba 100755 --- a/src/DataTableFactoryAwareTrait.php +++ b/src/DataTableFactoryAwareTrait.php @@ -51,4 +51,13 @@ protected function createDataTableBuilder(mixed $query = null, array $options = return $this->dataTableFactory->createBuilder(DataTableType::class, $query, $options); } + + protected function createNamedDataTableBuilder(string $name, mixed $query = null, array $options = []): DataTableBuilderInterface + { + if (null === $this->dataTableFactory) { + throw new LogicException(sprintf('You cannot use the "%s" method on controller without data table factory.', __METHOD__)); + } + + return $this->dataTableFactory->createNamedBuilder($name, DataTableType::class, $query, $options); + } } diff --git a/tests/Unit/DataTableFactoryAwareTraitTest.php b/tests/Unit/DataTableFactoryAwareTraitTest.php new file mode 100644 index 00000000..e9adc4db --- /dev/null +++ b/tests/Unit/DataTableFactoryAwareTraitTest.php @@ -0,0 +1,90 @@ + 'baz']]; + + $factory = $this->createMock(DataTableFactoryInterface::class); + $factory->expects($this->once())->method('create')->with(...$arguments); + + $this->createClassUsingTrait($factory)->execute('createDataTable', $arguments); + } + + public function testCreateNamedDataTable() + { + $arguments = ['foo', SimpleDataTableType::class, new CustomProxyQuery(), ['bar' => 'baz']]; + + $factory = $this->createMock(DataTableFactoryInterface::class); + $factory->expects($this->once())->method('createNamed')->with(...$arguments); + + $this->createClassUsingTrait($factory)->execute('createNamedDataTable', $arguments); + } + + public function testCreateDataTableBuilder() + { + $arguments = [new CustomProxyQuery(), ['bar' => 'baz']]; + + $factory = $this->createMock(DataTableFactoryInterface::class); + $factory->expects($this->once())->method('createBuilder')->with(DataTableType::class, ...$arguments); + + $this->createClassUsingTrait($factory)->execute('createDataTableBuilder', $arguments); + } + + public function testCreateNamedDataTableBuilder() + { + $arguments = ['foo', new CustomProxyQuery(), ['bar' => 'baz']]; + + $factory = $this->createMock(DataTableFactoryInterface::class); + $factory->expects($this->once())->method('createNamedBuilder')->with($arguments[0], DataTableType::class, $arguments[1], $arguments[2]); + + $this->createClassUsingTrait($factory)->execute('createNamedDataTableBuilder', $arguments); + } + + #[DataProvider('provideTraitCreateMethods')] + public function testExecutingMethodsWithoutFactoryThrows(string $method, array $arguments) + { + $this->expectExceptionMessage(vsprintf('You cannot use the "%s" method on controller without data table factory.', [ + DataTableFactoryAwareTrait::class.'::'.$method, + ])); + + $this->createClassUsingTrait()->execute($method, $arguments); + } + + public static function provideTraitCreateMethods(): iterable + { + yield 'createDataTable' => ['createDataTable', [DataTableType::class]]; + yield 'createNamedDataTable' => ['createNamedDataTable', ['foo', DataTableType::class]]; + yield 'createDataTableBuilder' => ['createDataTableBuilder', []]; + yield 'createNamedDataTableBuilder' => ['createNamedDataTableBuilder', ['foo']]; + } + + private function createClassUsingTrait(DataTableFactoryInterface $factory = null): object + { + $class = new class { + use DataTableFactoryAwareTrait; + + public function execute(string $method, array $arguments): void + { + $this->{$method}(...$arguments); + } + }; + + $class->setDataTableFactory($factory); + + return $class; + } +} \ No newline at end of file