package com.lmax.disruptor;

import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import com.lmax.disruptor.support.LongEvent;
import com.lmax.disruptor.util.DaemonThreadFactory;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.locks.LockSupport;

@RunWith(Parameterized.class)
public class BatchingTest
{
    private final ProducerType producerType;

    public BatchingTest(ProducerType producerType)
    {
        this.producerType = producerType;
    }

    @Parameters
    public static Collection<Object[]> generateData()
    {
        Object[][] producerTypes = {{ProducerType.MULTI}, {ProducerType.SINGLE}};
        return Arrays.asList(producerTypes);
    }

    private static class ParallelEventHandler implements EventHandler<LongEvent>
    {
        private final long mask;
        private final long ordinal;
        private final int batchSize = 10;

        private long eventCount;
        private long batchCount;
        private long publishedValue;
        private long tempValue;
        private volatile long processed;

        ParallelEventHandler(long mask, long ordinal)
        {
            this.mask = mask;
            this.ordinal = ordinal;
        }

        @Override
        public void onEvent(LongEvent event, long sequence, boolean endOfBatch) throws Exception
        {
            if ((sequence & mask) == ordinal)
            {
                eventCount++;
                tempValue = event.get();
            }

            if (endOfBatch || ++batchCount >= batchSize)
            {
                publishedValue = tempValue;
                batchCount = 0;
            }
            else
            {
                LockSupport.parkNanos(1);
            }

            processed = sequence;
        }
    }

    @SuppressWarnings("unchecked")
    @Test
    public void shouldBatch() throws Exception
    {
        Disruptor<LongEvent> d = new Disruptor<>(
                LongEvent.FACTORY, 2048, DaemonThreadFactory.INSTANCE,
                producerType, new SleepingWaitStrategy());

        ParallelEventHandler handler1 = new ParallelEventHandler(1, 0);
        ParallelEventHandler handler2 = new ParallelEventHandler(1, 1);

        d.handleEventsWith(handler1, handler2);

        RingBuffer<LongEvent> buffer = d.start();

        EventTranslator<LongEvent> translator = (event, sequence) -> event.set(sequence);

        int eventCount = 10000;
        for (int i = 0; i < eventCount; i++)
        {
            buffer.publishEvent(translator);
        }

        while (handler1.processed != eventCount - 1 ||
            handler2.processed != eventCount - 1)
        {
            Thread.sleep(1);
        }

        Assert.assertThat(handler1.publishedValue, CoreMatchers.is((long) eventCount - 2));
        Assert.assertThat(handler1.eventCount, CoreMatchers.is((long) eventCount / 2));
        Assert.assertThat(handler2.publishedValue, CoreMatchers.is((long) eventCount - 1));
        Assert.assertThat(handler2.eventCount, CoreMatchers.is((long) eventCount / 2));
    }
}

@@ -259,95 +259,21 @@
 nit.
-Assert;%0Aimport org.junit.Test;%0Aimport org.junit.runner.RunWith;%0Aimport org.junit.runner
+jupiter.param
 s.Pa
@@ -283,16 +283,20 @@
 eterized
+Test
 ;%0Aimport
@@ -310,260 +310,315 @@
 nit.
-runners.Parameterized.Parameter
+jupiter.params.provider.Argument
 s;%0A
-%0A
 import 
-java.util.Arrays;%0Aimport java.util.Collection;%0Aimport java.util.concurrent.locks.LockSupport;%0A%0A@RunWith(Parameterized.class)%0Apublic class BatchingTest%0A%7B%0A    private final ProducerType producerType;%0A%0A    
+org.junit.jupiter.params.provider.MethodSource;%0A%0Aimport java.util.concurrent.locks.LockSupport;%0Aimport java.util.stream.Stream;%0A%0Aimport static org.hamcrest.MatcherAssert.assertThat;%0Aimport static org.junit.jupiter.params.provider.Arguments.arguments;%0A%0A
 public 
+class 
 Batc
@@ -629,144 +629,45 @@
 Test
-(ProducerType producerType)%0A    %7B%0A        this.producerType = producerType;%0A    %7D%0A%0A    @Parameters%0A    public static Collection%3CObject%5B%5D
+%0A%7B%0A    public static Stream%3CArguments
 %3E ge
@@ -697,37 +697,35 @@
     
-Object%5B%5D%5B%5D producerTypes = %7B%7B
+return Stream.of(arguments(
 Prod
@@ -742,12 +742,21 @@
 ULTI
-%7D, %7B
+), arguments(
 Prod
@@ -774,54 +774,9 @@
 NGLE
-%7D%7D;%0A        return Arrays.asList(producerTypes
+)
 );%0A 
@@ -1913,41 +1913,113 @@
    @
-Test%0A    public void shouldBatch(
+ParameterizedTest%0A    @MethodSource(%22generateData%22)%0A    public void shouldBatch(ProducerType producerType
 ) th
@@ -2854,39 +2854,32 @@
      %7D%0A%0A        
-Assert.
 assertThat(handl
@@ -2939,39 +2939,32 @@
  - 2));%0A        
-Assert.
 assertThat(handl
@@ -3020,39 +3020,32 @@
  / 2));%0A        
-Assert.
 assertThat(handl
@@ -3113,23 +3113,16 @@
         
-Assert.
 assertTh

Rewrite BatchingTest in spirit of JUnit 5