From a6e76ff310298766803c43b6185b723429636449 Mon Sep 17 00:00:00 2001 From: Courela Date: Fri, 18 Jul 2025 22:34:39 +0100 Subject: [PATCH 1/3] Do not add previous alias to CurrentArrayToken when explicitly refer to other loop item as input for declaring one (cherry picked from commit 8d0d90647f3ae1894f018c5f2712494644fc93c7) --- JUST.net/JsonTransformer.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 3a97c6f..01b9001 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -477,7 +477,10 @@ private void LoopOperation(string propertyName, string arguments, State state, r if (args.Length > 2) { previousAlias = (string)ParseFunction(args[2].Trim(), state); - state.CurrentArrayToken.Add(new LevelKey() { Key = previousAlias, Level = _levelCounter }, Context.Input); + // if (!state.CurrentArrayToken.Any(t => t.Key.Key == previousAlias)) + // { + // state.CurrentArrayToken.Add(new LevelKey() { Key = previousAlias, Level = _levelCounter }, Context.Input); + // } } else if (state.CurrentArrayToken.Any(t => t.Key.Key == alias)) { From 692a73c92e9ff6193cb52fa0b21effb0f55298aa Mon Sep 17 00:00:00 2001 From: Courela Date: Fri, 18 Jul 2025 22:35:44 +0100 Subject: [PATCH 2/3] Add SingleLoopAlias test with implicit and explicit alias on item functions (cherry picked from commit 6d57d7579b6218281a60f6a1335fca7875721be7) --- UnitTests/Arrays/LoopingTests.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/UnitTests/Arrays/LoopingTests.cs b/UnitTests/Arrays/LoopingTests.cs index 65ec48e..93569a8 100644 --- a/UnitTests/Arrays/LoopingTests.cs +++ b/UnitTests/Arrays/LoopingTests.cs @@ -248,7 +248,17 @@ public void SingleIndexReference() } [Test] - public void LoopingAlias() + public void SingleLoopingAlias() + { + const string transformer = "{ \"hello\": { \"#loop($.NestedLoop.Organization.Employee, employee, root)\": { \"Name\": \"#currentvalueatpath($.Name)\", \"NameExplicit\": \"#currentvalueatpath($.Name, employee)\" } } }"; + + var result = new JsonTransformer(new JUSTContext() { EvaluationMode = EvaluationMode.Strict }).Transform(transformer, ExampleInputs.NestedArrays); + + Assert.AreEqual("{\"hello\":[{\"Name\":\"E2\",\"NameExplicit\":\"E2\"},{\"Name\":\"E1\",\"NameExplicit\":\"E1\"}]}", result); + } + + [Test] + public void MultipleLoopingAlias() { const string transformer = "{ \"hello\": { \"#loop($.NestedLoop.Organization.Employee, employee)\": { \"Details\": { \"#loop($.Details, details)\": { \"CurrentCountry\": \"#currentvalueatpath($.Country, details)\", \"OuterName\": \"#currentvalueatpath($.Name, employee)\", \"FirstLevel\": { \"#loop($.Roles, roles)\": { \"Employee\": \"#currentvalue(employee)\", \"Job\": \"#currentvalueatpath($.Job, roles)\" } } } } } } }"; From d4e7c665f8c55de76774fcbdbaf1743cd428c85e Mon Sep 17 00:00:00 2001 From: Courela Date: Fri, 18 Jul 2025 22:45:44 +0100 Subject: [PATCH 3/3] Add NestedLoopingAlias test (based on #314); clean up --- JUST.net/JsonTransformer.cs | 4 ---- UnitTests/Arrays/LoopingTests.cs | 12 ++++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/JUST.net/JsonTransformer.cs b/JUST.net/JsonTransformer.cs index 01b9001..a2be650 100644 --- a/JUST.net/JsonTransformer.cs +++ b/JUST.net/JsonTransformer.cs @@ -477,10 +477,6 @@ private void LoopOperation(string propertyName, string arguments, State state, r if (args.Length > 2) { previousAlias = (string)ParseFunction(args[2].Trim(), state); - // if (!state.CurrentArrayToken.Any(t => t.Key.Key == previousAlias)) - // { - // state.CurrentArrayToken.Add(new LevelKey() { Key = previousAlias, Level = _levelCounter }, Context.Input); - // } } else if (state.CurrentArrayToken.Any(t => t.Key.Key == alias)) { diff --git a/UnitTests/Arrays/LoopingTests.cs b/UnitTests/Arrays/LoopingTests.cs index 93569a8..a58ace3 100644 --- a/UnitTests/Arrays/LoopingTests.cs +++ b/UnitTests/Arrays/LoopingTests.cs @@ -277,6 +277,18 @@ public void MixedLoopingAlias() Assert.AreEqual("{\"hello\":[{\"Details\":[{\"CurrentCountry\":\"Iceland\",\"OuterName\":\"E2\"}]},{\"Details\":[{\"CurrentCountry\":\"Denmark\",\"OuterName\":\"E1\"}]}]}", result); } + [Test] + public void NestedLoopingAlias() + { + const string transformer = "{ \"payload\": { \"produce-color\": { \"green\": { \"#loop($..fruit[?(@.color == 'green')], outside-loop)\": { \"name\": \"#currentvalueatpath($.name)\", \"outer-index\": \"#currentindex()\", \"other\": { \"#loop($..vegetables[?(@.color == 'green')],inner-loop,root)\": { \"name\": \"#currentvalueatpath($.name)\", \"inner-index\": \"#currentindex()\" } }, \"addionalInformation\": { \"outside-name\": \"#currentvalueatpath($.name)\" } } } } }}"; + const string input = "{ \"root\": { \"type\": \"produce\", \"vegetables\": [ { \"name\": \"tomato\", \"color\": \"red\" }, { \"name\": \"cucumber\", \"color\": \"green\" }, { \"name\": \"bell-pepper\", \"color\": \"yellow\" }, { \"name\": \"colored-greens\", \"color\": \"green\" } ], \"fruit\": [ { \"name\": \"banana\", \"color\": \"yellow\" }, { \"name\": \"melon\", \"color\": \"green\" }, { \"name\": \"orange\", \"color\": \"orange\" }, { \"name\": \"apple\", \"color\": \"green\" }, { \"name\": \"pear\", \"color\": \"green\" } ] }}"; + + var context = new JUSTContext() { EvaluationMode = EvaluationMode.Strict }; + var result = new JsonTransformer(context).Transform(transformer, input); + + Assert.AreEqual("{\"payload\":{\"produce-color\":{\"green\":[{\"name\":\"melon\",\"outer-index\":0,\"other\":[{\"name\":\"cucumber\",\"inner-index\":0},{\"name\":\"colored-greens\",\"inner-index\":1}],\"addionalInformation\":{\"outside-name\":\"melon\"}},{\"name\":\"apple\",\"outer-index\":1,\"other\":[{\"name\":\"cucumber\",\"inner-index\":0},{\"name\":\"colored-greens\",\"inner-index\":1}],\"addionalInformation\":{\"outside-name\":\"apple\"}},{\"name\":\"pear\",\"outer-index\":2,\"other\":[{\"name\":\"cucumber\",\"inner-index\":0},{\"name\":\"colored-greens\",\"inner-index\":1}],\"addionalInformation\":{\"outside-name\":\"pear\"}}]}}}", result); + } + [Test] public void BulkFunctions() {