Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
RELEASE_TYPE: minor

Change the `Generators.uuids()` return type from `String` to `java.util.UUID`, and expose version configuration as a `uuids().version(v)` method.
12 changes: 8 additions & 4 deletions src/main/java/dev/hegel/Generators.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -463,8 +464,9 @@ public static <T> Deferred<T> deferred() {
* Derive a generator for {@code type} by reflection.
*
* <p>Supports scalar types ({@code int}, {@code long}, {@code boolean}, {@code float}, {@code
* double}, {@code String}, {@code byte[]} and their wrappers), enums, records (recursively), and
* {@code List}, {@code Set}, {@code Optional} and {@code Map} of supported element types.
* double}, {@code String}, {@code byte[]}, {@link UUID}, and their wrappers), enums, records
* (recursively), and {@code List}, {@code Set}, {@code Optional} and {@code Map} of supported
* element types.
*
* @param type the type to derive a generator for
* @param <T> the type
Expand Down Expand Up @@ -519,9 +521,11 @@ public static IpAddressGenerator ipAddresses() {
}

/**
* @return a generator of UUID strings
* Generates {@link UUID} values; see {@link UuidGenerator} for configuration capabilities.
*
* @return a UUID generator
*/
public static Generator<String> uuids() {
public static UuidGenerator uuids() {
return new UuidGenerator();
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/dev/hegel/generators/Derive.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ private static Generator<?> scalar(Class<?> cls) {
if (cls == String.class) {
return Generators.text();
}
if (cls == java.util.UUID.class) {
return Generators.uuids();
}
if (cls == byte[].class) {
return Generators.binary();
}
Expand Down
41 changes: 37 additions & 4 deletions src/main/java/dev/hegel/generators/UuidGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,47 @@
import com.upokecenter.cbor.CBORObject;
import dev.hegel.Cbor;
import dev.hegel.Generator;
import java.util.UUID;

/**
* Generates UUID strings. Always basic (one engine call).
* Generates {@link UUID} values. Always basic (one engine call).
*
* <p>By default generates UUIDs of any version; use {@link #version(int)} to restrict to a
* specific RFC 4122 version (1–5).
*/
public final class UuidGenerator implements Generator<String> {
public final class UuidGenerator implements Generator<UUID> {
private final Integer version;

public UuidGenerator() {
this((Integer) null);
}

private UuidGenerator(Integer version) {
this.version = validateVersion(version);
}

/**
* @param version the UUID version to generate; must be an RFC 4122 version in {@code [1, 5]}
* @return a copy pinned to the requested version
*/
public UuidGenerator version(int version) {
return new UuidGenerator(version);
}

private static Integer validateVersion(Integer version) {
if (version != null && (version < 1 || version > 5)) {
throw new IllegalArgumentException("uuids: version must be in [1, 5]");
}
return version;
}

/** @hidden */
@Override
public BasicGenerator<String> asBasic() {
return new BasicGenerator<>(CBORObject.NewMap().Add("type", "uuid"), Cbor::asString);
public BasicGenerator<UUID> asBasic() {
CBORObject schema = CBORObject.NewMap().Add("type", "uuid");
if (version != null) {
schema.Add("version", version);
}
return new BasicGenerator<>(schema, raw -> UUID.fromString(Cbor.asString(raw)));
}
}
3 changes: 2 additions & 1 deletion src/test/java/dev/hegel/ConformanceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Objects;
import org.junit.jupiter.api.Test;

/** Behaviour/conformance suite exercising every generator against the real engine. */
Expand Down Expand Up @@ -192,7 +193,7 @@ void formatGenerators() {
ipAddresses().v4(), s -> s.chars().filter(c -> c == '.').count() == 3);
assertAllExamples(ipAddresses().v6(), s -> s.contains(":"));
assertAllExamples(ipAddresses(), s -> s.contains(".") || s.contains(":"));
assertAllExamples(uuids(), s -> s.contains("-"));
assertAllExamples(uuids(), Objects::nonNull);
assertAllExamples(fromRegex("[0-9]{3}"), s -> s.matches(".*[0-9]{3}.*"));
}

Expand Down
7 changes: 7 additions & 0 deletions src/test/java/dev/hegel/DerivationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
import dev.hegel.generators.Derive;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import org.junit.jupiter.api.Test;

class DerivationTest {
Expand Down Expand Up @@ -96,6 +98,11 @@ void derivesWrapperScalarsAndBytes() {
w -> w.l() != null && w.b() != null && w.d() != null && w.data() != null && w.i() != null);
}

@Test
void derivesUuidScalars() {
assertAllExamples(forType(UUID.class), Objects::nonNull);
}

record Temporal(
java.time.Duration d,
java.time.LocalDate date,
Expand Down
37 changes: 37 additions & 0 deletions src/test/java/dev/hegel/UuidGeneratorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dev.hegel;

import static dev.hegel.Generators.uuids;
import static dev.hegel.Utils.assertAllExamples;
import static dev.hegel.Utils.findAny;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class UuidGeneratorTest {
@Test
void defaultGeneratesValidUuids() {
assertAllExamples(uuids(), u -> UUID.fromString(u.toString()).equals(u));
}

/** By default the version is unconstrained, so the engine emits non-RFC versions too. */
@Test
void defaultIsNotPinnedToAnRfcVersion() {
findAny(uuids(), u -> u.version() < 1 || u.version() > 5);
}

@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5})
void configuredUuidVersionsAreRespected(int version) {
assertAllExamples(
uuids().version(version), u -> UUID.fromString(u.toString()).equals(u) && u.version() == version);
}

@ParameterizedTest
@ValueSource(ints = {0, 6, 7, 8, 9})
void invalidVersionsAreRejected(int version) {
assertThrows(IllegalArgumentException.class, () -> uuids().version(version));
}
}
Loading