|
1 | 1 | package io.estatico.newtype.macros |
2 | 2 |
|
| 3 | +import io.estatico.newtype.NewTypeArray |
3 | 4 | import org.scalatest.{FlatSpec, Matchers} |
4 | 5 | import io.estatico.newtype.ops._ |
5 | 6 | import org.scalacheck.Arbitrary |
| 7 | +import org.scalatest.exceptions.TestFailedException |
| 8 | +import scala.reflect.runtime.universe.WeakTypeTag |
6 | 9 |
|
7 | 10 | class NewTypeMacrosTest extends FlatSpec with Matchers { |
8 | 11 |
|
@@ -39,9 +42,7 @@ class NewTypeMacrosTest extends FlatSpec with Matchers { |
39 | 42 |
|
40 | 43 | it should "work in arrays" in { |
41 | 44 | val foo = Foo(313) |
42 | | - // See https://github.com/estatico/scala-newtype/issues/25 |
43 | | - // Array(foo).apply(0) shouldBe foo |
44 | | - Array[Int](313).asInstanceOf[Array[Foo]].apply(0) shouldBe foo |
| 45 | + NewTypeArray(foo).apply(0) shouldBe foo |
45 | 46 | } |
46 | 47 |
|
47 | 48 | behavior of "@newtype class" |
@@ -102,9 +103,7 @@ class NewTypeMacrosTest extends FlatSpec with Matchers { |
102 | 103 | import scala.collection.immutable.Set |
103 | 104 | val repr = Set(Option("newtypes")) |
104 | 105 | val ot = OptionT(repr) |
105 | | - // See https://github.com/estatico/scala-newtype/issues/25 |
106 | | - // Array(ot).apply(0) shouldBe ot |
107 | | - Array(repr).asInstanceOf[Array[OptionT[Set, String]]].apply(0) shouldBe ot |
| 106 | + Array(repr).coerce[Array[OptionT[Set, String]]].apply(0) shouldBe ot |
108 | 107 | } |
109 | 108 |
|
110 | 109 | behavior of "@newtype with type bounds" |
@@ -363,6 +362,200 @@ class NewTypeMacrosTest extends FlatSpec with Matchers { |
363 | 362 | assertTypeError(""" 1 match { case Y1(x) => x }""") |
364 | 363 | } |
365 | 364 |
|
| 365 | + behavior of "NewTypeArray" |
| 366 | + |
| 367 | + it should "work with @newtype X(Int)" in { |
| 368 | + @newtype case class X(private val value: Int) |
| 369 | + |
| 370 | + val cls = scala.Predef.classOf[Array[Int]] |
| 371 | + val v: Int = 1 |
| 372 | + |
| 373 | + val a = NewTypeArray(X(v)) |
| 374 | + assertCompiles("a: Array[X]") |
| 375 | + a.apply(0) shouldBe v |
| 376 | + a.getClass shouldBe cls |
| 377 | + |
| 378 | + val a2 = NewTypeArray[X].downcast(a) |
| 379 | + assertCompiles("a2: Array[Int]") |
| 380 | + a2.apply(0) shouldBe v |
| 381 | + a2.getClass shouldBe cls |
| 382 | + |
| 383 | + val a3 = NewTypeArray[X].upcast(a2) |
| 384 | + assertCompiles("a3: Array[X]") |
| 385 | + a3.apply(0) shouldBe v |
| 386 | + a3.getClass shouldBe cls |
| 387 | + |
| 388 | + val a4 = a.coerce[Array[Int]] |
| 389 | + assertCompiles("a4: Array[Int]") |
| 390 | + a4.apply(0) shouldBe v |
| 391 | + a4.getClass shouldBe cls |
| 392 | + |
| 393 | + val a5 = a4.coerce[Array[X]] |
| 394 | + assertCompiles("a5: Array[X]") |
| 395 | + a5.apply(0) shouldBe v |
| 396 | + a5.getClass shouldBe cls |
| 397 | + } |
| 398 | + |
| 399 | + it should "work with @newsubtype X(Int)" in { |
| 400 | + @newsubtype case class X(private val value: Int) |
| 401 | + |
| 402 | + val cls = scala.Predef.classOf[Array[Int]] |
| 403 | + val v: Int = 1 |
| 404 | + |
| 405 | + val a = NewTypeArray(X(v)) |
| 406 | + assertCompiles("a: Array[X]") |
| 407 | + a.apply(0) shouldBe v |
| 408 | + a.getClass shouldBe cls |
| 409 | + |
| 410 | + val a2 = NewTypeArray[X].downcast(a) |
| 411 | + assertCompiles("a2: Array[Int]") |
| 412 | + a2.apply(0) shouldBe v |
| 413 | + a2.getClass shouldBe cls |
| 414 | + |
| 415 | + val a3 = NewTypeArray[X].upcast(a2) |
| 416 | + assertCompiles("a3: Array[X]") |
| 417 | + a3.apply(0) shouldBe v |
| 418 | + a3.getClass shouldBe cls |
| 419 | + |
| 420 | + val a4 = a.coerce[Array[Int]] |
| 421 | + assertCompiles("a4: Array[Int]") |
| 422 | + a4.apply(0) shouldBe v |
| 423 | + a4.getClass shouldBe cls |
| 424 | + |
| 425 | + val a5 = a4.coerce[Array[X]] |
| 426 | + assertCompiles("a5: Array[X]") |
| 427 | + a5.apply(0) shouldBe v |
| 428 | + a5.getClass shouldBe cls |
| 429 | + } |
| 430 | + |
| 431 | + it should "work with @newtype X[A](List[A])" in { |
| 432 | + @newtype case class X[A](private val value: List[A]) |
| 433 | + |
| 434 | + val cls = scala.Predef.classOf[Array[List[Int]]] |
| 435 | + val v: List[Int] = List(1) |
| 436 | + |
| 437 | + val a = NewTypeArray(X(v)) |
| 438 | + assertCompiles("a: Array[X[Int]]") |
| 439 | + a.apply(0) shouldBe v |
| 440 | + a.getClass shouldBe cls |
| 441 | + |
| 442 | + val a2 = NewTypeArray[X[Int]].downcast(a) |
| 443 | + assertCompiles("a2: Array[List[Int]]") |
| 444 | + a2.apply(0) shouldBe v |
| 445 | + a2.getClass shouldBe cls |
| 446 | + |
| 447 | + val a3 = NewTypeArray[X[Int]].upcast(a2) |
| 448 | + assertCompiles("a3: Array[X[Int]]") |
| 449 | + a3.apply(0) shouldBe v |
| 450 | + a3.getClass shouldBe cls |
| 451 | + |
| 452 | + val a4 = a.coerce[Array[List[Int]]] |
| 453 | + assertCompiles("a4: Array[List[Int]]") |
| 454 | + a4.apply(0) shouldBe v |
| 455 | + a4.getClass shouldBe cls |
| 456 | + |
| 457 | + val a5 = a4.coerce[Array[X[Int]]] |
| 458 | + assertCompiles("a5: Array[X[Int]]") |
| 459 | + a5.apply(0) shouldBe v |
| 460 | + a5.getClass shouldBe cls |
| 461 | + } |
| 462 | + |
| 463 | + it should "work with @newsubtype X[A](List[A])" in { |
| 464 | + @newsubtype case class X[A](private val value: List[A]) |
| 465 | + |
| 466 | + val cls = scala.Predef.classOf[Array[List[Int]]] |
| 467 | + val v: List[Int] = List(1) |
| 468 | + |
| 469 | + val a = NewTypeArray(X(v)) |
| 470 | + assertCompiles("a: Array[X[Int]]") |
| 471 | + a.apply(0) shouldBe v |
| 472 | + a.getClass shouldBe cls |
| 473 | + |
| 474 | + val a2 = NewTypeArray[X[Int]].downcast(a) |
| 475 | + assertCompiles("a2: Array[List[Int]]") |
| 476 | + a2.apply(0) shouldBe v |
| 477 | + a2.getClass shouldBe cls |
| 478 | + |
| 479 | + val a3 = NewTypeArray[X[Int]].upcast(a2) |
| 480 | + assertCompiles("a3: Array[X[Int]]") |
| 481 | + a3.apply(0) shouldBe v |
| 482 | + a3.getClass shouldBe cls |
| 483 | + |
| 484 | + val a4 = a.coerce[Array[List[Int]]] |
| 485 | + assertCompiles("a4: Array[List[Int]]") |
| 486 | + a4.apply(0) shouldBe v |
| 487 | + a4.getClass shouldBe cls |
| 488 | + |
| 489 | + val a5 = a4.coerce[Array[X[Int]]] |
| 490 | + assertCompiles("a5: Array[X[Int]]") |
| 491 | + a5.apply(0) shouldBe v |
| 492 | + a5.getClass shouldBe cls |
| 493 | + } |
| 494 | + |
| 495 | + it should "work with @newtype X[F[_]](Functor[F])" in { |
| 496 | + @newtype case class X[F[_]](private val value: Functor[F]) |
| 497 | + |
| 498 | + val cls = scala.Predef.classOf[Array[Functor[List]]] |
| 499 | + val v: Functor[List] = Functor.list |
| 500 | + |
| 501 | + val a = NewTypeArray(X(v)) |
| 502 | + assertCompiles("a: Array[X[List]]") |
| 503 | + a.apply(0) shouldBe v |
| 504 | + a.getClass shouldBe cls |
| 505 | + |
| 506 | + val a2 = NewTypeArray[X[List]].downcast(a) |
| 507 | + assertCompiles("a2: Array[Functor[List]]") |
| 508 | + a2.apply(0) shouldBe v |
| 509 | + a2.getClass shouldBe cls |
| 510 | + |
| 511 | + val a3 = NewTypeArray[X[List]].upcast(a2) |
| 512 | + assertCompiles("a3: Array[X[List]]") |
| 513 | + a3.apply(0) shouldBe v |
| 514 | + a3.getClass shouldBe cls |
| 515 | + |
| 516 | + val a4 = a.coerce[Array[Functor[List]]] |
| 517 | + assertCompiles("a4: Array[Functor[List]]") |
| 518 | + a4.apply(0) shouldBe v |
| 519 | + a4.getClass shouldBe cls |
| 520 | + |
| 521 | + val a5 = a4.coerce[Array[X[List]]] |
| 522 | + assertCompiles("a5: Array[X[List]]") |
| 523 | + a5.apply(0) shouldBe v |
| 524 | + a5.getClass shouldBe cls |
| 525 | + } |
| 526 | + |
| 527 | + it should "work with @newsubtype X[F[_]](Functor[F])" in { |
| 528 | + @newsubtype case class X[F[_]](private val value: Functor[F]) |
| 529 | + |
| 530 | + val cls = scala.Predef.classOf[Array[Functor[List]]] |
| 531 | + val v: Functor[List] = Functor.list |
| 532 | + |
| 533 | + val a = NewTypeArray(X(v)) |
| 534 | + assertCompiles("a: Array[X[List]]") |
| 535 | + a.apply(0) shouldBe v |
| 536 | + a.getClass shouldBe cls |
| 537 | + |
| 538 | + val a2 = NewTypeArray[X[List]].downcast(a) |
| 539 | + assertCompiles("a2: Array[Functor[List]]") |
| 540 | + a2.apply(0) shouldBe v |
| 541 | + a2.getClass shouldBe cls |
| 542 | + |
| 543 | + val a3 = NewTypeArray[X[List]].upcast(a2) |
| 544 | + assertCompiles("a3: Array[X[List]]") |
| 545 | + a3.apply(0) shouldBe v |
| 546 | + a3.getClass shouldBe cls |
| 547 | + |
| 548 | + val a4 = a.coerce[Array[Functor[List]]] |
| 549 | + assertCompiles("a4: Array[Functor[List]]") |
| 550 | + a4.apply(0) shouldBe v |
| 551 | + a4.getClass shouldBe cls |
| 552 | + |
| 553 | + val a5 = a4.coerce[Array[X[List]]] |
| 554 | + assertCompiles("a5: Array[X[List]]") |
| 555 | + a5.apply(0) shouldBe v |
| 556 | + a5.getClass shouldBe cls |
| 557 | + } |
| 558 | + |
366 | 559 | // Unfortunately, we don't have a way to assert on compiler warnings, which is |
367 | 560 | // what happens with the code below. If we run with -Xfatal-warnings, the test |
368 | 561 | // won't compile at all, so leaving here to do manual checking until scalatest |
|
0 commit comments