Skip to content

Commit

Permalink
add tests for good friends of friends via edge attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
danthe1st committed Jul 29, 2024
1 parent 6b3273e commit 2f5fbfb
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ static IntAttribute attribute(int value) {
static StringAttribute attribute(String value) {
return new StringAttribute(value);
}

static BooleanAttribute attribute(boolean value) {
return new BooleanAttribute(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import io.github.danthe1st.arebac.data.graph_pattern.GPEdge;
import io.github.danthe1st.arebac.data.graph_pattern.GPGraph;
Expand All @@ -21,10 +22,11 @@
import io.github.danthe1st.arebac.gpeval.GPEval;
import org.junit.jupiter.api.Test;

public class FriendOfFriendEvaluateTest {
class FriendOfFriendEvaluateTest {

private static final String FRIEND_EDGE_TYPE = "friend";
private static final String USER_NODE_TYPE = "user";
private static final String GOOD_FRIEND_EDGE_ATTRIBUTE = "goodFriend";

private InMemoryGraphNode outsider = new InMemoryGraphNode("out", USER_NODE_TYPE, Map.of());
private InMemoryGraphNode connector = new InMemoryGraphNode("con", USER_NODE_TYPE, Map.of());
Expand All @@ -44,16 +46,40 @@ public class FriendOfFriendEvaluateTest {
*/
public FriendOfFriendEvaluateTest() {
// outsider and connector are both friends
InMemoryGraphEdge outsiderEdge = new InMemoryGraphEdge(outsider, connector, "out->con", FRIEND_EDGE_TYPE, Map.of());
InMemoryGraphEdge outsiderBackEdge = new InMemoryGraphEdge(connector, outsider, "con->out", FRIEND_EDGE_TYPE, Map.of());
// outsider considers connector to be a good friend but not vice-versa
InMemoryGraphEdge outsiderEdge = new InMemoryGraphEdge(
outsider, connector, "out->con", FRIEND_EDGE_TYPE,
Map.of(GOOD_FRIEND_EDGE_ATTRIBUTE, attribute(true))
);
InMemoryGraphEdge outsiderBackEdge = new InMemoryGraphEdge(
connector, outsider, "con->out", FRIEND_EDGE_TYPE,
Map.of(GOOD_FRIEND_EDGE_ATTRIBUTE, attribute(false))
);

InMemoryGraphEdge connectorFriendEdge = new InMemoryGraphEdge(connector, connectorFriend, "con->conFriend", FRIEND_EDGE_TYPE, Map.of());
InMemoryGraphEdge connectorFriendBackEdge = new InMemoryGraphEdge(connectorFriend, connector, "conFriend->con", FRIEND_EDGE_TYPE, Map.of());
// connector and connectorFriend are (mutually) good friends
InMemoryGraphEdge connectorFriendEdge = new InMemoryGraphEdge(
connector, connectorFriend, "con->conFriend", FRIEND_EDGE_TYPE,
Map.of(GOOD_FRIEND_EDGE_ATTRIBUTE, attribute(true))
);
InMemoryGraphEdge connectorFriendBackEdge = new InMemoryGraphEdge(
connectorFriend, connector, "conFriend->con", FRIEND_EDGE_TYPE,
Map.of(GOOD_FRIEND_EDGE_ATTRIBUTE, attribute(true))
);

InMemoryGraphEdge connectorCompletorEdge = new InMemoryGraphEdge(connector, triangleCompletor, "con->completor", FRIEND_EDGE_TYPE, Map.of());
InMemoryGraphEdge connectorCompletorBackEdge = new InMemoryGraphEdge(triangleCompletor, connector, "completor->con", FRIEND_EDGE_TYPE, Map.of());
// completor considers connector to be good friend but not vice-versa
InMemoryGraphEdge connectorCompletorEdge = new InMemoryGraphEdge(
connector, triangleCompletor, "con->completor", FRIEND_EDGE_TYPE,
Map.of(GOOD_FRIEND_EDGE_ATTRIBUTE, attribute(false))
);
InMemoryGraphEdge connectorCompletorBackEdge = new InMemoryGraphEdge(
triangleCompletor, connector, "completor->con", FRIEND_EDGE_TYPE,
Map.of(GOOD_FRIEND_EDGE_ATTRIBUTE, attribute(true))
);

InMemoryGraphEdge connectorFriendToTriangleEdge = new InMemoryGraphEdge(connectorFriend, triangleCompletor, "con->completor", FRIEND_EDGE_TYPE, Map.of());
InMemoryGraphEdge connectorFriendToTriangleEdge = new InMemoryGraphEdge(
connectorFriend, triangleCompletor, "con->completor", FRIEND_EDGE_TYPE,
Map.of(GOOD_FRIEND_EDGE_ATTRIBUTE, attribute(false))
);
graph = new InMemoryGraph(
List.of(outsider, connector, connectorFriend, triangleCompletor),
List.of(
Expand All @@ -72,19 +98,40 @@ void evaluateOutsider() {
assertEquals(Set.of(List.of(triangleCompletor), List.of(connectorFriend)), result);
}

@Test
void evaluateGoodOutsiderFriends() {
GraphPattern pattern = createGoodFriendOfFriendRequirement(outsider.id());
Set<List<InMemoryGraphNode>> result = GPEval.evaluate(graph, pattern);
assertEquals(Set.of(List.of(connectorFriend)), result);
}

@Test
void evaluateConnector() {
GraphPattern pattern = createFriendOfFriendPattern(connector.id());
Set<List<InMemoryGraphNode>> result = GPEval.evaluate(graph, pattern);
assertEquals(Set.of(List.of(triangleCompletor)), result);
}

@Test
void evaluateGoodConnectorFriends() {
GraphPattern pattern = createGoodFriendOfFriendRequirement(connector.id());
Set<List<InMemoryGraphNode>> result = GPEval.evaluate(graph, pattern);
assertEquals(Set.of(), result);
}

@Test
void evaluateCompletor() {
GraphPattern pattern = createFriendOfFriendPattern(triangleCompletor.id());
Set<List<InMemoryGraphNode>> result = GPEval.evaluate(graph, pattern);
assertEquals(Set.of(List.of(outsider), List.of(connectorFriend)), result);
}

@Test
void evaluateGoodCompletorFriends() {
GraphPattern pattern = createGoodFriendOfFriendRequirement(triangleCompletor.id());
Set<List<InMemoryGraphNode>> result = GPEval.evaluate(graph, pattern);
assertEquals(Set.of(List.of(connectorFriend)), result);
}

// adaptation from example 17 of https://doi.org/10.1145/3401027
private GraphPattern createFriendOfFriendPattern(String requestorId) {
Expand All @@ -107,4 +154,17 @@ private GraphPattern createFriendOfFriendPattern(String requestorId) {
Map.of("requestor", requestor, FRIEND_EDGE_TYPE, friend, "friendOfFriend", friendOfFriend)
);
}

private GraphPattern createGoodFriendOfFriendRequirement(String requestorId) {
GraphPattern friendOfFriendPattern = createFriendOfFriendPattern(requestorId);
Map<GPEdge, List<AttributeRequirement>> newEdgeRequirements =
friendOfFriendPattern
.graph()
.outgoingEdges()
.values()
.stream()
.flatMap(List::stream)
.collect(Collectors.toMap(e -> e, e -> List.of(new AttributeRequirement(GOOD_FRIEND_EDGE_ATTRIBUTE, EQUAL, attribute(true)))));
return new GraphPattern(friendOfFriendPattern.graph(), friendOfFriendPattern.mutualExclusionConstraints(), friendOfFriendPattern.nodeRequirements(), newEdgeRequirements, friendOfFriendPattern.returnedNodes(), friendOfFriendPattern.actorsToNodes());
}
}

0 comments on commit 2f5fbfb

Please sign in to comment.