Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions backend/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ ThisBuild / scalaVersion := "3.8.1"
ThisBuild / evictionErrorLevel := Level.Debug

ThisBuild / semanticdbEnabled := true
ThisBuild / semanticdbVersion := scalafixSemanticdb.revision

val utils = (project in file("utils"))
.settings(Settings.common)
Expand Down Expand Up @@ -214,5 +213,5 @@ val root = (project in file("."))
`edsl`
)
.settings(
run / aggregate := false,
run / aggregate := false
)
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,17 @@ final case class JsonOptic private[optics] (private val jsonPath: Seq[PathPart])

def prune: Json => Json = { json =>
if (validate(json))
jsonPath.init.foldRight[Json => Json] { json =>
jsonPath.last.fold(
f => json.withObject(jo => Json.fromJsonObject(jo.remove(f))),
i => json.withArray(ja => Json.fromValues(ja.take(i) ++ ja.drop(i + 1))),
if (json.isArray) Json.Null else json
)
}((part, f) => modifyPart(Json.Null)(part)(f))(json)
jsonPath.lastOption.fold(json) { lastPart =>
jsonPath
.dropRight(1)
.foldRight[Json => Json] { innerJson =>
lastPart.fold(
f => innerJson.withObject(jo => Json.fromJsonObject(jo.remove(f))),
i => innerJson.withArray(ja => Json.fromValues(ja.take(i) ++ ja.drop(i + 1))),
if (innerJson.isArray) Json.Null else innerJson
)
}((part, f) => modifyPart(Json.Null)(part)(f))(json)
}
else json
}

Expand All @@ -82,7 +86,9 @@ final case class JsonOptic private[optics] (private val jsonPath: Seq[PathPart])
jsonPath.foldRight[Json => Json](op)((part, f) => modifyPart(Json.Null)(part)(f))

def modifyOpt(op: Option[Json] => Json): Json => Json =
jsonPath.init.foldRight[Json => Json](modifyPart(jsonPath.last)(op))((part, f) => modifyPart(Json.Null)(part)(f))
jsonPath.lastOption.fold[Json => Json](identity) { lastPart =>
jsonPath.dropRight(1).foldRight[Json => Json](modifyPart(lastPart)(op))((part, f) => modifyPart(Json.Null)(part)(f))
}

