/*
 * Copyright 2015 Olivier Grégoire <https://github.com/fror>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package be.fror.common.base;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThan;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import static org.junit.Assert.*;

import org.hamcrest.Matcher;

import java.util.Random;

/**
 *
 * @author Olivier Grégoire <https://github.com/fror>
 */
public class RandomDistributionTest {

  public RandomDistributionTest() {
  }

  @BeforeClass
  public static void setUpClass() {
  }

  @AfterClass
  public static void tearDownClass() {
  }

  private RandomDistribution instance;

  @Before
  public void setUp() {
    instance = RandomDistribution.using(new Random(0L));
  }

  @After
  public void tearDown() {
    instance = null;
  }

  /**
   * Test of using method, of class RandomDistribution.
   */
  @Test
  public void testUsing() {
  }

  /**
   * Test of uniform method, of class RandomDistribution.
   */
  @Test
  public void testUniform_0args() {
    for (int i = 0; i < 10000; i++) {
      assertThat(instance.uniform(), inRangeClosedOpen(0.0, 1.0));
    }
  }

  /**
   * Test of uniform method, of class RandomDistribution.
   */
  @Test
  public void testUniform_int() {
    for (int i = 0; i < 10000; i++) {
      assertThat(instance.uniform(1), is(0));
      assertThat(instance.uniform(2), is(inRangeClosedOpen(0, 2)));
      assertThat(instance.uniform(10), is(inRangeClosedOpen(0, 10)));
    }
  }

  /**
   * Test of uniform method, of class RandomDistribution.
   */
  @Test
  public void testUniform_int_int() {
    for (int i = 0; i < 10000; i++) {
      assertThat(instance.uniform(10, 11), is(10));
      assertThat(instance.uniform(10, 12), is(inRangeClosedOpen(10, 12)));
      assertThat(instance.uniform(10, 20), is(inRangeClosedOpen(10, 20)));
    }
  }

  /**
   * Test of uniform method, of class RandomDistribution.
   */
  @Test
  public void testUniform_double_double() {
    for (int i = 0; i < 10000; i++) {
      assertThat(instance.uniform(-1.0d, 1.0d), inRangeClosedOpen(-1.0d, 1.0d));
    }
  }

  /**
   * Test of bernoulli method, of class RandomDistribution.
   */
  @Test
  public void testBernoulli_double() {

    int runs = 10000;
    double distribution = 0.1;
    double epsilon = 0.1;

    int count = 0;
    for (int i = 0; i < runs; i++) {
      if (instance.bernoulli(distribution)) {
        count++;
      }
    }
    assertThat((double) count / runs, closeTo(distribution, epsilon));
  }

  /**
   * Test of bernoulli method, of class RandomDistribution.
   */
  @Test
  public void testBernoulli_0args() {

    int runs = 10000;
    double epsilon = 0.1;

    int count = 0;
    for (int i = 0; i < runs; i++) {
      if (instance.bernoulli()) {
        count++;
      }
    }
    assertThat((double) count / runs, closeTo(0.5, epsilon));
  }

  /**
   * Test of gaussian method, of class RandomDistribution.
   */
  @Test
  public void testGaussian_0args() {
  }

  /**
   * Test of gaussian method, of class RandomDistribution.
   */
  @Test
  public void testGaussian_double_double() {
  }

  /**
   * Test of geometric method, of class RandomDistribution.
   */
  @Test
  public void testGeometric() {
  }

  /**
   * Test of poisson method, of class RandomDistribution.
   */
  @Test
  public void testPoisson() {
  }

  /**
   * Test of pareto method, of class RandomDistribution.
   */
  @Test
  public void testPareto() {
  }

  /**
   * Test of cauchy method, of class RandomDistribution.
   */
  @Test
  public void testCauchy() {
  }

  /**
   * Test of discrete method, of class RandomDistribution.
   */
  @Test
  public void testDiscrete_doubleArr() {
  }

  /**
   * Test of discrete method, of class RandomDistribution.
   */
  @Test
  public void testDiscrete_doubleArr_double() {
  }

  /**
   * Test of exp method, of class RandomDistribution.
   */
  @Test
  public void testExponential() {
  }

  private static Matcher<Double> inRangeClosedOpen(double min, double max) {
    return allOf(greaterThanOrEqualTo(min), lessThan(max));
  }

  private static Matcher<Integer> inRangeClosedOpen(int min, int max) {
    return allOf(greaterThanOrEqualTo(min), lessThan(max));
  }

}

@@ -1358,32 +1358,164 @@
 nClass() %7B%0A  %7D%0A%0A
+  private static final int DEFAULT_RUNS = 100000;%0A  %0A  // Allow 1%25 deviation%0A  private static final double DEFAULT_EPSILON = 0.01;%0A%0A
   private Random
@@ -1537,16 +1537,16 @@
 stance;%0A
-
 %0A  @Befo
@@ -1935,37 +1935,44 @@
 (int i = 0; i %3C 
-10000
+DEFAULT_RUNS
 ; i++) %7B%0A      a
@@ -2170,37 +2170,44 @@
 (int i = 0; i %3C 
-10000
+DEFAULT_RUNS
 ; i++) %7B%0A      a
@@ -2526,37 +2526,44 @@
 (int i = 0; i %3C 
-10000
+DEFAULT_RUNS
 ; i++) %7B%0A      a
@@ -2914,21 +2914,28 @@
  0; i %3C 
-10000
+DEFAULT_RUNS
 ; i++) %7B
@@ -3154,37 +3154,44 @@
 %0A    int runs = 
-10000
+DEFAULT_RUNS
 ;%0A    double dis
@@ -3220,35 +3220,47 @@
 ouble epsilon = 
-0.1
+DEFAULT_EPSILON
 ;%0A%0A    int count
@@ -3589,21 +3589,28 @@
  runs = 
-10000
+DEFAULT_RUNS
 ;%0A    do
@@ -3624,19 +3624,31 @@
 silon = 
-0.1
+DEFAULT_EPSILON
 ;%0A%0A    i

Refactor RandomDistributionTest