From 8638948983cd9659a20ea3e3d89b7a300b7dce0c Mon Sep 17 00:00:00 2001 From: Thisaru Guruge Date: Thu, 4 Apr 2024 12:13:37 +0530 Subject: [PATCH 1/4] Improve build scripts --- ballerina/build.gradle | 17 ++--------------- build.gradle | 8 ++++---- compiler-plugin-test/build.gradle | 12 ++++++++++++ settings.gradle | 20 ++++++++++++++++++++ 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/ballerina/build.gradle b/ballerina/build.gradle index b2fad92..bcfbad6 100644 --- a/ballerina/build.gradle +++ b/ballerina/build.gradle @@ -17,19 +17,8 @@ import org.apache.tools.ant.taskdefs.condition.Os -buildscript { - repositories { - maven { - url = 'https://maven.pkg.github.com/ballerina-platform/plugin-gradle' - credentials { - username System.getenv("packageUser") - password System.getenv("packagePAT") - } - } - } - dependencies { - classpath "io.ballerina:plugin-gradle:${project.ballerinaGradlePluginVersion}" - } +plugins { + id 'io.ballerina.plugin' } description = 'Ballerina - Data JSON Module' @@ -57,8 +46,6 @@ def stripBallerinaExtensionVersion(String extVersion) { } } -apply plugin: 'io.ballerina.plugin' - ballerina { testCoverageParam = "--code-coverage --coverage-format=xml --includes=io.ballerina.lib.data.*:ballerina.*" packageOrganization = packageOrg diff --git a/build.gradle b/build.gradle index 2551eb1..7d55b12 100644 --- a/build.gradle +++ b/build.gradle @@ -17,10 +17,10 @@ */ plugins { - id "com.github.spotbugs" version "${githubSpotbugsVersion}" - id "com.github.johnrengelman.shadow" version "${githubJohnrengelmanShadowVersion}" - id "de.undercouch.download" version "${underCouchDownloadVersion}" - id "net.researchgate.release" version "${researchgateReleaseVersion}" + id "com.github.spotbugs" + id "com.github.johnrengelman.shadow" + id "de.undercouch.download" + id "net.researchgate.release" } allprojects { diff --git a/compiler-plugin-test/build.gradle b/compiler-plugin-test/build.gradle index efc4838..c3862bf 100644 --- a/compiler-plugin-test/build.gradle +++ b/compiler-plugin-test/build.gradle @@ -83,6 +83,18 @@ test { systemProperty "ballerina.offline.flag", "true" useTestNG() finalizedBy jacocoTestReport + + testLogging { + exceptionFormat = "full" + afterSuite { desc, result -> + if (!desc.parent) { // will match the outermost suite + def output = "Compiler Plugin Tests: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" + def startItem = '| ', endItem = ' |' + def repeatLength = startItem.length() + output.length() + endItem.length() + println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength)) + } + } + } } jacocoTestReport { diff --git a/settings.gradle b/settings.gradle index 3061afb..efba31e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,6 +16,26 @@ * under the License. */ +pluginManagement { + plugins { + id "com.github.spotbugs" version "${githubSpotbugsVersion}" + id "com.github.johnrengelman.shadow" version "${githubJohnrengelmanShadowVersion}" + id "de.undercouch.download" version "${underCouchDownloadVersion}" + id "net.researchgate.release" version "${researchgateReleaseVersion}" + id "io.ballerina.plugin" version "${ballerinaGradlePluginVersion}" + } + repositories { + gradlePluginPortal() + maven { + url = 'https://maven.pkg.github.com/ballerina-platform/*' + credentials { + username System.getenv("packageUser") + password System.getenv("packagePAT") + } + } + } +} + plugins { id "com.gradle.enterprise" version "3.2" } From 35871bbb64cfef376a3f86fd86c0d5face0a535f Mon Sep 17 00:00:00 2001 From: Thisaru Guruge Date: Thu, 4 Apr 2024 12:23:40 +0530 Subject: [PATCH 2/4] [Automated] Update the native jar versions --- ballerina/Dependencies.toml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index d5af461..161b38e 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -12,6 +12,7 @@ org = "ballerina" name = "data.jsondata" version = "0.1.0" dependencies = [ + {org = "ballerina", name = "file"}, {org = "ballerina", name = "io"}, {org = "ballerina", name = "jballerina.java"}, {org = "ballerina", name = "lang.float"}, @@ -24,6 +25,21 @@ modules = [ {org = "ballerina", packageName = "data.jsondata", moduleName = "data.jsondata"} ] +[[package]] +org = "ballerina" +name = "file" +version = "1.9.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "os"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerina", packageName = "file", moduleName = "file"} +] + [[package]] org = "ballerina" name = "io" @@ -120,6 +136,16 @@ modules = [ {org = "ballerina", packageName = "lang.value", moduleName = "lang.value"} ] +[[package]] +org = "ballerina" +name = "os" +version = "1.8.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"} +] + [[package]] org = "ballerina" name = "test" @@ -134,3 +160,12 @@ modules = [ {org = "ballerina", packageName = "test", moduleName = "test"} ] +[[package]] +org = "ballerina" +name = "time" +version = "2.4.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + From e82094437dbb8a3ff890586891959304e384a605 Mon Sep 17 00:00:00 2001 From: Thisaru Guruge Date: Thu, 4 Apr 2024 12:28:04 +0530 Subject: [PATCH 3/4] Add prettify API with tests --- ballerina/json_api.bal | 10 + ballerina/tests/prettify_test.bal | 224 ++++++++++++++++++ .../expected_results/array_of_empty_maps.json | 5 + .../expected_results/array_of_map.json | 20 ++ .../expected_results/boolean_value.json | 1 + .../expected_results/complex_example.json | 87 +++++++ ...mplex_example_with_custom_indentation.json | 87 +++++++ .../expected_results/empty_array.json | 1 + .../resources/expected_results/empty_map.json | 1 + .../resources/expected_results/int_value.json | 1 + .../tests/resources/expected_results/map.json | 11 + .../map_with_multiple_string_fields.json | 5 + .../map_with_string_field.json | 3 + .../expected_results/null_in_map.json | 9 + .../expected_results/string_array.json | 5 + .../expected_results/string_value.json | 1 + .../input_files/complex_example.json | 87 +++++++ ballerina/tests/utils.bal | 28 +++ ballerina/utils.bal | 108 +++++++++ build.gradle | 3 + gradle.properties | 12 +- settings.gradle | 8 +- 22 files changed, 709 insertions(+), 8 deletions(-) create mode 100644 ballerina/tests/prettify_test.bal create mode 100644 ballerina/tests/resources/expected_results/array_of_empty_maps.json create mode 100644 ballerina/tests/resources/expected_results/array_of_map.json create mode 100644 ballerina/tests/resources/expected_results/boolean_value.json create mode 100644 ballerina/tests/resources/expected_results/complex_example.json create mode 100644 ballerina/tests/resources/expected_results/complex_example_with_custom_indentation.json create mode 100644 ballerina/tests/resources/expected_results/empty_array.json create mode 100644 ballerina/tests/resources/expected_results/empty_map.json create mode 100644 ballerina/tests/resources/expected_results/int_value.json create mode 100644 ballerina/tests/resources/expected_results/map.json create mode 100644 ballerina/tests/resources/expected_results/map_with_multiple_string_fields.json create mode 100644 ballerina/tests/resources/expected_results/map_with_string_field.json create mode 100644 ballerina/tests/resources/expected_results/null_in_map.json create mode 100644 ballerina/tests/resources/expected_results/string_array.json create mode 100644 ballerina/tests/resources/expected_results/string_value.json create mode 100644 ballerina/tests/resources/input_files/complex_example.json create mode 100644 ballerina/tests/utils.bal create mode 100644 ballerina/utils.bal diff --git a/ballerina/json_api.bal b/ballerina/json_api.bal index 4720d71..c987814 100644 --- a/ballerina/json_api.bal +++ b/ballerina/json_api.bal @@ -58,6 +58,16 @@ public isolated function parseStream(stream s, Options options = public isolated function toJson(anydata v) returns json|Error = @java:Method {'class: "io.ballerina.lib.data.jsondata.json.Native"} external; +# Prettifies a `json` value to print it. +# +# + value - The `json` value to be prettified +# + indentation - The number of spaces for an indentation +# + return - The prettified `json` as a string +public isolated function prettify(json value, int indentation = 4) returns string { + string indent = getIndentation(indentation); + return prettifyJson(value, indent, 0); +} + # Represent the options that can be used to modify the behaviour of the projection. # # + allowDataProjection - Enable or disable projection diff --git a/ballerina/tests/prettify_test.bal b/ballerina/tests/prettify_test.bal new file mode 100644 index 0000000..63628c6 --- /dev/null +++ b/ballerina/tests/prettify_test.bal @@ -0,0 +1,224 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/test; + +@test:Config { + groups: ["prettify", "string"] +} +function testStringValue() returns error? { + json value = "Sam"; + string actual = prettify(value); + string expected = check getStringContentFromFile("string_value.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "int"] +} +function testIntValue() returns error? { + json value = 515; + string actual = prettify(value); + string expected = check getStringContentFromFile("int_value.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "boolean"] +} +function testBooleanValue() returns error? { + json value = false; + string actual = prettify(value); + string expected = check getStringContentFromFile("boolean_value.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "null"] +} +function testNullValue() returns error? { + json value = null; + string actual = prettify(value); + string expected = " null"; + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "null"] +} +isolated function testNullInMap() returns error? { + json value = { + name: "Sam", + age: null, + address: { + number: 308, + street: "Negra Arroyo Lane", + city: null + } + }; + string actual = prettify(value); + string expected = check getStringContentFromFile("null_in_map.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "array"] +} +function testStringArray() returns error? { + json value = ["sam", "bam", "tan"]; + string actual = prettify(value); + string expected = check getStringContentFromFile("string_array.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "array"] +} +function testEmptyArray() returns error? { + json value = []; + string actual = prettify(value); + string expected = check getStringContentFromFile("empty_array.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "map"] +} +function testEmptyMap() returns error? { + json value = {}; + string actual = prettify(value); + string expected = check getStringContentFromFile("empty_map.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "map"] +} +function testArrayOfEmptyMaps() returns error? { + json value = [ + {}, + {}, + {} + ]; + string actual = prettify(value); + string expected = check getStringContentFromFile("array_of_empty_maps.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "map"] +} +function testMapWithStringField() returns error? { + json value = { + name: "Walter White" + }; + string actual = prettify(value); + string expected = check getStringContentFromFile("map_with_string_field.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "map"] +} +function testMapWithMultipleStringFields() returns error? { + json value = { + name: "Walter White", + subject: "Chemistry", + city: "Albequerque" + }; + string actual = prettify(value); + string expected = check getStringContentFromFile("map_with_multiple_string_fields.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "map"] +} +function testMap() returns error? { + json value = { + person: { + name: "Walter White", + age: 51, + address: { + number: 308, + street: "Negra Arroyo Lane", + city: "Albequerque" + } + } + }; + string actual = prettify(value); + string expected = check getStringContentFromFile("map.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "map"] +} +function testArrayOfMap() returns error? { + json value = [ + { + name: "Walter White", + age: 51, + address: { + number: 308, + street: "Negra Arroyo Lane", + city: "Albequerque" + } + }, + { + name: "Jesse Pinkman", + age: 26, + address: { + number: 9809, + street: "Margo Street", + city: "Albequerque" + } + } + ]; + string actual = prettify(value); + string expected = check getStringContentFromFile("array_of_map.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "array", "map"] +} +function testComplexExample() returns error? { + json value = check getJsonContentFromFile("complex_example.json"); + string actual = prettify(value); + string expected = check getStringContentFromFile("complex_example.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "array", "map"] +} +function testComplexExampleWithCustomIndentation() returns error? { + json value = check getJsonContentFromFile("complex_example.json"); + string actual = prettify(value, 2); + string expected = check getStringContentFromFile("complex_example_with_custom_indentation.json"); + test:assertEquals(actual, expected); +} + +@test:Config { + groups: ["prettify", "array", "map"] +} +function testComplexExampleWithCustomIndentationInvalidTest() returns error? { + json value = check getJsonContentFromFile("complex_example.json"); + string actual = prettify(value, 2); + string expected = check getStringContentFromFile("complex_example.json"); + test:assertNotEquals(actual, expected); +} diff --git a/ballerina/tests/resources/expected_results/array_of_empty_maps.json b/ballerina/tests/resources/expected_results/array_of_empty_maps.json new file mode 100644 index 0000000..46133e6 --- /dev/null +++ b/ballerina/tests/resources/expected_results/array_of_empty_maps.json @@ -0,0 +1,5 @@ +[ + {}, + {}, + {} +] diff --git a/ballerina/tests/resources/expected_results/array_of_map.json b/ballerina/tests/resources/expected_results/array_of_map.json new file mode 100644 index 0000000..6f8c3b8 --- /dev/null +++ b/ballerina/tests/resources/expected_results/array_of_map.json @@ -0,0 +1,20 @@ +[ + { + "name": "Walter White", + "age": 51, + "address": { + "number": 308, + "street": "Negra Arroyo Lane", + "city": "Albequerque" + } + }, + { + "name": "Jesse Pinkman", + "age": 26, + "address": { + "number": 9809, + "street": "Margo Street", + "city": "Albequerque" + } + } +] diff --git a/ballerina/tests/resources/expected_results/boolean_value.json b/ballerina/tests/resources/expected_results/boolean_value.json new file mode 100644 index 0000000..c508d53 --- /dev/null +++ b/ballerina/tests/resources/expected_results/boolean_value.json @@ -0,0 +1 @@ +false diff --git a/ballerina/tests/resources/expected_results/complex_example.json b/ballerina/tests/resources/expected_results/complex_example.json new file mode 100644 index 0000000..c8403ff --- /dev/null +++ b/ballerina/tests/resources/expected_results/complex_example.json @@ -0,0 +1,87 @@ +{ + "colors": [ + { + "color": "black", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 255, + 255, + 1 + ], + "hex": "#000" + } + }, + { + "color": "white", + "category": "value", + "code": { + "rgba": [ + 0, + 0, + 0, + 1 + ], + "hex": "#FFF" + } + }, + { + "color": "red", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 0, + 0, + 1 + ], + "hex": "#FF0" + } + }, + { + "color": "blue", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 0, + 0, + 255, + 1 + ], + "hex": "#00F" + } + }, + { + "color": "yellow", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 255, + 0, + 1 + ], + "hex": "#FF0" + } + }, + { + "color": "green", + "category": "hue", + "type": "secondary", + "code": { + "rgba": [ + 0, + 255, + 0, + 1 + ], + "hex": "#0F0" + } + } + ] +} diff --git a/ballerina/tests/resources/expected_results/complex_example_with_custom_indentation.json b/ballerina/tests/resources/expected_results/complex_example_with_custom_indentation.json new file mode 100644 index 0000000..ea29bd3 --- /dev/null +++ b/ballerina/tests/resources/expected_results/complex_example_with_custom_indentation.json @@ -0,0 +1,87 @@ +{ + "colors": [ + { + "color": "black", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 255, + 255, + 1 + ], + "hex": "#000" + } + }, + { + "color": "white", + "category": "value", + "code": { + "rgba": [ + 0, + 0, + 0, + 1 + ], + "hex": "#FFF" + } + }, + { + "color": "red", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 0, + 0, + 1 + ], + "hex": "#FF0" + } + }, + { + "color": "blue", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 0, + 0, + 255, + 1 + ], + "hex": "#00F" + } + }, + { + "color": "yellow", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 255, + 0, + 1 + ], + "hex": "#FF0" + } + }, + { + "color": "green", + "category": "hue", + "type": "secondary", + "code": { + "rgba": [ + 0, + 255, + 0, + 1 + ], + "hex": "#0F0" + } + } + ] +} diff --git a/ballerina/tests/resources/expected_results/empty_array.json b/ballerina/tests/resources/expected_results/empty_array.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/ballerina/tests/resources/expected_results/empty_array.json @@ -0,0 +1 @@ +[] diff --git a/ballerina/tests/resources/expected_results/empty_map.json b/ballerina/tests/resources/expected_results/empty_map.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/ballerina/tests/resources/expected_results/empty_map.json @@ -0,0 +1 @@ +{} diff --git a/ballerina/tests/resources/expected_results/int_value.json b/ballerina/tests/resources/expected_results/int_value.json new file mode 100644 index 0000000..3cda32f --- /dev/null +++ b/ballerina/tests/resources/expected_results/int_value.json @@ -0,0 +1 @@ +515 diff --git a/ballerina/tests/resources/expected_results/map.json b/ballerina/tests/resources/expected_results/map.json new file mode 100644 index 0000000..670754a --- /dev/null +++ b/ballerina/tests/resources/expected_results/map.json @@ -0,0 +1,11 @@ +{ + "person": { + "name": "Walter White", + "age": 51, + "address": { + "number": 308, + "street": "Negra Arroyo Lane", + "city": "Albequerque" + } + } +} diff --git a/ballerina/tests/resources/expected_results/map_with_multiple_string_fields.json b/ballerina/tests/resources/expected_results/map_with_multiple_string_fields.json new file mode 100644 index 0000000..579d119 --- /dev/null +++ b/ballerina/tests/resources/expected_results/map_with_multiple_string_fields.json @@ -0,0 +1,5 @@ +{ + "name": "Walter White", + "subject": "Chemistry", + "city": "Albequerque" +} diff --git a/ballerina/tests/resources/expected_results/map_with_string_field.json b/ballerina/tests/resources/expected_results/map_with_string_field.json new file mode 100644 index 0000000..9363606 --- /dev/null +++ b/ballerina/tests/resources/expected_results/map_with_string_field.json @@ -0,0 +1,3 @@ +{ + "name": "Walter White" +} diff --git a/ballerina/tests/resources/expected_results/null_in_map.json b/ballerina/tests/resources/expected_results/null_in_map.json new file mode 100644 index 0000000..73d632a --- /dev/null +++ b/ballerina/tests/resources/expected_results/null_in_map.json @@ -0,0 +1,9 @@ +{ + "name": "Sam", + "age": null, + "address": { + "number": 308, + "street": "Negra Arroyo Lane", + "city": null + } +} diff --git a/ballerina/tests/resources/expected_results/string_array.json b/ballerina/tests/resources/expected_results/string_array.json new file mode 100644 index 0000000..3e5eed7 --- /dev/null +++ b/ballerina/tests/resources/expected_results/string_array.json @@ -0,0 +1,5 @@ +[ + "sam", + "bam", + "tan" +] diff --git a/ballerina/tests/resources/expected_results/string_value.json b/ballerina/tests/resources/expected_results/string_value.json new file mode 100644 index 0000000..6b5dec0 --- /dev/null +++ b/ballerina/tests/resources/expected_results/string_value.json @@ -0,0 +1 @@ +"Sam" diff --git a/ballerina/tests/resources/input_files/complex_example.json b/ballerina/tests/resources/input_files/complex_example.json new file mode 100644 index 0000000..c8403ff --- /dev/null +++ b/ballerina/tests/resources/input_files/complex_example.json @@ -0,0 +1,87 @@ +{ + "colors": [ + { + "color": "black", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 255, + 255, + 1 + ], + "hex": "#000" + } + }, + { + "color": "white", + "category": "value", + "code": { + "rgba": [ + 0, + 0, + 0, + 1 + ], + "hex": "#FFF" + } + }, + { + "color": "red", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 0, + 0, + 1 + ], + "hex": "#FF0" + } + }, + { + "color": "blue", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 0, + 0, + 255, + 1 + ], + "hex": "#00F" + } + }, + { + "color": "yellow", + "category": "hue", + "type": "primary", + "code": { + "rgba": [ + 255, + 255, + 0, + 1 + ], + "hex": "#FF0" + } + }, + { + "color": "green", + "category": "hue", + "type": "secondary", + "code": { + "rgba": [ + 0, + 255, + 0, + 1 + ], + "hex": "#0F0" + } + } + ] +} diff --git a/ballerina/tests/utils.bal b/ballerina/tests/utils.bal new file mode 100644 index 0000000..31286a3 --- /dev/null +++ b/ballerina/tests/utils.bal @@ -0,0 +1,28 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/file; +import ballerina/io; + +isolated function getStringContentFromFile(string fileName) returns string|error { + string path = check file:joinPath("tests", "resources", "expected_results", fileName); + return io:fileReadString(path); +} + +isolated function getJsonContentFromFile(string fileName) returns json|error { + string path = check file:joinPath("tests", "resources", "input_files", fileName); + return io:fileReadJson(path); +} diff --git a/ballerina/utils.bal b/ballerina/utils.bal new file mode 100644 index 0000000..c0cd794 --- /dev/null +++ b/ballerina/utils.bal @@ -0,0 +1,108 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +isolated function prettifyJson(json value, string indentation, int level, boolean isMapField = false) returns string { + if value == () { + return " null"; + } else if value is map { + return prettifyJsonMap(value, indentation, level, isMapField); + } else if value is json[] { + return prettifyJsonArray(value, indentation, level, isMapField); + } else { + return prettifyJsonField(value, indentation, level, isMapField); + } +} + +isolated function prettifyJsonMap(map value, string indentation, int level, boolean isMapField) returns string { + string initialIndentation = getInitialIndentation(indentation, level, isMapField); + string result = string `${initialIndentation}{`; + boolean isEmptyMap = value.keys().length() == 0; + if !isEmptyMap { + result += "\n"; + } + + int fieldLevel = level + 1; + string fieldIndentation = getIndentationForLevel(indentation, fieldLevel); + int length = value.length(); + int i = 1; + foreach string key in value.keys() { + string fieldValue = prettifyJson(value.get(key), indentation, fieldLevel, true); + string line = string `${fieldIndentation}"${key}":${fieldValue}`; + result += line; + if i != length { + result += ","; + } + result += "\n"; + i += 1; + } + + if !isEmptyMap { + result += getIndentationForLevel(indentation, level); + } + result += "}"; + return result; +} + +isolated function prettifyJsonArray(json[] array, string indentation, int level, boolean isMapField) returns string { + string initialIndentation = getInitialIndentation(indentation, level, isMapField); + string result = string `${initialIndentation}[`; + + boolean isEmptyArray = array.length() == 0; + if !isEmptyArray { + result += "\n"; + } + + int elementLevel = level + 1; + string[] elements = []; + foreach json value in array { + elements.push(prettifyJson(value, indentation, elementLevel)); + } + string separator = ",\n"; + result += 'string:'join(separator, ...elements); + + if !isEmptyArray { + result += "\n" + getIndentationForLevel(indentation, level); + } + return string `${result}]`; +} + +isolated function getIndentation(int indentation) returns string { + string result = ""; + foreach int i in 0 ..< indentation { + result += " "; + } + return result; +} + +isolated function getIndentationForLevel(string indentation, int level) returns string { + string result = ""; + foreach int i in 0 ..< level { + result += indentation; + } + return result; +} + +isolated function getInitialIndentation(string indentation, int level, boolean isMapField) returns string { + if isMapField { + return " "; + } + return getIndentationForLevel(indentation, level); +} + +isolated function prettifyJsonField(json value, string indentation, int level, boolean isMapField) returns string { + string initialIndentation = getInitialIndentation(indentation, level, isMapField); + return string `${initialIndentation}${value.toJsonString()}`; +} diff --git a/build.gradle b/build.gradle index 7d55b12..dc59376 100644 --- a/build.gradle +++ b/build.gradle @@ -67,7 +67,10 @@ subprojects { dependencies { /* Standard libraries */ + ballerinaStdLibs "io.ballerina.stdlib:file-ballerina:${stdlibFileVersion}" ballerinaStdLibs "io.ballerina.stdlib:io-ballerina:${stdlibIoVersion}" + ballerinaStdLibs "io.ballerina.stdlib:os-ballerina:${stdlibOsVersion}" + ballerinaStdLibs "io.ballerina.stdlib:time-ballerina:${stdlibTimeVersion}" } } diff --git a/gradle.properties b/gradle.properties index 9105995..c910b80 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,12 +7,16 @@ checkstyleToolVersion=10.12.0 puppycrawlCheckstyleVersion=10.12.0 testngVersion=7.6.1 slf4jVersion=2.0.7 -githubSpotbugsVersion=5.0.14 -githubJohnrengelmanShadowVersion=8.1.1 -underCouchDownloadVersion=4.0.4 -researchgateReleaseVersion=2.8.0 +spotbugsVersion=5.0.14 +shadowJarPluginVersion=8.1.1 +downloadPluginVersion=4.0.4 +releasePluginVersion=2.8.0 ballerinaGradlePluginVersion=2.0.1 javaJsonPathVersion=2.9.0 javaJsonSmartVersion=2.4.11 javaAccessorsSmartVersion=2.4.7 + +stdlibFileVersion=1.9.0 stdlibIoVersion=1.6.0 +stdlibOsVersion=1.8.0 +stdlibTimeVersion=2.4.0 diff --git a/settings.gradle b/settings.gradle index efba31e..80e39d1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,10 +18,10 @@ pluginManagement { plugins { - id "com.github.spotbugs" version "${githubSpotbugsVersion}" - id "com.github.johnrengelman.shadow" version "${githubJohnrengelmanShadowVersion}" - id "de.undercouch.download" version "${underCouchDownloadVersion}" - id "net.researchgate.release" version "${researchgateReleaseVersion}" + id "com.github.spotbugs" version "${spotbugsVersion}" + id "com.github.johnrengelman.shadow" version "${shadowJarPluginVersion}" + id "de.undercouch.download" version "${downloadPluginVersion}" + id "net.researchgate.release" version "${releasePluginVersion}" id "io.ballerina.plugin" version "${ballerinaGradlePluginVersion}" } repositories { From c7bbf73eed5ccff11af2558ee30b5efd26e22cb9 Mon Sep 17 00:00:00 2001 From: Thisaru Guruge Date: Fri, 5 Apr 2024 10:45:19 +0530 Subject: [PATCH 4/4] Apply suggestions from code review --- ballerina/utils.bal | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ballerina/utils.bal b/ballerina/utils.bal index c0cd794..918d139 100644 --- a/ballerina/utils.bal +++ b/ballerina/utils.bal @@ -96,10 +96,7 @@ isolated function getIndentationForLevel(string indentation, int level) returns } isolated function getInitialIndentation(string indentation, int level, boolean isMapField) returns string { - if isMapField { - return " "; - } - return getIndentationForLevel(indentation, level); + return isMapField ? " " : getIndentationForLevel(indentation, level); } isolated function prettifyJsonField(json value, string indentation, int level, boolean isMapField) returns string {