Search code examples
scalascalatestscalacheckproperty-based-testing

Circular Generators hanging indefinately


I have a set of names in a file. I need to implement a Generator that iterates through them continually. However, the code is hanging indefinitely at if (iter.hasNext) after the first pass.

Gen code

var asStream = getClass.getResourceAsStream("/firstnames/female/en_US_sample.txt")

var source: BufferedSource = Source.fromInputStream(asStream)
var iter: Iterator[String] = Iterator.continually(source.getLines()).flatten

val genLastName: Gen[String] = {
  genCannedData
}

def genCannedData: Gen[String] = {
    println("Generating names: " + iter)
    Gen.delay {
      if (iter.hasNext) {
        println("In if")
        Gen.const(iter.next)
      }
      else {
        println("In else")
        Gen.const(iter.next)
      }
    }
}

Sample Property test

property("FirstNames") = {
    forAll(genLastName) {
      a => {
        println(a)
        a == a
      }
    }
  }

en_US_sample.txt file contents

Abbie
Abby
Abigail
Ada
Adah

EDIT- Temporary working code

The following code works if I recreate the iterator but I was wondering why Iterator.continually is hanging?

def genCannedData: Gen[String] = {
    Gen.delay {
      if (iter.hasNext) {
        Gen.const(iter.next)
      }
      else {
        asStream = getClass.getResourceAsStream("/firstnames/female/en_US_sample.txt")
        source = Source.fromInputStream(asStream)
        iter = source.getLines()
        Gen.const(iter.next)
      }
    }
  }

Solution

  • After first iteration, an iterator returned by source.getLines() returns false for hasNext, which means an empty iterator. Iterator.continually() continually evaluate source.getLines() expecting a next iterator, but it continues to return an empty iterator. Then it forms an infinite loop.