Skip to content

Commit

Permalink
Support scala 3.x (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
Philippus authored Nov 9, 2024
1 parent 40fc535 commit f0cc295
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
scala-version: [2.13.x]
scala-version: [2.13.x, 3.3.x]
java-version: [8, 11, 17, 21]
steps:
- uses: actions/checkout@v4
Expand All @@ -18,6 +18,6 @@ jobs:
distribution: temurin
java-version: ${{ matrix.java-version }}
- name: Run tests
run: sbt ++${{ matrix.scala-version }} clean versionPolicyCheck coverage test coverageReport
run: sbt ++${{ matrix.scala-version }} clean coverage test coverageReport
- name: Upload coverage report
run: bash <(curl -s https://codecov.io/bash)
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ rewriteTokens = {
"→": "->"
"←": "<-"
}
runner.dialect = scala213
runner.dialect = scala213source3
30 changes: 24 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ developers := List(
)
)

crossScalaVersions := List("2.13.15")
scalaVersion := crossScalaVersions.value.last
scalaVersion := "2.13.15"
crossScalaVersions += "3.3.4"

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

scalacOptions += "-deprecation"
Test / unmanagedSourceDirectories ++= {
(Test / unmanagedSourceDirectories).value.map { dir =>
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 13)) => file(dir.getPath ++ "-2.13")
case _ => file(dir.getPath ++ "-3+")
}
}
}

scalacOptions ++= (CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 13)) => Seq("-Xsource:3", "-deprecation")
case _ => Seq("-deprecation")
})

val pureConfigVersion = "0.17.7"

libraryDependencies += (CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 13)) => "com.github.pureconfig" %% "pureconfig" % pureConfigVersion % Provided
case _ => "com.github.pureconfig" %% "pureconfig-core" % pureConfigVersion % Provided
})

libraryDependencies ++= Seq(
"com.github.pureconfig" %% "pureconfig" % "0.17.7" % Provided,
"commons-validator" % "commons-validator" % "1.9.0",
"org.scalameta" %% "munit" % "1.0.2" % Test
"commons-validator" % "commons-validator" % "1.9.0",
"org.scalameta" %% "munit" % "1.0.2" % Test
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import java.net.InetSocketAddress

import com.typesafe.config.ConfigFactory.parseString
import com.typesafe.config.ConfigOriginFactory
import pureconfig._
import pureconfig.*
import pureconfig.error.{CannotConvert, ConfigReaderFailures, ConvertFailure}
import pureconfig.generic.auto._
import pureconfig.syntax._
import pureconfig.generic.auto.*
import pureconfig.syntax.*

class JavanetSuite extends munit.FunSuite {
private val expectedConfigOrigin =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
package nl.gn0s1s.pureconfig.module.javanet

import java.net.InetSocketAddress

import com.typesafe.config.ConfigFactory.parseString
import com.typesafe.config.ConfigOriginFactory
import pureconfig.*
import pureconfig.error.{CannotConvert, ConfigReaderFailures, ConvertFailure}
import pureconfig.generic.derivation.default.*
import pureconfig.syntax.*

class JavanetSuite extends munit.FunSuite {
private val expectedConfigOrigin =
Some(ConfigOriginFactory.newSimple("String").withLineNumber(1))

test("can read a valid ipv4 address") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": "127.0.0.1:65535"""")

assert(conf.to[Config].contains(Config(InetSocketAddress.createUnresolved("127.0.0.1", 65535))))
}

test("can read a valid single named address") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": "abc.def.ghi:65535"""")

assert(conf.to[Config].contains(Config(InetSocketAddress.createUnresolved("abc.def.ghi", 65535))))
}

test("can read a valid ipv6 address") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": "2001:db8::1:80"""")

assert(conf.to[Config].contains(Config(InetSocketAddress.createUnresolved("2001:db8::1", 80))))
}

test("can read a valid ipv6 address in brackets") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": "[2001:db8::1]:80"""")

assert(conf.to[Config].contains(Config(InetSocketAddress.createUnresolved("2001:db8::1", 80))))
}

test("validates if a host is defined") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": ":80"""")

val expectedErrors = Left(
ConfigReaderFailures(
ConvertFailure(CannotConvert(":80", "InetSocketAddress", "no host defined"), expectedConfigOrigin, "host")
)
)

assert(conf.to[Config] == expectedErrors)
}

test("validates if a port is defined") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": "localhost123"""")

val expectedErrors = Left(
ConfigReaderFailures(
ConvertFailure(
CannotConvert("localhost123", "InetSocketAddress", "no port defined"),
expectedConfigOrigin,
"host"
)
)
)

assert(conf.to[Config] == expectedErrors)
}

