Skip to content

Commit

Permalink
add a test for the name of the test in resources vs the name listed in
Browse files Browse the repository at this point in the history
…@test. This will help isolate future docs updates when tests are reordered or one inserted in the middle.  In future, test resources will probably be loaded using this name rather than the method name in which case ordering will no longer matter.
  • Loading branch information
evanchooly committed Jun 12, 2024
1 parent c9e0572 commit 2c5f0ac
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 43 deletions.
59 changes: 44 additions & 15 deletions core/src/test/java/dev/morphia/test/TemplatedTestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.client.MongoCollection;
import com.mongodb.lang.NonNull;
import com.mongodb.lang.Nullable;

import dev.morphia.aggregation.Aggregation;
import dev.morphia.aggregation.AggregationImpl;
Expand Down Expand Up @@ -133,9 +135,9 @@ protected static String toString(List<Document> actual, String prefix) {

@Deprecated
public <D> void testQuery(MorphiaQuery<D> query, FindOptions options, boolean orderMatters) {
var resourceName = discoverResourceName(new Exception().getStackTrace());
var resourceName = discoverResourceName();

loadData(getDs().getCollection(query.getEntityClass()).getNamespace().getCollectionName());
loadData(resourceName, getDs().getCollection(query.getEntityClass()).getNamespace().getCollectionName());

List<D> actual = runQuery(resourceName, query, options);

Expand All @@ -148,22 +150,26 @@ public <D> void testQuery(MorphiaQuery<D> query, FindOptions options, boolean or
}
}

protected void loadData(String collection) {
protected void loadData(String resourceName, String collection) {
if (!skipDataCheck) {
var resourceName = discoverResourceName(new Exception().getStackTrace());
insert(collection, loadJson(format("%s/%s/data.json", prefix(), resourceName), "data", true));
}
}

protected void loadData(String collection, int index) {
if (!skipDataCheck) {
var resourceName = discoverResourceName(new Exception().getStackTrace());
insert(collection, loadJson(format("%s/%s/data%d.json", prefix(), discoverResourceName(), index), "data", true));
}
}

protected void loadData(String resourceName, String collection, int index) {
if (!skipDataCheck) {
insert(collection, loadJson(format("%s/%s/data%d.json", prefix(), resourceName, index), "data", true));
}
}

protected void loadIndex(String collectionName) {
var resourceName = discoverResourceName(new Exception().getStackTrace());
protected void loadIndex(String resourceName, String collectionName) {
final StackTraceElement[] stackTrace = new Exception().getStackTrace();
MongoCollection<Document> collection = getDatabase().getCollection(collectionName);
List<Document> documents = loadJson("%s/%s/index.json".formatted(prefix(), resourceName), "index", false);
documents.forEach(document -> {
Expand Down Expand Up @@ -266,6 +272,21 @@ protected Document loadQuery(String pipelineName) {
return parseAction(stream).get(0);
}

protected String loadTestName(String resourceName) {
String name = format("%s/%s/name", prefix(), resourceName);

InputStream stream = getClass().getResourceAsStream(name);
if (stream == null) {
fail(format("missing name file: %s", name));
}

try (var reader = new BufferedReader(new InputStreamReader(stream))) {
return reader.readLine();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private List<Document> loadPipeline(String pipelineName) {
InputStream stream = getClass().getResourceAsStream(pipelineName);
if (stream == null) {
Expand Down Expand Up @@ -377,26 +398,34 @@ protected <D> List<D> runQuery(@NonNull String queryTemplate, @NonNull MorphiaQu
}
}

protected String discoverResourceName(StackTraceElement[] stackTrace) {
String methodName = Arrays.stream(stackTrace)
.filter(e -> isTestMethod(e))
.findFirst()
.get().getMethodName();
protected String discoverResourceName() {
var method = findTestMethod();
String methodName = method.getName();

if (methodName.startsWith("test")) {
methodName = methodName.substring(4);
methodName = methodName.substring(0, 1).toLowerCase() + methodName.substring(1);
}
return methodName;
}

private boolean isTestMethod(StackTraceElement element) {
protected Method findTestMethod() {
return stream(new Exception().getStackTrace())
.map(this::isTestMethod)
.filter(Objects::nonNull)
.findFirst()
.get();
}

@Nullable
private Method isTestMethod(StackTraceElement element) {
try {
Class<?> klass = Class.forName(element.getClassName());
Method method = klass.getDeclaredMethod(element.getMethodName());

return method.getAnnotation(Test.class) != null;
return method.getAnnotation(Test.class) != null ? method : null;
} catch (ReflectiveOperationException e) {
return false;
return null;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public void testPipeline(ServerVersion serverVersion,
Function<Aggregation<Document>, Aggregation<Document>> pipeline) {
checkMinServerVersion(serverVersion);
checkMinDriverVersion(minDriver);
var resourceName = discoverResourceName(new Exception().getStackTrace());
loadData(AGG_TEST_COLLECTION);
loadIndex(AGG_TEST_COLLECTION);
var resourceName = discoverResourceName();
loadData(resourceName, AGG_TEST_COLLECTION);
loadIndex(resourceName, AGG_TEST_COLLECTION);

List<Document> actual = runPipeline(resourceName, pipeline.apply(getDs().aggregate(AGG_TEST_COLLECTION)));

Expand Down
27 changes: 22 additions & 5 deletions core/src/test/java/dev/morphia/test/query/filters/FilterTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.morphia.test.query.filters;

import java.lang.reflect.Method;
import java.util.List;
import java.util.function.Function;

Expand All @@ -12,12 +13,17 @@
import dev.morphia.test.util.Comparanator;

import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.Test;

import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static org.testng.Assert.assertEquals;

public class FilterTest extends TemplatedTestBase {
private static final Logger LOG = LoggerFactory.getLogger(FilterTest.class);

public FilterTest() {
super(buildConfig(Martian.class, User.class)
.applyIndexes(true)
Expand All @@ -33,11 +39,13 @@ public void testQuery(ServerVersion serverVersion,
boolean removeIds,
boolean orderMatters,
Function<Query<Document>, Query<Document>> function) {

checkMinServerVersion(serverVersion);
checkMinDriverVersion(minDriver);
var resourceName = discoverResourceName(new Exception().getStackTrace());
loadData(AGG_TEST_COLLECTION);
loadIndex(AGG_TEST_COLLECTION);
var resourceName = discoverResourceName();
validateTestName(resourceName);
loadData(resourceName, AGG_TEST_COLLECTION);
loadIndex(resourceName, AGG_TEST_COLLECTION);

List<Document> actual = runQuery(resourceName, function.apply(getDs().find(AGG_TEST_COLLECTION, Document.class)
.disableValidation()));
Expand All @@ -57,13 +65,22 @@ public void testQuery(ServerVersion serverVersion,
}
}

private void validateTestName(String resourceName) {
Method method = findTestMethod();
Test test = method.getAnnotation(Test.class);
assertEquals(
loadTestName(resourceName), test.testName(),
"%s#%s does not have a name configured on the test.".formatted(method.getDeclaringClass().getName(),
method.getName()));
}

@SuppressWarnings({ "unchecked", "rawtypes" })
protected List<Document> runQuery(String pipelineTemplate, Query<Document> query) {
String pipelineName = format("%s/%s/action.json", prefix(), pipelineTemplate);
String resourceName = format("%s/%s/action.json", prefix(), pipelineTemplate);
Document document = ((MorphiaQuery) query).toDocument();

if (!skipActionCheck) {
Document target = loadQuery(pipelineName);
Document target = loadQuery(resourceName);
assertEquals(toJson(document), toJson(target), "Should generate the same query document");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
import static dev.morphia.query.filters.Filters.gt;

public class TestAll extends FilterTest {
@Test
@Test(testName = "Use ``$all`` to Match Values")
public void testExample1() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(all("tags", List.of("appliance", "school", "book"))));
}

@Test
@Test(testName = "Use ``$all`` with ``$elemMatch``")
public void testExample2() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(all("qty",
List.of(elemMatch(eq("size", "M"), gt("num", 50)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
import static dev.morphia.query.filters.Filters.bitsAllClear;

public class TestBitsAllClear extends FilterTest {
@Test
@Test(testName = "Bit Position Array")
public void testExample1() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAllClear("a", new int[] { 1, 5 })));
}

@Test
@Test(testName = "Integer Bitmask")
public void testExample2() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAllClear("a", 35)));
}

@Test
@Test(testName = "BinData Bitmask")
public void testExample3() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAllClear("a", new byte[] { 32 })));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
import static dev.morphia.query.filters.Filters.bitsAllSet;

public class TestBitsAllSet extends FilterTest {
@Test
@Test(testName = "Bit Position Array")
public void testExample1() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAllSet("a", new int[] { 1, 5 })));
}

@Test
@Test(testName = "Integer Bitmask")
public void testExample2() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAllSet("a", 50)));
}

@Test
@Test(testName = "BinData Bitmask")
public void testExample3() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAllSet("a", new byte[] { 48 })));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
import static dev.morphia.query.filters.Filters.bitsAnyClear;

public class TestBitsAnyClear extends FilterTest {
@Test
@Test(testName = "Bit Position Array")
public void testExample1() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAnyClear("a", new int[] { 1, 5 })));
}

@Test
@Test(testName = "Integer Bitmask")
public void testExample2() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAnyClear("a", 35)));
}

@Test
@Test(testName = "BinData Bitmask")
public void testExample3() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAnyClear("a", new byte[] { 48 })));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
import static dev.morphia.query.filters.Filters.bitsAnySet;

public class TestBitsAnySet extends FilterTest {
@Test
@Test(testName = "Bit Position Array")
public void testExample1() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAnySet("a", new int[] { 1, 5 })));
}

