Skip to content

Commit a148cca

Browse files
committed
Support scala 3.x
1 parent 40fc535 commit a148cca

File tree

5 files changed

+281
-12
lines changed

5 files changed

+281
-12
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
scala-version: [2.13.x]
12+
scala-version: [2.13.x, 3.3.x]
1313
java-version: [8, 11, 17, 21]
1414
steps:
1515
- uses: actions/checkout@v4
@@ -18,6 +18,6 @@ jobs:
1818
distribution: temurin
1919
java-version: ${{ matrix.java-version }}
2020
- name: Run tests
21-
run: sbt ++${{ matrix.scala-version }} clean versionPolicyCheck coverage test coverageReport
21+
run: sbt ++${{ matrix.scala-version }} clean coverage test coverageReport
2222
- name: Upload coverage report
2323
run: bash <(curl -s https://codecov.io/bash)

.scalafmt.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ rewriteTokens = {
1010
"→": "->"
1111
"←": "<-"
1212
}
13-
runner.dialect = scala213
13+
runner.dialect = scala213source3

build.sbt

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ developers := List(
1313
)
1414
)
1515

16-
crossScalaVersions := List("2.13.15")
17-
scalaVersion := crossScalaVersions.value.last
16+
scalaVersion := "2.13.15"
17+
crossScalaVersions += "3.3.4"
1818

1919
ThisBuild / versionScheme := Some("semver-spec")
2020
ThisBuild / versionPolicyIntention := Compatibility.BinaryCompatible
@@ -23,10 +23,28 @@ Compile / packageBin / packageOptions += Package.ManifestAttributes(
2323
"Automatic-Module-Name" -> "nl.gn0s1s.pureconfig.module.javanet"
2424
)
2525

26-
scalacOptions += "-deprecation"
26+
Test / unmanagedSourceDirectories ++= {
27+
(Test / unmanagedSourceDirectories).value.map { dir =>
28+
CrossVersion.partialVersion(scalaVersion.value) match {
29+
case Some((2, 13)) => file(dir.getPath ++ "-2.13")
30+
case _ => file(dir.getPath ++ "-3+")
31+
}
32+
}
33+
}
34+
35+
scalacOptions ++= (CrossVersion.partialVersion(scalaVersion.value) match {
36+
case Some((2, 13)) => Seq("-Xsource:3", "-deprecation")
37+
case _ => Seq("-deprecation")
38+
})
39+
40+
val pureConfigVersion = "0.17.7"
41+
42+
libraryDependencies += (CrossVersion.partialVersion(scalaVersion.value) match {
43+
case Some((2, 13)) => "com.github.pureconfig" %% "pureconfig" % pureConfigVersion % Provided
44+
case _ => "com.github.pureconfig" %% "pureconfig-core" % pureConfigVersion % Provided
45+
})
2746

2847
libraryDependencies ++= Seq(
29-
"com.github.pureconfig" %% "pureconfig" % "0.17.7" % Provided,
30-
"commons-validator" % "commons-validator" % "1.9.0",
31-
"org.scalameta" %% "munit" % "1.0.2" % Test
48+
"commons-validator" % "commons-validator" % "1.9.0",
49+
"org.scalameta" %% "munit" % "1.0.2" % Test
3250
)

src/test/scala/nl/gn0s1s/pureconfig/module/javanet/JavanetSuite.scala renamed to src/test/scala-2.13/nl/gn0s1s/pureconfig/module/javanet/JavanetSuite.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import java.net.InetSocketAddress
44

55
import com.typesafe.config.ConfigFactory.parseString
66
import com.typesafe.config.ConfigOriginFactory
7-
import pureconfig._
7+
import pureconfig.*
88
import pureconfig.error.{CannotConvert, ConfigReaderFailures, ConvertFailure}
9-
import pureconfig.generic.auto._
10-
import pureconfig.syntax._
9+
import pureconfig.generic.auto.*
10+
import pureconfig.syntax.*
1111

