scalatestingclosuresspecs2

Trying to write a test with a closure in the end fails on Specs2


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!


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