package org.jabref.model.groups; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; import org.jabref.model.entry.BibEntry; import org.jabref.model.search.matchers.AndMatcher; import org.jabref.model.search.matchers.OrMatcher; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class GroupTreeNodeTest { private final List<BibEntry> entries = new ArrayList<>(); private BibEntry entry; /** * Gets the marked node in the following tree of explicit groups: * Root * A ExplicitA, Including * A ExplicitParent, Independent (= parent) * B ExplicitNode, Refining (<-- this) */ public static GroupTreeNode getNodeInSimpleTree(GroupTreeNode root) { root.addSubgroup(new ExplicitGroup("ExplicitA", GroupHierarchyType.INCLUDING, ',')); GroupTreeNode parent = root .addSubgroup(new ExplicitGroup("ExplicitParent", GroupHierarchyType.INDEPENDENT, ',')); return parent.addSubgroup(new ExplicitGroup("ExplicitNode", GroupHierarchyType.REFINING, ',')); } /** * Gets the marked node in the following tree: * Root * A SearchA * A ExplicitA, Including * A ExplicitGrandParent (= grand parent) * B ExplicitB * B KeywordParent (= parent) * C KeywordNode (<-- this) * D ExplicitChild (= child) * C SearchC * C ExplicitC * C KeywordC * B SearchB * B KeywordB * A KeywordA */ public static GroupTreeNode getNodeInComplexTree(GroupTreeNode root) { root.addSubgroup(getSearchGroup("SearchA")); root.addSubgroup(new ExplicitGroup("ExplicitA", GroupHierarchyType.INCLUDING, ',')); GroupTreeNode grandParent = root .addSubgroup(new ExplicitGroup("ExplicitGrandParent", GroupHierarchyType.INDEPENDENT, ',')); root.addSubgroup(getKeywordGroup("KeywordA")); grandParent.addSubgroup(getExplict("ExplicitB")); GroupTreeNode parent = grandParent.addSubgroup(getKeywordGroup("KeywordParent")); grandParent.addSubgroup(getSearchGroup("SearchB")); grandParent.addSubgroup(getKeywordGroup("KeywordB")); GroupTreeNode node = parent.addSubgroup(getKeywordGroup("KeywordNode")); parent.addSubgroup(getSearchGroup("SearchC")); parent.addSubgroup(getExplict("ExplicitC")); parent.addSubgroup(getKeywordGroup("KeywordC")); node.addSubgroup(getExplict("ExplicitChild")); return node; } private static AbstractGroup getKeywordGroup(String name) { return new WordKeywordGroup(name, GroupHierarchyType.INDEPENDENT, "searchField", "searchExpression", true,',', false); } private static AbstractGroup getSearchGroup(String name) { return new SearchGroup(name, GroupHierarchyType.INCLUDING, "searchExpression", true, false); } private static AbstractGroup getExplict(String name) { return new ExplicitGroup(name, GroupHierarchyType.REFINING, ','); } /** * Gets the marked in the following tree: * Root * A * A * A (<- this) * A */ /* public GroupTreeNode getNodeAsChild(TreeNodeMock root) { root.addChild(new TreeNodeMock()); root.addChild(new TreeNodeMock()); TreeNodeMock node = new TreeNodeMock(); root.addChild(node); root.addChild(new TreeNodeMock()); return node; } */ public static GroupTreeNode getRoot() { return GroupTreeNode.fromGroup(new AllEntriesGroup("All entries")); } @Before public void setUp() throws Exception { entries.clear(); entry = new BibEntry(); entries.add(entry); entries.add(new BibEntry().withField("author", "author1 and author2")); entries.add(new BibEntry().withField("author", "author1")); } /* public GroupTreeNode getNodeInComplexTree() { return getNodeInComplexTree(new TreeNodeMock()); } */ private GroupTreeNode getNodeInSimpleTree() { return getNodeInSimpleTree(getRoot()); } @Test public void getSearchRuleForIndependentGroupReturnsGroupAsMatcher() { GroupTreeNode node = GroupTreeNode .fromGroup(new ExplicitGroup("node", GroupHierarchyType.INDEPENDENT, ',')); assertEquals(node.getGroup(), node.getSearchMatcher()); } @Test public void getSearchRuleForRefiningGroupReturnsParentAndGroupAsMatcher() { GroupTreeNode parent = GroupTreeNode .fromGroup( new ExplicitGroup("parent", GroupHierarchyType.INDEPENDENT, ',')); GroupTreeNode node = parent .addSubgroup(new ExplicitGroup("node", GroupHierarchyType.REFINING, ',')); AndMatcher matcher = new AndMatcher(); matcher.addRule(node.getGroup()); matcher.addRule(parent.getGroup()); assertEquals(matcher, node.getSearchMatcher()); } @Test public void getSearchRuleForIncludingGroupReturnsGroupOrSubgroupAsMatcher() { GroupTreeNode node = GroupTreeNode.fromGroup(new ExplicitGroup("node", GroupHierarchyType.INCLUDING, ',')); GroupTreeNode child = node.addSubgroup(new ExplicitGroup("child", GroupHierarchyType.INDEPENDENT, ',')); OrMatcher matcher = new OrMatcher(); matcher.addRule(node.getGroup()); matcher.addRule(child.getGroup()); assertEquals(matcher, node.getSearchMatcher()); } @Test public void numberOfHitsReturnsZeroForEmptyList() throws Exception { assertEquals(0, getNodeInSimpleTree().calculateNumberOfMatches(Collections.emptyList())); } @Test public void numberOfHitsMatchesOneEntry() throws Exception { GroupTreeNode parent = getNodeInSimpleTree(); GroupTreeNode node = parent.addSubgroup( new WordKeywordGroup("node", GroupHierarchyType.INDEPENDENT, "author", "author2", true, ',', false)); assertEquals(1, node.calculateNumberOfMatches(entries)); } @Test public void numberOfHitsMatchesMultipleEntries() throws Exception { GroupTreeNode parent = getNodeInSimpleTree(); GroupTreeNode node = parent.addSubgroup( new WordKeywordGroup("node", GroupHierarchyType.INDEPENDENT, "author", "author1", true, ',', false)); assertEquals(2, node.calculateNumberOfMatches(entries)); } @Test public void numberOfHitsWorksForRefiningGroups() throws Exception { GroupTreeNode grandParent = getNodeInSimpleTree(); GroupTreeNode parent = grandParent.addSubgroup( new WordKeywordGroup("node", GroupHierarchyType.INDEPENDENT, "author", "author2", true, ',', false)); GroupTreeNode node = parent.addSubgroup( new WordKeywordGroup("node", GroupHierarchyType.REFINING, "author", "author1", true, ',', false)); assertEquals(1, node.calculateNumberOfMatches(entries)); } @Test public void numberOfHitsWorksForHierarchyOfIndependentGroups() throws Exception { GroupTreeNode grandParent = getNodeInSimpleTree(); GroupTreeNode parent = grandParent.addSubgroup( new WordKeywordGroup("node", GroupHierarchyType.INDEPENDENT, "author", "author2", true, ',', false)); GroupTreeNode node = parent.addSubgroup( new WordKeywordGroup("node", GroupHierarchyType.INDEPENDENT, "author", "author1", true, ',', false)); assertEquals(2, node.calculateNumberOfMatches(entries)); } @Test public void setGroupChangesUnderlyingGroup() throws Exception { GroupTreeNode node = getNodeInSimpleTree(); AbstractGroup newGroup = new ExplicitGroup("NewGroup", GroupHierarchyType.INDEPENDENT, ','); node.setGroup(newGroup, true, true, entries); assertEquals(newGroup, node.getGroup()); } @Test public void setGroupAddsPreviousAssignmentsExplicitToExplicit() throws Exception { ExplicitGroup oldGroup = new ExplicitGroup("OldGroup", GroupHierarchyType.INDEPENDENT, ','); oldGroup.add(entry); GroupTreeNode node = GroupTreeNode.fromGroup(oldGroup); AbstractGroup newGroup = new ExplicitGroup("NewGroup", GroupHierarchyType.INDEPENDENT, ','); node.setGroup(newGroup, true, true, entries); assertTrue(newGroup.isMatch(entry)); } @Test public void setGroupWithFalseDoesNotAddsPreviousAssignments() throws Exception { ExplicitGroup oldGroup = new ExplicitGroup("OldGroup", GroupHierarchyType.INDEPENDENT, ','); oldGroup.add(entry); GroupTreeNode node = GroupTreeNode.fromGroup(oldGroup); AbstractGroup newGroup = new ExplicitGroup("NewGroup", GroupHierarchyType.INDEPENDENT, ','); node.setGroup(newGroup, false, false, entries); assertFalse(newGroup.isMatch(entry)); } @Test public void setGroupAddsOnlyPreviousAssignments() throws Exception { ExplicitGroup oldGroup = new ExplicitGroup("OldGroup", GroupHierarchyType.INDEPENDENT, ','); assertFalse(oldGroup.isMatch(entry)); GroupTreeNode node = GroupTreeNode.fromGroup(oldGroup); AbstractGroup newGroup = new ExplicitGroup("NewGroup", GroupHierarchyType.INDEPENDENT, ','); node.setGroup(newGroup, true, true, entries); assertFalse(newGroup.isMatch(entry)); } @Test public void setGroupExplicitToSearchDoesNotKeepPreviousAssignments() throws Exception { ExplicitGroup oldGroup = new ExplicitGroup("OldGroup", GroupHierarchyType.INDEPENDENT, ','); oldGroup.add(entry); GroupTreeNode node = GroupTreeNode.fromGroup(oldGroup); AbstractGroup newGroup = new SearchGroup("NewGroup", GroupHierarchyType.INDEPENDENT, "test", false, false); node.setGroup(newGroup, true, true, entries); assertFalse(newGroup.isMatch(entry)); } @Test public void setGroupExplicitToExplicitIsRenameAndSoRemovesPreviousAssignment() throws Exception { ExplicitGroup oldGroup = new ExplicitGroup("OldGroup", GroupHierarchyType.INDEPENDENT, ','); oldGroup.add(entry); GroupTreeNode node = GroupTreeNode.fromGroup(oldGroup); AbstractGroup newGroup = new ExplicitGroup("NewGroup", GroupHierarchyType.INDEPENDENT, ','); node.setGroup(newGroup, true, true, entries); assertFalse(oldGroup.isMatch(entry)); } @Test public void getChildByPathFindsCorrectChildInSecondLevel() throws Exception { GroupTreeNode root = getRoot(); GroupTreeNode child = getNodeInSimpleTree(root); assertEquals(Optional.of(child), root.getChildByPath("ExplicitParent > ExplicitNode")); } @Test public void getPathSimpleTree() throws Exception { GroupTreeNode node = getNodeInSimpleTree(); assertEquals("ExplicitParent > ExplicitNode", node.getPath()); } }