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

net.jqwik.engine.properties.arbitraries.DefaultCharacterArbitrary Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
package net.jqwik.engine.properties.arbitraries;

import java.util.*;
import java.util.stream.*;

import net.jqwik.api.*;
import net.jqwik.api.arbitraries.*;

public class DefaultCharacterArbitrary extends TypedCloneable implements CharacterArbitrary {

	static final char[] WHITESPACE_CHARS;

	static {
		// determine WHITESPACE_CHARS at runtime because the environments differ . . .
		final StringBuilder whitespace =
			IntStream.range(Character.MIN_VALUE, Character.MAX_VALUE + 1)
					 .filter(Character::isWhitespace)
					 .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append);

		final int whitespaceLength = whitespace.length();
		final char[] charArray = new char[whitespaceLength];
		whitespace.getChars(0, whitespaceLength, charArray, 0);
		WHITESPACE_CHARS = charArray;
	}

	static final int MAX_ASCII_CODEPOINT = 0x007F;

	static boolean isNoncharacter(int codepoint) {
		if (codepoint >= 0xfdd0 && codepoint <= 0xfdef)
			return true;
		// see https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
		if (codepoint >= 0xd800 && codepoint <= 0xdfff)
			return true;
		return codepoint == 0xfffe || codepoint == 0xffff;
	}

	static boolean isPrivateUseCharacter(int codepoint) {
		return codepoint >= 0xe000 && codepoint <= 0xf8ff;
	}

	private List>> partsWithSize = new ArrayList<>();

	public DefaultCharacterArbitrary() {
	}

	@Override
	public RandomGenerator generator(int genSize) {
		return arbitrary().generator(genSize);
	}

	private Arbitrary arbitrary() {
		if (partsWithSize.isEmpty()) {
			return defaultArbitrary();
		}
		if (partsWithSize.size() == 1) {
			return partsWithSize.get(0).get2();
		}

		return Arbitraries.frequencyOf(partsWithSize);
	}

	private Arbitrary defaultArbitrary() {
		return rangeArbitrary(Character.MIN_VALUE, Character.MAX_VALUE)
				   .filter(c -> !DefaultCharacterArbitrary.isNoncharacter(c)
									&& !DefaultCharacterArbitrary.isPrivateUseCharacter(c));
	}

	@Override
	public Optional> exhaustive(long maxNumberOfSamples) {
		return arbitrary().exhaustive(maxNumberOfSamples);
	}

	@Override
	public EdgeCases edgeCases(int maxEdgeCases) {
		return arbitrary().edgeCases(maxEdgeCases);
	}

	@Override
	public CharacterArbitrary range(char min, char max) {
		return cloneWith(rangeArbitrary(min, max), max - min + 1);
	}

	@Override
	public CharacterArbitrary with(char... allowedChars) {
		return cloneWith(charsArbitrary(allowedChars), allowedChars.length);
	}

	@Override
	public CharacterArbitrary with(CharSequence allowedChars) {
		char[] chars = allowedChars.toString().toCharArray();
		return with(chars);
	}

	private Arbitrary charsArbitrary(char[] allowedChars) {
		return Arbitraries.of(allowedChars);
	}

	@Override
	public CharacterArbitrary all() {
		return new DefaultCharacterArbitrary();
	}

	@Override
	public CharacterArbitrary ascii() {
		return range((char) Character.MIN_CODE_POINT, (char) MAX_ASCII_CODEPOINT);
	}

	@Override
	public CharacterArbitrary numeric() {
		return range('0', '9');
	}

	@Override
	public CharacterArbitrary whitespace() {
		return with(DefaultCharacterArbitrary.WHITESPACE_CHARS);
	}

	@Override
	public CharacterArbitrary alpha() {
		return this.range('A', 'Z').range('a', 'z');
	}

	private CharacterArbitrary cloneWith(Arbitrary part, int size) {
		DefaultCharacterArbitrary clone = super.typedClone();
		clone.partsWithSize = new ArrayList<>(partsWithSize);
		clone.partsWithSize.add(Tuple.of(size, part));
		return clone;
	}

	private Arbitrary rangeArbitrary(char min, char max) {
		return new CharacterRangeArbitrary(min, max);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy