-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move examples and DSL for it to the separate project
- Loading branch information
Aleksei Shashev
committed
Aug 1, 2023
1 parent
643aa1b
commit 80fd925
Showing
19 changed files
with
386 additions
and
293 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
133 changes: 133 additions & 0 deletions
133
...amples/src/main/scala/ru/tinkoff/tcb/mockingbird/edsl/interpreter/MarkdownGenerator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package ru.tinkoff.tcb.mockingbird.edsl.interpreter | ||
|
||
import cats.arrow.FunctionK | ||
import cats.data.Writer | ||
import io.circe.Json | ||
import mouse.boolean.* | ||
import pl.muninn.scalamdtag.* | ||
import pl.muninn.scalamdtag.tags.Markdown | ||
|
||
import ru.tinkoff.tcb.mockingbird.edsl.ExampleSet | ||
import ru.tinkoff.tcb.mockingbird.edsl.interpreter.buildRequest | ||
import ru.tinkoff.tcb.mockingbird.edsl.model.* | ||
import ru.tinkoff.tcb.mockingbird.edsl.model.HttpMethod.Delete | ||
import ru.tinkoff.tcb.mockingbird.edsl.model.HttpMethod.Get | ||
import ru.tinkoff.tcb.mockingbird.edsl.model.HttpMethod.Post | ||
|
||
object MarkdownGenerator { | ||
type HttpResponseR = {} | ||
private val httpResponseR: HttpResponseR = new {} | ||
|
||
def apply(host: String): MarkdownGenerator = | ||
new MarkdownGenerator(host) | ||
|
||
private object implicits { | ||
implicit val httpMethodShow: Show[HttpMethod] = new Show[HttpMethod] { | ||
override def show(m: HttpMethod): String = | ||
m match { | ||
case Delete => "DELETE" | ||
case Get => "GET" | ||
case Post => "POST" | ||
} | ||
} | ||
|
||
implicit def valueMatcherShow[T: Show]: Show[ValueMatcher[T]] = | ||
(vm: ValueMatcher[T]) => | ||
vm match { | ||
case AnyValue(example) => example.show | ||
case FixedValue(value) => value.show | ||
} | ||
|
||
implicit class ValueMatcherOps[T](private val vm: ValueMatcher[T]) extends AnyVal { | ||
def value: T = vm match { | ||
case AnyValue(example) => example | ||
case FixedValue(value) => value | ||
} | ||
} | ||
|
||
implicit val checkShow: Show[Check] = (check: Check) => | ||
check match { | ||
case CheckAny(example) => example | ||
case CheckInteger(matcher) => matcher.show | ||
case CheckString(matcher) => matcher.show | ||
case cj: CheckJson => buildJson(cj).spaces2 | ||
} | ||
|
||
def buildJson(cj: CheckJson): Json = | ||
cj match { | ||
case CheckJsonAny(example) => example | ||
case CheckJsonArray(items*) => Json.arr(items.map(buildJson): _*) | ||
case CheckJsonNull => Json.Null | ||
case CheckJsonNumber(matcher) => Json.fromDoubleOrNull(matcher.value) | ||
case CheckJsonObject(fields*) => Json.obj(fields.map { case (n, v) => n -> buildJson(v) }: _*) | ||
case CheckJsonString(matcher) => Json.fromString(matcher.value) | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
class MarkdownGenerator(host: String) { | ||
import MarkdownGenerator.HttpResponseR | ||
import MarkdownGenerator.httpResponseR | ||
import MarkdownGenerator.implicits.* | ||
import cats.syntax.writer.* | ||
|
||
type W[A] = Writer[Vector[Markdown], A] | ||
|
||
def generate(set: ExampleSet[HttpResponseR]): String = { | ||
val tags = for { | ||
_ <- Vector(h1(set.name)).tell | ||
_ <- set.examples.traverse(generate) | ||
} yield () | ||
|
||
markdown(tags.written).md | ||
} | ||
|
||
def generate(desc: ExampleDescription): W[Unit] = | ||
for { | ||
_ <- Vector[Markdown](h2(desc.name)).tell | ||
_ <- desc.steps.foldMap(stepsPrinterW) | ||
} yield () | ||
|
||
def stepsPrinterW: FunctionK[Step, W] = new (Step ~> W) { | ||
def apply[A](fa: Step[A]): W[A] = | ||
fa match { | ||
case Describe(text, pos) => Vector(p(text)).tell | ||
|
||
case SendHttp(request, pos) => | ||
val skipCurlStrings = Seq("--max-redirs", "--location", "Content-Length") | ||
val sreq = buildRequest(host, request).toCurl | ||
.split("\n") | ||
.filterNot(s => skipCurlStrings.exists(r => s.contains(r))) | ||
.mkString("", "\n", "\n") | ||
Writer(Vector(codeBlock(sreq)), httpResponseR.asInstanceOf[A]) | ||
|
||
case CheckHttp(_, HttpResponseExpected(None, None, Seq()), _) => | ||
Writer value HttpResponse(0, None, Seq.empty) | ||
|
||
case CheckHttp(_, HttpResponseExpected(code, body, headers), _) => | ||
val bodyStr = body.map(_.show) | ||
val cb = Vector( | ||
code.map(c => s"Код ответа: ${c.matcher.show}\n"), | ||
headers.nonEmpty.option { | ||
headers.map { case (k, v) => s"$k: '${v.matcher.show}'\n" }.mkString("Заголовки ответа:\n", "\n", "") | ||
}, | ||
bodyStr.map("Тело ответа:\n" ++ _ ++ "\n"), | ||
).flatten.mkString("\n") | ||
|
||
Writer( | ||
Vector( | ||
p("Ответ:"), | ||
codeBlock(cb) | ||
), | ||
HttpResponse( | ||
code.fold(0L)(_.matcher.value).toInt, | ||
bodyStr, | ||
headers.map { case (k, c) => k -> c.matcher.value }, | ||
) | ||
) | ||
} | ||
} | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
backend/examples/src/main/scala/ru/tinkoff/tcb/mockingbird/edsl/interpreter/package.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package ru.tinkoff.tcb.mockingbird.edsl | ||
|
||
import sttp.client3.* | ||
import sttp.model.Uri | ||
|
||
import ru.tinkoff.tcb.mockingbird.edsl.model.HttpRequest | ||
import ru.tinkoff.tcb.mockingbird.edsl.model.HttpMethod.* | ||
|
||
package object interpreter { | ||
def makeUri(host: String, req: HttpRequest): Uri = { | ||
val endpoint = s"${host}${req.path}" | ||
val query = req.query | ||
uri"$endpoint?$query" | ||
} | ||
|
||
def buildRequest(host: String, m: HttpRequest): Request[String, Any] = { | ||
var req = m.body.fold(quickRequest)(quickRequest.body) | ||
req = m.headers.foldLeft(req) { case (r, (k, v)) => r.header(k, v, replaceExisting = true) } | ||
val url = makeUri(host, m) | ||
m.method match { | ||
case Delete => req.delete(url) | ||
case Get => req.get(url) | ||
case Post => req.post(url) | ||
} | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
backend/examples/src/main/scala/ru/tinkoff/tcb/mockingbird/examples/Main.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package ru.tinkoff.tcb.mockingbird.examples | ||
|
||
import ru.tinkoff.tcb.mockingbird.edsl.interpreter.MarkdownGenerator | ||
|
||
object Main extends ZIOAppDefault { | ||
def run: ZIO[Environment with ZIOAppArgs with Scope, Any, Any] = program | ||
|
||
val basicHttpStub = new BasicHttpStub[MarkdownGenerator.HttpResponseR]() | ||
val interpretator = MarkdownGenerator("http://localhost:8228") | ||
|
||
val program = | ||
for { | ||
_ <- Console.print(interpretator.generate(basicHttpStub)) | ||
} yield () | ||
} |
Oops, something went wrong.