package org.quaere.objects;
import junit.framework.Assert;
import org.apache.log4j.BasicConfigurator;
import org.junit.Ignore;
import org.junit.Test;
import static org.quaere.DSL.*;
import org.quaere.Group;
import org.quaere.Variant;
import org.quaere.model.Customer;
import org.quaere.model.Order;
import org.quaere.model.Product;
import java.util.*;
public class GroupingOperatorsScenarioTest {
public GroupingOperatorsScenarioTest() {
BasicConfigurator.configure();
}
@Test
public void canUseGroupByToPartitionAListOfNumbersByTheirRemainderWhenDividedByFive_linq40() {
Integer[] numbers = {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
Iterable<Variant> numberGroups =
from("n").in(numbers).
group("n").by("n % 5").into("g").
select(
create(
property("remainder", "g.getKey()"),
property("numbers", "g.getGroup()")
)
);
HashMap<Integer, List<Integer>> expectedNumberGroups = new HashMap<Integer, List<Integer>>();
expectedNumberGroups.put(0, Arrays.asList(5, 0));
expectedNumberGroups.put(4, Arrays.asList(4, 9));
expectedNumberGroups.put(1, Arrays.asList(1, 6));
expectedNumberGroups.put(3, Arrays.asList(3, 8));
expectedNumberGroups.put(2, Arrays.asList(7, 2));
for (Variant g : numberGroups) {
Assert.assertEquals(expectedNumberGroups.get(g.get("remainder")), g.get("numbers"));
}
}
@Test
@Ignore("There seems to be a problem with array indexing parsing in the ANTLR grammar")
public void canUseGroupByToPartitionAListOfWordsByTheirFirstLetter_linq41() {
String[] words = {"blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese"};
Iterable<Variant> wordGroups =
from("w").in(words).
group("w").by("w[0]").into("g").
select(
create(
property("firstLetter", "g.getKey()"),
property("words", "g.getGroup()")
)
);
HashMap<Character, List<String>> expectedWordGroups = new HashMap<Character, List<String>>();
expectedWordGroups.put('b', Arrays.asList("blueberry", "banana"));
expectedWordGroups.put('c', Arrays.asList("chimpanzee", "cheese"));
expectedWordGroups.put('a', Arrays.asList("abacus", "apple"));
for (Variant g : wordGroups) {
System.out.println(g.get("firstLetter"));
System.out.println(g.get("words"));
}
}
@Test
public void canUseGroupByClauseToPartitionAListOfProductsByCategory_linq42() {
// NOTE: Renamed orderGroups (LINQ) -> productGroups (this)
Product[] products = Product.getAllProducts();
Iterable<Variant> productGroups =
from("p").in(products).
group("p").by("p.getCategory()").into("g").
select(
create(
property("category", "g.getKey()"),
property("products", "g.getGroup()")
)
);
HashMap<String, List<Integer>> expectedProductGroups = new HashMap<String, List<Integer>>();
expectedProductGroups.put("Beverages", Arrays.asList(1, 2, 24, 34, 35, 38, 39, 43, 67, 70, 75, 76));
expectedProductGroups.put("Condiments", Arrays.asList(3, 4, 5, 6, 8, 15, 44, 61, 63, 65, 66, 77));
expectedProductGroups.put("Produce", Arrays.asList(7, 14, 28, 51, 74));
expectedProductGroups.put("Meat/Poultry", Arrays.asList(9, 17, 29, 53, 54, 55));
expectedProductGroups.put("Seafood", Arrays.asList(10, 13, 18, 30, 36, 37, 40, 41, 45, 46, 58, 73));
expectedProductGroups.put("Dairy Products", Arrays.asList(11, 12, 31, 32, 33, 59, 60, 69, 71, 72));
expectedProductGroups.put("Confections", Arrays.asList(16, 19, 20, 21, 25, 26, 27, 47, 48, 49, 50, 62, 68));
expectedProductGroups.put("Grains/Cereals", Arrays.asList(22, 23, 42, 52, 56, 57, 64));
for (Variant g : productGroups) {
System.out.println(g.get("category"));
System.out.println(g.get("products"));
}
}
@SuppressWarnings({"unchecked"})
@Test
public void canUseGroupByClauseToPartitionAListOfEachCustomersOrdersFirstByYearThenByMonth_linq43() {
Customer[] customers = Customer.getAllCustomers();
Iterable<Variant> customerOrderGroups =
from("c").in(customers).
select(
create(
property("c.getCompanyName()"),
property("yearGroups",
from("o1").in("c.getOrders()").
group("o1").by("o1.getOrderDate().getYear()").into("yg").
select(
create(
property("year", "yg.getKey()"),
property("monthGroups",
from("o2").in("yg.getGroup()").
orderBy("o2.getOrderDate().getMonth()").
group("o2").by("o2.getOrderDate().getMonth()").into("mg").
select(
create(
property("monthKey", "mg.getKey()"),
property("orders", "mg.getGroup()")
)
)
)
)
)
)
)
);
for (Variant group : customerOrderGroups) {
System.out.println("Company: " + group.get("companyName"));
for (Variant yearGroup : (List<Variant>) group.get("yearGroups")) {
System.out.println(" Year: " + yearGroup.get("year"));
for (Variant monthGroup : (List<Variant>) yearGroup.get("monthGroups")) {
System.out.println(" Month: " + monthGroup.get("monthKey"));
for (Order order : (List<Order>) monthGroup.get("orders")) {
System.out.printf(" %s\n", order != null ? order.toString() : "null");
}
}
}
}
}
@Test
public void canUseGroupByToPartitionTrimmedElementsOfAnArrayUsingACustomComparatorThatMatchesTheWordsThatAreAnagramsOfEachOther_linq44() {
String[] anagrams = {"from ", " salt", " earn ", " last ", " near ", " form "};
Iterable<Group> orderGroups =
from("a").in(anagrams).
group("a").by("a.trim()", new AnagramEqualityComparator()).into("g").select("g");
HashMap<Object, Iterable> expectedOrderGroups = new HashMap<Object, Iterable>();
expectedOrderGroups.put("from", Arrays.asList("from ", " form "));
expectedOrderGroups.put("salt", Arrays.asList(" salt", " last "));
expectedOrderGroups.put("earn", Arrays.asList(" earn ", " near "));
for (Group g : orderGroups) {
Assert.assertEquals(expectedOrderGroups.get(g.getKey()), g.getGroup());
}
}
private class AnagramEqualityComparator implements Comparator<String> {
public int compare(java.lang.String stringA, java.lang.String stringB) {
return getCanonicalString(stringA).equals(getCanonicalString(stringB)) ? 0 : -1;
}
private String getCanonicalString(java.lang.String word) {
char[] wordChars = word.toCharArray();
Arrays.sort(wordChars);
return new String(wordChars);
}
}
@Test
public void canEndAQueryWithAGroupClause() {
String[] anagrams = {"from ", " salt", " earn ", " last ", " near ", " form "};
Iterable<Group> orderGroups =
(Iterable<Group>) from("a").in(anagrams).
group("a").by("a.trim()", new AnagramEqualityComparator());
HashMap<Object, Iterable> expectedOrderGroups = new HashMap<Object, Iterable>();
expectedOrderGroups.put("from", Arrays.asList("from ", " form "));
expectedOrderGroups.put("salt", Arrays.asList(" salt", " last "));
expectedOrderGroups.put("earn", Arrays.asList(" earn ", " near "));
for (Group g : orderGroups) {
Assert.assertEquals(expectedOrderGroups.get(g.getKey()), g.getGroup());
}
}
}