@Test
@Test(testName = "Integer Bitmask")
public void testExample2() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAnySet("a", 35)));
}

@Test
@Test(testName = "BinData Bitmask")
public void testExample3() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
bitsAnySet("a", new byte[] { 48 })));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@
import static dev.morphia.query.filters.Filters.lt;

public class TestElemMatch extends FilterTest {
@Test(description = "Element Match")
@Test(testName = "Element Match")
public void testExample1() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
elemMatch("results", gte(80), lt(85))));
}

@Test
@Test(testName = "Array of Embedded Documents")
public void testExample2() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
elemMatch("results", eq("product", "xyz"), gte("score", 8))));
}

@Test
@Test(testName = "Single Query Condition")
public void testExample3() {
testQuery(ServerVersion.ANY, false, true, (query) -> query.filter(
elemMatch("results", eq("product", "xyz"))));
Expand Down
5 changes: 2 additions & 3 deletions docs/antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
name: "morphia"
title: "Morphia"
version: "3.0"
prerelease: "-SNAPSHOT"
nav:
- "modules/ROOT/nav.adoc"
asciidoc:
attributes:
version: "3.0.0-SNAPSHOT"
srcRef: "https://github.com/MorphiaOrg/morphia/blob/master"
version: "3.0.0"
srcRef: "https://github.com/MorphiaOrg/morphia/tree/3.0.x"

0 comments on commit 2c5f0ac

Please sign in to comment.