Как передать параметры в @Provide?

Есть ли способ передать параметры в @Provide? Я хочу что-то эквивалентное следующему:

      @Property
void test(@ForAll("charSequence", 2, 5) CharSequence cs) {
    // test property on cs, which is an arbitrary CharSequence of length minimum 2 and maximum length 5
}

@Provide
Arbitrary<CharSequence> charSequence(int minLength, int maxLength) {
    Arbitrary<String> stringArbitrary = Arbitraries.strings().ofMinLength(minLength).ofMaxLength(maxLength);
    Arbitrary<StringBuffer> stringBufferArbitrary = stringArbitrary.map
        (str -> null == str ? null : new StringBuffer(str));
    Arbitrary<StringBuilder> stringBuilderArbitrary = stringArbitrary.map
        (str -> null == str ? null : new StringBuilder(str));
    return Arbitraries.oneOf(stringArbitrary, stringBufferArbitrary, stringBuilderArbitrary);
}

Я пробовал создать собственную аннотацию

      public @interface Length {
    int min();
    int max();
}

и используя его как void test(@ForAll("charSequence") @Length(min = 2, max = 5) CharSequence cs)как предложено в методах поставщика с параметрами , но TypeUsage не воспринимает пользовательскую аннотацию, @Length. (Только @ForAll выбрано.)

1 ответ

В настоящее время в jqwik нет механизма для прямой передачи параметров методам провайдера. Однако механизм аннотации должен работать так, как вы предложили:

      @Property
void test(@ForAll("charSequence") @Length(min = 2, max = 5)  CharSequence cs) {
    System.out.println(cs);
}

@Provide
Arbitrary<CharSequence> charSequence(TypeUsage typeUsage) {
    Optional<Length> optionalLength = typeUsage.findAnnotation(Length.class);
    int minLength = optionalLength.map(l -> l.min()).orElse(1);
    int maxLength = optionalLength.map(l -> l.max()).orElse(255);

    Arbitrary<String> stringArbitrary = Arbitraries.strings().ofMinLength(minLength).ofMaxLength(maxLength);
    Arbitrary<StringBuffer> stringBufferArbitrary =
        stringArbitrary.map(str -> null == str ? null : new StringBuffer(str));
    Arbitrary<StringBuilder> stringBuilderArbitrary =
        stringArbitrary.map(str -> null == str ? null : new StringBuilder(str));

    return Arbitraries.oneOf(
            stringArbitrary, 
            stringBufferArbitrary, 
            stringBuilderArbitrary
    );
}

Я думаю, вы забыли включить сохранение времени выполнения для @Length, иначе аннотация просто будет удалена компилятором:

      @Target({ ElementType.ANNOTATION_TYPE, ElementType.PARAMETER, ElementType.TYPE_USE })
@Retention(RetentionPolicy.RUNTIME)
@interface Length {
    int min();
    int max();
}

Приведенный выше код должен генерировать вывод, аналогичный (последовательности длиной от 2 до 5):

      ꭀ訂
쯈쓁緈ﵬ
堰⾞ᒽ뒡ՙ
ᒽ뒡
쳨任๔蔢
涼嵒퓗
⫈ࣦ᩿쯧佺
佺㺻
䲠燷怟藤
...
Другие вопросы по тегам