test_class.declarator: topic1 = "topic1"
test_class.modifier: final private
test_class.original_string: final private String topic1 = "topic1";
test_class.type: String
test_class.var_name: topic1
test_class.declarator: topic2 = "topic2"
test_class.modifier: final private
test_class.original_string: final private String topic2 = "topic2";
test_class.type: String
test_class.var_name: topic2
test_class.declarator: intSerde = Serdes.Integer()
test_class.modifier: final private
test_class.original_string: final private Serde<Integer> intSerde = Serdes.Integer();
test_class.type: Serde<Integer>
test_class.var_name: intSerde
test_class.declarator: stringSerde = Serdes.String()
test_class.modifier: final private
test_class.original_string: final private Serde<String> stringSerde = Serdes.String();
test_class.type: Serde<String>
test_class.var_name: stringSerde
test_class.declarator: driver = null
test_class.modifier: private
test_class.original_string: private KStreamTestDriver driver = null;
test_class.type: KStreamTestDriver
test_class.var_name: driver
test_class.declarator: stateDir = null
test_class.modifier: private
test_class.original_string: private File stateDir = null;
test_class.type: File
test_class.var_name: stateDir
test_class.file: streams/src/test/java/org/apache/kafka/streams/kstream/internals/KTableKTableLeftJoinTest.java
test_class.identifier: KTableKTableLeftJoinTest
test_case.body: @Test
      public void testJoin() throws Exception {
          final KStreamBuilder builder = new KStreamBuilder();
  
          final int[] expectedKeys = new int[]{0, 1, 2, 3};
  
          KTable<Integer, String> table1 = builder.table(intSerde, stringSerde, topic1);
          KTable<Integer, String> table2 = builder.table(intSerde, stringSerde, topic2);
          KTable<Integer, String> joined = table1.leftJoin(table2, MockValueJoiner.STRING_JOINER);
          MockProcessorSupplier<Integer, String> processor;
          processor = new MockProcessorSupplier<>();
          joined.toStream().process(processor);
  
          Collection<Set<String>> copartitionGroups = builder.copartitionGroups();
  
          assertEquals(1, copartitionGroups.size());
          assertEquals(new HashSet<>(Arrays.asList(topic1, topic2)), copartitionGroups.iterator().next());
  
          KTableValueGetterSupplier<Integer, String> getterSupplier = ((KTableImpl<Integer, String, String>) joined).valueGetterSupplier();
  
          driver = new KStreamTestDriver(builder, stateDir);
          driver.setTime(0L);
  
          KTableValueGetter<Integer, String> getter = getterSupplier.get();
          getter.init(driver.context());
  
          // push two items to the primary stream. the other table is empty
  
          for (int i = 0; i < 2; i++) {
              driver.process(topic1, expectedKeys[i], "X" + expectedKeys[i]);
          }
  
          processor.checkAndClearProcessResult("0:X0+null", "1:X1+null");
          checkJoinedValues(getter, kv(0, "X0+null"), kv(1, "X1+null"), kv(2, null), kv(3, null));
  
          // push two items to the other stream. this should produce two items.
  
          for (int i = 0; i < 2; i++) {
              driver.process(topic2, expectedKeys[i], "Y" + expectedKeys[i]);
          }
  
          processor.checkAndClearProcessResult("0:X0+Y0", "1:X1+Y1");
          checkJoinedValues(getter, kv(0, "X0+Y0"), kv(1, "X1+Y1"), kv(2, null), kv(3, null));
  
          // push all four items to the primary stream. this should produce four items.
  
          for (int i = 0; i < expectedKeys.length; i++) {
              driver.process(topic1, expectedKeys[i], "X" + expectedKeys[i]);
          }
  
          processor.checkAndClearProcessResult("0:X0+Y0", "1:X1+Y1", "2:X2+null", "3:X3+null");
          checkJoinedValues(getter, kv(0, "X0+Y0"), kv(1, "X1+Y1"), kv(2, "X2+null"), kv(3, "X3+null"));
  
          // push all items to the other stream. this should produce four items.
          for (int i = 0; i < expectedKeys.length; i++) {
              driver.process(topic2, expectedKeys[i], "YY" + expectedKeys[i]);
          }
  
          processor.checkAndClearProcessResult("0:X0+YY0", "1:X1+YY1", "2:X2+YY2", "3:X3+YY3");
          checkJoinedValues(getter, kv(0, "X0+YY0"), kv(1, "X1+YY1"), kv(2, "X2+YY2"), kv(3, "X3+YY3"));
  
          // push all four items to the primary stream. this should produce four items.
  
          for (int i = 0; i < expectedKeys.length; i++) {
              driver.process(topic1, expectedKeys[i], "X" + expectedKeys[i]);
          }
  
          processor.checkAndClearProcessResult("0:X0+YY0", "1:X1+YY1", "2:X2+YY2", "3:X3+YY3");
          checkJoinedValues(getter, kv(0, "X0+YY0"), kv(1, "X1+YY1"), kv(2, "X2+YY2"), kv(3, "X3+YY3"));
  
          // push two items with null to the other stream as deletes. this should produce two item.
  
          for (int i = 0; i < 2; i++) {
              driver.process(topic2, expectedKeys[i], null);
          }
  
          processor.checkAndClearProcessResult("0:X0+null", "1:X1+null");
          checkJoinedValues(getter, kv(0, "X0+null"), kv(1, "X1+null"), kv(2, "X2+YY2"), kv(3, "X3+YY3"));
  
          // push all four items to the primary stream. this should produce four items.
  
          for (int i = 0; i < expectedKeys.length; i++) {
              driver.process(topic1, expectedKeys[i], "XX" + expectedKeys[i]);
          }
  
          processor.checkAndClearProcessResult("0:XX0+null", "1:XX1+null", "2:XX2+YY2", "3:XX3+YY3");
          checkJoinedValues(getter, kv(0, "XX0+null"), kv(1, "XX1+null"), kv(2, "XX2+YY2"), kv(3, "XX3+YY3"));
      }
test_case.class_method_signature: KTableKTableLeftJoinTest.testJoin()
test_case.full_signature: @Test public void testJoin()
test_case.identifier: testJoin
test_case.invocations: table table leftJoin process toStream copartitionGroups assertEquals size assertEquals asList next iterator valueGetterSupplier setTime get init context process checkAndClearProcessResult checkJoinedValues kv kv kv kv process checkAndClearProcessResult checkJoinedValues kv kv kv kv process checkAndClearProcessResult checkJoinedValues kv kv kv kv process checkAndClearProcessResult checkJoinedValues kv kv kv kv process checkAndClearProcessResult checkJoinedValues kv kv kv kv process checkAndClearProcessResult checkJoinedValues kv kv kv kv process checkAndClearProcessResult checkJoinedValues kv kv kv kv
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testJoin()
focal_class.file: streams/src/main/java/org/apache/kafka/streams/kstream/internals/KTableKTableLeftJoin.java
focal_class.identifier: KTableKTableLeftJoin
focal_class.class_method_signature: KTableKTableLeftJoin.KTableKTableLeftJoin(KTableImpl<K, ?, V1> table1, KTableImpl<K, ?, V2> table2, ValueJoiner<V1, V2, R> joiner)
focal_class.full_signature:   KTableKTableLeftJoin(KTableImpl<K, ?, V1> table1, KTableImpl<K, ?, V2> table2, ValueJoiner<V1, V2, R> joiner)
focal_class.identifier: KTableKTableLeftJoin
focal_class.parameters: (KTableImpl<K, ?, V1> table1, KTableImpl<K, ?, V2> table2, ValueJoiner<V1, V2, R> joiner)
focal_class.signature:  KTableKTableLeftJoin(KTableImpl<K, ?, V1> table1, KTableImpl<K, ?, V2> table2, ValueJoiner<V1, V2, R> joiner)
focal_class.class_method_signature: KTableKTableLeftJoin.get()
focal_class.full_signature: @Override public Processor<K, Change<V1>> get()
focal_class.identifier: get
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: Processor<K, Change<V1>>
focal_class.signature: Processor<K, Change<V1>> get()
focal_class.class_method_signature: KTableKTableLeftJoin.view()
focal_class.full_signature: @Override public KTableValueGetterSupplier<K, R> view()
focal_class.identifier: view
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: KTableValueGetterSupplier<K, R>
focal_class.signature: KTableValueGetterSupplier<K, R> view()
focal_class.superclass: extends KTableKTableAbstractJoin<K, R, V1, V2>
focal_method.body: @Override
      public Processor<K, Change<V1>> get() {
          return new KTableKTableLeftJoinProcessor(valueGetterSupplier2.get());
      }
focal_method.class_method_signature: KTableKTableLeftJoin.get()
focal_method.full_signature: @Override public Processor<K, Change<V1>> get()
focal_method.identifier: get
focal_method.invocations: get
focal_method.modifiers: @Override public
focal_method.parameters: ()
focal_method.return: Processor<K, Change<V1>>
focal_method.signature: Processor<K, Change<V1>> get()