All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.junitpioneer.jupiter.params.Range Maven / Gradle / Ivy

There is a newer version: 2.3.0
Show newest version
/*
 * Copyright 2015-2020 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v2.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v20.html
 */

package org.junitpioneer.jupiter.params;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.junit.platform.commons.PreconditionViolationException;
import org.junit.platform.commons.util.Preconditions;

/**
 * An iterator for numerical ranges, used as the backing logic for {@link RangeSourceArgumentsProvider}.
 * @param  The numerical type used by the range.
 */
abstract class Range> implements Iterator {

	private N from;
	private N to;
	private N step;
	private boolean closed;
	private N current;
	private int sign;

	Range(N from, N to, N step, boolean closed) {
		this.from = from;
		this.to = to;
		this.step = step;
		this.closed = closed;
		current = null;
		sign = step.compareTo(getZero());
	}

	/**
	 * Asserts the range is valid.
	 * @throws PreconditionViolationException if the range is not valid
	 */
	void validate() {
		Preconditions.condition(!step.equals(getZero()), "Illegal range. The step cannot be zero.");

		Preconditions
				.condition(closed || !from.equals(to), "Illegal range. Equal from and to will produce an empty range.");

		int cmp = from.compareTo(to);
		Preconditions
				.condition((cmp < 0 != sign < 0) || (closed && cmp == 0),
					() -> String
							.format("Illegal range. There's no way to get from %s to %s with a step of %s.", from, to,
								step));
	}

	N getStep() {
		return step;
	}

	N getCurrent() {
		return current;
	}

	/**
	 * The next value in the range. Calling {@link #next()} will return this value and advance the iterator to it.
	 */
	abstract N nextValue();

	private N getNextValue() {
		if (current == null) {
			return from;
		}
		return nextValue();
	}

	/**
	 * The value of the no-op "zero", illegal step in terms of N
	 */
	abstract N getZero();

	@Override
	public boolean hasNext() {
		if (current == null) {
			return true;
		}
		N nextValue = getNextValue();
		int cmp = nextValue.compareTo(to);
		int overflowCheck = nextValue.compareTo(current);
		return ((cmp < 0 != sign < 0) && (overflowCheck < 0 == sign < 0)) || (closed && cmp == 0);
	}

	@Override
	public N next() {
		if (!hasNext()) {
			throw new NoSuchElementException();
		}
		current = getNextValue();
		return current;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy