Skip to content

Instantly share code, notes, and snippets.

@dai0304
Created March 24, 2019 12:59
Show Gist options
  • Save dai0304/5f879548ec982f3e6a5781a185901f9b to your computer and use it in GitHub Desktop.
Save dai0304/5f879548ec982f3e6a5781a185901f9b to your computer and use it in GitHub Desktop.
import assertk.Assert
import assertk.all
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.containsExactly
import assertk.assertions.hasSize
import assertk.assertions.isEqualTo
import assertk.assertions.isLessThan
import assertk.assertions.isTrue
import assertk.assertions.support.expected
import assertk.assertions.support.show
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ArrayNode
import com.fasterxml.jackson.databind.node.BigIntegerNode
import com.fasterxml.jackson.databind.node.BooleanNode
import com.fasterxml.jackson.databind.node.DecimalNode
import com.fasterxml.jackson.databind.node.DoubleNode
import com.fasterxml.jackson.databind.node.FloatNode
import com.fasterxml.jackson.databind.node.IntNode
import com.fasterxml.jackson.databind.node.LongNode
import com.fasterxml.jackson.databind.node.NullNode
import com.fasterxml.jackson.databind.node.ObjectNode
import com.fasterxml.jackson.databind.node.ShortNode
import com.fasterxml.jackson.databind.node.TextNode
import com.fasterxml.jackson.databind.node.ValueNode
import com.jayway.jsonpath.Configuration
import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider
import org.junit.Test
import java.math.BigDecimal
import java.math.BigInteger
class JsonNodeAssertTest {
@Test
fun testExample() {
val objectJson = """
{
"foo": "aaa",
"bar": 1,
"baz": true,
"qux": null,
"quux": [ "bbb", "ccc" ],
"corge": {
"grault": "ddd",
"garply": "eee",
"waldo": "fff"
}
}
"""
assertThat(jsonNodeOf(objectJson)).isObject().all {
jsonPath("$.foo").isString().isEqualTo("aaa")
// or jsonPath("$.foo").isEqualTo("aaa")
jsonPath("$.bar").isInt().isLessThan(10)
jsonPath("$.baz").isBoolean().isTrue()
jsonPath("$.qux").isNullLiteral()
jsonPath("$.quux").isValueNodeArray().all {
hasSize(2)
containsExactly("bbb", "ccc")
}
jsonPath("$.corge").isObject().all {
jsonPath("$.grault").isString().contains("DD", ignoreCase = true)
jsonPath("$.garply").isString().isEqualTo("eee")
}
jsonPath("$.corge.waldo").isString().isEqualTo("fff")
}
}
}
private val mapper = ObjectMapper()
private val jsonPathConf = Configuration.builder()
.jsonProvider(JacksonJsonNodeJsonProvider(mapper))
.build()
fun jsonNodeOf(str: String) = mapper.readTree(str)
fun Assert<JsonNode>.isInt(): Assert<Int> = transform { actual ->
if (actual.isInt) return@transform actual.intValue()
expected("class:${show(Int::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isShort(): Assert<Short> = transform { actual ->
if (actual.isShort) return@transform actual.shortValue()
expected("class:${show(Int::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isLong(): Assert<Long> = transform { actual ->
if (actual.isLong) return@transform actual.longValue()
expected("class:${show(Long::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isBigInteger(): Assert<BigInteger> = transform { actual ->
if (actual.isBigInteger) return@transform actual.bigIntegerValue()
expected("class:${show(BigInteger::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isString(): Assert<String> = transform { actual ->
if (actual.isTextual) return@transform actual.textValue()
expected("class:${show(String::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isFloat(): Assert<Float> = transform { actual ->
if (actual.isFloat) return@transform actual.floatValue()
expected("class:${show(Double::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isDouble(): Assert<Double> = transform { actual ->
if (actual.isDouble) return@transform actual.doubleValue()
expected("class:${show(Double::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isBigDecimal(): Assert<BigDecimal> = transform { actual ->
if (actual.isBigDecimal) return@transform actual.decimalValue()
expected("class:${show(BigDecimal::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isBoolean(): Assert<Boolean> = transform { actual ->
if (actual.isBoolean) return@transform actual.booleanValue()
expected("class:${show(Boolean::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isObject(): Assert<ObjectNode> = transform { actual ->
if (actual.isObject) return@transform actual as ObjectNode
expected("class:${show(ObjectNode::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isArray(): Assert<ArrayNode> = transform { actual ->
if (actual.isArray) return@transform actual as ArrayNode
expected("class:${show(ArrayNode::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isValueNodeArray(): Assert<List<Any?>> = transform { actual ->
if (actual.isArray) {
return@transform Sequence { actual.elements() }.onEach {
if (it is ValueNode == false) {
expected("element class:${show(ValueNode::class)} but was element class:${show(it::class)}")
}
}.map {
@Suppress("IMPLICIT_CAST_TO_ANY")
when (it) {
is DoubleNode -> it.doubleValue()
is FloatNode -> it.floatValue()
is IntNode -> it.intValue()
is BigIntegerNode -> it.bigIntegerValue()
is DecimalNode -> it.decimalValue()
is ShortNode -> it.shortValue()
is LongNode -> it.longValue()
is NullNode -> null
is BooleanNode -> it.booleanValue()
is TextNode -> it.textValue()
else -> throw AssertionError("Unexpected node type ${it::class.java}")
}
}.toList()
}
expected("class:${show(ArrayNode::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.isNullLiteral(): Assert<NullNode> = transform { actual ->
if (actual.isNull) return@transform actual as NullNode
expected("class:${show(NullNode::class)} but was class:${show(actual::class)}")
}
fun Assert<JsonNode>.jsonPath(path: String): Assert<JsonNode> = transform { actual ->
return@transform JsonPath.using(jsonPathConf).parse(actual).read<JsonNode>(path)
}
@dai0304
Copy link
Author

dai0304 commented Mar 24, 2019

dependencies

implementation 'com.willowtreeapps.assertk:assertk-jvm:0.13'
implementation 'com.jayway.jsonpath:json-path:2.4.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment