使用 scalacheck 生成任意(合法)Unicode 字符?

发布于 2024-10-06 04:12:47 字数 1015 浏览 3 评论 0原文

我正在尝试创建一个生成器,使用 scalacheck 1.6.6 和 specs 1.7 (scala 2.8.1) 生成(非零长度)合法的 unicode 字符串。

我希望我可以创建像这样的生成器:

object Generators {
  def unicodeChar: Gen[Char] = 
    choose(Math.MIN_CHAR, Math.MAX_CHAR).map(_.toChar).filter(
      c => Character.isDefined(c))
  def unicodeStr: Gen[String] = for(cs <- listOf1(unicodeChar)) yield cs.mkString
}

...然后从像这样的规范中使用它们:

import org.specs.Specification
import org.specs.matcher.ScalaCheckMatchers

object CoreSpec extends Specification with ScalaCheckMatchers {        
  "The core" should {    
    "pass trivially" in {
      Generators.unicodeStr must pass((s: String) => s == s)
    }
  }
}

但是,似乎在 unicodeChar 中使用过滤器会导致问题:

Specification "CoreSpec"
  The core should
  x pass trivially
    Gave up after only 64 passed tests. 500 tests were discarded.

如果我从 unicodeChar 中删除过滤器,我的测试会通过,但我会遇到其他问题后来,因为我的字符串并不总是定义明确的 unicode。

预先感谢您提供有关如何实现这一目标的任何建议。

I'm trying to create a generator that produces (non-zero-length) legal unicode strings, with scalacheck 1.6.6 and specs 1.7 (scala 2.8.1).

I hoped I could just create generators like:

object Generators {
  def unicodeChar: Gen[Char] = 
    choose(Math.MIN_CHAR, Math.MAX_CHAR).map(_.toChar).filter(
      c => Character.isDefined(c))
  def unicodeStr: Gen[String] = for(cs <- listOf1(unicodeChar)) yield cs.mkString
}

...then use them from specs like:

import org.specs.Specification
import org.specs.matcher.ScalaCheckMatchers

object CoreSpec extends Specification with ScalaCheckMatchers {        
  "The core" should {    
    "pass trivially" in {
      Generators.unicodeStr must pass((s: String) => s == s)
    }
  }
}

But, it seems that using filter in unicodeChar causes a problem:

Specification "CoreSpec"
  The core should
  x pass trivially
    Gave up after only 64 passed tests. 500 tests were discarded.

If I remove the filter from unicodeChar, my test passes, but I run into other problems later, since my strings are not always well-defined unicode.

Thanks in advance for any suggestions on how to achieve this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等待我真够勒 2024-10-13 04:12:47

尝试在创建生成器之前过滤掉字符:

val unicodeChar: Gen[Char] = Gen.oneOf((Math.MIN_CHAR to Math.MAX_CHAR).filter(Character.isDefined(_)))

这会占用更多内存,因为在创建生成器时将分配完整的 unicode 字符列表,但只会使用该列表的一个实例,因此它不应该是一个大问题。

Try filtering out the characters before creating the generator:

val unicodeChar: Gen[Char] = Gen.oneOf((Math.MIN_CHAR to Math.MAX_CHAR).filter(Character.isDefined(_)))

It will be more memory intensive, since the complete list of unicode characters will be allocated when the generator is created, but only one instance of that list will be used so it shouldn't be a big problem.

友谊不毕业 2024-10-13 04:12:47

我不知道 2010 年情况如何,但现在你可以使用 Arbitrary

  import org.scalacheck.Arbitrary
  import org.scalacheck.Gen

  val unicodeChar: Gen[Char] = Arbitrary.arbChar.arbitrary
  val unicodeString: Gen[String] = Arbitrary.arbString.arbitrary

I don't know how it was in 2010, but nowadays you can use Arbitrary:

  import org.scalacheck.Arbitrary
  import org.scalacheck.Gen

  val unicodeChar: Gen[Char] = Arbitrary.arbChar.arbitrary
  val unicodeString: Gen[String] = Arbitrary.arbString.arbitrary
逆光飞翔i 2024-10-13 04:12:47

好吧,我明白了。这对我有用:

def unicodeChar = Gen((p: Gen.Params) => {
    var c = 0
    do {
      c = util.Random.nextInt(0xFFFF)
    } while (!Character.isDefined(c))
    Some(c.toChar)
  })

实际上很简单。我不明白的是,您可以通过传递函数 Gen.Params => 来创建 T 类型的任意生成器T 到 Gen.apply()。

Ok, I figured it out. This is what works for me:

def unicodeChar = Gen((p: Gen.Params) => {
    var c = 0
    do {
      c = util.Random.nextInt(0xFFFF)
    } while (!Character.isDefined(c))
    Some(c.toChar)
  })

Pretty simple, actually. What I didn't get is that you can create an arbitrary generator of type T by passing a function Gen.Params => T to Gen.apply().

2024-10-13 04:12:47

您是否尝试过使用 suchThat 而不是 filter

Have you tried suchThat instead of filter?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文