Skip to content

Commit fa45e23

Browse files
committed
Replace ConfigurableMoshi with MoshiReVoman, to make use of ParameterizedTypes
Signed-off-by: Gopal S Akshintala <[email protected]>
1 parent abcd102 commit fa45e23

File tree

15 files changed

+87
-87
lines changed

15 files changed

+87
-87
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ jobs:
77
- uses: actions/checkout@v4
88
- uses: actions/setup-java@v4
99
with:
10-
distribution: zulu
11-
java-version: 17
10+
distribution: jetbrains
11+
java-version: 21
1212

1313
- name: 'Setup Gradle'
1414
uses: gradle/gradle-build-action@v3

README.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,11 @@ endif::[]
344344
[.lead]
345345
Config built using `Kick.configure()` is *Immutable*.
346346

347-
When there are many tests leveraging the same config with minor modifications, You can define a common config and add your variations (like add more hooks),
347+
When there are many tests leveraging the same config with minor modifications, You can define a common config and add your variations (like add more hooks),
348348
using `override...()` methods,
349349
which are present for all config attributes, to create a new instance of config.
350350

351-
CAUTION: The new instance created from common config using `override...()` replaces the attributes.
351+
CAUTION: The new instance created from common config using `override...()` replaces the attributes.
352352

353353
* For iterable attributes (like `List`, `Map` etc), intentionally there are no methods to `add` or `append` or `prepend` attributes when creating new instance, to prevent any mix-up with the order of attributes. You can use any collection appending utilities to prepend/append previous hooks.
354354

detekt/baseline.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<ID>TooManyFunctions:ResponseConfig.kt$ResponseConfig$Companion</ID>
55
<ID>TooManyFunctions:PostmanEnvironment.kt$PostmanEnvironment&lt;ValueT : Any?> : MutableMap</ID>
66
<ID>TooManyFunctions:ExeUtils.kt$com.salesforce.revoman.internal.exe.ExeUtils.kt</ID>
7-
<ID>LongMethod:ReVoman.kt$ReVoman$private fun executeStepsSerially( pmStepsFlattened: List&lt;Pair&lt;Step, Item>>, kick: Kick, moshiReVoman: ConfigurableMoshi, ): List&lt;StepReport></ID>
7+
<ID>LongMethod:ReVoman.kt$ReVoman$private fun executeStepsSerially( pmStepsFlattened: List&lt;Pair&lt;Step, Item>>, kick: Kick, moshiReVoman: MoshiReVoman, ): List&lt;StepReport></ID>
88
<ID>SpreadOperator:Step.kt$Step$(*FOLDER_DELIMITER.toCharArray())</ID>
99
<ID>SpreadOperator:CaseInsensitiveEnumAdapter.kt$CaseInsensitiveEnumAdapter$(*nameStrings.toTypedArray())</ID>
1010
<ID>TooManyFunctions:JsonWriterUtils.kt$com.salesforce.revoman.input.json.JsonWriterUtils.kt</ID>

src/integrationTest/resources/pm-templates/restfulapidev/restful-api.dev.postman_collection.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
"pm.environment.set(\"objId\", responseJson.id);",
4747
""
4848
],
49-
"type": "text/javascript"
49+
"type": "text/javascript",
50+
"packages": {}
5051
}
5152
},
5253
{
@@ -57,7 +58,8 @@
5758
"pm.environment.set(\"$currentYear\", moment().year())",
5859
"pm.environment.set(\"$randomPrice\", _.random(1, 1000))"
5960
],
60-
"type": "text/javascript"
61+
"type": "text/javascript",
62+
"packages": {}
6163
}
6264
}
6365
],
@@ -66,7 +68,7 @@
6668
"header": [],
6769
"body": {
6870
"mode": "raw",
69-
"raw": "{\n \"name\": \"AI Phone\",\n \"data\": {\n \"year\": {{$currentYear}},\n \"price\": {{$randomPrice}}\n }\n}",
71+
"raw": "{\n \"name\": \"AI Phone\", \"data\": {\n \"year\": {{$currentYear}},\n \"price\": {{$randomPrice}}\n }\n}",
7072
"options": {
7173
"raw": {
7274
"language": "json"
@@ -106,4 +108,4 @@
106108
"response": []
107109
}
108110
]
109-
}
111+
}

