11package com .avsystem .commons
22package analyzer
33
4+ import org .scalatest .Suites
45import org .scalatest .funsuite .AnyFunSuite
56
6- class ImplicitValueClassesTest extends AnyFunSuite with AnalyzerTest {
7- test(" implicit classes should extend AnyVal" ) {
8- assertErrors(2 ,
7+ class DefaultImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
8+ test(" implicit final class extending AnyVal should pass" ) {
9+ assertNoErrors(
10+ // language=Scala
911 """
1012 |object whatever {
11- | // This should pass - implicit class extending AnyVal
12- | implicit class GoodImplicitClass(val x: Int) extends AnyVal {
13+ | implicit final class GoodImplicitClass(val x: Int) extends AnyVal {
1314 | def double: Int = x * 2
1415 | }
15- |
16- | // This should fail - implicit class not extending AnyVal
17- | implicit class BadImplicitClass1(val x: Int) {
16+ |}
17+ """ .stripMargin)
18+ }
19+
20+ test(" implicit class not extending AnyVal should fail" ) {
21+ assertErrors(1 ,
22+ // language=Scala
23+ """
24+ |object whatever {
25+ | implicit final class BadImplicitClass(val x: Int) {
1826 | def double: Int = x * 2
1927 | }
20- |
21- | // This should fail - another implicit class not extending AnyVal
22- | implicit class BadImplicitClass2[T <: Int](val x: T) {
28+ |}
29+ """ .stripMargin)
30+ }
31+
32+ test(" implicit class with type parameter not extending AnyVal should fail" ) {
33+ assertErrors(1 ,
34+ // language=Scala
35+ """
36+ |object whatever {
37+ | implicit final class BadImplicitClass[T <: Int](val x: T) {
2338 | def double: Int = x * 2
2439 | }
25- |
26- | // Regular class - should not be affected
40+ |}
41+ """ .stripMargin)
42+ }
43+
44+ test(" regular class should not be affected" ) {
45+ assertNoErrors(
46+ // language=Scala
47+ """
48+ |object whatever {
2749 | class RegularClass(val x: Int) {
2850 | def double: Int = x * 2
2951 | }
52+ |}
53+ """ .stripMargin)
54+ }
55+
56+ test(" implicit class with implicit parameter should not be affected" ) {
57+ assertNoErrors(
58+ // language=Scala
59+ """
60+ |object whatever {
61+ | implicit final class ImplicitClassWithImplicitParameter(val x: Int)(implicit dummy: DummyImplicit) {
62+ | def double: Int = x * 2
63+ | }
64+ |}
65+ """ .stripMargin)
66+ }
67+
68+ test(" implicit class extending other classes should not be affected" ) {
69+ assertNoErrors(
70+ // language=Scala
71+ """
72+ |object whatever {
73+ | class SomeClass
74+ |
75+ | implicit final class GoodImplicitClass1(val x: Int) extends SomeClass {
76+ | def double: Int = x * 2
77+ | }
3078 |
31- | // implicit class with implicit parameter - should not be affected
32- | implicit class ImplicitClassWithImplicitParameter (val x: Int)(implicit dummy: DummyImplicit) {
79+ | trait SomeTrait
80+ | implicit final class GoodImplicitClass2 (val x: Int) extends SomeTrait {
3381 | def double: Int = x * 2
3482 | }
3583 |}
3684 """ .stripMargin)
3785 }
38- }
86+
87+ test(" implicit class extending AnyVal with traits should be handled correctly" ) {
88+ // language=Scala
89+ assertErrors(1 ,
90+ """
91+ |object whatever {
92+ | trait AnyTrait extends Any
93+ | implicit final class GoodImplicitClass(val x: Int) extends AnyVal with AnyTrait {
94+ | def double: Int = x * 2
95+ | }
96+ | implicit final class BadImplicitClass(val x: Int) extends AnyTrait {
97+ | def double: Int = x * 2
98+ | }
99+ |}
100+ """ .stripMargin)
101+ }
102+
103+ test(" nested implicit class not extending AnyVal should pass" ) {
104+ assertNoErrors(
105+ // language=Scala
106+ """
107+ |object whatever {
108+ | class Outer {
109+ | implicit final class NestedImplicitClass(val x: Int) {
110+ | def double: Int = x * 2
111+ | }
112+ | }
113+ |}
114+ """ .stripMargin)
115+ }
116+ }
117+
118+ class NestedImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
119+ settings.pluginOptions.value ++= List (" AVSystemAnalyzer:+implicitValueClasses:true" )
120+
121+ test(" nested implicit class not extending AnyVal should fail" ) {
122+ assertErrors(1 ,
123+ """
124+ |object whatever {
125+ | class Outer {
126+ | implicit final class GoodNestedImplicitClass(val x: Int) {
127+ | def double: Int = x * 2
128+ | }
129+ | }
130+ |}
131+ """ .stripMargin)
132+ }
133+
134+
135+ test(" nested implicit class with type parameter not extending AnyVal should fail" ) {
136+ assertErrors(1 ,
137+ """
138+ |object whatever {
139+ | class Outer {
140+ | implicit final class BadNestedImplicitClass[T <: Int](val x: T) {
141+ | def double: Int = x * 2
142+ | }
143+ | }
144+ |}
145+ """ .stripMargin)
146+ }
147+
148+ test(" deeply nested implicit class not extending AnyVal should fail" ) {
149+ assertErrors(1 ,
150+ """
151+ |object whatever {
152+ | class Outer {
153+ | class Inner {
154+ | implicit final class BadDeeplyNestedImplicitClass(val x: Int) {
155+ | def double: Int = x * 2
156+ | }
157+ | }
158+ | }
159+ |}
160+ """ .stripMargin)
161+ }
162+
163+ test(" regular class should not be affected" ) {
164+ assertNoErrors(
165+ """
166+ |object whatever {
167+ | class Outer {
168+ | class RegularClass(val x: Int) {
169+ | def double: Int = x * 2
170+ | }
171+ | }
172+ |}
173+ """ .stripMargin)
174+ }
175+
176+ test(" implicit class extending other classes should not be affected" ) {
177+ assertNoErrors(
178+ """
179+ |object whatever {
180+ | class Outer {
181+ | class SomeClass
182+ |
183+ | implicit final class GoodImplicitClass1(val x: Int) extends SomeClass {
184+ | def double: Int = x * 2
185+ | }
186+ |
187+ | trait SomeTrait
188+ | implicit final class GoodImplicitClass2(val x: Int) extends SomeTrait {
189+ | def double: Int = x * 2
190+ | }
191+ | }
192+ |}
193+ """ .stripMargin)
194+ }
195+
196+ test(" implicit class extending AnyVal with traits should be handled correctly" ) {
197+ assertErrors(1 ,
198+ """
199+ |object whatever {
200+ | class Outer {
201+ | trait AnyTrait extends Any
202+ | implicit final class GoodImplicitClass(val x: Int) extends AnyVal with AnyTrait {
203+ | def double: Int = x * 2
204+ | }
205+ | implicit final class BadImplicitClass(val x: Int) extends AnyTrait {
206+ | def double: Int = x * 2
207+ | }
208+ | }
209+ |}
210+ """ .stripMargin)
211+ }
212+ }
213+
214+ class ImplicitValueClassesTest extends Suites (
215+ new DefaultImplicitValueClassesSuite ,
216+ new NestedImplicitValueClassesSuite
217+ )
0 commit comments