JGiven icon indicating copy to clipboard operation
JGiven copied to clipboard

provide VarArgFormatter

Open jangalinski opened this issue 6 years ago • 9 comments

When using given().something_with_varargs_params_$("foo","bar") I want to have nice formatting of the vararg params, currently its something like "something with varargs params String@12345"

jangalinski avatar Jun 21 '18 19:06 jangalinski

You can use the @Table annotation to format Arrays and varargs. See http://jgiven.org/userguide/#_tables_as_parameters

janschaefer avatar Jun 22 '18 18:06 janschaefer

Sure, @Table is nice, but a table breaks the page flow of the test description. For short lists, a comma-separated list is adequate too.

zambrovski avatar Jun 25 '18 08:06 zambrovski

Ok, I understand and I agree. But then this would be just an alternative implementation to format any lists, right? So maybe it should not only format varargs, but also any kind of Iterables. It should then also be named differently, IMHO.

janschaefer avatar Jul 06 '18 16:07 janschaefer

What about @CommaSeparated? Maybe even with an attribute that defines the separator? @CommaSeparated( sep = ';');

janschaefer avatar Jul 06 '18 17:07 janschaefer

I just tried to reproduce this issue and JGiven already formats varargs parameters as a comma-separated list. See linked commit.

janschaefer avatar Jul 28 '18 09:07 janschaefer

I see. This seems to be because of Kotlin we are using where a varags seems to be treated as an array. My y proposed formatter was actually an array formatter. By the way, I still owe you a Kotlin example...

zambrovski avatar Jul 28 '18 09:07 zambrovski

I see. Still even Java arrays are formatted as a comma-separated list. Is Kotlin using some other array type as Java? A Kotlin example would help me tracking down the issue :-)

janschaefer avatar Jul 28 '18 09:07 janschaefer

Did you test your PR with Kotlin? Because your code uses instanceof Object[]. I assume that this will not work for the Kotlin Array type.

janschaefer avatar Jul 28 '18 09:07 janschaefer

My actual implementation in Kotlin was:

import com.tngtech.jgiven.annotation.Format
import com.tngtech.jgiven.format.ArgumentFormatter
import com.tngtech.jgiven.format.PrintfFormatter

/**
 * Argument formatter dealing with varargs and displaying them as a comma-separated list of quoted strings.
 * Delegates on the Printf-Formatter for actual formatting.
 */
open class VarargsFormatter : ArgumentFormatter<Any> {

  private val printfFormatter = PrintfFormatter()

  override fun format(argumentToFormat: Any?, vararg formatterArguments: String?): String = if (argumentToFormat is Array<*>) {
    argumentToFormat.joinToString(", ") { printfFormatter.format(it, *formatterArguments) }
  } else {
    printfFormatter.format(argumentToFormat, *formatterArguments)
  }
}

/**
 * Annotation using the Vargarg Argument formatter.
 */
@MustBeDocumented
@Format(value = VarargsFormatter::class, args = ["\"%s\""])
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FIELD)
annotation class QuotedVarargs

zambrovski avatar Jul 30 '18 21:07 zambrovski