Skip to content

Commit f84e21d

Browse files
committed
added doctest, integ-tests, and unit tests
1 parent 70152eb commit f84e21d

File tree

12 files changed

+204
-3
lines changed

12 files changed

+204
-3
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.expression.json;
7+
8+
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
import static org.mockito.Mockito.when;
10+
import static org.opensearch.sql.data.model.ExprValueUtils.LITERAL_FALSE;
11+
import static org.opensearch.sql.data.model.ExprValueUtils.LITERAL_TRUE;
12+
import static org.opensearch.sql.data.type.ExprCoreType.STRING;
13+
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.ExtendWith;
16+
import org.mockito.Mock;
17+
import org.mockito.junit.jupiter.MockitoExtension;
18+
import org.opensearch.sql.data.model.ExprValue;
19+
import org.opensearch.sql.data.model.ExprValueUtils;
20+
import org.opensearch.sql.expression.DSL;
21+
import org.opensearch.sql.expression.Expression;
22+
import org.opensearch.sql.expression.FunctionExpression;
23+
import org.opensearch.sql.expression.env.Environment;
24+
25+
@ExtendWith(MockitoExtension.class)
26+
public class JsonFunctionsTest {
27+
28+
private static final ExprValue JsonObject = ExprValueUtils.stringValue("{\"a\":\"1\",\"b\":\"2\"}");
29+
private static final ExprValue JsonArray = ExprValueUtils.stringValue("[1, 2, 3, 4]");
30+
private static final ExprValue JsonScalarString = ExprValueUtils.stringValue("\"abc\"");
31+
private static final ExprValue JsonEmptyString = ExprValueUtils.stringValue("");
32+
private static final ExprValue JsonInvalidObject = ExprValueUtils.stringValue("{\"invalid\":\"json\", \"string\"}");
33+
private static final ExprValue JsonInvalidScalar = ExprValueUtils.stringValue("abc");
34+
35+
@Mock private Environment<Expression, ExprValue> env;
36+
37+
@Test
38+
public void json_valid_invalid_json_string() {
39+
assertEquals(LITERAL_FALSE, execute(JsonInvalidObject));
40+
assertEquals(LITERAL_FALSE, execute(JsonInvalidScalar));
41+
}
42+
43+
@Test
44+
public void json_valid_valid_json_string() {
45+
assertEquals(LITERAL_TRUE, JsonObject);
46+
assertEquals(LITERAL_TRUE, JsonArray);
47+
assertEquals(LITERAL_TRUE, JsonScalarString);
48+
assertEquals(LITERAL_TRUE, JsonEmptyString);
49+
}
50+
51+
private ExprValue execute(ExprValue jsonString) {
52+
final String fieldName = "json_string";
53+
FunctionExpression exp = DSL.jsonValid(DSL.literal(jsonString));
54+
55+
when(DSL.ref(fieldName, STRING).valueOf(env)).thenReturn(jsonString);
56+
57+
return exp.valueOf(env);
58+
}
59+
}

docs/category.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"user/ppl/functions/datetime.rst",
3535
"user/ppl/functions/expressions.rst",
3636
"user/ppl/functions/ip.rst",
37+
"user/ppl/functions/json.rst",
3738
"user/ppl/functions/math.rst",
3839
"user/ppl/functions/relevance.rst",
3940
"user/ppl/functions/string.rst"

docs/user/dql/metadata.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Example 1: Show All Indices Information
3535
SQL query::
3636

