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

java.lang.RuntimeException: Unable to resolve #{male_first_name} directive for FakerContext #1178

Open
bodiam opened this issue Apr 28, 2024 · 12 comments

Comments

@bodiam
Copy link
Contributor

bodiam commented Apr 28, 2024

Describe the bug

Running the following code shows the issue:

public class ExpressionBugTest {

    @Test
    void testExpressionEnglishFails() {
        Faker faker = new Faker(Locale.ENGLISH);
        String expression = faker.expression("#{name.first_name}");
        System.out.println(expression);
    }

    @Test
    void testExpressionFails() {
        Faker faker = new Faker();
        String expression = faker.expression("#{name.first_name}");
        System.out.println(expression);
    }

    @Test
    void testExpressionUsFails() {
        Faker faker = new Faker(new Locale("en", "US"));
        String expression = faker.expression("#{name.first_name}");
        System.out.println(expression);
    }

    @Test
    void testExpressionAUWorks() {
        Faker faker = new Faker(new Locale("en", "AU"));
        String expression = faker.expression("#{name.first_name}");
        System.out.println(expression);
    }

    @Test
    void testExpressionNLWorks() {
        Faker faker = new Faker(new Locale("nl", "nl"));
        String expression = faker.expression("#{name.first_name}");
        System.out.println(expression);
    }
}

Running this gives the following error:

java.lang.RuntimeException: Unable to resolve #{male_first_name} directive for FakerContext FakerContext{, locale=SingletonLocale{locale=en}, randomService=net.datafaker.service.RandomService@1}.

	at net.datafaker.service.FakeValuesService.resolveExpression(FakeValuesService.java:578)
	at net.datafaker.service.FakeValuesService.resolveExpression(FakeValuesService.java:580)
	at net.datafaker.service.FakeValuesService.expression(FakeValuesService.java:453)
	at net.datafaker.providers.base.BaseFaker.expression(BaseFaker.java:434)
	at net.datafaker.ExpressionBugTest.x(ExpressionBugTest.java:12)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:194)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)

To Reproduce
See above

Expected behavior
Generate a name

Versions:

  • Faker Version 2.2.2

Additional context
Add any other context about the problem here.

@kingthorin
Copy link
Collaborator

2.2.2 snapshot?

@kingthorin
Copy link
Collaborator

Are you working on a fix or hoping someone will pick this up?

@bodiam
Copy link
Contributor Author

bodiam commented Apr 28, 2024

No, not 2.2.2-snapshot, 2.2.2-non-snapshot. It probably affects other versions too.

And no, I'm not working on a fix at the moment. I had a look to see if I could find the issue, but so far I was a bit lost what's causing this. And yes, I would appreciate if a keen person for who it's not Sunday 9pm could have a look at this :-)

@kingthorin
Copy link
Collaborator

Sorry, apparently I lost track of releases this week 😀

I'll try to have a look this week.

@bodiam
Copy link
Contributor Author

bodiam commented Apr 28, 2024

Sorry, apparently I lost track of releases this week 😀

Well, that's excusable: I did 3 releases in 3 days ;-). I'll also try to have a look when I'm a bit more fresh, thanks!

@kingthorin
Copy link
Collaborator

kingthorin commented Apr 28, 2024

It has something to do with chained or nested expressions. In en-AU name.first_name is a litteral list. In en-US (or well default) name.first_name is:

      first_name:
      - "#{female_first_name}"
      - "#{male_first_name}"

If changed to:

      first_name:
      - "#{name.female_first_name}"
      - "#{name.male_first_name}"

The tests pass. I'll have to keep testing/playing but I thought I should mention it in-case one of you sees the fix quicker knowing the code better than me 👍

Conversely the following test fails (seemingly for the same reason as the other English/default tests):

    @Test
    void testExpressionNLWithMiddleWorks() {
        Faker faker = new Faker(new Locale("nl", "nl"));
        String expression = faker.expression("#{name.name_with_middle}");
        System.out.println(expression);
    }

@kingthorin
Copy link
Collaborator

The issue seems to be "current" being passed as null:

return resolveExpression(expression, null, faker, context);

The following makes the tests pass (obviously not a fix, but a PoC):

diff --git a/src/main/java/net/datafaker/service/FakeValuesService.java b/src/main/java/net/datafaker/service/FakeValuesService.java
index daafc8dd..dd026bd3 100644
--- a/src/main/java/net/datafaker/service/FakeValuesService.java
+++ b/src/main/java/net/datafaker/service/FakeValuesService.java
@@ -1,5 +1,6 @@
 package net.datafaker.service;

+import net.datafaker.Faker;
 import net.datafaker.internal.helper.COWMap;
 import net.datafaker.internal.helper.SingletonLocale;
 import net.datafaker.providers.base.AbstractProvider;
@@ -547,6 +548,9 @@ protected String resolveExpression(String expression, Object current, ProviderRe
         if (!expression.contains("}")) {
             return expression;
         }
+        if (current == null) {
+            current = new BaseFaker().name();
+        }
         final int expressionLength = expression.length();
         final String[] expressions = splitExpressions(expression, expressionLength);
         final StringBuilder result = new StringBuilder(expressions.length * expressionLength);

@snuyanzin
Copy link
Collaborator

yep, the issue is with current object however not only name could be here

for instance for this test

Faker faker = new Faker(new Locale("nl", "nl"));
faker.expression("#{address.full_address}");

the PoC code will fail

@kingthorin
Copy link
Collaborator

Yeah that's why I said it wasn't a fix, just a poc

@snuyanzin
Copy link
Collaborator

#1180
here i submitted a poc, however there is still one test which need to think how to handle it

@bodiam
Copy link
Contributor Author

bodiam commented May 1, 2024

@snuyanzin I've done some more tests, but things like this also don't work, no matter the Locale:

        String expression = faker.expression("#{address.city}");

@snuyanzin
Copy link
Collaborator

I added this test as well to the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants