From 1a5337c48b2d63fa5dae7302f49ba2745c529cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Cio=C5=82ecki?= Date: Tue, 26 Nov 2024 09:26:18 +0100 Subject: [PATCH] Fix: ToJsonEncoder keeps order fields during encoding map --- .../engine/util/json/ToJsonEncoder.scala | 11 +++++++---- .../engine/util/json/ToJsonEncoderSpec.scala | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/utils/utils/src/main/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoder.scala b/utils/utils/src/main/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoder.scala index a57223fdd4c..d88c84ca2ce 100644 --- a/utils/utils/src/main/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoder.scala +++ b/utils/utils/src/main/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoder.scala @@ -10,8 +10,8 @@ import pl.touk.nussknacker.engine.api.DisplayJson import pl.touk.nussknacker.engine.util.Implicits._ import java.util.ServiceLoader - import java.util.UUID +import scala.collection.SeqMap import scala.jdk.CollectionConverters._ object ToJsonEncoder { @@ -88,9 +88,12 @@ case class ToJsonEncoder( // TODO: make encoder aware of NU Types to encode things like multiset differently. Right now its handled by calling // toString on keys. private def encodeMap(map: Map[_, _]) = { - val mapWithStringKeys = map.view.map { case (k, v) => - k.toString -> v - }.toMap + val mapWithStringKeys = SeqMap.from( + map.toList.map { case (k, v) => + k.toString -> v + } + ) + fromFields(mapWithStringKeys.mapValuesNow(encode)) } diff --git a/utils/utils/src/test/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoderSpec.scala b/utils/utils/src/test/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoderSpec.scala index 05322f742f2..e82fe7490a4 100644 --- a/utils/utils/src/test/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoderSpec.scala +++ b/utils/utils/src/test/scala/pl/touk/nussknacker/engine/util/json/ToJsonEncoderSpec.scala @@ -9,6 +9,7 @@ import pl.touk.nussknacker.test.ClassLoaderWithServices import java.time._ import java.util import java.util.UUID +import scala.collection.SeqMap import scala.collection.immutable.{ListMap, ListSet} class ToJsonEncoderSpec extends AnyFunSpec with Matchers { @@ -101,6 +102,24 @@ class ToJsonEncoderSpec extends AnyFunSpec with Matchers { } + it("should convert map to json and keep order of keys") { + val map = ListMap( + "intNumber" -> 42, + "floatNumber" -> 42.42, + "someTimestamp" -> 1496930555793L, + "someString" -> "hello", + "booleanValue" -> true + ) + + encoder.encode(map) shouldBe Json.obj( + "intNumber" -> fromInt(42), + "floatNumber" -> fromFloatOrNull(42.42f), + "someTimestamp" -> fromLong(1496930555793L), + "someString" -> fromString("hello"), + "booleanValue" -> fromBoolean(true), + ) + } + } class CustomJsonEncoderCustomisation1 extends ToJsonEncoderCustomisation {