// Path: src/main/java/net/rptools/common/expression/RunData.java
// public class RunData {
//   private static ThreadLocal<RunData> current = new ThreadLocal<RunData>();
//   public static Random RANDOM = new SecureRandom();
// 
//   private final Result result;
// 
//   private long randomValue;
//   private long randomMax;
//   private long randomMin;
// 
//   /** Should not be modified directly. Use {@link #recordRolled(Integer)} */
//   private final List<Integer> rolled = new LinkedList<>();
// 
//   private final RunData parent;
// 
//   public RunData(Result result) {
//     this(result, null);
//   }
// 
//   /**
//    * Constructor for a new RunData with a parent.
//    *
//    * @param result the result object
//    * @param parent the parent RunData, to whom all rolls will be reported (if parent is not null)
//    */
//   RunData(Result result, RunData parent) {
//     this.result = result;
//     this.parent = parent;
//   }
// 
//   /** Returns a random integer between 1 and <code>maxValue</code> */
//   public int randomInt(int maxValue) {
//     return randomInt(1, maxValue);
//   }
// 
//   /** Returns a list of random integers between 1 and <code>maxValue</code> */
//   public int[] randomInts(int num, int maxValue) {
//     int[] ret = new int[num];
//     for (int i = 0; i < num; i++) {
//       ret[i] = randomInt(maxValue);
//     }
//     return ret;
//   }
// 
//   /** Returns a random integer between <code>minValue</code> and <code>maxValue</code> */
//   public int randomInt(int minValue, int maxValue) {
//     randomMin += minValue;
//     randomMax += maxValue;
// 
//     int result = RANDOM.nextInt(maxValue - minValue + 1) + minValue;
// 
//     recordRolled(result);
// 
//     randomValue += result;
// 
//     return result;
//   }
// 
//   /**
//    * Returns a list of random integers between <code>minValue</code> and <code>maxValue</code>
//    *
//    * @return
//    */
//   public int[] randomInts(int num, int minValue, int maxValue) {
//     int[] ret = new int[num];
//     for (int i = 0; i < num; i++) ret[i] = randomInt(minValue, maxValue);
//     return ret;
//   }
// 
//   public Result getResult() {
//     return result;
//   }
// 
//   public static boolean hasCurrent() {
//     return current.get() != null;
//   }
// 
//   public static RunData getCurrent() {
//     RunData data = current.get();
//     if (data == null) {
//       throw new NullPointerException("data cannot be null");
//     }
//     return data;
//   }
// 
//   public static void setCurrent(RunData data) {
//     current.set(data);
//   }
// 
//   // If a seed is set we need to switch from SecureRandom to
//   // random.
//   public static void setSeed(long seed) {
//     RANDOM = new Random(seed);
//   }
// 
//   /**
//    * Records the rolls, passing through to the parent RunData (if any)
//    *
//    * @param roll the new roll to record
//    */
//   void recordRolled(Integer roll) {
//     if (parent != null) parent.recordRolled(roll);
//     rolled.add(roll);
//   }
// 
//   /**
//    * Gets the list of rolled integers, including rolls generated by any child instances
//    *
//    * @return the list of rolls, in order
//    */
//   public List<Integer> getRolled() {
//     return Collections.unmodifiableList(rolled);
//   }
// 
//   /**
//    * Create a new RunData instance for a child execution. Rolls produced by the child instance
//    * should propagate up to the list of rolls maintained by this (parent) instance.
//    *
//    * @param childResult the Result object for the new RunData
//    * @return a new RunData with this RunData as its parent
//    */
//   public RunData createChildRunData(Result childResult) {
//     return new RunData(childResult, this);
//   }
// }


import java.math.BigDecimal;
import junit.framework.TestCase;
import net.rptools.common.expression.RunData;
import net.rptools.parser.Expression;
import net.rptools.parser.MapVariableResolver;
import net.rptools.parser.Parser;
import net.rptools.parser.ParserException;
import net.rptools.parser.function.EvaluationException;
import net.rptools.parser.function.ParameterException;
/*
 * This software Copyright by the RPTools.net development team, and
 * licensed under the Affero GPL Version 3 or, at your option, any later
 * version.
 *
 * MapTool Source Code is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public
 * License * along with this source Code.  If not, please visit
 * <http://www.gnu.org/licenses/> and specifically the Affero license
 * text at <http://www.gnu.org/licenses/agpl.html>.
 */
package net.rptools.common.expression.function;


