TransactionFixtureStrategy.php 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP(tm) Project
  13. * @since 5.0.0
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\TestSuite\Fixture;
  17. use Cake\Database\Connection;
  18. use RuntimeException;
  19. /**
  20. * Fixture strategy that wraps fixtures in a transaction that is rolled back
  21. * after each test.
  22. *
  23. * Any test that calls Connection::rollback(true) will break this strategy.
  24. */
  25. class TransactionFixtureStrategy implements FixtureStrategyInterface
  26. {
  27. /**
  28. * @var \Cake\TestSuite\Fixture\FixtureHelper
  29. */
  30. protected $helper;
  31. /**
  32. * @var array<\Cake\Datasource\FixtureInterface>
  33. */
  34. protected $fixtures = [];
  35. /**
  36. * Initialize strategy.
  37. */
  38. public function __construct()
  39. {
  40. $this->helper = new FixtureHelper();
  41. }
  42. /**
  43. * @inheritDoc
  44. */
  45. public function setupTest(array $fixtureNames): void
  46. {
  47. $this->fixtures = $this->helper->loadFixtures($fixtureNames);
  48. $this->helper->runPerConnection(function ($connection) {
  49. if ($connection instanceof Connection) {
  50. assert(
  51. $connection->inTransaction() === false,
  52. 'Cannot start transaction strategy inside a transaction. This is most likely a bug.'
  53. );
  54. $connection->enableSavePoints();
  55. if (!$connection->isSavePointsEnabled()) {
  56. throw new RuntimeException(
  57. "Could not enable save points for the `{$connection->configName()}` connection. " .
  58. 'Your database needs to support savepoints in order to use ' .
  59. 'TransactionFixtureStrategy.'
  60. );
  61. }
  62. $connection->begin();
  63. $connection->createSavePoint('__fixtures__');
  64. }
  65. }, $this->fixtures);
  66. $this->helper->insert($this->fixtures);
  67. }
  68. /**
  69. * @inheritDoc
  70. */
  71. public function teardownTest(): void
  72. {
  73. $this->helper->runPerConnection(function ($connection) {
  74. if ($connection->inTransaction()) {
  75. $connection->rollback(true);
  76. }
  77. }, $this->fixtures);
  78. }
  79. }