code: def test_hetero_link_neighbor_loader_triplet(
      disjoint, temporal, amount
  ):
      if not disjoint and temporal:
          return
  
      data = HeteroData()
  
      data["paper"].x = torch.arange(100)
      data["author"].x = torch.arange(100, 300)
  
      data["paper", "paper"].edge_index = get_random_edge_index(
          100, 100, 400
      )
      edge_label_index = get_random_edge_index(100, 100, 500)
      data["paper", "paper"].edge_label_index = edge_label_index
      data["paper", "author"].edge_index = get_random_edge_index(
          100, 200, 1000
      )
      data["author", "paper"].edge_index = get_random_edge_index(
          200, 100, 1000
      )
  
      time_attr = edge_label_time = None
      if temporal:
          time_attr = "time"
          data["paper"].time = torch.arange(data["paper"].num_nodes)
          data["author"].time = torch.arange(data["author"].num_nodes)
  
          edge_label_time = torch.max(
              data["paper"].time[
                  data["paper", "paper"].edge_label_index[0]
              ],
              data["paper"].time[
                  data["paper", "paper"].edge_label_index[1]
              ],
          )
          edge_label_time = edge_label_time + 50
  
      weight = (
          torch.rand(data["paper"].num_nodes) if not temporal else None
      )
  
      batch_size = 20
      index = (
          ("paper", "paper"),
          data["paper", "paper"].edge_label_index,
      )
      loader = LinkNeighborLoader(
          data,
          num_neighbors=[-1] * 2,
          batch_size=batch_size,
          edge_label_index=index,
          edge_label_time=edge_label_time,
          time_attr=time_attr,
          disjoint=disjoint,
          neg_sampling=dict(
              mode="triplet", amount=amount, weight=weight
          ),
          shuffle=True,
      )
  
      assert str(loader) == "LinkNeighborLoader()"
      assert len(loader) == 500 / batch_size
  
      for batch in loader:
          assert isinstance(batch, HeteroData)
  
          node_store = batch["paper"]
          edge_store = batch["paper", "paper"]
  
          # Check that `src_index` and `dst_pos_index` point to valid edges:
          assert torch.equal(
              node_store.x[node_store.src_index],
              data["paper", "paper"].edge_label_index[
                  0, edge_store.input_id
              ],
          )
          assert torch.equal(
              node_store.x[node_store.dst_pos_index],
              data["paper", "paper"].edge_label_index[
                  1, edge_store.input_id
              ],
          )
  
          # Check that `dst_neg_index` points to valid nodes in the batch:
          if amount == 1:
              assert node_store.dst_neg_index.size() == (batch_size,)
          else:
              assert node_store.dst_neg_index.size() == (
                  batch_size,
                  amount,
              )
          assert node_store.dst_neg_index.min() >= 0
          assert node_store.dst_neg_index.max() < node_store.num_nodes
  
          if disjoint:
              # In disjoint mode, seed nodes should always be placed first:
              assert node_store.src_index.min() == 0
              assert node_store.src_index.max() == batch_size - 1
  
              assert node_store.dst_pos_index.min() == batch_size
              assert (
                  node_store.dst_pos_index.max() == 2 * batch_size - 1
              )
  
              assert node_store.dst_neg_index.min() == 2 * batch_size
              max_seed_nodes = 2 * batch_size + batch_size * amount
              assert (
                  node_store.dst_neg_index.max() == max_seed_nodes - 1
              )
  
              assert node_store.batch.min() == 0
              assert node_store.batch.max() == batch_size - 1
  
              # Check that `batch` is always increasing:
              for i in range(0, max_seed_nodes, batch_size):
                  batch_vector = node_store.batch[i : i + batch_size]
                  assert torch.equal(
                      batch_vector, torch.arange(batch_size)
                  )
  
          if temporal:
              for i in range(batch_size):
                  assert (
                      node_store.time[node_store.batch == i].max()
                      <= node_store.seed_time[i]
                  )
  
file_path: pytorch_geometric/test/loader/test_link_neighbor_loader.py
imports: import pytest
  import torch
  from torch_geometric.data import Data, HeteroData
  from torch_geometric.loader import LinkNeighborLoader
  from torch_geometric.testing import MyFeatureStore, MyGraphStore, get_random_edge_index, onlyNeighborSampler, withCUDA, withPackage
label_desc: Use image node_id 12 for calling a global function with example usage: test_hetero_link_neighbor_loader_triplet(disjoint, temporal, amount) without return types