3737
os> SHOW TABLES LIKE '%'
38-
fetched rows / total rows = 10/10
38+
fetched rows / total rows = 11/11
3939
+----------------+-------------+-----------------+------------+---------+----------+------------+-----------+---------------------------+----------------+
4040
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE | REMARKS | TYPE_CAT | TYPE_SCHEM | TYPE_NAME | SELF_REFERENCING_COL_NAME | REF_GENERATION |
4141
|----------------+-------------+-----------------+------------+---------+----------+------------+-----------+---------------------------+----------------|
@@ -44,6 +44,7 @@ SQL query::
4444
| docTestCluster | null | accounts | BASE TABLE | null | null | null | null | null | null |
4545
| docTestCluster | null | apache | BASE TABLE | null | null | null | null | null | null |
4646
| docTestCluster | null | books | BASE TABLE | null | null | null | null | null | null |
47+
| docTestCluster | null | json_test | BASE TABLE | null | null | null | null | null | null |
4748
| docTestCluster | null | nested | BASE TABLE | null | null | null | null | null | null |
4849
| docTestCluster | null | nyc_taxi | BASE TABLE | null | null | null | null | null | null |
4950
| docTestCluster | null | people | BASE TABLE | null | null | null | null | null | null |

docs/user/ppl/functions/json.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
====================
2+
IP Address Functions
3+
====================
4+
5+
.. rubric:: Table of contents
6+
7+
.. contents::
8+
:local:
9+
:depth: 1
10+
11+
JSON_VALID
12+
----------
13+
14+
Description
15+
>>>>>>>>>>>
16+
17+
Usage: `json_valid(json_string)` checks if `json_string` is a valid STRING string.
18+
19+
Argument type: STRING
20+
21+
Return type: BOOLEAN
22+
23+
Example::
24+
25+
> source=json_test | where json_valid(json_string) | fields test_name, json_string
26+
fetched rows / total rows = 4/4
27+
+--------------------+--------------------+
28+
| test_name | json_string |
29+
|--------------------|--------------------|
30+
| json object | {"a":"1","b":"2"} |
31+
| json array | [1, 2, 3, 4] |
32+
| json scalar string | [1, 2, 3, 4] |
33+
| json empty string | [1, 2, 3, 4] |
34+
+--------------------+--------------------+

doctest/test_data/json_test.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{"test_name":"json object", "json_string":"{\"a\":\"1\",\"b\":\"2\"}"}
2+
{"test_name":"json array", "json_string":"[1, 2, 3, 4]"}
3+
{"test_name":"json scalar string", "json_string":"\"abc\""}
4+
{"test_name":"json empty string","json_string":""}
5+
{"test_name":"json invalid object", "json_string":"{\"invalid\":\"json\", \"string\"}"}

doctest/test_docs.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
NESTED = "nested"
3131
DATASOURCES = ".ql-datasources"
3232
WEBLOGS = "weblogs"
33+
JSON_TEST = "json_test"
3334

3435
class DocTestConnection(OpenSearchConnection):
3536

@@ -123,6 +124,7 @@ def set_up_test_indices(test):
123124
load_file("nested_objects.json", index_name=NESTED)
124125
load_file("datasources.json", index_name=DATASOURCES)
125126
load_file("weblogs.json", index_name=WEBLOGS)
127+
load_file("json_test.json", index_name=JSON_TEST)
126128

127129

128130
def load_file(filename, index_name):
@@ -151,7 +153,7 @@ def set_up(test):
151153

152154
def tear_down(test):
153155
# drop leftover tables after each test
154-
test_data_client.indices.delete(index=[ACCOUNTS, EMPLOYEES, PEOPLE, ACCOUNT2, NYC_TAXI, BOOKS, APACHE, WILDCARD, NESTED, WEBLOGS], ignore_unavailable=True)
156+
test_data_client.indices.delete(index=[ACCOUNTS, EMPLOYEES, PEOPLE, ACCOUNT2, NYC_TAXI, BOOKS, APACHE, WILDCARD, NESTED, WEBLOGS, JSON_TEST], ignore_unavailable=True)
155157

156158

