2

I have a feature, let's call it F1, which returns one and the same file as two streams:

* def aPdf1 = read('classpath:pdf.pdf')
* def aPdf2 = read('classpath:pdf.pdf')
* def out = { one: aPdf1, two: aPdf2 }

When I call F1 from another feature, let's say F2, and compare the streams, they do not match:

* def out = call read('F1.feature')
* match out.aPdf1 == out.aPdf2

and the error is:

com.intuit.karate.exception.KarateException: unexpected type: class java.io.BufferedInputStream

Is this a bug? Or is it a not yet implemented feature?

PS1: If I add the following line to F1, it completes successfully by itself:

* match aPdf1 == aPdf2

PS2: Utilizing the code from the answer to this question, I was able to match the streams in F2.

1 Answers1

1

The problem is you have created an invalid JSON that happens to have binary streams as the values. Just stick to comparing streams with streams - which will work as you have seen already. If you need to convert the PDF to a string you can do this:

* string aPdf2 = read('classpath:pdf.pdf')

Also you may have missed the difference between embedded-expressions and "enclosed javascript". Did you mean to do this ?

* def out = ({ one: aPdf1, two: aPdf2 })

or:

* def out = { one: '#(aPdf1)', two: '#(aPdf2)' }

Also for more context on JSON and binary values - refer this answer: https://stackoverflow.com/a/52541026/143475

EDIT: so if you want to compare two streams you have to convert them to byte-arrays first. Try this, and you can sub your own implementation of a stream-to-byte converter:

* def Utils = Java.type('com.intuit.karate.FileUtils')
* def stream1 = read('karate-logo.png')
* def bytes1 = Utils.toBytes(stream1)
* def stream2 = read('karate-logo.png')
* def bytes2 = Utils.toBytes(stream2)
* assert java.util.Arrays.equals(bytes1, bytes2)

EDIt - in newer versions of Karate you can "cast" to bytes, and the match keyword supports data which is bytes as well

Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
  • Thank you, Peter! You are right - I didn't realize the JSON is invalid having streams as values. The question now would be how comparing the streams through Java routine called in F2 succeeds? Does the JSON hold pointers to the streams? And no, I didn't miss the difference between embedded-expressions and "enclosed javascript". – Dragomir Draganov Oct 30 '18 at 08:38
  • 1
    As I mentioned PS2 above, I already have stream comparison. Thank you anyway! – Dragomir Draganov Oct 31 '18 at 10:33
  • 1
    @DragomirDraganov actually guess what - I realize this is a gap in Karate - so the next version will allow you to compare two byte-arrays. we also have introduced a `bytes` type conversion marker, see this example: https://github.com/intuit/karate/blob/fd9caa8e348e025aecfc936a2fd5a64baa826826/karate-junit4/src/test/java/com/intuit/karate/junit4/demos/bytes.feature – Peter Thomas Nov 01 '18 at 15:41