You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2019/10/27 00:24:51 UTC
[calcite] 01/02: Refactor SqlPrettyWriterTest,
using a fluent API for invoking tests
This is an automated email from the ASF dual-hosted git repository.
jhyde pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
commit dfd6a0cdc51b61e88787fcae92839119e868df0e
Author: Julian Hyde <jh...@apache.org>
AuthorDate: Fri Oct 25 17:04:12 2019 -0700
Refactor SqlPrettyWriterTest, using a fluent API for invoking tests
---
.../calcite/sql/test/SqlPrettyWriterTest.java | 454 +++++++++++----------
.../calcite/sql/test/SqlPrettyWriterTest.xml | 2 +-
2 files changed, 240 insertions(+), 216 deletions(-)
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java
index ce7a806..42a5041 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java
@@ -31,6 +31,9 @@ import org.junit.Test;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.UnaryOperator;
import static org.junit.Assert.assertTrue;
@@ -42,8 +45,6 @@ import static org.junit.Assert.assertTrue;
public class SqlPrettyWriterTest {
//~ Static fields/initializers ---------------------------------------------
- public static final String NL = System.getProperty("line.separator");
-
//~ Constructors -----------------------------------------------------------
public SqlPrettyWriterTest() {
@@ -65,289 +66,312 @@ public class SqlPrettyWriterTest {
try {
node = SqlParser.create(sql).parseQuery();
} catch (SqlParseException e) {
- String message = "Received error while parsing SQL '" + sql
- + "'; error is:" + NL + e.toString();
+ String message = "Received error while parsing SQL '" + sql + "'"
+ + "; error is:\n"
+ + e.toString();
throw new AssertionError(message);
}
return node;
}
- protected void assertPrintsTo(
- boolean newlines,
- final String sql,
- String expected) {
- final SqlNode node = parseQuery(sql);
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setAlwaysUseParentheses(false);
- if (newlines) {
- prettyWriter.setCaseClausesOnNewLines(true);
+ /** Helper. */
+ class Sql {
+ private final String sql;
+ private final boolean expr;
+ private final String desc;
+ private final String formatted;
+ private final UnaryOperator<SqlPrettyWriter> transform;
+
+ Sql(String sql, boolean expr, String desc, String formatted,
+ UnaryOperator<SqlPrettyWriter> transform) {
+ this.sql = Objects.requireNonNull(sql);
+ this.expr = expr;
+ this.desc = desc;
+ this.formatted = Objects.requireNonNull(formatted);
+ this.transform = Objects.requireNonNull(transform);
+ }
+
+ Sql withWriter(Consumer<SqlPrettyWriter> consumer) {
+ Objects.requireNonNull(consumer);
+ return new Sql(sql, expr, desc, formatted, w -> {
+ final SqlPrettyWriter w2 = transform.apply(w);
+ consumer.accept(w2);
+ return w2;
+ });
+ }
+
+ Sql expectingDesc(String desc) {
+ return Objects.equals(this.desc, desc)
+ ? this
+ : new Sql(sql, expr, desc, formatted, transform);
+ }
+
+ Sql withExpr(boolean expr) {
+ return this.expr == expr
+ ? this
+ : new Sql(sql, expr, desc, formatted, transform);
+ }
+
+ Sql expectingFormatted(String formatted) {
+ return Objects.equals(this.formatted, formatted)
+ ? this
+ : new Sql(sql, expr, desc, formatted, transform);
}
- String actual = prettyWriter.format(node);
- getDiffRepos().assertEquals("formatted", expected, actual);
-
- // Now parse the result, and make sure it is structurally equivalent
- // to the original.
- final String actual2 = actual.replaceAll("`", "\"");
- final SqlNode node2 = parseQuery(actual2);
- assertTrue(node.equalsDeep(node2, Litmus.THROW));
- }
- protected void assertExprPrintsTo(
- boolean newlines,
- final String sql,
- String expected) {
- final SqlCall valuesCall = (SqlCall) parseQuery("VALUES (" + sql + ")");
- final SqlCall rowCall = valuesCall.operand(0);
- final SqlNode node = rowCall.operand(0);
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setAlwaysUseParentheses(false);
- if (newlines) {
- prettyWriter.setCaseClausesOnNewLines(true);
+ Sql check() {
+ final SqlPrettyWriter prettyWriter =
+ transform.apply(new SqlPrettyWriter(AnsiSqlDialect.DEFAULT));
+ final SqlNode node;
+ if (expr) {
+ final SqlCall valuesCall = (SqlCall) parseQuery("VALUES (" + sql + ")");
+ final SqlCall rowCall = valuesCall.operand(0);
+ node = rowCall.operand(0);
+ } else {
+ node = parseQuery(sql);
+ }
+
+ // Describe settings
+ if (desc != null) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+ prettyWriter.describe(pw, true);
+ pw.flush();
+ final String desc = sw.toString();
+ getDiffRepos().assertEquals("desc", this.desc, desc);
+ }
+
+ // Format
+ final String formatted = prettyWriter.format(node);
+ getDiffRepos().assertEquals("formatted", this.formatted, formatted);
+
+ // Now parse the result, and make sure it is structurally equivalent
+ // to the original.
+ final String actual2 = formatted.replaceAll("`", "\"");
+ final SqlNode node2;
+ if (expr) {
+ final SqlCall valuesCall =
+ (SqlCall) parseQuery("VALUES (" + actual2 + ")");
+ final SqlCall rowCall = valuesCall.operand(0);
+ node2 = rowCall.operand(0);
+ } else {
+ node2 = parseQuery(actual2);
+ }
+ assertTrue(node.equalsDeep(node2, Litmus.THROW));
+
+ return this;
}
- String actual = prettyWriter.format(node);
- getDiffRepos().assertEquals("formatted", expected, actual);
-
- // Now parse the result, and make sure it is structurally equivalent
- // to the original.
- final String actual2 = actual.replaceAll("`", "\"");
- final SqlNode valuesCall2 = parseQuery("VALUES (" + actual2 + ")");
- assertTrue(valuesCall.equalsDeep(valuesCall2, Litmus.THROW));
}
- // ~ Tests ----------------------------------------------------------------
+ private Sql simple() {
+ return sql("select x as a, b as b, c as c, d,"
+ + " 'mixed-Case string',"
+ + " unquotedCamelCaseId,"
+ + " \"quoted id\" "
+ + "from"
+ + " (select *"
+ + " from t"
+ + " where x = y and a > 5"
+ + " group by z, zz"
+ + " window w as (partition by c),"
+ + " w1 as (partition by c,d order by a, b"
+ + " range between interval '2:2' hour to minute preceding"
+ + " and interval '1' day following)) "
+ + "order by gg");
+ }
- protected void checkSimple(
- SqlPrettyWriter prettyWriter,
- String expectedDesc,
- String expected) throws Exception {
- final SqlNode node =
- parseQuery("select x as a, b as b, c as c, d,"
- + " 'mixed-Case string',"
- + " unquotedCamelCaseId,"
- + " \"quoted id\" "
- + "from"
- + " (select *"
- + " from t"
- + " where x = y and a > 5"
- + " group by z, zz"
- + " window w as (partition by c),"
- + " w1 as (partition by c,d order by a, b"
- + " range between interval '2:2' hour to minute preceding"
- + " and interval '1' day following)) "
- + "order by gg");
-
- // Describe settings
- final StringWriter sw = new StringWriter();
- final PrintWriter pw = new PrintWriter(sw);
- prettyWriter.describe(pw, true);
- pw.flush();
- String desc = sw.toString();
- getDiffRepos().assertEquals("desc", expectedDesc, desc);
-
- // Format
- String actual = prettyWriter.format(node);
- getDiffRepos().assertEquals("formatted", expected, actual);
+ private Sql sql(String sql) {
+ return new Sql(sql, false, "${desc}", "${formatted}", w -> w);
}
- @Test public void testDefault() throws Exception {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ private Sql expr(String sql) {
+ return sql(sql).withExpr(true).expectingDesc(null);
}
- @Test public void testIndent8() throws Exception {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setIndentation(8);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ // ~ Tests ----------------------------------------------------------------
+
+ @Test public void testDefault() {
+ simple().check();
}
- @Test public void testClausesNotOnNewLine() throws Exception {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setClauseStartsLine(false);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ @Test public void testIndent8() {
+ simple()
+ .withWriter(w -> w.setIndentation(8))
+ .check();
}
- @Test public void testSelectListItemsOnSeparateLines() throws Exception {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setSelectListItemsOnSeparateLines(true);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ @Test public void testClausesNotOnNewLine() {
+ simple()
+ .withWriter(w -> w.setClauseStartsLine(false))
+ .check();
}
- @Test public void testSelectListExtraIndentFlag() throws Exception {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setSelectListItemsOnSeparateLines(true);
- prettyWriter.setSelectListExtraIndentFlag(false);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ @Test public void testSelectListItemsOnSeparateLines() {
+ simple()
+ .withWriter(w -> w.setSelectListItemsOnSeparateLines(true))
+ .check();
}
- @Test public void testKeywordsLowerCase() throws Exception {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setKeywordsLowerCase(true);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ @Test public void testSelectListExtraIndentFlag() {
+ simple()
+ .withWriter(w -> w.setSelectListItemsOnSeparateLines(true))
+ .withWriter(w -> w.setSelectListExtraIndentFlag(false))
+ .check();
}
- @Test public void testParenthesizeAllExprs() throws Exception {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setAlwaysUseParentheses(true);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ @Test public void testKeywordsLowerCase() {
+ simple()
+ .withWriter(w -> w.setKeywordsLowerCase(true))
+ .check();
}
- @Test public void testOnlyQuoteIdentifiersWhichNeedIt() throws Exception {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setQuoteAllIdentifiers(false);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ @Test public void testParenthesizeAllExprs() {
+ simple()
+ .withWriter(w -> w.setAlwaysUseParentheses(true))
+ .check();
}
- @Test public void testDamiansSubQueryStyle() throws Exception {
+ @Test public void testOnlyQuoteIdentifiersWhichNeedIt() {
+ simple()
+ .withWriter(w -> w.setQuoteAllIdentifiers(false))
+ .check();
+ }
+
+ @Test public void testBlackSubQueryStyle() {
// Note that ( is at the indent, SELECT is on the same line, and ) is
// below it.
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setSubQueryStyle(SqlWriter.SubQueryStyle.BLACK);
- checkSimple(prettyWriter, "${desc}", "${formatted}");
+ simple()
+ .withWriter(w -> w.setSubQueryStyle(SqlWriter.SubQueryStyle.BLACK))
+ .check();
}
@Ignore("default SQL parser cannot parse DDL")
@Test public void testExplain() {
- assertPrintsTo(false, "explain select * from t", "foo");
+ sql("explain select * from t")
+ .check();
}
@Test public void testCase() {
// Note that CASE is rewritten to the searched form. Wish it weren't
// so, but that's beyond the control of the pretty-printer.
- assertExprPrintsTo(
- true,
- "case 1 when 2 + 3 then 4 when case a when b then c else d end then 6 else 7 end",
- "CASE" + NL
- + "WHEN 1 = 2 + 3" + NL
- + "THEN 4" + NL
- + "WHEN 1 = CASE" + NL
- + " WHEN `A` = `B`" + NL // todo: indent should be 4 not 8
- + " THEN `C`" + NL
- + " ELSE `D`" + NL
- + " END" + NL
- + "THEN 6" + NL
- + "ELSE 7" + NL
- + "END");
+ // todo: indent should be 4 not 8
+ final String sql = "case 1\n"
+ + " when 2 + 3 then 4\n"
+ + " when case a when b then c else d end then 6\n"
+ + " else 7\n"
+ + "end";
+ final String formatted = "CASE\n"
+ + "WHEN 1 = 2 + 3\n"
+ + "THEN 4\n"
+ + "WHEN 1 = CASE\n"
+ + " WHEN `A` = `B`\n" // todo: indent should be 4 not 8
+ + " THEN `C`\n"
+ + " ELSE `D`\n"
+ + " END\n"
+ + "THEN 6\n"
+ + "ELSE 7\n"
+ + "END";
+ expr(sql)
+ .withWriter(w -> w.setCaseClausesOnNewLines(true))
+ .expectingFormatted(formatted)
+ .check();
}
@Test public void testCase2() {
- assertExprPrintsTo(
- false,
- "case 1 when 2 + 3 then 4 when case a when b then c else d end then 6 else 7 end",
- "CASE WHEN 1 = 2 + 3 THEN 4 WHEN 1 = CASE WHEN `A` = `B` THEN `C` ELSE `D` END THEN 6 ELSE 7 END");
+ final String sql = "case 1"
+ + " when 2 + 3 then 4"
+ + " when case a when b then c else d end then 6"
+ + " else 7 end";
+ final String formatted = "CASE WHEN 1 = 2 + 3 THEN 4"
+ + " WHEN 1 = CASE WHEN `A` = `B` THEN `C` ELSE `D` END THEN 6"
+ + " ELSE 7 END";
+ expr(sql)
+ .expectingFormatted(formatted)
+ .check();
}
@Test public void testBetween() {
- assertExprPrintsTo(
- true,
- "x not between symmetric y and z",
- "`X` NOT BETWEEN SYMMETRIC `Y` AND `Z`"); // todo: remove leading
+ // todo: remove leading
+ expr("x not between symmetric y and z")
+ .expectingFormatted("`X` NOT BETWEEN SYMMETRIC `Y` AND `Z`")
+ .check();
// space
}
@Test public void testCast() {
- assertExprPrintsTo(
- true,
- "cast(x + y as decimal(5, 10))",
- "CAST(`X` + `Y` AS DECIMAL(5, 10))");
+ expr("cast(x + y as decimal(5, 10))")
+ .expectingFormatted("CAST(`X` + `Y` AS DECIMAL(5, 10))")
+ .check();
}
@Test public void testLiteralChain() {
- assertExprPrintsTo(
- true,
- "'x' /* comment */ 'y'" + NL
- + " 'z' ",
- "'x'" + NL + "'y'" + NL + "'z'");
+ final String sql = "'x' /* comment */ 'y'\n"
+ + " 'z' ";
+ final String formatted = "'x'\n"
+ + "'y'\n"
+ + "'z'";
+ expr(sql).expectingFormatted(formatted).check();
}
@Test public void testOverlaps() {
- assertExprPrintsTo(
- true,
- "(x,xx) overlaps (y,yy) or x is not null",
- "PERIOD (`X`, `XX`) OVERLAPS PERIOD (`Y`, `YY`) OR `X` IS NOT NULL");
+ final String sql = "(x,xx) overlaps (y,yy) or x is not null";
+ final String formatted = "PERIOD (`X`, `XX`) OVERLAPS PERIOD (`Y`, `YY`)"
+ + " OR `X` IS NOT NULL";
+ expr(sql).expectingFormatted(formatted).check();
}
@Test public void testUnion() {
- assertPrintsTo(
- true,
- "select * from t "
- + "union select * from ("
- + " select * from u "
- + " union select * from v) "
- + "union select * from w "
- + "order by a, b",
-
- // todo: SELECT should not be indented from UNION, like this:
- // UNION
- // SELECT *
- // FROM `W`
-
- "${formatted}");
+ // todo: SELECT should not be indented from UNION, like this:
+ // UNION
+ // SELECT *
+ // FROM `W`
+ final String sql = "select * from t "
+ + "union select * from ("
+ + " select * from u "
+ + " union select * from v) "
+ + "union select * from w "
+ + "order by a, b";
+ sql(sql)
+ .expectingDesc(null)
+ .check();
}
@Test public void testMultiset() {
- assertPrintsTo(
- false,
- "values (multiset (select * from t))",
- "${formatted}");
+ sql("values (multiset (select * from t))")
+ .expectingDesc(null)
+ .check();
}
@Test public void testInnerJoin() {
- assertPrintsTo(
- true,
- "select * from x inner join y on x.k=y.k",
- "${formatted}");
- }
-
- @Test public void testWhereListItemsOnSeparateLinesOr() throws Exception {
- checkPrettySeparateLines(
- "select x"
- + " from y"
- + " where h is not null and i < j"
- + " or ((a or b) is true) and d not in (f,g)"
- + " or x <> z");
+ sql("select * from x inner join y on x.k=y.k")
+ .expectingDesc(null)
+ .check();
}
- @Test public void testWhereListItemsOnSeparateLinesAnd() throws Exception {
- checkPrettySeparateLines(
- "select x"
- + " from y"
- + " where h is not null and (i < j"
- + " or ((a or b) is true)) and (d not in (f,g)"
- + " or v <> ((w * x) + y) * z)");
+ @Test public void testWhereListItemsOnSeparateLinesOr() {
+ final String sql = "select x"
+ + " from y"
+ + " where h is not null and i < j"
+ + " or ((a or b) is true) and d not in (f,g)"
+ + " or x <> z";
+ sql(sql)
+ .withWriter(w -> w.setSelectListItemsOnSeparateLines(true))
+ .withWriter(w -> w.setSelectListExtraIndentFlag(false))
+ .withWriter(w -> w.setWhereListItemsOnSeparateLines(true))
+ .check();
}
- private void checkPrettySeparateLines(String sql) {
- final SqlPrettyWriter prettyWriter =
- new SqlPrettyWriter(AnsiSqlDialect.DEFAULT);
- prettyWriter.setSelectListItemsOnSeparateLines(true);
- prettyWriter.setSelectListExtraIndentFlag(false);
-
- final SqlNode node = parseQuery(sql);
-
- // Describe settings
- final StringWriter sw = new StringWriter();
- final PrintWriter pw = new PrintWriter(sw);
- prettyWriter.describe(pw, true);
- pw.flush();
- String desc = sw.toString();
- getDiffRepos().assertEquals("desc", "${desc}", desc);
- prettyWriter.setWhereListItemsOnSeparateLines(true);
-
- // Format
- String actual = prettyWriter.format(node);
- getDiffRepos().assertEquals("formatted", "${formatted}", actual);
+ @Test public void testWhereListItemsOnSeparateLinesAnd() {
+ final String sql = "select x"
+ + " from y"
+ + " where h is not null and (i < j"
+ + " or ((a or b) is true)) and (d not in (f,g)"
+ + " or v <> ((w * x) + y) * z)";
+ sql(sql)
+ .withWriter(w -> w.setSelectListItemsOnSeparateLines(true))
+ .withWriter(w -> w.setSelectListExtraIndentFlag(false))
+ .withWriter(w -> w.setWhereListItemsOnSeparateLines(true))
+ .check();
}
}
diff --git a/core/src/test/resources/org/apache/calcite/sql/test/SqlPrettyWriterTest.xml b/core/src/test/resources/org/apache/calcite/sql/test/SqlPrettyWriterTest.xml
index 472061d..a349946 100644
--- a/core/src/test/resources/org/apache/calcite/sql/test/SqlPrettyWriterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/sql/test/SqlPrettyWriterTest.xml
@@ -154,7 +154,7 @@ FROM (SELECT *
ORDER BY GG]]>
</Resource>
</TestCase>
- <TestCase name="testDamiansSubQueryStyle">
+ <TestCase name="testBlackSubQueryStyle">
<Resource name="desc"/>
<Resource name="formatted">
<![CDATA[SELECT `X` AS `A`, `B` AS `B`, `C` AS `C`, `D`, 'mixed-Case string', `UNQUOTEDCAMELCASEID`, `quoted id`