def modifyObjectValues(op: Json => Json): Json => Json = { json =>
getOpt(json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ package object optics {
else {
val itemsToAdd = index - ja.length + 1
Json.fromValues(
ja ++ Vector.tabulate(itemsToAdd)(idx => if (idx == itemsToAdd - 1) mod(None) else Json.Null)
ja ++ Vector.tabulate(itemsToAdd)(idx => if (idx === itemsToAdd - 1) mod(None) else Json.Null)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ package object circe {

if (baseArr.length >= patchArr.length)
Json.fromValues((baseArr zip patchArr).map(mrgPair.tupled))
else Json.fromValues(baseArr.zipAll(patchArr, Json.Null, patchArr.last).map(mrgPair.tupled))
else
Json.fromValues(
baseArr.zipAll(patchArr, Json.Null, patchArr.lastOption.getOrElse(Json.Null)).map(mrgPair.tupled)
)
case (p, JsonNull()) if arraySubvalues => p
case (_, p) => p
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class OpticSpec extends RefSpec with Matchers {

val optic = JLens \ "value"

optic.modify(_.withNumber(jn => Json.fromInt(jn.toInt.get * 2)))(target) shouldBe
optic.modify(_.withNumber(jn => jn.toInt.fold(Json.Null)(n => Json.fromInt(n * 2))))(target) shouldBe
json"""{"value": 4}"""
}

Expand All @@ -159,7 +159,7 @@ class OpticSpec extends RefSpec with Matchers {

val optic = (JLens \ "value").traverse

optic.modify(_.withNumber(jn => Json.fromInt(jn.toInt.get * 2)))(target) shouldBe
optic.modify(_.withNumber(jn => jn.toInt.fold(Json.Null)(n => Json.fromInt(n * 2))))(target) shouldBe
json"""{"value": [2, 4, 6]}"""
}
}
Expand All @@ -171,7 +171,7 @@ class OpticSpec extends RefSpec with Matchers {
val optic = JLens \ "value"

optic.modifyOpt {
case Some(json) => json.withNumber(jn => Json.fromInt(jn.toInt.get * 2))
case Some(json) => json.withNumber(jn => jn.toInt.fold(Json.Null)(n => Json.fromInt(n * 2)))
case None => Json.fromInt(2)
}(target) shouldBe
json"""{"value": 4}"""
Expand All @@ -183,7 +183,7 @@ class OpticSpec extends RefSpec with Matchers {
val optic = JLens \ "value"

optic.modifyOpt {
case Some(json) => json.withNumber(jn => Json.fromInt(jn.toInt.get * 2))
case Some(json) => json.withNumber(jn => jn.toInt.fold(Json.Null)(n => Json.fromInt(n * 2)))
case None => Json.fromInt(2)
}(target) shouldBe
json"""{"value": 2}"""
Expand All @@ -196,7 +196,8 @@ class OpticSpec extends RefSpec with Matchers {

val optic = JLens \ "outer"

optic.modifyObjectValues(_.withNumber(jn => Json.fromInt(jn.toInt.get * 2)))(target) shouldBe
optic
.modifyObjectValues(_.withNumber(jn => jn.toInt.fold(Json.Null)(n => Json.fromInt(n * 2))))(target) shouldBe
json"""{"outer": {"inner": 84}}"""
}
}
Expand All @@ -208,7 +209,7 @@ class OpticSpec extends RefSpec with Matchers {
val optic = JLens \ "outer"

optic.modifyFields { case (key, value) =>
key -> value.withNumber(jn => Json.fromInt(jn.toInt.get * 2))
key -> value.withNumber(jn => jn.toInt.fold(Json.Null)(n => Json.fromInt(n * 2)))
}(target) shouldBe json"""{"outer": {"inner": 84}}"""
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package ru.tinkoff.tcb.dataaccess

final case class UpdateResult(matched: Long, modified: Long) {
val successful: Boolean = matched > 0 || modified > 0
val noMatch: Boolean = matched == 0
val noOp: Boolean = modified == 0
val noMatch: Boolean = matched === 0L
val noOp: Boolean = modified === 0L
val unsuccessful: Boolean = noMatch && noOp
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ object Fields extends AutoDerivation[Fields] {
implicit def enumEntry[T <: EnumEntry]: Fields[T] = mk(Nil)
implicit def strEnum[T <: StringEnumEntry]: Fields[T] = mk(Nil)

def join[T](caseClass: CaseClass[Fields, T]): Fields[T] =
override def join[T](caseClass: CaseClass[Fields, T]): Fields[T] =
mk(
caseClass.parameters
.foldLeft(List.newBuilder[String])((acc, fld) =>
Expand All @@ -44,5 +44,5 @@ object Fields extends AutoDerivation[Fields] {
.result()
)

def split[T](sealedTrait: SealedTrait[Fields, T]): Fields[T] = mk(Nil)
override def split[T](sealedTrait: SealedTrait[Fields, T]): Fields[T] = mk(Nil)
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ object RootOptionFields extends AutoDerivation[RootOptionFields] {
implicit def refn[T, R, F[_, _]](implicit rt: RefType[F], rof: RootOptionFields[T]): RootOptionFields[F[T, R]] =
mk(rof.fields)

def join[T](caseClass: CaseClass[RootOptionFields, T]): RootOptionFields[T] =
override def join[T](caseClass: CaseClass[RootOptionFields, T]): RootOptionFields[T] =
mk(
caseClass.parameters
.foldLeft(Set.newBuilder[String])((acc, fld) =>
Expand All @@ -45,5 +45,5 @@ object RootOptionFields extends AutoDerivation[RootOptionFields] {
.result()
)

def split[T](sealedTrait: SealedTrait[RootOptionFields, T]): RootOptionFields[T] = mk(Set.empty)
override def split[T](sealedTrait: SealedTrait[RootOptionFields, T]): RootOptionFields[T] = mk(Set.empty)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class RoundRobinSpec extends AnyFunSuite with Matchers with TryValues {
implicit private val regexEquality: Equality[Regex] =
(a: Regex, b: Any) =>
b match {
case rb: Regex => a.regex == rb.regex
case rb: Regex => a.regex === rb.regex
case _ => false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ package ru.tinkoff.tcb.bson.enumeratum

import oolong.bson.*
import org.mongodb.scala.bson.*
import org.scalatest.TryValues
import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers

class BsonEnumSpec extends AnyFunSpec with Matchers {
class BsonEnumSpec extends AnyFunSpec with Matchers with TryValues {
describe("BSON serdes") {

describe("deserialisation") {

it("should work with valid values") {
val bsonValue: BsonValue = BsonString("A")
BsonDecoder[Dummy].fromBson(bsonValue).get shouldBe Dummy.A
BsonDecoder[Dummy].fromBson(bsonValue).success.value shouldBe Dummy.A
}

it("should fail with invalid values") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package ru.tinkoff.tcb.bson.enumeratum.values
import enumeratum.values.*
import oolong.bson.*
import org.mongodb.scala.bson.*
import org.scalatest.TryValues
import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers

trait EnumBsonHandlerHelpers { this: AnyFunSpec & Matchers =>
trait EnumBsonHandlerHelpers { this: AnyFunSpec & Matchers & TryValues =>
def testWriter[EntryType <: ValueEnumEntry[ValueType], ValueType](
enumKind: String,
`enum`: ValueEnum[ValueType, EntryType],
Expand All @@ -28,7 +29,7 @@ trait EnumBsonHandlerHelpers { this: AnyFunSpec & Matchers =>
val reader = providedReader.getOrElse(EnumHandler.reader(`enum`))
describe(enumKind) {
it("should read valid values") {
`enum`.values.foreach(entry => reader.fromBson(entry.value.bson).get shouldBe entry)
`enum`.values.foreach(entry => reader.fromBson(entry.value.bson).success.value shouldBe entry)
}
it("should fail to read with invalid values") {
reader.fromBson(BsonInt32(Int.MaxValue)) shouldBe Symbol("failure")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package ru.tinkoff.tcb.bson.enumeratum.values

import oolong.bson.given
import org.scalatest.TryValues
import org.scalatest.funspec.AnyFunSpec
import org.scalatest.matchers.should.Matchers

class EnumBsonHandlerSpec extends AnyFunSpec with Matchers with EnumBsonHandlerHelpers {
class EnumBsonHandlerSpec extends AnyFunSpec with Matchers with TryValues with EnumBsonHandlerHelpers {
describe(".reader") {

testReader("IntEnum", BsonLibraryItem)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ final class MarkdownGenerator(baseUri: Uri) {
} yield ()

private[interpreter] def stepsPrinterW: FunctionK[Step, W] = new (Step ~> W) {
def apply[A](fa: Step[A]): W[A] =
override def apply[A](fa: Step[A]): W[A] =
fa match {
case Describe(text, pos) => Vector(p(text)).tell

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ object Check {
* null value
* @group CheckJson
*/
final case object CheckJsonNull extends CheckJson
case object CheckJsonNull extends CheckJson

/**
* Any valid JSON.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import ru.tinkoff.tcb.mockingbird.edsl.model.Check.*
import ru.tinkoff.tcb.mockingbird.edsl.model.ValueMatcher.syntax.*

class AsyncScalaTestSuiteTest extends AsyncScalaTestSuite with Matchers with AsyncMockFactory with BeforeAndAfterEach {
given Eq[Uri] = Eq.fromUniversalEquals

val eset = new ExampleSet[HttpResponseR] {
override def name: String = ""
}
Expand Down Expand Up @@ -65,9 +67,9 @@ class AsyncScalaTestSuiteTest extends AsyncScalaTestSuite with Matchers with Asy

sttpbackend_ = HttpClientFutureBackend.stub().whenRequestMatchesPartial {
case Request(POST, uri, StringBody(`body`, _, _), hs, _, _, _)
if uri == uri"http://some.domain.com:8090/api/handler?service=world"
&& hs.exists(h => h.name == "x-token" && h.value == "asd5453qwe")
&& hs.exists(h => h.name == "Content-Type" && h.value == "application/json") =>
if uri === uri"http://some.domain.com:8090/api/handler?service=world"
&& hs.exists(h => h.name === "x-token" && h.value === "asd5453qwe")
&& hs.exists(h => h.name === "Content-Type" && h.value === "application/json") =>
new Response[String](
body = "got request",
code = StatusCode.Ok,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class AsyncScalaTestSuiteWholeTest
with AsyncMockFactory
with BeforeAndAfterAll {

given Eq[sttp.model.Method] = Eq.fromUniversalEquals

val eset = new CatsFacts[HttpResponseR]()

var sttpbackend_ : WebSocketBackendStub[Future] =
Expand Down Expand Up @@ -58,8 +60,8 @@ class AsyncScalaTestSuiteWholeTest
sttpbackend_ = HttpClientFutureBackend
.stub()
.whenRequestMatches { req =>
req.method == GET && req.uri.toString() == s"https://localhost.example:9977/fact" &&
req.headers.exists(h => h.name == "X-CSRF-TOKEN" && h.value == "unEENxJqSLS02rji2GjcKzNLc0C0ySlWih9hSxwn")
req.method === GET && req.uri.toString() === s"https://localhost.example:9977/fact" &&
req.headers.exists(h => h.name === "X-CSRF-TOKEN" && h.value === "unEENxJqSLS02rji2GjcKzNLc0C0ySlWih9hSxwn")
}
.thenRespond(
new Response(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.tinkoff.tcb.mockingbird.edsl.interpreter

import org.scalatest.OptionValues
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
import pl.muninn.scalamdtag.*
Expand All @@ -11,7 +12,7 @@ import ru.tinkoff.tcb.mockingbird.edsl.model.Check.*
import ru.tinkoff.tcb.mockingbird.edsl.model.ValueMatcher.syntax.*
import ru.tinkoff.tcb.mockingbird.examples.CatsFacts

class MarkdownGeneratorSuite extends AnyFunSuite with Matchers {
class MarkdownGeneratorSuite extends AnyFunSuite with Matchers with OptionValues {
val eset = new ExampleSet[MarkdownGenerator.HttpResponseR] {
override def name: String = ""
}
Expand All @@ -36,7 +37,7 @@ class MarkdownGeneratorSuite extends AnyFunSuite with Matchers {

val mds = eset.describe(text).foldMap(mdg.stepsPrinterW).written
mds should have length 1
mds.head.md shouldBe ("\n".concat(text).concat("\n"))
mds.headOption.value.md shouldBe ("\n".concat(text).concat("\n"))
}

test("sendHttp produces curl command") {
Expand All @@ -58,7 +59,7 @@ class MarkdownGeneratorSuite extends AnyFunSuite with Matchers {
.written
mds should have length 1

val obtains = mds.head.md
val obtains = mds.headOption.value.md
val expected =
raw"""```
|curl \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,11 @@ class BasicHttpStub[HttpResponseR] extends ExampleSet[HttpResponseR] {
).some,
)
)
idEphemeral = parser.parse(r.body.get).toOption.flatMap((JLens \ "id").getOpt).flatMap(_.asString).get
idEphemeral = r.body
.flatMap(b => parser.parse(b).toOption)
.flatMap((JLens \ "id").getOpt)
.flatMap(_.asString)
.getOrElse(throw new NoSuchElementException("Expected 'id' field in response"))

_ <- describe("And creating a stub in the `countdown` scope with `times` equal to 2.")
resp <- sendHttp(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,13 @@ class HttpStubWithState[HttpResponseR] extends ExampleSet[HttpResponseR] {
).some
)
)
o1v1 = checked.body.flatMap(b => parser.parse(b).toOption).get
o1v1created = (JLens \ "meta" \ "created").getOpt(o1v1).flatMap(_.asString).get
o1v1 = checked.body
.flatMap(b => parser.parse(b).toOption)
.getOrElse(throw new NoSuchElementException("Expected JSON response body"))
o1v1created = (JLens \ "meta" \ "created")
.getOpt(o1v1)
.flatMap(_.asString)
.getOrElse(throw new NoSuchElementException("Expected meta.created in response"))
_ <- describe("And now retrieve the state")
resp <- sendHttp(
method = Post,
Expand Down Expand Up @@ -328,8 +333,13 @@ class HttpStubWithState[HttpResponseR] extends ExampleSet[HttpResponseR] {
).some
)
)
o1v2 = checked.body.flatMap(b => parser.parse(b).toOption).get
o1v2modified = (JLens \ "meta" \ "modified").getOpt(o1v2).flatMap(_.asString).get
o1v2 = checked.body
.flatMap(b => parser.parse(b).toOption)
.getOrElse(throw new NoSuchElementException("Expected JSON response body"))
o1v2modified = (JLens \ "meta" \ "modified")
.getOpt(o1v2)
.flatMap(_.asString)
.getOrElse(throw new NoSuchElementException("Expected meta.modified in response"))
_ <- describe("And again, we request the state of object `o1`")
resp <- sendHttp(
method = Post,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ import sttp.model.Uri
import ru.tinkoff.tcb.mockingbird.edsl.interpreter.AsyncScalaTestSuite

trait BaseSuite extends AsyncScalaTestSuite with TestContainerForAll {
private var httpHost: Uri = scala.compiletime.uninitialized
@annotation.nowarn("msg=is never used")
private var grpcHost: String = scala.compiletime.uninitialized
private var httpHost: Option[Uri] = None

override def baseUri = httpHost
override def baseUri = httpHost.getOrElse(throw new IllegalStateException("httpHost not initialized"))

override val containerDef: DockerComposeContainer.Def =
DockerComposeContainer.Def(
Expand All @@ -34,10 +32,8 @@ trait BaseSuite extends AsyncScalaTestSuite with TestContainerForAll {

val host = containers.getServiceHost("mockingbird", 8228)
val httpPort = containers.getServicePort("mockingbird", 8228)
val grpcPort = containers.getServicePort("mockingbird", 9000)

httpHost = uri"http://$host:$httpPort"
grpcHost = s"$host:$grpcPort"
httpHost = Some(uri"http://$host:$httpPort")

val sb = HttpClientSyncBackend()
val resp = quickRequest
Expand Down
Loading