1212
class JavanetSuite extends munit.FunSuite {
1313
private val expectedConfigOrigin =
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
package nl.gn0s1s.pureconfig.module.javanet
2+
3+
import java.net.InetSocketAddress
4+
5+
import com.typesafe.config.ConfigFactory.parseString
6+
import com.typesafe.config.ConfigOriginFactory
7+
import pureconfig.*
8+
import pureconfig.error.{CannotConvert, ConfigReaderFailures, ConvertFailure}
9+
import pureconfig.generic.derivation.default.*
10+
import pureconfig.syntax.*
11+
12+
class JavanetSuite extends munit.FunSuite {
13+
private val expectedConfigOrigin =
14+
Some(ConfigOriginFactory.newSimple("String").withLineNumber(1))
15+
16+
test("can read a valid ipv4 address") {
17+
case class Config(host: InetSocketAddress) derives ConfigReader
18+
19+
val conf = parseString(""""host": "127.0.0.1:65535"""")
20+
21+
assert(conf.to[Config].contains(Config(InetSocketAddress.createUnresolved("127.0.0.1", 65535))))
22+
}
23+
24+
test("can read a valid single named address") {
25+
case class Config(host: InetSocketAddress) derives ConfigReader
26+
27+
val conf = parseString(""""host": "abc.def.ghi:65535"""")
28+
29+
assert(conf.to[Config].contains(Config(InetSocketAddress.createUnresolved("abc.def.ghi", 65535))))
30+
}
31+
32+
test("can read a valid ipv6 address") {
33+
case class Config(host: InetSocketAddress) derives ConfigReader
34+
35+
val conf = parseString(""""host": "2001:db8::1:80"""")
36+
37+
assert(conf.to[Config].contains(Config(InetSocketAddress.createUnresolved("2001:db8::1", 80))))
38+
}
39+
40+
test("can read a valid ipv6 address in brackets") {
41+
case class Config(host: InetSocketAddress) derives ConfigReader
42+
43+
val conf = parseString(""""host": "[2001:db8::1]:80"""")
44+
45+
assert(conf.to[Config].contains(Config(InetSocketAddress.createUnresolved("2001:db8::1", 80))))
46+
}
47+
48+
test("validates if a host is defined") {
49+
case class Config(host: InetSocketAddress) derives ConfigReader
50+
51+
val conf = parseString(""""host": ":80"""")
52+
53+
val expectedErrors = Left(
54+
ConfigReaderFailures(
55+
ConvertFailure(CannotConvert(":80", "InetSocketAddress", "no host defined"), expectedConfigOrigin, "host")
56+
)
57+
)
58+
59+
assert(conf.to[Config] == expectedErrors)
60+
}
61+
62+
test("validates if a port is defined") {
63+
case class Config(host: InetSocketAddress) derives ConfigReader
64+
65+
val conf = parseString(""""host": "localhost123"""")
66+
67+
val expectedErrors = Left(
68+
ConfigReaderFailures(
69+
ConvertFailure(
70+
CannotConvert("localhost123", "InetSocketAddress", "no port defined"),
71+
expectedConfigOrigin,
72+
"host"
73+
)
74+
)
75+
)
76+
77+
assert(conf.to[Config] == expectedErrors)
78+
}
79+
80+
test("validates if a port is defined when a colon is present") {
81+
case class Config(host: InetSocketAddress) derives ConfigReader
82+
83+
val conf = parseString(""""host": "abc:"""")
84+
85+
val expectedErrors = Left(
86+
ConfigReaderFailures(
87+
ConvertFailure(CannotConvert("abc:", "InetSocketAddress", "no port defined"), expectedConfigOrigin, "host")
88+
)
89+
)
90+
91+
assert(conf.to[Config] == expectedErrors)
92+
}
93+
94+
test("validates if a port is a number") {
95+
case class Config(host: InetSocketAddress) derives ConfigReader
96+
97+
val conf = parseString(""""host": "abc:def"""")
98+
99+
val expectedErrors = Left(
100+
ConfigReaderFailures(
101+
ConvertFailure(
102+
CannotConvert("abc:def", "InetSocketAddress", "port is not a number:def"),
103+
expectedConfigOrigin,
104+
"host"
105+
)
106+
)
107+
)
108+
109+
assert(conf.to[Config] == expectedErrors)
110+
}
111+
112+
test("validates if a port is within range") {
113+
case class Config(host: InetSocketAddress) derives ConfigReader
114+
115+
val conf = parseString(""""host": "abc:65536"""")
116+
117+
val expectedErrors = Left(
118+
ConfigReaderFailures(
119+
ConvertFailure(
120+
CannotConvert("abc:65536", "InetSocketAddress", "port out of range:65536"),
121+
expectedConfigOrigin,
122+
"host"
123+
)
124+
)
125+
)
126+
127+
assert(conf.to[Config] == expectedErrors)
128+
}
129+
130+
test("can read back a written address") {
131+
val address = InetSocketAddress.createUnresolved("localhost", 65535)
132+
133+
assert(ConfigReader[InetSocketAddress].from(ConfigWriter[InetSocketAddress].to(address)).contains(address))
134+
}
135+
136+
test("can read multiple addresses") {
137+
case class Config(hosts: Seq[InetSocketAddress]) derives ConfigReader
138+
139+
val conf = parseString("""hosts: "localhost:65535,127.0.0.1:80,localhost:443"""")
140+
141+
assert(
142+
conf
143+
.to[Config]
144+
.contains(
145+
Config(
146+
Seq(
147+
InetSocketAddress.createUnresolved("localhost", 65535),
148+
InetSocketAddress.createUnresolved("127.0.0.1", 80),
149+
InetSocketAddress.createUnresolved("localhost", 443)
150+
)
151+
)
152+
)
153+
)
154+
}
155+
156+
test("can read multiple addresses as a list") {
157+
case class Config(hosts: List[InetSocketAddress]) derives ConfigReader
158+
159+
val conf = parseString("""hosts: "localhost:65535,127.0.0.1:80,localhost:443"""")
160+
161+
assert(
162+
conf
163+
.to[Config]
164+
.contains(
165+
Config(
166+
List(
167+
InetSocketAddress.createUnresolved("localhost", 65535),
168+
InetSocketAddress.createUnresolved("127.0.0.1", 80),
169+
InetSocketAddress.createUnresolved("localhost", 443)
170+
)
171+
)
172+
)
173+
)
174+
}
175+
176+
test("can read a single address as multiple addresses") {
177+
case class Config(hosts: Seq[InetSocketAddress]) derives ConfigReader
178+
179+
val conf = parseString("""hosts: "localhost:65535"""")
180+
181+
assert(conf.to[Config].contains(Config(Seq(InetSocketAddress.createUnresolved("localhost", 65535)))))
182+
}
183+
184+
test("is lenient about whitespace") {
185+
case class Config(hosts: Seq[InetSocketAddress]) derives ConfigReader
186+
187+
val conf = parseString("""hosts: "localhost: 65535,127.0.0.1: 80,localhost: 443"""")
188+
189+
assert(
190+
conf
191+
.to[Config]
192+
.contains(
193+
Config(
194+
Seq(
195+
InetSocketAddress.createUnresolved("localhost", 65535),
196+
InetSocketAddress.createUnresolved("127.0.0.1", 80),
197+
InetSocketAddress.createUnresolved("localhost", 443)
198+
)
199+
)
200+
)
201+
)
202+
}
203+
204+
test("can read back a written Seq[InetSocketAddress]") {
205+
val addresses = Seq(
206+
InetSocketAddress.createUnresolved("localhost", 65535),
207+
InetSocketAddress.createUnresolved("127.0.0.1", 80),
208+
InetSocketAddress.createUnresolved("localhost", 443)
209+
)
210+
211+
assert(
212+
ConfigReader[Seq[InetSocketAddress]].from(ConfigWriter[Seq[InetSocketAddress]].to(addresses)).contains(addresses)
213+
)
214+
}
215+
216+
test("can read back a written List[InetSocketAddress]") {
217+
val addresses = List(
218+
InetSocketAddress.createUnresolved("localhost", 65535),
219+
InetSocketAddress.createUnresolved("127.0.0.1", 80),
220+
InetSocketAddress.createUnresolved("localhost", 443)
221+
)
222+
223+
assert(
224+
ConfigReader[List[InetSocketAddress]].from(ConfigWriter[List[InetSocketAddress]].to(addresses)).contains(
225+
addresses
226+
)
227+
)
228+
}
229+
230+
test("validates the supplied setting") {
231+
case class Config(hosts: Seq[InetSocketAddress]) derives ConfigReader
232+
233+
val conf = parseString("""hosts: "localhost:65535 + localhost:80"""")
234+
235+
val expectedErrors = Left(
236+
ConfigReaderFailures(
237+
ConvertFailure(
238+
CannotConvert(
239+
"localhost:65535 + localhost:80",
240+
"Seq[InetSocketAddress]",
241+
"Cannot parse string into hosts and ports"
242+
),
243+
expectedConfigOrigin,
244+
"hosts"
245+
)
246+
)
247+
)
248+
249+
assert(conf.to[Config] == expectedErrors)
250+
}
251+
}

0 commit comments

Comments
 (0)