Question

I'm trying to write the following spec using Specs2 but can't seem to get it to work, the compiler always complains about "no implicit view available from Unit => org.specs2.execute.Result".

Here's the test source:

    "generate the correct output when merging an extraction" in {
        val source = new File("src/test/resources/sample-docs/text-and-image-on-page-2.pdf")
        val output = this.extractor.extract(source)
        val pdfGenerator = new ITextPdfGenerator()
        val processor = new ExecutableProcessor()

        val ocrInput = IOUtils.createTempFile("ocr_input", "pdf")
        val ocrOutput = IOUtils.createTempFile("ocr_output", "pdf")

        deleteWhenDone[MatchResult[Any]](output.getFullTextFile, ocrInput, ocrOutput) ( {

            pdfGenerator.generatePdf(source, ocrInput, output.getPagesWithImages)
            processor.process(ocrInput, ocrOutput)

            this.extractor.mergeExtraction(output, ocrOutput)

            IOUtils.readFile(output.getFullTextFile) === """sample text on line 1 page 1 sample text on line 2 page 1 sample text on line 1 page 3 sample text on line 2 page 3 """

        })

    }

And the delete when done function is as follows:

def deleteWhenDone[T]( files : File* ) ( fn : => T ) {
    try {
        fn
    } finally {
        IOUtils.deleteFiles( files )
    }
}

If this line is at the end of the spec, it does work:

IOUtils.readFile(output.getFullTextFile) === "sample text on line 1 page 1 sample text on line 2 page 1 sample text on line 1 page 3 sample text on line 2 page 3 "

Why would it fail like this and what can I do to still use the closure and get the test to compile?

EDIT

Changed the deleteWhenDone call to this:

deleteWhenDone[Result](output.getFullTextFile, ocrInput, ocrOutput) ( {

  pdfGenerator.generatePdf(source, ocrInput, output.getPagesWithImages)
  processor.process(ocrInput, ocrOutput)

  this.extractor.mergeExtraction(output, ocrOutput)

  IOUtils.readFile(output.getFullTextFile) === "sample text on line 1 page 1 sample text on line 2 page 1 sample text on line 1 page 3 sample text on line 2 page 3 "

})

But still doesn't work.

EDIT 2

Thanks to Rafael's answer, the final code that made it work was:

def deleteWhenDone[T]( files : File* ) ( fn : => T ) : T = {
    try {
        fn
    } finally {
        IOUtils.deleteFiles( files )
    }
}

I missed the method return type. Thanks!

Was it helpful?

Solution

The deleteWhenDone function has Unit for its result type, which isn't compatible with the expcted type of the in parameter. You can change it to return T by adding an equals sign to the definition:

def deleteWhenDone[T]( files : File* ) ( fn : => T ) = {
    try {
        fn
    } finally {
        IOUtils.deleteFiles( files )
    }
}

OTHER TIPS

The in method is defined as follows:

def in[T <% Result](r: => T): Example

So it expects as parameter a code block whose return type is derived from Result or can be implicitly converted to Result. If you write Success() at the end of your test, it will compile.

You can also do something like that:

implicit def anyToSuccess[T](a: T): org.specs2.execute.Result = success 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top