157159
docsuite = partial(doctest.DocFileSuite,

integ-test/src/test/java/org/opensearch/sql/legacy/SQLIntegTestCase.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.opensearch.sql.legacy.TestUtils.getGameOfThronesIndexMapping;
2323
import static org.opensearch.sql.legacy.TestUtils.getGeopointIndexMapping;
2424
import static org.opensearch.sql.legacy.TestUtils.getJoinTypeIndexMapping;
25+
import static org.opensearch.sql.legacy.TestUtils.getJsonTestIndexMapping;
2526
import static org.opensearch.sql.legacy.TestUtils.getLocationIndexMapping;
2627
import static org.opensearch.sql.legacy.TestUtils.getMappingFile;
2728
import static org.opensearch.sql.legacy.TestUtils.getNestedSimpleIndexMapping;
@@ -745,7 +746,12 @@ public enum Index {
745746
TestsConstants.TEST_INDEX_GEOPOINT,
746747
"dates",
747748
getGeopointIndexMapping(),
748-
"src/test/resources/geopoints.json");
749+
"src/test/resources/geopoints.json"),
750+
JSON_TEST(
751+
TestsConstants.TEST_INDEX_JSON_TEST,
752+
"json",
753+
getJsonTestIndexMapping(),
754+
"src/test/resources/json_test.json");
749755

750756
private final String name;
751757
private final String type;

integ-test/src/test/java/org/opensearch/sql/legacy/TestUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,11 @@ public static String getGeopointIndexMapping() {
250250
return getMappingFile(mappingFile);
251251
}
252252

253+
public static String getJsonTestIndexMapping() {
254+
String mappingFile = "json_test_index_mapping.json";
255+
return getMappingFile(mappingFile);
256+
}
257+
253258
public static void loadBulk(Client client, String jsonPath, String defaultIndex)
254259
throws Exception {
255260
System.out.println(String.format("Loading file %s into opensearch cluster", jsonPath));

integ-test/src/test/java/org/opensearch/sql/legacy/TestsConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public class TestsConstants {
5858
public static final String TEST_INDEX_MULTI_NESTED_TYPE = TEST_INDEX + "_multi_nested";
5959
public static final String TEST_INDEX_NESTED_WITH_NULLS = TEST_INDEX + "_nested_with_nulls";
6060
public static final String TEST_INDEX_GEOPOINT = TEST_INDEX + "_geopoint";
61+
public static final String TEST_INDEX_JSON_TEST = TEST_INDEX + "_json_test";
6162
public static final String DATASOURCES = ".ql-datasources";
6263

6364
public static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.ppl;
7+
8+
import org.junit.jupiter.api.Test;
9+
10+
import java.io.IOException;
11+
import org.json.JSONObject;
12+
13+
import javax.json.Json;
14+
15+
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_JSON_TEST;
16+
import static org.opensearch.sql.util.MatcherUtils.rows;
17+
import static org.opensearch.sql.util.MatcherUtils.schema;
18+
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
19+
import static org.opensearch.sql.util.MatcherUtils.verifySchema;
20+
21+
public class JsonFunctionIT extends PPLIntegTestCase {
22+
@Override
23+
public void init() throws IOException {
24+
loadIndex(Index.JSON_TEST);
25+
}
26+
27+
@Test
28+
public void test_json_valid() throws IOException {
29+
JSONObject result;
30+
31+
result =
32+
executeQuery(
33+
String.format(
34+
"source=%s | where json_valid(json_string) | fields test_name",
35+
TEST_INDEX_JSON_TEST
36+
)
37+
);
38+
verifySchema(result, schema("test_name", null, "string"));
39+
verifyDataRows(
40+
result,
41+
rows("json object"),
42+
rows("json array"),
43+
rows("json scalar string"),
44+
rows("json empty string")
45+
);
46+
}
47+
48+
@Test
49+
public void test_not_json_valid() throws IOException {
50+
JSONObject result;
51+
52+
result =
53+
executeQuery(
54+
String.format(
55+
"source=%s | where not json_valid(json_string) | fields test_name",
56+
TEST_INDEX_JSON_TEST
57+
)
58+
);
59+
verifySchema(result, schema("test_name", null, "string"));
60+
verifyDataRows(
61+
result,
62+
rows("json invalid object")
63+
);
64+
}
65+
}

0 commit comments

Comments
 (0)