1
+ package com .avsystem .commons
2
+ package opaque
3
+
4
+ import com .avsystem .commons .opaque .Subopaque .*
5
+ import com .avsystem .commons .opaque .SubopaqueTest .*
6
+ import org .scalatest .flatspec .AnyFlatSpec
7
+ import org .scalatest .matchers .should .Matchers
8
+
9
+ final class SubopaqueTest extends AnyFlatSpec with Matchers {
10
+
11
+ " SubOpaque" should " create a type with no runtime overhead" in {
12
+ PosInt (1 ) shouldEqual 1
13
+ PosInt (- 1 ) shouldEqual 0
14
+ }
15
+
16
+ it should " be a subtype of its Repr" in {
17
+ type Foo = Foo .Type
18
+ object Foo extends Subopaque .Default [Int ]
19
+ assertCompiles(" Foo(1): Foo" )
20
+ assertCompiles(" Foo(1): Int" )
21
+
22
+ Foo (1 ) - Foo (0 ) shouldEqual Foo (1 )
23
+ }
24
+
25
+ it should " support user ops" in {
26
+ (PosInt (3 ) -- PosInt (1 )) shouldEqual PosInt (2 )
27
+ }
28
+
29
+ it should " work in Arrays" in {
30
+ object Foo extends Subopaque .Default [Int ]
31
+
32
+ val foo = Foo (42 )
33
+ Array (foo).apply(0 ) shouldEqual foo
34
+ }
35
+
36
+ " Subopaque.Default" should " automatically create an apply method" in {
37
+ object PersonId extends Subopaque .Default [Int ]
38
+ PersonId (1 ) shouldEqual 1
39
+ }
40
+ }
41
+
42
+ object SubopaqueTest {
43
+ object PosInt extends Subopaque [Int ] {
44
+ def apply (value : Int ): Type = wrap {
45
+ if (value < 0 ) 0 else value
46
+ }
47
+
48
+ implicit final class Ops (private val me : PosInt .Type ) extends AnyVal {
49
+ def -- (other : PosInt .Type ): PosInt .Type = wrap {
50
+ val result = unwrap(me) - unwrap(other)
51
+ if (result < 0 ) 0 else result
52
+ }
53
+ }
54
+ }
55
+ }
0 commit comments