You are here

public function EntityFieldTest::testComputedFields in Drupal 9

Same name and namespace in other branches
  1. 8 core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php \Drupal\KernelTests\Core\Entity\EntityFieldTest::testComputedFields()
  2. 10 core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php \Drupal\KernelTests\Core\Entity\EntityFieldTest::testComputedFields()

Tests all the interaction points of a computed field.

File

core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php, line 748

Class

EntityFieldTest
Tests the Entity Field API.

Namespace

Drupal\KernelTests\Core\Entity

Code

public function testComputedFields() {
  $this
    ->installEntitySchema('entity_test_computed_field');
  \Drupal::state()
    ->set('entity_test_computed_field_item_list_value', [
    'foo computed',
  ]);

  // Check that the values are not computed unnecessarily during the lifecycle
  // of an entity when the field is not interacted with directly.
  \Drupal::state()
    ->set('computed_test_field_execution', 0);
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertSame(0, \Drupal::state()
    ->get('computed_test_field_execution', 0));
  $entity->name->value = $this
    ->randomString();
  $this
    ->assertSame(0, \Drupal::state()
    ->get('computed_test_field_execution', 0));
  $entity
    ->save();
  $this
    ->assertSame(0, \Drupal::state()
    ->get('computed_test_field_execution', 0));

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::getValue().
  \Drupal::state()
    ->set('computed_test_field_execution', 0);
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertSame([
    [
      'value' => 'foo computed',
    ],
  ], $entity->computed_string_field
    ->getValue());

  // Check that the values are only computed once.
  $this
    ->assertSame(1, \Drupal::state()
    ->get('computed_test_field_execution', 0));

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::setValue(). This also
  // checks that a subsequent getter does not try to re-compute the value.
  \Drupal::state()
    ->set('computed_test_field_execution', 0);
  $entity = EntityTestComputedField::create([]);
  $entity->computed_string_field
    ->setValue([
    [
      'value' => 'foo computed 1',
    ],
    [
      'value' => 'foo computed 2',
    ],
  ]);
  $this
    ->assertSame([
    [
      'value' => 'foo computed 1',
    ],
    [
      'value' => 'foo computed 2',
    ],
  ], $entity->computed_string_field
    ->getValue());

  // Check that the values have not been computed when they were explicitly
  // set.
  $this
    ->assertSame(0, \Drupal::state()
    ->get('computed_test_field_execution', 0));

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::getString().
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertSame('foo computed', $entity->computed_string_field
    ->getString());

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::get().
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertSame('foo computed', $entity->computed_string_field
    ->get(0)->value);
  $this
    ->assertEmpty($entity->computed_string_field
    ->get(1));

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::set().
  $entity = EntityTestComputedField::create([]);
  $entity->computed_string_field
    ->set(1, 'foo computed 1');
  $this
    ->assertSame('foo computed', $entity->computed_string_field[0]->value);
  $this
    ->assertSame('foo computed 1', $entity->computed_string_field[1]->value);
  $entity->computed_string_field
    ->set(0, 'foo computed 0');
  $this
    ->assertSame('foo computed 0', $entity->computed_string_field[0]->value);
  $this
    ->assertSame('foo computed 1', $entity->computed_string_field[1]->value);

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::appendItem().
  $entity = EntityTestComputedField::create([]);
  $entity->computed_string_field
    ->appendItem('foo computed 1');
  $this
    ->assertSame('foo computed', $entity->computed_string_field[0]->value);
  $this
    ->assertSame('foo computed 1', $entity->computed_string_field[1]->value);

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::removeItem().
  $entity = EntityTestComputedField::create([]);
  $entity->computed_string_field
    ->removeItem(0);
  $this
    ->assertTrue($entity->computed_string_field
    ->isEmpty());

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::isEmpty().
  \Drupal::state()
    ->set('entity_test_computed_field_item_list_value', []);
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertTrue($entity->computed_string_field
    ->isEmpty());
  \Drupal::state()
    ->set('entity_test_computed_field_item_list_value', [
    'foo computed',
  ]);
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertFalse($entity->computed_string_field
    ->isEmpty());

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::filter().
  $filter_callback = function ($item) {
    return !$item
      ->isEmpty();
  };
  $entity = EntityTestComputedField::create([]);
  $entity->computed_string_field
    ->filter($filter_callback);
  $this
    ->assertCount(1, $entity->computed_string_field);

  // Add an empty item to the list and check that it is filtered out.
  $entity->computed_string_field
    ->appendItem();
  $entity->computed_string_field
    ->filter($filter_callback);
  $this
    ->assertCount(1, $entity->computed_string_field);

  // Add a non-empty item to the list and check that it is not filtered out.
  $entity->computed_string_field
    ->appendItem('foo computed 1');
  $entity->computed_string_field
    ->filter($filter_callback);
  $this
    ->assertCount(2, $entity->computed_string_field);

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::offsetExists().
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertTrue($entity->computed_string_field
    ->offsetExists(0));
  $this
    ->assertFalse($entity->computed_string_field
    ->offsetExists(1));

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::getIterator().
  $entity = EntityTestComputedField::create([]);
  foreach ($entity->computed_string_field as $delta => $item) {
    $this
      ->assertSame('foo computed', $item->value);
  }

  // Test \Drupal\Core\TypedData\ComputedItemListTrait::count().
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertCount(1, $entity->computed_string_field);

  // Check that computed items are not auto-created when they have no values.
  \Drupal::state()
    ->set('entity_test_computed_field_item_list_value', []);
  $entity = EntityTestComputedField::create([]);
  $this
    ->assertCount(0, $entity->computed_string_field);

  // Test \Drupal\Core\Field\FieldItemList::equals() for a computed field.
  \Drupal::state()
    ->set('entity_test_computed_field_item_list_value', [
    'foo computed',
  ]);
  $entity = EntityTestComputedField::create([]);
  $computed_item_list1 = $entity->computed_string_field;
  $entity = EntityTestComputedField::create([]);
  $computed_item_list2 = $entity->computed_string_field;
  $this
    ->assertTrue($computed_item_list1
    ->equals($computed_item_list2));
  $computed_item_list2->value = 'foo computed 2';
  $this
    ->assertFalse($computed_item_list1
    ->equals($computed_item_list2));
}