public class RollTest extends TestCase {
  public void testEvaluateRoll() throws ParserException, EvaluationException, ParameterException {
    Parser p = new Parser();
    p.addFunction(new Roll());

    try {
      RunData.setCurrent(new RunData(null));

      Expression xp = p.parseExpression("roll(6)");

      for (int i = 0; i < 1000; i++) {
// Path: src/main/java/net/rptools/common/expression/RunData.java
// public class RunData {
//   private static ThreadLocal<RunData> current = new ThreadLocal<RunData>();
//   public static Random RANDOM = new SecureRandom();
// 
//   private final Result result;
// 
//   private long randomValue;
//   private long randomMax;
//   private long randomMin;
// 
//   /** Should not be modified directly. Use {@link #recordRolled(Integer)} */
//   private final List<Integer> rolled = new LinkedList<>();
// 
//   private final RunData parent;
// 
//   public RunData(Result result) {
//     this(result, null);
//   }
// 
//   /**
//    * Constructor for a new RunData with a parent.
//    *
//    * @param result the result object
//    * @param parent the parent RunData, to whom all rolls will be reported (if parent is not null)
//    */
//   RunData(Result result, RunData parent) {
//     this.result = result;
//     this.parent = parent;
//   }
// 
//   /** Returns a random integer between 1 and <code>maxValue</code> */
//   public int randomInt(int maxValue) {
//     return randomInt(1, maxValue);
//   }
// 
//   /** Returns a list of random integers between 1 and <code>maxValue</code> */
//   public int[] randomInts(int num, int maxValue) {
//     int[] ret = new int[num];
//     for (int i = 0; i < num; i++) {
//       ret[i] = randomInt(maxValue);
//     }
//     return ret;
//   }
// 
//   /** Returns a random integer between <code>minValue</code> and <code>maxValue</code> */
//   public int randomInt(int minValue, int maxValue) {
//     randomMin += minValue;
//     randomMax += maxValue;
// 
//     int result = RANDOM.nextInt(maxValue - minValue + 1) + minValue;
// 
//     recordRolled(result);
// 
//     randomValue += result;
// 
//     return result;
//   }
// 
//   /**
//    * Returns a list of random integers between <code>minValue</code> and <code>maxValue</code>
//    *
//    * @return
//    */
//   public int[] randomInts(int num, int minValue, int maxValue) {
//     int[] ret = new int[num];
//     for (int i = 0; i < num; i++) ret[i] = randomInt(minValue, maxValue);
//     return ret;
//   }
// 
//   public Result getResult() {
//     return result;
//   }
// 
//   public static boolean hasCurrent() {
//     return current.get() != null;
//   }
// 
//   public static RunData getCurrent() {
//     RunData data = current.get();
//     if (data == null) {
//       throw new NullPointerException("data cannot be null");
//     }
//     return data;
//   }
// 
//   public static void setCurrent(RunData data) {
//     current.set(data);
//   }
// 
//   // If a seed is set we need to switch from SecureRandom to
//   // random.
//   public static void setSeed(long seed) {
//     RANDOM = new Random(seed);
//   }
// 
//   /**
//    * Records the rolls, passing through to the parent RunData (if any)
//    *
//    * @param roll the new roll to record
//    */
//   void recordRolled(Integer roll) {
//     if (parent != null) parent.recordRolled(roll);
//     rolled.add(roll);
//   }
// 
//   /**
//    * Gets the list of rolled integers, including rolls generated by any child instances
//    *
//    * @return the list of rolls, in order
//    */
//   public List<Integer> getRolled() {
//     return Collections.unmodifiableList(rolled);
//   }
// 
//   /**
//    * Create a new RunData instance for a child execution. Rolls produced by the child instance
//    * should propagate up to the list of rolls maintained by this (parent) instance.
//    *
//    * @param childResult the Result object for the new RunData
//    * @return a new RunData with this RunData as its parent
//    */
//   public RunData createChildRunData(Result childResult) {
//     return new RunData(childResult, this);
//   }
// }


// Path: src/test/java/net/rptools/common/expression/function/RollTest.java
import java.math.BigDecimal;
import junit.framework.TestCase;
import net.rptools.common.expression.RunData;
import net.rptools.parser.Expression;
import net.rptools.parser.MapVariableResolver;
import net.rptools.parser.Parser;
import net.rptools.parser.ParserException;
import net.rptools.parser.function.EvaluationException;
import net.rptools.parser.function.ParameterException;

/*
 * This software Copyright by the RPTools.net development team, and
 * licensed under the Affero GPL Version 3 or, at your option, any later
 * version.
 *
 * MapTool Source Code is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public
 * License * along with this source Code.  If not, please visit
 * <http://www.gnu.org/licenses/> and specifically the Affero license
 * text at <http://www.gnu.org/licenses/agpl.html>.
 */
package net.rptools.common.expression.function;


public class RollTest extends TestCase {
  public void testEvaluateRoll() throws ParserException, EvaluationException, ParameterException {
    Parser p = new Parser();
    p.addFunction(new Roll());

    try {
      RunData.setCurrent(new RunData(null));

      Expression xp = p.parseExpression("roll(6)");

      for (int i = 0; i < 1000; i++) {
        long result = ((BigDecimal) xp.evaluate()).longValueExact();