Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite Blob to facilitate interop with other libs #1211

Merged
merged 5 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 102 additions & 8 deletions modules/bootstrapped/test/src/smithy4s/BlobSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package smithy4s
import munit._

import java.nio.ByteBuffer

import java.io.ByteArrayOutputStream
class BlobSpec() extends FunSuite {

test("sameBytesAs works across data structures") {
Expand All @@ -37,13 +37,6 @@ class BlobSpec() extends FunSuite {
)
}

test("ByteBufferBlob.toArray is idempotent, instantiation-wise") {
val blob = Blob(ByteBuffer.wrap("foo".getBytes))
assert(blob.toArray != null)
assert(blob.toArray.eq(blob.toArray))
assertEquals(Blob(blob.toArray), Blob("foo"))
}

test("ByteArrayBlob.hashcode is consistent") {
def makeBlob(str: String) = Blob(str.getBytes)
val blob1 = makeBlob("foo")
Expand All @@ -62,4 +55,105 @@ class BlobSpec() extends FunSuite {
assertNotEquals(blob1.hashCode, blob3.hashCode)
}

test("Concat works as expected") {
val blob = Blob("foo") ++ Blob("bar")
assertEquals(blob.size, 6)
assertEquals(blob(2), 'o'.toByte)
assertEquals(blob(4), 'a'.toByte)
java.util.Arrays
.equals(blob.toArray, "foo".getBytes ++ "bar".getBytes())
}

val all = List(
"Queue" -> (Blob("foo") ++ Blob("bar")),
"Array" -> Blob("foobar"),
"Buffer" -> Blob(ByteBuffer.wrap("foobar".getBytes()))
)

for {
x <- all
y <- all
} {
test(s"${x._1} and ${y._1} : same bytes") {
assert(x._2.sameBytesAs(y._2))
}
}

all.foreach { case (name, data) =>
test(s"$name: size") {
assertEquals(data.size, 6)
}

test(s"$name: index access") {
assertEquals(data(2), 'o'.toByte)
}

test(s"$name: out of bounds access") {
try {
val _ = data(6)
fail("expected exception")
} catch {
case _: IndexOutOfBoundsException => ()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try {
val _ = data(6)
fail("expected exception")
} catch {
case _: IndexOutOfBoundsException => ()
}
intercept[IndexOutOfBoundsException]{ data(6) }

Copy link
Contributor Author

@Baccata Baccata Sep 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks ! b50d8d4

}

test(s"$name: utf8String") {
assertEquals(data.toUTF8String, "foobar")
}

test(s"$name: toArraySliceBlob") {
assertEquals[Blob, Blob](
data.toArraySliceBlob,
Blob.slice("foobar".getBytes(), 0, 6)
)
}

test(s"$name: copyToArray") {
val target = Array.fill[Byte](6)(0)
data.copyToArray(target, 0, 0, data.size)
assert(target.sameElements("foobar".getBytes()))
}

test(s"$name: copyToBuffer") {
val target = ByteBuffer.wrap(Array.fill[Byte](6)(0))
data.copyToBuffer(target, 0, data.size)
assert(target.array.sameElements("foobar".getBytes()))
}

test(s"$name: copyToStream") {
val stream = new ByteArrayOutputStream()
try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the other day I discovered Using and Using.resource to do this kind of resource management

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I was under the impression it was a 2.13+ only thing

b50d8d4

data.copyToStream(stream, 0, data.size)
assert(stream.toByteArray().sameElements("foobar".getBytes()))
} finally {
stream.close()
}
}
}

test("asByteBufferUnsafe") {
val arr = "Hello, world!".getBytes
assert(arr eq Blob.view(ByteBuffer.wrap(arr)).asByteBufferUnsafe.array)
assert(
arr eq Blob.view(ByteBuffer.wrap(arr)).asByteBufferUnsafe.array
)
}

test("asByteBufferUnsafe has independent position+limit") {
val bv = Blob.view(ByteBuffer.wrap("Hello, world!".getBytes))
val bb1 = bv.asByteBufferUnsafe
assertEquals(bb1.position(), 0)
assertEquals(bb1.limit(), 13)
val bb2 = bv.asByteBufferUnsafe
bb2.position(1)
bb2.limit(2)
assertEquals(bb1.position(), 0)
assertEquals(bb1.limit(), 13)
}

test("Array slice: access") {
val slice = Blob.slice("foobar".getBytes(), 1, 4)
assert(slice.sameBytesAs(Blob("ooba")))
}

}
Loading