Repository: calcite Updated Branches: refs/heads/master fe3b65f50 -> fb8ebd315
[CALCITE-2197] Fix test failures on Windows due to line endings Add several new matchers in Matchers: isLinux, containsStringLinux, hasTree, compose. Change tests that generate platform-specific strings to use them. Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/fb8ebd31 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/fb8ebd31 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/fb8ebd31 Branch: refs/heads/master Commit: fb8ebd31526cd2e203fa3526ca8de7a22ee0d139 Parents: fe3b65f Author: Julian Hyde <jh...@apache.org> Authored: Wed Feb 28 18:10:35 2018 -0800 Committer: Julian Hyde <jh...@apache.org> Committed: Mon Mar 12 00:16:13 2018 -0700 ---------------------------------------------------------------------- .../apache/calcite/interpreter/SortNode.java | 4 +- .../org/apache/calcite/rel/core/Project.java | 4 +- .../calcite/rel/metadata/RelMdCollation.java | 2 +- .../sql/type/CompositeOperandTypeChecker.java | 12 +- .../org/apache/calcite/plan/RelWriterTest.java | 8 +- .../rel/rel2sql/RelToSqlConverterTest.java | 7 +- .../org/apache/calcite/test/CalciteAssert.java | 18 +- .../java/org/apache/calcite/test/JdbcTest.java | 9 +- .../org/apache/calcite/test/LatticeTest.java | 8 +- .../java/org/apache/calcite/test/Matchers.java | 105 +++++++ .../org/apache/calcite/test/RelBuilderTest.java | 300 ++++++++++--------- .../java/org/apache/calcite/util/UtilTest.java | 55 ++++ .../org/apache/calcite/test/ServerTest.java | 6 +- 13 files changed, 356 insertions(+), 182 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/main/java/org/apache/calcite/interpreter/SortNode.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/interpreter/SortNode.java b/core/src/main/java/org/apache/calcite/interpreter/SortNode.java index dff97a6..04c95bf 100644 --- a/core/src/main/java/org/apache/calcite/interpreter/SortNode.java +++ b/core/src/main/java/org/apache/calcite/interpreter/SortNode.java @@ -89,8 +89,8 @@ public class SortNode extends AbstractSingleNode<Sort> { } return Ordering.compound( Iterables.transform(rel.getCollation().getFieldCollations(), - new Function<RelFieldCollation, Comparator<? super Row>>() { - public Comparator<? super Row> apply(RelFieldCollation input) { + new Function<RelFieldCollation, Comparator<Row>>() { + public Comparator<Row> apply(RelFieldCollation input) { return comparator(input); } })); http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/main/java/org/apache/calcite/rel/core/Project.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/core/Project.java b/core/src/main/java/org/apache/calcite/rel/core/Project.java index c3a2c2b..3119959 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Project.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Project.java @@ -279,7 +279,7 @@ public abstract class Project extends SingleRel { Mappings.TargetMapping mapping = Mappings.create(MappingType.INVERSE_SURJECTION, inputFieldCount, projects.size()); - for (Ord<RexNode> exp : Ord.zip(projects)) { + for (Ord<RexNode> exp : Ord.<RexNode>zip(projects)) { if (!(exp.e instanceof RexInputRef)) { return null; } @@ -306,7 +306,7 @@ public abstract class Project extends SingleRel { Mappings.TargetMapping mapping = Mappings.create(MappingType.INVERSE_FUNCTION, inputFieldCount, projects.size()); - for (Ord<RexNode> exp : Ord.zip(projects)) { + for (Ord<RexNode> exp : Ord.<RexNode>zip(projects)) { if (exp.e instanceof RexInputRef) { mapping.set(((RexInputRef) exp.e).getIndex(), exp.i); } http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java index b48e763..8fed9bb 100644 --- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java +++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java @@ -217,7 +217,7 @@ public class RelMdCollation final Multimap<Integer, Integer> targets = LinkedListMultimap.create(); final Map<Integer, SqlMonotonicity> targetsWithMonotonicity = new HashMap<>(); - for (Ord<RexNode> project : Ord.zip(projects)) { + for (Ord<RexNode> project : Ord.<RexNode>zip(projects)) { if (project.e instanceof RexInputRef) { targets.put(((RexInputRef) project.e).getIndex(), project.i); } else if (project.e instanceof RexCall) { http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java b/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java index c8b7f13..36d47cb 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java +++ b/core/src/main/java/org/apache/calcite/sql/type/CompositeOperandTypeChecker.java @@ -129,7 +129,8 @@ public class CompositeOperandTypeChecker implements SqlOperandTypeChecker { "specify allowedSignatures or override getAllowedSignatures"); } StringBuilder ret = new StringBuilder(); - for (Ord<SqlOperandTypeChecker> ord : Ord.zip(allowedRules)) { + for (Ord<SqlOperandTypeChecker> ord + : Ord.<SqlOperandTypeChecker>zip(allowedRules)) { if (ord.i > 0) { ret.append(SqlOperator.NL); } @@ -272,7 +273,8 @@ public class CompositeOperandTypeChecker implements SqlOperandTypeChecker { if (callBinding.getOperandCount() != allowedRules.size()) { return false; } - for (Ord<SqlOperandTypeChecker> ord : Ord.zip(allowedRules)) { + for (Ord<SqlOperandTypeChecker> ord + : Ord.<SqlOperandTypeChecker>zip(allowedRules)) { SqlOperandTypeChecker rule = ord.e; if (!((SqlSingleOperandTypeChecker) rule).checkSingleOperandType( callBinding, @@ -285,7 +287,8 @@ public class CompositeOperandTypeChecker implements SqlOperandTypeChecker { return true; case AND: - for (Ord<SqlOperandTypeChecker> ord : Ord.zip(allowedRules)) { + for (Ord<SqlOperandTypeChecker> ord + : Ord.<SqlOperandTypeChecker>zip(allowedRules)) { SqlOperandTypeChecker rule = ord.e; if (!rule.checkOperandTypes(callBinding, false)) { // Avoid trying other rules in AND if the first one fails. @@ -295,7 +298,8 @@ public class CompositeOperandTypeChecker implements SqlOperandTypeChecker { return true; case OR: - for (Ord<SqlOperandTypeChecker> ord : Ord.zip(allowedRules)) { + for (Ord<SqlOperandTypeChecker> ord + : Ord.<SqlOperandTypeChecker>zip(allowedRules)) { SqlOperandTypeChecker rule = ord.e; if (rule.checkOperandTypes(callBinding, false)) { return true; http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java index 4f4829b..2ceea23 100644 --- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java +++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java @@ -34,7 +34,6 @@ import org.apache.calcite.sql.type.SqlTypeName; import org.apache.calcite.test.JdbcTest; import org.apache.calcite.tools.Frameworks; import org.apache.calcite.util.ImmutableBitSet; -import org.apache.calcite.util.Util; import com.google.common.collect.ImmutableList; @@ -44,6 +43,8 @@ import java.io.IOException; import java.math.BigDecimal; import java.util.Arrays; +import static org.apache.calcite.test.Matchers.isLinux; + import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -178,9 +179,8 @@ public class RelWriterTest { } }); - assertThat(Util.toLinux(s), - is( - "LogicalAggregate(group=[{0}], agg#0=[COUNT(DISTINCT $1)], agg#1=[COUNT()])\n" + assertThat(s, + isLinux("LogicalAggregate(group=[{0}], agg#0=[COUNT(DISTINCT $1)], agg#1=[COUNT()])\n" + " LogicalFilter(condition=[=($1, 10)])\n" + " LogicalTableScan(table=[[hr, emps]])\n")); } http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java index 2cdda74..afec0c2 100644 --- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java +++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java @@ -45,7 +45,6 @@ import org.apache.calcite.tools.Program; import org.apache.calcite.tools.Programs; import org.apache.calcite.tools.RuleSet; import org.apache.calcite.tools.RuleSets; -import org.apache.calcite.util.Util; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; @@ -56,6 +55,8 @@ import java.util.List; import junit.framework.AssertionFailedError; +import static org.apache.calcite.test.Matchers.isLinux; + import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -2406,7 +2407,7 @@ public class RelToSqlConverterTest { } Sql ok(String expectedQuery) { - assertThat(exec(), is(expectedQuery)); + assertThat(exec(), isLinux(expectedQuery)); return this; } @@ -2434,7 +2435,7 @@ public class RelToSqlConverterTest { final RelToSqlConverter converter = new RelToSqlConverter(dialect); final SqlNode sqlNode = converter.visitChild(0, rel).asStatement(); - return Util.toLinux(sqlNode.toSqlString(dialect).getSql()); + return sqlNode.toSqlString(dialect).getSql(); } catch (RuntimeException e) { throw e; } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/test/java/org/apache/calcite/test/CalciteAssert.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java index 49a9c31..2a30093 100644 --- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java +++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java @@ -101,9 +101,13 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.sql.DataSource; +import static org.apache.calcite.test.Matchers.containsStringLinux; +import static org.apache.calcite.test.Matchers.isLinux; + import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; @@ -242,8 +246,8 @@ public class CalciteAssert { if (counter != null) { counter.incrementAndGet(); } - String s = Util.toLinux(RelOptUtil.toString(relNode)); - assertThat(s, containsString(expected)); + String s = RelOptUtil.toString(relNode); + assertThat(s, containsStringLinux(expected)); return null; } }; @@ -313,7 +317,7 @@ public class CalciteAssert { public Void apply(ResultSet resultSet) { try { resultSetFormatter.resultSet(resultSet); - assertEquals(expected, Util.toLinux(resultSetFormatter.string())); + assertThat(resultSetFormatter.string(), isLinux(expected)); return null; } catch (SQLException e) { throw new RuntimeException(e); @@ -333,8 +337,8 @@ public class CalciteAssert { throw new AssertionError("expected 1 column"); } final String resultString = resultSet.getString(1); - assertEquals(expected, - resultString == null ? null : Util.toLinux(resultString)); + assertThat(resultString, + expected == null ? nullValue(String.class) : isLinux(expected)); return null; } catch (SQLException e) { throw new RuntimeException(e); @@ -451,9 +455,9 @@ public class CalciteAssert { return new Function<ResultSet, Void>() { public Void apply(ResultSet s) { try { - final String actual = Util.toLinux(CalciteAssert.toString(s)); + final String actual = CalciteAssert.toString(s); for (String st : expected) { - assertThat(actual, containsString(st)); + assertThat(actual, containsStringLinux(st)); } return null; } catch (SQLException e) { http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/test/java/org/apache/calcite/test/JdbcTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java index bf2bd81..37651a3 100644 --- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java +++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java @@ -141,6 +141,7 @@ import java.util.TimeZone; import java.util.regex.Pattern; import javax.sql.DataSource; +import static org.apache.calcite.test.Matchers.isLinux; import static org.apache.calcite.util.Static.RESOURCE; import static org.hamcrest.CoreMatchers.containsString; @@ -267,8 +268,8 @@ public class JdbcTest { + "insert into \"adhoc\".V\n" + "values ('Fred', 56, 123.4)"); assertThat(resultSet.next(), is(true)); - assertThat(Util.toLinux(resultSet.getString(1)), - is( + assertThat(resultSet.getString(1), + isLinux( "EnumerableTableModify(table=[[adhoc, MUTABLE_EMPLOYEES]], operation=[INSERT], flattened=[false])\n" + " EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t1):JavaType(int) NOT NULL], expr#4=[10], expr#5=[CAST($t0):JavaType(class java.lang.String)], expr#6=[CAST($t2):JavaType(float) NOT NULL], expr#7=[null], empid=[$t3], deptno=[$t4], name=[$t5], salary=[$t6], commission=[$t7])\n" + " EnumerableValues(tuples=[[{ 'Fred', 56, 123.4 }]])\n")); @@ -6278,8 +6279,8 @@ public class JdbcTest { .returns("C=0\n"); switch (CalciteAssert.DB) { case HSQLDB: - assertThat(Util.toLinux(sqls[0]), - equalTo("SELECT COUNT(*) AS \"C\"\n" + assertThat(sqls[0], + isLinux("SELECT COUNT(*) AS \"C\"\n" + "FROM \"foodmart\".\"employee\"\n" + "WHERE \"first_name\" = 'abcde' AND \"gender\" = 'F'")); break; http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/test/java/org/apache/calcite/test/LatticeTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/LatticeTest.java b/core/src/test/java/org/apache/calcite/test/LatticeTest.java index 8dc0589..539a2cc 100644 --- a/core/src/test/java/org/apache/calcite/test/LatticeTest.java +++ b/core/src/test/java/org/apache/calcite/test/LatticeTest.java @@ -27,7 +27,6 @@ import org.apache.calcite.runtime.Hook; import org.apache.calcite.schema.SchemaPlus; import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.TestUtil; -import org.apache.calcite.util.Util; import com.google.common.base.Function; import com.google.common.base.Throwables; @@ -48,6 +47,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import static org.apache.calcite.test.Matchers.containsStringLinux; import static org.apache.calcite.test.Matchers.within; import static org.hamcrest.CoreMatchers.anyOf; @@ -313,14 +313,14 @@ public class LatticeTest { new Function<RelNode, Void>() { public Void apply(RelNode relNode) { counter.incrementAndGet(); - String s = Util.toLinux(RelOptUtil.toString(relNode)); + String s = RelOptUtil.toString(relNode); assertThat(s, anyOf( - containsString( + containsStringLinux( "LogicalProject(brand_name=[$1], customer_id=[$0])\n" + " LogicalAggregate(group=[{2, 10}])\n" + " LogicalTableScan(table=[[adhoc, star]])\n"), - containsString( + containsStringLinux( "LogicalAggregate(group=[{2, 10}])\n" + " LogicalTableScan(table=[[adhoc, star]])\n"))); return null; http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/test/java/org/apache/calcite/test/Matchers.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/Matchers.java b/core/src/test/java/org/apache/calcite/test/Matchers.java index 76d994f..5ea3a4e 100644 --- a/core/src/test/java/org/apache/calcite/test/Matchers.java +++ b/core/src/test/java/org/apache/calcite/test/Matchers.java @@ -16,18 +16,24 @@ */ package org.apache.calcite.test; +import org.apache.calcite.plan.RelOptUtil; +import org.apache.calcite.rel.RelNode; import org.apache.calcite.util.Util; +import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.hamcrest.BaseMatcher; +import org.hamcrest.CoreMatchers; import org.hamcrest.CustomTypeSafeMatcher; import org.hamcrest.Description; import org.hamcrest.Factory; import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import org.hamcrest.core.Is; import java.sql.ResultSet; import java.sql.SQLException; @@ -125,6 +131,81 @@ public class Matchers { return new IsWithin<T>(value, epsilon); } + /** Creates a matcher by applying a function to a value before calling + * another matcher. */ + public static <F, T> Matcher<F> compose(Matcher<T> matcher, + Function<F, T> f) { + return new ComposingMatcher<>(matcher, f); + } + + /** + * Creates a Matcher that matches when the examined string is equal to the + * specified {@code value} when all Windows-style line endings ("\r\n") + * have been converted to Unix-style line endings ("\n"). + * + * <p>Thus, if {@code foo()} is a function that returns "hello{newline}world" + * in the current operating system's line endings, then + * + * <blockquote> + * assertThat(foo(), isLinux("hello\nworld")); + * </blockquote> + * + * <p>will succeed on all platforms. + * + * @see Util#toLinux(String) + */ + @Factory + public static Matcher<String> isLinux(final String value) { + return compose(Is.is(value), + new Function<String, String>() { + public String apply(String input) { + return input == null ? null : Util.toLinux(input); + } + }); + } + + /** + * Creates a Matcher that matches a {@link RelNode} its string representation, + * after converting Windows-style line endings ("\r\n") + * to Unix-style line endings ("\n"), is equal to the given {@code value}. + */ + @Factory + public static Matcher<RelNode> hasTree(final String value) { + return compose(Is.is(value), + new Function<RelNode, String>() { + public String apply(RelNode input) { + // Convert RelNode to a string with Linux line-endings + return Util.toLinux(RelOptUtil.toString(input)); + } + }); + } + + /** + * Creates a matcher that matches when the examined string is equal to the + * specified <code>operand</code> when all Windows-style line endings ("\r\n") + * have been converted to Unix-style line endings ("\n"). + * + * <p>Thus, if {@code foo()} is a function that returns "hello{newline}world" + * in the current operating system's line endings, then + * + * <blockquote> + * assertThat(foo(), isLinux("hello\nworld")); + * </blockquote> + * + * <p>will succeed on all platforms. + * + * @see Util#toLinux(String) + */ + @Factory + public static Matcher<String> containsStringLinux(String value) { + return compose(CoreMatchers.containsString(value), + new Function<String, String>() { + public String apply(String input) { + return Util.toLinux(input); + } + }); + } + /** * Is the numeric value within a given difference another value? * @@ -162,6 +243,30 @@ public class Matchers { return min <= a && a <= max; } } + + /** Matcher that transforms the input value using a function before + * passing to another matcher. + * + * @param <F> From type: the type of value to be matched + * @param <T> To type: type returned by function, and the resulting matcher + */ + private static class ComposingMatcher<F, T> extends TypeSafeMatcher<F> { + private final Matcher<T> matcher; + private final Function<F, T> f; + + ComposingMatcher(Matcher<T> matcher, Function<F, T> f) { + this.matcher = matcher; + this.f = f; + } + + protected boolean matchesSafely(F item) { + return matcher.matches(f.apply(item)); + } + + public void describeTo(Description description) { + matcher.describeTo(description); + } + } } // End Matchers.java http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java index d04397f..1290191 100644 --- a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java @@ -16,7 +16,6 @@ */ package org.apache.calcite.test; -import org.apache.calcite.plan.RelOptUtil; import org.apache.calcite.plan.RelTraitDef; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.AggregateCall; @@ -44,7 +43,6 @@ import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.tools.RelRunners; import org.apache.calcite.util.Holder; import org.apache.calcite.util.ImmutableBitSet; -import org.apache.calcite.util.Util; import org.apache.calcite.util.mapping.Mappings; import com.google.common.collect.ImmutableList; @@ -59,6 +57,8 @@ import java.util.Arrays; import java.util.List; import java.util.TreeSet; +import static org.apache.calcite.test.Matchers.hasTree; + import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -109,11 +109,6 @@ public class RelBuilderTest { .programs(Programs.heuristicJoinOrder(Programs.RULE_SET, true, 2)); } - /** Converts a relational expression to a string with linux line-endings. */ - private String str(RelNode r) { - return Util.toLinux(RelOptUtil.toString(r)); - } - @Test public void testScan() { // Equivalent SQL: // SELECT * @@ -122,8 +117,8 @@ public class RelBuilderTest { RelBuilder.create(config().build()) .scan("EMP") .build(); - assertThat(str(root), - is("LogicalTableScan(table=[[scott, EMP]])\n")); + assertThat(root, + hasTree("LogicalTableScan(table=[[scott, EMP]])\n")); } @Test public void testScanQualifiedTable() { @@ -134,8 +129,8 @@ public class RelBuilderTest { RelBuilder.create(config().build()) .scan("scott", "EMP") .build(); - assertThat(str(root), - is("LogicalTableScan(table=[[scott, EMP]])\n")); + assertThat(root, + hasTree("LogicalTableScan(table=[[scott, EMP]])\n")); } @Test public void testScanInvalidTable() { @@ -208,8 +203,8 @@ public class RelBuilderTest { builder.scan("EMP") .filter(builder.literal(true)) .build(); - assertThat(str(root), - is("LogicalTableScan(table=[[scott, EMP]])\n")); + assertThat(root, + hasTree("LogicalTableScan(table=[[scott, EMP]])\n")); } @Test public void testScanFilterTriviallyFalse() { @@ -222,8 +217,8 @@ public class RelBuilderTest { builder.scan("EMP") .filter(builder.equals(builder.literal(1), builder.literal(2))) .build(); - assertThat(str(root), - is("LogicalValues(tuples=[[]])\n")); + assertThat(root, + hasTree("LogicalValues(tuples=[[]])\n")); } @Test public void testScanFilterEquals() { @@ -237,9 +232,9 @@ public class RelBuilderTest { .filter( builder.equals(builder.field("DEPTNO"), builder.literal(20))) .build(); - assertThat(str(root), - is("LogicalFilter(condition=[=($7, 20)])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "LogicalFilter(condition=[=($7, 20)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testScanFilterOr() { @@ -258,9 +253,10 @@ public class RelBuilderTest { builder.isNull(builder.field(6))), builder.isNotNull(builder.field(3))) .build(); - assertThat(str(root), - is("LogicalFilter(condition=[AND(OR(=($7, 20), IS NULL($6)), IS NOT NULL($3))])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalFilter(condition=[AND(OR(=($7, 20), IS NULL($6)), IS NOT NULL($3))])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testScanFilterOr2() { @@ -284,9 +280,9 @@ public class RelBuilderTest { builder.field("DEPTNO"), builder.literal(20)))) .build(); - assertThat(str(root), - is("LogicalFilter(condition=[>($7, 20)])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "LogicalFilter(condition=[>($7, 20)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testScanFilterAndFalse() { @@ -305,8 +301,8 @@ public class RelBuilderTest { builder.literal(20)), builder.literal(false)) .build(); - final String plan = "LogicalValues(tuples=[[]])\n"; - assertThat(str(root), is(plan)); + final String expected = "LogicalValues(tuples=[[]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testScanFilterAndTrue() { @@ -323,9 +319,9 @@ public class RelBuilderTest { builder.literal(20)), builder.literal(true)) .build(); - final String plan = "LogicalFilter(condition=[>($7, 20)])\n" + final String expected = "LogicalFilter(condition=[>($7, 20)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(plan)); + assertThat(root, hasTree(expected)); } @Test public void testBadFieldName() { @@ -383,10 +379,10 @@ public class RelBuilderTest { .build(); // Note: CAST(COMM) gets the COMM alias because it occurs first // Note: AS(COMM, C) becomes just $6 - assertThat(str(root), - is( - "LogicalProject(DEPTNO=[$7], COMM=[CAST($6):SMALLINT NOT NULL], $f2=[20], COMM0=[$6], C=[$6])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalProject(DEPTNO=[$7], COMM=[CAST($6):SMALLINT NOT NULL], $f2=[20], COMM0=[$6], C=[$6])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } /** Tests each method that creates a scalar expression. */ @@ -414,12 +410,13 @@ public class RelBuilderTest { builder.field(6), builder.alias(builder.field(6), "C")) .build(); - assertThat(str(root), - is("LogicalProject(DEPTNO=[$7], COMM=[CAST($6):SMALLINT NOT NULL]," - + " $f2=[OR(=($7, 20), AND(null, =($7, 10), IS NULL($6)," - + " IS NULL($7)), =($7, 30))], n2=[IS NULL($2)]," - + " nn2=[IS NOT NULL($3)], $f5=[20], COMM0=[$6], C=[$6])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalProject(DEPTNO=[$7], COMM=[CAST($6):SMALLINT NOT NULL]," + + " $f2=[OR(=($7, 20), AND(null, =($7, 10), IS NULL($6)," + + " IS NULL($7)), =($7, 30))], n2=[IS NULL($2)]," + + " nn2=[IS NOT NULL($3)], $f5=[20], COMM0=[$6], C=[$6])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testProjectIdentity() { @@ -429,7 +426,7 @@ public class RelBuilderTest { .project(builder.fields(Mappings.bijection(Arrays.asList(0, 1, 2)))) .build(); final String expected = "LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** Test case for @@ -449,7 +446,7 @@ public class RelBuilderTest { .build(); final String expected = "LogicalProject(a=[$0], c=[$2])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** Variation on {@link #testProjectIdentityWithFieldsRename}: don't use a @@ -477,7 +474,7 @@ public class RelBuilderTest { + " LogicalAggregate(group=[{0, 1, 2}], agg#0=[SUM($0)])\n" + " LogicalFilter(condition=[=($0, 20)])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testProjectLeadingEdge() { @@ -488,7 +485,7 @@ public class RelBuilderTest { .build(); final String expected = "LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testRename() { @@ -500,14 +497,14 @@ public class RelBuilderTest { .rename(Arrays.asList("DEPTNO", null)) .build(); final String expected = "LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); // No rename necessary (prefix matches) root = builder.scan("DEPT") .rename(ImmutableList.of("DEPTNO")) .build(); - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); // Add project to rename fields root = @@ -517,7 +514,7 @@ public class RelBuilderTest { final String expected2 = "" + "LogicalProject(NAME=[$0], DNAME=[$1], DEPTNO=[$2])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected2)); + assertThat(root, hasTree(expected2)); // If our requested list has non-unique names, we might get the same field // names we started with. Don't add a useless project. @@ -528,14 +525,14 @@ public class RelBuilderTest { final String expected3 = "" + "LogicalProject(DEPTNO=[$0], DNAME=[$1], DEPTNO0=[$2])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected3)); + assertThat(root, hasTree(expected3)); root = builder.scan("DEPT") .rename(Arrays.asList("DEPTNO", null, "DEPTNO")) .rename(Arrays.asList("DEPTNO", null, "DEPTNO")) .build(); // No extra Project - assertThat(str(root), is(expected3)); + assertThat(root, hasTree(expected3)); // Name list too long try { @@ -556,14 +553,14 @@ public class RelBuilderTest { .build(); final String expected = "LogicalValues(tuples=[[{ true, 1 }, { false, -50 }]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); // When you rename Values, you get a Values with a new row type, no Project root = builder.push(root) .rename(ImmutableList.of("x", "y z")) .build(); - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); assertThat(root.getRowType().getFieldNames().toString(), is("[x, y z]")); } @@ -575,7 +572,7 @@ public class RelBuilderTest { .build(); final String expected = "LogicalProject(JOB=[$2], EMPNO=[$0], ENAME=[$1])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testConvert() { @@ -593,7 +590,7 @@ public class RelBuilderTest { final String expected = "" + "LogicalProject(DEPTNO=[CAST($0):BIGINT NOT NULL], DNAME=[CAST($1):VARCHAR(10) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL], LOC=[CAST($2):VARCHAR(10) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testConvertRename() { @@ -611,7 +608,7 @@ public class RelBuilderTest { final String expected = "" + "LogicalProject(a=[CAST($0):BIGINT NOT NULL], b=[CAST($1):VARCHAR(10) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL], c=[CAST($2):VARCHAR(10) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAggregate() { @@ -626,9 +623,10 @@ public class RelBuilderTest { builder.aggregateCall(SqlStdOperatorTable.COUNT, true, false, null, "C", builder.field("DEPTNO"))) .build(); - assertThat(str(root), - is("LogicalAggregate(group=[{}], C=[COUNT(DISTINCT $7)])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalAggregate(group=[{}], C=[COUNT(DISTINCT $7)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testAggregate2() { @@ -652,11 +650,11 @@ public class RelBuilderTest { builder.call(SqlStdOperatorTable.PLUS, builder.field(3), builder.literal(1)))) .build(); - assertThat(str(root), - is("" - + "LogicalAggregate(group=[{1, 8}], C=[COUNT()], S=[SUM($9)])\n" - + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[+($4, $3)], $f9=[+($3, 1)])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalAggregate(group=[{1, 8}], C=[COUNT()], S=[SUM($9)])\n" + + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[+($4, $3)], $f9=[+($3, 1)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } /** Test case for @@ -683,7 +681,7 @@ public class RelBuilderTest { + "LogicalProject(ENAME=[$0])\n" + " LogicalAggregate(group=[{1}], C=[COUNT()])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** As {@link #testAggregate3()} but with Filter. */ @@ -712,7 +710,7 @@ public class RelBuilderTest { + " LogicalFilter(condition=[>($1, 3)])\n" + " LogicalAggregate(group=[{1}], C=[COUNT()])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAggregateFilter() { @@ -735,7 +733,7 @@ public class RelBuilderTest { + "LogicalAggregate(group=[{7}], groups=[[{7}, {}]], C=[COUNT() FILTER $8])\n" + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[>($0, 100)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAggregateFilterFails() { @@ -778,7 +776,7 @@ public class RelBuilderTest { + "LogicalAggregate(group=[{7}], C=[SUM($5) FILTER $8])\n" + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[IS TRUE(<($6, 100))])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** Test case for @@ -801,7 +799,7 @@ public class RelBuilderTest { + " LogicalProject(departmentNo=[$0])\n" + " LogicalProject(DEPTNO=[$7])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAggregateProjectWithExpression() { @@ -822,7 +820,7 @@ public class RelBuilderTest { + " LogicalProject(DEPTNO=[$0], $f1=[+($0, 3)])\n" + " LogicalProject(DEPTNO=[$7])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAggregateGroupingKeyOutOfRangeFails() { @@ -868,7 +866,7 @@ public class RelBuilderTest { final String expected = "" + "LogicalAggregate(group=[{6, 7}], groups=[[{6}, {7}]])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAggregateGrouping() { @@ -882,7 +880,7 @@ public class RelBuilderTest { final String expected = "" + "LogicalAggregate(group=[{6, 7}], g=[GROUPING($7)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAggregateGroupingWithDistinctFails() { @@ -929,8 +927,7 @@ public class RelBuilderTest { final String expected = "LogicalAggregate(group=[{0}])\n" + " LogicalProject(DEPTNO=[$7])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), - is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testDistinctAlready() { @@ -940,8 +937,8 @@ public class RelBuilderTest { builder.scan("DEPT") .distinct() .build(); - assertThat(str(root), - is("LogicalTableScan(table=[[scott, DEPT]])\n")); + final String expected = "LogicalTableScan(table=[[scott, DEPT]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testDistinctEmpty() { @@ -964,7 +961,7 @@ public class RelBuilderTest { + " LogicalProject\n" + " LogicalFilter(condition=[IS NULL($6)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testUnion() { @@ -984,13 +981,14 @@ public class RelBuilderTest { .project(builder.field("EMPNO")) .union(true) .build(); - assertThat(str(root), - is("LogicalUnion(all=[true])\n" - + " LogicalProject(DEPTNO=[$0])\n" - + " LogicalTableScan(table=[[scott, DEPT]])\n" - + " LogicalProject(EMPNO=[$0])\n" - + " LogicalFilter(condition=[=($7, 20)])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalUnion(all=[true])\n" + + " LogicalProject(DEPTNO=[$0])\n" + + " LogicalTableScan(table=[[scott, DEPT]])\n" + + " LogicalProject(EMPNO=[$0])\n" + + " LogicalFilter(condition=[=($7, 20)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } /** Test case for @@ -1036,14 +1034,15 @@ public class RelBuilderTest { .project(builder.field("DEPTNO")) .union(true, 3) .build(); - assertThat(str(root), - is("LogicalUnion(all=[true])\n" - + " LogicalProject(DEPTNO=[$0])\n" - + " LogicalTableScan(table=[[scott, DEPT]])\n" - + " LogicalProject(EMPNO=[$0])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n" - + " LogicalProject(DEPTNO=[$7])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalUnion(all=[true])\n" + + " LogicalProject(DEPTNO=[$0])\n" + + " LogicalTableScan(table=[[scott, DEPT]])\n" + + " LogicalProject(EMPNO=[$0])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n" + + " LogicalProject(DEPTNO=[$7])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testUnion1() { @@ -1063,9 +1062,9 @@ public class RelBuilderTest { .project(builder.field("DEPTNO")) .union(true, 1) .build(); - assertThat(str(root), - is("LogicalProject(DEPTNO=[$7])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "LogicalProject(DEPTNO=[$7])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testIntersect() { @@ -1086,13 +1085,14 @@ public class RelBuilderTest { .project(builder.field("EMPNO")) .intersect(false) .build(); - assertThat(str(root), - is("LogicalIntersect(all=[false])\n" - + " LogicalProject(DEPTNO=[$0])\n" - + " LogicalTableScan(table=[[scott, DEPT]])\n" - + " LogicalProject(EMPNO=[$0])\n" - + " LogicalFilter(condition=[=($7, 20)])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalIntersect(all=[false])\n" + + " LogicalProject(DEPTNO=[$0])\n" + + " LogicalTableScan(table=[[scott, DEPT]])\n" + + " LogicalProject(EMPNO=[$0])\n" + + " LogicalFilter(condition=[=($7, 20)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testIntersect3() { @@ -1112,14 +1112,15 @@ public class RelBuilderTest { .project(builder.field("DEPTNO")) .intersect(true, 3) .build(); - assertThat(str(root), - is("LogicalIntersect(all=[true])\n" - + " LogicalProject(DEPTNO=[$0])\n" - + " LogicalTableScan(table=[[scott, DEPT]])\n" - + " LogicalProject(EMPNO=[$0])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n" - + " LogicalProject(DEPTNO=[$7])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalIntersect(all=[true])\n" + + " LogicalProject(DEPTNO=[$0])\n" + + " LogicalTableScan(table=[[scott, DEPT]])\n" + + " LogicalProject(EMPNO=[$0])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n" + + " LogicalProject(DEPTNO=[$7])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testExcept() { @@ -1140,13 +1141,14 @@ public class RelBuilderTest { .project(builder.field("EMPNO")) .minus(false) .build(); - assertThat(str(root), - is("LogicalMinus(all=[false])\n" - + " LogicalProject(DEPTNO=[$0])\n" - + " LogicalTableScan(table=[[scott, DEPT]])\n" - + " LogicalProject(EMPNO=[$0])\n" - + " LogicalFilter(condition=[=($7, 20)])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n")); + final String expected = "" + + "LogicalMinus(all=[false])\n" + + " LogicalProject(DEPTNO=[$0])\n" + + " LogicalTableScan(table=[[scott, DEPT]])\n" + + " LogicalProject(EMPNO=[$0])\n" + + " LogicalFilter(condition=[=($7, 20)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(root, hasTree(expected)); } @Test public void testJoin() { @@ -1171,7 +1173,7 @@ public class RelBuilderTest { + " LogicalFilter(condition=[IS NULL($6)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** Same as {@link #testJoin} using USING. */ @@ -1190,7 +1192,7 @@ public class RelBuilderTest { + " LogicalFilter(condition=[IS NULL($6)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root2), is(expected)); + assertThat(root2, hasTree(expected)); } @Test public void testJoin2() { @@ -1219,7 +1221,7 @@ public class RelBuilderTest { + "LogicalJoin(condition=[AND(=($7, $8), =($0, 123))], joinType=[left])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testJoinCartesian() { @@ -1235,7 +1237,7 @@ public class RelBuilderTest { "LogicalJoin(condition=[true], joinType=[inner])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testCorrelationFails() { @@ -1277,7 +1279,7 @@ public class RelBuilderTest { + " LogicalFilter(condition=[=($cor0.SAL, 1000)])\n" + " LogicalFilter(condition=[=($0, $cor0.DEPTNO)])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAlias() { @@ -1302,7 +1304,7 @@ public class RelBuilderTest { + " LogicalJoin(condition=[true], joinType=[left])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); final RelDataTypeField field = root.getRowType().getFieldList().get(1); assertThat(field.getName(), is("DNAME")); assertThat(field.getType().isNullable(), is(true)); @@ -1336,7 +1338,7 @@ public class RelBuilderTest { + " LogicalJoin(condition=[true], joinType=[inner])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAliasSort() { @@ -1351,7 +1353,7 @@ public class RelBuilderTest { + "LogicalProject(EMPNO=[$0])\n" + " LogicalSort(sort0=[$0], dir0=[ASC])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAliasLimit() { @@ -1367,7 +1369,7 @@ public class RelBuilderTest { + "LogicalProject(EMPNO=[$0])\n" + " LogicalSort(sort0=[$1], dir0=[ASC], offset=[10], fetch=[20])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** Test case for @@ -1386,7 +1388,7 @@ public class RelBuilderTest { + "LogicalProject(DEPTNO=[$0])\n" + " LogicalProject(DEPTNO=[$7], $f1=[20])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testAliasAggregate() { @@ -1407,7 +1409,7 @@ public class RelBuilderTest { + " LogicalAggregate(group=[{0}], agg#0=[SUM($1)])\n" + " LogicalProject(DEPTNO=[$7], $f1=[20])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** Tests that a projection retains field names after a join. */ @@ -1432,7 +1434,7 @@ public class RelBuilderTest { + " LogicalJoin(condition=[true], joinType=[inner])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testMultiLevelAlias() { @@ -1466,7 +1468,7 @@ public class RelBuilderTest { + " LogicalJoin(condition=[true], joinType=[inner])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testUnionAlias() { @@ -1494,7 +1496,7 @@ public class RelBuilderTest { + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalProject(EMPNO=[$0], $f1=[||($1, '-2')])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** Test case for @@ -1525,7 +1527,7 @@ public class RelBuilderTest { + "LogicalJoin(condition=[AND(=($7, $8), =($0, 123))], joinType=[left])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** As {@link #testAliasPastTop()}. */ @@ -1561,7 +1563,7 @@ public class RelBuilderTest { + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, EMP]])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testEmpty() { @@ -1577,7 +1579,7 @@ public class RelBuilderTest { .build(); final String expected = "LogicalValues(tuples=[[]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); final String expectedType = "RecordType(TINYINT NOT NULL DEPTNO, BOOLEAN NOT NULL $f1) NOT NULL"; assertThat(root.getRowType().getFullTypeString(), is(expectedType)); @@ -1592,7 +1594,7 @@ public class RelBuilderTest { .build(); final String expected = "LogicalValues(tuples=[[{ true, 1 }, { false, -50 }]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); final String expectedType = "RecordType(BOOLEAN NOT NULL a, INTEGER NOT NULL b) NOT NULL"; assertThat(root.getRowType().getFullTypeString(), is(expectedType)); @@ -1609,7 +1611,7 @@ public class RelBuilderTest { false, null, "longer string").build(); final String expected = "LogicalValues(tuples=[[{ null, 1, 'abc' }, { false, null, 'longer string' }]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); final String expectedType = "RecordType(BOOLEAN a, INTEGER expr$1, CHAR(13) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL c) NOT NULL"; assertThat(root.getRowType().getFullTypeString(), is(expectedType)); @@ -1682,7 +1684,7 @@ public class RelBuilderTest { builder.values(rowType, null, null, 1, null).build(); final String expected = "LogicalValues(tuples=[[{ null, null }, { 1, null }]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); final String expectedType = "RecordType(BIGINT NOT NULL a, VARCHAR(10) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL a) NOT NULL"; assertThat(root.getRowType().getFullTypeString(), is(expectedType)); @@ -1701,14 +1703,14 @@ public class RelBuilderTest { final String expected = "LogicalSort(sort0=[$2], sort1=[$0], dir0=[ASC], dir1=[DESC])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); // same result using ordinals final RelNode root2 = builder.scan("EMP") .sort(2, -1) .build(); - assertThat(str(root2), is(expected)); + assertThat(root2, hasTree(expected)); } /** Test case for @@ -1725,7 +1727,7 @@ public class RelBuilderTest { .sortLimit(0, -1, ImmutableList.<RexNode>of()) .build(); final String expected = "LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testSortDuplicate() { @@ -1746,7 +1748,7 @@ public class RelBuilderTest { final String expected = "LogicalSort(sort0=[$0], sort1=[$7], sort2=[$4], " + "dir0=[DESC], dir1=[ASC], dir2=[ASC])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testSortByExpression() { @@ -1767,7 +1769,7 @@ public class RelBuilderTest { + " LogicalSort(sort0=[$1], sort1=[$8], dir0=[DESC-nulls-last], dir1=[ASC-nulls-first])\n" + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[+($4, $3)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testLimit() { @@ -1783,7 +1785,7 @@ public class RelBuilderTest { final String expected = "LogicalSort(offset=[2], fetch=[10])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testSortLimit() { @@ -1799,7 +1801,7 @@ public class RelBuilderTest { final String expected = "LogicalSort(sort0=[$7], dir0=[DESC], fetch=[10])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testSortLimit0() { @@ -1813,7 +1815,7 @@ public class RelBuilderTest { .sortLimit(-1, 0, builder.desc(builder.field("DEPTNO"))) .build(); final String expected = "LogicalValues(tuples=[[]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } /** Test case for @@ -1828,7 +1830,7 @@ public class RelBuilderTest { // inner sort node .limit(0, 1) .build(); - RelNode r = builder.scan("EMP") + RelNode root = builder.scan("EMP") .sort(0) .project(Lists.newArrayList(builder.field(1)), Lists.newArrayList("F1")) @@ -1839,7 +1841,7 @@ public class RelBuilderTest { String expected = "LogicalProject(F1=[$1])\n" + " LogicalSort(sort0=[$0], dir0=[ASC], fetch=[1])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(r), is(expected)); + assertThat(root, hasTree(expected)); } /** Tests that a sort on a field followed by a limit gives the same @@ -1858,13 +1860,13 @@ public class RelBuilderTest { final String expected = "" + "LogicalSort(sort0=[$7], dir0=[DESC], fetch=[10])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); final RelNode root2 = builder.scan("EMP") .sortLimit(-1, 10, builder.desc(builder.field("DEPTNO"))) .build(); - assertThat(str(root2), is(expected)); + assertThat(root2, hasTree(expected)); } /** Tests that a sort on an expression followed by a limit gives the same @@ -1884,7 +1886,7 @@ public class RelBuilderTest { + " LogicalSort(sort0=[$3], dir0=[DESC], offset=[3], fetch=[10])\n" + " LogicalProject(DEPTNO=[$0], DNAME=[$1], LOC=[$2], $f3=[+($0, 1)])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); final RelNode root2 = builder.scan("DEPT") @@ -1893,7 +1895,7 @@ public class RelBuilderTest { builder.call(SqlStdOperatorTable.PLUS, builder.field("DEPTNO"), builder.literal(1)))) .build(); - assertThat(str(root2), is(expected)); + assertThat(root2, hasTree(expected)); } /** Tests {@link org.apache.calcite.tools.RelRunner} for a VALUES query. */ @@ -2046,7 +2048,7 @@ public class RelBuilderTest { + ">(PREV(UP.$3, 0), PREV(UP.$3, 1))]], " + "inputFields=[[EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO]])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } @Test public void testFilterCastAny() { @@ -2063,7 +2065,7 @@ public class RelBuilderTest { final String expected = "" + "LogicalFilter(condition=[CAST($0):BOOLEAN NOT NULL])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(expected)); + assertThat(root, hasTree(expected)); } } http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/core/src/test/java/org/apache/calcite/util/UtilTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/util/UtilTest.java b/core/src/test/java/org/apache/calcite/util/UtilTest.java index dc3b6f8..c7cb9f9 100644 --- a/core/src/test/java/org/apache/calcite/util/UtilTest.java +++ b/core/src/test/java/org/apache/calcite/util/UtilTest.java @@ -35,6 +35,7 @@ import org.apache.calcite.sql.dialect.CalciteSqlDialect; import org.apache.calcite.sql.util.SqlBuilder; import org.apache.calcite.sql.util.SqlString; import org.apache.calcite.test.DiffTestCase; +import org.apache.calcite.test.Matchers; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; @@ -44,6 +45,8 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.primitives.Ints; +import org.hamcrest.Matcher; +import org.hamcrest.StringDescription; import org.junit.BeforeClass; import org.junit.Test; @@ -79,6 +82,8 @@ import java.util.TimeZone; import java.util.TreeSet; import javax.annotation.Nullable; +import static org.apache.calcite.test.Matchers.isLinux; + import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; @@ -2075,6 +2080,56 @@ public class UtilTest { + "</root>\n"; assertThat(Util.toLinux(s), is(expected)); } + + /** Unit test for {@link Matchers#compose}. */ + @Test public void testComposeMatcher() { + assertThat("x", is("x")); + assertThat(is("x").matches("x"), is(true)); + assertThat(is("X").matches("x"), is(false)); + final Function<String, String> toUpper = + new Function<String, String>() { + public String apply(String input) { + return input.toUpperCase(Locale.ROOT); + } + }; + assertThat(Matchers.compose(is("A"), toUpper).matches("a"), is(true)); + assertThat(Matchers.compose(is("A"), toUpper).matches("A"), is(true)); + assertThat(Matchers.compose(is("a"), toUpper).matches("A"), is(false)); + assertThat(describe(Matchers.compose(is("a"), toUpper)), is("is \"a\"")); + assertThat(mismatchDescription(Matchers.compose(is("a"), toUpper), "A"), + is("was \"A\"")); + } + + /** Unit test for {@link Matchers#isLinux}. */ + @Test public void testIsLinux() { + assertThat("xy", isLinux("xy")); + assertThat("x\ny", isLinux("x\ny")); + assertThat("x\r\ny", isLinux("x\ny")); + assertThat(isLinux("x").matches("x"), is(true)); + assertThat(isLinux("X").matches("x"), is(false)); + assertThat(mismatchDescription(isLinux("X"), "x"), is("was \"x\"")); + assertThat(describe(isLinux("X")), is("is \"X\"")); + assertThat(isLinux("x\ny").matches("x\ny"), is(true)); + assertThat(isLinux("x\ny").matches("x\r\ny"), is(true)); + // \n\r is not a valid windows line ending + assertThat(isLinux("x\ny").matches("x\n\ry"), is(false)); + assertThat(isLinux("x\ny").matches("x\n\ryz"), is(false)); + // left-hand side must be linux or will never match + assertThat(isLinux("x\r\ny").matches("x\r\ny"), is(false)); + assertThat(isLinux("x\r\ny").matches("x\ny"), is(false)); + } + + static String mismatchDescription(Matcher m, Object item) { + final StringDescription d = new StringDescription(); + m.describeMismatch(item, d); + return d.toString(); + } + + static String describe(Matcher m) { + final StringDescription d = new StringDescription(); + m.describeTo(d); + return d.toString(); + } } // End UtilTest.java http://git-wip-us.apache.org/repos/asf/calcite/blob/fb8ebd31/server/src/test/java/org/apache/calcite/test/ServerTest.java ---------------------------------------------------------------------- diff --git a/server/src/test/java/org/apache/calcite/test/ServerTest.java b/server/src/test/java/org/apache/calcite/test/ServerTest.java index 3a97412..92885ff 100644 --- a/server/src/test/java/org/apache/calcite/test/ServerTest.java +++ b/server/src/test/java/org/apache/calcite/test/ServerTest.java @@ -28,6 +28,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import static org.apache.calcite.test.Matchers.isLinux; + import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -120,7 +122,7 @@ public class ServerTest { + "EnumerableTableModify(table=[[T]], operation=[INSERT], flattened=[false])\n" + " EnumerableCalc(expr#0..1=[{inputs}], expr#2=[1], expr#3=[+($t1, $t2)], proj#0..1=[{exprs}], J=[$t3])\n" + " EnumerableValues(tuples=[[{ 3, 4 }]])\n"; - assertThat(r.getString(1), is(plan)); + assertThat(r.getString(1), isLinux(plan)); assertThat(r.next(), is(false)); } @@ -265,7 +267,7 @@ public class ServerTest { + " EnumerableTableScan(table=[[T]])\n"; try (ResultSet r = s.executeQuery("explain plan for " + sql)) { assertThat(r.next(), is(true)); - assertThat(r.getString(1), is(plan)); + assertThat(r.getString(1), isLinux(plan)); } } }