package org.quaere.objects;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.quaere.Queryable;
import org.quaere.QueryableIterable;
import org.quaere.Variant;
import org.quaere.expressions.*;
import org.quaere.model.Customer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ObjectsQueryEngineTest {
private ObjectQueryEngine queryEngine;
@Before
public void setup() {
queryEngine = new ObjectQueryEngine();
}
@Test
public void canEvaluateConstants() {
Constant constant = new Constant(42f);
queryEngine.visit(constant);
Assert.assertEquals(42f, queryEngine.result);
Assert.assertTrue(queryEngine.result instanceof Float);
}
@Test
public void canRetriveNamedSourceByIdentifier() {
Identifier identifier = new Identifier("id");
final List<Integer> values = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
Queryable<Integer> source = new QueryableIterable<Integer>(
values
);
queryEngine.addSource(identifier, source);
queryEngine.evaluate(new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
}
});
queryEngine.visit(identifier);
Assert.assertEquals(values, queryEngine.result);
}
@Test
public void canGetUnnamedSourceByIdentifier() {
Identifier identifier = new Identifier("id");
final List<Integer> values = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
Queryable<Integer> source = new QueryableIterable<Integer>(
values
);
FromClause fromClause = new FromClause(identifier, new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = values;
}
});
queryEngine.addSource(identifier, source);
queryEngine.visit(fromClause);
queryEngine.currentTuple = new ArrayList<Object>();
queryEngine.currentTuple.add(values);
queryEngine.result = null;
queryEngine.visit(identifier);
Assert.assertEquals(values, queryEngine.result);
}
@Test
public void canGetFieldValueByIdentifier() {
Customer customer = new Customer();
customer.setCity("Gotham");
Identifier city = new Identifier("city");
queryEngine.result = customer;
queryEngine.visit(city);
Assert.assertEquals(customer.getCity(), queryEngine.result);
}
@Test
public void canInvokeOperation() {
MethodCall methodCall = new MethodCall(
new Identifier("getInformation"),
Arrays.<Expression>asList(
new Constant("Customer: "),
new Constant(true),
new Constant(false)
));
Customer customer = new Customer();
customer.setCompanyName("Big Company");
customer.setCity("Gotham");
queryEngine.result = customer;
queryEngine.visit(methodCall);
Assert.assertEquals("Customer: Big Company", queryEngine.result);
}
// TODO: Need test cases for method resolving...
@Test
public void canInvokeCountOperatorWithoutLambdaExpression() {
MethodCall methodCall = new MethodCall(
new Identifier("count"),
Arrays.<Expression>asList(),
null,
null,
null
);
queryEngine.result = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
queryEngine.visit(methodCall);
Assert.assertEquals(10, queryEngine.result);
}
@Test
public void canInvokeCountOperatorWithLamdaExpression() {
final int[] lambdaExpressionInvoked = new int[]{0};
MethodCall methodCall = new MethodCall(
new Identifier("count"),
Arrays.<Expression>asList(),
null,
null,
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
lambdaExpressionInvoked[0]++;
queryEngine.result = true;
}
}
);
queryEngine.result = Arrays.asList(9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
queryEngine.visit(methodCall);
Assert.assertTrue(lambdaExpressionInvoked[0] > 0);
Assert.assertEquals(10, queryEngine.result);
}
@Test
public void canInvokeCountOperatorWithIndexer() {
final Identifier indexedIdentifier = new Identifier("indexer");
final int[] lastIndex = new int[]{0};
MethodCall methodCall = new MethodCall(
new Identifier("count"),
Arrays.<Expression>asList(),
null,
indexedIdentifier,
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = null;
queryEngine.visit(indexedIdentifier);
Assert.assertEquals(lastIndex[0]++, queryEngine.result);
queryEngine.result = true;
}
}
);
queryEngine.result = Arrays.asList(9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
queryEngine.visit(methodCall);
Assert.assertEquals(10, queryEngine.result);
}
@Test
public void canInvokeCountOperatorWithAnonymousIndentifer() {
final Identifier anonIdentifier = new Identifier("anonymous");
final int[] lastIndex = new int[]{0};
final List<Integer> values = Arrays.asList(9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
MethodCall methodCall = new MethodCall(
new Identifier("count"),
Arrays.<Expression>asList(),
anonIdentifier,
null,
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = null;
queryEngine.visit(anonIdentifier);
Assert.assertEquals(values.get(lastIndex[0]++), queryEngine.result);
queryEngine.result = true;
}
}
);
queryEngine.result = values;
queryEngine.visit(methodCall);
Assert.assertEquals(10, queryEngine.result);
}
// TODO: Need unit tests for other extension methods... where, take, skip etc.
@Test
public void canEvaluateStatements() {
final int[] acceptInvocations = new int[]{0};
Expression mockExpression = new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
acceptInvocations[0]++;
}
};
Statement statement = new Statement(
Arrays.<Expression>asList(mockExpression, mockExpression, mockExpression)
);
queryEngine.visit(statement);
Assert.assertEquals(3, acceptInvocations[0]);
}
@Test
public void canCreateVariants() {
NewExpression newExpression = new NewExpression((Class<?>) null, new Property(new Identifier("a"), new Constant("a")));
queryEngine.visit(newExpression);
Assert.assertTrue(queryEngine.result instanceof Variant);
Variant v = (Variant) queryEngine.result;
Assert.assertEquals("a", v.get("a"));
}
@Test
public void canCreateDefinedType() {
NewExpression newExpression = new NewExpression(
Customer.class,
new Property(new Identifier("customerID"), new Constant("ALFKI")),
new Property(new Identifier("companyName"), new Constant("Alfred's Futterkiste"))
);
queryEngine.visit(newExpression);
Assert.assertTrue(queryEngine.result instanceof Customer);
Customer alfki = (Customer) queryEngine.result;
Assert.assertEquals("ALFKI", alfki.getCustomerID());
Assert.assertEquals("Alfred's Futterkiste", alfki.getCompanyName());
}
@Test
public void canApplyIndexerToArray() {
final Integer[] numbers = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
Indexer indexer = new Indexer(
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = numbers;
}
},
new Constant(2)
);
queryEngine.visit(indexer);
Assert.assertEquals(7, queryEngine.result);
}
@Test
public void canApplyIndexerToList() {
final List<Integer> numbers = Arrays.asList(9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
Indexer indexer = new Indexer(
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = numbers;
}
},
new Constant(2)
);
queryEngine.visit(indexer);
Assert.assertEquals(7, queryEngine.result);
}
@Test
public void canApplyCharAtUsingIndexer() {
Indexer indexer = new Indexer(
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = "9876543210";
}
},
new Constant(2)
);
queryEngine.visit(indexer);
Assert.assertEquals('7', queryEngine.result);
}
@Test
public void fromClauseAddsIdentifierToSourceNameRegistry() {
FromClause fromClause = new FromClause(new Identifier("id"),
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = new ArrayList();
}
}
);
queryEngine.visit(fromClause);
Assert.assertTrue(queryEngine.sourceNames.contains("id"));
}
@Test
public void fromClauseEvaluatesInnerExperession() {
final boolean[] innerExpressionEvaluated = new boolean[]{false};
FromClause fromClause = new FromClause(new Identifier("id"),
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
innerExpressionEvaluated[0] = true;
queryEngine.result = new ArrayList();
}
}
);
queryEngine.visit(fromClause);
Assert.assertTrue(innerExpressionEvaluated[0]);
}
@Test
public void fromClauseCreatesSingleTupleForSingleSource() {
FromClause fromClause = new FromClause(new Identifier("id"),
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = Arrays.asList(1, 2, 3, 4);
}
}
);
queryEngine.visit(fromClause);
Assert.assertEquals(4, queryEngine.tuples.size());
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(1)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(2)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(3)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(4)));
}
@Test
public void fromClauseCreatesScalarProductForMultipleSources() {
FromClause fromClause1 = new FromClause(new Identifier("id1"),
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = Arrays.asList(1, 2, 3, 4);
}
}
);
FromClause fromClause2 = new FromClause(new Identifier("id2"),
new Expression() {
public void accept(ExpressionTreeVisitor visitor) {
queryEngine.result = Arrays.asList(5, 6, 7, 8);
}
}
);
queryEngine.visit(fromClause1);
queryEngine.visit(fromClause2);
Assert.assertEquals(16, queryEngine.tuples.size());
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(1, 5)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(2, 5)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(3, 5)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(4, 5)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(1, 6)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(2, 6)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(3, 6)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(4, 6)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(1, 7)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(2, 7)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(3, 7)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(4, 7)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(1, 8)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(2, 8)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(3, 8)));
Assert.assertTrue(queryEngine.tuples.contains(Arrays.<Object>asList(4, 8)));
}
}