package com.pholser.junit.quickcheck.internal.generator;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;

import com.pholser.junit.quickcheck.generator.GenerationStatus;
import com.pholser.junit.quickcheck.generator.Generator;
import com.pholser.junit.quickcheck.internal.ParameterTypeContext;
import com.pholser.junit.quickcheck.internal.generator.conventiontestclasses.Convention;
import com.pholser.junit.quickcheck.internal.generator.conventiontestclasses.GeneratesOtherTypes;
import com.pholser.junit.quickcheck.internal.generator.conventiontestclasses.NotAGenerator;
import com.pholser.junit.quickcheck.random.SourceOfRandomness;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class RegisterGeneratorsByConventionTest {
    private GeneratorRepository repo;
    @Mock private SourceOfRandomness random;
    @Mock private GenerationStatus generationStatus;

    @Before
    public void setupRepository() {
        repo = new GeneratorRepository(random);
    }

    @Test
    public void canGenerateValues() {
        Generator<?> generator =
            repo.generatorFor(ParameterTypeContext.forClass(Convention.class));

        assertNotNull(generator);
        assertThat(
            generator.generate(random, generationStatus),
            instanceOf(Convention.class));
    }

    @Test
    public void classNameFollowsConventionButNotAGenerator() {
        assertThatNoGeneratorCanBeFound(NotAGenerator.class);
    }

    @Test
    public void noValueTypeMatch() {
        assertThatNoGeneratorCanBeFound(GeneratesOtherTypes.class);
    }

    @Test
    public void notAClassFollowingNamingConvention() {
        assertThatNoGeneratorCanBeFound(this.getClass());
    }

    private void assertThatNoGeneratorCanBeFound(Class<?> valueClass) {
        IllegalArgumentException ex =
            assertThrows(
                IllegalArgumentException.class,
                () -> repo.generatorFor(
                    ParameterTypeContext.forClass(valueClass)));

        assertThat(
            ex.getMessage(),
            containsString(
                "Cannot find generator for " + valueClass.getName()));
    }
}

@@ -55,253 +55,8 @@
 r;%0A%0A
-import static org.hamcrest.MatcherAssert.assertThat;%0Aimport static org.hamcrest.Matchers.containsString;%0Aimport static org.hamcrest.Matchers.instanceOf;%0Aimport static org.junit.Assert.assertNotNull;%0Aimport static org.junit.Assert.assertThrows;%0A%0A
 impo
@@ -104,25 +104,18 @@
 .Generat
-ionStatus
+or
 ;%0Aimport
@@ -144,35 +144,46 @@
 ckcheck.
-generator.Generator
+internal.GeometricDistribution
 ;%0Aimport
@@ -637,148 +637,279 @@
 st;%0A
+%0A
 import 
-org.junit.runner.RunWith;%0Aimport org.mockito.Mock;%0Aimport org.mockito.runners.MockitoJUnitRunner;%0A%0A@RunWith(MockitoJUnitRunner.class)
+java.util.Random;%0A%0Aimport static org.hamcrest.MatcherAssert.assertThat;%0Aimport static org.hamcrest.Matchers.containsString;%0Aimport static org.hamcrest.Matchers.instanceOf;%0Aimport static org.junit.Assert.assertNotNull;%0Aimport static org.junit.Assert.assertThrows;%0A
 %0Apub
@@ -993,30 +993,24 @@
 y repo;%0A    
-@Mock 
 private Sour
@@ -1036,109 +1036,111 @@
 om;%0A
-    @Mock private GenerationStatus generationStatus;%0A%0A    @Before%0A    public void setupRepository() %7B
+%0A    @Before%0A    public void setupRepository() %7B%0A        random = new SourceOfRandomness(new Random());
 %0A   
@@ -1442,32 +1442,115 @@
 ate(
-random, generationStatus
+%0A                random,%0A                new SimpleGenerationStatus(new GeometricDistribution(), random, 1)
 ),%0A 

remove to-be-removed mockito class