Создал юникод и юникод без генераторов пробелов в ScalaCheck

Во время тестирования мы хотим квалифицировать символы Юникода, иногда с широкими диапазонами, а иногда с более узкими. Я создал несколько конкретных генераторов:

// Generate a wide varying of Unicode strings with all legal characters (21-40 characters):
val latinUnicodeCharacter = Gen.choose('\u0041', '\u01B5').filter(Character.isDefined)

// Generate latin Unicode strings with all legal characters (21-40 characters):
val latinUnicodeGenerator: Gen[String] = Gen.chooseNum(21, 40).flatMap { n =>
    Gen.sequence[String, Char](List.fill(n)(latinUnicodeCharacter))
}

// Generate latin unicode strings without whitespace (21-40 characters): !! COMES UP SHORT...
val latinUnicodeGeneratorNoWhitespace: Gen[String] = Gen.chooseNum(21, 40).flatMap { n =>
    Gen.sequence[String, Char](List.fill(n)(latinUnicodeCharacter)).map(_.replaceAll("[\\p{Z}\\p{C}]", ""))
}

Генератор latinUnicodeCharacter выбирает символы от стандартной латиницы ("A", "B" и т. д.) до латинских символов более высокого порядка (германские/скандинавские и другие). Это хорошо для тестирования ввода символов на основе латиницы, скажем, для имен.

latinUnicodeGenerator создает строки длиной от 21 до 40 символов. Эти строки включают горизонтальный пробел (не только пробел, но и другой «горизонтальный пробел»).

Последний пример, latinUnicodeGeneratorNoWhitespace, используется, скажем, для адресов электронной почты. Нам нужны латинские символы, но не нужны пробелы, управляющие коды и тому подобное. Проблема: поскольку я отображаю окончательный результат String и отфильтровываю управляющие символы, String сжимается, и я получаю общую длину менее 21 символа (иногда).

Итак, вопрос: как я могу реализовать latinUnicodeGeneratorNoWhitespace, но сделать это внутри генератора таким образом, чтобы я всегда получал строки из 21-40 символов?


person Zac    schedule 22.05.2015    source источник


Ответы (1)


Вы можете сделать это, собрав последовательность ваших непробельных символов, другую из пробелов, а затем выбрав либо только непробельные символы, либо оба вместе:

import org.scalacheck.Gen

val myChars = ('A' to 'Z') ++ ('a' to 'z')
val ws = Seq(' ', '\t')

val myCharsGenNoWhitespace: Gen[String] = Gen.chooseNum(21, 40).flatMap { n =>
  Gen.buildableOfN[String, Char](n, Gen.oneOf(myChars))
}

val myCharsGen: Gen[String] = Gen.chooseNum(21, 40).flatMap { n =>
  Gen.buildableOfN[String, Char](n, Gen.oneOf(myChars ++ ws))
}

Однако я бы предложил рассмотреть, что вы на самом деле тестируете: чем больше вы ограничиваете тестовые примеры, тем меньше вы проверяете, как ваша программа будет вести себя при неожиданных входных данных.

person Travis Brown    schedule 22.05.2015
comment
Спасибо, это отличный подход, который я могу расширить. Чтобы ответить на ваш вопрос: мы тестируем обработку адресов электронной почты, и стандарты для электронной почты не требуют пробелов. Так что, по сути, нам нужен Unicode, но без каких-либо символов горизонтального пробела (что было бы запрещено практически любым почтовым сервером). - person Zac; 23.05.2015
comment
@ Зак Рад, что это помогло! Я не слишком удивлюсь, если кто-то уже создал Gen для действительных адресов электронной почты — возможно, стоит осмотреться. - person Travis Brown; 23.05.2015