Version 1
[yaffs-website] / web / core / modules / migrate / tests / src / Unit / MigrationPluginManagerTest.php
diff --git a/web/core/modules/migrate/tests/src/Unit/MigrationPluginManagerTest.php b/web/core/modules/migrate/tests/src/Unit/MigrationPluginManagerTest.php
new file mode 100644 (file)
index 0000000..91351cf
--- /dev/null
@@ -0,0 +1,220 @@
+<?php
+
+namespace Drupal\Tests\migrate\Unit;
+
+use Drupal\migrate\Plugin\Migration;
+use Drupal\migrate\Plugin\MigrationPluginManager;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\migrate\Plugin\MigrationPluginManager
+ * @group migrate
+ */
+class MigrationPluginManagerTest extends UnitTestCase {
+
+  /**
+   * A plugin manager.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationPluginManager $pluginManager
+   */
+  protected $pluginManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    // Get a plugin manager for testing.
+    $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
+    $cache_backend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
+    $language_manager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
+    $this->pluginManager = new MigrationPluginManager($module_handler, $cache_backend, $language_manager);
+  }
+
+  /**
+   * Tests building dependencies for multiple migrations.
+   *
+   * @dataProvider dependencyProvider
+   */
+  public function testDependencyBuilding($migrations_data, $result_ids) {
+    $migrations = [];
+    foreach ($migrations_data as $migration_id => $migration_data) {
+      $migrations[$migration_id] = new TestMigrationMock($migration_id, $migration_data['dependencies']);
+    }
+
+    $ordered_migrations = $this->pluginManager->buildDependencyMigration($migrations, []);
+
+    // Verify results.
+    $this->assertEquals($result_ids, array_keys($ordered_migrations));
+    foreach ($migrations_data as $migration_id => $migration_data) {
+      $migration = $migrations[$migration_id];
+
+      $requirements = $migration_data['result_requirements'];
+      if (empty($requirements)) {
+        $this->assertEquals([], $migration->set);
+      }
+      else {
+        $requirements = array_combine($requirements, $requirements);
+
+        $this->assertEquals(1, count($migration->set));
+        list($set_prop, $set_requirements) = reset($migration->set);
+        $this->assertEquals('requirements', $set_prop);
+        $this->assertEquals($requirements, $set_requirements);
+      }
+    }
+  }
+
+  /**
+   * Provide dependency data for testing.
+   */
+  public function dependencyProvider() {
+    return [
+      // Just one migration, with no dependencies.
+      [
+        [
+          'm1' => [
+            'dependencies' => [],
+            'result_requirements' => [],
+          ],
+        ],
+        ['m1'],
+      ],
+
+      // Just one migration, with required dependencies.
+      [
+        [
+          'm1' => [
+            'dependencies' => [
+              'required' => ['required1', 'required2'],
+            ],
+            'result_requirements' => ['required1', 'required2'],
+          ],
+        ],
+        ['m1'],
+      ],
+
+      // Just one migration, with optional dependencies.
+      [
+        [
+          'm1' => [
+            'dependencies' => [
+              'optional' => ['optional1'],
+            ],
+            'result_requirements' => [],
+          ],
+        ],
+        ['m1'],
+      ],
+
+      // Multiple migrations.
+      [
+        [
+          'm1' => [
+            'dependencies' => [
+              'required' => ['required1', 'required2'],
+            ],
+            'result_requirements' => ['required1', 'required2'],
+          ],
+          'm2' => [
+            'dependencies' => [
+              'optional' => ['optional1'],
+            ],
+            'result_requirements' => [],
+          ],
+        ],
+        ['m1', 'm2'],
+      ],
+
+      // Multiple migrations, reordered due to optional requirement.
+      [
+        [
+          'm1' => [
+            'dependencies' => [
+              'optional' => ['m2'],
+            ],
+            'result_requirements' => [],
+          ],
+          'm2' => [
+            'dependencies' => [
+              'optional' => ['optional1'],
+            ],
+            'result_requirements' => [],
+          ],
+        ],
+        ['m2', 'm1'],
+      ],
+
+      // Ensure that optional requirements aren't turned into required ones,
+      // if the last migration has no optional deps.
+      [
+        [
+          'm1' => [
+            'dependencies' => [
+              'optional' => ['m2'],
+            ],
+            'result_requirements' => [],
+          ],
+          'm2' => [
+            'dependencies' => [],
+            'result_requirements' => [],
+          ],
+        ],
+        ['m2', 'm1'],
+      ],
+    ];
+  }
+
+}
+
+/**
+ * A mock migration plugin.
+ *
+ * Why are we using a custom class here?
+ *
+ * 1. The function buildDependencyMigration() calls $migration->set(), which
+ * is not actually in MigrationInterface.
+ *
+ * 2. The function buildDependencyMigration() calls array_multisort on an
+ * array with mocks in it. PHPUnit mocks are really complex, and if PHP tries
+ * to compare them it will die with "Nesting level too deep".
+ */
+class TestMigrationMock extends Migration {
+  /**
+   * The values passed into set().
+   *
+   * @var array $set
+   */
+  public $set = [];
+
+  /**
+   * TestMigrationMock constructor.
+   */
+  public function __construct($id, $dependencies) {
+    // Intentionally ignore parent constructor.
+    $this->id = $id;
+    $this->dependencies = $dependencies;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function id() {
+    return $this->id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getMigrationDependencies() {
+    return $this->dependencies;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function set($prop, $value) {
+    $this->set[] = func_get_args();
+  }
+
+}