|
View:
New views
10 Messages
—
Rating Filter:
Alert me
|
|
|
Strange behavior....
by Arnaud Bailly
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Hello,
I have the following class: class XmlDiffOracle(e: Option[File], a: Option[File]) extends FileDiffOracle(e,a) { var explainFailure : List[Difference] = Nil var explainError : String = "" override def compareFiles(exp : File, act: File) : TestOutcome = { val diff = new DetailedDiff(new org.custommonkey.xmlunit.Diff(new InputSource(new FileInputStream(exp)), new InputSource(new FileInputStream(act)))) if(diff.identical) TestSuccessful else { explainFailure = new BufferWrapper[Difference]{ def underlying = diff.getAllDifferences }.toList println(explainFailure) TestFailure } } } and the following test case : def testFailedXmlOracleStoresDifferenceList = { val oracle = new XmlDiffOracle(Some(xexpected),Some(xactual)) // should compare the found diffrences assertEquals("expected failure", TestFailure, oracle.outcome) println(oracle) assertEquals(4,oracle.explainFailure.length) } This test fails (ie. oracle.explainFailure.length is 0). However, the println(x) in the class displays the rigght content, whereas the second one displays an empty list. Is there something I missed about var x ... behavior or java wrapping ? Regards, -- OQube < software engineering \ génie logiciel > Arnaud Bailly, Dr. \web> http://www.oqube.com |
|
|
Re: Strange behavior....
by Arnaud Bailly
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Anyone ? Am I really dumb ?
-- OQube < software engineering \ génie logiciel > Arnaud Bailly, Dr. \web> http://www.oqube.com |
|
|
Re: Strange behavior....
by Eric Torreborre
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Don't know,...
Where is the code of the "outcome" method? I guess it must call "compareFiles", but what else does it do? E.
|
|
|
Re: Strange behavior....
by Arnaud Bailly
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Eric Torreborre <etorreborre@...> writes:
> Don't know,... > > Where is the code of the "outcome" method? I guess it must call > "compareFiles", but what else does it do? > Nothing else. just extracting the files from an option classe. Here is the full code: /** * A trait for understanding the outcome of a test. */ trait TestOracle { val outcome : TestOutcome } /** * This class produces a TestOutcome for a single test. */ abstract class FileDiffOracle(val expected: Option[File], val actual: Option[File]) extends TestOracle{ /** * This oracle compares two text files and produces an oracle according * to the following rules: * <ul> * <li>If the two input streams contain identical text, the test is a TestSuccess</li> * <li>If the two input streams contain different text, the test is a TestFailure</li> * <li>If the first inputstream is empty, the test is a TestSkipped</li> * <li>If second imput stream is empty, the test is a TestError</li> * </ul> * @return a TestOutcome */ override val outcome : TestOutcome = { (expected,actual) match { case (None,_) => TestSkipped case (_,None) => TestError case (Some(e),Some(a)) => compareFiles(e,a) } } /** * Method that compute the differences between files. * To implement by subclasses. */ def compareFiles(exp : File, act: File) : TestOutcome; } /** * Textual diff comparison oracle. * The outcome is produced by comparing the two input streams given * as actual and expected string. The oracle produces an outcome based * on the <em>textual</em> differences between the two files.<br /> * <strong>Note</strong>This class transforms the content of the files into * a String which is not optimal and may cause large memory consumption. It * would be better to parse the files on the fly but this implies adapting the * algorithm used in DiffMatchPatch. */ class TextDiffOracle(e: Option[File], a: Option[File])(implicit val lines : Boolean) extends FileDiffOracle(e,a) { var explainFailure : List[Diff] = Nil var explainError : String = "" override def compareFiles(exp : File, act: File) : TestOutcome = { val diff = new DiffMatchPatch() val stre = makeString(exp) val stra = makeString(act) val diffs = diff.diff_main(stre,stra,lines) if(diffs.size == 1 && diffs.get(0).asInstanceOf[Diff].operation == DiffMatchPatch.Operation.EQUAL) TestSuccessful else { this.explainFailure = diffs.toArray.map(_.asInstanceOf[Diff]).toList.filter(dif => dif.operation != DiffMatchPatch.Operation.EQUAL) println(explainFailure.length) TestFailure } } /** * Construct a string from the content of a file (if it exists) using * default locale. */ def makeString(f : File) : String = { val bos = new ByteArrayOutputStream val fis = new FileInputStream(f) new Pipe(bos,fis).pump bos.toString } } /** * XML diff comparison oracle. * The outcome is produced by comparing two files as XML content. */ class XmlDiffOracle(e: Option[File], a: Option[File]) extends FileDiffOracle(e,a) { var explainFailure : List[Difference] = Nil var explainError : String = "" override def compareFiles(exp : File, act: File) : TestOutcome = { val diff = new DetailedDiff(new org.custommonkey.xmlunit.Diff(new InputSource(new FileInputStream(exp)), new InputSource(new FileInputStream(act)))) if(diff.identical) TestSuccessful else { explainFailure = new BufferWrapper[Difference]{ def underlying = diff.getAllDifferences }.toList println(explainFailure) TestFailure } } override def toString : String = explainFailure.toString } -- OQube < software engineering \ génie logiciel > Arnaud Bailly, Dr. \web> http://www.oqube.com |
|
|
Re: Strange behavior....
by Eric Torreborre
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message I tried with a simplified version of the code using a java.util.ArrayList as an underlying to the BufferWrapper and it works.
So I suspect this is may be something with the collection you're using as an underlying to the BufferWrapper. Can you try just using a simple ArrayList to see what happens? Eric. |
|
|
Re: Strange behavior....
by Arnaud Bailly
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Hello Eric,
Thanks for your interest :) I checked in the source code of xmlunit which is the library I am using, and the getAllDifferences method returns an ArrayList. There must be something obvious I am missing :( Regards -- OQube < software engineering \ génie logiciel > Arnaud Bailly, Dr. \web> http://www.oqube.com |
|
|
Re: Strange behavior....
by Eric Torreborre
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Stranger and stranger,...
So I run the exact same code as you with 2 files (one with , the other one with </z>) and I have one difference showing up as expected. And the print statement in the test displays a proper list too. I just added something which was missing: trait TestOutcome object TestSkipped extends TestOutcome object TestError extends TestOutcome object TestSuccessful extends TestOutcome object TestFailure extends TestOutcome I am testing with Scala 2.6.0 (with the latest eclipse plugin), xml-unit1.1 and java 6. Is that some side-effect with your test suite having a static something, somewhere? Eric.
|
|
|
Re: Strange behavior....
by Arnaud Bailly
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message ????!!!!! No, I do not have static things (static is evil :)). I will try something else tomorrow. Thanks for very much for taking the time investigating my problem, that's really puzzling. I am pretty sure this is some silly thing so obvious I am skipping it. Best regards, -- Arnaud Bailly, PhD OQube - Software Engineering http://www.oqube.com |
|
|
Re: Strange behavior....
by Eric Torreborre
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message > ????!!!!!
> No, I do not have static things (static is evil :)) I was just thinking "hidden state". But I like working with people infuriated by the mere mentioning of static variables! Keep me updated, I'm curious. Eric. |
|
|
Re: Strange behavior....
by Arnaud Bailly
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Hello (and Happy New Year), I found the reason for my problem. Here is a skeleton code illustrating the issues, the reason should be obvious from this code ;-): trait Oracle { val outcome : Outcome; } abstract class AbstractOracle(val f: Option[File]) extends Oracle { override val outcome : Outcome = { f match { case None => Error case Some(f) => test(f) // (1) } } def test(f : File) : Outcome; } class ConcreteOracle(f1 : Option[File]) extends AbstractOracle(f1) { var explainFailure : List[Diff] = Nil // (2) override def test(f : File) : Outcome = { if(testok(f)) Success else { explainFailure = explain(f) // (3) Failure } } } The problem is that (2) gets called after (1) because the constructor code of ConcreteOracle is called after its superclasses'. Hence explainFailure is correctly computed in (3) and reset to Nil in (2). Some classical trap with OO constructor dispatch... Everything works fine when I write : abstract class AbstractOracle(val f: Option[File]) extends Oracle { override lazy val outcome : Outcome = { Then outcome is called only when requested, which does occur after the constructor sequence has finished. BTW, lazy values does not seem to be memoized (according to the generated bytecode at least) or maybe I missed something. Is there a deep reason for this ? I think that Haskell's (and maybe OCaml's) lazy values are memoized which leads to better performances. Best regards, -- Arnaud Bailly, PhD OQube - Software Engineering http://www.oqube.com |
| Free embeddable forum powered by Nabble | Forum Help |