src/main/kotlin/com/salesforce/revoman/ReVoman.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.salesforce.revoman.internal.exe.shouldHaltExecution
2525
import com.salesforce.revoman.internal.exe.shouldStepBePicked
2626
import com.salesforce.revoman.internal.exe.unmarshallRequest
2727
import com.salesforce.revoman.internal.exe.unmarshallResponse
28+
import com.salesforce.revoman.internal.json.MoshiReVoman
2829
import com.salesforce.revoman.internal.json.initMoshi
2930
import com.salesforce.revoman.internal.postman.Info
3031
import com.salesforce.revoman.internal.postman.PostmanSDK
@@ -42,7 +43,6 @@ import com.squareup.moshi.adapter
4243
import io.github.oshai.kotlinlogging.KotlinLogging
4344
import io.vavr.control.Either.left
4445
import org.http4k.core.Request
45-
import org.http4k.format.ConfigurableMoshi
4646

4747
object ReVoman {
4848
@JvmStatic
@@ -127,7 +127,7 @@ object ReVoman {
127127
private fun executeStepsSerially(
128128
pmStepsFlattened: List<Step>,
129129
kick: Kick,
130-
moshiReVoman: ConfigurableMoshi,
130+
moshiReVoman: MoshiReVoman,
131131
regexReplacer: RegexReplacer,
132132
pm: PostmanSDK,
133133
): List<StepReport> {

src/main/kotlin/com/salesforce/revoman/internal/exe/PMJSEval.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ import com.salesforce.revoman.output.report.failure.ResponseFailure.PostResJSFai
2121

2222
internal fun executePreReqJS(
2323
currentStep: Step,
24-
item: Item,
24+
itemWithRegex: Item,
2525
pm: PostmanSDK,
2626
): Either<PreReqJSFailure, Unit> {
27-
val preReqJS = item.event?.find { it.listen == "prerequest" }?.script?.exec?.joinToString("\n")
27+
val preReqJS =
28+
itemWithRegex.event?.find { it.listen == "prerequest" }?.script?.exec?.joinToString("\n")
2829
return if (!preReqJS.isNullOrBlank()) {
29-
runCatching(currentStep, PRE_REQ_JS) { executePreReqJSWithPolyglot(preReqJS, item.request, pm) }
30+
runCatching(currentStep, PRE_REQ_JS) {
31+
executePreReqJSWithPolyglot(preReqJS, itemWithRegex.request, pm)
32+
}
3033
.mapLeft { PreReqJSFailure(it, pm.currentStepReport.requestInfo!!.get()) }
3134
} else {
3235
Right(Unit)

src/main/kotlin/com/salesforce/revoman/internal/exe/UnmarshallRequest.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,23 @@ package com.salesforce.revoman.internal.exe
1010
import arrow.core.Either
1111
import arrow.core.Either.Right
1212
import com.salesforce.revoman.input.config.Kick
13+
import com.salesforce.revoman.internal.json.MoshiReVoman
1314
import com.salesforce.revoman.internal.postman.PostmanSDK
1415
import com.salesforce.revoman.output.ExeType.UNMARSHALL_REQUEST
1516
import com.salesforce.revoman.output.report.Step
1617
import com.salesforce.revoman.output.report.TxnInfo
1718
import com.salesforce.revoman.output.report.failure.RequestFailure.UnmarshallRequestFailure
18-
import com.squareup.moshi.rawType
1919
import io.exoquery.pprint
2020
import io.github.oshai.kotlinlogging.KotlinLogging
2121
import java.lang.reflect.Type
2222
import org.http4k.core.ContentType.Companion.APPLICATION_JSON
2323
import org.http4k.core.Request
24-
import org.http4k.format.ConfigurableMoshi
2524

2625
internal fun unmarshallRequest(
2726
currentStep: Step,
2827
pmRequest: com.salesforce.revoman.internal.postman.template.Request,
2928
kick: Kick,
30-
moshiReVoman: ConfigurableMoshi,
29+
moshiReVoman: MoshiReVoman,
3130
pm: PostmanSDK,
3231
): Either<UnmarshallRequestFailure, TxnInfo<Request>> {
3332
val httpRequest = pmRequest.toHttpRequest()
@@ -42,7 +41,7 @@ internal fun unmarshallRequest(
4241
return when {
4342
isJson(httpRequest) ->
4443
runCatching(currentStep, UNMARSHALL_REQUEST) {
45-
pmRequest.body?.let { body -> moshiReVoman.asA(body.raw, requestType.rawType.kotlin) }
44+
pmRequest.body?.let { body -> moshiReVoman.fromJson<Any>(body.raw, requestType) }
4645
}
4746
.mapLeft { UnmarshallRequestFailure(it, TxnInfo(requestType, null, httpRequest)) }
4847
else -> {

src/main/kotlin/com/salesforce/revoman/internal/exe/UnmarshallResponse.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,20 @@ package com.salesforce.revoman.internal.exe
1010
import arrow.core.Either
1111
import arrow.core.Either.Right
1212
import com.salesforce.revoman.input.config.Kick
13+
import com.salesforce.revoman.internal.json.MoshiReVoman
1314
import com.salesforce.revoman.internal.postman.PostmanSDK
1415
import com.salesforce.revoman.output.ExeType.UNMARSHALL_RESPONSE
1516
import com.salesforce.revoman.output.report.TxnInfo
1617
import com.salesforce.revoman.output.report.failure.ResponseFailure.UnmarshallResponseFailure
17-
import com.squareup.moshi.rawType
1818
import io.exoquery.pprint
1919
import io.github.oshai.kotlinlogging.KotlinLogging
2020
import java.lang.reflect.Type
2121
import org.http4k.core.ContentType.Companion.APPLICATION_JSON
2222
import org.http4k.core.Response
23-
import org.http4k.format.ConfigurableMoshi
2423

2524
internal fun unmarshallResponse(
2625
kick: Kick,
27-
moshiReVoman: ConfigurableMoshi,
26+
moshiReVoman: MoshiReVoman,
2827
pm: PostmanSDK,
2928
): Either<UnmarshallResponseFailure, TxnInfo<Response>> {
3029
val httpResponse = pm.currentStepReport.responseInfo!!.get().httpMsg
@@ -44,7 +43,7 @@ internal fun unmarshallResponse(
4443
?.objType ?: Any::class.java
4544
val requestInfo = pm.currentStepReport.requestInfo!!.get()
4645
runCatching(currentStep, UNMARSHALL_RESPONSE) {
47-
moshiReVoman.asA(httpResponse.bodyString(), responseType.rawType.kotlin)
46+
moshiReVoman.fromJson<Any>(httpResponse.bodyString(), responseType)
4847
}
4948
.mapLeft {
5049
UnmarshallResponseFailure(it, requestInfo, TxnInfo(responseType, null, httpResponse))

src/main/kotlin/com/salesforce/revoman/internal/json/MoshiReVoman.kt

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
* http://www.apache.org/licenses/LICENSE-2.0
66
* ************************************************************************************************
77
*/
8-
@file:JvmName("MoshiReVoman")
9-
108
package com.salesforce.revoman.internal.json
119

1210
import com.salesforce.revoman.internal.json.adapters.BigDecimalAdapter
@@ -24,23 +22,58 @@ import dev.zacsweers.moshix.adapters.AdaptedBy
2422
import dev.zacsweers.moshix.adapters.JsonString
2523
import io.vavr.control.Either
2624
import java.lang.reflect.Type
27-
import java.util.Date
28-
import org.http4k.format.ConfigurableMoshi
25+
import java.util.*
2926
import org.http4k.format.EventAdapter
3027
import org.http4k.format.ListAdapter
3128
import org.http4k.format.MapAdapter
3229
import org.http4k.format.ThrowableAdapter
3330
import org.http4k.format.asConfigurable
3431
import org.http4k.format.withStandardMappings
3532

33+
open class MoshiReVoman(builder: Moshi.Builder) {
34+
private val moshi = builder.build()
35+
36+
private fun <PojoT : Any> lenientAdapter(targetType: Type): JsonAdapter<PojoT?> =
37+
moshi.adapter<PojoT>(targetType).lenient()
38+
39+
private inline fun <reified PojoT : Any> lenientAdapter(): JsonAdapter<PojoT?> =
40+
moshi.adapter<PojoT>(PojoT::class.java).lenient()
41+
42+
fun <PojoT : Any> fromJson(input: String?, targetType: Type = Any::class.java): PojoT? =
43+
input?.let { lenientAdapter<PojoT>(targetType).fromJson(it) }
44+
45+
inline fun <reified PojoT : Any> fromJson(input: String?): PojoT? =
46+
fromJson(input, PojoT::class.java)
47+
48+
fun <PojoT : Any> toJson(
49+
input: PojoT?,
50+
sourceType: Type = input?.javaClass ?: Any::class.java,
51+
): String = lenientAdapter<PojoT>(sourceType).toJson(input)
52+
53+
inline fun <reified PojoT : Any> toJson(input: PojoT?): String = toJson(input, PojoT::class.java)
54+
55+
fun <PojoT : Any> toPrettyJson(
56+
input: PojoT?,
57+
sourceType: Type = input?.javaClass ?: Any::class.java,
58+
indent: String = " "
59+
): String = lenientAdapter<PojoT>(sourceType).indent(indent).toJson(input)
60+
61+
inline fun <reified PojoT : Any> toPrettyJson(input: PojoT?, indent: String = " "): String = toPrettyJson(input, PojoT::class.java, indent)
62+
63+
fun <PojoT : Any> objToJsonStrToObj(
64+
input: Any?,
65+
targetType: Type = input?.javaClass ?: Any::class.java,
66+
): PojoT? = lenientAdapter<PojoT>(targetType).fromJson(toJson(input))
67+
}
68+
3669
@JvmOverloads
3770
internal fun initMoshi(
3871
customAdapters: List<Any> = emptyList(),
3972
customAdaptersWithType: Map<Type, List<Either<JsonAdapter<out Any>, Factory>>> = emptyMap(),
4073
typesToIgnore: Set<Class<out Any>> = emptySet(),
41-
): ConfigurableMoshi {
74+
): MoshiReVoman {
4275
val moshiBuilder = buildMoshi(customAdapters, customAdaptersWithType, typesToIgnore)
43-
return object : ConfigurableMoshi(moshiBuilder) {}
76+
return object : MoshiReVoman(moshiBuilder) {}
4477
}
4578

4679
@SuppressWarnings("kotlin:S3923")

src/main/kotlin/com/salesforce/revoman/internal/postman/PostmanSDK.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package com.salesforce.revoman.internal.postman
99

1010
import com.github.underscore.U
11+
import com.salesforce.revoman.internal.json.MoshiReVoman
1112
import com.salesforce.revoman.internal.postman.template.Body
1213
import com.salesforce.revoman.internal.postman.template.Event
1314
import com.salesforce.revoman.internal.postman.template.Header
@@ -21,14 +22,13 @@ import org.graalvm.polyglot.Context
2122
import org.graalvm.polyglot.HostAccess
2223
import org.graalvm.polyglot.Source
2324
import org.graalvm.polyglot.Value
24-
import org.http4k.format.ConfigurableMoshi
2525

2626
/**
2727
* SDK to execute pre-req and post-res js scripts, to be compatible with the Postman API reference:
2828
* https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/
2929
*/
3030
class PostmanSDK(
31-
private val moshiReVoman: ConfigurableMoshi,
31+
private val moshiReVoman: MoshiReVoman,
3232
nodeModulesRelativePath: String? = null,
3333
val regexReplacer: RegexReplacer = RegexReplacer(),
3434
mutableEnv: MutableMap<String, Any?> = mutableMapOf(),
@@ -40,7 +40,7 @@ class PostmanSDK(
4040
lateinit var currentStepReport: StepReport
4141
@Suppress("unused") @JvmField val variables: Variables = Variables()
4242
lateinit var rundown: Rundown
43-
@JvmField val xml2Json = Xml2Json { xml -> moshiReVoman.asA(U.xmlToJson(xml)) }
43+
@JvmField val xml2Json = Xml2Json { xml -> moshiReVoman.fromJson(U.xmlToJson(xml)) }
4444
// * NOTE 28 Apr 2024 gopala.akshintala: This has to be initialized at last
4545
private val jsEvaluator: JSEvaluator = JSEvaluator(nodeModulesRelativePath)
4646

0 commit comments

Comments
 (0)