4

私は、scalacheck1.6.6とspecs1.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でfilterを使用すると、問題が発生するようです。

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

unicodeCharからフィルターを削除すると、テストは成功しますが、文字列が常に明確に定義されたユニコードであるとは限らないため、後で他の問題が発生します。

これを達成する方法についての提案を事前に感謝します。

4

4 に答える 4

9

ジェネレータを作成する前に、文字を除外してみてください。

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

ジェネレータの作成時にUnicode文字の完全なリストが割り当てられるため、メモリを大量に消費しますが、そのリストの1つのインスタンスのみが使用されるため、大きな問題にはなりません。

于 2010-12-07T17:56:14.800 に答える
5

2010年の様子はわかりませんが、最近は次のように使用できますArbitrary

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

  val unicodeChar: Gen[Char] = Arbitrary.arbChar.arbitrary
  val unicodeString: Gen[String] = Arbitrary.arbString.arbitrary
于 2016-02-23T12:56:28.260 に答える
3

わかりました、わかりました。これは私のために働くものです:

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をGen.apply()に渡すことで、タイプTの任意のジェネレーターを作成できることです。

于 2010-12-07T17:52:15.737 に答える
0

suchThat代わりに試しましたfilterか?

于 2010-12-07T18:42:35.283 に答える