This is an automated email from the ASF dual-hosted git repository.
liuxun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 171f7fb486 [#6799] feat(clients/cli): Suport `TableFormat`,
`PlainFormat` for `Tag` (#6847)
171f7fb486 is described below
commit 171f7fb486578716d814b5520e4518ecc4e11dca
Author: Eric Chang <[email protected]>
AuthorDate: Mon May 12 18:34:01 2025 +0800
[#6799] feat(clients/cli): Suport `TableFormat`, `PlainFormat` for `Tag`
(#6847)
### What changes were proposed in this pull request?
This PR introduce table format and plain format to display the results
in `gcli.sh`.
### Why are the changes needed?
Support different formats of results.
Fix: #6799
### Does this PR introduce _any_ user-facing change?
Yes, it introduce plain format and table format to display results of
commands.
### How was this patch tested?
Tested manually and by `TestTableFormat` and `TestPlainFormat`.
This are steps to reproduce test result:
```
# build distribution
./gradlew clean compileDistribution -x test
cd distribution/package/bin
# start gravitino server
./gravitino.sh start
# create metalake
./gcli.sh metalake create --metalake my_metalake --comment "This is my
metalake"
my_metalake created
# create tags
./gcli.sh tag create --metalake my_metalake --tag tagA tagB
# set properties
./gcli.sh tag set --metalake my_metalake --tag tagA --property key1 --value
value1
tagA property set.
./gcli.sh tag set --metalake my_metalake --tag tagB --property key2 --value
value2
tagB property set.
# list properties with plain format
./gcli.sh tag properties --metalake my_metalake --tag tagA
key,value
key1,value1
# list properties with table format
./gcli.sh tag properties --metalake my_metalake --tag tagA --output table
+------+--------+
| Key | Value |
+------+--------+
| key1 | value1 |
+------+--------+
# list tags with plain format
./gcli.sh tag list --metalake my_metalake
name
tagA
tagB
# list tags with table format
./gcli.sh tag list --metalake my_metalake --output table
+------+
| Name |
+------+
| tagA |
| tagB |
+------+
# list properties with plain format
./gcli.sh tag properties --metalake my_metalake --tag tagA
key,value
key1,value1
test,value
# list properties with table format
./gcli.sh tag properties --metalake my_metalake --tag tagA --output table
+------+--------+
| Key | Value |
+------+--------+
| key1 | value1 |
| test | value |
+------+--------+
# add comment to tag
./gcli.sh tag update --metalake my_metalake --tag tagA --comment "new
comment"
tagA comment changed.
# show details in plain format
./gcli.sh tag details --metalake my_metalake --tag tagA
name,comment
tagA,new comment
# show details in table format
./gcli.sh tag details --metalake my_metalake --tag tagA --output table
+------+-------------+
| Name | Comment |
+------+-------------+
| tagA | new comment |
+------+-------------+
```
---
.../apache/gravitino/cli/commands/ListAllTags.java | 7 +-
.../gravitino/cli/commands/ListProperties.java | 8 +-
.../gravitino/cli/commands/ListTagProperties.java | 8 +-
.../apache/gravitino/cli/commands/TagDetails.java | 2 +-
.../org/apache/gravitino/cli/outputs/LineUtil.java | 12 +++
.../apache/gravitino/cli/outputs/PlainFormat.java | 83 +++++++++++++++-
.../apache/gravitino/cli/outputs/TableFormat.java | 95 +++++++++++++++++-
.../gravitino/cli/output/TestPlainFormat.java | 60 ++++++++++++
.../gravitino/cli/output/TestTableFormat.java | 107 +++++++++++++++++++++
9 files changed, 367 insertions(+), 15 deletions(-)
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListAllTags.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListAllTags.java
index 63657bb0fd..a5fcd2a402 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListAllTags.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListAllTags.java
@@ -23,6 +23,7 @@ import org.apache.gravitino.cli.CommandContext;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.tag.Tag;
/* Lists all tags in a metalake. */
public class ListAllTags extends Command {
@@ -43,10 +44,10 @@ public class ListAllTags extends Command {
/** Lists all tags in a metalake. */
@Override
public void handle() {
- String[] tags = new String[0];
+ Tag[] tags = new Tag[] {};
try {
GravitinoClient client = buildClient(metalake);
- tags = client.listTags();
+ tags = client.listTagsInfo();
} catch (NoSuchMetalakeException err) {
exitWithError(ErrorMessages.UNKNOWN_METALAKE);
} catch (Exception exp) {
@@ -56,7 +57,7 @@ public class ListAllTags extends Command {
if (tags.length == 0) {
printInformation("No tags exist.");
} else {
- printResults(String.join(",", tags));
+ printResults(tags);
}
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListProperties.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListProperties.java
index 5ad7e53256..5625621e33 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListProperties.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListProperties.java
@@ -45,12 +45,6 @@ public class ListProperties extends Command {
* @param properties The name, value pairs of properties.
*/
public void printProperties(Map<String, String> properties) {
- StringBuilder all = new StringBuilder();
-
- for (Map.Entry<String, String> property : properties.entrySet()) {
- all.append(property.getKey() + "," + property.getValue() +
System.lineSeparator());
- }
-
- System.out.print(all);
+ printResults(properties);
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListTagProperties.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListTagProperties.java
index 13ace743f7..6e2b5f73ed 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListTagProperties.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListTagProperties.java
@@ -19,6 +19,7 @@
package org.apache.gravitino.cli.commands;
+import java.util.Collections;
import java.util.Map;
import org.apache.gravitino.cli.CommandContext;
import org.apache.gravitino.cli.ErrorMessages;
@@ -61,7 +62,10 @@ public class ListTagProperties extends ListProperties {
exitWithError(exp.getMessage());
}
- Map<String, String> properties = gTag.properties();
- printProperties(properties);
+ if (gTag != null) {
+ Map<String, String> props =
+ gTag.properties() != null ? gTag.properties() :
Collections.emptyMap();
+ printProperties(props);
+ }
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TagDetails.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TagDetails.java
index 75b127cf55..e3d1073143 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TagDetails.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TagDetails.java
@@ -61,7 +61,7 @@ public class TagDetails extends Command {
}
if (result != null) {
- printResults(result.name() + "," + result.comment());
+ printResults(result);
}
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/LineUtil.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/LineUtil.java
index 356a588953..95052f18d2 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/LineUtil.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/LineUtil.java
@@ -26,6 +26,7 @@ import org.apache.gravitino.rel.expressions.Expression;
import org.apache.gravitino.rel.expressions.FunctionExpression;
import org.apache.gravitino.rel.expressions.literals.Literal;
import org.apache.gravitino.rel.types.Type;
+import org.apache.gravitino.tag.Tag;
public class LineUtil {
// This expression is primarily used to match characters that have a display
width of
@@ -34,6 +35,7 @@ public class LineUtil {
Pattern.compile(
"[\u1100-\u115F\u2E80-\uA4CF\uAC00-\uD7A3\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE6F\uFF00-\uFF60\uFFE0-\uFFE6]");
public static final String EMPTY_DEFAULT_VALUE = "";
+ public static final String NULL_DEFAULT_VALUE = "N/A";
public static final String EMPTY_STRING_TYPE_DEFAULT_VALUE = "''";
/**
@@ -191,4 +193,14 @@ public class LineUtil {
public static String getComment(org.apache.gravitino.rel.Column column) {
return column.comment() == null ? "N/A" : column.comment();
}
+
+ /**
+ * Get the comment of a tag. If the tag does not have a comment, return
"N/A".
+ *
+ * @param tag the tag to get.
+ * @return the comment of the tag.
+ */
+ static String getComment(Tag tag) {
+ return tag.comment() == null ? "N/A" : tag.comment();
+ }
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/PlainFormat.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/PlainFormat.java
index 649c676e0b..6418021c29 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/PlainFormat.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/PlainFormat.java
@@ -20,6 +20,7 @@ package org.apache.gravitino.cli.outputs;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import org.apache.gravitino.Audit;
import org.apache.gravitino.Catalog;
@@ -31,6 +32,7 @@ import org.apache.gravitino.cli.CommandContext;
import org.apache.gravitino.model.Model;
import org.apache.gravitino.rel.Column;
import org.apache.gravitino.rel.Table;
+import org.apache.gravitino.tag.Tag;
/** Plain format to print a pretty string to standard out. */
public abstract class PlainFormat<T> extends BaseOutputFormat<T> {
@@ -76,8 +78,15 @@ public abstract class PlainFormat<T> extends
BaseOutputFormat<T> {
new AuditPlainFormat(context).output((Audit) entity);
} else if (entity instanceof Column[]) {
new ColumnListPlainFormat(context).output((Column[]) entity);
+ } else if (entity instanceof Tag) {
+ new TagDetailsPlainFormat(context).output((Tag) entity);
+ } else if (entity instanceof Tag[]) {
+ new TagListPlainFormat(context).output((Tag[]) entity);
+ } else if (entity instanceof Map) {
+ new PropertiesListPlainFormat(context).output((Map<?, ?>) entity);
} else {
- throw new IllegalArgumentException("Unsupported object type");
+ throw new IllegalArgumentException(
+ "Unsupported object type: " + (entity == null ? "null" :
entity.getClass().getName()));
}
}
@@ -404,4 +413,76 @@ public abstract class PlainFormat<T> extends
BaseOutputFormat<T> {
return
COMMA_JOINER.join(Arrays.stream(groups).map(Group::name).collect(Collectors.toList()));
}
}
+
+ /**
+ * Formats detail information of {@link org.apache.gravitino.tag.Tag}.
Output format: name,
+ * comment
+ */
+ static final class TagDetailsPlainFormat extends PlainFormat<Tag> {
+
+ /**
+ * Creates a new {@link TagDetailsPlainFormat}.
+ *
+ * @param context The command context.
+ */
+ public TagDetailsPlainFormat(CommandContext context) {
+ super(context);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getOutput(Tag tag) {
+ String comment = tag.comment() == null ? "N/A" : tag.comment();
+ return COMMA_JOINER.join(tag.name(), comment);
+ }
+ }
+
+ /** Formats array of {@link org.apache.gravitino.tag.Tag} information.
Output format: name */
+ static final class TagListPlainFormat extends PlainFormat<Tag[]> {
+
+ /**
+ * Creates a new {@link TagListPlainFormat}.
+ *
+ * @param context The command context.
+ */
+ public TagListPlainFormat(CommandContext context) {
+ super(context);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getOutput(Tag[] tags) {
+ List<String> tagNames =
Arrays.stream(tags).map(Tag::name).collect(Collectors.toList());
+ return NEWLINE_JOINER.join(tagNames);
+ }
+ }
+
+ /**
+ * Formats information about properties of {@link
org.apache.gravitino.tag.Tag}. Output format:
+ * key, value
+ */
+ static final class PropertiesListPlainFormat extends PlainFormat<Map<?, ?>> {
+
+ /**
+ * Creates a new {@link PropertiesListPlainFormat}.
+ *
+ * @param context The command context.
+ */
+ public PropertiesListPlainFormat(CommandContext context) {
+ super(context);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getOutput(Map<?, ?> properties) {
+ StringBuilder data = new StringBuilder();
+ properties.forEach(
+ (key, value) -> {
+ data.append(COMMA_JOINER.join(key.toString(), value.toString()));
+ data.append(System.lineSeparator());
+ });
+
+ return data.toString();
+ }
+ }
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java
index c4e556abd3..a34602f11b 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java
@@ -44,6 +44,7 @@ import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import org.apache.gravitino.Audit;
import org.apache.gravitino.Catalog;
@@ -55,6 +56,7 @@ import org.apache.gravitino.cli.CommandContext;
import org.apache.gravitino.cli.commands.Command;
import org.apache.gravitino.model.Model;
import org.apache.gravitino.rel.Table;
+import org.apache.gravitino.tag.Tag;
/**
* Abstract base class for formatting entity information into ASCII-art
tables. Provides
@@ -106,8 +108,15 @@ public abstract class TableFormat<T> extends
BaseOutputFormat<T> {
new AuditTableFormat(context).output((Audit) entity);
} else if (entity instanceof org.apache.gravitino.rel.Column[]) {
new
ColumnListTableFormat(context).output((org.apache.gravitino.rel.Column[])
entity);
+ } else if (entity instanceof Tag) {
+ new TagDetailsTableFormat(context).output((Tag) entity);
+ } else if (entity instanceof Tag[]) {
+ new TagListTableFormat(context).output((Tag[]) entity);
+ } else if (entity instanceof Map) {
+ new PropertiesListTableFormat(context).output((Map<?, ?>) entity);
} else {
- throw new IllegalArgumentException("Unsupported object type");
+ throw new IllegalArgumentException(
+ "Unsupported object type: " + (entity == null ? "null" :
entity.getClass().getName()));
}
}
@@ -902,4 +911,88 @@ public abstract class TableFormat<T> extends
BaseOutputFormat<T> {
return getTableFormat(name);
}
}
+
+ /**
+ * Formats a single {@link org.apache.gravitino.tag.Tag} instance into a
two-column table display.
+ * Displays tag details including name and comment information.
+ */
+ static final class TagDetailsTableFormat extends TableFormat<Tag> {
+ public TagDetailsTableFormat(CommandContext context) {
+ super(context);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getOutput(Tag tag) {
+ Column columnName = new Column(context, "name");
+ Column columnComment = new Column(context, "comment");
+
+ columnName.addCell(tag.name());
+ columnComment.addCell(LineUtil.getComment(tag));
+
+ return getTableFormat(columnName, columnComment);
+ }
+ }
+
+ /** Formats an array of {@link org.apache.gravitino.tag.Tag} names into
table display. */
+ static final class TagListTableFormat extends TableFormat<Tag[]> {
+
+ /**
+ * Creates a new {@link TableFormat} with the specified properties.
+ *
+ * @param context the command context.
+ */
+ public TagListTableFormat(CommandContext context) {
+ super(context);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getOutput(Tag[] tags) {
+ Column columnName = new Column(context, "name");
+
+ for (Tag t : tags) {
+ columnName.addCell(t.name());
+ }
+
+ return getTableFormat(columnName);
+ }
+ }
+
+ /**
+ * Formats a {@link java.util.Map} which key and value are {@link String}
into table display.
+ * Lists all key, values in a vertical format.
+ */
+ static final class PropertiesListTableFormat extends TableFormat<Map<?, ?>> {
+
+ /**
+ * Creates a new {@link TableFormat} with the specified properties.
+ *
+ * @param context the command context.
+ */
+ public PropertiesListTableFormat(CommandContext context) {
+ super(context);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getOutput(Map<?, ?> properties) {
+ Column columnKey = new Column(context, "key");
+ Column columnValue = new Column(context, "value");
+
+ properties.forEach(
+ (key, value) -> {
+ columnKey.addCell(key.toString());
+ columnValue.addCell(value.toString());
+ });
+
+ // if we have empty property, add a placeholder to it.
+ if (properties.isEmpty()) {
+ columnKey.addCell(LineUtil.NULL_DEFAULT_VALUE);
+ columnValue.addCell(LineUtil.NULL_DEFAULT_VALUE);
+ }
+
+ return getTableFormat(columnKey, columnValue);
+ }
+ }
}
diff --git
a/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestPlainFormat.java
b/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestPlainFormat.java
index c69424e116..7e4309391d 100644
---
a/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestPlainFormat.java
+++
b/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestPlainFormat.java
@@ -28,6 +28,7 @@ import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.List;
+import java.util.Map;
import org.apache.gravitino.Audit;
import org.apache.gravitino.Catalog;
import org.apache.gravitino.Metalake;
@@ -43,11 +44,13 @@ import org.apache.gravitino.rel.expressions.Expression;
import org.apache.gravitino.rel.expressions.literals.Literal;
import org.apache.gravitino.rel.types.Type;
import org.apache.gravitino.rel.types.Types;
+import org.apache.gravitino.tag.Tag;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.shaded.com.google.common.collect.ImmutableList;
+import org.testcontainers.shaded.com.google.common.collect.ImmutableMap;
public class TestPlainFormat {
@@ -256,6 +259,50 @@ public class TestPlainFormat {
output);
}
+ @Test
+ void testTagDetailsWithPlainFormat() {
+ CommandContext mockContext = getMockContext();
+ Tag mockTag = getMockTag("tag1", "comment for tag1", ImmutableMap.of("k1",
"v1", "k2", "v2"));
+
+ PlainFormat.output(mockTag, mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals("tag1,comment for tag1", output);
+ }
+
+ @Test
+ void testTagDetailsWithPlainFormatWithNullValues() {
+ CommandContext mockContext = getMockContext();
+ Tag mockTag = getMockTag("tag1", null);
+
+ PlainFormat.output(mockTag, mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals("tag1,N/A", output);
+ }
+
+ @Test
+ void testListAllTagsWithPlainFormat() {
+ CommandContext mockContext = getMockContext();
+
+ Tag mockTag1 = getMockTag("tag1", "comment for tag1");
+ Tag mockTag2 = getMockTag("tag2", "comment for tag2");
+ Tag mockTag3 = getMockTag("tag3", "comment for tag3");
+
+ PlainFormat.output(new Tag[] {mockTag1, mockTag2, mockTag3}, mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals("tag1\n" + "tag2\n" + "tag3", output);
+ }
+
+ @Test
+ void testListTagPropertiesWithPlainFormat() {
+ CommandContext mockContext = getMockContext();
+
+ Tag mockTag1 = getMockTag("tag1", "comment for tag1",
ImmutableMap.of("k1", "v1", "k2", "v2"));
+
+ PlainFormat.output(mockTag1.properties(), mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals("k1,v1\n" + "k2,v2", output);
+ }
+
@Test
void testOutputWithUnsupportType() {
CommandContext mockContext = getMockContext();
@@ -451,4 +498,17 @@ public class TestPlainFormat {
return mockGroup;
}
+
+ private Tag getMockTag(String name, String comment) {
+ return getMockTag(name, comment, ImmutableMap.of("k1", "v2", "k2", "v2"));
+ }
+
+ private Tag getMockTag(String name, String comment, Map<String, String>
properties) {
+ Tag mockTag = mock(Tag.class);
+ when(mockTag.name()).thenReturn(name);
+ when(mockTag.comment()).thenReturn(comment);
+ when(mockTag.properties()).thenReturn(properties);
+
+ return mockTag;
+ }
}
diff --git
a/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestTableFormat.java
b/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestTableFormat.java
index 45909b89ce..fe6b97f897 100644
---
a/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestTableFormat.java
+++
b/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestTableFormat.java
@@ -30,7 +30,9 @@ import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.apache.gravitino.Audit;
import org.apache.gravitino.Catalog;
import org.apache.gravitino.Metalake;
@@ -47,10 +49,12 @@ import
org.apache.gravitino.rel.expressions.FunctionExpression;
import org.apache.gravitino.rel.expressions.literals.Literal;
import org.apache.gravitino.rel.types.Type;
import org.apache.gravitino.rel.types.Types;
+import org.apache.gravitino.tag.Tag;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.testcontainers.shaded.com.google.common.collect.ImmutableMap;
public class TestTableFormat {
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
@@ -672,6 +676,96 @@ public class TestTableFormat {
output);
}
+ @Test
+ void testTagDetailsWithTableFormat() {
+ CommandContext mockContext = getMockContext();
+ Tag mockTag = getMockTag("tag1", "comment for tag1");
+
+ TableFormat.output(mockTag, mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals(
+ "+------+------------------+\n"
+ + "| Name | Comment |\n"
+ + "+------+------------------+\n"
+ + "| tag1 | comment for tag1 |\n"
+ + "+------+------------------+",
+ output);
+ }
+
+ @Test
+ void testTagDetailsWithTableFormatWithNullValues() {
+ CommandContext mockContext = getMockContext();
+ Tag mockTag = mock(Tag.class);
+ when(mockTag.name()).thenReturn("tag1");
+ when(mockTag.comment()).thenReturn(null);
+
+ TableFormat.output(mockTag, mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals(
+ "+------+---------+\n"
+ + "| Name | Comment |\n"
+ + "+------+---------+\n"
+ + "| tag1 | N/A |\n"
+ + "+------+---------+",
+ output);
+ }
+
+ @Test
+ void testListAllTagsWithTableFormat() {
+ CommandContext mockContext = getMockContext();
+
+ Tag mockTag1 = getMockTag("tag1", "comment for tag1");
+ Tag mockTag2 = getMockTag("tag2", "comment for tag2");
+ Tag mockTag3 = getMockTag("tag3", "comment for tag3");
+
+ TableFormat.output(new Tag[] {mockTag1, mockTag2, mockTag3}, mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals(
+ "+------+\n"
+ + "| Name |\n"
+ + "+------+\n"
+ + "| tag1 |\n"
+ + "| tag2 |\n"
+ + "| tag3 |\n"
+ + "+------+",
+ output);
+ }
+
+ @Test
+ void testListTagPropertiesWithTableFormat() {
+ CommandContext mockContext = getMockContext();
+
+ Tag mockTag1 = getMockTag("tag1", "comment for tag1");
+
+ TableFormat.output(mockTag1.properties(), mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals(
+ "+-----+-------+\n"
+ + "| Key | Value |\n"
+ + "+-----+-------+\n"
+ + "| k1 | v1 |\n"
+ + "| k2 | v2 |\n"
+ + "+-----+-------+",
+ output);
+ }
+
+ @Test
+ void testListTagPropertiesWithTableFormatWithEmptyMap() {
+ CommandContext mockContext = getMockContext();
+
+ Tag mockTag1 = getMockTag("tag1", "comment for tag1",
Collections.emptyMap());
+
+ TableFormat.output(mockTag1.properties(), mockContext);
+ String output = new String(outContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ Assertions.assertEquals(
+ "+-----+-------+\n"
+ + "| Key | Value |\n"
+ + "+-----+-------+\n"
+ + "| N/A | N/A |\n"
+ + "+-----+-------+",
+ output);
+ }
+
@Test
void testOutputWithUnsupportType() {
CommandContext mockContext = getMockContext();
@@ -803,4 +897,17 @@ public class TestTableFormat {
return mockGroup;
}
+
+ private Tag getMockTag(String name, String comment) {
+ return getMockTag(name, comment, ImmutableMap.of("k1", "v1", "k2", "v2"));
+ }
+
+ private Tag getMockTag(String name, String comment, Map<String, String>
properties) {
+ Tag mockTag = mock(Tag.class);
+ when(mockTag.name()).thenReturn(name);
+ when(mockTag.comment()).thenReturn(comment);
+ when(mockTag.properties()).thenReturn(properties);
+
+ return mockTag;
+ }
}