From 10df2a5d7d6dfdbac7d8a740f0a665d55bb0063c Mon Sep 17 00:00:00 2001 From: Hernan Najles Date: Mon, 16 Jan 2023 12:47:57 -0300 Subject: [PATCH] Add jsonld instance rendering by syntax, using terms names without looking the schema --- .../platform/JsonLDSchemaElementClient.scala | 27 ++++++++ .../config/JsonLDSchemaConfiguration.scala | 57 ++++++++++------- .../scala/JsonLDSchemaElementClient.scala | 27 ++++++++ .../config/JsonLDSchemaConfiguration.scala | 3 +- .../domain/jsonldinstance/JsonLDObject.scala | 5 +- .../scala/render/JsonLDObjectRender.scala | 63 +++++++++++++++++++ .../convert/ShapesBaseConverter.scala | 42 ++++++++++--- .../render/JsonLDObjectRenderTest.scala | 48 ++++++++++++++ 8 files changed, 239 insertions(+), 33 deletions(-) create mode 100644 amf-shapes/shared/src/main/scala/amf/shapes/client/platform/JsonLDSchemaElementClient.scala create mode 100644 amf-shapes/shared/src/main/scala/amf/shapes/client/scala/JsonLDSchemaElementClient.scala create mode 100644 amf-shapes/shared/src/main/scala/amf/shapes/client/scala/render/JsonLDObjectRender.scala create mode 100644 amf-shapes/shared/src/test/scala/amf/shapes/client/jsonldschema/render/JsonLDObjectRenderTest.scala diff --git a/amf-shapes/shared/src/main/scala/amf/shapes/client/platform/JsonLDSchemaElementClient.scala b/amf-shapes/shared/src/main/scala/amf/shapes/client/platform/JsonLDSchemaElementClient.scala new file mode 100644 index 0000000000..aa8b9898e4 --- /dev/null +++ b/amf-shapes/shared/src/main/scala/amf/shapes/client/platform/JsonLDSchemaElementClient.scala @@ -0,0 +1,27 @@ +package amf.shapes.client.platform + +import amf.aml.client.platform.BaseAMLElementClient +import amf.core.client.platform.model.domain.DomainElement +import amf.core.internal.render.YNodeDocBuilderPopulator +import amf.shapes.client.platform.config.JsonLDSchemaConfiguration +import amf.shapes.client.scala.{JsonLDSchemaElementClient => InternalJsonLDSchemaElementClient} +import amf.shapes.internal.convert.ShapeClientConverters._ +import org.yaml.builder.DocBuilder + +import scala.scalajs.js.annotation.JSExportAll + +@JSExportAll +class JsonLDSchemaElementClient private[amf] (private[amf] val _internal: InternalJsonLDSchemaElementClient) + extends BaseAMLElementClient(_internal) { + + private[amf] def this(configuration: JsonLDSchemaConfiguration) = { + this(new InternalJsonLDSchemaElementClient(configuration)) + } + + override def getConfiguration(): JsonLDSchemaConfiguration = _internal.getConfiguration + + override def renderToBuilder[T](element: DomainElement, builder: DocBuilder[T]): Unit = { + val node = _internal.renderElement(element, Nil) + YNodeDocBuilderPopulator.populate(node, builder) + } +} diff --git a/amf-shapes/shared/src/main/scala/amf/shapes/client/platform/config/JsonLDSchemaConfiguration.scala b/amf-shapes/shared/src/main/scala/amf/shapes/client/platform/config/JsonLDSchemaConfiguration.scala index 5eeba12075..794ca623bf 100644 --- a/amf-shapes/shared/src/main/scala/amf/shapes/client/platform/config/JsonLDSchemaConfiguration.scala +++ b/amf-shapes/shared/src/main/scala/amf/shapes/client/platform/config/JsonLDSchemaConfiguration.scala @@ -1,6 +1,7 @@ package amf.shapes.client.platform.config import amf.aml.client.platform.model.document.Dialect +import amf.core.client.platform.AMFGraphElementClient import amf.core.client.platform.config.AMFEventListener import amf.core.client.platform.errorhandling.ErrorHandlerProvider import amf.core.client.platform.execution.ExecutionEnvironment @@ -9,35 +10,41 @@ import amf.core.client.platform.resource.ResourceLoader import amf.core.client.scala.transform._ import amf.core.client.platform.config._ import amf.core.internal.convert.CoreClientConverters.ClientFuture -import amf.shapes.client.platform.{BaseShapesConfiguration, ShapesConfiguration} -import amf.shapes.client.scala.config.{JsonLDSchemaConfiguration => InternalJsonLDSchemaDocumentConfiguration, JsonLDSchemaConfigurationClient => InternalJsonLDSchemaConfigurationClient} +import amf.shapes.client.platform.{BaseShapesConfiguration, JsonLDSchemaElementClient, ShapesConfiguration} +import amf.shapes.client.scala.config.{ + JsonLDSchemaConfiguration => InternalJsonLDSchemaDocumentConfiguration, + JsonLDSchemaConfigurationClient => InternalJsonLDSchemaConfigurationClient +} import amf.shapes.internal.convert.ShapeClientConverters._ import amf.core.internal.convert.ClientErrorHandlerConverter._ - - import scala.scalajs.js.annotation.{JSExportAll, JSExportTopLevel} @JSExportAll -class JsonLDSchemaConfiguration private [amf]( - private [amf] override val _internal: InternalJsonLDSchemaDocumentConfiguration +class JsonLDSchemaConfiguration private[amf] ( + private[amf] override val _internal: InternalJsonLDSchemaDocumentConfiguration ) extends BaseShapesConfiguration(_internal) { /** Contains common AMF graph operations associated to documents */ override def baseUnitClient(): JsonLDSchemaConfigurationClient = _internal.baseUnitClient() - override def withParsingOptions(parsingOptions: ParsingOptions): JsonLDSchemaConfiguration = _internal.withParsingOptions(parsingOptions) + override def elementClient(): JsonLDSchemaElementClient = _internal.elementClient() + + override def withParsingOptions(parsingOptions: ParsingOptions): JsonLDSchemaConfiguration = + _internal.withParsingOptions(parsingOptions) - override def withRenderOptions(renderOptions: RenderOptions): JsonLDSchemaConfiguration = _internal.withRenderOptions(renderOptions) + override def withRenderOptions(renderOptions: RenderOptions): JsonLDSchemaConfiguration = + _internal.withRenderOptions(renderOptions) -/** Add a [[ResourceLoader]] - * @param rl - * [[ResourceLoader]] to add to configuration object - * @return - * [[ShapesConfiguration]] with the [[ResourceLoader]] added - */ + /** Add a [[ResourceLoader]] + * @param rl + * [[ResourceLoader]] to add to configuration object + * @return + * [[ShapesConfiguration]] with the [[ResourceLoader]] added + */ - override def withResourceLoader(rl: ResourceLoader): JsonLDSchemaConfiguration = _internal.withResourceLoader(ResourceLoaderMatcher.asInternal(rl)) + override def withResourceLoader(rl: ResourceLoader): JsonLDSchemaConfiguration = + _internal.withResourceLoader(ResourceLoaderMatcher.asInternal(rl)) /** Set the configuration [[ResourceLoader]]s * @@ -47,23 +54,29 @@ class JsonLDSchemaConfiguration private [amf]( * [[ShapesConfiguration]] with [[ResourceLoader]]s set */ - override def withResourceLoaders(rl: ClientList[ResourceLoader]): JsonLDSchemaConfiguration = _internal.withResourceLoaders(rl.asInternal.toList) + override def withResourceLoaders(rl: ClientList[ResourceLoader]): JsonLDSchemaConfiguration = + _internal.withResourceLoaders(rl.asInternal.toList) - override def withUnitCache(cache: UnitCache): JsonLDSchemaConfiguration = _internal.withUnitCache(UnitCacheMatcher.asInternal(cache)) + override def withUnitCache(cache: UnitCache): JsonLDSchemaConfiguration = + _internal.withUnitCache(UnitCacheMatcher.asInternal(cache)) - def withTransformationPipeline(pipeline: TransformationPipeline): JsonLDSchemaConfiguration = _internal.withTransformationPipeline(pipeline) + def withTransformationPipeline(pipeline: TransformationPipeline): JsonLDSchemaConfiguration = + _internal.withTransformationPipeline(pipeline) - override def withErrorHandlerProvider(provider: ErrorHandlerProvider): JsonLDSchemaConfiguration = _internal.withErrorHandlerProvider(() => provider.errorHandler()) + override def withErrorHandlerProvider(provider: ErrorHandlerProvider): JsonLDSchemaConfiguration = + _internal.withErrorHandlerProvider(() => provider.errorHandler()) - override def withEventListener(listener: AMFEventListener): JsonLDSchemaConfiguration = _internal.withEventListener(listener) + override def withEventListener(listener: AMFEventListener): JsonLDSchemaConfiguration = + _internal.withEventListener(listener) - def withExecutionEnvironment(executionEnv: ExecutionEnvironment): JsonLDSchemaConfiguration = _internal.withExecutionEnvironment(executionEnv._internal) + def withExecutionEnvironment(executionEnv: ExecutionEnvironment): JsonLDSchemaConfiguration = + _internal.withExecutionEnvironment(executionEnv._internal) override def withDialect(dialect: Dialect): JsonLDSchemaConfiguration = _internal.withDialect(dialect) def withDialect(url: String): ClientFuture[JsonLDSchemaConfiguration] = _internal.withDialect(url).asClient - def forInstance(url:String): ClientFuture[JsonLDSchemaConfiguration] = _internal.forInstance(url).asClient + def forInstance(url: String): ClientFuture[JsonLDSchemaConfiguration] = _internal.forInstance(url).asClient } @JSExportAll diff --git a/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/JsonLDSchemaElementClient.scala b/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/JsonLDSchemaElementClient.scala new file mode 100644 index 0000000000..ae2ed00f1f --- /dev/null +++ b/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/JsonLDSchemaElementClient.scala @@ -0,0 +1,27 @@ +package amf.shapes.client.scala + +import amf.core.client.scala.model.document.BaseUnit +import amf.core.client.scala.model.domain.DomainElement +import amf.core.internal.render.BaseEmitters.traverse +import amf.shapes.client.scala.config.JsonLDSchemaConfiguration +import amf.shapes.client.scala.model.domain.jsonldinstance.JsonLDObject +import amf.shapes.client.scala.render.{JsonLDObjectRender, TermNameSyntaxProvider} +import org.yaml.builder.YDocumentBuilder +import org.yaml.model.{YDocument, YNode} + +class JsonLDSchemaElementClient private[amf] (override protected val configuration: JsonLDSchemaConfiguration) + extends ShapesElementClient(configuration) { + override def renderElement(element: DomainElement, references: Seq[BaseUnit]): YNode = { + element match { + case jsonLdObject: JsonLDObject => + val emitter = new JsonLDObjectRender(jsonLdObject, TermNameSyntaxProvider) + val document = YDocument { b => + traverse(Seq(emitter), b) + } + document.node + case _ => super.renderElement(element, references) + } + } + + override def getConfiguration: JsonLDSchemaConfiguration = configuration +} diff --git a/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/config/JsonLDSchemaConfiguration.scala b/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/config/JsonLDSchemaConfiguration.scala index 6e5098fd35..bb90fa9c30 100644 --- a/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/config/JsonLDSchemaConfiguration.scala +++ b/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/config/JsonLDSchemaConfiguration.scala @@ -18,7 +18,7 @@ import amf.core.internal.registries.AMFRegistry import amf.core.internal.resource.AMFResolvers import amf.core.internal.validation.EffectiveValidations import amf.core.internal.validation.core.ValidationProfile -import amf.shapes.client.scala.ShapesConfiguration +import amf.shapes.client.scala.{JsonLDSchemaElementClient, ShapesConfiguration, ShapesElementClient} import amf.shapes.client.scala.model.document.JsonSchemaDocument import amf.shapes.internal.convert.JsonLDSchemaRegister import amf.shapes.internal.plugins.render.AMFJsonLDSchemaGraphRenderPlugin @@ -53,6 +53,7 @@ class JsonLDSchemaConfiguration private[amf] ( ) override def baseUnitClient(): JsonLDSchemaConfigurationClient = new JsonLDSchemaConfigurationClient(this) + override def elementClient(): JsonLDSchemaElementClient = new JsonLDSchemaElementClient(this) def withJsonLDSchema(jsonDocument: JsonSchemaDocument): JsonLDSchemaConfiguration = { val transformed = if (!jsonDocument.processingData.transformed.value()) transform(jsonDocument) else jsonDocument diff --git a/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/model/domain/jsonldinstance/JsonLDObject.scala b/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/model/domain/jsonldinstance/JsonLDObject.scala index ee5bafb244..5bb5abc4c0 100644 --- a/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/model/domain/jsonldinstance/JsonLDObject.scala +++ b/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/model/domain/jsonldinstance/JsonLDObject.scala @@ -55,7 +55,10 @@ case class JsonLDObject( private def buildArray(values: Seq[JsonLDElement]) = JsonLDArray(values) - private def updateModel(field: Field) = model.copy(fields = model.fields.filterNot(_ == field) :+ field) + private def updateModel(field: Field) = { + if (model.fields.contains(field)) model // preserve initial order + else model.copy(fields = model.fields :+ field) + } private def copyWithProperty(field: Field, element: JsonLDElement) = copy(fields = fields.copy(), model = updateModel(field)).set(field, element) diff --git a/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/render/JsonLDObjectRender.scala b/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/render/JsonLDObjectRender.scala new file mode 100644 index 0000000000..ffe73fc580 --- /dev/null +++ b/amf-shapes/shared/src/main/scala/amf/shapes/client/scala/render/JsonLDObjectRender.scala @@ -0,0 +1,63 @@ +package amf.shapes.client.scala.render + +import amf.core.client.platform.model.DataTypes +import amf.core.client.scala.model.domain.{AmfArray, AmfElement, AmfScalar} +import amf.core.client.scala.vocabulary.{Namespace, ValueType} +import amf.core.internal.metamodel.{Obj, Type} +import amf.core.internal.metamodel.Type.{ArrayLike, Scalar} +import amf.core.internal.parser.domain.Value +import amf.core.internal.render.emitters.PartEmitter +import amf.shapes.client.scala.model.domain.jsonldinstance.JsonLDObject +import org.mulesoft.common.client.lexical.Position +import org.yaml.model.{YDocument, YNode} +import org.yaml.model.YDocument.{EntryBuilder, PartBuilder} + +class JsonLDObjectRender(obj: JsonLDObject, syntaxProvider: SyntaxProvider) extends PartEmitter { + override def emit(b: YDocument.PartBuilder): Unit = { + emitObject(obj, b) + } + + private def emitElement(element: AmfElement, pb: PartBuilder): Unit = element match { + case scalar: AmfScalar => emitScalar(scalar, pb) + case arr: AmfArray => emitArray(arr, pb) + case obj: JsonLDObject => emitObject(obj, pb) + case _ => ??? + } + + private def emitObject(innerObj: JsonLDObject, builder: YDocument.PartBuilder): Unit = { + builder.obj(eb => { + innerObj.meta.fields.filter(f => innerObj.fields.exists(f)).foreach { field => + val element: AmfElement = innerObj.fields.get(field) + val pbFunc: PartBuilder => Unit = (pb: PartBuilder) => { + emitElement(element, pb) + } + eb.entry(syntaxProvider.keyFor(obj.meta.typeIris.head, field.value.iri()), pbFunc) + } + }) + } + + private def emitArray(arr: AmfArray, pb: PartBuilder) = { + pb.list(f => arr.values.foreach(emitElement(_, f))) + } + + private def emitScalar(scalar: AmfScalar, pb: PartBuilder): Unit = { + scalar.value match { + case s: String => pb += s + case i: Int => pb += i + case f: Float => pb += f + case b: Boolean => pb += b + case _ => pb += YNode.Null + } + } + + override def position(): Position = Position.ZERO +} + +trait SyntaxProvider { + + def keyFor(clazz: String, property: String): String +} + +object TermNameSyntaxProvider extends SyntaxProvider { + override def keyFor(clazz: String, property: String): String = ValueType(property).name +} diff --git a/amf-shapes/shared/src/main/scala/amf/shapes/internal/convert/ShapesBaseConverter.scala b/amf-shapes/shared/src/main/scala/amf/shapes/internal/convert/ShapesBaseConverter.scala index 419c80d4d4..49731a756c 100644 --- a/amf-shapes/shared/src/main/scala/amf/shapes/internal/convert/ShapesBaseConverter.scala +++ b/amf-shapes/shared/src/main/scala/amf/shapes/internal/convert/ShapesBaseConverter.scala @@ -3,11 +3,21 @@ package amf.shapes.internal.convert import amf.aml.internal.convert.VocabulariesBaseConverter import amf.core.internal.convert.BidirectionalMatcher import amf.core.internal.unsafe.PlatformSecrets -import amf.shapes.client.platform.config.{JsonLDSchemaConfiguration, JsonLDSchemaConfigurationClient, AMFSemanticSchemaResult => ClientAMFSemanticSchemaResult, SemanticJsonSchemaConfiguration => ClientSemanticJsonSchemaConfiguration} +import amf.shapes.client.platform.config.{ + JsonLDSchemaConfiguration, + JsonLDSchemaConfigurationClient, + AMFSemanticSchemaResult => ClientAMFSemanticSchemaResult, + SemanticJsonSchemaConfiguration => ClientSemanticJsonSchemaConfiguration +} import amf.shapes.client.platform.model.document.{JsonSchemaDocument => ClientJsonSchemaDocument} import amf.shapes.client.scala.model.document.JsonSchemaDocument import amf.shapes.client.platform.model.domain -import amf.shapes.client.platform.{JsonLDInstanceResult, JsonLDSchemaResult, ShapesConfiguration => ClientShapesConfiguration} +import amf.shapes.client.platform.{ + JsonLDInstanceResult, + JsonLDSchemaElementClient, + JsonLDSchemaResult, + ShapesConfiguration => ClientShapesConfiguration +} import amf.shapes.client.scala.ShapesConfiguration import amf.shapes.client.scala.config.{AMFSemanticSchemaResult, SemanticJsonSchemaConfiguration, JsonLDSchemaConfiguration => InternalJsonLDSchemaConfiguration, JsonLDSchemaConfigurationClient => InternalJsonLDSchemaConfigurationClient} import amf.shapes.client.scala.model.domain._ @@ -15,7 +25,11 @@ import amf.shapes.client.scala.model.domain.federation._ import amf.shapes.client.platform.model.domain.jsonldinstance.{JsonLDArray, JsonLDElement, JsonLDObject, JsonLDScalar} import amf.shapes.client.scala.model.domain.jsonldinstance import amf.shapes.client.scala.model.domain.operations._ -import amf.shapes.client.scala.{JsonLDInstanceResult => InternalJsonLDInstanceResult, JsonLDSchemaResult => InternalJsonLDSchemaResult} +import amf.shapes.client.scala.{ + JsonLDSchemaElementClient => InternalJsonLDSchemaElementClient, + JsonLDInstanceResult => InternalJsonLDInstanceResult, + JsonLDSchemaResult => InternalJsonLDSchemaResult +} trait ShapesBaseConverter extends VocabulariesBaseConverter @@ -214,7 +228,6 @@ trait SemanticSchemaConfigurationConverter { } } - trait AMFSemanticSchemaResultConverter { implicit object AMFSemanticSchemaResultMatcher extends BidirectionalMatcher[AMFSemanticSchemaResult, ClientAMFSemanticSchemaResult] { @@ -377,16 +390,18 @@ trait JsonLDElementConverter extends PlatformSecrets { } -trait JsonLDSchemaResultConverter extends PlatformSecrets{ - implicit object JsonLDSchemaResultConverter extends BidirectionalMatcher[InternalJsonLDSchemaResult, JsonLDSchemaResult]{ +trait JsonLDSchemaResultConverter extends PlatformSecrets { + implicit object JsonLDSchemaResultConverter + extends BidirectionalMatcher[InternalJsonLDSchemaResult, JsonLDSchemaResult] { override def asInternal(from: JsonLDSchemaResult): InternalJsonLDSchemaResult = from._internal override def asClient(from: InternalJsonLDSchemaResult): JsonLDSchemaResult = new JsonLDSchemaResult(from) } } -trait JsonLDInstanceResultConverter extends PlatformSecrets{ - implicit object JsonLDInstanceResultConverter extends BidirectionalMatcher[InternalJsonLDInstanceResult, JsonLDInstanceResult]{ +trait JsonLDInstanceResultConverter extends PlatformSecrets { + implicit object JsonLDInstanceResultConverter + extends BidirectionalMatcher[InternalJsonLDInstanceResult, JsonLDInstanceResult] { override def asInternal(from: JsonLDInstanceResult): InternalJsonLDInstanceResult = from._internal override def asClient(from: InternalJsonLDInstanceResult): JsonLDInstanceResult = new JsonLDInstanceResult(from) @@ -397,7 +412,16 @@ trait JsonLDSchemaConfigurationConverter extends PlatformSecrets{ implicit object JsonLDSchemaConfigurationConverter extends BidirectionalMatcher[InternalJsonLDSchemaConfiguration, JsonLDSchemaConfiguration]{ override def asInternal(from: JsonLDSchemaConfiguration): InternalJsonLDSchemaConfiguration = from._internal - override def asClient(from: InternalJsonLDSchemaConfiguration): JsonLDSchemaConfiguration = new JsonLDSchemaConfiguration(from) + override def asClient(from: InternalJsonLDSchemaConfiguration): JsonLDSchemaConfiguration = + new JsonLDSchemaConfiguration(from) + } + + implicit object JsonLDSchemaElementClientConverter + extends BidirectionalMatcher[InternalJsonLDSchemaElementClient, JsonLDSchemaElementClient] { + override def asInternal(from: JsonLDSchemaElementClient): InternalJsonLDSchemaElementClient = from._internal + + override def asClient(from: InternalJsonLDSchemaElementClient): JsonLDSchemaElementClient = + new JsonLDSchemaElementClient(from) } } diff --git a/amf-shapes/shared/src/test/scala/amf/shapes/client/jsonldschema/render/JsonLDObjectRenderTest.scala b/amf-shapes/shared/src/test/scala/amf/shapes/client/jsonldschema/render/JsonLDObjectRenderTest.scala new file mode 100644 index 0000000000..652f4430eb --- /dev/null +++ b/amf-shapes/shared/src/test/scala/amf/shapes/client/jsonldschema/render/JsonLDObjectRenderTest.scala @@ -0,0 +1,48 @@ +package amf.shapes.client.jsonldschema.render + +import amf.core.client.scala.vocabulary.ValueType +import amf.core.internal.metamodel.domain.common.DescribedElementModel +import amf.shapes.client.scala.config.JsonLDSchemaConfiguration +import amf.shapes.client.scala.model.domain.jsonldinstance.JsonLDObject +import amf.shapes.internal.domain.metamodel.jsonldschema.JsonLDEntityModel +import amf.shapes.internal.spec.jsonldschema.parser.JsonPath +import org.scalatest.funsuite.AsyncFunSuite +import org.scalatest.matchers.should.Matchers +import org.yaml.render.YamlRender + +class JsonLDObjectRenderTest extends AsyncFunSuite with Matchers { + + val base = "http://a.ml/jsonld#" + + val model = + JsonLDEntityModel(List(ValueType(s"${base}Object")), List(DescribedElementModel.Description), JsonPath.empty) + + val innerObjKey = s"${base}keyObj" + val rootKey = base + "key" + + val model2 = + JsonLDEntityModel(List(ValueType(s"${base}Object2")), List(DescribedElementModel.Description), JsonPath.empty) + val obj = JsonLDObject + .empty(model, JsonPath.empty) + .withProperty(rootKey, "value") + .withProperty(innerObjKey, JsonLDObject.empty(model, JsonPath.empty).withProperty(s"${base}innerObj", "ab")) + + val expected = + """key: value + |keyObj: + | innerObj: ab""".stripMargin + test("serialize jsonldObject") { + val node = JsonLDSchemaConfiguration.JsonLDSchema().elementClient().renderElement(obj, Nil) + val result = YamlRender.render(node) + result shouldBe (expected) + } + + test("serialize mutated inner jsonldObject") { + val innerObj = obj.graph.getObjectByProperty(innerObjKey).collectFirst({ case obj: JsonLDObject => obj }).head + obj.withProperty(innerObjKey, innerObj.withProperty(s"${base}innerObjKey2", 2)).withProperty(rootKey, "value2") + + val node = JsonLDSchemaConfiguration.JsonLDSchema().elementClient().renderElement(obj, Nil) + val result = YamlRender.render(node) + result shouldBe (expected) + } +}