This is an automated email from the ASF dual-hosted git repository.

jinmeiliao pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 1da8eb9  GEODE-5288: improve ResultModel assertions (#2038)
1da8eb9 is described below

commit 1da8eb9259be5367aad70e1cb725067f3700a419
Author: FSOUTHERLAND <[email protected]>
AuthorDate: Mon Jun 11 07:55:09 2018 -0700

    GEODE-5288: improve ResultModel assertions (#2038)
    
    Co-authored-by: Finn Southerland <[email protected]>
---
 .../internal/cli/result/model/ResultModel.java     |  14 ++
 .../cli/result/model/TabularResultModel.java       |  52 ++++++-
 .../cli/commands/CreateIndexCommandTest.java       |   8 +-
 .../commands/ExecuteFunctionCommandDUnitTest.java  | 163 ++++++++++++++-------
 .../internal/cli/result/model/ResultModelTest.java |  11 ++
 .../cli/result/model/TabularResultModelTest.java   |  57 +++++++
 .../assertions/AbstractResultModelAssert.java      |  40 +++++
 .../test/junit/assertions/CommandResultAssert.java |  69 ++++++++-
 .../junit/assertions/DataResultModelAssert.java    |  34 +++++
 .../junit/assertions/InfoResultModelAssert.java    |  40 +++++
 .../junit/assertions/TabularResultModelAssert.java |  55 +++++++
 .../geode/test/junit/rules/GfshParserRule.java     |   2 +-
 12 files changed, 470 insertions(+), 75 deletions(-)

diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/model/ResultModel.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/model/ResultModel.java
index ef3f2f2..fc4785a 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/model/ResultModel.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/model/ResultModel.java
@@ -20,6 +20,7 @@ import static 
org.apache.geode.management.internal.cli.result.AbstractResultData
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -156,6 +157,8 @@ public class ResultModel {
     files.put(fileName, fileModel);
   }
 
+
+
   /**
    * Overloaded method to create an {@code InfoResultModel} section called 
"info".
    */
@@ -186,6 +189,10 @@ public class ResultModel {
         .map(InfoResultModel.class::cast).collect(Collectors.toList());
   }
 
+  public InfoResultModel getInfoSection(String name) {
+    return (InfoResultModel) sections.get(name);
+  }
+
   public TabularResultModel addTable(String namedSection) {
     Object model = sections.get(namedSection);
     if (model != null) {
@@ -276,6 +283,13 @@ public class ResultModel {
     return (DataResultModel) sections.get(name);
   }
 
+  public List<String> getSectionNames() {
+    List<String> sectionNames = new ArrayList<>();
+    sections.forEach((k, v) -> sectionNames.add(k));
+    return sectionNames;
+  }
+
+
   public String toJson() {
     ObjectMapper mapper = new ObjectMapper();
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
diff --git 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/model/TabularResultModel.java
 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/model/TabularResultModel.java
index 8d24f35..9bd5fe5 100644
--- 
a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/model/TabularResultModel.java
+++ 
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/model/TabularResultModel.java
@@ -21,7 +21,6 @@ import java.util.List;
 import java.util.Map;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
-import org.apache.commons.lang.ArrayUtils;
 
 public class TabularResultModel extends AbstractResultModel {
 
@@ -30,9 +29,6 @@ public class TabularResultModel extends AbstractResultModel {
    */
   private Map<String, List<String>> table = new LinkedHashMap<>();
 
-  @JsonIgnore
-  private String[] columnHeaders = new String[0];
-
   TabularResultModel() {}
 
   public TabularResultModel accumulate(String column, String value) {
@@ -42,7 +38,6 @@ public class TabularResultModel extends AbstractResultModel {
       List<String> list = new ArrayList<>();
       list.add(value);
       table.put(column, list);
-      columnHeaders = (String[]) ArrayUtils.add(columnHeaders, column);
     }
 
     return this;
@@ -54,18 +49,59 @@ public class TabularResultModel extends AbstractResultModel 
{
   }
 
   public void setColumnHeader(String... columnHeaders) {
-    this.columnHeaders = columnHeaders;
     for (String columnHeader : columnHeaders) {
       table.put(columnHeader, new ArrayList<>());
     }
   }
 
   public void addRow(String... values) {
-    if (values.length != columnHeaders.length) {
+    if (values.length != table.size()) {
       throw new IllegalStateException("row size is different than the column 
header size.");
     }
+    List<String> columnHeaders = getHeaders();
     for (int i = 0; i < values.length; i++) {
-      table.get(columnHeaders[i]).add(values[i]);
+      table.get(columnHeaders.get(i)).add(values[i]);
+    }
+  }
+
+  @JsonIgnore
+  public List<String> getHeaders() {
+    // this should maintain the original insertion order
+    List<String> headers = new ArrayList<>();
+    headers.addAll(table.keySet());
+    return headers;
+  }
+
+  @JsonIgnore
+  public String getValue(String columnName, int rowIndex) {
+    return table.get(columnName).get(rowIndex);
+  }
+
+  @JsonIgnore
+  public int getColumnSize() {
+    return table.size();
+  }
+
+  @JsonIgnore
+  public int getRowSize() {
+    if (table.size() == 0) {
+      return 0;
+    }
+    return table.values().iterator().next().size();
+  }
+
+  @JsonIgnore
+  public List<String> getValuesInColumn(String header) {
+    return table.get(header);
+  }
+
+  @JsonIgnore
+  public List<String> getValuesInRow(int index) {
+    List<String> headers = getHeaders();
+    List<String> values = new ArrayList<>();
+    for (String header : headers) {
+      values.add(table.get(header).get(index));
     }
+    return values;
   }
 }
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommandTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommandTest.java
index 5bd0be9..62782b6 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommandTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateIndexCommandTest.java
@@ -61,10 +61,10 @@ public class CreateIndexCommandTest {
 
   @Test
   public void missingName() throws Exception {
-    result = gfshParser.executeCommandWithInstance(command,
-        "create index --expression=abc --region=abc");
-    assertThat(result.getStatus()).isEqualTo(ERROR);
-    assertThat(result.getMessageFromContent()).contains("Invalid command");
+    gfshParser.executeAndAssertThat(command,
+        "create index --expression=abc --region=abc")
+        .statusIsError()
+        .containsOutput("Invalid command");
   }
 
   @Test
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommandDUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommandDUnitTest.java
index e8218dd..7a22bcc 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommandDUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ExecuteFunctionCommandDUnitTest.java
@@ -32,11 +32,10 @@ import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.FunctionService;
 import org.apache.geode.cache.execute.RegionFunctionContext;
-import org.apache.geode.management.internal.cli.result.ModelCommandResult;
-import 
org.apache.geode.management.internal.cli.result.model.TabularResultModel;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.assertions.CommandResultAssert;
+import org.apache.geode.test.junit.assertions.TabularResultModelAssert;
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.categories.GfshTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
@@ -68,7 +67,9 @@ public class ExecuteFunctionCommandDUnitTest {
 
     // create a partitioned region on only group1
     gfsh.executeAndAssertThat(
-        "create region --name=regionA --type=PARTITION --group=group1 
--redundant-copies=0 --total-num-buckets=2 
--partition-resolver=org.apache.geode.management.internal.cli.commands.ExecuteFunctionCommandDUnitTest$MyPartitionResolver");
+        "create region --name=regionA --type=PARTITION --group=group1 
--redundant-copies=0 --total-num-buckets=2 
--partition-resolver=org.apache.geode.management.internal.cli.commands.ExecuteFunctionCommandDUnitTest$MyPartitionResolver")
+        .statusIsSuccess()
+        .tableHasColumnOnlyWithValues("Member", "server-1", "server-2");
 
     locator.waitTillRegionsAreReadyOnServers("/regionA", 2);
 
@@ -79,51 +80,70 @@ public class ExecuteFunctionCommandDUnitTest {
     });
 
     // this makes sure entry a and entry b are on different member
-    CommandResultAssert locate1 =
-        gfsh.executeAndAssertThat("locate entry --key=a 
--region=/regionA").statusIsSuccess();
-    CommandResultAssert locate2 =
-        gfsh.executeAndAssertThat("locate entry --key=b 
--region=/regionA").statusIsSuccess();
-
-    TabularResultModel section1 =
-        ((ModelCommandResult) locate1.getCommandResult()).getResultData()
-            .getTableSection("location");
-    String member1 = section1.getContent().get("MemberName").get(0);
-    TabularResultModel section2 =
-        ((ModelCommandResult) locate2.getCommandResult()).getResultData()
-            .getTableSection("location");
-    String member2 = section2.getContent().get("MemberName").get(0);
+    CommandResultAssert locateACommand =
+        gfsh.executeAndAssertThat("locate entry --key=a 
--region=/regionA").statusIsSuccess()
+            .hasSection("location", "data-info");
+    locateACommand.hasDataSection().hasContent().containsEntry("Locations 
Found", "1");
+    
locateACommand.hasTableSection().hasColumnSize(4).hasColumn("MemberName").hasSize(1)
+        .isSubsetOf("server-1", "server-2");
+
+    CommandResultAssert locateBCommand =
+        gfsh.executeAndAssertThat("locate entry --key=b 
--region=/regionA").statusIsSuccess()
+            .hasSection("location", "data-info");
+    locateBCommand.hasDataSection().hasContent().containsEntry("Locations 
Found", "1");
+    
locateBCommand.hasTableSection().hasColumnSize(4).hasColumn("MemberName").hasSize(1)
+        .isSubsetOf("server-1", "server-2");
+
+    String member1 =
+        
locateACommand.getResultModel().getTableSection("location").getValue("MemberName",
 0);
+    String member2 =
+        
locateBCommand.getResultModel().getTableSection("location").getValue("MemberName",
 0);
+
     assertThat(member1).isNotEqualToIgnoringCase(member2);
   }
 
   @Test
   public void noExtraArgument() {
-    gfsh.executeAndAssertThat(command).statusIsSuccess()
-        .tableHasColumnWithExactValuesInAnyOrder("Member", "server-1", 
"server-2", "server-3")
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[genericFunctionId]",
-            "[genericFunctionId]", "[genericFunctionId]");
+    TabularResultModelAssert tableAssert =
+        gfsh.executeAndAssertThat(command).statusIsSuccess()
+            .hasTableSection()
+            .hasRowSize(3)
+            .hasColumnSize(3);
+    tableAssert.hasColumn("Member").containsExactlyInAnyOrder("server-1", 
"server-2", "server-3");
+    
tableAssert.hasColumn("Message").containsExactlyInAnyOrder("[genericFunctionId]",
+        "[genericFunctionId]", "[genericFunctionId]");
   }
 
   @Test
   public void withMemberOnly() {
     gfsh.executeAndAssertThat(command + "--member=server-1").statusIsSuccess()
-        .tableHasColumnWithExactValuesInAnyOrder("Member", "server-1")
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[genericFunctionId]");
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0).containsExactly("server-1", "OK", "[genericFunctionId]");
   }
 
   @Test
   public void withGroupOnly() {
-    gfsh.executeAndAssertThat(command + "--group=group1").statusIsSuccess()
-        .tableHasColumnWithExactValuesInAnyOrder("Member", "server-1", 
"server-2")
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[genericFunctionId]",
-            "[genericFunctionId]");
+    TabularResultModelAssert tableAssert =
+        gfsh.executeAndAssertThat(command + "--group=group1").statusIsSuccess()
+            .hasTableSection()
+            .hasRowSize(2)
+            .hasColumnSize(3);
+    tableAssert.hasColumn("Member").containsExactlyInAnyOrder("server-1", 
"server-2");
+    tableAssert.hasColumn("Message").containsExactly("[genericFunctionId]", 
"[genericFunctionId]");
   }
 
   @Test
   public void withArgumentsOnly() {
-    gfsh.executeAndAssertThat(command + 
"--arguments=arguments").statusIsSuccess()
-        .tableHasColumnWithExactValuesInAnyOrder("Member", "server-1", 
"server-2", "server-3")
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[genericFunctionId-arguments]",
-            "[genericFunctionId-arguments]", "[genericFunctionId-arguments]");
+    TabularResultModelAssert tableAssert =
+        gfsh.executeAndAssertThat(command + 
"--arguments=arguments").statusIsSuccess()
+            .hasTableSection()
+            .hasRowSize(3)
+            .hasColumnSize(3);
+    tableAssert.hasColumn("Member").containsExactlyInAnyOrder("server-1", 
"server-2", "server-3");
+    
tableAssert.hasColumn("Message").containsExactlyInAnyOrder("[genericFunctionId-arguments]",
+        "[genericFunctionId-arguments]", "[genericFunctionId-arguments]");
   }
 
 
@@ -132,9 +152,11 @@ public class ExecuteFunctionCommandDUnitTest {
     // function is only executed on one member, but the returned message is 
repeated twice
     // i.e. that member will execute the function on other members
     gfsh.executeAndAssertThat(command + "--region=/regionA").statusIsSuccess()
-        .tableHasRowCount("Member", 1)
-        .tableHasColumnWithExactValuesInAnyOrder("Message",
-            "[genericFunctionId, genericFunctionId]");
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .containsExactly("server-2", "OK", "[genericFunctionId, 
genericFunctionId]");
   }
 
   @Test
@@ -144,31 +166,43 @@ public class ExecuteFunctionCommandDUnitTest {
     // or "[genericFunctionId-b, genericFunctionId-a]" depending which 
server's function gets
     // executed first
     gfsh.executeAndAssertThat(command + "--region=/regionA 
--filter=a,b").statusIsSuccess()
-        .tableHasRowCount("Member", 1)
-        .tableHasColumnWithValuesContaining("Message", "[genericFunctionId-a, 
genericFunctionId-b]",
-            "[genericFunctionId-b, genericFunctionId-a]");
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .isSubsetOf("server1", "server-2", "OK", "[genericFunctionId-b, 
genericFunctionId-a]",
+            "[genericFunctionId-a, genericFunctionId-b]");
   }
 
   @Test
   public void withRegionAndFilterMatchingOnlyOneMember() {
     gfsh.executeAndAssertThat(command + "--region=/regionA 
--filter=a").statusIsSuccess()
-        .tableHasRowCount("Member", 1)
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[genericFunctionId-a]");
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .isSubsetOf("server-1", "server-2", "OK", "[genericFunctionId-a]");
   }
 
   @Test
   public void withRegionAndArguments() {
     gfsh.executeAndAssertThat(command + "--region=/regionA 
--arguments=arguments").statusIsSuccess()
-        .tableHasRowCount("Member", 1)
-        .tableHasColumnWithExactValuesInAnyOrder("Message",
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .isSubsetOf("server-1", "server-2", "OK",
             "[genericFunctionId-arguments, genericFunctionId-arguments]");
   }
 
   @Test
   public void withRegionAndFilterAndArgument() {
     gfsh.executeAndAssertThat(command + "--region=/regionA --filter=b 
--arguments=arguments")
-        .tableHasRowCount("Member", 1)
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[genericFunctionId-b-arguments]");
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .isSubsetOf("server-1", "server-2", "OK", 
"[genericFunctionId-b-arguments]");
   }
 
   @Test
@@ -176,8 +210,11 @@ public class ExecuteFunctionCommandDUnitTest {
     gfsh.executeAndAssertThat(
         command + "--region=/regionA --filter=a --arguments=arguments 
--result-collector="
             + ToUpperResultCollector.class.getName())
-        .tableHasRowCount("Member", 1)
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[GENERICFUNCTIONID-A-ARGUMENTS]");
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .isSubsetOf("server-1", "server-2", "OK", 
"[GENERICFUNCTIONID-A-ARGUMENTS]");
   }
 
   @Test
@@ -185,16 +222,22 @@ public class ExecuteFunctionCommandDUnitTest {
     gfsh.executeAndAssertThat(
         command + "--region=/regionA --arguments=arguments --result-collector="
             + ToUpperResultCollector.class.getName())
-        .tableHasRowCount("Member", 1)
-        .tableHasColumnWithExactValuesInAnyOrder("Message",
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .isSubsetOf("server-1", "server-2", "OK",
             "[GENERICFUNCTIONID-ARGUMENTS, GENERICFUNCTIONID-ARGUMENTS]");
   }
 
   @Test
   public void withMemberAndArgument() {
     gfsh.executeAndAssertThat(command + "--member=server-3 
--arguments=arguments").statusIsSuccess()
-        .tableHasColumnWithExactValuesInAnyOrder("Member", "server-3")
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[genericFunctionId-arguments]");
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .containsExactly("server-3", "OK", "[genericFunctionId-arguments]");
   }
 
   @Test
@@ -202,17 +245,27 @@ public class ExecuteFunctionCommandDUnitTest {
     gfsh.executeAndAssertThat(
         command + "--member=server-1 --arguments=arguments  
--result-collector="
             + ToUpperResultCollector.class.getName())
-        .statusIsSuccess().tableHasColumnWithExactValuesInAnyOrder("Member", 
"server-1")
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[GENERICFUNCTIONID-ARGUMENTS]");
+        .statusIsSuccess()
+        .hasTableSection()
+        .hasRowSize(1)
+        .hasColumnSize(3)
+        .hasRow(0)
+        .containsExactly("server-1", "OK", "[GENERICFUNCTIONID-ARGUMENTS]");
   }
 
   @Test
   public void withArgumentAndResultCollector() {
-    gfsh.executeAndAssertThat(command + "--arguments=arguments  
--result-collector="
-        + ToUpperResultCollector.class.getName()).statusIsSuccess()
-        .tableHasColumnWithExactValuesInAnyOrder("Member", "server-1", 
"server-2", "server-3")
-        .tableHasColumnWithExactValuesInAnyOrder("Message", 
"[GENERICFUNCTIONID-ARGUMENTS]",
-            "[GENERICFUNCTIONID-ARGUMENTS]", "[GENERICFUNCTIONID-ARGUMENTS]");
+
+    TabularResultModelAssert tableAssert =
+        gfsh.executeAndAssertThat(command + "--arguments=arguments  
--result-collector="
+            + ToUpperResultCollector.class.getName()).statusIsSuccess()
+            .hasTableSection()
+            .hasRowSize(3)
+            .hasColumnSize(3);
+
+    tableAssert.hasColumn("Member").containsExactlyInAnyOrder("server-1", 
"server-2", "server-3");
+    
tableAssert.hasColumn("Message").containsExactlyInAnyOrder("[GENERICFUNCTIONID-ARGUMENTS]",
+        "[GENERICFUNCTIONID-ARGUMENTS]", "[GENERICFUNCTIONID-ARGUMENTS]");
   }
 
 
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/result/model/ResultModelTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/result/model/ResultModelTest.java
index 9eec88c..cc75357 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/result/model/ResultModelTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/result/model/ResultModelTest.java
@@ -154,4 +154,15 @@ public class ResultModelTest {
     assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
     assertThat(table.getContent().get("Status").toString()).isEqualTo("[ERROR, 
ERROR]");
   }
+
+  @Test
+  public void getSectionName() {
+    result.addInfo("Section1");
+    result.addInfo("Section2");
+    result.addTable("Section3");
+    result.addData("Section4");
+
+    List<String> sectionNames = result.getSectionNames();
+    assertThat(sectionNames).containsExactly("Section1", "Section2", 
"Section3", "Section4");
+  }
 }
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/result/model/TabularResultModelTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/result/model/TabularResultModelTest.java
index e7c89d1..55b3261 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/result/model/TabularResultModelTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/result/model/TabularResultModelTest.java
@@ -45,17 +45,74 @@ public class TabularResultModelTest {
     table1.accumulate("c3", "v3");
     table1.accumulate("c3", "v6");
 
+    assertThat(table1.getColumnSize()).isEqualTo(3);
+
     TabularResultModel table2 = new TabularResultModel();
     table2.setColumnHeader("c1", "c2", "c3");
     table2.addRow("v1", "v2", "v3");
     table2.addRow("v4", "v5", "v6");
 
+    assertThat(table2.getColumnSize()).isEqualTo(3);
+
     
assertThat(table1.getContent()).isEqualToComparingFieldByFieldRecursively(table2.getContent());
   }
 
   @Test
+  public void fromJson() {
+    ResultModel result = new ResultModel();
+    table1 = result.addTable("table1");
+    // create table that has 2 columns and 1 rows
+    table1.accumulate("c1", "v1");
+    table1.accumulate("c2", "v2");
+    assertThat(table1.getColumnSize()).isEqualTo(2);
+    assertThat(table1.getRowSize()).isEqualTo(1);
+
+    String json = result.toJson();
+    assertThat(json).contains(
+        
"{\"table1\":{\"modelClass\":\"org.apache.geode.management.internal.cli.result.model.TabularResultModel\",\"header\":\"\",\"footer\":\"\",\"content\":{\"c1\":[\"v1\"],\"c2\":[\"v2\"]}}}");
+    // these make sure we don't serialize extra info
+    assertThat(json).doesNotContain("headers");
+    assertThat(json).doesNotContain("values");
+    assertThat(json).doesNotContain("columnSize");
+    assertThat(json).doesNotContain("rowSize");
+    assertThat(json).doesNotContain("valuesInColumn");
+    assertThat(json).doesNotContain("valuesInRow");
+
+    // convert the json back to the ResultModel object
+    ResultModel result2 = ResultModel.fromJson(json);
+    TabularResultModel table2 = result2.getTableSection("table1");
+    assertThat(table2.getColumnSize()).isEqualTo(2);
+    assertThat(table2.getHeaders()).containsExactly("c1", "c2");
+    assertThat(table2.getValuesInRow(0)).containsExactly("v1", "v2");
+    assertThat(table2.getRowSize()).isEqualTo(1);
+  }
+
+  @Test
   public void cannotAddRowWithDifferentSize() {
     table1.setColumnHeader("c1", "c2", "c3");
     assertThatThrownBy(() -> table1.addRow("v1", 
"v2")).isInstanceOf(IllegalStateException.class);
   }
+
+  @Test
+  public void getTableSizes() {
+    table1.setColumnHeader("header1");
+    assertThat(table1.getRowSize()).isZero();
+    table1.addRow("v1");
+    assertThat(table1.getRowSize()).isEqualTo(1);
+    table1.addRow("v2");
+    assertThat(table1.getRowSize()).isEqualTo(2);
+
+    assertThat(table1.getColumnSize()).isEqualTo(1);
+  }
+
+  @Test
+  public void getValuesInRow() {
+    table1.setColumnHeader("c1", "c2", "c3");
+    table1.addRow("v1", "k1", "t1");
+    table1.addRow("v2", "k2", "t2");
+    table1.addRow("v3", "k3", "t3");
+    assertThat(table1.getValuesInRow(0)).containsExactly("v1", "k1", "t1");
+    assertThat(table1.getValuesInRow(1)).containsExactly("v2", "k2", "t2");
+    assertThat(table1.getValuesInRow(2)).containsExactly("v3", "k3", "t3");
+  }
 }
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/assertions/AbstractResultModelAssert.java
 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/AbstractResultModelAssert.java
new file mode 100644
index 0000000..9ffca34
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/AbstractResultModelAssert.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF 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.
+ */
+
+package org.apache.geode.test.junit.assertions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.assertj.core.api.AbstractAssert;
+import org.assertj.core.api.AbstractCharSequenceAssert;
+
+import 
org.apache.geode.management.internal.cli.result.model.AbstractResultModel;
+
+public abstract class AbstractResultModelAssert<S extends 
AbstractResultModelAssert<S, T>, T extends AbstractResultModel>
+    extends
+    AbstractAssert<S, T> {
+
+  public AbstractResultModelAssert(T t, Class<?> selfType) {
+    super(t, selfType);
+  }
+
+  public AbstractCharSequenceAssert<?, String> hasHeader() {
+    return assertThat(actual.getHeader());
+  }
+
+  public AbstractCharSequenceAssert<?, String> hasFooter() {
+    return assertThat(actual.getFooter());
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/assertions/CommandResultAssert.java
 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/CommandResultAssert.java
index cb25cbc..d288017 100644
--- 
a/geode-core/src/test/java/org/apache/geode/test/junit/assertions/CommandResultAssert.java
+++ 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/CommandResultAssert.java
@@ -15,6 +15,7 @@
 package org.apache.geode.test.junit.assertions;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -24,10 +25,14 @@ import java.util.Map;
 import org.apache.commons.lang.StringUtils;
 import org.assertj.core.api.AbstractAssert;
 import org.assertj.core.api.Assertions;
-import org.json.JSONArray;
 
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.result.CommandResult;
+import org.apache.geode.management.internal.cli.result.ModelCommandResult;
+import org.apache.geode.management.internal.cli.result.model.DataResultModel;
+import org.apache.geode.management.internal.cli.result.model.InfoResultModel;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import 
org.apache.geode.management.internal.cli.result.model.TabularResultModel;
 
 
 public class CommandResultAssert
@@ -183,7 +188,6 @@ public class CommandResultAssert
   }
 
 
-
   public CommandResultAssert tableHasRowWithValues(String... 
headersThenValues) {
     assertThat(headersThenValues.length % 2)
         .describedAs("You need to pass even number of 
parameters.").isEqualTo(0);
@@ -276,13 +280,64 @@ public class CommandResultAssert
     return this;
   }
 
-  private Object[] toArray(JSONArray array) {
-    Object[] values = new Object[array.length()];
+  /*
+   * methods that are only applicable to ModelCommandResult
+   */
+
+  // Will throw error unless this is a ModelCommand Result
+  public ResultModel getResultModel() {
+    ModelCommandResult modelCommandResult = (ModelCommandResult) 
actual.getCommandResult();
+    return modelCommandResult.getResultData();
+  }
+
+  public CommandResultAssert hasSection(String... sectionName) {
+    ResultModel resultModel = getResultModel();
+    assertThat(resultModel.getSectionNames()).contains(sectionName);
+    return this;
+  }
+
+  // convenience method to get the first info section. if more than one info 
section
+  // use the sectionName to get it
+  public InfoResultModelAssert hasInfoSection() {
+    return new 
InfoResultModelAssert(getResultModel().getInfoSections().get(0));
+  }
+
+  public InfoResultModelAssert hasInfoSection(String sectionName) {
+    ResultModel resultModel = getResultModel();
+    InfoResultModel section = resultModel.getInfoSection(sectionName);
+    if (section == null) {
+      fail(sectionName + " section not found");
+    }
+    return new InfoResultModelAssert(section);
+  }
+
+  // convenience method to get the first table section. if more than one table 
section
+  // use the sectionName to get it
+  public TabularResultModelAssert hasTableSection() {
+    return new 
TabularResultModelAssert(getResultModel().getTableSections().get(0));
+  }
 
-    for (int i = 0; i < array.length(); i++) {
-      values[i] = array.get(i);
+  public TabularResultModelAssert hasTableSection(String sectionName) {
+    ResultModel resultModel = getResultModel();
+    TabularResultModel section = resultModel.getTableSection(sectionName);
+    if (section == null) {
+      fail(sectionName + " section not found");
     }
+    return new TabularResultModelAssert(section);
+  }
+
+  // convenience method to get the first data section. if more than one data 
section
+  // use the sectionName to get it
+  public DataResultModelAssert hasDataSection() {
+    return new 
DataResultModelAssert(getResultModel().getDataSections().get(0));
+  }
 
-    return values;
+  public DataResultModelAssert hasDataSection(String sectionName) {
+    ResultModel resultModel = getResultModel();
+    DataResultModel section = resultModel.getDataSection(sectionName);
+    if (section == null) {
+      fail(sectionName + " section not found");
+    }
+    return new DataResultModelAssert(section);
   }
 }
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/assertions/DataResultModelAssert.java
 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/DataResultModelAssert.java
new file mode 100644
index 0000000..22eadc1
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/DataResultModelAssert.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF 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.
+ */
+
+package org.apache.geode.test.junit.assertions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.assertj.core.api.MapAssert;
+
+import org.apache.geode.management.internal.cli.result.model.DataResultModel;
+
+public class DataResultModelAssert
+    extends AbstractResultModelAssert<DataResultModelAssert, DataResultModel> {
+
+  public DataResultModelAssert(DataResultModel resultModel) {
+    super(resultModel, DataResultModelAssert.class);
+  }
+
+  public MapAssert<String, String> hasContent() {
+    return assertThat(actual.getContent());
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/assertions/InfoResultModelAssert.java
 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/InfoResultModelAssert.java
new file mode 100644
index 0000000..5c7e4ff
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/InfoResultModelAssert.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF 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.
+ */
+
+package org.apache.geode.test.junit.assertions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.assertj.core.api.AbstractCharSequenceAssert;
+import org.assertj.core.api.ListAssert;
+
+import org.apache.geode.management.internal.cli.result.model.InfoResultModel;
+
+public class InfoResultModelAssert
+    extends AbstractResultModelAssert<InfoResultModelAssert, InfoResultModel> {
+
+  public InfoResultModelAssert(InfoResultModel infoResultModel) {
+    super(infoResultModel, InfoResultModelAssert.class);
+  }
+
+  public AbstractCharSequenceAssert<?, String> hasOutput() {
+    String output = String.join(System.lineSeparator(), actual.getContent());
+    return assertThat(output);
+  }
+
+  public ListAssert<String> hasLines() {
+    return assertThat(actual.getContent());
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/assertions/TabularResultModelAssert.java
 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/TabularResultModelAssert.java
new file mode 100644
index 0000000..1c59249
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/test/junit/assertions/TabularResultModelAssert.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF 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.
+ */
+
+package org.apache.geode.test.junit.assertions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.assertj.core.api.ListAssert;
+
+import 
org.apache.geode.management.internal.cli.result.model.TabularResultModel;
+
+public class TabularResultModelAssert
+    extends AbstractResultModelAssert<TabularResultModelAssert, 
TabularResultModel> {
+
+  public TabularResultModelAssert(TabularResultModel resultModel) {
+    super(resultModel, TabularResultModelAssert.class);
+  }
+
+  public TabularResultModelAssert hasRowSize(int expectedSize) {
+    assertThat(actual.getRowSize()).isEqualTo(expectedSize);
+    return this;
+  }
+
+
+  public TabularResultModelAssert hasColumnSize(int expectedSize) {
+    assertThat(actual.getColumnSize()).isEqualTo(expectedSize);
+    return this;
+  }
+
+  /**
+   * return a ListAssert for a column of values
+   */
+  public ListAssert<String> hasColumn(String header) {
+    return assertThat(actual.getValuesInColumn(header));
+  }
+
+  /**
+   * return a ListAssert for a row of values
+   */
+  public ListAssert<String> hasRow(int rowIndex) {
+    return assertThat(actual.getValuesInRow(rowIndex));
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/rules/GfshParserRule.java
 
b/geode-core/src/test/java/org/apache/geode/test/junit/rules/GfshParserRule.java
index 4085639..906eee2 100644
--- 
a/geode-core/src/test/java/org/apache/geode/test/junit/rules/GfshParserRule.java
+++ 
b/geode-core/src/test/java/org/apache/geode/test/junit/rules/GfshParserRule.java
@@ -62,7 +62,7 @@ public class GfshParserRule extends ExternalResource {
     GfshParseResult parseResult = parse(command);
 
     if (parseResult == null) {
-      return ResultBuilder.createUserErrorResult("Invalid command: " + 
command);
+      return new ModelCommandResult(ResultModel.createError("Invalid command: 
" + command));
     }
 
     CliAroundInterceptor interceptor = null;

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to