Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
DataFixtureBeforeTransaction.php
Go to the documentation of this file.
1 <?php
11 
12 use PHPUnit\Framework\Exception;
13 
15 {
19  protected $_fixtureBaseDir;
20 
26  private $_appliedFixtures = [];
27 
34  public function __construct($fixtureBaseDir)
35  {
36  if (!is_dir($fixtureBaseDir)) {
37  throw new \Magento\Framework\Exception\LocalizedException(
38  new \Magento\Framework\Phrase("Fixture base directory '%1' does not exist.", [$fixtureBaseDir])
39  );
40  }
41  $this->_fixtureBaseDir = realpath($fixtureBaseDir);
42  }
43 
49  public function startTest(\PHPUnit\Framework\TestCase $test)
50  {
51  if ($this->_getFixtures($test)) {
52  $this->_applyFixtures($this->_getFixtures($test));
53  }
54  }
55 
61  public function endTest(\PHPUnit\Framework\TestCase $test)
62  {
63  /* Isolate other tests from test-specific fixtures */
64  if ($this->_appliedFixtures && $this->_getFixtures($test)) {
65  $this->_revertFixtures();
66  }
67  }
68 
77  protected function _getFixtures(\PHPUnit\Framework\TestCase $test, $scope = null)
78  {
79  if ($scope === null) {
80  $annotations = $this->getAnnotations($test);
81  } else {
82  $annotations = $test->getAnnotations()[$scope];
83  }
84  $result = [];
85  if (!empty($annotations['magentoDataFixtureBeforeTransaction'])) {
86  foreach ($annotations['magentoDataFixtureBeforeTransaction'] as $fixture) {
87  if (strpos($fixture, '\\') !== false) {
88  // usage of a single directory separator symbol streamlines search across the source code
89  throw new \Magento\Framework\Exception\LocalizedException(
90  new \Magento\Framework\Phrase('Directory separator "\\" is prohibited in fixture declaration.')
91  );
92  }
93  $fixtureMethod = [get_class($test), $fixture];
94  if (is_callable($fixtureMethod)) {
95  $result[] = $fixtureMethod;
96  } else {
97  $result[] = $this->_fixtureBaseDir . '/' . $fixture;
98  }
99  }
100  }
101  return $result;
102  }
103 
108  private function getAnnotations(\PHPUnit\Framework\TestCase $test)
109  {
110  $annotations = $test->getAnnotations();
111  return array_replace($annotations['class'], $annotations['method']);
112  }
113 
120  protected function getDbIsolationState(\PHPUnit\Framework\TestCase $test)
121  {
122  $annotations = $this->getAnnotations($test);
123  return isset($annotations[DbIsolation::MAGENTO_DB_ISOLATION])
124  ? $annotations[DbIsolation::MAGENTO_DB_ISOLATION]
125  : null;
126  }
127 
134  protected function _applyOneFixture($fixture)
135  {
136  try {
137  if (is_callable($fixture)) {
138  call_user_func($fixture);
139  } else {
140  require $fixture;
141  }
142  } catch (\Exception $e) {
143  throw new Exception(
144  sprintf(
145  "Error in fixture: %s.\n %s\n %s",
146  json_encode($fixture),
147  $e->getMessage(),
148  $e->getTraceAsString()
149  ),
150  500,
151  $e
152  );
153  }
154  }
155 
162  protected function _applyFixtures(array $fixtures)
163  {
164  /* Execute fixture scripts */
165  foreach ($fixtures as $oneFixture) {
166  /* Skip already applied fixtures */
167  if (in_array($oneFixture, $this->_appliedFixtures, true)) {
168  continue;
169  }
170  $this->_applyOneFixture($oneFixture);
171  $this->_appliedFixtures[] = $oneFixture;
172  }
173  }
174 
178  protected function _revertFixtures()
179  {
180  foreach ($this->_appliedFixtures as $fixture) {
181  if (is_callable($fixture)) {
182  $fixture[1] .= 'Rollback';
183  if (is_callable($fixture)) {
184  $this->_applyOneFixture($fixture);
185  }
186  } else {
187  $fileInfo = pathinfo($fixture);
188  $extension = '';
189  if (isset($fileInfo['extension'])) {
190  $extension = '.' . $fileInfo['extension'];
191  }
192  $rollbackScript = $fileInfo['dirname'] . '/' . $fileInfo['filename'] . '_rollback' . $extension;
193  if (file_exists($rollbackScript)) {
194  $this->_applyOneFixture($rollbackScript);
195  }
196  }
197  }
198  $this->_appliedFixtures = [];
199  }
200 }
$fixtureBaseDir
Definition: bootstrap.php:15