2010-12-07 6 views
2

Ich versuche, einen Generator zu erstellen, der (Unicode-Strings ungleich Null Länge erzeugt) mit Scalacheck 1.6.6 und Spezifikationen 1.7 (Scala 2.8.1) erstellt.Generieren Sie beliebiges (legales) Unicode-Zeichen mit Scalacheck?

Ich hatte gehofft, ich könnte einfach Generatoren schaffen wie:

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 
} 

... sie dann von Spezifikationen wie verwenden:

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) 
    } 
    } 
} 

Aber es scheint, dass in unicodeChar ein Problem Filter bewirkt:

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

Wenn ich den Filter aus unicodeChar entfernen, mein Test bestanden, aber ich laufe in ein anderes Problem s später, da meine Strings nicht immer eindeutig Unicode sind.

Vielen Dank im Voraus für Vorschläge, wie dies zu erreichen ist.

+0

Es scheint ein wenig einfacher, wenn ich nicht Specs verwenden und eine neue implizite Params Instanz bereitzustellen. Aber das behebt nur das Symptom, es löst nicht wirklich die zugrunde liegende Ursache. –

Antwort

7

Versuchen Sie, die Zeichen Ausfiltern vor dem Generator zu schaffen:

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

wird es speicherintensiv sein, da wird die komplette Liste der Unicode-Zeichen zugeordnet werden, wenn der Generator erzeugt wird, sondern nur eine Instanz, dass Liste wird verwendet, so sollte es kein großes Problem sein.

+0

Ah, das macht Sinn. Vielen Dank! –

+2

Hier ist eine Alternative: val unicodeChar = Gen.choose (Char.MinValue, Char.MaxValue) .filter (Character.isDefined) –

2

Ok, ich habe es herausgefunden. Das funktioniert bei mir:

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

Ziemlich einfach, eigentlich. Was ich nicht bekommen habe ist, dass Sie einen beliebigen Generator vom Typ T erzeugen können, indem Sie Gen.Params => T an Gen.apply() übergeben.

0

Haben Sie versucht suchThat anstelle von filter?

+0

Ich habe das nach dem Lesen ein bisschen weiter versucht; Es hat das gleiche Symptom. –

+1

In der Tat ist dies nur ein Wrapper auf Filter: def so That (p: T => Boolean): Gen [T] = Filter (p) –

1

Ich weiß nicht, wie es im Jahr 2010 war, aber heutzutage kann man Arbitrary verwenden:

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

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