### Question:
Expr implements JsonSerializable { @Override public boolean equals(Object obj) { if (obj instanceof Expr) { Expr casted = (Expr) obj; if (this.opType == casted.opType && equalsTo(casted)) { if (this instanceof UnaryOperator) { UnaryOperator one = (UnaryOperator) this; UnaryOperator another = (UnaryOperator) casted; return one.getChild().equals(another.getChild()); } else if (this instanceof BinaryOperator) { BinaryOperator bin = (BinaryOperator) this; BinaryOperator anotherBin = (BinaryOperator) casted; if (!bin.getLeft().equals(anotherBin.getLeft())) { return false; } if (!bin.getRight().equals(anotherBin.getRight())) { return false; } return true; } else { return this.equalsTo(casted); } } } return false; } Expr(OpType opType); OpType getType(); @Override abstract int hashCode(); @Override boolean equals(Object obj); @Override String toString(); String toJson(); void accept(ExprVisitor visitor);  }### Answer:
@Test public void testBinaryHierarchyEquals() { Expr left1 = new BinaryOperator(OpType.Plus, new LiteralValue("1", LiteralType.Unsigned_Integer), new LiteralValue("2", LiteralType.Unsigned_Integer)); Expr right1 = new BinaryOperator(OpType.Multiply, new LiteralValue("2", LiteralType.Unsigned_Integer), new LiteralValue("3", LiteralType.Unsigned_Integer)); Expr one = new BinaryOperator(OpType.Plus, left1, right1); Expr left2 = new BinaryOperator(OpType.Plus, new LiteralValue("1", LiteralType.Unsigned_Integer), new LiteralValue("2", LiteralType.Unsigned_Integer)); Expr right2 = new BinaryOperator(OpType.Multiply, new LiteralValue("2", LiteralType.Unsigned_Integer), new LiteralValue("3", LiteralType.Unsigned_Integer)); Expr two = new BinaryOperator(OpType.Plus, left2, right2); assertEquals(one, two); Expr left3 = new BinaryOperator(OpType.Minus, new LiteralValue("1", LiteralType.Unsigned_Integer), new LiteralValue("2", LiteralType.Unsigned_Integer)); Expr wrong1 = new BinaryOperator(OpType.Plus, left3, right1); assertFalse(one.equals(wrong1)); }
@Test public void testEquals() throws Exception { Expr expr = new BinaryOperator(OpType.LessThan, new LiteralValue("1", LiteralType.Unsigned_Integer), new LiteralValue("2", LiteralType.Unsigned_Integer)); Relation relation = new Relation("employee"); Selection selection = new Selection(expr); selection.setChild(relation); Aggregation aggregation = new Aggregation(); aggregation.setTargets(new NamedExpr[]{ new NamedExpr(new ColumnReferenceExpr("col1")) } ); aggregation.setChild(selection); Sort.SortSpec spec = new Sort.SortSpec(new ColumnReferenceExpr("col2")); Sort sort = new Sort(new Sort.SortSpec[]{spec}); sort.setChild(aggregation); assertEquals(sort, sort); Expr different = generateOneExpr(); assertFalse(sort.equals(different)); }