test("validates if a port is defined when a colon is present") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": "abc:"""")

val expectedErrors = Left(
ConfigReaderFailures(
ConvertFailure(CannotConvert("abc:", "InetSocketAddress", "no port defined"), expectedConfigOrigin, "host")
)
)

assert(conf.to[Config] == expectedErrors)
}

test("validates if a port is a number") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": "abc:def"""")

val expectedErrors = Left(
ConfigReaderFailures(
ConvertFailure(
CannotConvert("abc:def", "InetSocketAddress", "port is not a number:def"),
expectedConfigOrigin,
"host"
)
)
)

assert(conf.to[Config] == expectedErrors)
}

test("validates if a port is within range") {
case class Config(host: InetSocketAddress) derives ConfigReader

val conf = parseString(""""host": "abc:65536"""")

val expectedErrors = Left(
ConfigReaderFailures(
ConvertFailure(
CannotConvert("abc:65536", "InetSocketAddress", "port out of range:65536"),
expectedConfigOrigin,
"host"
)
)
)

assert(conf.to[Config] == expectedErrors)
}

test("can read back a written address") {
val address = InetSocketAddress.createUnresolved("localhost", 65535)

assert(ConfigReader[InetSocketAddress].from(ConfigWriter[InetSocketAddress].to(address)).contains(address))
}

test("can read multiple addresses") {
case class Config(hosts: Seq[InetSocketAddress]) derives ConfigReader

val conf = parseString("""hosts: "localhost:65535,127.0.0.1:80,localhost:443"""")

assert(
conf
.to[Config]
.contains(
Config(
Seq(
InetSocketAddress.createUnresolved("localhost", 65535),
InetSocketAddress.createUnresolved("127.0.0.1", 80),
InetSocketAddress.createUnresolved("localhost", 443)
)
)
)
)
}

test("can read multiple addresses as a list") {
case class Config(hosts: List[InetSocketAddress]) derives ConfigReader

val conf = parseString("""hosts: "localhost:65535,127.0.0.1:80,localhost:443"""")

assert(
conf
.to[Config]
.contains(
Config(
List(
InetSocketAddress.createUnresolved("localhost", 65535),
InetSocketAddress.createUnresolved("127.0.0.1", 80),
InetSocketAddress.createUnresolved("localhost", 443)
)
)
)
)
}

test("can read a single address as multiple addresses") {
case class Config(hosts: Seq[InetSocketAddress]) derives ConfigReader

val conf = parseString("""hosts: "localhost:65535"""")

assert(conf.to[Config].contains(Config(Seq(InetSocketAddress.createUnresolved("localhost", 65535)))))
}

test("is lenient about whitespace") {
case class Config(hosts: Seq[InetSocketAddress]) derives ConfigReader

val conf = parseString("""hosts: "localhost: 65535,127.0.0.1: 80,localhost: 443"""")

assert(
conf
.to[Config]
.contains(
Config(
Seq(
InetSocketAddress.createUnresolved("localhost", 65535),
InetSocketAddress.createUnresolved("127.0.0.1", 80),
InetSocketAddress.createUnresolved("localhost", 443)
)
)
)
)
}

test("can read back a written Seq[InetSocketAddress]") {
val addresses = Seq(
InetSocketAddress.createUnresolved("localhost", 65535),
InetSocketAddress.createUnresolved("127.0.0.1", 80),
InetSocketAddress.createUnresolved("localhost", 443)
)

assert(
ConfigReader[Seq[InetSocketAddress]].from(ConfigWriter[Seq[InetSocketAddress]].to(addresses)).contains(addresses)
)
}

test("can read back a written List[InetSocketAddress]") {
val addresses = List(
InetSocketAddress.createUnresolved("localhost", 65535),
InetSocketAddress.createUnresolved("127.0.0.1", 80),
InetSocketAddress.createUnresolved("localhost", 443)
)

assert(
ConfigReader[List[InetSocketAddress]].from(ConfigWriter[List[InetSocketAddress]].to(addresses)).contains(
addresses
)
)
}

test("validates the supplied setting") {
case class Config(hosts: Seq[InetSocketAddress]) derives ConfigReader

val conf = parseString("""hosts: "localhost:65535 + localhost:80"""")

val expectedErrors = Left(
ConfigReaderFailures(
ConvertFailure(
CannotConvert(
"localhost:65535 + localhost:80",
"Seq[InetSocketAddress]",
"Cannot parse string into hosts and ports"
),
expectedConfigOrigin,
"hosts"
)
)
)

assert(conf.to[Config] == expectedErrors)
}
}

0 comments on commit f0cc295

Please sign in to comment.