Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for locale hash #14

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ new WireMockServer(wireMockConfig().extensions(RandomExtension.class));

This will generate random first names in the `en-US` locale for every request.

You can optionally add:
* the `seed` parameter to always generate the same value for the same seed
* the `locale` parameter to generate values in a specific locale

{% raw %}
```handle

{% raw %}
```handlebars
{{ random 'Name.first_name' seed=1234 locale='es' }}
```
%}

### Technical notes
This library brings `net.datafaker:datafaker` as transitive dependency, which may result in conflicts at building time.
Expand Down
33 changes: 31 additions & 2 deletions src/main/java/org/wiremock/RandomHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,59 @@

import com.github.jknack.handlebars.Options;
import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.HandlebarsHelper;
import java.util.Random;
import net.datafaker.Faker;
import org.apache.commons.lang3.LocaleUtils;

/*
* Author: Shreya Agarwal
*/
public class RandomHelper extends HandlebarsHelper<Object> {

private static final String SEED_HASH = "seed";
private static final String LOCALE_HASH = "locale";

private final Random random;
private final Faker faker;

public RandomHelper() {
faker = new Faker();
this(new Random());
}

RandomHelper(Random random) {
this.random = random;
this.faker = new Faker(random);
}

@Override
public Object apply(Object context, Options options) {

// Use a seeded/localized/default Faker if `locale` or `seed` hash exist
final Faker myFaker = this.getFaker(options.hash(SEED_HASH), options.hash(LOCALE_HASH));

try {
// Used the `expression` method instead of `resolve` as the
// resolve method is not able to resolve nested references in the yml files. For example, in
// the resource file for en-US, `address.full_address` wasn't resolving because of the
// `#{street_address}` nested reference, but `address.postcode_by_state.AL` would work fine.
// `expression` is able to handle all cases.
return faker.expression("#{" + context + "}");
return myFaker.expression("#{" + context + "}");
} catch (RuntimeException e) {
return handleError("Unable to evaluate the expression " + context, e);
}
}

private Faker getFaker(Object seed, String locale) {
final Faker myFaker;
if (seed != null && locale != null) {
myFaker = new Faker(LocaleUtils.toLocale(locale), new Random(seed.hashCode()));
} else if (seed != null) {
myFaker = new Faker(new Random(seed.hashCode()));
} else if (locale != null) {
myFaker = new Faker(LocaleUtils.toLocale(locale), this.random);
} else {
myFaker = this.faker;
}
return myFaker;
}
}
41 changes: 32 additions & 9 deletions src/test/java/org/wiremock/RandomHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@

import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.HandlebarsHelperTestBase;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Random;
import net.datafaker.Faker;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand All @@ -18,7 +17,7 @@ public class RandomHelperTest extends HandlebarsHelperTestBase {

@BeforeEach
public void init() {
helper = new RandomHelper();
helper = new RandomHelper(new Random(123456789L));
}

@Test
Expand All @@ -31,13 +30,37 @@ public void rendersAMeaningfulErrorWhenExpressionIsInvalid() throws IOException
}

@ParameterizedTest
@CsvSource(value = {"123456789, Name.firstName, Herb", "123456789, Name.lastName, Hauck"})
public void returnsRandomValue(int seed, String expression, String expected) throws Exception {
Field newFaker = helper.getClass().getDeclaredField("faker");
newFaker.setAccessible(true);
newFaker.set(helper, new Faker(new Random(seed)));

@CsvSource(
value = {
"Name.firstName, Herb",
"Name.lastName, Hauck",
})
public void returnsRandomValue(String expression, String expected) throws Exception {
String actual = renderHelperValue(helper, expression);
assertThat(actual, is(expected));
}

@ParameterizedTest
@CsvSource(
value = {
", , Herb",
", es, José María",
", fr_QC, Clément",
"1, , Donny",
"hello, , Nickie",
"test, de, Franz"
})
public void rendersSeededLocalizedRandomValue(Object seed, Object locale, String expected) {
final var map = new HashMap<String, Object>();
if (seed != null) {
map.put("seed", seed);
}
if (locale != null) {
map.put("locale", locale);
}

final var actual = helper.apply("Name.firstName", createOptions(map));

assertThat(actual, is(expected));
}
}