From 425128bd9166f63f0fdc0d9cd6cde6c1250027c6 Mon Sep 17 00:00:00 2001 From: c Date: Thu, 19 Dec 2024 20:42:48 -0700 Subject: [PATCH] Bug fixes and tests. Added UnzipTest Added NArray type verifications to testing. Introduced ClassTag matching to ofSize and NArrayBuilder.apply. --- .../main/scala/narr/native/Extensions.scala | 91 +++-- .../src/main/scala/narr/native/package.scala | 28 +- .../src/main/scala/narr/NArrayBuilder.scala | 40 ++- narr/shared/src/main/scala/narr/package.scala | 101 +++--- tests/shared/src/test/scala/BuilderTest.scala | 145 +++++--- tests/shared/src/test/scala/CopyTest.scala | 40 +-- .../src/test/scala/InstantiationTest.scala | 317 ++++++++++++------ .../shared/src/test/scala/NArrayOpsTest.scala | 108 +++--- tests/shared/src/test/scala/UnzipTest.scala | 79 +++++ tests/shared/src/test/scala/Util.scala | 35 +- 10 files changed, 658 insertions(+), 326 deletions(-) create mode 100644 tests/shared/src/test/scala/UnzipTest.scala diff --git a/narr/js/src/main/scala/narr/native/Extensions.scala b/narr/js/src/main/scala/narr/native/Extensions.scala index 6ccd351..db51b50 100644 --- a/narr/js/src/main/scala/narr/native/Extensions.scala +++ b/narr/js/src/main/scala/narr/native/Extensions.scala @@ -17,7 +17,6 @@ package narr.native import narr.* -import narr.NArray.builderFor import scala.collection.{IndexedSeqView, immutable, mutable} import scala.scalajs.js @@ -43,6 +42,10 @@ object Extensions { def sorted: ByteArray = sorted(Ordering.Byte) def sorted(ord: Ordering[Byte]): ByteArray = sortByteArray(copy[Byte](a), ord) + + def unzip[A1, A2](using asPair: Byte => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (NArray[A1], NArray[A2]) = { + narr.native.NArray.unzip[Byte, A1, A2](a) + } } extension (a: ShortArray) { @@ -52,6 +55,10 @@ object Extensions { def sorted: ShortArray = sorted(Ordering.Short) def sorted(ord: Ordering[Short]): ShortArray = sortShortArray(copy[Short](a), ord) + + def unzip[A1, A2](using asPair: Short => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (NArray[A1], NArray[A2]) = { + narr.native.NArray.unzip[Short, A1, A2](a) + } } extension (a: IntArray) { @@ -60,6 +67,10 @@ object Extensions { def sorted:IntArray = sorted(Ordering.Int) def sorted(ord:Ordering[Int]): IntArray = sortIntArray(copy[Int](a), ord) + + def unzip[A1, A2](using asPair: Int => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (NArray[A1], NArray[A2]) = { + narr.native.NArray.unzip[Int, A1, A2](a) + } } extension (a: FloatArray) { @@ -68,6 +79,10 @@ object Extensions { def sort(ord: Ordering[Float]): FloatArray = sortFloatArray(a, ord) def sorted: FloatArray = sorted(Ordering.Float.TotalOrdering) def sorted(ord: Ordering[Float]): FloatArray = sortFloatArray(copy[Float](a), ord) + + def unzip[A1, A2](using asPair: Float => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (NArray[A1], NArray[A2]) = { + narr.native.NArray.unzip[Float, A1, A2](a) + } } extension (a: DoubleArray) { @@ -75,6 +90,10 @@ object Extensions { def sort(ord: Ordering[Double]): DoubleArray = sortDoubleArray(a, ord) def sorted: DoubleArray = sorted(Ordering.Double.TotalOrdering) def sorted(ord: Ordering[Double]): DoubleArray = sortDoubleArray(copy[Double](a), ord) + + def unzip[A1, A2](using asPair: Double => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (NArray[A1], NArray[A2]) = { + narr.native.NArray.unzip[Double, A1, A2](a) + } } extension[T <: AnyRef | Boolean | Char | Long | Unit] (a:NArray[T]) { @@ -216,7 +235,7 @@ object Extensions { * of this array. */ inline def slice(from: Int, until: Int): NArray[T] = { - a.asInstanceOf[NArr[T]].slice(from, until).asInstanceOf[NArray[T]] + ((a.asInstanceOf[NArr[T]]).slice(from, until)).asInstanceOf[NArray[T]] } /** The rest of the NArray without its first element. */ @@ -355,8 +374,8 @@ object Extensions { /** A pair of, first, all elements that satisfy predicate `p` and, second, all elements that do not. */ def partition(p: T => Boolean)(using ClassTag[T], ClassTag[NArray[T]]): (NArray[T], NArray[T]) = { - val nab1 = builderFor[T]() - val nab2 = builderFor[T]() + val nab1 = NArrayBuilder[T]() + val nab2 = NArrayBuilder[T]() var i = 0; while (i < a.length) { val x = a(i) @@ -696,7 +715,7 @@ object Extensions { * `f` to each element of this array and concatenating the results. */ def flatMap[B: ClassTag](f: T => IterableOnce[B]): NArray[B] = { - val b = NArray.builderFor[B]() + val b = NArrayBuilder[B]() var i = 0 while (i < a.length) { b ++= f(a(i)) @@ -715,7 +734,7 @@ object Extensions { * @param asIterable A function that converts elements of this array to rows - Iterables of type `B`. * @return An array obtained by concatenating rows of this array. */ - def flatten[B](using asIterable: T => IterableOnce[B], m: ClassTag[B]): NArray[B] = { + def flatten[B:ClassTag](using asIterable: T => IterableOnce[B]): NArray[B] = { val len = a.length var size = 0 var i = 0 @@ -734,7 +753,7 @@ object Extensions { } i += 1 } - val b = NArray.builderFor[B](size) + val b = NArrayBuilder[B](size) i = 0 while (i < len) { b ++= asIterable(a(i)) @@ -754,7 +773,7 @@ object Extensions { */ def collect[B: ClassTag](pf: PartialFunction[T, B]): NArray[B] = { val fallback: Any => Any = Any => Extensions.fallback - val b = NArray.builderFor[B]() + val b = NArrayBuilder[B]() var i = 0 while (i < a.length) { val v = pf.applyOrElse(a(i), fallback) @@ -790,7 +809,7 @@ object Extensions { */ def zip[B](that: IterableOnce[B]): NArray[(T, B)] = { val k = that.knownSize - val b = NArray.builderFor[(T, B)](if (k >= 0) Math.min(k, a.length) else a.length) + val b = NArrayBuilder.builderFor[(T, B)]( if (k >= 0) Math.min(k, a.length) else a.length ) var i = 0 val it = that.iterator @@ -816,7 +835,7 @@ object Extensions { * If `that` is shorter than this array, `thatElem` values are used to pad the result. */ def zipAll[A1 >: T, B](that: Iterable[B], thisElem: A1, thatElem: B): NArray[(A1, B)] = { - val b = NArray.builderFor[(A1, B)](Math.max(that.knownSize, a.length)) + val b = NArrayBuilder.builderFor[(A1, B)](Math.max(that.knownSize, a.length)) var i = 0 val it = that.iterator while (i < a.length && it.hasNext) { @@ -867,14 +886,19 @@ object Extensions { /** A copy of this array with all elements of a collection prepended. */ def prependedAll[B >: T : ClassTag](prefix: IterableOnce[B]): NArray[B] = { val k = prefix.knownSize - val b = NArray.builderFor[B]((if (k >= 0) k else 0) + a.length) + val b = NArrayBuilder[B]((if (k >= 0) k else 0) + a.length) b.addAll(prefix) b.addAll(a.asInstanceOf[NArray[B]]) b.result } /** A copy of this array with all elements of an array prepended. */ - def prependedAll[B >: T : ClassTag](prefix: NArray[B] ): NArray[B] = NArray.concatenate(prefix, a.asInstanceOf[NArray[B]]) + def prependedAll[B >: T : ClassTag](prefix: NArray[B] ): NArray[B] = { + val out = NArray.ofSize[B](prefix.length + a.length) + NArray.copy[B](prefix, out, 0) + NArray.copy[B](a.asInstanceOf[NArray[B]], out, prefix.length) + out + } inline def ++:[B >: T : ClassTag](prefix: IterableOnce[B]): NArray[B] = prependedAll(prefix) @@ -882,7 +906,7 @@ object Extensions { /** A copy of this array with all elements of a collection appended. */ def appendedAll[B >: T : ClassTag](suffix: IterableOnce[B]): NArray[B] = { - val nab = NArray.builderFor[B]() + val nab = NArrayBuilder[B]() nab.addAll(a.asInstanceOf[NArray[B]]) val itr = suffix.iterator while (itr.hasNext) nab += itr.next() @@ -890,19 +914,24 @@ object Extensions { } /** A copy of this array with all elements of an array appended. */ - def appendedAll[B >: T : ClassTag](suffix: NArray[B]): NArray[B] = NArray.concatenate(a, suffix) + def appendedAll[B >: T : ClassTag](suffix: NArray[B]): NArray[B] = { + val out = NArray.ofSize[B](a.length + suffix.length) + NArray.copy[B](a.asInstanceOf[NArray[B]], out, 0) + NArray.copy[B](suffix, out, a.length) + out + } inline def :++ [B >: T : ClassTag](suffix: IterableOnce[B]): NArray[B] = appendedAll(suffix) - inline def :++ [B >: T : ClassTag](suffix: NArray[B]): NArray[B] = NArray.concatenate(a, suffix) + inline def :++ [B >: T : ClassTag](suffix: NArray[B]): NArray[B] = appendedAll[B](suffix) inline def concat[B >: T : ClassTag](suffix: IterableOnce[B]): NArray[B] = appendedAll(suffix) - inline def concat[B >: T : ClassTag](suffix: NArray[B]): NArray[B] = NArray.concatenate(a, suffix) + inline def concat[B >: T : ClassTag](suffix: NArray[B]): NArray[B] = appendedAll[B](suffix) inline def ++[B >: T : ClassTag](xs: IterableOnce[B]): NArray[B] = appendedAll(xs) - inline def ++[B >: T : ClassTag](suffix: NArray[B]): NArray[B] = NArray.concatenate(a, suffix) + inline def ++[B >: T : ClassTag](suffix: NArray[B]): NArray[B] = appendedAll[B](suffix) /** Tests whether this array contains a given value as an element. * @@ -931,7 +960,7 @@ object Extensions { def patch[B >: T : ClassTag](from: Int, other: IterableOnce[B], replaced: Int): NArray[B] = { val k = other.knownSize val r = if (replaced < 0) 0 else replaced - val b = NArray.builderFor[B](if (k >= 0) a.length + k - r else 0) + val b = NArrayBuilder[B](if (k >= 0) a.length + k - r else 0) val chunk1 = if (from > 0) Math.min(from, a.length) else 0 if (chunk1 > 0) b.addAll(a.asInstanceOf[NArray[B]], 0, chunk1) b.addAll(other) @@ -954,19 +983,9 @@ object Extensions { * of each element pair of this Array. */ def unzip[A1, A2](using asPair: T => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (NArray[A1], NArray[A2]) = { - val a1 = NArray.ofSize[A1](a.length) - val a2 = NArray.ofSize[A2](a.length) - var i = 0 - while (i < a.length) { - val e = asPair(a(i)) - a1(i) = e._1 - a2(i) = e._2 - i += 1 - } - (a1, a2) + narr.native.NArray.unzip[T, A1, A2](a) } - /** Converts an array of triples into three arrays, one containing the elements from each position of the triple. * * @tparam A1 the type of the first of three elements in the triple @@ -1007,10 +1026,10 @@ object Extensions { */ def transpose[B](using asArray: T => NArray[B]): NArray[NArray[B]] = { val aClass = a.getClass.getComponentType - val bb = NArray.builderFor[NArray[B]]() + val bb = NArrayBuilder.builderFor[NArray[B]]() if (a.length == 0) bb.result else { - def mkRowBuilder() = NArray.builderFor[B]() + def mkRowBuilder() = NArrayBuilder.builderFor[B]() val bs = asArray(a(0)).map((x: B) => mkRowBuilder()) @@ -1050,7 +1069,7 @@ object Extensions { * @return a new array consisting of all the elements of this array without duplicates. */ def distinctBy[B](f: T => B): NArray[T] = - NArray.builderFor[T]().addAll(iterator.distinctBy(f)).result + NArrayBuilder.builderFor[T]().addAll(iterator.distinctBy(f)).result /** A copy of this array with an element value appended until a given target length is reached. * @@ -1097,7 +1116,7 @@ object Extensions { while(i < len) { val elem = a(i) val key = f(elem) - val bldr = m.getOrElseUpdate(key, NArray.builderFor[T]()) + val bldr = m.getOrElseUpdate(key, NArrayBuilder.builderFor[T]()) bldr += elem i += 1 } @@ -1129,7 +1148,7 @@ object Extensions { while (i < len) { val elem = a(i) val k = key(elem) - val bldr = m.getOrElseUpdate(k, NArray.builderFor[B]()) + val bldr = m.getOrElseUpdate(k, NArrayBuilder[B]()) bldr += f(elem) i += 1 } @@ -1296,7 +1315,7 @@ object Extensions { if (isEmpty || that.isEmpty) a.copy else { val occ = occCounts(that) - val b = builderFor[T]() + val b = NArrayBuilder.builderFor[T]() var i = 0 while (i < a.length) { val x = a(i) @@ -1327,7 +1346,7 @@ object Extensions { if (isEmpty || that.isEmpty) a.slice(0, 0) else { val occ = occCounts(that) - val b = builderFor[T]() + val b = NArrayBuilder.builderFor[T]() var i = 0 while (i < a.length) { val x = a(i) diff --git a/narr/js/src/main/scala/narr/native/package.scala b/narr/js/src/main/scala/narr/native/package.scala index 640ebb0..baaf288 100644 --- a/narr/js/src/main/scala/narr/native/package.scala +++ b/narr/js/src/main/scala/narr/native/package.scala @@ -170,9 +170,35 @@ package object native { println(s"cp = $cp, newLength = $newLength") narr.NArray.copy[T]( original, cp, 0 ) } - } + /** Converts an array of pairs into an array of first elements and an array of second elements. + * + * @tparam A1 the type of the first half of the element pairs + * @tparam A2 the type of the second half of the element pairs + * @param asPair an implicit conversion which asserts that the element type + * of this Array is a pair. + * @param ct1 a class tag for `A1` type parameter that is required to create an instance + * of `Array[A1]` + * @param ct2 a class tag for `A2` type parameter that is required to create an instance + * of `Array[A2]` + * @return a pair of Arrays, containing, respectively, the first and second half + * of each element pair of this Array. + */ + def unzip[T, A1, A2](a: NArray[T])(using asPair: T => (A1, A2), ct1: ClassTag[A1], ct2: ClassTag[A2]): (NArray[A1], NArray[A2]) = { + val a1 = narr.NArray.ofSize[A1](a.length) + val a2 = narr.NArray.ofSize[A2](a.length) + var i = 0 + while (i < a.length) { + val e = asPair(a(i)) + a1(i) = e._1 + a2(i) = e._2 + i += 1 + } + (a1, a2) + } + } + inline def makeNativeArrayOfSize[A](n:Int)(using ClassTag[A]):NativeArray[A] = (new scala.scalajs.js.Array[Any](n)).asInstanceOf[NativeArray[A]] } diff --git a/narr/shared/src/main/scala/narr/NArrayBuilder.scala b/narr/shared/src/main/scala/narr/NArrayBuilder.scala index 845c727..a012fdd 100644 --- a/narr/shared/src/main/scala/narr/NArrayBuilder.scala +++ b/narr/shared/src/main/scala/narr/NArrayBuilder.scala @@ -23,8 +23,6 @@ package narr import narr.* -import narr.native.NativeArrayBuilder - import scala.compiletime.erasedValue import scala.reflect.ClassTag @@ -32,14 +30,14 @@ object NArrayBuilder { val DefaultInitialSize:Int = 16 val MAX_NArraySize:Int = 2147483639 - transparent inline def apply[A:ClassTag](initialCapacity: Int = DefaultInitialSize)(using ClassTag[NArray[A]]):NArrayBuilder[A] = (inline erasedValue[A] match { - case _: Byte => ByteArrayBuilder(initialCapacity) - case _: Short => ShortArrayBuilder(initialCapacity) - case _: Int => IntArrayBuilder(initialCapacity) - case _: Float => FloatArrayBuilder(initialCapacity) - case _: Double => DoubleArrayBuilder(initialCapacity) - case _ => NativeArrayBuilder[A](initialCapacity) - }).asInstanceOf[NArrayBuilder[A]] +// transparent inline def apply[A:ClassTag](initialCapacity: Int = DefaultInitialSize)(using ClassTag[NArray[A]]):NArrayBuilder[A] = (inline erasedValue[A] match { +// case _: Byte => ByteArrayBuilder(initialCapacity) +// case _: Short => ShortArrayBuilder(initialCapacity) +// case _: Int => IntArrayBuilder(initialCapacity) +// case _: Float => FloatArrayBuilder(initialCapacity) +// case _: Double => DoubleArrayBuilder(initialCapacity) +// case _ => NativeArrayBuilder[A](initialCapacity) +// }).asInstanceOf[NArrayBuilder[A]] // def main(args:Array[String]):Unit = { // var i:Int = DefaultInitialSize @@ -56,6 +54,24 @@ object NArrayBuilder { // } + inline def apply[T](initialCapacity: Int = DefaultInitialSize)(using ct:ClassTag[T]): NArrayBuilder[T] = (ct match { + case ClassTag.Byte => ByteArrayBuilder(initialCapacity) + case ClassTag.Short => ShortArrayBuilder(initialCapacity) + case ClassTag.Int => IntArrayBuilder(initialCapacity) + case ClassTag.Float => FloatArrayBuilder(initialCapacity) + case ClassTag.Double => DoubleArrayBuilder(initialCapacity) + case _ => narr.native.NativeArrayBuilder[T](initialCapacity) + }).asInstanceOf[NArrayBuilder[T]] + + inline def builderFor[T](initialCapacity: Int = NArrayBuilder.DefaultInitialSize): NArrayBuilder[T] = (inline erasedValue[T] match { + case _: Byte => ByteArrayBuilder() + case _: Short => ShortArrayBuilder() + case _: Int => IntArrayBuilder() + case _: Float => FloatArrayBuilder() + case _: Double => DoubleArrayBuilder() + case _ => narr.native.NativeArrayBuilder[Any]() + }).asInstanceOf[NArrayBuilder[T]] + } /** @@ -83,14 +99,16 @@ trait NArrayBuilder[T] { addAll( xs.slice( offset1, - length.max(0).min(xs.length - offset1) + offset1 + length.max(0).min(xs.length - offset1) ) ) } + def addAll(itr: Iterator[T]): this.type = { while (itr.hasNext) addOne(itr.next()) this } + def addAll(xs: IterableOnce[T]): this.type = { addAll(xs.iterator) this diff --git a/narr/shared/src/main/scala/narr/package.scala b/narr/shared/src/main/scala/narr/package.scala index e7bebdb..6d27e58 100644 --- a/narr/shared/src/main/scala/narr/package.scala +++ b/narr/shared/src/main/scala/narr/package.scala @@ -15,7 +15,6 @@ */ import scala.compiletime.* -import narr.native.Extensions.* import scala.collection.AbstractIndexedSeqView import scala.language.implicitConversions @@ -56,37 +55,55 @@ package object narr { object NArray { -// transparent inline def builderFrom[T](example:NArray[T]): NArrayBuilder[T] = (example match { -// case _: ByteArray => ByteArrayBuilder() -// case _: ShortArray => ShortArrayBuilder() -// case _: IntArray => IntArrayBuilder() -// case _: FloatArray => FloatArrayBuilder() -// case _: DoubleArray => DoubleArrayBuilder() -// case _ => NativeArrayBuilder[Any]() -// }).asInstanceOf[NArrayBuilder[T]] - - transparent inline def builderFor[T](initialCapacity:Int = NArrayBuilder.DefaultInitialSize): NArrayBuilder[T] = (inline erasedValue[T] match { - case _: Byte => ByteArrayBuilder() - case _: Short => ShortArrayBuilder() - case _: Int => IntArrayBuilder() - case _: Float => FloatArrayBuilder() - case _: Double => DoubleArrayBuilder() - case _ => narr.native.NativeArrayBuilder[Any]() - }).asInstanceOf[NArrayBuilder[T]] - def apply[A](elem: A*)(using ClassTag[A]): NArray[A] = tabulate[A](elem.size)((i: Int) => elem(i)) inline def empty[A](using ClassTag[A]): NArray[A] = ofSize[A](0) - transparent inline def ofSize[A](length: Int)(using ClassTag[A]): NArr[A] & NArray[A] = (inline erasedValue[A] match { - case _: Byte => new ByteArray(length) - case _: Short => new ShortArray(length) - case _: Int => new IntArray(length) - case _: Float => new FloatArray(length) - case _: Double => new DoubleArray(length) + transparent inline def ofSize[A](length: Int)(using ct:ClassTag[A]): NArr[A] & NArray[A] = (ct match { + case ClassTag.Byte => new ByteArray(length) + case ClassTag.Short => new ShortArray(length) + case ClassTag.Int => new IntArray(length) + case ClassTag.Float => new FloatArray(length) + case ClassTag.Double => new DoubleArray(length) case _ => makeNativeArrayOfSize[A](length) }).asInstanceOf[NArr[A] & NArray[A]] + inline def fill[A](length: Int)(t: A)(using ClassTag[A]): NArray[A] = { + val out: NArray[A] = ofSize[A](length) + var i: Int = 0 + while (i < length) { + out(i) = t + i += 1 + } + + out + } + + inline def tabulate[A](length: Int)(f: Int => A)(using ClassTag[A]): NArray[A] = { + val out: NArray[A] = ofSize[A](length) + var i: Int = 0 + while (i < length) { + out(i) = f(i) + i += 1 + } + out + } + + transparent inline def from[A](arr: Array[A])(using ClassTag[A]): NArray[A] = { + val out: NArray[A] = ofSize[A](arr.length) + var i: Int = 0 + while (i < arr.length) { + out(i) = arr(i) + i += 1 + } + out + } + +// inline def concatenate[A](a: NArray[A], b: NArray[A]):NArray[A] = { +// (a.asInstanceOf[NArr[A]]).concat(b).asInstanceOf[NArray[A]] +// } + + def copy[T](nArr: NArray[T]): NArray[T] = nArr.slice(0, nArr.length) /** Copy one array to another. @@ -174,40 +191,6 @@ package object narr { */ def copyOf[T](original: NArray[T], newLength: Int)(using ClassTag[T]): NArray[T] = native.NArray.copyOf[T](original, newLength) - inline def fill[A](length: Int)(t: A)(using ClassTag[A]): NArray[A] = { - val out: NArray[A] = ofSize[A](length) - var i: Int = 0 - while (i < length) { - out(i) = t - i += 1 - } - - out - } - - inline def tabulate[A](length: Int)(f: Int => A)(using ClassTag[A]): NArray[A] = { - val out: NArray[A] = ofSize[A](length) - var i: Int = 0 - while (i < length) { - out(i) = f(i) - i += 1 - } - out - } - - transparent inline def from[A](arr: Array[A])(using ClassTag[A]): NArray[A] = { - val out: NArray[A] = ofSize[A](arr.length) - var i: Int = 0 - while (i < arr.length) { - out(i) = arr(i) - i += 1 - } - out - } - - inline def concatenate[A, B >: A : ClassTag](a: NArray[A], b: NArray[B]):NArray[B] = { - (a.asInstanceOf[NArr[A]]).concat(b).asInstanceOf[NArray[B]] - } } type NArr[T] = narr.native.NArr[T] diff --git a/tests/shared/src/test/scala/BuilderTest.scala b/tests/shared/src/test/scala/BuilderTest.scala index 9ceed79..1e90804 100644 --- a/tests/shared/src/test/scala/BuilderTest.scala +++ b/tests/shared/src/test/scala/BuilderTest.scala @@ -14,104 +14,163 @@ * limitations under the License. */ -import Util.assertNArrayEquality +import munit.{Compare, Location} import narr.* +import Util.* +import Util.NArrayType.* import scala.reflect.ClassTag import scala.util.Random class BuilderTest extends munit.FunSuite { val r:Random = new Random() + val N: Int = 8192 - class AddOneByOneTest[T: ClassTag](nab: NArrayBuilder[T], r0: () => T) { + class AddOneByOneTest[T: ClassTag](nab: NArrayBuilder[T], values: NArray[T], nt: NArrayType) { def runTests(): Unit = { - val n: Int = 8192 - val truth: NArray[T] = NArray.tabulate[T](n)((i: Int) => r0()) - - var i: Int = 0; while (i < n) { - nab.addOne(truth(i)) + var i: Int = 0; while (i < N) { + nab.addOne(values(i)) i = i + 1 } val result: NArray[T] = nab.result - assertEquals(result.length, n) - assertNArrayEquality[T](truth, result) + assertEquals(result.length, N) + assertNArrayEquality[T](values, result, nt) // accessor test var accumulator = true - i = 0; while (i < n) { - if (truth(i) != nab(i)) println(s"truth($i) == nab($i): ${truth(i)} == ${nab(i)}") - accumulator = accumulator && (truth(i) == nab(i)) + i = 0; while (i < N) { + if (values(i) != nab(i)) println(s"values($i) == nab($i): ${values(i)} == ${nab(i)}") + accumulator = accumulator && (values(i) == nab(i)) i = i + 1 } assert(accumulator) } } - class AddAllTest[T: ClassTag](nab: NArrayBuilder[T], r0: () => T) { + class AddAllTest[T: ClassTag](nab: NArrayBuilder[T], values: NArray[T], nt: NArrayType) { def runTests(): Unit = { - - val n: Int = 8192 - val truth: NArray[T] = NArray.tabulate[T](n)((i: Int) => r0()) - var i: Int = 0; while (i < n) { - val j:Int = Math.min(r.nextInt(128), n - i) - val s:NArray[T] = truth.slice( i, i + j ) - nab.addAll(s) - i = i + j + var i: Int = 0; while (i < N) { + val j:Int = Math.min(r.nextInt(128), N - i) + if (Math.random() > 0.5) { + val s: NArray[T] = values.slice(i, i + j) + nab.addAll(s) + i = i + j + } else { + nab.addAll(values, i, j) + i = i + j + } } val result: NArray[T] = nab.result - assertEquals(result.length, n) - assertNArrayEquality[T](truth, result) + assertEquals(result.length, N) + assertNArrayEquality[T](values, result, nt) + } + } + + private class BuilderResultTypeTest[T: ClassTag](expectedNArrType: NArrayType) { + + def runTests(): Unit = { + // Indirect + assertNArrayType[T](NArrayBuilder[T]().result, expectedNArrType) } } + // builderFor + test(" NArray.builderFor[]()") { + // Direct + assertNArrayType[Byte](NArrayBuilder.builderFor[Byte]().result, BYTE_ARRAY) + assertNArrayType[Short](NArrayBuilder.builderFor[Short]().result, SHORT_ARRAY) + assertNArrayType[Int](NArrayBuilder.builderFor[Int]().result, INT_ARRAY) + assertNArrayType[Float](NArrayBuilder.builderFor[Float]().result, FLOAT_ARRAY) + assertNArrayType[Double](NArrayBuilder.builderFor[Double]().result, DOUBLE_ARRAY) + assertNArrayType[Unit](NArrayBuilder.builderFor[Unit]().result, NATIVE_ARRAY) + assertNArrayType[Boolean](NArrayBuilder.builderFor[Boolean]().result, NATIVE_ARRAY) + assertNArrayType[Long](NArrayBuilder.builderFor[Long]().result, NATIVE_ARRAY) + assertNArrayType[String](NArrayBuilder.builderFor[String]().result, NATIVE_ARRAY) + assertNArrayType[Any](NArrayBuilder.builderFor[Any]().result, NATIVE_ARRAY) + } + test(" NArrayBuilder[Boolean] ") { - AddOneByOneTest[Boolean](NArrayBuilder[Boolean](), () => r.nextBoolean()).runTests() - AddAllTest[Boolean](NArrayBuilder[Boolean](), () => r.nextBoolean()).runTests() + val f = () => r.nextBoolean() + val values: NArray[Boolean] = NArray.tabulate[Boolean](N)((i: Int) => f()) + AddOneByOneTest[Boolean](NArrayBuilder[Boolean](), values, NATIVE_ARRAY).runTests() + AddAllTest[Boolean](NArrayBuilder[Boolean](), values, NATIVE_ARRAY).runTests() + BuilderResultTypeTest[Boolean](NATIVE_ARRAY).runTests() } test(" NArrayBuilder[Byte] ") { - AddOneByOneTest[Byte](NArrayBuilder[Byte](), () => r.nextBytes(1)(0)).runTests() - AddAllTest[Byte](NArrayBuilder[Byte](), () => r.nextBytes(1)(0)).runTests() + val f = () => r.nextBytes(1)(0) + val values: NArray[Byte] = NArray.tabulate[Byte](N)((i: Int) => f()) + AddOneByOneTest[Byte](NArrayBuilder[Byte](), values, BYTE_ARRAY).runTests() + AddAllTest[Byte](NArrayBuilder[Byte](), values, BYTE_ARRAY).runTests() + //assertBuilderResultType[Byte](values.builder[Byte]().result, BYTE_ARRAY) + BuilderResultTypeTest[Byte](BYTE_ARRAY).runTests() } test(" NArrayBuilder[Short] ") { - AddOneByOneTest[Short](NArrayBuilder[Short](), () => r.nextInt().toShort).runTests() - AddAllTest[Short](NArrayBuilder[Short](), () => r.nextInt().toShort).runTests() + val f = () => r.nextInt().toShort + val values: NArray[Short] = NArray.tabulate[Short](N)((i: Int) => f()) + AddOneByOneTest[Short](NArrayBuilder[Short](), values, SHORT_ARRAY).runTests() + AddAllTest[Short](NArrayBuilder[Short](), values, SHORT_ARRAY).runTests() + //assertBuilderResultType[Short](values.builder[Short]().result, SHORT_ARRAY) + BuilderResultTypeTest[Short](SHORT_ARRAY).runTests() } test(" NArrayBuilder[Int] ") { - AddOneByOneTest[Int](NArrayBuilder[Int](), () => r.nextInt()).runTests() - AddAllTest[Int](NArrayBuilder[Int](), () => r.nextInt()).runTests() + val f = () => r.nextInt() + val values: NArray[Int] = NArray.tabulate[Int](N)((i: Int) => f()) + AddOneByOneTest[Int](NArrayBuilder[Int](), values, INT_ARRAY).runTests() + AddAllTest[Int](NArrayBuilder[Int](), values, INT_ARRAY).runTests() + //assertBuilderResultType[Int](values.builder[Int]().result, INT_ARRAY) + BuilderResultTypeTest[Int](INT_ARRAY).runTests() } test(" NArrayBuilder[Long] ") { - AddOneByOneTest[Long](NArrayBuilder[Long](), () => r.nextLong()).runTests() - AddAllTest[Long](NArrayBuilder[Long](), () => r.nextLong()).runTests() - + val f = () => r.nextLong() + val values: NArray[Long] = NArray.tabulate[Long](N)((i: Int) => f()) + AddOneByOneTest[Long](NArrayBuilder[Long](), values, NATIVE_ARRAY).runTests() + AddAllTest[Long](NArrayBuilder[Long](), values, NATIVE_ARRAY).runTests() + //assertBuilderResultType[Long](values.builder[Long]().result, NATIVE_ARRAY) + BuilderResultTypeTest[Long](NATIVE_ARRAY).runTests() } test(" NArrayBuilder[Float] ") { - AddOneByOneTest[Float](NArrayBuilder[Float](), () => r.nextFloat()).runTests() - AddAllTest[Float](NArrayBuilder[Float](), () => r.nextFloat()).runTests() + val f = () => r.nextFloat() + val values: NArray[Float] = NArray.tabulate[Float](N)((i: Int) => f()) + AddOneByOneTest[Float](NArrayBuilder[Float](), values, FLOAT_ARRAY).runTests() + AddAllTest[Float](NArrayBuilder[Float](), values, FLOAT_ARRAY).runTests() + //assertBuilderResultType[Float](values.builder[Float]().result, FLOAT_ARRAY) + BuilderResultTypeTest[Float](FLOAT_ARRAY).runTests() } test(" NArrayBuilder[Double] ") { - AddOneByOneTest[Double](NArrayBuilder[Double](), () => r.nextDouble()).runTests() - AddAllTest[Double](NArrayBuilder[Double](), () => r.nextDouble()).runTests() + val f = () => r.nextDouble() + val values: NArray[Double] = NArray.tabulate[Double](N)((i: Int) => f()) + AddOneByOneTest[Double](NArrayBuilder[Double](), values, DOUBLE_ARRAY).runTests() + AddAllTest[Double](NArrayBuilder[Double](), values, DOUBLE_ARRAY).runTests() + //assertBuilderResultType[Double](values.builder[Double]().result, DOUBLE_ARRAY) + BuilderResultTypeTest[Double](DOUBLE_ARRAY).runTests() } test(" NArrayBuilder[String] ") { - AddOneByOneTest[String](NArrayBuilder[String](), () => r.nextString(1 + r.nextInt(9))).runTests() - AddAllTest[String](NArrayBuilder[String](), () => r.nextString(1 + r.nextInt(9))).runTests() + val f = () => r.nextString(1 + r.nextInt(9)) + val values: NArray[String] = NArray.tabulate[String](N)((i: Int) => f()) + AddOneByOneTest[String](NArrayBuilder[String](), values, NATIVE_ARRAY).runTests() + AddAllTest[String](NArrayBuilder[String](), values, NATIVE_ARRAY).runTests() + //assertBuilderResultType[String](values.builder[String]().result, NATIVE_ARRAY) + BuilderResultTypeTest[String](NATIVE_ARRAY).runTests() } test(" NArrayBuilder[Unit] ") { - AddOneByOneTest[Unit](NArrayBuilder[Unit](), () => ()).runTests() - AddAllTest[Unit](NArrayBuilder[Unit](), () => ()).runTests() + val f = () => () + val values: NArray[Unit] = NArray.tabulate[Unit](N)((i: Int) => f()) + AddOneByOneTest[Unit](NArrayBuilder[Unit](), values, NATIVE_ARRAY).runTests() + AddAllTest[Unit](NArrayBuilder[Unit](), values, NATIVE_ARRAY).runTests() + //assertBuilderResultType[Unit](values.builder[Unit]().result, NATIVE_ARRAY) + BuilderResultTypeTest[Unit](NATIVE_ARRAY).runTests() } - // add a stress test. + // TODO: add a stress test. } diff --git a/tests/shared/src/test/scala/CopyTest.scala b/tests/shared/src/test/scala/CopyTest.scala index 1c3fd56..a57dd28 100644 --- a/tests/shared/src/test/scala/CopyTest.scala +++ b/tests/shared/src/test/scala/CopyTest.scala @@ -34,56 +34,56 @@ class CopyTest extends munit.FunSuite { // Unit val uaTabulate: NArray[Unit] = NArray.tabulate[Unit](N)(_ => ()) - assertNArrayEquality[Unit](uaTabulate, uaTabulate.copy) - assertNArrayEquality[Unit](uaTabulate, copy(uaTabulate)) + assertNArrayEquality[Unit](uaTabulate, uaTabulate.copy, NArrayType.NATIVE_ARRAY) + assertNArrayEquality[Unit](uaTabulate, copy(uaTabulate), NArrayType.NATIVE_ARRAY) N += 1 // Boolean val boolArrTabulate: NArray[Boolean] = NArray.tabulate[Boolean](N)((i: Int) => i % 2 == 0) - assertNArrayEquality[Boolean](boolArrTabulate, boolArrTabulate.copy) - assertNArrayEquality[Boolean](boolArrTabulate, copy(boolArrTabulate)) + assertNArrayEquality[Boolean](boolArrTabulate, boolArrTabulate.copy, NArrayType.NATIVE_ARRAY) + assertNArrayEquality[Boolean](boolArrTabulate, copy(boolArrTabulate), NArrayType.NATIVE_ARRAY) N += 1 // Byte val baTabulate: NArray[Byte] = NArray.tabulate[Byte](N)((i: Int) => i.toByte) - assertNArrayEquality[Byte](baTabulate, baTabulate.copy) - assertNArrayEquality[Byte](baTabulate, copy(baTabulate)) + assertNArrayEquality[Byte](baTabulate, baTabulate.copy, NArrayType.BYTE_ARRAY) + assertNArrayEquality[Byte](baTabulate, copy(baTabulate), NArrayType.BYTE_ARRAY) N += 1 // Short val saTabulate: NArray[Short] = NArray.tabulate[Short](N)((i: Int) => i.toShort) - assertNArrayEquality[Short](saTabulate, saTabulate.copy) - assertNArrayEquality[Short](saTabulate, copy(saTabulate)) + assertNArrayEquality[Short](saTabulate, saTabulate.copy, NArrayType.SHORT_ARRAY) + assertNArrayEquality[Short](saTabulate, copy(saTabulate), NArrayType.SHORT_ARRAY) N += 1 // Int val iaTabulate: NArray[Int] = NArray.tabulate[Int](N)((i: Int) => i) - assertNArrayEquality[Int](iaTabulate, iaTabulate.copy) - assertNArrayEquality[Int](iaTabulate, copy(iaTabulate)) + assertNArrayEquality[Int](iaTabulate, iaTabulate.copy, NArrayType.INT_ARRAY) + assertNArrayEquality[Int](iaTabulate, copy(iaTabulate), NArrayType.INT_ARRAY) N += 1 // Long val laTabulate: NArray[Long] = NArray.tabulate[Long](N)((i: Int) => i.toLong) - assertNArrayEquality[Long](laTabulate, laTabulate.copy) - assertNArrayEquality[Long](laTabulate, copy(laTabulate)) + assertNArrayEquality[Long](laTabulate, laTabulate.copy, NArrayType.NATIVE_ARRAY) + assertNArrayEquality[Long](laTabulate, copy(laTabulate), NArrayType.NATIVE_ARRAY) N += 1 // Float val faTabulate: NArray[Float] = NArray.tabulate[Float](N)((i: Int) => i.toFloat) - assertNArrayEquality[Float](faTabulate, faTabulate.copy) - assertNArrayEquality[Float](faTabulate, copy(faTabulate)) + assertNArrayEquality[Float](faTabulate, faTabulate.copy, NArrayType.FLOAT_ARRAY) + assertNArrayEquality[Float](faTabulate, copy(faTabulate), NArrayType.FLOAT_ARRAY) N += 1 // Double val daTabulate: NArray[Double] = NArray.tabulate[Double](N)((i: Int) => i.toDouble) - assertNArrayEquality[Double](daTabulate, copy(daTabulate)) + assertNArrayEquality[Double](daTabulate, copy(daTabulate), NArrayType.DOUBLE_ARRAY) N += 1 // Char val caTabulate: NArray[Char] = NArray.tabulate[Char](N)((i: Int) => i.toChar) - assertNArrayEquality[Char](caTabulate, copy(caTabulate)) + assertNArrayEquality[Char](caTabulate, copy(caTabulate), NArrayType.NATIVE_ARRAY) //////////////////// // Reference Types: @@ -92,14 +92,14 @@ class CopyTest extends munit.FunSuite { N += 1 // String val strArrTabulate: NArray[String] = NArray.tabulate[String](N)((i: Int) => i.toString) - assertNArrayEquality[String](strArrTabulate, strArrTabulate.copy) - assertNArrayEquality[String](strArrTabulate, copy(strArrTabulate)) + assertNArrayEquality[String](strArrTabulate, strArrTabulate.copy, NArrayType.NATIVE_ARRAY) + assertNArrayEquality[String](strArrTabulate, copy(strArrTabulate), NArrayType.NATIVE_ARRAY) N += 1 // AnyRef val anyRefArrTabulate: NArray[AnyRef] = NArray.tabulate[AnyRef](N)(_ => new AnyRef()) - assertNArrayEquality[AnyRef](anyRefArrTabulate, anyRefArrTabulate.copy) - assertNArrayEquality[AnyRef](anyRefArrTabulate, copy(anyRefArrTabulate)) + assertNArrayEquality[AnyRef](anyRefArrTabulate, anyRefArrTabulate.copy, NArrayType.NATIVE_ARRAY) + assertNArrayEquality[AnyRef](anyRefArrTabulate, copy(anyRefArrTabulate), NArrayType.NATIVE_ARRAY) } } \ No newline at end of file diff --git a/tests/shared/src/test/scala/InstantiationTest.scala b/tests/shared/src/test/scala/InstantiationTest.scala index afd4328..391267d 100644 --- a/tests/shared/src/test/scala/InstantiationTest.scala +++ b/tests/shared/src/test/scala/InstantiationTest.scala @@ -15,131 +15,234 @@ */ import narr.* +import Util.* +import Util.NArrayType.* + +import scala.reflect.ClassTag class InstantiationTest extends munit.FunSuite { - test(" NArray constructors and factories ") { + var N: Int = 11 + + def tabulateTypeTest[T](f: (Int) => T, nt:NArrayType)(using ClassTag[T]): Unit = { + assertNArrayType(NArray.tabulate[T](N)(f), nt) + } - var N: Int = 11 + //////////////// + // Value Types: + //////////////// - //////////////// - // Value Types: - //////////////// + test(" NArray[Unit] constructors and factories ") { // Unit - val uaNew: NArray[Unit] = new NArray[Unit](N) - val uaOfSize: NArray[Unit] = NArray.ofSize[Unit](N) - val uaFill: NArray[Unit] = NArray.fill[Unit](N)(()) - val uaTabulate: NArray[Unit] = NArray.tabulate[Unit](N)(_ => ()) - assertEquals(uaNew.length, uaOfSize.length) - assertEquals(uaOfSize.length, uaFill.length) - assertEquals(uaFill.length, uaTabulate.length) - - N += 1 + val f = (_:Int) => () + val na: NArray[Unit] = new NArray[Unit](N) + val aos: NArray[Unit] = NArray.ofSize[Unit](N) + val af: NArray[Unit] = NArray.fill[Unit](N)(()) + val at: NArray[Unit] = NArray.tabulate[Unit](N)(f) + + assertNArrayType[Unit](na, NATIVE_ARRAY) + assertNArrayType[Unit](aos, NATIVE_ARRAY) + assertNArrayType[Unit](af, NATIVE_ARRAY) + assertNArrayType[Unit](at, NATIVE_ARRAY) + tabulateTypeTest[Unit](f, NATIVE_ARRAY) + + assertEquals(na.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + + test(" NArray[Boolean] constructors and factories ") { + val f = (i: Int) => i % 2 == 0 // Boolean - val boolArrNew: NArray[Boolean] = new NArray[Boolean](N) - val boolArrOfSize: NArray[Boolean] = NArray.ofSize[Boolean](N) - val boolArrFill: NArray[Boolean] = NArray.fill[Boolean](N)(false) - val boolArrTabulate: NArray[Boolean] = NArray.tabulate[Boolean](N)((i: Int) => i % 2 == 0) - assertEquals(boolArrNew.length, boolArrOfSize.length) - assertEquals(boolArrOfSize.length, boolArrFill.length) - assertEquals(boolArrFill.length, boolArrTabulate.length) - - N += 1 + val an: NArray[Boolean] = new NArray[Boolean](N) + val aos: NArray[Boolean] = NArray.ofSize[Boolean](N) + val af: NArray[Boolean] = NArray.fill[Boolean](N)(false) + val at: NArray[Boolean] = NArray.tabulate[Boolean](N)(f) + + assertNArrayType[Boolean](an, NATIVE_ARRAY) + assertNArrayType[Boolean](aos, NATIVE_ARRAY) + assertNArrayType[Boolean](af, NATIVE_ARRAY) + assertNArrayType[Boolean](at, NATIVE_ARRAY) + tabulateTypeTest[Boolean](f, NATIVE_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + + test(" NArray[Byte] constructors and factories ") { + val f = (i: Int) => i.toByte // Byte - val baNew: NArray[Byte] = new NArray[Byte](N) - val baOfSize: NArray[Byte] = NArray.ofSize[Byte](N) - val baFill: NArray[Byte] = NArray.fill[Byte](N)(1) - val baTabulate: NArray[Byte] = NArray.tabulate[Byte](N)((i: Int) => i.toByte) - assertEquals(baNew.length, baOfSize.length) - assertEquals(baOfSize.length, baFill.length) - assertEquals(baFill.length, baTabulate.length) - - N += 1 + val an: NArray[Byte] = new NArray[Byte](N) + val aos: NArray[Byte] = NArray.ofSize[Byte](N) + val af: NArray[Byte] = NArray.fill[Byte](N)(1) + val at: NArray[Byte] = NArray.tabulate[Byte](N)(f) + + assertNArrayType[Byte](an, BYTE_ARRAY) + assertNArrayType[Byte](aos, BYTE_ARRAY) + assertNArrayType[Byte](af, BYTE_ARRAY) + assertNArrayType[Byte](at, BYTE_ARRAY) + tabulateTypeTest[Byte](f, BYTE_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + + test(" NArray[Short] constructors and factories ") { + val f = (i: Int) => i.toShort // Short - val saNew: NArray[Short] = new NArray[Short](N) - val saOfSize: NArray[Short] = NArray.ofSize[Short](N) - val saFill: NArray[Short] = NArray.fill[Short](N)(1) - val saTabulate: NArray[Short] = NArray.tabulate[Short](N)((i: Int) => i.toShort) - assertEquals(saNew.length, saOfSize.length) - assertEquals(saOfSize.length, saFill.length) - assertEquals(saFill.length, saTabulate.length) - - N += 1 + val an: NArray[Short] = new NArray[Short](N) + val aos: NArray[Short] = NArray.ofSize[Short](N) + val af: NArray[Short] = NArray.fill[Short](N)(1) + val at: NArray[Short] = NArray.tabulate[Short](N)(f) + + assertNArrayType[Short](an, SHORT_ARRAY) + assertNArrayType[Short](aos, SHORT_ARRAY) + assertNArrayType[Short](af, SHORT_ARRAY) + assertNArrayType[Short](at, SHORT_ARRAY) + tabulateTypeTest[Short](f, SHORT_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + + test(" NArray[Int] constructors and factories ") { + val f = (i: Int) => i // Int - val iaNew: NArray[Int] = new NArray[Int](N) - val iaOfSize: NArray[Int] = NArray.ofSize[Int](N) - val iaFill: NArray[Int] = NArray.fill[Int](N)(1) - val iaTabulate: NArray[Int] = NArray.tabulate[Int](N)((i: Int) => i) - assertEquals(iaNew.length, iaOfSize.length) - assertEquals(iaOfSize.length, iaFill.length) - assertEquals(iaFill.length, iaTabulate.length) - - N += 1 + val an: NArray[Int] = new NArray[Int](N) + val aos: NArray[Int] = NArray.ofSize[Int](N) + val af: NArray[Int] = NArray.fill[Int](N)(1) + val at: NArray[Int] = NArray.tabulate[Int](N)(f) + + assertNArrayType[Int](an, INT_ARRAY) + assertNArrayType[Int](aos, INT_ARRAY) + assertNArrayType[Int](af, INT_ARRAY) + assertNArrayType[Int](at, INT_ARRAY) + tabulateTypeTest[Int](f, INT_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + + test(" NArray[Long] constructors and factories ") { + val f = (i: Int) => i.toLong // Long - val laNew: NArray[Long] = new NArray[Long](N) - val laOfSize: NArray[Long] = NArray.ofSize[Long](N) - val laFill: NArray[Long] = NArray.fill[Long](N)(1L) - val laTabulate: NArray[Long] = NArray.tabulate[Long](N)((i: Int) => i.toLong) - assertEquals(laNew.length, laOfSize.length) - assertEquals(laOfSize.length, laFill.length) - assertEquals(laFill.length, laTabulate.length) - - N += 1 + val an: NArray[Long] = new NArray[Long](N) + val aos: NArray[Long] = NArray.ofSize[Long](N) + val af: NArray[Long] = NArray.fill[Long](N)(1L) + val at: NArray[Long] = NArray.tabulate[Long](N)(f) + + assertNArrayType[Long](an, NATIVE_ARRAY) + assertNArrayType[Long](aos, NATIVE_ARRAY) + assertNArrayType[Long](af, NATIVE_ARRAY) + assertNArrayType[Long](at, NATIVE_ARRAY) + tabulateTypeTest[Long](f, NATIVE_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + + test(" NArray[Float] constructors and factories ") { + val f = (i: Int) => i.toFloat // Float - val faNew: NArray[Float] = new NArray[Float](N) - val faOfSize: NArray[Float] = NArray.ofSize[Float](N) - val faFill: NArray[Float] = NArray.fill[Float](N)(1L) - val faTabulate: NArray[Float] = NArray.tabulate[Float](N)((i: Int) => i.toFloat) - assertEquals(faNew.length, faOfSize.length) - assertEquals(faOfSize.length, faFill.length) - assertEquals(faFill.length, faTabulate.length) - - N += 1 + val an: NArray[Float] = new NArray[Float](N) + val aos: NArray[Float] = NArray.ofSize[Float](N) + val af: NArray[Float] = NArray.fill[Float](N)(1L) + val at: NArray[Float] = NArray.tabulate[Float](N)(f) + + assertNArrayType[Float](an, FLOAT_ARRAY) + assertNArrayType[Float](aos, FLOAT_ARRAY) + assertNArrayType[Float](af, FLOAT_ARRAY) + assertNArrayType[Float](at, FLOAT_ARRAY) + tabulateTypeTest[Float](f, FLOAT_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + + test(" NArray[Double] constructors and factories ") { + val f = (i: Int) => i.toDouble // Double - val daNew: NArray[Double] = new NArray[Double](N) - val daOfSize: NArray[Double] = NArray.ofSize[Double](N) - val daFill: NArray[Double] = NArray.fill[Double](N)(1L) - val daTabulate: NArray[Double] = NArray.tabulate[Double](N)((i: Int) => i.toDouble) - assertEquals(daNew.length, daOfSize.length) - assertEquals(daOfSize.length, daFill.length) - assertEquals(daFill.length, daTabulate.length) - - N += 1 - // Char - val caNew: NArray[Char] = new NArray[Char](N) - val caOfSize: NArray[Char] = NArray.ofSize[Char](N) - val caFill: NArray[Char] = NArray.fill[Char](N)('a') - val caTabulate: NArray[Char] = NArray.tabulate[Char](N)((i: Int) => i.toChar) - assertEquals(caNew.length, caOfSize.length) - assertEquals(caOfSize.length, caFill.length) - assertEquals(caFill.length, caTabulate.length) + val an: NArray[Double] = new NArray[Double](N) + val aos: NArray[Double] = NArray.ofSize[Double](N) + val af: NArray[Double] = NArray.fill[Double](N)(1L) + val at: NArray[Double] = NArray.tabulate[Double](N)(f) + + assertNArrayType[Double](an, DOUBLE_ARRAY) + assertNArrayType[Double](aos, DOUBLE_ARRAY) + assertNArrayType[Double](af, DOUBLE_ARRAY) + assertNArrayType[Double](at, DOUBLE_ARRAY) + tabulateTypeTest[Double](f, DOUBLE_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + test(" NArray[Char] constructors and factories ") { + val f = (i: Int) => i.toChar + // Char + val an: NArray[Char] = new NArray[Char](N) + val aos: NArray[Char] = NArray.ofSize[Char](N) + val af: NArray[Char] = NArray.fill[Char](N)('a') + val at: NArray[Char] = NArray.tabulate[Char](N)(f) + + assertNArrayType[Char](an, NATIVE_ARRAY) + assertNArrayType[Char](aos, NATIVE_ARRAY) + assertNArrayType[Char](af, NATIVE_ARRAY) + assertNArrayType[Char](at, NATIVE_ARRAY) + tabulateTypeTest[Char](f, NATIVE_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } - //////////////////// - // Reference Types: - //////////////////// + //////////////////// + // Reference Types: + //////////////////// - N += 1 + test(" NArray[String] constructors and factories ") { + val f = (i: Int) => i.toString // String - val strArrNew: NArray[String] = new NArray[String](N) - val strArrOfSize: NArray[String] = NArray.ofSize[String](N) - val strArrFill: NArray[String] = NArray.fill[String](N)("Asdf.") - val strArrTabulate: NArray[String] = NArray.tabulate[String](N)((i: Int) => i.toString) - assertEquals(strArrNew.length, strArrOfSize.length) - assertEquals(strArrOfSize.length, strArrFill.length) - assertEquals(strArrFill.length, strArrTabulate.length) - - N += 1 - // AnyRef - val anyRefArrNew: NArray[AnyRef] = new NArray[AnyRef](N) - val anyRefArrOfSize: NArray[AnyRef] = NArray.ofSize[AnyRef](N) - val anyRefArrFill: NArray[AnyRef] = NArray.fill[AnyRef](N)(new AnyRef()) - val anyRefArrTabulate: NArray[AnyRef] = NArray.tabulate[AnyRef](N)(_ => new AnyRef()) - assertEquals(anyRefArrNew.length, anyRefArrOfSize.length) - assertEquals(anyRefArrOfSize.length, anyRefArrFill.length) - assertEquals(anyRefArrFill.length, anyRefArrTabulate.length) - + val an: NArray[String] = new NArray[String](N) + val aos: NArray[String] = NArray.ofSize[String](N) + val af: NArray[String] = NArray.fill[String](N)("Asdf.") + val at: NArray[String] = NArray.tabulate[String](N)(f) + + assertNArrayType[String](an, NATIVE_ARRAY) + assertNArrayType[String](aos, NATIVE_ARRAY) + assertNArrayType[String](af, NATIVE_ARRAY) + assertNArrayType[String](at, NATIVE_ARRAY) + tabulateTypeTest[String](f, NATIVE_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) + } + test(" NArray[AnyRef] constructors and factories ") { + val f = (_:Int) => new AnyRef() + // AnyRef + val an: NArray[AnyRef] = new NArray[AnyRef](N) + val aos: NArray[AnyRef] = NArray.ofSize[AnyRef](N) + val af: NArray[AnyRef] = NArray.fill[AnyRef](N)(new AnyRef()) + val at: NArray[AnyRef] = NArray.tabulate[AnyRef](N)(f) + + assertNArrayType[AnyRef](an, NATIVE_ARRAY) + assertNArrayType[AnyRef](aos, NATIVE_ARRAY) + assertNArrayType[AnyRef](af, NATIVE_ARRAY) + assertNArrayType[AnyRef](at, NATIVE_ARRAY) + tabulateTypeTest[AnyRef](f, NATIVE_ARRAY) + + assertEquals(an.length, aos.length) + assertEquals(aos.length, af.length) + assertEquals(af.length, at.length) } } diff --git a/tests/shared/src/test/scala/NArrayOpsTest.scala b/tests/shared/src/test/scala/NArrayOpsTest.scala index 98a8312..a7de459 100644 --- a/tests/shared/src/test/scala/NArrayOpsTest.scala +++ b/tests/shared/src/test/scala/NArrayOpsTest.scala @@ -16,6 +16,7 @@ import narr.* import Util.* +import Util.NArrayType.* import scala.reflect.ClassTag import scala.util.Random as r @@ -27,6 +28,7 @@ class NArrayOpsTest extends munit.FunSuite { private trait HasNArray[T:ClassTag] { val a: NArray[T] + val nt: NArrayType } private trait UniversalNArrayOpsTest[T:ClassTag] extends HasNArray[T] { @@ -58,21 +60,28 @@ class NArrayOpsTest extends munit.FunSuite { val start:Int = middleIndex - r.nextInt(middleIndex - 1) val end:Int = middleIndex + r.nextInt(middleIndex - 1) + val sliced = a.slice(start, end) + assertNArrayType(sliced, nt) + val tabulated = NArray.tabulate[T](end - start)((i:Int) => a(start + i)) + assertNArrayType(tabulated, nt) assertNArrayEquality[T]( - a.slice(start, end), - NArray.tabulate[T](end - start)((i:Int) => a(start + i)) + sliced, + tabulated, + nt ) // tail assertNArrayEquality[T]( a.tail, - NArray.tabulate[T](lastIndex)((i: Int) => a(1 + i)) + NArray.tabulate[T](lastIndex)((i: Int) => a(1 + i)), + nt ) // init assertNArrayEquality[T]( a.init, - NArray.tabulate[T](lastIndex)((i: Int) => a(i)) + NArray.tabulate[T](lastIndex)((i: Int) => a(i)), + nt ) // reverse @@ -100,27 +109,29 @@ class NArrayOpsTest extends munit.FunSuite { val rArr: Array[T] = right.toArray[T] // take - assertNArrayEquality[T]( a.take(fulcrum), left ) + assertNArrayEquality[T]( a.take(fulcrum), left, nt) // drop - assertNArrayEquality[T]( a.drop(fulcrum), right ) + assertNArrayEquality[T]( a.drop(fulcrum), right, nt ) // takeRight assertNArrayEquality[T]( a.takeRight(fulcrum), - NArray.tabulate[T](fulcrum)((i: Int) => a(N - fulcrum + i)) + NArray.tabulate[T](fulcrum)((i: Int) => a(N - fulcrum + i)), + nt ) // dropRight assertNArrayEquality[T]( a.dropRight(fulcrum), - NArray.tabulate[T](N - fulcrum)((i: Int) => a(i)) + NArray.tabulate[T](N - fulcrum)((i: Int) => a(i)), + nt ) // splitAt val (s1:NArray[T], s2:NArray[T]) = a.splitAt(fulcrum) - assertNArrayEquality[T](s1, left) - assertNArrayEquality[T](s2, right) + assertNArrayEquality[T](s1, left, nt) + assertNArrayEquality[T](s2, right, nt) // appended assertArray2NArrayEquality[T](lArr.appended(arr(0)), left.appended(a(0))) @@ -130,16 +141,16 @@ class NArrayOpsTest extends munit.FunSuite { // Doesn't work for Unit. https://github.com/scala/bug/issues/13068 if (a(0) != ()) { // prependedAll - assertNArrayEquality[T](right.prependedAll[T](left), a) - assertNArrayEquality[T](right.prependedAll[T](left.toSeq), a) + assertNArrayEquality[T](right.prependedAll[T](left), a, nt) + assertNArrayEquality[T](right.prependedAll[T](left.toSeq), a, nt) // appendedAll - assertNArrayEquality[T](left.appendedAll[T](right), a) - assertNArrayEquality[T](left.appendedAll[T](right.toSeq), a) + assertNArrayEquality[T](left.appendedAll[T](right), a, nt) + assertNArrayEquality[T](left.appendedAll[T](right.toSeq), a, nt) // concat, toSeq, toIndexedSeq - assertNArrayEquality[T](left.concat[T](right), a) - assertNArrayEquality[T](left.concat[T](right.toSeq), a) + assertNArrayEquality[T](left.concat[T](right), a, nt) + assertNArrayEquality[T](left.concat[T](right.toSeq), a, nt) } // find @@ -154,6 +165,12 @@ class NArrayOpsTest extends munit.FunSuite { // contains assertEquals(true, a.contains(a(fulcrum))) + // patch + assertArray2NArrayEquality( + arr.patch[T](0, rArr.toSeq, rArr.length), + a.patch[T](0, right.toSeq, right.length) + ) + // startsWith assertEquals(a.startsWith(left), true) assertEquals(a.startsWith(right, fulcrum), true) @@ -239,7 +256,7 @@ class NArrayOpsTest extends munit.FunSuite { val group: NArray[T] = gi.next() val t = a.slice(i, i + groupSize) assertEquals(t.length, group.length) - assertNArrayEquality[T](group, t) + assertNArrayEquality[T](group, t, nt) i += groupSize } @@ -277,19 +294,21 @@ class NArrayOpsTest extends munit.FunSuite { // takeWhile assertNArrayEquality[T]( a.takeWhile((t: T) => t != a(fulcrum)), - left + left, + nt ) // dropWhile assertNArrayEquality[T]( a.dropWhile((t: T) => t != a(fulcrum)), - right + right, + nt ) val (spanLeft, spanRight) = a.span((t: T) => t != a(fulcrum)) // span - assertNArrayEquality[T](spanLeft, left) - assertNArrayEquality[T](spanRight, right) + assertNArrayEquality[T](spanLeft, left, nt) + assertNArrayEquality[T](spanRight, right, nt) // lastIndexWhere assertEquals( @@ -319,11 +338,11 @@ class NArrayOpsTest extends munit.FunSuite { } - private case class NArrayWithDuplicateElementsOpsTest[T:ClassTag](override val a:NArray[T]) extends UniversalNArrayOpsTest[T] { + private case class NArrayWithDuplicateElementsOpsTest[T:ClassTag](override val a:NArray[T], override val nt:NArrayType) extends UniversalNArrayOpsTest[T] { def test():Unit = universalTest() } - private case class NArrayOfUniquelyValuedElementsOpsTest[T:ClassTag](override val a:NArray[T]) extends UniversalNArrayOpsTest[T] with NArrayOpsSearchTest[T] { + private case class NArrayOfUniquelyValuedElementsOpsTest[T:ClassTag](override val a:NArray[T], override val nt:NArrayType) extends UniversalNArrayOpsTest[T] with NArrayOpsSearchTest[T] { def test(): Unit = { universalTest() searchTest() @@ -331,7 +350,7 @@ class NArrayOpsTest extends munit.FunSuite { } - private case class NArraySelfMapOpsTest[T:ClassTag](override val a:NArray[T], selfMap: T => T) extends HasNArray[T] { + private case class NArraySelfMapOpsTest[T:ClassTag](override val a:NArray[T], override val nt:NArrayType, selfMap: T => T) extends HasNArray[T] { def test(): Unit = { // mapInPlace @@ -345,18 +364,19 @@ class NArrayOpsTest extends munit.FunSuite { } } + //////////////// // Value Types: //////////////// test("NArrayWithDuplicateElementsOpsTest[Unit]") { - NArrayWithDuplicateElementsOpsTest[Unit](NArray.tabulate[Unit](N)(_ => ())).test() + NArrayWithDuplicateElementsOpsTest[Unit](NArray.tabulate[Unit](N)(_ => ()), NATIVE_ARRAY).test() } test("NArrayWithDuplicateElementsOpsTest[Boolean]") { val a1: NArray[Boolean] = NArray.tabulate[Boolean](N)((i: Int) => i % 2 == 0) - val t1 = NArrayWithDuplicateElementsOpsTest[Boolean](a1) + val t1 = NArrayWithDuplicateElementsOpsTest[Boolean](a1, NATIVE_ARRAY) t1.test() - NArraySelfMapOpsTest[Boolean](t1.a, (b: Boolean) => !b).test() + NArraySelfMapOpsTest[Boolean](t1.a, NATIVE_ARRAY, (b: Boolean) => !b).test() // partition val (t:NArray[Boolean], f:NArray[Boolean]) = a1.partition((b:Boolean) => b) @@ -365,39 +385,39 @@ class NArrayOpsTest extends munit.FunSuite { } test("NArrayOfUniquelyValuedElementsOpsTest[Byte]") { - val t1 = NArrayOfUniquelyValuedElementsOpsTest[Byte](NArray.tabulate[Byte](N)((i:Int) => i.toByte)) + val t1 = NArrayOfUniquelyValuedElementsOpsTest[Byte](NArray.tabulate[Byte](N)((i:Int) => i.toByte), BYTE_ARRAY) t1.test() - NArraySelfMapOpsTest[Byte](t1.a, (b: Byte) => (-b).toByte).test() + NArraySelfMapOpsTest[Byte](t1.a, BYTE_ARRAY, (b: Byte) => (-b).toByte).test() } test("NArrayOfUniquelyValuedElementsOpsTest[Short]") { - val t1 = NArrayOfUniquelyValuedElementsOpsTest[Short](NArray.tabulate[Short](N)((i: Int) => i.toShort)) + val t1 = NArrayOfUniquelyValuedElementsOpsTest[Short](NArray.tabulate[Short](N)((i: Int) => i.toShort), SHORT_ARRAY) t1.test() - NArraySelfMapOpsTest[Short](t1.a, (s: Short) => (-s).toShort).test() + NArraySelfMapOpsTest[Short](t1.a, SHORT_ARRAY, (s: Short) => (-s).toShort).test() } test("NArrayOfUniquelyValuedElementsOpsTest[Int]") { - val t1 = NArrayOfUniquelyValuedElementsOpsTest[Int](NArray.tabulate[Int](N)((i: Int) => i)) + val t1 = NArrayOfUniquelyValuedElementsOpsTest[Int](NArray.tabulate[Int](N)((i: Int) => i), INT_ARRAY) t1.test() - NArraySelfMapOpsTest[Int](t1.a, (i: Int) => -i).test() + NArraySelfMapOpsTest[Int](t1.a, INT_ARRAY, (i: Int) => -i).test() } test("NArrayOfUniquelyValuedElementsOpsTest[Long]") { - val t1 = NArrayOfUniquelyValuedElementsOpsTest[Long](NArray.tabulate[Long](N)((i: Int) => i.toLong)) + val t1 = NArrayOfUniquelyValuedElementsOpsTest[Long](NArray.tabulate[Long](N)((i: Int) => i.toLong), NATIVE_ARRAY) t1.test() - NArraySelfMapOpsTest[Long](t1.a, (l: Long) => -l).test() + NArraySelfMapOpsTest[Long](t1.a, NATIVE_ARRAY, (l: Long) => -l).test() } test("NArrayOfUniquelyValuedElementsOpsTest[Float]") { - val t1 = NArrayOfUniquelyValuedElementsOpsTest[Float](NArray.tabulate[Float](N)((i: Int) => i.toFloat)) + val t1 = NArrayOfUniquelyValuedElementsOpsTest[Float](NArray.tabulate[Float](N)((i: Int) => i.toFloat), FLOAT_ARRAY) t1.test() - NArraySelfMapOpsTest[Float](t1.a, (f: Float) => -f).test() + NArraySelfMapOpsTest[Float](t1.a, FLOAT_ARRAY, (f: Float) => -f).test() } test("NArrayOfUniquelyValuedElementsOpsTest[Double]") { - val t1 = NArrayOfUniquelyValuedElementsOpsTest[Double](NArray.tabulate[Double](N)((i: Int) => i.toDouble)) + val t1 = NArrayOfUniquelyValuedElementsOpsTest[Double](NArray.tabulate[Double](N)((i: Int) => i.toDouble), DOUBLE_ARRAY) t1.test() - NArraySelfMapOpsTest[Double](t1.a, (d: Double) => -d).test() + NArraySelfMapOpsTest[Double](t1.a, DOUBLE_ARRAY, (d: Double) => -d).test() } test("NArrayOfUniquelyValuedElementsOpsTest[Char]") { - val t1 = NArrayOfUniquelyValuedElementsOpsTest[Char](NArray.tabulate[Char](N)((i: Int) => ('a'.toInt + i).toChar)) + val t1 = NArrayOfUniquelyValuedElementsOpsTest[Char](NArray.tabulate[Char](N)((i: Int) => ('a'.toInt + i).toChar), NATIVE_ARRAY) t1.test() - NArraySelfMapOpsTest[Char](t1.a, (c: Char) => (c.toInt + 1).toChar).test() + NArraySelfMapOpsTest[Char](t1.a, NATIVE_ARRAY, (c: Char) => (c.toInt + 1).toChar).test() } //////////////////// @@ -405,10 +425,10 @@ class NArrayOpsTest extends munit.FunSuite { //////////////////// test("NArrayOfUniquelyValuedElementsOpsTest[String]") { - val t1 = NArrayOfUniquelyValuedElementsOpsTest[String](NArray.tabulate[String](N)((i: Int) => i.toString)) + val t1 = NArrayOfUniquelyValuedElementsOpsTest[String](NArray.tabulate[String](N)((i: Int) => i.toString), NATIVE_ARRAY) t1.test() - NArraySelfMapOpsTest[String](t1.a, (s: String) => s.reverse).test() + NArraySelfMapOpsTest[String](t1.a, NATIVE_ARRAY, (s: String) => s.reverse).test() } - test("NArrayOfUniquelyValuedElementsOpsTest[AnyRef]") { NArrayWithDuplicateElementsOpsTest[AnyRef](NArray.tabulate[AnyRef](N)(_ => new AnyRef())).test() } + test("NArrayOfUniquelyValuedElementsOpsTest[AnyRef]") { NArrayWithDuplicateElementsOpsTest[AnyRef](NArray.tabulate[AnyRef](N)(_ => new AnyRef()), NATIVE_ARRAY).test() } } \ No newline at end of file diff --git a/tests/shared/src/test/scala/UnzipTest.scala b/tests/shared/src/test/scala/UnzipTest.scala new file mode 100644 index 0000000..7e3c792 --- /dev/null +++ b/tests/shared/src/test/scala/UnzipTest.scala @@ -0,0 +1,79 @@ +import Util.* +import Util.NArrayType.* +import narr.* + +import scala.reflect.ClassTag + +class UnzipTest extends munit.FunSuite { + + val N:Int = 11 + + private case class Unzip[T, A1, A2]( + a: NArray[T], f: Function1[T, (A1, A2)], + ntA1: NArrayType, ntA2: NArrayType + )(using ClassTag[T], ClassTag[A1], ClassTag[A2]) { + + given asPair: Function1[T, (A1, A2)] = f + + def test():Unit = { + val (a1, a2) = a.unzip[A1, A2] + assertEquals(a1.length, a2.length) + assertNArrayType[A1](a1, ntA1) + assertNArrayType[A2](a2, ntA2) + + // compare to scala array unzip + val arr: Array[T] = a.toArray[T] + val (sa1, sa2) = arr.unzip + assertArray2NArrayEquality[A1](sa1, a1) + assertArray2NArrayEquality[A2](sa2, a2) + } + } + + // direct + test("Unzip Directly NArray[Double] ") { + val arr: NArray[Double] = NArray.tabulate[Double](N)((i: Int) => i / Math.PI) + given asPair:Function1[Double, (Double, Double)] = (d:Double) => (-d, d) + val (a1, a2) = arr.unzip + assertEquals(a1.length, a2.length) + assertNArrayType[Double](a1, DOUBLE_ARRAY) + assertNArrayType[Double](a2, DOUBLE_ARRAY) + var i = 0 + while (i < arr.length) { + assertEquals(-a1(i), a2(i)) + i = i + 1 + } + } + + // indirect + test("UnzipTest[Byte => (Int, Int)]") { + Unzip[Byte, Int, Int]( + NArray.tabulate[Byte](N)((i: Int) => i.toByte), + (i:Byte) => (-i.toInt, i.toInt), + INT_ARRAY, INT_ARRAY + ).test() + } + + test("UnzipTest[Int => (Int, Int)]") { + Unzip[Int, Int, Int]( + NArray.tabulate[Int](N)((i: Int) => i), + (i:Int) => (-i, i), + INT_ARRAY, INT_ARRAY + ).test() + } + + test("UnzipTest[Int => (Double, String)]") { + Unzip[Int, Double, String]( + NArray.tabulate[Int](N)((i: Int) => i), + (i:Int) => (i.toDouble/3.0, i.toString), + DOUBLE_ARRAY, NATIVE_ARRAY + ).test() + } + + test("UnzipTest[String]") { + Unzip[String, String, String]( + NArray.tabulate[String](N)((i: Int) => i.toString), + (s: String) => (s.reverse, s), + NATIVE_ARRAY, NATIVE_ARRAY + ).test() + } +} diff --git a/tests/shared/src/test/scala/Util.scala b/tests/shared/src/test/scala/Util.scala index 6023623..becb452 100644 --- a/tests/shared/src/test/scala/Util.scala +++ b/tests/shared/src/test/scala/Util.scala @@ -21,8 +21,32 @@ object Util { import munit.* import munit.Assertions.* - def assertNArrayEquality[T](nArr1: NArray[T], nArr2: NArray[T])(using loc: Location, compare: Compare[T, T]): Unit = { + enum NArrayType: + case BYTE_ARRAY, SHORT_ARRAY, INT_ARRAY, FLOAT_ARRAY, DOUBLE_ARRAY, NATIVE_ARRAY + import NArrayType.* + + def getNArrayType[T](narr: NArray[T]): NArrayType = { + narr match { + case _: ByteArray => BYTE_ARRAY + case _: ShortArray => SHORT_ARRAY + case _: IntArray => INT_ARRAY + case _: FloatArray => FLOAT_ARRAY + case _: DoubleArray => DOUBLE_ARRAY + case _: NativeArray[?] => NATIVE_ARRAY + } + } + + def assertNArrayType[T](narr: NArray[T], expectedNArrType: NArrayType)(using loc: Location, compare: Compare[NArrayType, NArrayType]): Unit = { + assertEquals[NArrayType, NArrayType]( + expectedNArrType, + getNArrayType(narr) + ) + } + + def assertNArrayEquality[T](nArr1: NArray[T], nArr2: NArray[T], nt:NArrayType)(using loc: Location, compare: Compare[T, T]): Unit = { assertEquals(nArr1.length, nArr2.length) + assertEquals[NArrayType, NArrayType](getNArrayType[T](nArr1), nt) + assertEquals[NArrayType, NArrayType](getNArrayType[T](nArr2), nt) var i: Int = 0 while (i < nArr1.length) { assertEquals(nArr1(i), nArr2(i)) @@ -30,11 +54,12 @@ object Util { } } - def assertArray2NArrayEquality[T](arr1: Array[T], nArr2: NArray[T])(using loc: Location, compare: Compare[T, T]): Unit = { - assertEquals(arr1.length, nArr2.length) + def assertArray2NArrayEquality[T](arr: Array[T], nArr: NArray[T])(using loc: Location, compare: Compare[T, T]): Unit = { + assertEquals(arr.length, nArr.length) var i: Int = 0 - while (i < arr1.length) { - assertEquals(arr1(i), nArr2(i)) + while (i < arr.length) { + val comparison:Boolean = arr(i) == nArr(i) + assertEquals(comparison, true) i += 1 } }