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
100 changes: 100 additions & 0 deletions src/test/java/net/datafaker/providers/base/CustomFakerTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.datafaker.providers.base;

import net.datafaker.annotations.Deterministic;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -155,4 +156,103 @@ void weightedInsectNameTest() {
assertThat(insectCounts.get("Driver ant")).as(() -> "Insects: " + insectCounts).isGreaterThan(insectCounts.get("Fire ant"));
assertThat(insectCounts.get("Fire ant")).as(() -> "Insects: " + insectCounts).isGreaterThan(insectCounts.get("Harvester ant"));
}

public static final class HolderA {
public static final class WidgetCustomTestFaker extends AbstractProvider<BaseProviders> {
public WidgetCustomTestFaker(BaseProviders faker) {
super(faker);
}

@Deterministic
public String value() {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edge case for different fakers with same methods

return "A-widget";
}
}
}

public static final class HolderB {
public static final class WidgetCustomTestFaker extends AbstractProvider<BaseProviders> {
public WidgetCustomTestFaker(BaseProviders faker) {
super(faker);
}

@Deterministic
public String value() {
return "B-widget";
}
}
}

public static final class FakerA extends BaseFaker {
public FakerA() {
super(Locale.ENGLISH);
}

public HolderA.WidgetCustomTestFaker widget() {
return getProvider(HolderA.WidgetCustomTestFaker.class, HolderA.WidgetCustomTestFaker::new);
}
}

public static final class FakerB extends BaseFaker {
public FakerB() {
super(Locale.ENGLISH);
}

public HolderB.WidgetCustomTestFaker widget() {
return getProvider(HolderB.WidgetCustomTestFaker.class, HolderB.WidgetCustomTestFaker::new);
}
}

public static final class HolderG {
public static final class GizmoCustomTestFaker extends AbstractProvider<BaseProviders> {
public GizmoCustomTestFaker(BaseProviders faker) {
super(faker);
}

@Deterministic
public String value() {
return "G-value";
}
}
}

public static final class FakerG extends BaseFaker {
public FakerG() {
super(Locale.ENGLISH);
}

public HolderG.GizmoCustomTestFaker gizmo() {
return getProvider(HolderG.GizmoCustomTestFaker.class, HolderG.GizmoCustomTestFaker::new);
}
}

@Test
void recipeMustNotLeakAcrossRootsWithSameSimpleProviderName() {
// Need for multiple iteration because of possible cache issues
for (int i = 0; i < 100; i++) {
FakerA a = new FakerA();
FakerB b = new FakerB();

// Sanity: each faker resolves its own provider correctly in isolation.
assertThat(a.expression("#{Widget.value}")).isEqualTo("A-widget"); // populates static recipe

// HolderA.Widget#value against a HolderB.Widget instance.
assertThat(b.expression("#{Widget.value}")).isEqualTo("B-widget");
}
}

@Test
void recipeMustNotNpeWhenOtherRootLacksTheProvider() {
// Need for multiple iteration because of possible cache issues
for (int i = 0; i < 100; i++) {
FakerG withGizmo = new FakerG();
BaseFaker plain = new BaseFaker(Locale.ENGLISH);

assertThat(withGizmo.expression("#{Gizmo.value}")).isEqualTo("G-value"); // populates static recipe

assertThatThrownBy(() -> plain.expression("#{Gizmo.value}"))
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("Unable to resolve");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public class ProvidersDocsGenerator {
private final Set<Class<?>> subTypes = new TreeSet<>(providersComparatorBySimpleName);

// Exclude non-providers from generation
private static final Set<String> providersToExcludeFromGeneration = Set.of("CustomFakerTest", "InsectFromFile", "Insect");
private static final Set<String> providersToExcludeFromGeneration =
Set.of("CustomFakerTest", "InsectFromFile", "Insect", "GizmoCustomTestFaker", "WidgetCustomTestFaker");

private final Set<String> fakersWithoutSinceTag = new HashSet<>();

Expand Down Expand Up @@ -74,7 +75,7 @@ void generateProvidersDocs(BufferedWriter writer) throws IOException {
System.out.println("Providers without '@since' tag: " + fakersWithoutSinceTag);
}

private String extractGroupName(Class<?> clazz) {
private static String extractGroupName(Class<?> clazz) {
// `packageName` should be such format: net.datafaker.providers.<groupName> (e.g. base, sport, movie)
String packageName = clazz.getPackage().getName();
// And just splitting by '.' we're getting groupName (e.g. base, sport, movie)
Expand Down Expand Up @@ -143,7 +144,7 @@ private String providersPerVersionTable() {
Map<String, Integer> providersPerVersion = extractProvidersPerVersion();

StringBuilder sb = new StringBuilder()
.append("\nNumber of providers per Datafaker version\n")
.append("\nNumber of providers per Datafaker version:\n")
.append("\n| Version | Number of new providers | Total number of providers |")
.append("\n|---------|-------------------------|---------------------------|\n");

Expand Down Expand Up @@ -180,7 +181,7 @@ private Map<String, Integer> extractProvidersPerVersion() {
return providersPerVersion;
}

private String formatGroupName(String groupName) {
private static String formatGroupName(String groupName) {
return Character.toUpperCase(groupName.charAt(0)) + groupName.substring(1);
}

Expand Down
Loading