diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index a687da4bd62..b43a6ea0f8c 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -12,14 +12,6 @@ updates: ignore: - dependency-name: "*" update-types: [ "version-update:semver-major" ] - - package-ecosystem: maven - target-branch: 2.3.x - directory: "/" - schedule: - interval: daily - ignore: - - dependency-name: "*" - update-types: [ "version-update:semver-minor", "version-update:semver-major" ] - package-ecosystem: "github-actions" directory: "/" schedule: @@ -28,9 +20,4 @@ updates: target-branch: 2.4.x directory: "/" schedule: - interval: daily - - package-ecosystem: "github-actions" - target-branch: 2.3.x - directory: "/" - schedule: - interval: daily + interval: daily \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0ccda3104a4..a53b95fae7c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,10 +16,27 @@ jobs: Build: uses: evanchooly/workflows/.github/workflows/build.yml@master + secrets: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} with: java: 17 saveBuild: true + Critter: + uses: evanchooly/workflows/.github/workflows/build.yml@master + needs: + - Build + strategy: + fail-fast: false + matrix: + java: [ 17, 21, 24-ea ] + secrets: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + with: + java: ${{ matrix.java }} + maven-flags: "-Pcritter" + optional: true + Matrix: runs-on: ubuntu-latest steps: @@ -89,6 +106,8 @@ jobs: driver: ${{ fromJson(needs.matrix.outputs.driver_latest) }} java: [ 17 ] uses: evanchooly/workflows/.github/workflows/build.yml@master + secrets: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} with: java: ${{ matrix.java }} reuseBuild: true @@ -111,14 +130,16 @@ jobs: java: 21 mongo: 7 - driver: ${{ fromJson(needs.matrix.outputs.driver_latest)[0] }} - java: 22 + java: 23-ea mongo: 7 - optional: tre + optional: true - driver: ${{ needs.matrix.outputs.driver_snapshot }} java: 17 mongo: 7 optional: true uses: evanchooly/workflows/.github/workflows/build.yml@master + secrets: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} with: java: ${{ matrix.java }} reuseBuild: true @@ -138,11 +159,11 @@ jobs: java: 17 secrets: GH_PUSH_TOKEN : ${{ secrets.GH_PUSH_TOKEN }} - GPG_PASSPHRASE : ${{ secrets.GPG_PASSPHRASE }} + MAVEN_GPG_PASSPHRASE : ${{ secrets.MAVEN_GPG_PASSPHRASE }} GPG_PUBLIC_KEY : ${{ secrets.GPG_PUBLIC_KEY }} GPG_PRIVATE_KEY : ${{ secrets.GPG_PRIVATE_KEY }} SONATYPE_USERNAME : ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD : ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_TOKEN : ${{ secrets.SONATYPE_TOKEN }} Docs: name: Update Documentation diff --git a/.mvn/develocity.xml b/.mvn/develocity.xml new file mode 100644 index 00000000000..3c55385df8d --- /dev/null +++ b/.mvn/develocity.xml @@ -0,0 +1,45 @@ + + + + + + + https://develocity.commonhaus.dev + false + + morphia + + #{isFalse(env['CI'])} + + + + + #{{'0.0.0.0'}} + #{isTrue(env['CI']) ? 'GH actions' : 'Carmen Sandiego'} + + + + + false + + + false + #{isTrue(env['CI'])} + + + diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index ff99d6143d7..657e9ea911f 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -1,4 +1,14 @@ + + com.gradle + develocity-maven-extension + 1.22.2 + + + com.gradle + common-custom-user-data-maven-extension + 2.0.1 + true @@ -62,7 +71,7 @@ org.apache.maven.plugin-tools maven-plugin-annotations - 3.13.1 + 3.15.0 provided @@ -88,8 +97,8 @@ compile - com.github.zafarkhaja - java-semver + org.semver4j + semver4j compile @@ -101,5 +110,36 @@ org.jboss.forge.roaster roaster-jdt + + + org.ow2.asm + asm-tree + + + org.ow2.asm + asm-util + + + com.google.devtools.ksp + symbol-processing-api + + + com.google.devtools.ksp + symbol-processing-common-deps + + + com.google.devtools.ksp + symbol-processing-aa-embeddable + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + com.squareup + kotlinpoet-jvm + 1.18.1 + diff --git a/build-plugins/src/main/java/util/AnnotationBuilders.java b/build-plugins/src/main/java/util/AnnotationBuilders.java index 23473e6e4b8..9be5908dde3 100644 --- a/build-plugins/src/main/java/util/AnnotationBuilders.java +++ b/build-plugins/src/main/java/util/AnnotationBuilders.java @@ -96,7 +96,8 @@ private void emitFactory() throws IOException { var code = builders.entrySet().stream() .map(entry -> { JavaClassSource builder = entry.getValue(); - return "if (kind.equals(%s.class)) return (K)%s.%s().build();".formatted(entry.getKey(), builder.getQualifiedName(), + return "if (kind.equals(%s.class)) return (K)%s.%s().build();".formatted(entry.getKey(), + builder.getQualifiedName(), methodCase(builder.getName())); }) .collect(Collectors.joining("\n")); @@ -184,6 +185,13 @@ private void emitBuilder(File sourceFile) throws IOException { .setReturnType(builder.getName()) .setBody(format("return new %s();", builder.getName())); + builder.addField() + .setName("defaults") + .setStatic(true) + .setPublic() + .setType(source.getName()) + .setLiteralInitializer("%s().build()".formatted(builderMethodName(source.getName()))); + JavaClassSource morphiaAnnotation = annotationType(source, builder); List elements = source.getAnnotationElements(); if (!elements.isEmpty()) { @@ -219,6 +227,18 @@ private void emitBuilder(File sourceFile) throws IOException { format("annotation.%s = %s; return this;", name, name)) .addParameter(parameterType, name).setVarArgs(varargs); + + if (element.getType().isPrimitive()) { + builder.addMethod() + .setPublic() + .setName(name) + .setReturnType(builder.getName()) + .setBody( + format("annotation.%s = %s; return this;", name, + name)) + .addParameter(wrapper(parameterType), name).setVarArgs(varargs); + } + } for (Import anImport : source.getImports()) { @@ -229,6 +249,14 @@ private void emitBuilder(File sourceFile) throws IOException { } } + private String wrapper(String type) { + return switch (type) { + case "int" -> "Integer"; + case "char" -> "Character"; + default -> type.substring(0, 1).toUpperCase(Locale.ROOT) + type.substring(1); + }; + } + private JavaClassSource createClass(String name) { var classBuilder = Roaster.create(JavaClassSource.class) .setName(name) @@ -329,7 +357,7 @@ private void setDefaults(MethodSource constructor, JavaAnnotati } - String methodCase(String name) { + public static String methodCase(String name) { return name.substring(0, 1).toLowerCase() + name.substring(1); } diff --git a/build-plugins/src/main/java/util/AsmBuilders.java b/build-plugins/src/main/java/util/AsmBuilders.java new file mode 100644 index 00000000000..140e64bc1e5 --- /dev/null +++ b/build-plugins/src/main/java/util/AsmBuilders.java @@ -0,0 +1,446 @@ +package util; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileWriter; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; +import java.util.TreeMap; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.jboss.forge.roaster.ParserException; +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster.model.source.AnnotationElementSource; +import org.jboss.forge.roaster.model.source.JavaAnnotationSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.jboss.forge.roaster.model.source.JavaDocSource; +import org.jboss.forge.roaster.model.source.JavaSource; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AnnotationNode; + +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static util.AnnotationBuilders.methodCase; + +@Mojo(name = "morphia-annotations-asm", defaultPhase = LifecyclePhase.GENERATE_SOURCES) +public class AsmBuilders extends AbstractMojo { + + private Map builders = new TreeMap<>(); + + @Parameter(defaultValue = "${project}", required = true, readonly = true) + private MavenProject project; + + private JavaClassSource factory; + + private File generated; + + private final FileFilter filter = pathname -> pathname.getName().endsWith(".java") + && !pathname.getName().endsWith("Handler.java") + && !pathname.getName().endsWith("Helper.java") + && !pathname.getName().equals("package-info.java"); + + @Override + @SuppressWarnings("ConstantConditions") + public void execute() throws MojoExecutionException { + List files = new ArrayList<>(); + generated = new File(project.getBasedir() + "/target/generated-sources/morphia-annotations/"); + + String path = core() + "/src/main/java/dev/morphia/annotations"; + files.addAll(find(path)); + project.addCompileSourceRoot(generated.getAbsolutePath()); + + try { + for (File file : files) { + try { + var source = Roaster.parse(JavaAnnotationSource.class, file); + if (source.isPublic()) { + builders.put(source.getName(), source); + } + } catch (ParserException e) { + throw new MojoExecutionException("Could not parse " + file, e); + } + } + emitFactory(); + } catch (Exception e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + + private File core() { + var dir = project.getBasedir(); + while (!new File(dir, ".git").exists()) { + dir = dir.getParentFile(); + } + return new File(dir, "core"); + } + + private void emitFactory() throws Exception { + if (factory == null) { + factory = createClass(); + factory.addImport(Type.class); + factory.addImport(MethodVisitor.class); + factory.addImport(AnnotationNode.class); + + var ifTree = new StringJoiner(" else "); + builders.values().forEach(builder -> { + String name = methodCase(builder.getName()) + "Type"; + factory.addField() + .setStatic(true) + .setFinal(true) + .setPrivate() + .setName(name) + .setType(String.class) + .setStringInitializer(descriptor(builder.getQualifiedName())); + ifTree.add(MessageFormat.format(""" + if (annotation.desc.equals({0})) '{' + emit{1}(mv, annotation); + '}' + """, name, builder.getName())); + }); + + var factoryMethod = factory.addMethod() + .setPublic() + .setStatic(true); + factoryMethod + .setName("build") + .addParameter(MethodVisitor.class, "mv"); + factoryMethod + .addParameter(AnnotationNode.class, "annotation"); + + var code = ifTree.toString(); + factoryMethod.setBody(code); + + emitBuilderConstruction(factory); + invokeAnnotation(factory); + invokeBoolean(factory); + invokeClass(factory); + invokeEnum(factory); + invokeInt(factory); + invokeLong(factory); + invokeString(factory); + for (JavaAnnotationSource source : builders.values()) { + emitterMethod(factory, source); + } + } + + var outputFile = new File(generated, factory.getQualifiedName().replace('.', '/') + ".java"); + if (!outputFile.getParentFile().mkdirs() && !outputFile.getParentFile().exists()) { + throw new IOException(format("Could not create directory: %s", outputFile.getParentFile())); + } + try (var writer = new FileWriter(outputFile)) { + writer.write(factory.toString()); + } + } + + private void emitBuilderConstruction(JavaClassSource factory) { + var method = factory.addMethod() + .setName("emitBuilderConstruction") + .setStatic(true); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(Type.class, "builder"); + method.addParameter(String.class, "methodName"); + factory.addImport(Opcodes.class); + + var code = """ + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "dev/morphia/annotations/internal/PropertyBuilder", + "propertyBuilder", "()Ldev/morphia/annotations/internal/PropertyBuilder;", false); + """; + method.setBody(code); + } + + private void emitterMethod(JavaClassSource factory, JavaAnnotationSource builder) throws ClassNotFoundException { + var method = factory.addMethod() + .setStatic(true) + .setName("emit" + builder.getName()); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(AnnotationNode.class, "node"); + + var builderName = builderName(builder); + + Type builderType = Type.getType(descriptor(builderName)); + + var code = MessageFormat.format(""" + emitBuilderConstruction(mv, Type.getType("{0}"), "{1}Builder"); + if (node.values != null) '{' + for (int i = 0; i < node.values.size(); i+=2) '{' + var name = (String)node.values.get(i); + var value = node.values.get(i++);""", + builderType.getDescriptor(), methodCase(builder.getName())); + + var first = true; + for (AnnotationElementSource element : builder.getAnnotationElements()) { + if (!first) { + code += " else "; + } + code += "if (name.equals(\"%s\")) {".formatted(element.getName()); + if (element.getType().getName().equals("String")) { + code += "invokeString(mv, \"%s\", \"%s\", name, (String)value);".formatted(builderType.getDescriptor(), + builderType.getInternalName()); + } else if (element.getType().getName().equals("boolean")) { + code += "invokeBoolean(mv, \"%s\", \"%s\", name, Boolean.valueOf((String)value));".formatted(builderType.getDescriptor(), + builderType.getInternalName()); + } else if (element.getType().getName().equals("int")) { + code += "invokeInt(mv, \"%s\", \"%s\", name, (int)value);".formatted(builderType.getDescriptor(), + builderType.getInternalName()); + } else if (element.getType().getName().equals("long")) { + code += "invokeLong(mv, \"%s\", \"%s\", name, (long)value);" + .formatted(builderType.getDescriptor(), builderType.getInternalName()); + } else if (element.getType().getName().equals("Class")) { + code += "invokeClass(mv, \"%s\", \"%s\", name, (String)value);".formatted(builderType.getDescriptor(), + builderType.getInternalName()); + } else if (element.getType().getQualifiedName().startsWith("com.mongodb.client.model.") + || element.getType().getQualifiedName().startsWith("dev.morphia.mapping.")) { + Type type = type(element.getType().getQualifiedName()); + code += "invokeEnum(mv, \"%s\", \"%s\", \"%s\", \"%s\", name, (String)value);" + .formatted(type.getDescriptor(), type.getInternalName(), builderType.getDescriptor(), + builderType.getInternalName()); + } else if (element.getType().isArray()) { + System.out.printf("unknown type: %n\t%s %n\t%s %n\t%s %n", + element.getType().getName(), + element.getType().getQualifiedName(), + element.getType().getOrigin().isEnum()); + } else if (element.getType().getQualifiedName().startsWith("dev.morphia.annotations.")) { + Type type = type(element.getType().getQualifiedName()); + code += "invokeAnnotation(mv, \"%s\", \"%s\", \"%s\", name, (AnnotationNode)value);" + .formatted(type.getDescriptor(), builderType.getDescriptor(), + builderType.getInternalName()); + } else { + System.out.printf("unknown type: %n\t%s %n\t%s %n\t%s %n", + element.getType().getName(), + element.getType().getQualifiedName(), + element.getType().getOrigin().isEnum()); + + } + code += "}"; + first = false; + } + + code += "}"; + code += "}"; + try { + method.setBody(code); + } catch (Exception e) { + System.out.println("***** code = " + code); + System.out.println(e.getMessage()); + System.exit(1); + } + } + + private Type type(String qualifiedName) { + return Type.getType(descriptor(qualifiedName)); + } + + private String descriptor(String qualifiedName) { + return "L%s;".formatted(qualifiedName.replace('.', '/')); + } + + private static String builderName(JavaSource builder) { + var pkg = builder.getPackage() + ".internal."; + var name = builder.getName() + "Builder"; + return pkg + name; + } + + private void invokeString(JavaClassSource factory) { + var method = factory.addMethod() + .setStatic(true) + .setName("invokeString"); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(String.class, "descriptor"); + method.addParameter(String.class, "internalName"); + method.addParameter(String.class, "method"); + method.addParameter(String.class, "value"); + + method.setBody(""" + mv.visitLdcInsn(value); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, internalName, method, + "(Ljava/lang/String;)" + descriptor, false);"""); + } + + private void invokeBoolean(JavaClassSource factory) { + var method = factory.addMethod() + .setStatic(true) + .setName("invokeBoolean"); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(String.class, "descriptor"); + method.addParameter(String.class, "internalName"); + method.addParameter(String.class, "method"); + method.addParameter(boolean.class, "value"); + + method.setBody(""" + mv.visitLdcInsn(value); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, internalName, method, + "(Z)" + descriptor, false);"""); + } + + private void invokeInt(JavaClassSource factory) { + var method = factory.addMethod() + .setStatic(true) + .setName("invokeInt"); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(String.class, "descriptor"); + method.addParameter(String.class, "internalName"); + method.addParameter(String.class, "method"); + method.addParameter(int.class, "value"); + + method.setBody(""" + mv.visitLdcInsn(value); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, internalName, method, + "(I)" + descriptor, false);"""); + } + + private void invokeLong(JavaClassSource factory) { + var method = factory.addMethod() + .setStatic(true) + .setName("invokeLong"); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(String.class, "descriptor"); + method.addParameter(String.class, "internalName"); + method.addParameter(String.class, "method"); + method.addParameter(long.class, "value"); + + method.setBody(""" + mv.visitLdcInsn(value); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, internalName, method, + "(J)" + descriptor, false);"""); + } + + private void invokeClass(JavaClassSource factory) { + var method = factory.addMethod() + .setStatic(true) + .setName("invokeClass"); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(String.class, "descriptor"); + method.addParameter(String.class, "internalName"); + method.addParameter(String.class, "method"); + method.addParameter(String.class, "value"); + + method.setBody(""" + mv.visitLdcInsn(Type.getType(value)); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, internalName, method, + "(Ljava/lang/Class;)" + descriptor, false);"""); + } + + private void invokeEnum(JavaClassSource factory) { + var method = factory.addMethod() + .setStatic(true) + .setName("invokeEnum"); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(String.class, "enumDescriptor"); + method.addParameter(String.class, "enumInternalName"); + method.addParameter(String.class, "descriptor"); + method.addParameter(String.class, "internalName"); + method.addParameter(String.class, "method"); + method.addParameter(String.class, "value"); + + method.setBody(""" + mv.visitFieldInsn(Opcodes.GETSTATIC, enumInternalName, value, enumDescriptor); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, internalName, method, "(" + enumDescriptor + ")" + descriptor, false);"""); + } + + private void invokeAnnotation(JavaClassSource factory) { + var method = factory.addMethod() + .setStatic(true) + .setName("invokeAnnotation"); + method.addParameter(MethodVisitor.class, "mv"); + method.addParameter(String.class, "annotationDescriptor"); + method.addParameter(String.class, "descriptor"); + method.addParameter(String.class, "internalName"); + method.addParameter(String.class, "method"); + method.addParameter(AnnotationNode.class, "value"); + + method.setBody(""" + build(mv, value); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, internalName, method, "(" + annotationDescriptor + ")" + descriptor, false);"""); + } + + /* + * + * private fun AnnotationNode.toBuilder() { + * var label = Label() + * methodVisitor.visitLabel(label) + * methodVisitor.visitLineNumber(24, label) + * methodVisitor.visitVarInsn(ALOAD, 0) + * val builderType = lookupBuilder(this) + * methodVisitor.visitMethodInsn( + * INVOKESTATIC, + * builderType.internalName, + * builderType.className.substringAfterLast(".").identifierCase(), + * "()${builderType.descriptor}", + * false + * ) + * values.windowed(2, 2) { (name, value) -> + * println("**************** name = ${name}") + * println("**************** value = ${value}") + * if (value is List<*>) { + * "DUMMY" + * } else { + * methodVisitor.visitLdcInsn(value) + * } + * val label3 = Label() + * methodVisitor.visitLabel(label3) + * methodVisitor.visitLineNumber(25, label3) + * val paramType = Type.getType(value::class.java) + * methodVisitor.visitMethodInsn( + * INVOKEVIRTUAL, + * builderType.internalName, + * name as String, + * "(${paramType.descriptor})${builderType.descriptor}", + * false + * ) + * } + * label = Label() + * methodVisitor.visitLabel(label) + * methodVisitor.visitLineNumber(26, label) + * methodVisitor.visitMethodInsn( + * INVOKEVIRTUAL, + * builderType.internalName, + * "build", + * "()${this.desc}", + * false + * ) + * label = Label() + * methodVisitor.visitLabel(label) + * methodVisitor.visitLineNumber(24, label) + * methodVisitor.visitMethodInsn( + * INVOKEVIRTUAL, + * generatedType.internalName, + * "annotation", + * "(Ljava/lang/annotation/Annotation;)Ldev/morphia/mapping/codec/pojo/PropertyModel;", + * false + * ) + * methodVisitor.visitInsn(POP) + * } + * + * + */ + private JavaClassSource createClass() { + var classBuilder = Roaster.create(JavaClassSource.class) + .setName("AnnotationAsmFactory") + .setPackage(builders.values().iterator().next().getPackage() + ".internal") + .setFinal(true); + classBuilder.addAnnotation("dev.morphia.annotations.internal.MorphiaInternal"); + JavaDocSource javaDoc = classBuilder.getJavaDoc(); + javaDoc.addTagValue("@since", "2.3"); + javaDoc.addTagValue("@hidden", ""); + javaDoc.addTagValue("@morphia.internal", ""); + + return classBuilder; + } + + private List find(String path) { + File[] files = new File(path).listFiles(filter); + return files != null ? asList(files) : List.of(); + } +} diff --git a/build-plugins/src/main/java/util/DocsConfig.java b/build-plugins/src/main/java/util/DocsConfig.java index 332d9f38d2c..f7f1948ff30 100644 --- a/build-plugins/src/main/java/util/DocsConfig.java +++ b/build-plugins/src/main/java/util/DocsConfig.java @@ -11,11 +11,11 @@ import java.util.Map; import java.util.Properties; import java.util.TreeMap; +import java.util.regex.Pattern; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SequenceWriter; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.github.zafarkhaja.semver.Version; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; @@ -24,6 +24,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.semver4j.Semver; import static java.util.List.of; @@ -52,43 +53,52 @@ public void execute() throws MojoExecutionException { try { antora = antora(); model = pom(); - master = "master".equals(gitProperties().get("git.branch")); - - Version pomVersion = Version.parse(model.getVersion()); - String url = model.getUrl(); - - var updated = new LinkedHashMap(); - copy(updated, antora, "name"); - copy(updated, antora, "title"); - updated.put("version", String.format("%s.%s", pomVersion.majorVersion(), pomVersion.minorVersion())); - if (master) { - updated.put("prerelease", "-SNAPSHOT"); + String branch = gitProperties().get("git.branch").toString(); + + if (validateBranch(branch)) { + master = "master".equals(branch); + var pomVersion = Semver.parse(model.getVersion()); + String url = model.getUrl(); + + var updated = new LinkedHashMap(); + copy(updated, antora, "name"); + copy(updated, antora, "title"); + updated.put("version", String.format("%s.%s", pomVersion.getMajor(), pomVersion.getMinor())); + if (master) { + updated.put("prerelease", "-SNAPSHOT"); + } + copy(updated, antora, "nav"); + copy(updated, antora, "asciidoc"); + Map attributes = walk(antora, of("asciidoc", "attributes")); + attributes.put("version", previous(pomVersion).toString()); + + String path; + if (master) { + path = "/blob/master"; + } else { + path = String.format("/tree/%s.%s.x", pomVersion.getMajor(), pomVersion.getMinor()); + } + attributes.put("srcRef", String.format("%s%s", url, path)); + + SequenceWriter sw = objectMapper.writer().writeValues(new FileWriter(DOCS_ANTORA_YML)); + sw.write(updated); } - copy(updated, antora, "nav"); - copy(updated, antora, "asciidoc"); - Map attributes = walk(antora, of("asciidoc", "attributes")); - attributes.put("version", previous(pomVersion).toString()); - - String path; - if (master) { - path = "/blob/master"; - } else { - path = String.format("/tree/%s.%s.x", pomVersion.majorVersion(), pomVersion.minorVersion()); - } - attributes.put("srcRef", String.format("%s%s", url, path)); - - SequenceWriter sw = objectMapper.writer().writeValues(new FileWriter(DOCS_ANTORA_YML)); - sw.write(updated); } catch (Exception e) { throw new MojoExecutionException(e.getMessage(), e); } } - private Object previous(Version version) { - Version previous = Version.of(version.majorVersion(), version.minorVersion(), - Math.max(version.patchVersion() - 1, 0)); + private boolean validateBranch(String branch) { + Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.x"); + + return "master".equals(branch) || pattern.matcher(branch).matches(); + } + + private Object previous(Semver version) { + var previous = Semver.of(version.getMajor(), version.getMinor(), + Math.max(version.getPatch() - 1, 0)); if (master) { - previous = previous.setPreReleaseVersion("SNAPSHOT"); + previous = previous.withPreRelease("SNAPSHOT"); } return previous; } diff --git a/build-plugins/src/main/java/util/KotlinAnnotationExtensions.java b/build-plugins/src/main/java/util/KotlinAnnotationExtensions.java new file mode 100644 index 00000000000..95d7b8c4b96 --- /dev/null +++ b/build-plugins/src/main/java/util/KotlinAnnotationExtensions.java @@ -0,0 +1,332 @@ +package util; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileWriter; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import com.google.devtools.ksp.symbol.KSAnnotation; +import com.google.devtools.ksp.symbol.KSClassDeclaration; +import com.squareup.kotlinpoet.AnnotationSpec; +import com.squareup.kotlinpoet.AnnotationSpec.UseSiteTarget; +import com.squareup.kotlinpoet.ClassName; +import com.squareup.kotlinpoet.FileSpec; +import com.squareup.kotlinpoet.FunSpec; +import com.squareup.kotlinpoet.TypeSpec; +import com.squareup.kotlinpoet.TypeSpec.Builder; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.jboss.forge.roaster.ParserException; +import org.jboss.forge.roaster.Roaster; +import org.jboss.forge.roaster.model.Type; +import org.jboss.forge.roaster.model.source.AnnotationElementSource; +import org.jboss.forge.roaster.model.source.JavaAnnotationSource; +import org.jboss.forge.roaster.model.source.JavaClassSource; +import org.jboss.forge.roaster.model.source.JavaDocSource; +import org.jboss.forge.roaster.model.source.JavaSource; +import org.jboss.forge.roaster.model.util.Types; +import org.jetbrains.annotations.NotNull; + +import kotlin.Suppress; + +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static util.AnnotationBuilders.methodCase; + +@Mojo(name = "morphia-annotations-kotlin", defaultPhase = LifecyclePhase.GENERATE_SOURCES) +public class KotlinAnnotationExtensions extends AbstractMojo { + + private Map builders = new TreeMap<>(); + + private FileSpec.Builder fileBuilder; + + @Parameter(defaultValue = "${project}", required = true, readonly = true) + private MavenProject project; + + private Builder factory; + + private File generated; + + private final FileFilter filter = pathname -> (pathname.getName().endsWith(".java") || pathname.getName().endsWith(".kt")) + && !pathname.getName().endsWith("Handler.java") + && !pathname.getName().endsWith("Helper.java") + && !pathname.getName().equals("package-info.java"); + + @Override + @SuppressWarnings("ConstantConditions") + public void execute() throws MojoExecutionException { + List files = new ArrayList<>(); + generated = new File(project.getBasedir() + "/target/generated-sources/morphia-annotations/"); + + String path = core() + "/src/main/java/dev/morphia/annotations"; + files.addAll(find(path)); + project.addCompileSourceRoot(generated.getAbsolutePath()); + + try { + for (File file : files) { + try { + var source = Roaster.parse(JavaAnnotationSource.class, file); + if (source.isPublic()) { + builders.put(source.getName(), source); + } + } catch (ParserException e) { + throw new MojoExecutionException("Could not parse " + file, e); + } + } + fileBuilder = FileSpec.builder(builders.values().iterator().next().getPackage() + ".internal", "AnnotationKspFactory"); + fileBuilder.addAnnotation(AnnotationSpec.builder(Suppress.class) + .addMember("%S", "UNCHECKED_CAST") + .useSiteTarget(UseSiteTarget.FILE) + .build()); + + fileBuilder.addImport("dev.morphia.critter.parser.ksp.extensions", + "allAnnotations", "name", "className"); + fileBuilder.addImport("dev.morphia.mapping", "MappingException"); + fileBuilder.addImport("java.util", "Objects"); + emitFactory(); + } catch (Exception e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + + private File core() { + var dir = project.getBasedir(); + while (!new File(dir, ".git").exists()) { + dir = dir.getParentFile(); + } + return new File(dir, "core"); + } + + private void emitFactory() throws Exception { + if (factory == null) { + factory = createFactory(); + for (JavaAnnotationSource source : builders.values()) { + annotationConverters(source); + annotationExtractors(source); + annotationCodeBuilders(source); + } + } + + fileBuilder.addType(factory.build()); + + FileSpec fileSpec = fileBuilder.build(); + var outputFile = new File(generated, fileSpec.getRelativePath()); + if (!outputFile.getParentFile().mkdirs() && !outputFile.getParentFile().exists()) { + throw new IOException(format("Could not create directory: %s", outputFile.getParentFile())); + } + try (var out = new FileWriter(outputFile)) { + fileSpec.writeTo(out); + } + } + + private void annotationExtractors(JavaAnnotationSource source) { + var method = FunSpec.builder("%sAnnotation".formatted(methodCase(source.getName()))) + .receiver(KSClassDeclaration.class) + .returns(ClassName.bestGuess(source.getQualifiedName())); + + method.addCode(""" + return try { + allAnnotations() + .first { it.annotationType.className() == %L::class.java.name } + .to%L() + } catch (e: NoSuchElementException) { + throw MappingException("No Entity annotation found on ${name()}") + } + """, source.getName(), source.getName()); + + factory.addFunction(method.build()); + } + + private void annotationConverters(JavaAnnotationSource source) { + var method = FunSpec.builder("to" + source.getName()) + .receiver(KSAnnotation.class) + .returns(ClassName.bestGuess(source.getQualifiedName())); + + var code = MessageFormat.format(""" + val map = arguments + .map '{' it -> (it.name?.asString() ?: "value") to it.value } + .toMap() + var builder = {0}Builder.{1}Builder().apply '{' + """, + source.getName(), methodCase(source.getName())); + + for (AnnotationElementSource element : source.getAnnotationElements()) { + String name = element.getName(); + String cast = processType(element.getType()); + if (element.getType().isArray()) { + cast = "*(%s)".formatted(cast); + } + code += ("map[\"%s\"]?.let { %s(%s) }\n").formatted(name, name, cast); + } + + code += "}\n return builder.build()"; + method.addCode(code); + + factory.addFunction(method.build()); + } + + private void annotationCodeBuilders(JavaAnnotationSource source) { + var method = FunSpec.builder(methodCase(source.getName()) + "CodeGen") + .receiver(KSAnnotation.class) + .returns(ClassName.bestGuess("kotlin.String")); + + ClassName className = ClassName.bestGuess(builderName(source)); + fileBuilder.addImport(className.getPackageName(), className.getSimpleName()); + method.addCode(MessageFormat.format(""" + val map = arguments + .map '{' it -> (it.name?.asString() ?: "value") to it.value } + .toMap() + var code = "{0}Builder.{1}Builder()" + """, source.getName(), methodCase(source.getName()))); + + for (AnnotationElementSource element : source.getAnnotationElements()) { + String name = element.getName(); + String value; + + method.addCode(""" + map["%s"]?.let { + """.formatted(name)); + + Type type = element.getType(); + if (type.getQualifiedName().startsWith("dev.morphia.annotations.")) { + String typeName = type.getSimpleName(); + method.addCode(""" + if (!Objects.equals(%sBuilder.defaults.%s, (it as KSAnnotation).to%s())) { + """.formatted(source.getName(), name, typeName)); + value = "${it.%sCodeGen()}".formatted(methodCase(typeName)); + } else { + method.addCode(""" + if (!Objects.equals(%sBuilder.defaults.%s, it)) { + """.formatted(source.getName(), name)); + + value = getValue(type); + } + + method.addCode(""" + code += ".%s(%s)" + } + } + """.formatted(name, value)); + } + + method.addCode(""" + code += ".build()" + """); + method.addCode("return code"); + + factory.addFunction(method.build()); + } + + private static String builderName(JavaSource builder) { + var pkg = builder.getPackage() + ".internal."; + var name = builder.getName() + "Builder"; + return pkg + name; + } + + private String getValue(Type type) { + String typeName = type.getName(); + String code = "$it"; + + if (typeName.equals("String")) { + code = "\\\"%s\\\"".formatted(code); + } else if (typeName.equals("Class")) { + code += ".class"; + } + return code; + } + + private String processType(Type type) { + String typeName = type.getName(); + String code = "NOT SET"; + String cast = "it as %s"; + + if (typeName.equals("boolean")) { + code = "Boolean"; + } else if (typeName.equals("String")) { + code = "String"; + } else if (typeName.equals("int")) { + code = "Int"; + } else if (typeName.equals("long")) { + code = "Long"; + cast = "(it as Number).to%s()"; + } else if (typeName.equals("Class")) { + code = "Class<*>"; + } else if (type.isArray()) { + code = processArrayType(type); + } else if (type.getQualifiedName().startsWith("com.mongodb.client.model.") + || type.getQualifiedName().startsWith("dev.morphia.mapping.")) { + code = type.getQualifiedName(); + } else if (type.getQualifiedName().startsWith("dev.morphia.annotations.")) { + cast = "(it as KSAnnotation).to%s()"; + code = type.getSimpleName(); + } else { + System.out.printf("unknown type: %n\t%s %n\t%s %n\t%s %n", + typeName, + type.getQualifiedName(), + type.getOrigin().isEnum()); + code = ""; + } + + return cast.formatted(code); + } + + @NotNull + private static String processArrayType(Type type) { + String code; + code = type.getSimpleName(); + var parameterized = type.isParameterized(); + List> params = parameterized ? type.getTypeArguments() + : emptyList(); + if (!params.isEmpty()) { + Type param = params.get(0); + var parameterName = Types.toSimpleName(param.getQualifiedName()); + if (param.isWildcard()) { + parameterName = parameterName.substring(parameterName.lastIndexOf(' ') + 1); + } + if (!Types.isQualified(parameterName)) { + var target = parameterName; + var imp = type.getOrigin().getImports().stream().filter(i -> i.getSimpleName().equals(target)) + .findFirst().orElseThrow(); + parameterName = imp.getQualifiedName(); + } + if (param.isWildcard()) { + parameterName += "<*>"; + } + + code = "%s<%s>".formatted(type.getSimpleName(), parameterName); + } + code = "Array".formatted(code); + return code; + } + + private Builder createFactory() { + Builder annotationKspFactory = TypeSpec.objectBuilder("AnnotationKspFactory"); + var classBuilder = Roaster.create(JavaClassSource.class) + .setName("AnnotationKspFactory") + .setPackage(builders.values().iterator().next().getPackage() + ".internal") + .setFinal(true); + classBuilder.addAnnotation("dev.morphia.annotations.internal.MorphiaInternal"); + JavaDocSource javaDoc = classBuilder.getJavaDoc(); + javaDoc.addTagValue("@since", "3.0"); + javaDoc.addTagValue("@hidden", ""); + javaDoc.addTagValue("@morphia.internal", ""); + + return annotationKspFactory; + } + + private List find(String path) { + File[] files = new File(path).listFiles(filter); + return files != null ? asList(files) : List.of(); + } +} diff --git a/build-plugins/src/main/kotlin/util/AnnotationNodeExtensions.kt b/build-plugins/src/main/kotlin/util/AnnotationNodeExtensions.kt new file mode 100644 index 00000000000..1d7cd7760de --- /dev/null +++ b/build-plugins/src/main/kotlin/util/AnnotationNodeExtensions.kt @@ -0,0 +1,363 @@ +package util + +import com.squareup.kotlinpoet.AnnotationSpec +import com.squareup.kotlinpoet.AnnotationSpec.UseSiteTarget.FILE +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.ClassName.Companion.bestGuess +import com.squareup.kotlinpoet.DelicateKotlinPoetApi +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.TypeSpec +import com.squareup.kotlinpoet.TypeSpec.Companion.objectBuilder +import com.squareup.kotlinpoet.TypeVariableName +import com.squareup.kotlinpoet.asClassName +import java.io.File +import java.io.FileFilter +import java.io.FileWriter +import java.io.IOException +import java.util.TreeMap +import org.apache.maven.plugin.AbstractMojo +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.plugins.annotations.LifecyclePhase.GENERATE_SOURCES +import org.apache.maven.plugins.annotations.Mojo +import org.apache.maven.plugins.annotations.Parameter +import org.apache.maven.project.MavenProject +import org.jboss.forge.roaster.ParserException +import org.jboss.forge.roaster.Roaster +import org.jboss.forge.roaster.model.Type +import org.jboss.forge.roaster.model.source.Import +import org.jboss.forge.roaster.model.source.JavaAnnotationSource +import org.jboss.forge.roaster.model.source.JavaClassSource +import org.jboss.forge.roaster.model.util.Types +import org.objectweb.asm.Type as AsmType +import org.objectweb.asm.tree.AnnotationNode +import util.AnnotationBuilders.methodCase + +@OptIn(DelicateKotlinPoetApi::class) +@Mojo(name = "morphia-annotation-node", defaultPhase = GENERATE_SOURCES) +class AnnotationNodeExtensions : AbstractMojo() { + companion object { + val RESULT_HANDLE = ClassName("io.quarkus.gizmo", "ResultHandle") + val METHOD_CREATOR = ClassName("io.quarkus.gizmo", "MethodCreator") + val METHOD_DESCRIPTOR = ClassName("io.quarkus.gizmo", "MethodDescriptor") + } + + private val builders: MutableMap = TreeMap() + lateinit var fileBuilder: FileSpec.Builder + + @Parameter(defaultValue = "\${project}", required = true, readonly = true) + private val project: MavenProject? = null + lateinit var factory: TypeSpec.Builder + private var generated: File? = null + private val filter = FileFilter { pathname: File -> + (pathname.name.endsWith(".java") || pathname.name.endsWith(".kt")) && + !pathname.name.endsWith("Handler.java") && + !pathname.name.endsWith("Helper.java") && + pathname.name != "package-info.java" + } + + @Throws(MojoExecutionException::class) + override fun execute() { + val files: MutableList = ArrayList() + generated = + File(project!!.basedir.toString() + "/target/generated-sources/morphia-annotations/") + val path = core().toString() + "/src/main/java/dev/morphia/annotations" + files.addAll(find(path)) + project.addCompileSourceRoot(generated!!.absolutePath) + + try { + for (file in files) { + try { + val source = Roaster.parse(JavaAnnotationSource::class.java, file) + if (source.isPublic) { + builders[source.name] = source + } + } catch (e: ParserException) { + throw MojoExecutionException("Could not parse $file", e) + } + } + fileBuilder = + FileSpec.builder( + builders.values.iterator().next().getPackage() + ".internal", + "AnnotationNodeExtensions" + ) + fileBuilder.addAnnotation( + AnnotationSpec.builder(Suppress::class.java) + .addMember("%S", "UNCHECKED_CAST") + .useSiteTarget(FILE) + .build() + ) + + fileBuilder.addImport("kotlin.reflect.full", "declaredMemberProperties") + fileBuilder.addImport("kotlin.reflect.jvm", "javaType") + fileBuilder.addImport("dev.morphia.mapping", "MappingException") + fileBuilder.addImport("java.util", "Objects") + fileBuilder.addImport("dev.morphia.critter.parser", "methodCase") + fileBuilder.addImport( + "dev.morphia.critter.parser.gizmo", + "load", + "attributeType", + "rawType" + ) + emitFactory() + } catch (e: Exception) { + throw MojoExecutionException(e.message, e) + } + } + + private fun core(): File { + var dir = project!!.basedir + while (!File(dir, ".git").exists()) { + dir = dir.parentFile + } + return File(dir, "core") + } + + @Throws(Exception::class) + private fun emitFactory() { + factory = createFactory() + genericSetters() + genericConverter() + for (source in builders.values) { + annotationConverters(source) + annotationValueSetters(source) + } + + fileBuilder.addType(factory.build()) + val fileSpec: FileSpec = fileBuilder.build() + val outputFile = File(generated, fileSpec.relativePath) + if (!outputFile.parentFile.mkdirs() && !outputFile.parentFile.exists()) { + throw IOException( + String.format("Could not create directory: %s", outputFile.parentFile) + ) + } + FileWriter(outputFile).use { out -> fileSpec.writeTo(out) } + } + + private fun genericConverter() { + val typeVariable = TypeVariableName("T", Annotation::class.asClassName()) + val method = + FunSpec.builder("toMorphiaAnnotation") + .addTypeVariable(typeVariable) + .receiver(AnnotationNode::class.asClassName()) + .returns(typeVariable) + + method.beginControlFlow("return when (desc)") + for (source in builders.values) { + val type = bestGuess(source.qualifiedName).toType() + method.addStatement(""""${type.descriptor}" -> to${source.name}()""") + } + method.addStatement( + """else -> throw %T("Unknown annotation type: ${"$"}{desc}")""", + IllegalArgumentException::class + ) + + method.endControlFlow() + method.addStatement("as T") + + factory.addFunction(method.build()) + } + + private fun genericSetters() { + val method = + FunSpec.builder("setBuilderValues") + .receiver(AnnotationNode::class.asClassName()) + .addParameter("creator", METHOD_CREATOR) + .addParameter("local", RESULT_HANDLE) + // .returns(RESULT_HANDLE) + + method.beginControlFlow("return when (desc)") + builders.values.forEach() { source -> + val type = bestGuess(source.qualifiedName).toType() + method.addStatement( + """"${type.descriptor}" -> set${source.name}Values(creator, local)""" + ) + } + method.addStatement( + """else -> throw IllegalArgumentException("Unknown annotation type: ${"$"}{desc}")""" + ) + + method.endControlFlow() + + factory.addFunction(method.build()) + } + + private fun annotationValueSetters(source: JavaAnnotationSource) { + val builderName = "${source.name}Builder" + fileBuilder.addImport(fileBuilder.packageName, "$builderName.${methodCase(builderName)}") + val method = + FunSpec.builder("set${source.name}Values") + .addModifiers(KModifier.PRIVATE) + .receiver(AnnotationNode::class.java) + .addParameter("creator", METHOD_CREATOR) + .addParameter("local", RESULT_HANDLE) + + if (source.annotationElements.isNotEmpty()) { + method.addCode( + """ + val map = (values?.windowed(2, 2) ?: emptyList()) + .map { it -> (it[0] ?: "value") to it[1] } + .toMap() + + """ + .trimIndent() + ) + } + + for (element in source.annotationElements) { + val builderName = + ClassName(fileBuilder.packageName, "${source.name}Builder") /*.reflectionName()*/ + val name = element.name + method.addCode( + """ + + map["${name}"]?.let { + val type = attributeType(${source.name}::class, "$name") + val method = %T.ofMethod( %T::class.java, "${name}", %T::class.java, rawType(type) ) + creator.invokeVirtualMethod(method, local, load(creator, type, it)) + } + + """ + .trimIndent(), + METHOD_DESCRIPTOR, + builderName, + builderName + ) + } + + factory.addFunction(method.build()) + } + + private fun annotationConverters(source: JavaAnnotationSource) { + val builderName = "${source.name}Builder" + fileBuilder.addImport(fileBuilder.packageName, "$builderName.${methodCase(builderName)}") + val method = + FunSpec.builder("to" + source.name) + .receiver(AnnotationNode::class.asClassName()) + .addModifiers(KModifier.PRIVATE) + .returns(bestGuess(source.qualifiedName)) + var code = "" + if (source.annotationElements.isNotEmpty()) { + code += + """ + val map = (values?.windowed(2, 2) ?: emptyList()) + .map { it -> (it[0] ?: "value") to it[1] } + .toMap() + + """ + .trimIndent() + } + code += + """ + return ${methodCase(source.name)}Builder().apply { + + """ + .trimIndent() + + for (element in source.annotationElements) { + val name = element.name + code += ("map[\"${name}\"]?.let { ${name}(${processType(element.type)}) }\n") + } + + code += "}\n.build()" + method.addCode(code) + + factory.addFunction(method.build()) + } + + private fun processType(type: Type): String { + val typeName = type.name + var code: String? = "NOT SET" + + if (typeName == "boolean") { + code = "it as Boolean" + } else if (typeName == "String") { + code = "it as String" + } else if (typeName == "int") { + code = "it as Int" + } else if (typeName == "long") { + code = "(it as Number).toLong()" + } else if (typeName == "Class") { + code = "it as Class<*>" + } else if (type.isArray) { + code = processArrayType(type) + } else if (type.qualifiedName.startsWith("com.mongodb.client.model.")) { + addImport(type.qualifiedName) + code = "${type.simpleName}.valueOf((it as Array)[1])" + } else if (type.qualifiedName.startsWith("dev.morphia.mapping.")) { + code = "${type.qualifiedName}.valueOf(it as String)" + } else if (type.qualifiedName.startsWith("dev.morphia.annotations.")) { + code = "(it as AnnotationNode).to${type.simpleName}()" + } else { + System.out.printf( + "unknown type: %n\t%s %n\t%s %n\t%s %n", + typeName, + type.qualifiedName, + type.origin.isEnum + ) + code = "" + } + + return code + } + + private fun addImport(typeName: String) { + val className = bestGuess(typeName) + fileBuilder.addImport(className.packageName, className.simpleName) + } + + private fun createFactory(): TypeSpec.Builder { + val extensionsFactory = objectBuilder("AnnotationNodeExtensions") + val classBuilder = + Roaster.create(JavaClassSource::class.java) + .setName("AnnotationNodeExtensions") + .setPackage(builders.values.iterator().next().getPackage() + ".internal") + .setFinal(true) + classBuilder.addAnnotation("dev.morphia.annotations.internal.MorphiaInternal") + + return extensionsFactory + } + + private fun find(path: String): List { + val files = File(path).listFiles(filter) + return if (files != null) listOf(*files) else listOf() + } + + private fun processArrayType(type: Type): String { + var code: String = type.simpleName + val parameterized = type.isParameterized + val params = if (parameterized) type.typeArguments else emptyList() + when { + type.qualifiedName == "java.lang.Class" -> { + val param = params[0] + var parameterName = Types.toSimpleName(param.qualifiedName) + if (param.isWildcard) { + parameterName = parameterName.substringAfterLast(' ') + } + if (!Types.isQualified(parameterName)) { + parameterName = + type.origin.imports + .filter { i: Import -> i.simpleName == parameterName } + .map { i -> i.qualifiedName } + .first() + } + if (param.isWildcard) { + parameterName += "<*>" + } + + code = "${type.simpleName}<${parameterName}>" + return """*(it as List) + .map { Class.forName(it.className) } + .toTypedArray() as Array<$code>""" + .trimMargin() + } + type.qualifiedName.startsWith("dev.morphia.annotations.") -> + return "*(it as List).map { it.to$code() } .toTypedArray()" + type.qualifiedName == "java.lang.String" -> return "*(it as List<$code>).toTypedArray()" + else -> TODO("unknown type: $type") + } + } +} + +private fun ClassName.toType() = AsmType.getType("L${canonicalName};".replace('.', '/')) diff --git a/core/pom.xml b/core/pom.xml index a6f7754f287..e23bb837098 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -17,7 +17,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.4.1 + 3.4.2 test-jar @@ -57,7 +57,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.7.0 + 3.10.1 true false @@ -91,10 +91,22 @@ + + maven-surefire-plugin + + + + true + 4 + 0 + + + + io.github.git-commit-id git-commit-id-maven-plugin - 8.0.2 + 9.0.1 git info @@ -184,13 +196,17 @@ org.testng testng + + org.junit.support + testng-engine + org.skyscreamer jsonassert - com.github.zafarkhaja - java-semver + org.semver4j + semver4j org.awaitility diff --git a/core/src/main/java/dev/morphia/MorphiaDatastore.java b/core/src/main/java/dev/morphia/MorphiaDatastore.java index 8fc3339d97e..9f2f75c5a89 100644 --- a/core/src/main/java/dev/morphia/MorphiaDatastore.java +++ b/core/src/main/java/dev/morphia/MorphiaDatastore.java @@ -21,6 +21,7 @@ import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.CreateCollectionOptions; import com.mongodb.client.model.ValidationOptions; +import com.mongodb.client.model.geojson.codecs.GeoJsonCodecProvider; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.InsertManyResult; import com.mongodb.client.result.InsertOneResult; @@ -52,6 +53,7 @@ import dev.morphia.mapping.codec.MorphiaExpressionCodecProvider; import dev.morphia.mapping.codec.MorphiaFilterCodecProvider; import dev.morphia.mapping.codec.MorphiaTypesCodecProvider; +import dev.morphia.mapping.codec.MorphiaUpdateOperatorCodecProvider; import dev.morphia.mapping.codec.PrimitiveCodecRegistry; import dev.morphia.mapping.codec.pojo.EntityModel; import dev.morphia.mapping.codec.pojo.MergingEncoder; @@ -168,10 +170,12 @@ private CodecRegistry buildRegistry(CodecRegistry codecRegistry) { new EnumCodecProvider(), new MorphiaExpressionCodecProvider(this), new MorphiaFilterCodecProvider(this), + new MorphiaUpdateOperatorCodecProvider(this), new AggregationCodecProvider(this))); providers.addAll(morphiaCodecProviders); providers.add(codecRegistry); + providers.add(new GeoJsonCodecProvider()); codecRegistry = fromProviders(providers); return codecRegistry; } @@ -1085,7 +1089,11 @@ public UpdateResult updateMany(MongoCollection collection, Document query @Override public UpdateResult updateOne(MongoCollection collection, Document query, Document updates, UpdateOptions options) { - return collection.updateOne(query, updates, options); + try { + return collection.updateOne(query, updates, options); + } catch (MongoWriteException e) { + throw e; + } } @Override diff --git a/core/src/main/java/dev/morphia/aggregation/AggregationOptions.java b/core/src/main/java/dev/morphia/aggregation/AggregationOptions.java index 43b52577953..93eb1374e6c 100644 --- a/core/src/main/java/dev/morphia/aggregation/AggregationOptions.java +++ b/core/src/main/java/dev/morphia/aggregation/AggregationOptions.java @@ -9,6 +9,7 @@ import com.mongodb.client.AggregateIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; +import com.mongodb.client.cursor.TimeoutMode; import com.mongodb.client.model.Collation; import com.mongodb.lang.Nullable; @@ -25,16 +26,20 @@ @SuppressWarnings("unused") public class AggregationOptions implements ReadConfigurable, WriteConfigurable, CollectionConfigurable { - private String collection; private boolean allowDiskUse; private Integer batchSize; private boolean bypassDocumentValidation; private Collation collation; + private String collection; + private String comment; + private Document hint; + private Document let; + private Long maxAwaitTime; private Long maxTimeMS; - private ReadPreference readPreference; private ReadConcern readConcern; + private ReadPreference readPreference; + private TimeoutMode timeoutMode; private WriteConcern writeConcern; - private Document hint; /** * Enables writing to temporary files. @@ -47,59 +52,6 @@ public AggregationOptions allowDiskUse(boolean allowDiskUse) { return this; } - /** - * Applies the configured options to the collection. - * - * @param the collection type - * @param the result type - * @param documents the stage documents - * @param database - * @param collection the collection to configure - * @param resultType the result type - * @return the updated collection - * @hidden - * @morphia.internal - */ - @MorphiaInternal - AggregateIterable apply(List documents, - MongoDatabase database, MongoCollection collection, Class resultType) { - MongoCollection bound = prepare(collection, database); - if (readConcern != null) { - bound = bound.withReadConcern(readConcern); - } - if (readPreference != null) { - bound = bound.withReadPreference(readPreference); - } - AggregateIterable aggregate = bound.aggregate(documents, resultType) - .allowDiskUse(allowDiskUse) - .bypassDocumentValidation(bypassDocumentValidation); - if (batchSize != null) { - aggregate.batchSize(batchSize); - } - if (collation != null) { - aggregate.collation(collation); - } - if (maxTimeMS != null) { - aggregate.maxTime(maxTime(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS); - } - if (hint != null) { - aggregate.hint(hint); - } - - return aggregate; - } - - /** - * @param unit the target unit type - * @return the configuration value - * @hidden - * @morphia.internal - */ - @MorphiaInternal - public long maxTime(TimeUnit unit) { - return unit.convert(maxTimeMS, TimeUnit.MILLISECONDS); - } - /** * Sets the batch size for fetching results. * @@ -162,16 +114,52 @@ public String collection() { return collection; } + /** + * Sets the comment for this operation. A null value means no comment is set. + * + * @param comment the comment + * @return this + * @since 3.0 + * @mongodb.server.release 3.6 + */ + public AggregationOptions comment(String comment) { + this.comment = comment; + return this; + } + /** * Sets the hint for which index to use. A null value means no hint is set. * * @param hint the hint * @return this * @mongodb.server.release 3.6 - * @since 3.6 */ public AggregationOptions hint(String hint) { - this.hint = new Document("hint", hint); + return hint(new Document("hint", hint)); + } + + /** + * Sets the hint for which index to use. A null value means no hint is set. + * + * @param hint the hint + * @return this + * @mongodb.server.release 3.6 + * @since 3.0 + */ + public AggregationOptions hint(Document hint) { + this.hint = hint; + return this; + } + + /** + * Defines any variables to use when evaluating the pipeline + * + * @param let the variable definitions + * @return this + * @since 3.0 + */ + public AggregationOptions let(Document let) { + this.let = let; return this; } @@ -187,6 +175,34 @@ public AggregationOptions maxTimeMS(long maxTimeMS) { return this; } + /** + * Specifies a time limit for processing operations on a cursor. If you do not specify a value for maxTime, + * operations will not time out. A value of 0 explicitly specifies the default unbounded behavior. + * + * @param maxTime the max time + * @param timeUnit the time unit + * @return this + * @since 3.0 + */ + public AggregationOptions maxTime(long maxTime, TimeUnit timeUnit) { + this.maxTimeMS = timeUnit.toMillis(maxTime); + return this; + } + + /** + * Specifies a time limit for processing operations on a cursor. If you do not specify a value for maxTime, + * operations will not time out. A value of 0 explicitly specifies the default unbounded behavior. + * + * @param maxTime the max time + * @param timeUnit the time unit + * @return this + * @since 3.0 + */ + public AggregationOptions maxAwaitTime(long maxTime, TimeUnit timeUnit) { + this.maxAwaitTime = timeUnit.toMillis(maxTime); + return this; + } + /** * @return the configuration value * @hidden @@ -230,11 +246,34 @@ public AggregationOptions readPreference(ReadPreference readPreference) { } /** + * Sets the timeout mode + * + * @param timeoutMode the timeout mode + * @return this + * @since 3.0 + */ + public AggregationOptions timeoutMode(TimeoutMode timeoutMode) { + this.timeoutMode = timeoutMode; + return this; + } + + /** + * @return the timeout mode * @hidden * @morphia.internal + * @since 3.0 */ @MorphiaInternal + public TimeoutMode timeoutMode() { + return timeoutMode; + } + + /** + * @hidden + * @morphia.internal + */ @Override + @MorphiaInternal public String toString() { return ("AggregationOptions{allowDiskUse=%s, batchSize=%d, bypassDocumentValidation=%s, collation=%s, maxTimeMS=%d, " + "readPreference=%s, readConcern=%s, writeConcern=%s, hint=%s}").formatted(allowDiskUse, batchSize, @@ -262,4 +301,77 @@ public AggregationOptions writeConcern(@Nullable WriteConcern writeConcern) { public WriteConcern writeConcern() { return writeConcern; } + + /** + * Applies the configured options to the collection. + * + * @param the collection type + * @param the result type + * @param documents the stage documents + * @param database + * @param collection the collection to configure + * @param resultType the result type + * @return the updated collection + * @hidden + * @morphia.internal + */ + @MorphiaInternal + AggregateIterable apply(List documents, + MongoDatabase database, MongoCollection collection, Class resultType) { + MongoCollection bound = prepare(collection, database); + if (readConcern != null) { + bound = bound.withReadConcern(readConcern); + } + if (readPreference != null) { + bound = bound.withReadPreference(readPreference); + } + AggregateIterable aggregate = bound.aggregate(documents, resultType) + .allowDiskUse(allowDiskUse) + .bypassDocumentValidation(bypassDocumentValidation); + if (batchSize != null) { + aggregate.batchSize(batchSize); + } + if (collation != null) { + aggregate.collation(collation); + } + if (maxTimeMS != null) { + aggregate.maxTime(maxTime(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS); + } + if (maxAwaitTime != null) { + aggregate.maxAwaitTime(maxAwaitTime(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS); + } + if (hint != null) { + aggregate.hint(hint); + } + if (let != null) { + aggregate.let(let); + } + if (comment != null) { + aggregate.comment(comment); + } + + return aggregate; + } + + /** + * @param unit the target unit type + * @return the configuration value + * @hidden + * @morphia.internal + */ + @MorphiaInternal + public long maxTime(TimeUnit unit) { + return unit.convert(maxTimeMS, TimeUnit.MILLISECONDS); + } + + /** + * @param unit the target unit type + * @return the configuration value + * @hidden + * @morphia.internal + */ + @MorphiaInternal + public long maxAwaitTime(TimeUnit unit) { + return unit.convert(maxAwaitTime, TimeUnit.MILLISECONDS); + } } diff --git a/core/src/main/java/dev/morphia/aggregation/expressions/TypeExpressions.java b/core/src/main/java/dev/morphia/aggregation/expressions/TypeExpressions.java index 5089c7d92d1..ea3022892a0 100644 --- a/core/src/main/java/dev/morphia/aggregation/expressions/TypeExpressions.java +++ b/core/src/main/java/dev/morphia/aggregation/expressions/TypeExpressions.java @@ -119,6 +119,10 @@ public static Expression toString(Object input) { return StringExpressions.toString(input); } + public static Expression toUuid(Object input) { + return new Expression("$toUUID", wrap(input)); + } + /** * Return the BSON data type of the field. * diff --git a/core/src/main/java/dev/morphia/aggregation/stages/ChangeStream.java b/core/src/main/java/dev/morphia/aggregation/stages/ChangeStream.java index fc4fc793584..d77674938d7 100644 --- a/core/src/main/java/dev/morphia/aggregation/stages/ChangeStream.java +++ b/core/src/main/java/dev/morphia/aggregation/stages/ChangeStream.java @@ -45,6 +45,7 @@ protected ChangeStream() { * * @return the new ChangeStream stage * @aggregation.stage $changeStream + * @mongodb.server.release 5.0 * @since 2.3 */ public static ChangeStream changeStream() { diff --git a/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java b/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java index e980f76c28e..38ef4cb3aa5 100644 --- a/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java +++ b/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java @@ -31,9 +31,13 @@ public class ManualMorphiaConfig implements MorphiaConfig { Boolean applyCaps; Boolean applyDocumentValidations; Boolean applyIndexes; - String database; + Optional codecProvider; + NamingStrategy collectionNaming; + + String database; + DateStorage dateStorage; DiscriminatorFunction discriminator; String discriminatorKey; @@ -41,6 +45,7 @@ public class ManualMorphiaConfig implements MorphiaConfig { Boolean ignoreFinals; List packages; PropertyDiscovery propertyDiscovery; + List> propertyAnnotationProviders; NamingStrategy propertyNaming; QueryFactory queryFactory; Boolean storeEmpties; @@ -90,6 +95,22 @@ public static ManualMorphiaConfig configure(MorphiaConfig base) { return new ManualMorphiaConfig(base); } + @Override + public String toString() { + return ("MorphiaConfig{applyCaps=%s, applyDocumentValidations=%s, applyIndexes=%s, database='%s', codecProvider=%s, " + + "collectionNaming=%s, dateStorage=%s, discriminator=%s, discriminatorKey='%s', enablePolymorphicQueries=%s, " + + "ignoreFinals=%s, packages=%s, propertyDiscovery=%s, propertyNaming=%s, queryFactory=%s, " + + "storeEmpties=%s, storeNulls=%s}").formatted( + applyCaps(), applyDocumentValidations(), applyIndexes(), database(), codecProvider(), collectionNaming(), + dateStorage(), discriminator(), discriminatorKey(), enablePolymorphicQueries(), ignoreFinals(), packages(), + propertyDiscovery(), propertyNaming(), queryFactory(), storeEmpties(), storeNulls()); + } + + @Override + public String database() { + return orDefault(database, "morphia"); + } + @Override public Boolean applyCaps() { return orDefault(applyCaps, FALSE); @@ -114,11 +135,6 @@ public NamingStrategy collectionNaming() { return orDefault(collectionNaming, camelCase()); } - @Override - public String database() { - return orDefault(database, "morphia"); - } - @Override public DateStorage dateStorage() { return orDefault(dateStorage, UTC); @@ -149,6 +165,11 @@ public List packages() { return orDefault(packages, List.of()); } + @Override + public List> propertyAnnotationProviders() { + return orDefault(propertyAnnotationProviders, List.of(new MorphiaPropertyAnnotationProvider())); + } + @Override public PropertyDiscovery propertyDiscovery() { return orDefault(propertyDiscovery, FIELDS); @@ -174,17 +195,6 @@ public Boolean storeNulls() { return orDefault(storeNulls, FALSE); } - @Override - public String toString() { - return ("MorphiaConfig{applyCaps=%s, applyDocumentValidations=%s, applyIndexes=%s, database='%s', codecProvider=%s, " + - "collectionNaming=%s, dateStorage=%s, discriminator=%s, discriminatorKey='%s', enablePolymorphicQueries=%s, " + - "ignoreFinals=%s, packages=%s, propertyDiscovery=%s, propertyNaming=%s, queryFactory=%s, " + - "storeEmpties=%s, storeNulls=%s}").formatted( - applyCaps(), applyDocumentValidations(), applyIndexes(), database(), codecProvider(), collectionNaming(), - dateStorage(), discriminator(), discriminatorKey(), enablePolymorphicQueries(), ignoreFinals(), packages(), - propertyDiscovery(), propertyNaming(), queryFactory(), storeEmpties(), storeNulls()); - } - protected T orDefault(@Nullable T localValue, T defaultValue) { return localValue != null ? localValue : defaultValue; } diff --git a/core/src/main/java/dev/morphia/config/MorphiaConfig.java b/core/src/main/java/dev/morphia/config/MorphiaConfig.java index 0d4c9e581e3..1cc9931a64b 100644 --- a/core/src/main/java/dev/morphia/config/MorphiaConfig.java +++ b/core/src/main/java/dev/morphia/config/MorphiaConfig.java @@ -8,6 +8,12 @@ import dev.morphia.annotations.Property; import dev.morphia.annotations.Validation; import dev.morphia.annotations.internal.MorphiaExperimental; +import dev.morphia.annotations.internal.MorphiaInternal; +import dev.morphia.config.converters.CodecProviderConverter; +import dev.morphia.config.converters.DiscriminatorFunctionConverter; +import dev.morphia.config.converters.NamingStrategyConverter; +import dev.morphia.config.converters.PropertyAnnotationProviderConverter; +import dev.morphia.config.converters.QueryFactoryConverter; import dev.morphia.mapping.DateStorage; import dev.morphia.mapping.DiscriminatorFunction; import dev.morphia.mapping.NamingStrategy; @@ -374,6 +380,50 @@ default MorphiaConfig packages(List value) { return newConfig; } + /** + * Specifies the providers of any external annotations to use as markers for properties for Morphia to consider while mapping. This + * method is marked as internal only to note that, as a relatively lower level hook in to Morphia functionality, the regular + * guarantees about stability do not apply. This property and its underlying types and behaviors are subject to potential change + * based on the evolving needs of Morphia internals. Users who need it are encouraged to use it with that caveat in mind. + * + * Morphia annotations will, of course, always be used regardless of any additional types specified. + * + * @return the list of providers + * @since 3.0 + * @morphia.experimental + * @morphia.internal + * + * @see PropertyAnnotationProvider + */ + @MorphiaInternal + @MorphiaExperimental + @WithConverter(PropertyAnnotationProviderConverter.class) + @WithDefault("dev.morphia.config.MorphiaPropertyAnnotationProvider") + List> propertyAnnotationProviders(); + + /** + * Updates this configuration to include the new annotation providers for property discovery. If the default morphia provider is not + * included it will be added. + * + * @param list the new providers + * + * @return this + * @since 3.0 + * @morphia.internal + * @morphia.experimental + * @see #propertyAnnotationProviders() + */ + @MorphiaInternal + @MorphiaExperimental + default MorphiaConfig propertyAnnotationProviders(List> list) { + var newConfig = new ManualMorphiaConfig(this); + newConfig.propertyAnnotationProviders = list; + if (list.isEmpty() || list.stream().noneMatch(p -> p instanceof MorphiaPropertyAnnotationProvider)) { + newConfig.propertyAnnotationProviders.add(new MorphiaPropertyAnnotationProvider()); + } + return newConfig; + } + /** * Determines how properties are discovered. The traditional value is by scanning for fields which involves a bit more reflective * work. Alternately, scanning can check for get/set method pairs to determine which class properties should be mapped. @@ -381,6 +431,7 @@ default MorphiaConfig packages(List value) { * @return the discovery method to use * @see PropertyDiscovery */ + @Deprecated @WithDefault("fields") @PossibleValues(value = { "fields", "methods" }, fqcn = false) PropertyDiscovery propertyDiscovery(); diff --git a/core/src/main/java/dev/morphia/config/MorphiaConfigHelper.java b/core/src/main/java/dev/morphia/config/MorphiaConfigHelper.java index b4332d69b60..c3e78e8b3a6 100644 --- a/core/src/main/java/dev/morphia/config/MorphiaConfigHelper.java +++ b/core/src/main/java/dev/morphia/config/MorphiaConfigHelper.java @@ -31,7 +31,7 @@ */ @MorphiaInternal public class MorphiaConfigHelper { - static final String MORPHIA_CONFIG_PROPERTIES = "META-INF/morphia-config.properties"; + public static final String MORPHIA_CONFIG_PROPERTIES = "META-INF/morphia-config.properties"; final String prefix; private final MorphiaConfig config; private final boolean showComplete; diff --git a/core/src/main/java/dev/morphia/config/MorphiaPropertyAnnotationProvider.java b/core/src/main/java/dev/morphia/config/MorphiaPropertyAnnotationProvider.java new file mode 100644 index 00000000000..269f7b42948 --- /dev/null +++ b/core/src/main/java/dev/morphia/config/MorphiaPropertyAnnotationProvider.java @@ -0,0 +1,15 @@ +package dev.morphia.config; + +import dev.morphia.annotations.Property; + +public class MorphiaPropertyAnnotationProvider implements PropertyAnnotationProvider { + @Override + public Property convertToMorphia(Property annotation) { + return annotation; + } + + @Override + public Class provides() { + return Property.class; + } +} diff --git a/core/src/main/java/dev/morphia/config/PropertyAnnotationProvider.java b/core/src/main/java/dev/morphia/config/PropertyAnnotationProvider.java new file mode 100644 index 00000000000..7957f095172 --- /dev/null +++ b/core/src/main/java/dev/morphia/config/PropertyAnnotationProvider.java @@ -0,0 +1,22 @@ +package dev.morphia.config; + +import dev.morphia.annotations.Property; +import dev.morphia.annotations.internal.MorphiaExperimental; +import dev.morphia.annotations.internal.MorphiaInternal; + +/** + * This type defines support for a given an annotation as usable to denoting an annotation on an entity and provides a conversion + * function to map it to a standard Morphia {@link Property} annotation. + * + * @param The type of annotation to use to denote a property + * @since 3.0 + * @morphia.experimental + * @morphia.internal + */ +@MorphiaInternal +@MorphiaExperimental +public interface PropertyAnnotationProvider { + Property convertToMorphia(T annotation); + + Class provides(); +} diff --git a/core/src/main/java/dev/morphia/config/ClassNameConverter.java b/core/src/main/java/dev/morphia/config/converters/ClassNameConverter.java similarity index 95% rename from core/src/main/java/dev/morphia/config/ClassNameConverter.java rename to core/src/main/java/dev/morphia/config/converters/ClassNameConverter.java index 2a73f517619..5dc1d5ad6f8 100644 --- a/core/src/main/java/dev/morphia/config/ClassNameConverter.java +++ b/core/src/main/java/dev/morphia/config/converters/ClassNameConverter.java @@ -1,4 +1,4 @@ -package dev.morphia.config; +package dev.morphia.config.converters; import com.mongodb.lang.Nullable; diff --git a/core/src/main/java/dev/morphia/config/CodecProviderConverter.java b/core/src/main/java/dev/morphia/config/converters/CodecProviderConverter.java similarity index 86% rename from core/src/main/java/dev/morphia/config/CodecProviderConverter.java rename to core/src/main/java/dev/morphia/config/converters/CodecProviderConverter.java index 5bc7c1b8751..9d755966748 100644 --- a/core/src/main/java/dev/morphia/config/CodecProviderConverter.java +++ b/core/src/main/java/dev/morphia/config/converters/CodecProviderConverter.java @@ -1,4 +1,4 @@ -package dev.morphia.config; +package dev.morphia.config.converters; import dev.morphia.annotations.internal.MorphiaInternal; diff --git a/core/src/main/java/dev/morphia/config/DiscriminatorFunctionConverter.java b/core/src/main/java/dev/morphia/config/converters/DiscriminatorFunctionConverter.java similarity index 97% rename from core/src/main/java/dev/morphia/config/DiscriminatorFunctionConverter.java rename to core/src/main/java/dev/morphia/config/converters/DiscriminatorFunctionConverter.java index 05eeaf428bd..2fc5d49bbcc 100644 --- a/core/src/main/java/dev/morphia/config/DiscriminatorFunctionConverter.java +++ b/core/src/main/java/dev/morphia/config/converters/DiscriminatorFunctionConverter.java @@ -1,4 +1,4 @@ -package dev.morphia.config; +package dev.morphia.config.converters; import dev.morphia.annotations.internal.MorphiaInternal; import dev.morphia.mapping.DiscriminatorFunction; diff --git a/core/src/main/java/dev/morphia/config/NamingStrategyConverter.java b/core/src/main/java/dev/morphia/config/converters/NamingStrategyConverter.java similarity index 97% rename from core/src/main/java/dev/morphia/config/NamingStrategyConverter.java rename to core/src/main/java/dev/morphia/config/converters/NamingStrategyConverter.java index 841bf0a0353..4be790ee644 100644 --- a/core/src/main/java/dev/morphia/config/NamingStrategyConverter.java +++ b/core/src/main/java/dev/morphia/config/converters/NamingStrategyConverter.java @@ -1,4 +1,4 @@ -package dev.morphia.config; +package dev.morphia.config.converters; import dev.morphia.annotations.internal.MorphiaInternal; import dev.morphia.mapping.MappingException; diff --git a/core/src/main/java/dev/morphia/config/converters/PropertyAnnotationProviderConverter.java b/core/src/main/java/dev/morphia/config/converters/PropertyAnnotationProviderConverter.java new file mode 100644 index 00000000000..1eb9fb5631c --- /dev/null +++ b/core/src/main/java/dev/morphia/config/converters/PropertyAnnotationProviderConverter.java @@ -0,0 +1,36 @@ +package dev.morphia.config.converters; + +import java.util.ArrayList; +import java.util.List; + +import dev.morphia.annotations.internal.MorphiaInternal; +import dev.morphia.config.MorphiaPropertyAnnotationProvider; +import dev.morphia.config.PropertyAnnotationProvider; +import dev.morphia.mapping.MappingException; + +import org.eclipse.microprofile.config.spi.Converter; + +import static java.util.Arrays.asList; + +/** + * @hidden + * @since 3.0 + * @morphia.internal + */ +@MorphiaInternal +@SuppressWarnings("unchecked") +public class PropertyAnnotationProviderConverter implements Converter>> { + @Override + public List> convert(String value) { + List list = new ArrayList<>(List.of(MorphiaPropertyAnnotationProvider.class.getName())); + list.addAll(asList(value.split(","))); + return (List>) list.stream().distinct() + .map(s -> { + try { + return Class.forName(s.trim()).getConstructor().newInstance(); + } catch (ReflectiveOperationException e) { + throw new MappingException(e.getMessage(), e); + } + }).toList(); + } +} diff --git a/core/src/main/java/dev/morphia/config/QueryFactoryConverter.java b/core/src/main/java/dev/morphia/config/converters/QueryFactoryConverter.java similarity index 90% rename from core/src/main/java/dev/morphia/config/QueryFactoryConverter.java rename to core/src/main/java/dev/morphia/config/converters/QueryFactoryConverter.java index 73b0d9aeb95..babd2ba12a5 100644 --- a/core/src/main/java/dev/morphia/config/QueryFactoryConverter.java +++ b/core/src/main/java/dev/morphia/config/converters/QueryFactoryConverter.java @@ -1,4 +1,4 @@ -package dev.morphia.config; +package dev.morphia.config.converters; import dev.morphia.annotations.internal.MorphiaInternal; import dev.morphia.query.QueryFactory; diff --git a/core/src/main/java/dev/morphia/mapping/DiscriminatorFunction.java b/core/src/main/java/dev/morphia/mapping/DiscriminatorFunction.java index 6f2031142c3..7f3fbbc26d5 100644 --- a/core/src/main/java/dev/morphia/mapping/DiscriminatorFunction.java +++ b/core/src/main/java/dev/morphia/mapping/DiscriminatorFunction.java @@ -1,7 +1,5 @@ package dev.morphia.mapping; -import dev.morphia.annotations.Entity; -import dev.morphia.mapping.codec.pojo.EntityModel; import dev.morphia.mapping.discriminator.ClassNameDiscriminator; import dev.morphia.mapping.discriminator.LowerClassNameDiscriminator; import dev.morphia.mapping.discriminator.LowerSimpleNameDiscriminator; @@ -52,20 +50,13 @@ public static DiscriminatorFunction simpleName() { /** * Applies the function to the given model to determine the discriminator value * - * @param model the model to evaluate + * @param type + * @param discriminator + * @return * @hidden */ - public final void apply(EntityModel model) { - String discriminator = Mapper.IGNORED_FIELDNAME; - Entity entity = model.getAnnotation(Entity.class); - if (entity != null) { - discriminator = entity.discriminator(); - } - if (discriminator.equals(Mapper.IGNORED_FIELDNAME)) { - discriminator = compute(model.getType()); - } - - model.discriminator(discriminator); + public final String apply(Class type, String discriminator) { + return discriminator.equals(Mapper.IGNORED_FIELDNAME) ? compute(type) : discriminator; } /** diff --git a/core/src/main/java/dev/morphia/mapping/codec/MorphiaFilterCodecProvider.java b/core/src/main/java/dev/morphia/mapping/codec/MorphiaFilterCodecProvider.java index 6060fdc4706..db096002d44 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/MorphiaFilterCodecProvider.java +++ b/core/src/main/java/dev/morphia/mapping/codec/MorphiaFilterCodecProvider.java @@ -7,12 +7,14 @@ import dev.morphia.mapping.codec.filters.BaseFilterCodec; import dev.morphia.mapping.codec.filters.BoxCodec; import dev.morphia.mapping.codec.filters.CenterFilterCodec; +import dev.morphia.mapping.codec.filters.CommentFilterCodec; import dev.morphia.mapping.codec.filters.ElemMatchFilterCodec; import dev.morphia.mapping.codec.filters.EqFilterCodec; import dev.morphia.mapping.codec.filters.ExistsFilterCodec; import dev.morphia.mapping.codec.filters.ExprFilterCodec; import dev.morphia.mapping.codec.filters.FilterCodec; import dev.morphia.mapping.codec.filters.GeoIntersectsFilterCodec; +import dev.morphia.mapping.codec.filters.GeoWithinFilterCodec; import dev.morphia.mapping.codec.filters.JsonSchemaFilterCodec; import dev.morphia.mapping.codec.filters.LogicalFilterCodec; import dev.morphia.mapping.codec.filters.NearFilterCodec; @@ -35,12 +37,14 @@ public MorphiaFilterCodecProvider(MorphiaDatastore datastore) { this.datastore = datastore; addCodec(new BoxCodec(datastore)); addCodec(new CenterFilterCodec(datastore)); + addCodec(new CommentFilterCodec(datastore)); addCodec(new ElemMatchFilterCodec(datastore)); addCodec(new EqFilterCodec(datastore)); addCodec(new ExistsFilterCodec(datastore)); addCodec(new ExprFilterCodec(datastore)); addCodec(new FilterCodec(datastore)); addCodec(new GeoIntersectsFilterCodec(datastore)); + addCodec(new GeoWithinFilterCodec(datastore)); addCodec(new JsonSchemaFilterCodec(datastore)); addCodec(new LogicalFilterCodec(datastore)); addCodec(new ModFilterCodec(datastore)); diff --git a/core/src/main/java/dev/morphia/mapping/codec/MorphiaTypesCodecProvider.java b/core/src/main/java/dev/morphia/mapping/codec/MorphiaTypesCodecProvider.java index 8516609a6f5..634bffbf7f9 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/MorphiaTypesCodecProvider.java +++ b/core/src/main/java/dev/morphia/mapping/codec/MorphiaTypesCodecProvider.java @@ -30,13 +30,16 @@ public MorphiaTypesCodecProvider(MorphiaDatastore datastore) { addCodec(new MorphiaMapCodec(datastore)); addCodec(new MorphiaLocalDateTimeCodec(datastore)); addCodec(new MorphiaLocalTimeCodec()); + addCodec(new PolygonCoordinatesCodec()); addCodec(new ClassCodec()); addCodec(new LocaleCodec()); addCodec(new ObjectCodec(datastore)); + // addCodec(new PatternCodec()); addCodec(new URICodec()); addCodec(new ByteWrapperArrayCodec()); addCodec(new BitSetCodec()); addCodec(new FieldsCodec(datastore)); + addCodec(new TypeCodec()); List.of(boolean.class, Boolean.class, char.class, Character.class, @@ -48,7 +51,16 @@ public MorphiaTypesCodecProvider(MorphiaDatastore datastore) { } protected void addCodec(Codec codec) { - codecs.put(codec.getEncoderClass(), codec); + Class encoderClass = codec.getEncoderClass(); + if (!encoderClass.isEnum()) { + codecs.put(encoderClass, codec); + } else { + T[] enumConstants = encoderClass.getEnumConstants(); + for (T enumConstant : enumConstants) { + Class aClass = enumConstant.getClass(); + codecs.put(aClass, codec); + } + } } @Override @@ -64,4 +76,5 @@ public Codec get(Class clazz, CodecRegistry registry) { return null; } } + } diff --git a/core/src/main/java/dev/morphia/mapping/codec/MorphiaUpdateOperatorCodecProvider.java b/core/src/main/java/dev/morphia/mapping/codec/MorphiaUpdateOperatorCodecProvider.java new file mode 100644 index 00000000000..7d9907004dd --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/MorphiaUpdateOperatorCodecProvider.java @@ -0,0 +1,60 @@ +package dev.morphia.mapping.codec; + +import java.util.HashMap; +import java.util.Map; + +import com.mongodb.lang.Nullable; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.mapping.codec.updates.AddToSetOperatorCodec; +import dev.morphia.mapping.codec.updates.BaseOperatorCodec; +import dev.morphia.mapping.codec.updates.BitOperatorCodec; +import dev.morphia.mapping.codec.updates.CurrentDateOperatorCodec; +import dev.morphia.mapping.codec.updates.PopOperatorCodec; +import dev.morphia.mapping.codec.updates.PullOperatorCodec; +import dev.morphia.mapping.codec.updates.PushOperatorCodec; +import dev.morphia.mapping.codec.updates.SetEntityOperatorCodec; +import dev.morphia.mapping.codec.updates.SetOnInsertOperatorCodec; +import dev.morphia.mapping.codec.updates.UpdateOperatorCodec; +import dev.morphia.query.updates.UpdateOperator; + +import org.bson.codecs.Codec; +import org.bson.codecs.configuration.CodecProvider; +import org.bson.codecs.configuration.CodecRegistry; + +public class MorphiaUpdateOperatorCodecProvider implements CodecProvider { + protected final MorphiaDatastore datastore; + private final Map, BaseOperatorCodec> codecs = new HashMap<>(); + + public MorphiaUpdateOperatorCodecProvider(MorphiaDatastore datastore) { + this.datastore = datastore; + addCodec(new AddToSetOperatorCodec(datastore)); + addCodec(new BitOperatorCodec(datastore)); + addCodec(new CurrentDateOperatorCodec(datastore)); + addCodec(new PopOperatorCodec(datastore)); + addCodec(new PullOperatorCodec(datastore)); + addCodec(new PushOperatorCodec(datastore)); + addCodec(new SetEntityOperatorCodec(datastore)); + addCodec(new SetOnInsertOperatorCodec(datastore)); + addCodec(new UpdateOperatorCodec(datastore)); + addCodec(new UnsetOperatorCodec(datastore)); + } + + @Override + @Nullable + @SuppressWarnings("unchecked") + public Codec get(Class clazz, CodecRegistry registry) { + Codec codec = (Codec) codecs.get(clazz); + + if (codec == null && UpdateOperator.class.isAssignableFrom(clazz)) { + // throw new UnsupportedOperationException(clazz.getName() + " needs a codec"); + return (Codec) codecs.get(UpdateOperator.class); + } + return codec; + } + + private void addCodec(BaseOperatorCodec codec) { + codecs.put(codec.getEncoderClass(), codec); + } + +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/PatternCodec.java b/core/src/main/java/dev/morphia/mapping/codec/PatternCodec.java new file mode 100644 index 00000000000..fa9b790e19a --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/PatternCodec.java @@ -0,0 +1,122 @@ +package dev.morphia.mapping.codec; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +import com.mongodb.lang.Nullable; + +import org.bson.BsonReader; +import org.bson.BsonRegularExpression; +import org.bson.BsonWriter; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; + +/** + * Morphia-local codec based on code from the Java Driver. + * + * @hidden + */ +public class PatternCodec implements Codec { + @Override + public Pattern decode(BsonReader reader, DecoderContext decoderContext) { + BsonRegularExpression regularExpression = reader.readRegularExpression(); + return Pattern.compile(regularExpression.getPattern(), getOptionsAsInt(regularExpression)); + } + + @Override + public void encode(BsonWriter writer, Pattern value, EncoderContext encoderContext) { + writer.writeString("/%s/%s".formatted(value.pattern(), getOptionsAsString(value))); + } + + @Override + public Class getEncoderClass() { + return Pattern.class; + } + + private static String getOptionsAsString(final Pattern pattern) { + int flags = pattern.flags(); + StringBuilder buf = new StringBuilder(); + + for (final RegexFlag flag : RegexFlag.values()) { + if ((pattern.flags() & flag.javaFlag) > 0) { + buf.append(flag.flagChar); + flags -= flag.javaFlag; + } + } + + if (flags > 0) { + throw new IllegalArgumentException("some flags could not be recognized."); + } + + return buf.toString(); + } + + private static int getOptionsAsInt(final BsonRegularExpression regularExpression) { + int optionsInt = 0; + + String optionsString = regularExpression.getOptions(); + + if (optionsString == null || optionsString.length() == 0) { + return optionsInt; + } + + optionsString = optionsString.toLowerCase(); + + for (int i = 0; i < optionsString.length(); i++) { + RegexFlag flag = RegexFlag.getByCharacter(optionsString.charAt(i)); + if (flag != null) { + optionsInt |= flag.javaFlag; + if (flag.unsupported != null) { + // TODO: deal with logging + // warnUnsupportedRegex( flag.unsupported ); + } + } else { + // TODO: throw a better exception here + throw new IllegalArgumentException("unrecognized flag [" + optionsString.charAt(i) + "] " + (int) optionsString.charAt(i)); + } + } + return optionsInt; + } + + private static final int GLOBAL_FLAG = 256; + + /** + * @hidden + */ + public enum RegexFlag { + CANON_EQ(Pattern.CANON_EQ, 'c', "Pattern.CANON_EQ"), + UNIX_LINES(Pattern.UNIX_LINES, 'd', "Pattern.UNIX_LINES"), + GLOBAL(GLOBAL_FLAG, 'g', null), + CASE_INSENSITIVE(Pattern.CASE_INSENSITIVE, 'i', null), + MULTILINE(Pattern.MULTILINE, 'm', null), + DOTALL(Pattern.DOTALL, 's', "Pattern.DOTALL"), + LITERAL(Pattern.LITERAL, 't', "Pattern.LITERAL"), + UNICODE_CASE(Pattern.UNICODE_CASE, 'u', "Pattern.UNICODE_CASE"), + COMMENTS(Pattern.COMMENTS, 'x', null); + + private static final Map BY_CHARACTER = new HashMap<>(); + + public final int javaFlag; + public final char flagChar; + private final String unsupported; + + static { + for (final RegexFlag flag : values()) { + BY_CHARACTER.put(flag.flagChar, flag); + } + } + + public static RegexFlag getByCharacter(final char ch) { + return BY_CHARACTER.get(ch); + } + + RegexFlag(final int f, final char ch, @Nullable final String u) { + javaFlag = f; + flagChar = ch; + unsupported = u; + } + } + +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/PolygonCoordinatesCodec.java b/core/src/main/java/dev/morphia/mapping/codec/PolygonCoordinatesCodec.java new file mode 100644 index 00000000000..2ff331e7d34 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/PolygonCoordinatesCodec.java @@ -0,0 +1,127 @@ +package dev.morphia.mapping.codec; + +import java.util.ArrayList; +import java.util.List; + +import com.mongodb.client.model.geojson.PolygonCoordinates; +import com.mongodb.client.model.geojson.Position; + +import org.bson.BsonReader; +import org.bson.BsonType; +import org.bson.BsonWriter; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.codecs.configuration.CodecConfigurationException; + +import static java.lang.String.format; + +/** + * This codec has been cobbled together via sources from com.mongodb.client.model.geojson.codecs.GeometryDecoderHelper + * and com.mongodb.client.model.geojson.codecs.GeometryEncoderHelper + */ +public class PolygonCoordinatesCodec implements Codec { + + @Override + public PolygonCoordinates decode(BsonReader reader, DecoderContext decoderContext) { + reader.readStartArray(); + List> values = new ArrayList<>(); + while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { + values.add(decodeCoordinates(reader)); + } + reader.readEndArray(); + + if (values.isEmpty()) { + throw new CodecConfigurationException("Invalid Polygon no coordinates."); + } + + List exterior = values.remove(0); + + try { + return new PolygonCoordinates(exterior, values); + } catch (IllegalArgumentException e) { + throw new CodecConfigurationException(format("Invalid Polygon: %s", e.getMessage())); + } + + } + + @Override + public void encode(BsonWriter writer, PolygonCoordinates polygonCoordinates, EncoderContext encoderContext) { + writer.writeStartArray(); + encodeLinearRing(polygonCoordinates.getExterior(), writer); + for (List ring : polygonCoordinates.getHoles()) { + encodeLinearRing(ring, writer); + } + writer.writeEndArray(); + } + + @Override + public Class getEncoderClass() { + return PolygonCoordinates.class; + } + + private static List decodeCoordinates(final BsonReader reader) { + validateIsArray(reader); + reader.readStartArray(); + List values = new ArrayList<>(); + while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { + values.add(decodePosition(reader)); + } + reader.readEndArray(); + return values; + } + + private static Position decodePosition(final BsonReader reader) { + validateIsArray(reader); + reader.readStartArray(); + List values = new ArrayList<>(); + while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { + values.add(readAsDouble(reader)); + } + reader.readEndArray(); + + try { + return new Position(values); + } catch (IllegalArgumentException e) { + throw new CodecConfigurationException(format("Invalid Position: %s", e.getMessage())); + } + } + + private static double readAsDouble(final BsonReader reader) { + if (reader.getCurrentBsonType() == BsonType.DOUBLE) { + return reader.readDouble(); + } else if (reader.getCurrentBsonType() == BsonType.INT32) { + return reader.readInt32(); + } else if (reader.getCurrentBsonType() == BsonType.INT64) { + return reader.readInt64(); + } + + throw new CodecConfigurationException("A GeoJSON position value must be a numerical type, but the value is of type " + + reader.getCurrentBsonType()); + } + + private void encodeLinearRing(final List ring, final BsonWriter writer) { + writer.writeStartArray(); + for (Position position : ring) { + encodePosition(writer, position); + } + writer.writeEndArray(); + } + + private void encodePosition(final BsonWriter writer, final Position value) { + writer.writeStartArray(); + + for (double number : value.getValues()) { + writer.writeDouble(number); + } + + writer.writeEndArray(); + } + + private static void validateIsArray(final BsonReader reader) { + if (reader.getCurrentBsonType() != BsonType.ARRAY) { + throw new CodecConfigurationException("Invalid BsonType expecting an Array"); + } + } + +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/TypeCodec.java b/core/src/main/java/dev/morphia/mapping/codec/TypeCodec.java new file mode 100644 index 00000000000..46e38298ebd --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/TypeCodec.java @@ -0,0 +1,39 @@ +package dev.morphia.mapping.codec; + +import dev.morphia.query.Type; + +import org.bson.BsonReader; +import org.bson.BsonWriter; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; + +public class TypeCodec implements Codec { + @Override + public Type decode(BsonReader bsonReader, DecoderContext decoderContext) { + throw new UnsupportedOperationException(); + } + + @Override + public void encode(BsonWriter bsonWriter, Type type, EncoderContext encoderContext) { + var value = switch (type) { + case BINARY_DATA -> "binData"; + case OBJECT_ID -> "objectId"; + case BOOLEAN -> "bool"; + case REGULAR_EXPRESSION -> "regex"; + case DB_POINTER -> "dbPointer"; + case INTEGER_32_BIT -> "int"; + case INTEGER_64_BIT -> "long"; + case DECIMAL_128 -> "decimal"; + case MIN_KEY -> "minKey"; + case MAX_KEY -> "maxKey"; + default -> type.name().toLowerCase(); + }; + bsonWriter.writeString(value); + } + + @Override + public Class getEncoderClass() { + return Type.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/UnsetOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/UnsetOperatorCodec.java new file mode 100644 index 00000000000..8ac179921fb --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/UnsetOperatorCodec.java @@ -0,0 +1,38 @@ +package dev.morphia.mapping.codec; + +import java.util.List; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.internal.PathTarget; +import dev.morphia.mapping.codec.updates.BaseOperatorCodec; +import dev.morphia.query.updates.UnsetOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; + +public class UnsetOperatorCodec extends BaseOperatorCodec { + public UnsetOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + @SuppressWarnings("unchecked") + public void encode(BsonWriter writer, UnsetOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + for (String field : ((List) operator.value())) { + var target = new PathTarget(datastore.getMapper(), operator.model(), field, operator.validate()).translatedPath(); + namedValue(writer, datastore, target, "", encoderContext); + } + }); + }); + } + + @Override + public Class getEncoderClass() { + return UnsetOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/filters/CommentFilterCodec.java b/core/src/main/java/dev/morphia/mapping/codec/filters/CommentFilterCodec.java new file mode 100644 index 00000000000..bcbb752deb2 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/filters/CommentFilterCodec.java @@ -0,0 +1,25 @@ +package dev.morphia.mapping.codec.filters; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.filters.CommentFilter; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.namedValue; + +public class CommentFilterCodec extends BaseFilterCodec { + public CommentFilterCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, CommentFilter value, EncoderContext encoderContext) { + namedValue(writer, datastore, value.getName(), value.comment(), encoderContext); + } + + @Override + public Class getEncoderClass() { + return CommentFilter.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/filters/ElemMatchFilterCodec.java b/core/src/main/java/dev/morphia/mapping/codec/filters/ElemMatchFilterCodec.java index 3e6dbc267ff..4221c714ce3 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/filters/ElemMatchFilterCodec.java +++ b/core/src/main/java/dev/morphia/mapping/codec/filters/ElemMatchFilterCodec.java @@ -20,14 +20,23 @@ public ElemMatchFilterCodec(MorphiaDatastore datastore) { @Override public void encode(BsonWriter writer, ElemMatchFilter elemMatch, EncoderContext encoderContext) { - document(writer, elemMatch.path(datastore.getMapper()), () -> { - if (elemMatch.isNot()) { - document(writer, "$not", () -> encodeFilter(writer, elemMatch, encoderContext)); - } else { - encodeFilter(writer, elemMatch, encoderContext); - } - }); - + if (elemMatch.getField() != null && !elemMatch.getField().equals("")) { + document(writer, elemMatch.path(datastore.getMapper()), () -> { + if (elemMatch.isNot()) { + document(writer, "$not", () -> encodeFilter(writer, elemMatch, encoderContext)); + } else { + encodeFilter(writer, elemMatch, encoderContext); + } + }); + } else { + document(writer, () -> { + if (elemMatch.isNot()) { + document(writer, "$not", () -> encodeFilter(writer, elemMatch, encoderContext)); + } else { + encodeFilter(writer, elemMatch, encoderContext); + } + }); + } } @SuppressWarnings({ "unchecked", "rawtypes" }) diff --git a/core/src/main/java/dev/morphia/mapping/codec/filters/FilterCodec.java b/core/src/main/java/dev/morphia/mapping/codec/filters/FilterCodec.java index d05e9d461a9..22f490b0d5b 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/filters/FilterCodec.java +++ b/core/src/main/java/dev/morphia/mapping/codec/filters/FilterCodec.java @@ -16,7 +16,18 @@ public FilterCodec(MorphiaDatastore datastore) { @Override public void encode(BsonWriter writer, Filter filter, EncoderContext encoderContext) { - document(writer, filter.path(datastore.getMapper()), () -> { + String path = filter.path(datastore.getMapper()); + if (!path.equals("")) { + document(writer, path, () -> { + if (filter.isNot()) { + document(writer, "$not", () -> { + CodecHelper.namedValue(writer, datastore, filter.getName(), filter.getValue(datastore), encoderContext); + }); + } else { + CodecHelper.namedValue(writer, datastore, filter.getName(), filter.getValue(datastore), encoderContext); + } + }); + } else { if (filter.isNot()) { document(writer, "$not", () -> { CodecHelper.namedValue(writer, datastore, filter.getName(), filter.getValue(datastore), encoderContext); @@ -24,7 +35,7 @@ public void encode(BsonWriter writer, Filter filter, EncoderContext encoderConte } else { CodecHelper.namedValue(writer, datastore, filter.getName(), filter.getValue(datastore), encoderContext); } - }); + } } @Override diff --git a/core/src/main/java/dev/morphia/mapping/codec/filters/GeoWithinFilterCodec.java b/core/src/main/java/dev/morphia/mapping/codec/filters/GeoWithinFilterCodec.java new file mode 100644 index 00000000000..4c1ced256c7 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/filters/GeoWithinFilterCodec.java @@ -0,0 +1,62 @@ +package dev.morphia.mapping.codec.filters; + +import com.mongodb.client.model.geojson.CoordinateReferenceSystem; +import com.mongodb.client.model.geojson.GeoJsonObjectType; +import com.mongodb.client.model.geojson.Geometry; +import com.mongodb.client.model.geojson.MultiPolygon; +import com.mongodb.client.model.geojson.Polygon; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.filters.GeoWithinFilter; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.value; + +public class GeoWithinFilterCodec extends BaseFilterCodec { + public GeoWithinFilterCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, GeoWithinFilter value, EncoderContext encoderContext) { + document(writer, value.path(datastore.getMapper()), () -> { + if (value.isNot()) { + document(writer, "$not", () -> { + encodeFilter(writer, value, encoderContext); + }); + } else { + encodeFilter(writer, value, encoderContext); + } + }); + } + + private void encodeFilter(BsonWriter writer, GeoWithinFilter value, EncoderContext encoderContext) { + document(writer, value.getName(), () -> { + document(writer, "$geometry", () -> { + Geometry geometry = (Geometry) value.getValue(); + value(writer, "type", geometry.getType().getTypeName()); + GeoJsonObjectType type = geometry.getType(); + if (type == GeoJsonObjectType.POLYGON) { + var coordinates = ((Polygon) geometry).getCoordinates(); + value(datastore.getCodecRegistry(), writer, "coordinates", coordinates, encoderContext); + } else if (type == GeoJsonObjectType.MULTI_POLYGON) { + var coordinates = ((MultiPolygon) geometry).getCoordinates(); + value(datastore.getCodecRegistry(), writer, "coordinates", coordinates, encoderContext); + } + CoordinateReferenceSystem crs = geometry.getCoordinateReferenceSystem(); + if (crs != null) { + value(datastore.getCodecRegistry(), writer, "crs", crs, encoderContext); + } + + }); + }); + } + + @Override + public Class getEncoderClass() { + return GeoWithinFilter.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/filters/NearFilterCodec.java b/core/src/main/java/dev/morphia/mapping/codec/filters/NearFilterCodec.java index 333b627a17f..d8001466b7a 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/filters/NearFilterCodec.java +++ b/core/src/main/java/dev/morphia/mapping/codec/filters/NearFilterCodec.java @@ -33,8 +33,8 @@ private void encodeFilter(BsonWriter writer, NearFilter near, EncoderContext con document(writer, near.getName(), () -> { writer.writeName("$geometry"); CodecHelper.unnamedValue(writer, datastore, near.getValue(datastore), context); - value(writer, "$maxDistance", near.maxDistance()); value(writer, "$minDistance", near.minDistance()); + value(writer, "$maxDistance", near.maxDistance()); value(datastore.getCodecRegistry(), writer, "crs", near.crs(), context); }); } diff --git a/core/src/main/java/dev/morphia/mapping/codec/filters/RegexFilterCodec.java b/core/src/main/java/dev/morphia/mapping/codec/filters/RegexFilterCodec.java index eda15b20115..b6c9dae0a9a 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/filters/RegexFilterCodec.java +++ b/core/src/main/java/dev/morphia/mapping/codec/filters/RegexFilterCodec.java @@ -7,7 +7,7 @@ import org.bson.codecs.EncoderContext; import static dev.morphia.mapping.codec.CodecHelper.document; -import static dev.morphia.mapping.codec.CodecHelper.value; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; public class RegexFilterCodec extends BaseFilterCodec { public RegexFilterCodec(MorphiaDatastore datastore) { @@ -29,8 +29,7 @@ public void encode(BsonWriter writer, RegexFilter filter, EncoderContext encoder } private void encodeFilter(BsonWriter writer, RegexFilter filter, EncoderContext context) { - value(writer, "$regex", filter.getValue().toString()); - value(writer, "$options", filter.options()); + namedValue(writer, datastore, "$regex", filter.pattern(), context); } @Override diff --git a/core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModel.java b/core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModel.java index b7ac3d77981..1339cfd6beb 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModel.java +++ b/core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModel.java @@ -29,11 +29,13 @@ import dev.morphia.annotations.Entity; import dev.morphia.annotations.EntityListeners; import dev.morphia.annotations.ExternalEntity; +import dev.morphia.annotations.Id; import dev.morphia.annotations.PostLoad; import dev.morphia.annotations.PostPersist; import dev.morphia.annotations.PreLoad; import dev.morphia.annotations.PrePersist; import dev.morphia.annotations.ShardKeys; +import dev.morphia.annotations.Version; import dev.morphia.annotations.internal.MorphiaInternal; import dev.morphia.mapping.InstanceCreatorFactory; import dev.morphia.mapping.InstanceCreatorFactoryImpl; @@ -98,11 +100,11 @@ public EntityModel(Class type) { throw new MappingException(Sofia.noInnerClasses(type.getName())); } this.type = type; + creatorFactory = new InstanceCreatorFactoryImpl(this); } public EntityModel(Mapper mapper, Class type) { this(type); - creatorFactory = new InstanceCreatorFactoryImpl(this); new MappingUtil(mapper); @@ -167,6 +169,13 @@ public boolean addProperty(PropertyModel property) { var added = propertyModelsByName.putIfAbsent(property.getName(), property) == null; added &= propertyModelsByMappedName.put(property.getMappedName(), property) == null; + if (added) { + if (property.hasAnnotation(Id.class)) { + idProperty = property; + } else if (property.hasAnnotation(Version.class)) { + versionProperty = property; + } + } return added; } @@ -335,12 +344,14 @@ public PropertyModel getProperty(@Nullable String name) { return name != null ? propertyModelsByMappedName.getOrDefault(name, propertyModelsByName.get(name)) : null; } - @Nullable - public EntityModel getSubtype(Class type) { - return subtypes.stream().filter(subtype -> subtype.type.equals(type)) - .findFirst() - .orElse(null); - } + /* + * @Nullable + * public EntityModel getSubtype(Class type) { + * return subtypes.stream().filter(subtype -> subtype.type.equals(type)) + * .findFirst() + * .orElse(null); + * } + */ /** * Get the subtypes of this model diff --git a/core/src/main/java/dev/morphia/mapping/codec/pojo/PropertyModel.java b/core/src/main/java/dev/morphia/mapping/codec/pojo/PropertyModel.java index cd1b0111321..62ad67addbc 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/pojo/PropertyModel.java +++ b/core/src/main/java/dev/morphia/mapping/codec/pojo/PropertyModel.java @@ -146,7 +146,7 @@ public A getAnnotation(Class type) { return type.cast(annotationMap.get(type)); } - public List getAnnotations() { + public final List getAnnotations() { return new ArrayList<>(annotationMap.values()); } @@ -323,10 +323,10 @@ public Codec specializeCodec(Datastore datastore) { @Override public String toString() { return new StringJoiner(", ", PropertyModel.class.getSimpleName() + "[", "]") - .add("name='" + name + "'") - .add("mappedName='" + mappedName + "'") - .add("typeData=" + typeData) - .add("annotations=" + annotationMap.values()) + .add("name='" + getName() + "'") + .add("mappedName='" + getMappedName() + "'") + .add("typeData=" + getTypeData()) + .add("annotations=" + getAnnotations()) .toString(); } @@ -344,13 +344,6 @@ public boolean isMap() { return Map.class.isAssignableFrom(getTypeData().getType()); } - /** - * @return true if this field is a container type such as a List, Map, Set, or array - */ - public boolean isMultipleValues() { - return !isScalarValue(); - } - /** * @return true if this field is a reference to a foreign document * @see Reference @@ -363,7 +356,7 @@ public boolean isReference() { /** * @return true if this field is not a container type such as a List, Map, Set, or array */ - public boolean isScalarValue() { + public final boolean isScalarValue() { return !isMap() && !isArray() && !isCollection(); } @@ -399,7 +392,7 @@ public void setValue(Object instance, @Nullable Object value) { * @param value the value to check * @return true if the given value should be serialized */ - public boolean shouldSerialize(@Nullable Object value) { + public final boolean shouldSerialize(@Nullable Object value) { return serialization.shouldSerialize(value); } @@ -442,7 +435,7 @@ private Handler getHandler() { return handler; } - private boolean isCollection() { + public boolean isCollection() { return Collection.class.isAssignableFrom(getTypeData().getType()); } diff --git a/core/src/main/java/dev/morphia/mapping/codec/pojo/TypeData.java b/core/src/main/java/dev/morphia/mapping/codec/pojo/TypeData.java index 3194cb38747..8155f6dfca7 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/pojo/TypeData.java +++ b/core/src/main/java/dev/morphia/mapping/codec/pojo/TypeData.java @@ -21,6 +21,7 @@ import org.bson.codecs.pojo.TypeWithTypeParameters; import static java.lang.String.format; +import static java.util.Arrays.asList; import static org.bson.assertions.Assertions.notNull; /** @@ -54,6 +55,27 @@ public class TypeData implements TypeWithTypeParameters { */ public TypeData(Class type) { this.type = type; + array = type.isArray(); + } + + /** + * Creates a new TypeData with the concrete type and type parameters around it. + *

+ * e.g., List<Address> would be + * + *

+     * 
+     * new TypeData(Address.class, TypeData.builder(List.class).build())
+     * 
+     * 
+ * + * @param type the type + * @param typeParameters the parameters + */ + public TypeData(Class type, TypeData... typeParameters) { + this.type = type; + this.typeParameters.addAll(asList(typeParameters)); + array = type.isArray(); } /** @@ -73,6 +95,7 @@ public TypeData(Class type) { public TypeData(Class type, List> typeParameters) { this.type = type; this.typeParameters.addAll(typeParameters); + array = type.isArray(); } /** diff --git a/core/src/main/java/dev/morphia/mapping/codec/pojo/critter/CritterEntityModel.java b/core/src/main/java/dev/morphia/mapping/codec/pojo/critter/CritterEntityModel.java index e0512fd38d6..874eeb353ec 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/pojo/critter/CritterEntityModel.java +++ b/core/src/main/java/dev/morphia/mapping/codec/pojo/critter/CritterEntityModel.java @@ -1,23 +1,65 @@ package dev.morphia.mapping.codec.pojo.critter; +import java.lang.annotation.Annotation; + import dev.morphia.annotations.Entity; import dev.morphia.mapping.Mapper; import dev.morphia.mapping.codec.pojo.EntityModel; +/** + * 0 + * + * @hidden + * @morphia.internal + */ +@SuppressWarnings("NullableProblems") public abstract class CritterEntityModel extends EntityModel { - private Entity entityAnnotation; + protected final Mapper mapper; + protected Entity entityAnnotation; public CritterEntityModel(Mapper mapper, Class type) { - super(mapper, type); + super(type); + this.mapper = mapper; + } + + @Override + public final EntityModel collectionName(String collectionName) { + throw new UnsupportedOperationException(); + } + + @Override + public final void discriminator(String discriminator) { + throw new UnsupportedOperationException(); + } + + @Override + public final EntityModel discriminatorEnabled(boolean discriminatorEnabled) { + throw new UnsupportedOperationException(); } @Override - public Entity getEntityAnnotation() { - if (entityAnnotation == null) { - entityAnnotation = entityAnnotation(); - } - return entityAnnotation; + public final EntityModel discriminatorKey(String discriminatorKey) { + throw new UnsupportedOperationException(); } - protected abstract Entity entityAnnotation(); + @Override + public abstract String collectionName(); + + @Override + public abstract String discriminator(); + + @Override + public abstract String discriminatorKey(); + + @Override + public abstract boolean hasLifecycle(Class type); + + @Override + public abstract boolean isAbstract(); + + @Override + public abstract boolean isInterface(); + + @Override + public abstract boolean useDiscriminator(); } diff --git a/core/src/main/java/dev/morphia/mapping/codec/pojo/critter/CritterPropertyModel.java b/core/src/main/java/dev/morphia/mapping/codec/pojo/critter/CritterPropertyModel.java index 49266e65d76..6db41ef62a5 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/pojo/critter/CritterPropertyModel.java +++ b/core/src/main/java/dev/morphia/mapping/codec/pojo/critter/CritterPropertyModel.java @@ -19,13 +19,17 @@ public CritterPropertyModel(EntityModel entityModel) { public abstract PropertyAccessor getAccessor(); @Override - public abstract A getAnnotation(Class type); + public final PropertyModel accessor(PropertyAccessor accessor) { + throw new UnsupportedOperationException(); + } @Override - public abstract List getAnnotations(); + public abstract boolean isFinal(); @Override - public abstract boolean isFinal(); + public PropertyModel isFinal(boolean isFinal) { + throw new UnsupportedOperationException(); + } @Override public abstract String getFullName(); @@ -36,9 +40,19 @@ public CritterPropertyModel(EntityModel entityModel) { @Override public abstract String getMappedName(); + @Override + public PropertyModel mappedName(String name) { + throw new UnsupportedOperationException(); + } + @Override public abstract String getName(); + @Override + public PropertyModel name(String name) { + throw new UnsupportedOperationException(); + } + @Override public abstract Class getNormalizedType(); @@ -49,19 +63,23 @@ public CritterPropertyModel(EntityModel entityModel) { public abstract TypeData getTypeData(); @Override - public abstract boolean isArray(); + public PropertyModel typeData(TypeData data) { + throw new UnsupportedOperationException(); + } @Override - public abstract boolean isMap(); + public boolean hasAnnotation(Class type) { + return super.hasAnnotation(type); + } @Override - public abstract boolean isMultipleValues(); + public abstract boolean isArray(); @Override - public abstract boolean isReference(); + public abstract boolean isMap(); @Override - public abstract boolean isScalarValue(); + public abstract boolean isReference(); @Override public abstract boolean isSet(); @@ -70,5 +88,7 @@ public CritterPropertyModel(EntityModel entityModel) { public abstract boolean isTransient(); @Override - public abstract PropertyModel serialization(PropertySerialization serialization); + public PropertyModel serialization(PropertySerialization serialization) { + throw new UnsupportedOperationException(); + } } diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/AddToSetOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/AddToSetOperatorCodec.java new file mode 100644 index 00000000000..8186347125e --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/AddToSetOperatorCodec.java @@ -0,0 +1,42 @@ +package dev.morphia.mapping.codec.updates; + +import java.util.List; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.updates.AddToSetOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; +import static dev.morphia.mapping.codec.CodecHelper.value; + +public class AddToSetOperatorCodec extends BaseOperatorCodec { + public AddToSetOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, AddToSetOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + Object value = operator.value(); + if (value instanceof List list && list.size() > 1) { + document(writer, operator.field(), () -> { + namedValue(writer, datastore, "$each", list, encoderContext); + }); + } else { + namedValue(writer, datastore, operator.field(), value, encoderContext); + } + + }); + }); + + } + + @Override + public Class getEncoderClass() { + return AddToSetOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/BaseOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/BaseOperatorCodec.java new file mode 100644 index 00000000000..e24f90c3cfb --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/BaseOperatorCodec.java @@ -0,0 +1,23 @@ +package dev.morphia.mapping.codec.updates; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.updates.UpdateOperator; +import dev.morphia.sofia.Sofia; + +import org.bson.BsonReader; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; + +public abstract class BaseOperatorCodec implements Codec { + protected MorphiaDatastore datastore; + + public BaseOperatorCodec(MorphiaDatastore datastore) { + this.datastore = datastore; + } + + @Override + public final T decode(BsonReader reader, DecoderContext decoderContext) { + throw new UnsupportedOperationException(Sofia.encodingOnly()); + } + +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/BitOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/BitOperatorCodec.java new file mode 100644 index 00000000000..5afc1e5ef72 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/BitOperatorCodec.java @@ -0,0 +1,33 @@ +package dev.morphia.mapping.codec.updates; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.updates.BitOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; + +public class BitOperatorCodec extends BaseOperatorCodec { + public BitOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, BitOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + document(writer, operator.field(), () -> { + namedValue(writer, datastore, operator.operation(), operator.value(), encoderContext); + }); + }); + }); + + } + + @Override + public Class getEncoderClass() { + return BitOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/CurrentDateOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/CurrentDateOperatorCodec.java new file mode 100644 index 00000000000..d3d59dff465 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/CurrentDateOperatorCodec.java @@ -0,0 +1,35 @@ +package dev.morphia.mapping.codec.updates; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.updates.CurrentDateOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; + +public class CurrentDateOperatorCodec extends BaseOperatorCodec { + public CurrentDateOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, CurrentDateOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + writer.writeName(operator.field()); + switch (operator.type()) { + case DATE -> writer.writeBoolean(true); + case TIMESTAMP -> document(writer, () -> { + writer.writeString("$type", "timestamp"); + }); + } + }); + }); + } + + @Override + public Class getEncoderClass() { + return CurrentDateOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/PopOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/PopOperatorCodec.java new file mode 100644 index 00000000000..8df2e11b3b5 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/PopOperatorCodec.java @@ -0,0 +1,31 @@ +package dev.morphia.mapping.codec.updates; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.updates.PopOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; + +public class PopOperatorCodec extends BaseOperatorCodec { + public PopOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, PopOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + namedValue(writer, datastore, operator.field(), operator.value(), encoderContext); + }); + }); + + } + + @Override + public Class getEncoderClass() { + return PopOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/PullOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/PullOperatorCodec.java new file mode 100644 index 00000000000..d84cefd8cea --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/PullOperatorCodec.java @@ -0,0 +1,43 @@ +package dev.morphia.mapping.codec.updates; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.filters.Filter; +import dev.morphia.query.updates.PullOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; +import static dev.morphia.mapping.codec.CodecHelper.unnamedValue; + +public class PullOperatorCodec extends BaseOperatorCodec { + public PullOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void encode(BsonWriter writer, PullOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + Object value = operator.value(); + if (value instanceof Filter[] filters) { + document(writer, operator.field(), () -> { + for (Filter filter : filters) { + unnamedValue(writer, datastore, filter, encoderContext); + } + }); + } else { + namedValue(writer, datastore, operator.field(), value, encoderContext); + } + }); + }); + + } + + @Override + public Class getEncoderClass() { + return PullOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/PushOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/PushOperatorCodec.java new file mode 100644 index 00000000000..dc41d98913d --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/PushOperatorCodec.java @@ -0,0 +1,56 @@ +package dev.morphia.mapping.codec.updates; + +import java.util.List; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.updates.PushOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; +import static dev.morphia.mapping.codec.CodecHelper.value; + +public class PushOperatorCodec extends BaseOperatorCodec { + public PushOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, PushOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + Object value = operator.value(); + if (value instanceof List list) { + if (list.size() == 1 && !hasOptions(operator)) { + namedValue(writer, datastore, operator.field(), list.get(0), encoderContext); + } else { + document(writer, operator.field(), () -> { + namedValue(writer, datastore, "$each", list, encoderContext); + value(writer, "$position", operator.position()); + value(writer, "$sort", operator.sort()); + if (operator.sortDocument() != null) { + namedValue(writer, datastore, "$sort", operator.sortDocument(), encoderContext); + } + value(writer, "$slice", operator.slice()); + }); + } + } + }); + }); + + } + + private boolean hasOptions(PushOperator operator) { + return operator.slice() != null + || operator.sort() != null + || operator.position() != null + || operator.sortDocument() != null; + } + + @Override + public Class getEncoderClass() { + return PushOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/SetEntityOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/SetEntityOperatorCodec.java new file mode 100644 index 00000000000..c439213a2c1 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/SetEntityOperatorCodec.java @@ -0,0 +1,42 @@ +package dev.morphia.mapping.codec.updates; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.mapping.codec.pojo.EntityModel; +import dev.morphia.mapping.codec.writer.DocumentWriter; +import dev.morphia.query.updates.SetEntityOperator; + +import org.bson.BsonWriter; +import org.bson.Document; +import org.bson.codecs.Codec; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; + +@SuppressWarnings({ "unchecked", "rawtypes" }) +public class SetEntityOperatorCodec extends BaseOperatorCodec { + public SetEntityOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, SetEntityOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + DocumentWriter documentWriter = new DocumentWriter(datastore.getMapper().getConfig()); + Codec codec = datastore.getCodecRegistry().get(operator.value().getClass()); + encoderContext.encodeWithChildContext(codec, documentWriter, operator.value()); + Document document = documentWriter.getDocument(); + EntityModel model = operator.model(); + if (model != null && model.getVersionProperty() != null) { + document.remove(model.getVersionProperty().getMappedName()); + } + + namedValue(writer, datastore, "$set", document, encoderContext); + }); + } + + @Override + public Class getEncoderClass() { + return SetEntityOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/SetOnInsertOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/SetOnInsertOperatorCodec.java new file mode 100644 index 00000000000..5889dc5ca99 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/SetOnInsertOperatorCodec.java @@ -0,0 +1,37 @@ +package dev.morphia.mapping.codec.updates; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.internal.PathTarget; +import dev.morphia.query.updates.SetOnInsertOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; +import static dev.morphia.mapping.codec.CodecHelper.value; + +public class SetOnInsertOperatorCodec extends BaseOperatorCodec { + public SetOnInsertOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, SetOnInsertOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + var model = operator.model(); + var mapper = datastore.getMapper(); + operator.insertValues().forEach((key, value) -> { + PathTarget keyTarget = new PathTarget(mapper, model, key, operator.validate()); + namedValue(writer, datastore, keyTarget.translatedPath(), value, encoderContext); + }); + }); + }); + } + + @Override + public Class getEncoderClass() { + return SetOnInsertOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/updates/UpdateOperatorCodec.java b/core/src/main/java/dev/morphia/mapping/codec/updates/UpdateOperatorCodec.java new file mode 100644 index 00000000000..de3bb3ae0e6 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/updates/UpdateOperatorCodec.java @@ -0,0 +1,42 @@ +package dev.morphia.mapping.codec.updates; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.aggregation.expressions.impls.DocumentExpression; +import dev.morphia.aggregation.expressions.impls.Expression; +import dev.morphia.query.updates.UpdateOperator; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.namedValue; +import static dev.morphia.mapping.codec.CodecHelper.unnamedValue; + +public class UpdateOperatorCodec extends BaseOperatorCodec { + public UpdateOperatorCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, UpdateOperator operator, EncoderContext encoderContext) { + document(writer, () -> { + document(writer, operator.operator(), () -> { + Object value = operator.value(); + if (value instanceof DocumentExpression) { + namedValue(writer, datastore, operator.field(), value, encoderContext); + } else if (value instanceof Expression) { + document(writer, operator.field(), () -> { + unnamedValue(writer, datastore, value, encoderContext); + }); + } else { + namedValue(writer, datastore, operator.field(), value, encoderContext); + } + }); + }); + } + + @Override + public Class getEncoderClass() { + return UpdateOperator.class; + } +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/writer/DocumentWriter.java b/core/src/main/java/dev/morphia/mapping/codec/writer/DocumentWriter.java index 49a0e5980f4..cf24df61b5a 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/writer/DocumentWriter.java +++ b/core/src/main/java/dev/morphia/mapping/codec/writer/DocumentWriter.java @@ -3,6 +3,8 @@ import java.time.Instant; import java.time.LocalDateTime; +import com.mongodb.lang.Nullable; + import dev.morphia.annotations.internal.MorphiaInternal; import dev.morphia.config.MorphiaConfig; import dev.morphia.mapping.Mapper; @@ -54,7 +56,7 @@ public DocumentWriter(MorphiaConfig config) { * @param config * @param seed the seed Document */ - public DocumentWriter(MorphiaConfig config, Document seed) { + public DocumentWriter(MorphiaConfig config, @Nullable Document seed) { root = new RootState(this, seed); this.config = config; state = root; diff --git a/core/src/main/java/dev/morphia/mapping/codec/writer/RootState.java b/core/src/main/java/dev/morphia/mapping/codec/writer/RootState.java index c7205b1071b..5fd86e87e03 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/writer/RootState.java +++ b/core/src/main/java/dev/morphia/mapping/codec/writer/RootState.java @@ -1,11 +1,14 @@ package dev.morphia.mapping.codec.writer; +import com.mongodb.lang.Nullable; + import dev.morphia.mapping.codec.writer.DocumentState.MergingDocument; import org.bson.Document; class RootState extends WriteState { + @Nullable private Document seed; private DocumentState documentState; @@ -13,7 +16,7 @@ class RootState extends WriteState { super(writer, null); } - RootState(DocumentWriter writer, Document seed) { + RootState(DocumentWriter writer, @Nullable Document seed) { super(writer, null); this.seed = seed; } diff --git a/core/src/main/java/dev/morphia/mapping/conventions/MorphiaDefaultsConvention.java b/core/src/main/java/dev/morphia/mapping/conventions/MorphiaDefaultsConvention.java index 3ea0eb954d6..5fa1f353731 100644 --- a/core/src/main/java/dev/morphia/mapping/conventions/MorphiaDefaultsConvention.java +++ b/core/src/main/java/dev/morphia/mapping/conventions/MorphiaDefaultsConvention.java @@ -18,7 +18,7 @@ public class MorphiaDefaultsConvention implements MorphiaConvention { public void apply(Mapper mapper, EntityModel model) { MorphiaConfig config = mapper.getConfig(); - final Entity entity = model.getAnnotation(Entity.class); + Entity entity = model.getAnnotation(Entity.class); final ExternalEntity externalEntity = model.getAnnotation(ExternalEntity.class); if (entity != null) { model.discriminatorEnabled(entity.useDiscriminator()); @@ -26,20 +26,21 @@ public void apply(Mapper mapper, EntityModel model) { } else if (externalEntity != null) { model.discriminatorEnabled(externalEntity.useDiscriminator()); model.discriminatorKey(applyDefaults(externalEntity.discriminatorKey(), config.discriminatorKey())); - model.annotation(EntityBuilder.entityBuilder() + entity = EntityBuilder.entityBuilder() .cap(externalEntity.cap()) .concern(externalEntity.concern()) .discriminator(externalEntity.discriminator()) .discriminatorKey(externalEntity.discriminatorKey()) .value(externalEntity.value()) .useDiscriminator(externalEntity.useDiscriminator()) - .build()); + .build(); + model.annotation(entity); } - config.discriminator().apply(model); + model.discriminator(config.discriminator().apply(model.getType(), entity.discriminator())); } - String applyDefaults(String configured, String defaultValue) { + public static String applyDefaults(String configured, String defaultValue) { if (!configured.equals(Mapper.IGNORED_FIELDNAME)) { return configured; } else { diff --git a/core/src/main/java/dev/morphia/query/FindOptions.java b/core/src/main/java/dev/morphia/query/FindOptions.java index fd674a521c9..6ea1326cc58 100644 --- a/core/src/main/java/dev/morphia/query/FindOptions.java +++ b/core/src/main/java/dev/morphia/query/FindOptions.java @@ -10,6 +10,7 @@ import com.mongodb.ReadPreference; import com.mongodb.assertions.Assertions; import com.mongodb.client.FindIterable; +import com.mongodb.client.cursor.TimeoutMode; import com.mongodb.client.model.Collation; import dev.morphia.annotations.internal.MorphiaInternal; @@ -41,28 +42,54 @@ public final class FindOptions implements ReadConfigurable, CollectionConfigurable { private Boolean allowDiskUse; private int batchSize; - private int limit; - private long maxTimeMS; - private long maxAwaitTimeMS; - private int skip; - private Document variables; - private Document sort; - private CursorType cursorType; - private boolean noCursorTimeout; - private boolean partial; + private Collation collation; + + private String collection; + private BsonValue comment; + + private CursorType cursorType; + + private boolean disableValidation = false; + private Document hint; + private String hintString; + + private int limit; + private Document max; + + private long maxAwaitTimeMS; + + private long maxTimeMS; + private Document min; - private boolean returnKey; - private boolean showRecordId; - private ReadConcern readConcern; - private ReadPreference readPreference; + + private boolean noCursorTimeout; + + private boolean partial; + private Projection projection; + private String queryLogId; - private String collection; + + private ReadConcern readConcern; + + private ReadPreference readPreference; + + private boolean returnKey; + + private boolean showRecordId; + + private int skip; + + private Document sort; + + private TimeoutMode timeoutMode; + + private Document variables; /** * Enables writing to temporary files on the server. When set to true, the server @@ -92,6 +119,7 @@ public FindIterable apply(FindIterable iterable, Mapper mapper, Class< logQuery(); // reset to a new ID } if (projection != null) { + projection.disableValidation(disableValidation); iterable.projection(projection.map(mapper, type)); } @@ -129,10 +157,47 @@ public FindIterable apply(FindIterable iterable, Mapper mapper, Class< } iterable.sort(mapped); } - tryInvoke(v4_6_0, () -> iterable.let(variables)); + iterable.let(variables); + if (timeoutMode != null) { + iterable.timeoutMode(timeoutMode); + } return iterable; } + /** + * This is an internal method. It's implementation and presence are subject to change. + * + * @return this + * @hidden + * @morphia.internal + */ + @MorphiaInternal + public boolean isLogQuery() { + return queryLogId != null; + } + + /** + * This is an experimental method. It's implementation and presence are subject to change. + * + * @return this + */ + public FindOptions logQuery() { + queryLogId = new ObjectId().toString(); + comment(Sofia.loggedQuery(queryLogId)); + return this; + } + + /** + * Sets the comment to log with the query + * + * @param comment the comment + * @return this + */ + public FindOptions comment(String comment) { + this.comment = new BsonString(comment); + return this; + } + /** * Sets the batch size * @@ -171,17 +236,6 @@ public String collection() { return collection; } - /** - * Sets the comment to log with the query - * - * @param comment the comment - * @return this - */ - public FindOptions comment(String comment) { - this.comment = new BsonString(comment); - return this; - } - /** * Sets the comment to log with the query * @@ -251,6 +305,16 @@ public FindOptions cursorType(CursorType cursorType) { return this; } + /** + * @param disable + * @hidden + * @morphia.internal + */ + @MorphiaInternal + public void disableValidation(boolean disable) { + this.disableValidation = disable; + } + /** * @hidden * @morphia.internal @@ -288,6 +352,37 @@ public boolean equals(Object o) { && Objects.equals(queryLogId, that.queryLogId); } + /** + * @hidden + * @morphia.internal + */ + @MorphiaInternal + @Override + public String toString() { + return new StringJoiner(", ", FindOptions.class.getSimpleName() + "[", "]") + .add("allowDiskUse=" + allowDiskUse) + .add("batchSize=" + batchSize) + .add("limit=" + limit) + .add("maxTimeMS=" + maxTimeMS) + .add("maxAwaitTimeMS=" + maxAwaitTimeMS) + .add("skip=" + skip) + .add("sort=" + sort) + .add("cursorType=" + cursorType) + .add("noCursorTimeout=" + noCursorTimeout) + .add("partial=" + partial) + .add("collation=" + collation) + .add("comment='" + comment + "'") + .add("hint=" + hint) + .add("max=" + max) + .add("min=" + min) + .add("returnKey=" + returnKey) + .add("showRecordId=" + showRecordId) + .add("readPreference=" + readPreference) + .add("queryLogId='" + queryLogId + "'") + .add("projection=" + projection) + .toString(); + } + /** * Sets the index hint * @@ -321,18 +416,6 @@ public FindOptions hintString(String hint) { return this; } - /** - * This is an internal method. It's implementation and presence are subject to change. - * - * @return this - * @hidden - * @morphia.internal - */ - @MorphiaInternal - public boolean isLogQuery() { - return queryLogId != null; - } - /** * Add top-level variables to the operation. A null value means no variables are set. * @@ -349,16 +432,6 @@ public FindOptions let(Document variables) { return this; } - /** - * @return the query log id used for retrieving the logged query - * @hidden - * @morphia.internal - */ - @MorphiaInternal - public String queryLogId() { - return queryLogId; - } - /** * Sets the limit * @@ -370,17 +443,6 @@ public FindOptions limit(int limit) { return this; } - /** - * This is an experimental method. It's implementation and presence are subject to change. - * - * @return this - */ - public FindOptions logQuery() { - queryLogId = new ObjectId().toString(); - comment(Sofia.loggedQuery(queryLogId)); - return this; - } - /** * Sets the max index value * @@ -466,16 +528,13 @@ public FindOptions partial(boolean partial) { } /** - * @return the projection + * @return the query log id used for retrieving the logged query * @hidden * @morphia.internal */ @MorphiaInternal - public Projection projection() { - if (projection == null) { - projection = new Projection(this); - } - return projection; + public String queryLogId() { + return queryLogId; } /** @@ -544,46 +603,39 @@ public FindOptions skip(int skip) { } /** + * Sets to the sort to use + * + * @param meta the meta data to sort by + * @return this + * @since 2.0 + */ + public FindOptions sort(Meta meta) { + projection().project(meta); + return sort(meta.toDatabase()); + } + + /** + * @return the projection * @hidden * @morphia.internal */ @MorphiaInternal - @Override - public String toString() { - return new StringJoiner(", ", FindOptions.class.getSimpleName() + "[", "]") - .add("allowDiskUse=" + allowDiskUse) - .add("batchSize=" + batchSize) - .add("limit=" + limit) - .add("maxTimeMS=" + maxTimeMS) - .add("maxAwaitTimeMS=" + maxAwaitTimeMS) - .add("skip=" + skip) - .add("sort=" + sort) - .add("cursorType=" + cursorType) - .add("noCursorTimeout=" + noCursorTimeout) - .add("partial=" + partial) - .add("collation=" + collation) - .add("comment='" + comment + "'") - .add("hint=" + hint) - .add("max=" + max) - .add("min=" + min) - .add("returnKey=" + returnKey) - .add("showRecordId=" + showRecordId) - .add("readPreference=" + readPreference) - .add("queryLogId='" + queryLogId + "'") - .add("projection=" + projection) - .toString(); + public Projection projection() { + if (projection == null) { + projection = new Projection(this); + } + return projection; } /** * Sets to the sort to use * - * @param meta the meta data to sort by + * @param sort the sort document * @return this - * @since 2.0 */ - public FindOptions sort(Meta meta) { - projection().project(meta); - return sort(meta.toDatabase()); + public FindOptions sort(Document sort) { + this.sort = new Document(sort); + return this; } /** @@ -604,17 +656,6 @@ public FindOptions sort(Meta meta, Sort... sorts) { return this; } - /** - * Sets to the sort to use - * - * @param sort the sort document - * @return this - */ - public FindOptions sort(Document sort) { - this.sort = new Document(sort); - return this; - } - /** * Sets to the sort to use * @@ -629,4 +670,13 @@ public FindOptions sort(Sort... sorts) { return this; } + public TimeoutMode timeoutMode() { + return timeoutMode; + } + + public FindOptions timeoutMode(TimeoutMode timeoutMode) { + this.timeoutMode = timeoutMode; + return this; + } + } diff --git a/core/src/main/java/dev/morphia/query/MorphiaQuery.java b/core/src/main/java/dev/morphia/query/MorphiaQuery.java index aaca5beff3e..8a1a8f485bf 100644 --- a/core/src/main/java/dev/morphia/query/MorphiaQuery.java +++ b/core/src/main/java/dev/morphia/query/MorphiaQuery.java @@ -194,7 +194,7 @@ public Class getEntityClass() { public T modify(ModifyOptions options, UpdateOperator first, UpdateOperator... updates) { EntityModel entityModel = mapper.getEntityModel(getEntityClass()); - Operations value = new Operations(entityModel, coalesce(first, updates), validate); + Operations value = new Operations(datastore, entityModel, coalesce(first, updates), validate); return datastore.operations().findOneAndUpdate(datastore.configureCollection(options, collection), toDocument(), value.toDocument(datastore), options); @@ -206,8 +206,8 @@ public boolean isValidate() { } @Override - public MorphiaCursor iterator(FindOptions options) { - return new MorphiaCursor<>(prepareCursor(options, collection)); + public MorphiaCursor iterator(@Nullable FindOptions options) { + return new MorphiaCursor<>(prepareCursor(options != null ? options : new FindOptions(), collection)); } /** @@ -227,9 +227,10 @@ public UpdateResult update(UpdateOptions options, UpdateOperator first, UpdateOp if (invalid != null) { throw invalid; } - EntityModel entityModel = mapper.getEntityModel(getEntityClass()); - Document updateOperations = new Operations(entityModel, coalesce(first, updates), isValidate()) - .toDocument(datastore); + Class entityClass = getEntityClass(); + EntityModel entityModel = !entityClass.equals(Document.class) ? mapper.getEntityModel(entityClass) : null; + Operations operations = new Operations(datastore, entityModel, coalesce(first, updates), isValidate()); + Document updateOperations = operations.toDocument(datastore); final Document queryObject = toDocument(); if (options.isUpsert()) { @@ -317,6 +318,7 @@ private MongoCursor prepareCursor(FindOptions options, MongoCollection if (options.isLogQuery()) { oldProfile = datastore.getDatabase().runCommand(new Document("profile", 2).append("slowms", 0)); } + options.disableValidation(!isValidate()); try { return options .apply(iterable(options, collection), mapper, type) diff --git a/core/src/main/java/dev/morphia/query/OperationTarget.java b/core/src/main/java/dev/morphia/query/OperationTarget.java index b8079015e87..4addb51a13b 100644 --- a/core/src/main/java/dev/morphia/query/OperationTarget.java +++ b/core/src/main/java/dev/morphia/query/OperationTarget.java @@ -22,6 +22,7 @@ * @hidden * @morphia.internal */ +@Deprecated(forRemoval = true) @MorphiaInternal public class OperationTarget { private final PathTarget target; diff --git a/core/src/main/java/dev/morphia/query/Operations.java b/core/src/main/java/dev/morphia/query/Operations.java index fa4c62627be..5abf522aaed 100644 --- a/core/src/main/java/dev/morphia/query/Operations.java +++ b/core/src/main/java/dev/morphia/query/Operations.java @@ -1,20 +1,22 @@ package dev.morphia.query; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.StringJoiner; + +import com.mongodb.lang.Nullable; import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; import dev.morphia.mapping.codec.pojo.EntityModel; import dev.morphia.mapping.codec.pojo.PropertyModel; +import dev.morphia.mapping.codec.writer.DocumentWriter; import dev.morphia.query.updates.UpdateOperator; import org.bson.Document; +import org.bson.codecs.Codec; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.query.updates.UpdateOperators.inc; /** * @morphia.internal @@ -22,98 +24,72 @@ */ @MorphiaInternal public class Operations { - private final Map> ops = new HashMap<>(); + private final MorphiaDatastore datastore; - private final EntityModel model; - private final List updates; private final boolean validate; + private final EntityModel model; + private final List updates = new ArrayList<>(); + /** * @param model the entity model * @param updates the updates * @param validate validate or not */ - public Operations(EntityModel model, List updates, boolean validate) { - this.model = model; - this.updates = updates; + public Operations(MorphiaDatastore datastore, @Nullable EntityModel model, List updates, boolean validate) { + this.datastore = datastore; this.validate = validate; + this.model = model; + updates.forEach(this::add); } - @Override - public String toString() { - return new StringJoiner(", ", Operations.class.getSimpleName() + "[", "]") - .add("ops=" + ops) - .toString(); + private void add(UpdateOperator update) { + update.validate(validate); + update.model(model); + update.datastore(datastore); + updates.add(update); } - private void versionUpdate(MorphiaDatastore datastore, EntityModel entityModel) { - PropertyModel versionField = entityModel.getVersionProperty(); - if (versionField != null) { - List operationTargets = ops.get("$inc"); - String version = versionField.getMappedName(); - boolean already = operationTargets != null - && operationTargets.stream() - .anyMatch(tv -> { - PathTarget target = tv.getTarget(); - return target != null && target.translatedPath().equals(version); - }); - if (!already) { - add("$inc", new OperationTarget(new PathTarget(datastore.getMapper(), entityModel, versionField.getName()), 1L)); + private void versionUpdate(@Nullable EntityModel entityModel) { + if (entityModel != null) { + PropertyModel versionField = entityModel.getVersionProperty(); + if (versionField != null) { + String version = versionField.getMappedName(); + boolean already = updates.stream() + .filter(f -> f.operator().equals("$inc")) + .anyMatch(f -> f.field().equals(version)); + if (!already) { + add(inc(version)); + } } } } - /** - * Add an operator - * - * @param operator the operator - * @param value the value - */ - private void add(String operator, OperationTarget value) { - ops.computeIfAbsent(operator, o -> new ArrayList<>()).add(value); - } - - // Document toDocument(MorphiaDatastore datastore) { - // return toDocument(); - /* - */ - // } - - /** - * @param datastore the datastore - * @return the Document form of this instance - */ public Document toDocument(MorphiaDatastore datastore) { - /* - * maybe i'll come back to the codec solution - * DocumentWriter writer = new DocumentWriter(datastore.getMapper().getConfig()); - * datastore.getCodecRegistry() - * .get(Operations.class) - * .encode(writer, this, - * EncoderContext.builder().build()); - * return writer.getDocument(); - * - */ - versionUpdate(datastore, model); + var document = new Document(); + versionUpdate(model); for (UpdateOperator update : updates) { - add(update.operator(), update.toOperationTarget(datastore, model, validate)); - } - Document document = new Document(); - for (Entry> entry : ops.entrySet()) { - Document targets = new Document(); - for (OperationTarget operationTarget : entry.getValue()) { - Object encode = operationTarget.encode(datastore); - if (encode instanceof Document) { - targets.putAll((Document) encode); + Document encoded = encode(datastore, update); + encoded.forEach((key, value) -> { + if (!document.containsKey(key)) { + document.putAll(encoded); } else { - document.put(entry.getKey(), encode); + Document o = (Document) document.get(key); + o.putAll((Document) encoded.get(key)); } - } - if (!targets.isEmpty()) { - document.put(entry.getKey(), targets); - } + }); } + return document; } + @SuppressWarnings({ "unchecked", "rawtypes" }) + private Document encode(MorphiaDatastore datastore, UpdateOperator update) { + var codecRegistry = datastore.getCodecRegistry(); + var writer = new DocumentWriter(datastore.getMapper().getConfig()); + ((Codec) codecRegistry.get(update.getClass())) + .encode(writer, update, EncoderContext.builder().build()); + return writer.getDocument(); + } + } diff --git a/core/src/main/java/dev/morphia/query/Projection.java b/core/src/main/java/dev/morphia/query/Projection.java index 710227a5e69..681ee560942 100644 --- a/core/src/main/java/dev/morphia/query/Projection.java +++ b/core/src/main/java/dev/morphia/query/Projection.java @@ -7,9 +7,9 @@ import com.mongodb.lang.Nullable; import dev.morphia.annotations.Entity; +import dev.morphia.annotations.internal.MorphiaInternal; import dev.morphia.internal.PathTarget; import dev.morphia.mapping.Mapper; -import dev.morphia.mapping.codec.pojo.EntityModel; import dev.morphia.sofia.Sofia; import org.bson.Document; @@ -19,6 +19,9 @@ */ public class Projection { private final FindOptions options; + + private boolean disableValidation; + private List includes; private List excludes; private String arrayField; @@ -30,6 +33,17 @@ public class Projection { this.options = options; } + /** + * @param disableValidation + * @hidden + * @morphia.internal + */ + @MorphiaInternal + public void disableValidation(boolean disableValidation) { + + this.disableValidation = disableValidation; + } + /** * Adds a field to the projection clause. The _id field is always included unless explicitly suppressed. * @@ -112,7 +126,8 @@ private void iterate(Mapper mapper, Document projection, Class clazz, @Nullab int include) { if (fields != null) { for (String field : fields) { - projection.put(new PathTarget(mapper, mapper.getEntityModel(clazz), field).translatedPath(), include); + String key = disableValidation ? field : new PathTarget(mapper, mapper.getEntityModel(clazz), field).translatedPath(); + projection.put(key, include); } } } @@ -137,8 +152,10 @@ private Document project(Mapper mapper, Class clazz) { iterate(mapper, projection, clazz, includes, 1); iterate(mapper, projection, clazz, excludes, 0); - final EntityModel model = mapper.getEntityModel(clazz); - Entity entityAnnotation = model.getEntityAnnotation(); + Entity entityAnnotation = null; + if (!clazz.equals(Document.class)) { + entityAnnotation = mapper.getEntityModel(clazz).getEntityAnnotation(); + } if (isIncluding() && entityAnnotation != null && entityAnnotation.useDiscriminator()) { projection.put(mapper.getConfig().discriminatorKey(), 1); @@ -148,7 +165,9 @@ private Document project(Mapper mapper, Class clazz) { } private Document slice(Mapper mapper, Class clazz) { - String fieldName = new PathTarget(mapper, mapper.getEntityModel(clazz), arrayField).translatedPath(); + String fieldName = disableValidation + ? arrayField + : new PathTarget(mapper, mapper.getEntityModel(clazz), arrayField).translatedPath(); return new Document(fieldName, slice.toDatabase()); } diff --git a/core/src/main/java/dev/morphia/query/Query.java b/core/src/main/java/dev/morphia/query/Query.java index befe9a9e182..778d05429f8 100644 --- a/core/src/main/java/dev/morphia/query/Query.java +++ b/core/src/main/java/dev/morphia/query/Query.java @@ -195,9 +195,7 @@ default T modify(UpdateOperator first, UpdateOperator... updates) { * @since 2.3 */ @Nullable - default T modify(ModifyOptions options, UpdateOperator first, UpdateOperator... updates) { - throw new UnsupportedOperationException(); - } + T modify(ModifyOptions options, UpdateOperator first, UpdateOperator... updates); /** * Execute the query and get the results. @@ -206,7 +204,7 @@ default T modify(ModifyOptions options, UpdateOperator first, UpdateOperator... * @return a MorphiaCursor * @since 2.0 */ - MorphiaCursor iterator(FindOptions options); + MorphiaCursor iterator(@Nullable FindOptions options); /** * Provides a {@link Stream} representation of the results of this query. diff --git a/core/src/main/java/dev/morphia/query/Type.java b/core/src/main/java/dev/morphia/query/Type.java index 7881dba0671..c19d5012bb7 100644 --- a/core/src/main/java/dev/morphia/query/Type.java +++ b/core/src/main/java/dev/morphia/query/Type.java @@ -60,6 +60,11 @@ public enum Type { */ REGULAR_EXPRESSION(11), + /** + * DBPointer + */ + DB_POINTER(12), + /** * javascript */ @@ -90,6 +95,11 @@ public enum Type { */ INTEGER_64_BIT(18), + /** + * Decimal128 + */ + DECIMAL_128(19), + /** * minKey */ diff --git a/core/src/main/java/dev/morphia/query/filters/CommentFilter.java b/core/src/main/java/dev/morphia/query/filters/CommentFilter.java new file mode 100644 index 00000000000..7c968bb0c7a --- /dev/null +++ b/core/src/main/java/dev/morphia/query/filters/CommentFilter.java @@ -0,0 +1,14 @@ +package dev.morphia.query.filters; + +public class CommentFilter extends Filter { + private final String comment; + + public CommentFilter(String comment) { + super("$comment"); + this.comment = comment; + } + + public String comment() { + return comment; + } +} diff --git a/core/src/main/java/dev/morphia/query/filters/ElemMatchFilter.java b/core/src/main/java/dev/morphia/query/filters/ElemMatchFilter.java index 951e9c42765..3744de79d60 100644 --- a/core/src/main/java/dev/morphia/query/filters/ElemMatchFilter.java +++ b/core/src/main/java/dev/morphia/query/filters/ElemMatchFilter.java @@ -10,6 +10,15 @@ */ @MorphiaInternal public class ElemMatchFilter extends Filter { + /** + * @hidden + * @morphia.internal + */ + @MorphiaInternal + ElemMatchFilter(List query) { + super("$elemMatch", null, query); + } + /** * @hidden * @morphia.internal diff --git a/core/src/main/java/dev/morphia/query/filters/Filter.java b/core/src/main/java/dev/morphia/query/filters/Filter.java index 1ae8294c2b6..6dca4062c3b 100644 --- a/core/src/main/java/dev/morphia/query/filters/Filter.java +++ b/core/src/main/java/dev/morphia/query/filters/Filter.java @@ -25,12 +25,14 @@ @SuppressWarnings({ "unchecked", "rawtypes" }) public class Filter { private final String name; + @Nullable private String field; @Nullable private Object value; private boolean not; private boolean validate; private Class entityClass; + @Nullable private PathTarget pathTarget; private boolean mapped; @@ -104,6 +106,7 @@ public Filter not() { * @hidden * @morphia.internal */ + @Nullable @MorphiaInternal public String getName() { return name; diff --git a/core/src/main/java/dev/morphia/query/filters/Filters.java b/core/src/main/java/dev/morphia/query/filters/Filters.java index c1292d92932..564270213e0 100644 --- a/core/src/main/java/dev/morphia/query/filters/Filters.java +++ b/core/src/main/java/dev/morphia/query/filters/Filters.java @@ -51,49 +51,27 @@ public static Filter and(Filter... filters) { /** * Matches numeric or binary values in which a set of bit positions all have a value of 0. * - * @param field the field to check - * @param positions the value to check - * @return the filter - * @query.filter $bitsAllClear - */ - public static Filter bitsAllClear(String field, int[] positions) { - return new Filter("$bitsAllClear", field, positions); - } - - /** - * Matches numeric or binary values in which a set of bit positions all have a value of 0. - * - * @param field the field to check - * @param bitMask the numeric bitmask to use + * @param field the field to check + * @param val the value to check * @return the filter * @query.filter $bitsAllClear + * @since 3.0 changed to take a plain Object instead of overloading */ - public static Filter bitsAllClear(String field, int bitMask) { - return new Filter("$bitsAllClear", field, bitMask); + public static Filter bitsAllClear(String field, Object val) { + return new Filter("$bitsAllClear", field, val); } /** * Matches numeric or binary values in which a set of bit positions all have a value of 1. * - * @param field the field to check - * @param bitMask the numeric bitmask to use - * @return the filter - * @query.filter $bitsAllSet - */ - public static Filter bitsAllSet(String field, int bitMask) { - return new Filter("$bitsAllSet", field, bitMask); - } - - /** - * Matches numeric or binary values in which a set of bit positions all have a value of 1. - * - * @param field the field to check - * @param positions the value to check + * @param field the field to check + * @param val the value to check * @return the filter * @query.filter $bitsAllSet + * @since 3.0 changed to take a plain Object instead of overloading */ - public static Filter bitsAllSet(String field, int[] positions) { - return new Filter("$bitsAllSet", field, positions); + public static Filter bitsAllSet(String field, Object val) { + return new Filter("$bitsAllSet", field, val); } /** @@ -170,13 +148,23 @@ public static Filter centerSphere(String field, Point center, double radius) { /** * Adds a comment to a query predicate. * - * @param field the field to check - * @param val the value to check + * @param comment the comment to attach * @return the filter * @query.filter $comment */ - public static Filter comment(String field, Object val) { - return new Filter("$comment", field, val); + public static Filter comment(String comment) { + return new CommentFilter(comment); + } + + /** + * Selects documents if a value in the results matches all the specified $elemMatch conditions. + * + * @param filters the filters to evaluate against + * @return the filter + * @query.filter $elemMatch + */ + public static Filter elemMatch(Filter... filters) { + return new ElemMatchFilter(asList(filters)); } /** @@ -273,6 +261,17 @@ public static Filter geometry(String field, Object val) { return new Filter("$geometry", field, val); } + /** + * $gt selects those documents where the value is greater than the specified value. + * + * @param val the value to check + * @return the filter + * @query.filter $gt + */ + public static Filter gt(Object val) { + return new Filter("$gt", null, val); + } + /** * $gt selects those documents where the value of the field is greater than the specified value. * @@ -286,7 +285,7 @@ public static Filter gt(String field, Object val) { } /** - * $gte selects the documents where the value of the field is greater than or equal to a specified value (e.g. value.) + * $gte selects the documents where the value of the field is greater than or equal to a specified value * * @param field the field to check * @param val the value to check @@ -297,6 +296,18 @@ public static Filter gte(String field, Object val) { return new Filter("$gte", field, val); } + /** + * $gte selects the documents where the value of the target field is greater than or equal to a specified value + * + * @param val the value to check + * @return the filter + * @query.filter $gte + * @since 3.0 + */ + public static Filter gte(Object val) { + return new Filter("$gte", null, val); + } + /** * The $in operator selects the documents where the value of a field equals any value in the specified array. * @@ -309,6 +320,18 @@ public static Filter in(String field, Iterable val) { return new Filter("$in", field, val); } + /** + * The $in operator selects the documents where the value of a field equals any value in a given array. + * + * @param val the values to check + * @return the filter + * @query.filter $in + * @since 3.0 + */ + public static Filter in(Iterable val) { + return new Filter("$in", null, val); + } + /** * Filters documents against the given JSON Schema. * @@ -321,6 +344,18 @@ public static Filter jsonSchema(Document schema) { return new JsonSchemaFilter(schema); } + /** + * $lt selects the documents where the value of the field is less than the specified value. + * + * @param val the value to check + * @return the filter + * @query.filter $lt + * @since 3.0 + */ + public static Filter lt(Object val) { + return new Filter("$lt", null, val); + } + /** * $lt selects the documents where the value of the field is less than the specified value. * @@ -333,6 +368,17 @@ public static Filter lt(String field, Object val) { return new Filter("$lt", field, val); } + /** + * $lte selects the documents where the value is less than or equal to the specified value. + * + * @param val the value to check + * @return the filter + * @query.filter $lte + */ + public static Filter lte(Object val) { + return new Filter("$lte", null, val); + } + /** * $lte selects the documents where the value of the field is less than or equal to the specified value. * @@ -382,6 +428,20 @@ public static Filter mod(String field, long divisor, long remainder) { return new ModFilter(field, divisor, remainder); } + /** + * Performs a modulo operation on the value of a field and selects documents with a specified result. + * + * @param field the field to check + * @param divisor the value to divide by + * @param remainder the remainder to check for + * @return the filter + * @query.filter $mod + * @since 3.0 + */ + public static Filter mod(String field, double divisor, double remainder) { + return new ModFilter(field, divisor, remainder); + } + /** * $ne selects the documents where the value of the field is not equal to the specified value. This includes documents that do not * contain the field. @@ -483,10 +543,11 @@ public static Filter polygon(String field, Point... points) { * @param pattern the regex pattern * @return the filter * @query.filter $regex + * @mongodb.server.release 1.9.0 * @since 2.4.0 */ public static RegexFilter regex(String field, String pattern) { - return new RegexFilter(field, pattern); + return new RegexFilter(field, Pattern.compile(pattern)); } /** @@ -496,10 +557,11 @@ public static RegexFilter regex(String field, String pattern) { * @param pattern the regex pattern * @return the filter * @query.filter $regex + * @mongodb.server.release 1.9.0 * @since 2.4.0 */ public static RegexFilter regex(String field, Pattern pattern) { - return new RegexFilter(field, pattern.pattern()); + return new RegexFilter(field, pattern); } /** @@ -533,8 +595,8 @@ public static TextSearchFilter text(String textSearch) { * @return the filter * @query.filter $type */ - public static Filter type(String field, Type val) { - return new Filter("$type", field, val.toString().toLowerCase()); + public static Filter type(String field, Type... val) { + return new Filter("$type", field, val.length == 1 ? val[0] : val); } /** diff --git a/core/src/main/java/dev/morphia/query/filters/ModFilter.java b/core/src/main/java/dev/morphia/query/filters/ModFilter.java index 8cd60622244..1931969a426 100644 --- a/core/src/main/java/dev/morphia/query/filters/ModFilter.java +++ b/core/src/main/java/dev/morphia/query/filters/ModFilter.java @@ -8,11 +8,11 @@ */ @MorphiaInternal public class ModFilter extends Filter { - private final long divisor; + private final Number divisor; - private final long remainder; + private final Number remainder; - public ModFilter(String field, long divisor, long remainder) { + public ModFilter(String field, Number divisor, Number remainder) { super("$mod", field, null); this.divisor = divisor; this.remainder = remainder; @@ -24,7 +24,7 @@ public ModFilter(String field, long divisor, long remainder) { * @return the divisor */ @MorphiaInternal - public long divisor() { + public Number divisor() { return divisor; } @@ -34,7 +34,7 @@ public long divisor() { * @return the remainder */ @MorphiaInternal - public long remainder() { + public Number remainder() { return remainder; } } diff --git a/core/src/main/java/dev/morphia/query/filters/RegexFilter.java b/core/src/main/java/dev/morphia/query/filters/RegexFilter.java index 94835061386..97df7d718a7 100644 --- a/core/src/main/java/dev/morphia/query/filters/RegexFilter.java +++ b/core/src/main/java/dev/morphia/query/filters/RegexFilter.java @@ -1,9 +1,11 @@ package dev.morphia.query.filters; -import com.mongodb.lang.Nullable; +import java.util.regex.Pattern; import dev.morphia.annotations.internal.MorphiaInternal; +import static dev.morphia.mapping.codec.PatternCodec.RegexFlag.getByCharacter; + /** * Defines a regular expression filter * @@ -11,7 +13,8 @@ */ @SuppressWarnings("unused") public class RegexFilter extends Filter { - private String options; + + Pattern pattern; /** * @param field the field @@ -20,8 +23,16 @@ public class RegexFilter extends Filter { * @morphia.internal */ @MorphiaInternal - RegexFilter(String field, @Nullable String pattern) { - super("$regex", field, pattern); + RegexFilter(String field, Pattern pattern) { + super("$regex", field, null); + this.pattern = pattern; + } + + /** + * @hidden + */ + public Pattern pattern() { + return pattern; } /** @@ -31,7 +42,9 @@ public class RegexFilter extends Filter { * @return this */ public RegexFilter options(String options) { - this.options = options; + for (char c : options.toCharArray()) { + add(c); + } return this; } @@ -41,7 +54,7 @@ public RegexFilter options(String options) { * @return this */ public RegexFilter caseInsensitive() { - add("i"); + add('i'); return this; } @@ -57,7 +70,7 @@ public RegexFilter caseInsensitive() { * @return this */ public RegexFilter extended() { - add("x"); + add('x'); return this; } @@ -68,7 +81,7 @@ public RegexFilter extended() { * @return this */ public RegexFilter multiline() { - add("m"); + add('m'); return this; } @@ -78,26 +91,12 @@ public RegexFilter multiline() { * @return this */ public RegexFilter special() { - add("s"); + add('s'); return this; } - private void add(String option) { - if (options == null) { - options = ""; - } - if (!options.contains(option)) { - options += option; - } - } - - /** - * @hidden - * @morphia.internal - * @return the options - */ - @MorphiaInternal - public String options() { - return options; + private void add(char option) { + pattern = Pattern.compile(pattern.pattern(), + pattern.flags() | getByCharacter(option).javaFlag); } } diff --git a/core/src/main/java/dev/morphia/query/updates/AddToSetOperator.java b/core/src/main/java/dev/morphia/query/updates/AddToSetOperator.java index d8fad2b1943..e820ac4c994 100644 --- a/core/src/main/java/dev/morphia/query/updates/AddToSetOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/AddToSetOperator.java @@ -2,13 +2,7 @@ import java.util.Collection; -import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; -import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.query.OperationTarget; - -import org.bson.Document; /** * Defines the $addToSet operator @@ -18,7 +12,7 @@ * @morphia.internal */ @MorphiaInternal -class AddToSetOperator extends UpdateOperator { +public class AddToSetOperator extends UpdateOperator { private final boolean each; /** @@ -33,15 +27,4 @@ public AddToSetOperator(String field, Object values) { each = values instanceof Collection; } - /** - * @hidden - * @morphia.internal - */ - @MorphiaInternal - @Override - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - var pathTarget = new PathTarget(datastore.getMapper(), model, field(), validate); - return new OperationTarget(pathTarget, each ? new Document("$each", value()) : value()); - } - } diff --git a/core/src/main/java/dev/morphia/query/updates/BitOperator.java b/core/src/main/java/dev/morphia/query/updates/BitOperator.java index 2489e9bff75..51b5b1ae585 100644 --- a/core/src/main/java/dev/morphia/query/updates/BitOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/BitOperator.java @@ -1,14 +1,13 @@ package dev.morphia.query.updates; -import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; -import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.query.OperationTarget; -import org.bson.Document; - -class BitOperator extends UpdateOperator { +/** + * @hidden + * @morphia.internal + */ +@MorphiaInternal +public class BitOperator extends UpdateOperator { private final String operation; BitOperator(String operation, String field, int value) { @@ -16,15 +15,8 @@ class BitOperator extends UpdateOperator { this.operation = operation; } - /** - * @hidden - * @morphia.internal - */ - @MorphiaInternal - @Override - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - var pathTarget = new PathTarget(datastore.getMapper(), model, field(), validate); - return new OperationTarget(pathTarget, new Document(operation, value())); + public String operation() { + return operation; } } diff --git a/core/src/main/java/dev/morphia/query/updates/CurrentDateOperator.java b/core/src/main/java/dev/morphia/query/updates/CurrentDateOperator.java index 88301884598..c9b9e78ed93 100644 --- a/core/src/main/java/dev/morphia/query/updates/CurrentDateOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/CurrentDateOperator.java @@ -1,10 +1,6 @@ package dev.morphia.query.updates; -import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; -import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.query.OperationTarget; import org.bson.Document; @@ -14,7 +10,7 @@ * @since 2.0 */ public class CurrentDateOperator extends UpdateOperator { - private TypeSpecification typeSpec = TypeSpecification.DATE; + private TypeSpecification type = TypeSpecification.DATE; /** * Creates an operator for a field @@ -28,18 +24,6 @@ protected CurrentDateOperator(String field) { super("$currentDate", field, field); } - /** - * @hidden - * @morphia.internal - */ - @MorphiaInternal - @Override - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - var pathTarget = new PathTarget(datastore.getMapper(), model, field(), validate); - - return new OperationTarget(pathTarget, typeSpec.toTarget()); - } - /** * Sets the type of value to set when updating the field * @@ -47,10 +31,19 @@ public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel * @return this */ public CurrentDateOperator type(TypeSpecification type) { - this.typeSpec = type; + this.type = type; return this; } + /** + * @hidden + * @morphia.internal + */ + @MorphiaInternal + public TypeSpecification type() { + return type; + } + /** * The type options when setting the current date */ diff --git a/core/src/main/java/dev/morphia/query/updates/PullOperator.java b/core/src/main/java/dev/morphia/query/updates/PullOperator.java index 2ec69d35dd3..94167f485d7 100644 --- a/core/src/main/java/dev/morphia/query/updates/PullOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/PullOperator.java @@ -1,28 +1,17 @@ package dev.morphia.query.updates; -import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; -import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.mapping.codec.writer.DocumentWriter; -import dev.morphia.query.OperationTarget; import dev.morphia.query.filters.Filter; -import org.bson.Document; -import org.bson.codecs.Codec; -import org.bson.codecs.EncoderContext; -import org.bson.codecs.configuration.CodecRegistry; - -import static dev.morphia.mapping.codec.CodecHelper.document; - /** * Defines an operator for $pull * * @since 2.0 * @morphia.internal + * @hidden */ @MorphiaInternal -class PullOperator extends UpdateOperator { +public class PullOperator extends UpdateOperator { /** * @param field the field * @param filter the filter to apply @@ -30,32 +19,19 @@ class PullOperator extends UpdateOperator { * @morphia.internal */ @MorphiaInternal - public PullOperator(String field, Filter filter) { + public PullOperator(String field, Filter... filter) { super("$pull", field, filter); } /** + * @param field the field + * @param value the value to pull * @hidden * @morphia.internal */ @MorphiaInternal - @Override - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - var pathTarget = new PathTarget(datastore.getMapper(), model, field(), validate); - - return new OperationTarget(pathTarget, value()) { - @Override - public Object encode(MorphiaDatastore datastore) { - DocumentWriter writer = new DocumentWriter(datastore.getMapper().getConfig()); - CodecRegistry registry = datastore.getCodecRegistry(); - document(writer, () -> { - Filter filter = (Filter) getValue(); - Codec codec = registry.get(filter.getClass()); - codec.encode(writer, filter, EncoderContext.builder().build()); - }); - - return new Document(pathTarget.translatedPath(), writer.getDocument()); - } - }; + public PullOperator(String field, Object value) { + super("$pull", field, value instanceof Filter ? new Filter[] { (Filter) value } : value); } + } diff --git a/core/src/main/java/dev/morphia/query/updates/PushOperator.java b/core/src/main/java/dev/morphia/query/updates/PushOperator.java index abf8c0badaa..7719a485acd 100644 --- a/core/src/main/java/dev/morphia/query/updates/PushOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/PushOperator.java @@ -2,13 +2,10 @@ import java.util.List; -import dev.morphia.MorphiaDatastore; +import com.mongodb.lang.Nullable; + import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; -import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.query.OperationTarget; import dev.morphia.query.Sort; -import dev.morphia.query.UpdateException; import dev.morphia.sofia.Sofia; import org.bson.Document; @@ -19,9 +16,13 @@ * @since 2.0 */ public class PushOperator extends UpdateOperator { + @Nullable private Integer position; + @Nullable private Integer slice; + @Nullable private Integer sort; + @Nullable private Document sortDocument; /** @@ -35,6 +36,11 @@ public class PushOperator extends UpdateOperator { super("$push", field, values); } + @Nullable + public Integer position() { + return position; + } + /** * Sets the position for the update * @@ -42,13 +48,15 @@ public class PushOperator extends UpdateOperator { * @return this */ public PushOperator position(int position) { - if (position < 0) { - throw new UpdateException("The position must be at least 0."); - } this.position = position; return this; } + @Nullable + public Integer slice() { + return slice; + } + /** * Sets the slice value for the update * @@ -60,6 +68,11 @@ public PushOperator slice(int slice) { return this; } + @Nullable + public Integer sort() { + return sort; + } + /** * Sets the sort value for the update * @@ -91,28 +104,9 @@ public PushOperator sort(Sort value) { return this; } - /** - * @hidden - * @morphia.internal - */ - @MorphiaInternal - @Override - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - var pathTarget = new PathTarget(datastore.getMapper(), model, field(), validate); - Document document = new Document("$each", value()); - if (position != null) { - document.put("$position", position); - } - if (slice != null) { - document.put("$slice", slice); - } - if (sort != null) { - document.put("$sort", sort); - } - if (sortDocument != null) { - document.put("$sort", sortDocument); - } - - return new OperationTarget(pathTarget, document); + @Nullable + public Document sortDocument() { + return sortDocument; } + } diff --git a/core/src/main/java/dev/morphia/query/updates/SetEntityOperator.java b/core/src/main/java/dev/morphia/query/updates/SetEntityOperator.java index 8744c0adff7..3b4a2212144 100644 --- a/core/src/main/java/dev/morphia/query/updates/SetEntityOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/SetEntityOperator.java @@ -1,23 +1,14 @@ package dev.morphia.query.updates; -import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; -import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.mapping.codec.pojo.PropertyModel; -import dev.morphia.mapping.codec.writer.DocumentWriter; -import dev.morphia.query.OperationTarget; - -import org.bson.Document; -import org.bson.codecs.Codec; -import org.bson.codecs.EncoderContext; /** + * @hidden * @morphia.internal * @since 2.0 */ @MorphiaInternal -class SetEntityOperator extends UpdateOperator { +public class SetEntityOperator extends UpdateOperator { /** * @param value the value * @hidden @@ -28,35 +19,4 @@ public SetEntityOperator(Object value) { super("$set", "", value); } - /** - * @hidden - * @morphia.internal - */ - @MorphiaInternal - @Override - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - var pathTarget = new PathTarget(datastore.getMapper(), model, field(), validate); - - return new OperationTarget(null, value()) { - @Override - @SuppressWarnings("unchecked") - public Object encode(MorphiaDatastore datastore) { - Object value = value(); - EntityModel entityModel = datastore.getMapper().getEntityModel(value.getClass()); - PropertyModel versionProperty = entityModel.getVersionProperty(); - if (versionProperty == null) { - return super.encode(datastore); - } - - Codec codec = datastore.getCodecRegistry().get((Class) value.getClass()); - DocumentWriter writer = new DocumentWriter(datastore.getMapper().getConfig()); - - codec.encode(writer, value, EncoderContext.builder().build()); - - Document document = writer.getDocument(); - document.remove(versionProperty.getMappedName()); - return document; - } - }; - } } diff --git a/core/src/main/java/dev/morphia/query/updates/SetOnInsertOperator.java b/core/src/main/java/dev/morphia/query/updates/SetOnInsertOperator.java index e5dda7087ca..59277257f42 100644 --- a/core/src/main/java/dev/morphia/query/updates/SetOnInsertOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/SetOnInsertOperator.java @@ -3,25 +3,15 @@ import java.util.LinkedHashMap; import java.util.Map; -import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; -import dev.morphia.mapping.Mapper; -import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.mapping.codec.writer.DocumentWriter; -import dev.morphia.query.OperationTarget; - -import org.bson.codecs.Codec; -import org.bson.codecs.EncoderContext; - -import static dev.morphia.mapping.codec.CodecHelper.document; /** * @morphia.internal + * @hidden * @since 2.0 */ @MorphiaInternal -class SetOnInsertOperator extends UpdateOperator { +public class SetOnInsertOperator extends UpdateOperator { private final Map insertValues; /** @@ -40,27 +30,8 @@ public SetOnInsertOperator(Map values) { * @morphia.internal */ @MorphiaInternal - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - var pathTarget = new PathTarget(datastore.getMapper(), model, field(), validate); - - Mapper mapper = pathTarget.mapper(); - DocumentWriter writer = new DocumentWriter(mapper.getConfig()); - document(writer, () -> { - insertValues.forEach((key, value) -> { - PathTarget keyTarget = new PathTarget(mapper, model, key, true); - writer.writeName(keyTarget.translatedPath()); - Codec valueCodec = datastore.getCodecRegistry().get(value.getClass()); - valueCodec.encode(writer, value, EncoderContext.builder().build()); - }); - }); - - return new OperationTarget(null, null) { - @Override - public Object encode(MorphiaDatastore datastore) { - return writer.getDocument(); - } - }; + public Map insertValues() { + return insertValues; } + } diff --git a/core/src/main/java/dev/morphia/query/updates/UnsetOperator.java b/core/src/main/java/dev/morphia/query/updates/UnsetOperator.java index ec7d120fee2..82429c0f2af 100644 --- a/core/src/main/java/dev/morphia/query/updates/UnsetOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/UnsetOperator.java @@ -1,43 +1,25 @@ package dev.morphia.query.updates; -import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; -import dev.morphia.internal.PathTarget; -import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.query.OperationTarget; -import org.bson.Document; +import static dev.morphia.mapping.codec.CodecHelper.coalesce; /** + * @hidden * @morphia.internal * @since 2.0 */ @MorphiaInternal -class UnsetOperator extends UpdateOperator { +public class UnsetOperator extends UpdateOperator { /** - * @param field the field + * @param field the first field + * @param others any other fields * @hidden * @morphia.internal */ @MorphiaInternal - public UnsetOperator(String field) { - super("$unset", field, "unused"); + public UnsetOperator(String field, String[] others) { + super("$unset", "", coalesce(field, others)); } - /** - * @hidden - * @morphia.internal - */ - @MorphiaInternal - @Override - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - var pathTarget = new PathTarget(datastore.getMapper(), model, field(), validate); - - return new OperationTarget(pathTarget, "") { - @Override - public Object encode(MorphiaDatastore datastore) { - return new Document(pathTarget.translatedPath(), ""); - } - }; - } } diff --git a/core/src/main/java/dev/morphia/query/updates/UpdateOperator.java b/core/src/main/java/dev/morphia/query/updates/UpdateOperator.java index c436918b68a..5fdcbc8a5b5 100644 --- a/core/src/main/java/dev/morphia/query/updates/UpdateOperator.java +++ b/core/src/main/java/dev/morphia/query/updates/UpdateOperator.java @@ -2,13 +2,12 @@ import java.util.List; +import com.mongodb.lang.Nullable; + import dev.morphia.MorphiaDatastore; import dev.morphia.annotations.internal.MorphiaInternal; import dev.morphia.internal.PathTarget; import dev.morphia.mapping.codec.pojo.EntityModel; -import dev.morphia.query.OperationTarget; -import dev.morphia.query.UpdateException; -import dev.morphia.sofia.Sofia; /** * Defines an update operator @@ -16,8 +15,17 @@ * @since 2.0 */ public class UpdateOperator { - private final String operator; private final String field; + + private final String operator; + + private MorphiaDatastore datastore = null; + + @Nullable + private EntityModel model; + + private boolean validate; + private Object value; /** @@ -43,14 +51,24 @@ protected UpdateOperator(String operator, String field, Object value) { */ @MorphiaInternal protected UpdateOperator(String operator, String field, List values) { - if (values.isEmpty()) { - throw new UpdateException(Sofia.valuesCannotBeNullOrEmpty()); - } this.operator = operator; this.field = field; this.value = values; } + public MorphiaDatastore datastore() { + return datastore; + } + + public UpdateOperator datastore(MorphiaDatastore datastore) { + this.datastore = datastore; + return this; + } + + public void entityModel(@Nullable EntityModel model) { + this.model = model; + } + /** * @return the field * @hidden @@ -58,9 +76,35 @@ protected UpdateOperator(String operator, String field, List values) { */ @MorphiaInternal public String field() { + if (field != null && !field.equals("")) { + return new PathTarget(datastore.getMapper(), model, field, validate).translatedPath(); + } return field; } + /** + * @hidden + * @morphia.internal + */ + @Nullable + @MorphiaInternal + public EntityModel model() { + return model; + } + + public UpdateOperator model(@Nullable EntityModel model) { + this.model = model; + return this; + } + + @Override + public String toString() { + return "UpdateOperator{" + + "operator='" + operator + '\'' + + ", field='" + field + '\'' + + '}'; + } + /** * @return the operator * @hidden @@ -72,18 +116,22 @@ public String operator() { } /** - * Creates the OperationTarget for serialization - * - * @param datastore the datastore to use - * @param model the entity model - * @param validate if the target path should be validated - * @return the OperationTarget * @hidden * @morphia.internal */ @MorphiaInternal - public OperationTarget toOperationTarget(MorphiaDatastore datastore, EntityModel model, boolean validate) { - return new OperationTarget(new PathTarget(datastore.getMapper(), model, field(), validate), value()); + public boolean validate() { + return model != null && validate; + } + + /** + * @hidden + * @morphia.internal + */ + @MorphiaInternal + public UpdateOperator validate(boolean validate) { + this.validate = validate; + return this; } /** diff --git a/core/src/main/java/dev/morphia/query/updates/UpdateOperators.java b/core/src/main/java/dev/morphia/query/updates/UpdateOperators.java index 001932cc734..1ca5a8c7c9d 100644 --- a/core/src/main/java/dev/morphia/query/updates/UpdateOperators.java +++ b/core/src/main/java/dev/morphia/query/updates/UpdateOperators.java @@ -64,6 +64,20 @@ public static UpdateOperator and(String field, int value) { return new BitOperator("and", field, value); } + /** + * Multiplies the value of the field by the specified amount. + * + * @param field the field to multiply + * @param value the number to multiply by + * @return the update operator + * @update.operator $bit + * @since 3.0 + * @mongodb.server.release 5.0 + */ + public static UpdateOperator bit(String field, Number value) { + return new UpdateOperator("$bit", field, value); + } + /** * The $currentDate operator sets the value of a field to the current date, either as a Date or a timestamp. The default type is Date. * @@ -104,26 +118,26 @@ public static UpdateOperator dec(String field, Number value) { } /** - * Increments the value of the field by one. + * Increments the value of the field by the specified amount. * * @param field the field to increment + * @param value the number to increment by * @return the update operator * @update.operator $inc */ - public static UpdateOperator inc(String field) { - return inc(field, 1); + public static UpdateOperator inc(String field, Number value) { + return new UpdateOperator("$inc", field, value); } /** - * Increments the value of the field by the specified amount. + * Increments the value of the field by one. * * @param field the field to increment - * @param value the number to increment by * @return the update operator * @update.operator $inc */ - public static UpdateOperator inc(String field, Number value) { - return new UpdateOperator("$inc", field, value); + public static UpdateOperator inc(String field) { + return inc(field, 1); } /** @@ -244,13 +258,25 @@ public static PopOperator pop(String field) { /** * The $pull operator removes from an existing array all instances of a value or values that match a specified condition. * - * @param field the field to update - * @param filter the filter to apply + * @param field the field to update + * @param filters the filters to apply + * @return the update operator + * @update.operator $pull + */ + public static UpdateOperator pull(String field, Filter... filters) { + return new PullOperator(field, filters); + } + + /** + * The $pull operator removes from an existing array all instances of a value or values that match a specified condition. + * + * @param field the field to update + * @param value the value to pull * @return the update operator * @update.operator $pull */ - public static UpdateOperator pull(String field, Filter filter) { - return new PullOperator(field, filter); + public static UpdateOperator pull(String field, Object value) { + return new PullOperator(field, value); } /** @@ -345,8 +371,8 @@ public static UpdateOperator setOnInsert(Map values) { * @return the update operator * @update.operator $unset */ - public static UpdateOperator unset(String field) { - return new UnsetOperator(field); + public static UpdateOperator unset(String field, String... others) { + return new UnsetOperator(field, others); } /** diff --git a/core/src/main/java/dev/morphia/transactions/SessionDatastore.java b/core/src/main/java/dev/morphia/transactions/SessionDatastore.java index 13dec49e78a..7be97fa065b 100644 --- a/core/src/main/java/dev/morphia/transactions/SessionDatastore.java +++ b/core/src/main/java/dev/morphia/transactions/SessionDatastore.java @@ -13,6 +13,7 @@ import com.mongodb.client.result.InsertManyResult; import com.mongodb.client.result.InsertOneResult; import com.mongodb.client.result.UpdateResult; +import com.mongodb.internal.TimeoutContext; import com.mongodb.lang.NonNull; import com.mongodb.lang.Nullable; import com.mongodb.session.ServerSession; @@ -44,6 +45,8 @@ public class SessionDatastore extends MorphiaDatastore implements MorphiaSession private final ClientSession session; + private TimeoutContext timeoutContext; + /** * Creates a new session. * @@ -275,6 +278,15 @@ public BsonDocument getClusterTime() { return session.getClusterTime(); } + @Override + public TimeoutContext getTimeoutContext() { + return timeoutContext; + } + + public void setTimeoutContext(TimeoutContext timeoutContext) { + this.timeoutContext = timeoutContext; + } + @Override public void close() { session.close(); diff --git a/core/src/test/java/dev/morphia/test/CoverageTest.java b/core/src/test/java/dev/morphia/test/CoverageTest.java index fbeff11d067..e8767b1c1d0 100644 --- a/core/src/test/java/dev/morphia/test/CoverageTest.java +++ b/core/src/test/java/dev/morphia/test/CoverageTest.java @@ -7,7 +7,6 @@ import java.util.StringJoiner; import dev.morphia.mapping.NamingStrategy; -import dev.morphia.test.aggregation.AggregationTest; import org.testng.annotations.Test; @@ -31,7 +30,7 @@ public void noMissingTestCases() { } private void findMissing(String root, StringJoiner message) { - File path = AggregationTest.rootToCore(root); + File path = TemplatedTestBase.rootToCore(root); try { stream(path.listFiles()) .filter(file -> new File(file, "ignored").exists()) diff --git a/core/src/test/java/dev/morphia/test/DriverVersion.java b/core/src/test/java/dev/morphia/test/DriverVersion.java index 63dcaafe447..5826f16510c 100644 --- a/core/src/test/java/dev/morphia/test/DriverVersion.java +++ b/core/src/test/java/dev/morphia/test/DriverVersion.java @@ -1,6 +1,6 @@ package dev.morphia.test; -import com.github.zafarkhaja.semver.Version; +import org.semver4j.Semver; public enum DriverVersion { ANY(0, 0), @@ -9,7 +9,8 @@ public enum DriverVersion { v43(4, 3), v45(4, 5), v46(4, 6), - v47(4, 7); + v47(4, 7), + v52(5, 2); private final int major; @@ -20,7 +21,7 @@ public enum DriverVersion { this.minor = minor; } - public final Version version() { - return Version.forIntegers(major, minor); + public final Semver version() { + return Semver.of(major, minor, 0); } } diff --git a/core/src/test/java/dev/morphia/test/MongoHolder.java b/core/src/test/java/dev/morphia/test/MongoHolder.java index 45a5bea8f27..d36dab8c7d5 100644 --- a/core/src/test/java/dev/morphia/test/MongoHolder.java +++ b/core/src/test/java/dev/morphia/test/MongoHolder.java @@ -1,6 +1,7 @@ package dev.morphia.test; import com.mongodb.ConnectionString; +import com.mongodb.ServerAddress; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; @@ -40,6 +41,8 @@ public MongoClient getMongoClient() { .applyConnectionString(new ConnectionString(connectionString)) .build()); + ServerAddress serverAddress = mongoClient.getClusterDescription().getClusterSettings().getHosts().get(0); + System.out.println("connection to database on port " + serverAddress.getPort()); } return mongoClient; } diff --git a/core/src/test/java/dev/morphia/test/MorphiaContainer.java b/core/src/test/java/dev/morphia/test/MorphiaContainer.java index 6071044619e..d64e5701653 100644 --- a/core/src/test/java/dev/morphia/test/MorphiaContainer.java +++ b/core/src/test/java/dev/morphia/test/MorphiaContainer.java @@ -1,6 +1,5 @@ package dev.morphia.test; -import com.github.zafarkhaja.semver.Version; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoDatabase; @@ -8,6 +7,7 @@ import dev.morphia.config.MorphiaConfig; import org.bson.Document; +import org.semver4j.Semver; public class MorphiaContainer { private MorphiaDatastore datastore; @@ -29,12 +29,12 @@ public void reset() { datastore = null; } - protected Version getServerVersion() { + protected Semver getServerVersion() { String version = (String) mongoClient .getDatabase("admin") .runCommand(new Document("serverStatus", 1)) .get("version"); - return Version.valueOf(version); + return Semver.parse(version); } public Document runIsMaster() { diff --git a/core/src/test/java/dev/morphia/test/MorphiaTestSetup.java b/core/src/test/java/dev/morphia/test/MorphiaTestSetup.java index a10efd62b0d..9eaad0aa42a 100644 --- a/core/src/test/java/dev/morphia/test/MorphiaTestSetup.java +++ b/core/src/test/java/dev/morphia/test/MorphiaTestSetup.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.stream.Collectors; -import com.github.zafarkhaja.semver.Version; import com.mongodb.client.MongoClient; import dev.morphia.config.MorphiaConfig; @@ -12,6 +11,7 @@ import dev.morphia.test.config.ManualMorphiaTestConfig; import dev.morphia.test.config.MorphiaTestConfig; +import org.semver4j.Semver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.containers.MongoDBContainer; @@ -102,9 +102,9 @@ protected void assumeTrue(boolean condition, String message) { protected void checkMinDriverVersion(DriverVersion version) { String property = System.getProperty("driver.version"); - Version driverVersion = property != null ? Version.valueOf(property) : null; + var driverVersion = property != null ? Semver.parse(property) : null; - assumeTrue(driverVersion == null || driverVersion.greaterThanOrEqualTo(version.version()), + assumeTrue(driverVersion == null || driverVersion.isGreaterThanOrEqualTo(version.version()), format("Server should be at least %s but found %s", version, getServerVersion())); } @@ -117,7 +117,7 @@ protected MongoClient getMongoClient() { return getMongoHolder().getMongoClient(); } - protected Version getServerVersion() { + protected Semver getServerVersion() { return morphiaContainer.getServerVersion(); } @@ -129,8 +129,8 @@ protected boolean isReplicaSet() { * @param version the minimum version allowed * @return true if server is at least specified version */ - protected boolean serverIsAtLeastVersion(Version version) { - return getServerVersion().greaterThanOrEqualTo(version); + protected boolean serverIsAtLeastVersion(Semver version) { + return getServerVersion().isGreaterThanOrEqualTo(version); } protected void withSharding(Runnable body) { diff --git a/core/src/test/java/dev/morphia/test/MorphiaVersionTest.java b/core/src/test/java/dev/morphia/test/MorphiaVersionTest.java index e1e71752d65..c72a0f82bf1 100644 --- a/core/src/test/java/dev/morphia/test/MorphiaVersionTest.java +++ b/core/src/test/java/dev/morphia/test/MorphiaVersionTest.java @@ -1,13 +1,13 @@ package dev.morphia.test; +import java.io.File; import java.io.FileReader; -import com.github.zafarkhaja.semver.Version; - import dev.morphia.MorphiaVersion30; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.semver4j.Semver; import org.testng.annotations.Test; import static java.lang.String.format; @@ -17,10 +17,10 @@ public class MorphiaVersionTest { @Test public void testVersion() throws Exception { MavenXpp3Reader reader = new MavenXpp3Reader(); - Model model = reader.read(new FileReader("../pom.xml")); + Model model = reader.read(new FileReader(new File("../pom.xml").getAbsoluteFile())); - Version version = Version.valueOf(model.getVersion()); - String minorVersion = format("%s%s", version.getMajorVersion(), version.getMinorVersion()); + var version = Semver.parse(model.getVersion()); + String minorVersion = format("%s%s", version.getMajor(), version.getMinor()); //noinspection MisorderedAssertEqualsArguments assertEquals(MorphiaVersion30.class.getSimpleName().replaceAll("\\D", ""), minorVersion); } diff --git a/core/src/test/java/dev/morphia/test/OptionsTest.java b/core/src/test/java/dev/morphia/test/OptionsTest.java index c387df33fc9..795069c3983 100644 --- a/core/src/test/java/dev/morphia/test/OptionsTest.java +++ b/core/src/test/java/dev/morphia/test/OptionsTest.java @@ -4,10 +4,12 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.List; +import java.util.stream.Stream; import com.mongodb.ReadConcern; import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; +import com.mongodb.client.AggregateIterable; import com.mongodb.client.FindIterable; import com.mongodb.client.model.FindOneAndDeleteOptions; import com.mongodb.client.model.FindOneAndUpdateOptions; @@ -23,21 +25,26 @@ import dev.morphia.query.FindAndDeleteOptions; import dev.morphia.query.FindOptions; +import org.bson.BsonValue; import org.bson.Document; import org.bson.conversions.Bson; import org.testng.Assert; import org.testng.annotations.Test; @SuppressWarnings("SameParameterValue") -public class OptionsTest { +public class OptionsTest extends TestBase { @Test public void aggregationOptions() { - beanScan(com.mongodb.AggregationOptions.class, AggregationOptions.class, List.of("builder", + checkMinDriverVersion(DriverVersion.v52); + beanScan(AggregateIterable.class, AggregationOptions.class, List.of("builder", + "explain", "getAllowDiskUse", "getBatchSize", "getBypassDocumentValidation", "getCollation", - "getMaxTime")); + "getMaxTime", + "hintString", + "toCollection")); } @Test @@ -62,6 +69,7 @@ public void findAndModifyOptions() { @Test public void findOptions() { + checkMinDriverVersion(DriverVersion.v52); beanScan(FindIterable.class, FindOptions.class, List.of("explain", "filter", "projection")); } @@ -86,15 +94,19 @@ public void updateOptions() { } private void beanScan(Class driver, Class morphia, List filtered) { - try { - Method[] methods = driver.getDeclaredMethods(); - for (Method method : methods) { - if (!filtered.contains(method.getName()) && method.getAnnotation(Deprecated.class) == null) { + Method[] methods = driver.getDeclaredMethods(); + for (Method method : methods) { + if (!filtered.contains(method.getName()) && method.getAnnotation(Deprecated.class) == null) { + try { morphia.getDeclaredMethod(method.getName(), convert(method.getParameterTypes())); + } catch (ReflectiveOperationException e) { + try { + morphia.getDeclaredMethod(method.getName(), method.getParameterTypes()); + } catch (NoSuchMethodException ex) { + throw new RuntimeException("Method not found: " + e.getMessage(), e); + } } } - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e.getMessage(), e); } } @@ -113,13 +125,41 @@ private void checkOverride(Class driverType, Class morphiaType, Method met } } - private Class[] convert(Class[] types) { - for (int i = 0; i < types.length; i++) { - if (types[i].equals(Bson.class)) { - types[i] = Document.class; - } - } - return types; + @SuppressWarnings("rawtypes") + private Class[] convert(Class[] types) { + List list = Stream.of(types) + .map(type -> { + if (type.equals(Bson.class)) { + return Document.class; + } + if (type.equals(BsonValue.class)) { + return String.class; + } + if (type.equals(Boolean.class)) { + return boolean.class; + } + if (type.equals(Character.class)) { + return char.class; + } + if (type.equals(Byte.class)) { + return byte.class; + } + if (type.equals(Double.class)) { + return double.class; + } + if (type.equals(Float.class)) { + return float.class; + } + if (type.equals(Integer.class)) { + return int.class; + } + if (type.equals(Long.class)) { + return long.class; + } + return type; + }) + .toList(); + return list.toArray(new Class[0]); } private boolean getter(Method method) { diff --git a/core/src/test/java/dev/morphia/test/ServerVersion.java b/core/src/test/java/dev/morphia/test/ServerVersion.java index 9b302d68ed4..139986c0cb5 100644 --- a/core/src/test/java/dev/morphia/test/ServerVersion.java +++ b/core/src/test/java/dev/morphia/test/ServerVersion.java @@ -1,6 +1,6 @@ package dev.morphia.test; -import com.github.zafarkhaja.semver.Version; +import org.semver4j.Semver; public enum ServerVersion { ANY(0, 0), @@ -10,7 +10,8 @@ public enum ServerVersion { v53(5, 3), v60(6, 0), v63(6, 3), - v70(7, 0); + v70(7, 0), + v80(8, 0); private final int major; @@ -21,7 +22,7 @@ public enum ServerVersion { this.minor = minor; } - public final Version version() { - return Version.forIntegers(major, minor); + public final Semver version() { + return Semver.of(major, minor, 0); } } diff --git a/core/src/test/java/dev/morphia/test/TemplatedTestBase.java b/core/src/test/java/dev/morphia/test/TemplatedTestBase.java index be40bc09f11..ae993472397 100644 --- a/core/src/test/java/dev/morphia/test/TemplatedTestBase.java +++ b/core/src/test/java/dev/morphia/test/TemplatedTestBase.java @@ -1,164 +1,169 @@ package dev.morphia.test; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.StringReader; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.function.Function; 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; -import dev.morphia.config.MorphiaConfig; -import dev.morphia.mapping.codec.reader.DocumentReader; import dev.morphia.query.FindOptions; import dev.morphia.query.MorphiaQuery; +import dev.morphia.query.Operations; +import dev.morphia.query.Query; +import dev.morphia.query.updates.UpdateOperator; +import dev.morphia.test.util.ActionTestOptions; import dev.morphia.test.util.Comparanator; import org.bson.BsonInvalidOperationException; import org.bson.Document; -import org.bson.codecs.DecoderContext; import org.bson.json.JsonParseException; import org.bson.json.JsonWriterSettings; import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.annotations.BeforeMethod; +import org.testng.annotations.AfterClass; import org.testng.annotations.Test; +import static dev.morphia.mapping.codec.CodecHelper.coalesce; import static java.lang.Character.toLowerCase; import static java.lang.String.format; +import static java.util.Arrays.stream; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; import static org.bson.json.JsonWriterSettings.builder; import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; import static org.testng.Assert.fail; public abstract class TemplatedTestBase extends TestBase { - private static final Logger LOG = LoggerFactory.getLogger(TemplatedTestBase.class); - public static final JsonWriterSettings JSON_WRITER_SETTINGS = builder() .indent(true) .build(); - protected static final String AGG_TEST_COLLECTION = "aggtest"; + protected static final String EXAMPLE_TEST_COLLECTION = "example_test"; protected final ObjectMapper mapper = new ObjectMapper(); - private boolean skipPipelineCheck = false; - private boolean skipDataCheck = false; public TemplatedTestBase() { + buildConfig() + .codecProvider(new ZDTCodecProvider()); } - public TemplatedTestBase(MorphiaConfig config) { - super(config); + protected static String toString(List actual, String prefix) { + return actual.stream() + .map(c -> c.toJson(JSON_WRITER_SETTINGS)) + .collect(joining("\n\t", prefix, "")); } - @BeforeMethod - public void resetSkip() { - skipPipelineCheck = false; + private static List unwrapArray(List resource) { + String line = resource.get(0).trim(); + if (line.startsWith("[")) { + resource.set(0, line.trim().substring(1)); + } + var last = resource.size() - 1; + line = resource.get(last).trim(); + if (line.endsWith("]")) { + resource.set(last, line.substring(0, line.length() - 1)); + } + + return resource; } - public final String prefix() { - String root = getClass().getSimpleName().replace("Test", ""); - return toLowerCase(root.charAt(0)) + root.substring(1); + @AfterClass + public void testCoverage() { + var type = getClass(); + var methods = stream(type.getDeclaredMethods()) + .filter(m -> m.getName().startsWith("testExample")) + .map(m -> { + String name = m.getName().substring(4); + return toLowerCase(name.charAt(0)) + name.substring(1); + }) + .toList(); + String path = type.getPackageName(); + String simpleName = type.getSimpleName().substring(4); + var operatorName = toLowerCase(simpleName.charAt(0)) + simpleName.substring(1); + var resourceFolder = TemplatedTestBase.rootToCore("src/test/resources/%s/%s".formatted(path.replace('.', '/'), operatorName)); + + if (!resourceFolder.exists()) { + throw new IllegalStateException("%s does not exist inside %s".formatted(resourceFolder, + new File(".").getAbsolutePath())); + } + List list = Arrays.stream(resourceFolder.list()) + .map(s -> new File(resourceFolder, s)) + .toList(); + + List examples = list.stream() + .filter(d -> new File(d, "action.json").exists()) + .map(File::getName) + .toList(); + var missing = examples.stream() + .filter(example -> !methods.contains(example)) + .collect(joining(", ")); + if (!missing.isEmpty()) { + fail("Missing test cases for $%s: %s".formatted(operatorName, missing)); + } } - public void skipDataCheck() { - skipDataCheck = true; + @NotNull + public static File rootToCore(String path) { + return new File(CORE_ROOT, path); } - public void skipPipelineCheck() { - skipPipelineCheck = true; + public void testPipeline(Function, Aggregation> pipeline) { + testPipeline(new ActionTestOptions(), pipeline); } - public void testPipeline(ServerVersion serverVersion, - boolean removeIds, - boolean orderMatters, + public void testPipeline(ActionTestOptions options, Function, Aggregation> pipeline) { - checkMinServerVersion(serverVersion); - checkMinDriverVersion(minDriver); - var resourceName = discoverResourceName(new Exception().getStackTrace()); - loadData(AGG_TEST_COLLECTION); - loadIndex(AGG_TEST_COLLECTION); + var resourceName = prepareDatabase(options); - List actual = runPipeline(resourceName, pipeline.apply(getDs().aggregate(AGG_TEST_COLLECTION))); + validateTestName(resourceName); - if (!skipDataCheck) { - List expected = loadExpected(resourceName); - - actual = removeIds ? removeIds(actual) : actual; - expected = removeIds ? removeIds(expected) : expected; + List actual = runPipeline(options, resourceName, pipeline.apply(getDs().aggregate(EXAMPLE_TEST_COLLECTION))); - try { - Comparanator.of(null, actual, expected, orderMatters).compare(); - } catch (AssertionError e) { - throw new AssertionError("%s\n\n actual: %s".formatted(e.getMessage(), toString(actual, "\n\t")), - e); - } - } - } - - private static String toString(List actual, String prefix) { - return actual.stream() - .map(c -> c.toJson(JSON_WRITER_SETTINGS)) - .collect(joining("\n\t", prefix, "")); + checkExpected(options, resourceName, actual); } - public void testQuery(MorphiaQuery query, FindOptions options, boolean orderMatters) { - var resourceName = discoverResourceName(new Exception().getStackTrace()); - - loadData(getDs().getCollection(query.getEntityClass()).getNamespace().getCollectionName()); - - List actual = runQuery(resourceName, query, options); + protected String discoverResourceName() { + var method = findTestMethod(); + String methodName = method.getName(); - List expected = map(query.getEntityClass(), loadExpected(resourceName)); - - if (orderMatters) { - assertEquals(actual, expected); - } else { - assertListEquals(actual, expected); + if (methodName.startsWith("test")) { + methodName = methodName.substring(4); + methodName = methodName.substring(0, 1).toLowerCase() + methodName.substring(1); } + return methodName; } - protected void loadData(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 resourceName, String collection) { + 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(), resourceName, index), "data", true)); - } - } - - protected void loadIndex(String collectionName) { - var resourceName = discoverResourceName(new Exception().getStackTrace()); - MongoCollection collection = getDatabase().getCollection(collectionName); - List documents = loadJson("%s/%s/index.json".formatted(prefix(), resourceName), "index", false); - documents.forEach(document -> { - collection.createIndex(document); - }); + insert(collection, loadJson(format("%s/%s/data%d.json", prefix(), discoverResourceName(), index), "data", true)); } protected @NotNull List loadExpected(String resourceName) { return loadJson("%s/%s/expected.json".formatted(prefix(), resourceName), "expected", true); } - protected @NotNull List loadExpected(Class type, String resourceName) { - return loadJson(type, format("%s/%s/expected.json", prefix(), resourceName)); + protected Method findTestMethod() { + return stream(new Exception().getStackTrace()) + .map(this::isTestMethod) + .filter(Objects::nonNull) + .findFirst() + .get(); } @NotNull @@ -190,36 +195,112 @@ protected List loadJson(String name, String type, boolean failOnMissin return data; } - @NotNull - protected List loadJson(Class type, String name) { - List data = new ArrayList<>(); + public final String prefix() { + String root = getClass().getSimpleName().replace("Test", ""); + return toLowerCase(root.charAt(0)) + root.substring(1); + } + + @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 ? method : null; + } catch (ReflectiveOperationException e) { + return null; + } + } + + public void testQuery(Function, Query> function) { + testQuery(new ActionTestOptions(), function); + } + + public void testQuery(ActionTestOptions options, + Function, Query> function) { + + var resourceName = prepareDatabase(options); + + Query apply = function.apply(getDs().find(EXAMPLE_TEST_COLLECTION, Document.class) + .disableValidation()); + List actual = runQuery(options, resourceName, apply, options.findOptions()); + + checkExpected(options, resourceName, actual); + } + + public void testUpdate(Function, Query> function, UpdateOperator... operators) { + testUpdate(new ActionTestOptions(), function, operators); + } + + public void testUpdate(ActionTestOptions options, + Function, Query> function, UpdateOperator... operators) { + + var resourceName = prepareDatabase(options); + + Query query = function.apply(getDs().find(EXAMPLE_TEST_COLLECTION, Document.class) + .disableValidation()); + List actual = runUpdate(options, resourceName, query, options.findOptions(), operators); + + checkExpected(options, resourceName, actual); + } + + protected List loadAction(String actionName) { + return extractDocuments(unwrapArray(loadResource(actionName))); + } + + protected void loadData(ActionTestOptions options, String collection, int index) { + if (!options.skipDataCheck()) { + insert(collection, loadJson(format("%s/%s/data%d.json", prefix(), discoverResourceName(), index), "data", true)); + } + } + + protected void loadIndex(String resourceName, String collectionName) { + MongoCollection collection = getDatabase().getCollection(collectionName); + List documents = loadJson("%s/%s/index.json".formatted(prefix(), resourceName), "index", false); + documents.forEach(document -> collection.createIndex(document)); + } + + protected Document loadQuery(String pipelineName) { + return loadAction(pipelineName).get(0); + } + + protected List loadResource(String pipelineName) { + InputStream stream = getClass().getResourceAsStream(pipelineName); + if (stream == null) { + fail(format("missing action file: src/test/resources/%s/%s", getClass().getPackageName().replace('.', '/'), + pipelineName)); + } + return new BufferedReader(new InputStreamReader(stream)) + .lines() + .collect(toList()); + } + + protected String loadTestName(String resourceName) { + String name = format("%s/%s/name", prefix(), resourceName); + InputStream stream = getClass().getResourceAsStream(name); if (stream == null) { - fail("missing data file: " + name); + fail(format("missing name file: %s", name)); } - ObjectMapper mapper = new ObjectMapper(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { - while (reader.ready()) { - data.add(mapper.readValue(reader.readLine(), type)); - } + try (var reader = new BufferedReader(new InputStreamReader(stream))) { + return reader.readLine(); } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + throw new RuntimeException(e); } - return data; } @SuppressWarnings({ "unchecked", "rawtypes" }) - protected List runPipeline(String pipelineTemplate, Aggregation aggregation) { - String pipelineName = format("%s/%s/pipeline.json", prefix(), pipelineTemplate); + protected List runPipeline(ActionTestOptions options, String pipelineTemplate, Aggregation aggregation) { + String pipelineName = format("%s/%s/action.json", prefix(), pipelineTemplate); List pipeline = ((AggregationImpl) aggregation).pipeline(); - if (!skipPipelineCheck) { - List target = loadPipeline(pipelineName); + if (!options.skipActionCheck()) { + List target = loadAction(pipelineName); assertEquals(toJson(pipeline), toJson(target), "Should generate the same pipeline"); } - if (!skipDataCheck) { + if (!options.skipDataCheck()) { try (var cursor = aggregation.execute(Document.class)) { return cursor.toList(); } @@ -228,66 +309,72 @@ protected List runPipeline(String pipelineTemplate, Aggregation pipeline) { - return pipeline.stream() - .map(d -> d.toJson(JSON_WRITER_SETTINGS, getDatabase().getCodecRegistry().get(Document.class))) - .collect(joining("\n, ", "[\n", "\n]")); - } + @SuppressWarnings({ "rawtypes" }) + protected List runQuery(ActionTestOptions testOptions, String pipelineTemplate, Query query, FindOptions options) { + String resourceName = format("%s/%s/action.json", prefix(), pipelineTemplate); + Document document = ((MorphiaQuery) query).toDocument(); - private List loadPipeline(String pipelineName) { - InputStream stream = getClass().getResourceAsStream(pipelineName); - if (stream == null) { - fail(format("missing data file: src/test/resources/%s/%s", getClass().getPackageName().replace('.', '/'), - pipelineName)); + if (!testOptions.skipActionCheck()) { + Document target = loadQuery(resourceName); + assertEquals(toJson(document), toJson(target), "Should generate the same query document"); } - return parsePipeline(stream); - } - - private List parsePipeline(InputStream stream) { - List list = new ArrayList<>(new BufferedReader(new InputStreamReader(stream)) - .lines() - .map(String::trim) - // .map(line -> line.replaceAll("(\\$*\\w+?):", "\"$1\":")) - .toList()); - String line = list.get(0); - if (line.startsWith("[")) { - line = line.substring(1); - if (!line.isBlank()) { - list.set(0, line); - } else { - list.remove(0); + if (!testOptions.skipDataCheck()) { + try (var cursor = query.iterator(options)) { + return cursor.toList(); } + } else { + return emptyList(); } - line = list.get(list.size() - 1); - if (line.endsWith("]")) { - line = line.substring(0, line.length() - 1); - if (!line.isBlank()) { - list.set(list.size() - 1, line); - } else { - list.remove(list.size() - 1); + } + + @SuppressWarnings({ "rawtypes" }) + protected List runUpdate(ActionTestOptions testOptions, String pipelineTemplate, Query query, + FindOptions options, UpdateOperator... operators) { + String resourceName = format("%s/%s/action.json", prefix(), pipelineTemplate); + Document document = ((MorphiaQuery) query).toDocument(); + + var first = operators[0]; + var others = Arrays.copyOfRange(operators, 1, operators.length); + + checkAction(testOptions, resourceName, document, first, others); + + if (!testOptions.skipDataCheck()) { + var resource = loadResource(resourceName).stream().collect(joining()); + query.update(testOptions.updateOptions().multi(resource.contains("updateMany")), first, others); + try (var cursor = query.iterator()) { + return cursor.toList(); } + } else { + return emptyList(); } + } - var json = list.iterator(); - List stages = new ArrayList<>(); - String current = ""; - while (json.hasNext()) { - while (current.isBlank() || !balanced(current)) { - var next = json.next(); - if (!next.trim().isBlank()) { - current += next; - } - } - try { - stages.add(Document.parse(current)); - } catch (BsonInvalidOperationException e) { - throw new BsonInvalidOperationException("Failed to parse:\n" + current, e); - } - current = ""; + private void checkAction(ActionTestOptions testOptions, + String resourceName, + Document document, + UpdateOperator first, + UpdateOperator[] others) { + if (!testOptions.skipActionCheck()) { + List action = loadAction(resourceName); + assertEquals(toJson(document), toJson(action.get(0)), "Should generate the same query document"); + Operations operations = new Operations(getDs(), null, coalesce(first, others), false); + Document updates = operations.toDocument(getDs()); + assertEquals(toJson(updates), toJson(action.get(1)), "Should generate the same update document"); } + } + + protected String toJson(Document document) { + return document.toJson(JSON_WRITER_SETTINGS, getDatabase().getCodecRegistry().get(Document.class)); + } - return stages; + protected void validateTestName(String resourceName) { + Method method = findTestMethod(); + Test test = method.getAnnotation(Test.class); + assertEquals( + test.testName(), loadTestName(resourceName), + "%s#%s does not have a name configured on the test.".formatted(method.getDeclaringClass().getName(), + method.getName())); } private boolean balanced(String input) { @@ -300,62 +387,75 @@ private boolean balanced(String input) { close++; } - return open == close; + return open != 0 && open == close; } - @NonNull - protected List runQuery(@NonNull String queryTemplate, @NonNull MorphiaQuery query, @NonNull FindOptions options) { - String queryName = format("%s/%s/query.json", prefix(), queryTemplate); - try { - - InputStream stream = getClass().getResourceAsStream(queryName); - assertNotNull(stream, "Could not find query template: " + queryName); - Document expectedQuery; - try (InputStreamReader reader = new InputStreamReader(stream)) { - expectedQuery = Document.parse(new BufferedReader(reader).readLine()); - } + private void checkExpected(ActionTestOptions options, String resourceName, List actual) { + if (!options.skipDataCheck()) { + List expected = loadExpected(resourceName); - assertDocumentEquals(query.toDocument(), expectedQuery); + actual = options.removeIds() ? removeIds(actual) : actual; + expected = options.removeIds() ? removeIds(expected) : expected; - try (var cursor = query.iterator(options)) { - return cursor.toList(); + try { + Comparanator.of(null, actual, expected, options.orderMatters()).compare(); + } catch (AssertionError e) { + throw new AssertionError("%s\n\n actual: %s".formatted(e.getMessage(), toString(actual, "\n\t")), + e); } - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); } } - protected String discoverResourceName(StackTraceElement[] stackTrace) { - String methodName = Arrays.stream(stackTrace) - .filter(e -> isTestMethod(e)) - .findFirst() - .get().getMethodName(); - if (methodName.startsWith("test")) { - methodName = methodName.substring(4); - methodName = methodName.substring(0, 1).toLowerCase() + methodName.substring(1); + private List extractDocuments(List resource) { + var line = resource.get(0).trim(); + if (line.startsWith("db.")) { + line = line.substring(line.indexOf("(") + 1).trim(); + resource.set(0, line); + line = resource.get(resource.size() - 1); + line = line.substring(0, line.lastIndexOf(")")); + resource.set(resource.size() - 1, line); + } + List docs = new ArrayList<>(); + var current = ""; + try (var lines = new StringReader(String.join("", resource))) { + int read; + while ((read = lines.read()) != -1) { + char c = (char) read; + if (!List.of(',', ' ', '\n').contains(c) || !current.isEmpty()) { + + current += c; + if (balanced(current)) { + try { + docs.add(Document.parse(current)); + current = ""; + } catch (JsonParseException | BsonInvalidOperationException e) { + throw new RuntimeException("Error parsing " + current, e); + } + } + } + } + } catch (IOException e) { + throw new RuntimeException(e); } - return methodName; - } - private boolean isTestMethod(StackTraceElement element) { - try { - Class klass = Class.forName(element.getClassName()); - Method method = klass.getDeclaredMethod(element.getMethodName()); + return docs; + } - return method.getAnnotation(Test.class) != null; - } catch (ReflectiveOperationException e) { - return false; + private String prepareDatabase(ActionTestOptions options) { + checkMinServerVersion(options.serverVersion()); + checkMinDriverVersion(options.minDriver()); + var resourceName = discoverResourceName(); + validateTestName(resourceName); + if (!options.skipDataCheck()) { + loadData(resourceName, EXAMPLE_TEST_COLLECTION); } + loadIndex(resourceName, EXAMPLE_TEST_COLLECTION); + return resourceName; } - private List map(Class entityClass, List documents) { - var codec = getDs().getCodecRegistry().get(entityClass); - - DecoderContext context = DecoderContext.builder().build(); - return documents.stream() - .map(document -> { - return codec.decode(new DocumentReader(document), context); - }) - .collect(toList()); + private String toJson(List pipeline) { + return pipeline.stream() + .map(d -> d.toJson(JSON_WRITER_SETTINGS, getDatabase().getCodecRegistry().get(Document.class))) + .collect(joining("\n, ", "[\n", "\n]")); } } diff --git a/core/src/test/java/dev/morphia/test/TestArrayUpdates.java b/core/src/test/java/dev/morphia/test/TestArrayUpdates.java index 920a995e5b1..641f6fb9130 100644 --- a/core/src/test/java/dev/morphia/test/TestArrayUpdates.java +++ b/core/src/test/java/dev/morphia/test/TestArrayUpdates.java @@ -1,91 +1,21 @@ package dev.morphia.test; -import java.util.ArrayList; -import java.util.List; - import dev.morphia.Datastore; import dev.morphia.UpdateOptions; -import dev.morphia.annotations.Entity; -import dev.morphia.annotations.Id; -import dev.morphia.query.FindOptions; import dev.morphia.query.Query; import dev.morphia.test.models.Grade; import dev.morphia.test.models.Student; -import org.bson.types.ObjectId; import org.testng.annotations.Test; import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.query.filters.Filters.lt; import static dev.morphia.query.updates.UpdateOperators.inc; -import static dev.morphia.query.updates.UpdateOperators.set; -import static java.lang.String.format; import static java.util.Collections.singletonMap; -import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; public class TestArrayUpdates extends TestBase { - @Test - public void testStudents() { - final Datastore datastore = getDs(); - - datastore.save(new Student(1L, new Grade(80, singletonMap("name", "Homework")), - new Grade(90, singletonMap("name", "Test")))); - - Query testQuery = datastore.find(Student.class) - .filter(eq("_id", 1L), - eq("grades.data.name", "Test"), - eq("grades.data.bad.path.should.be.null", null)); - assertNotNull(testQuery.iterator(new FindOptions().limit(1)) - .tryNext()); - - testQuery.update(set("grades.$.data.name", "Makeup Test")); - - assertNull(testQuery.iterator(new FindOptions().limit(1)) - .tryNext()); - - assertNotNull(datastore.find(Student.class) - .filter(eq("_id", 1L), - eq("grades.data.name", "Makeup Test")) - .iterator(new FindOptions().limit(1)) - .tryNext()); - } - - @Test - public void testUpdates() { - BatchData theBatch = new BatchData(); - theBatch.files.add(new Files(0, "fileName1", "fileHash1")); - theBatch.files.add(new Files(0, "fileName2", "fileHash2")); - getDs().save(theBatch); - ObjectId id = theBatch.id; - - theBatch = new BatchData(); - theBatch.files.add(new Files(0, "fileName3", "fileHash3")); - theBatch.files.add(new Files(0, "fileName4", "fileHash4")); - getDs().save(theBatch); - ObjectId id2 = theBatch.id; - - getDs().find(BatchData.class) - .filter(eq("_id", id), - eq("files.fileName", "fileName1")) - .update(set("files.$.fileHash", "new hash")); - - BatchData data = getDs().find(BatchData.class) - .filter(eq("_id", id)).iterator(new FindOptions().limit(1)) - .tryNext(); - - assertEquals(data.files.get(0).fileHash, "new hash"); - assertEquals(data.files.get(1).fileHash, "fileHash2"); - - data = getDs().find(BatchData.class) - .filter(eq("_id", id2)) - .iterator(new FindOptions().limit(1)) - .tryNext(); - - assertEquals(data.files.get(0).fileHash, "fileHash3"); - assertEquals(data.files.get(1).fileHash, "fileHash4"); - } @Test public void testUpdatesWithArrayFilters() { @@ -132,39 +62,4 @@ public void testUpdatesWithArrayFilters() { .tryNext()); } - - @Entity - private static class BatchData { - - private final List files = new ArrayList<>(); - @Id - private ObjectId id; - - @Override - public String toString() { - return format("BatchData{id=%s, files=%s}", id, files); - } - } - - @Entity - private static class Files { - private int position; - private String fileName = ""; - private String fileHash = ""; - - public Files() { - } - - public Files(int pos, String fileName, String fileHash) { - this.position = pos; - this.fileName = fileName; - this.fileHash = fileHash; - } - - @Override - public String toString() { - return format("Files{fileHash='%s', fileName='%s', position=%d}", fileHash, fileName, position); - } - } - } diff --git a/core/src/test/java/dev/morphia/test/TestBase.java b/core/src/test/java/dev/morphia/test/TestBase.java index 052232a2fbc..bb32b272257 100644 --- a/core/src/test/java/dev/morphia/test/TestBase.java +++ b/core/src/test/java/dev/morphia/test/TestBase.java @@ -63,8 +63,6 @@ public abstract class TestBase extends MorphiaTestSetup { } } - protected DriverVersion minDriver = DriverVersion.v41; - public TestBase() { } @@ -261,10 +259,26 @@ protected void insert(String collectionName, List list) { protected List removeIds(List documents) { return documents.stream() - .peek(d -> d.remove("_id")) + .peek(d -> removeId(d)) .collect(toList()); } + private static Object removeId(Document d) { + Object doc = d.remove("_id"); + d.values().forEach(v -> { + if (v instanceof Document document) { + removeId(document); + } else if (v instanceof List list) { + list.forEach(e -> { + if (e instanceof Document document) { + removeId(document); + } + }); + } + }); + return doc; + } + protected Document toDocument(Object entity) { final Class type = getMapper().getEntityModel(entity.getClass()).getType(); @@ -346,11 +360,6 @@ private void assertSameType(String path, Object actual, Object expected) { } } - @BeforeMethod - private void setDriverMinimum() { - minDriver = DriverVersion.v43; - } - public static class ZDTCodecProvider implements CodecProvider { @Override public Codec get(Class clazz, CodecRegistry registry) { diff --git a/core/src/test/java/dev/morphia/test/TestTransactions.java b/core/src/test/java/dev/morphia/test/TestTransactions.java index 8149efb1437..32ede5ee5d4 100644 --- a/core/src/test/java/dev/morphia/test/TestTransactions.java +++ b/core/src/test/java/dev/morphia/test/TestTransactions.java @@ -21,6 +21,7 @@ import org.bson.types.ObjectId; import org.testng.Assert; +import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -32,7 +33,7 @@ import static org.testng.Assert.assertNull; //@Tags(@Tag("transactions")) -public class TestTransactions extends TemplatedTestBase { +public class TestTransactions extends dev.morphia.test.TemplatedTestBase { @BeforeMethod public void before() { checkForReplicaSet(); @@ -42,6 +43,11 @@ public void before() { getDs().find(User.class).findAndDelete(); } + @AfterClass + @Override + public void testCoverage() { + } + @Test public void delete() { Rectangle rectangle = new Rectangle(1, 1); @@ -158,17 +164,19 @@ public void merge() { assertEquals(getDs().find(Rectangle.class).first().getWidth(), 20, 0.5); } - @Test + @Test(testName = "transactional aggregations") public void aggregation() { getDs().withTransaction(session -> { - testPipeline(ServerVersion.ANY, false, false, aggregation -> { - loadData("aggTest2", 2); - return aggregation - .lookup(Lookup.lookup("aggTest2") - .localField("item") - .foreignField("sku") - .as("inventory_docs")); - }); + testPipeline( + new dev.morphia.test.util.ActionTestOptions().orderMatters(false), + aggregation -> { + loadData("aggTest2", 2); + return aggregation + .lookup(Lookup.lookup("aggTest2") + .localField("item") + .foreignField("sku") + .as("inventory_docs")); + }); return null; }); } diff --git a/core/src/test/java/dev/morphia/test/TestUpdateOperations.java b/core/src/test/java/dev/morphia/test/TestUpdateOperations.java index d645ac09219..6d14430b77c 100644 --- a/core/src/test/java/dev/morphia/test/TestUpdateOperations.java +++ b/core/src/test/java/dev/morphia/test/TestUpdateOperations.java @@ -1,11 +1,8 @@ package dev.morphia.test; -import java.time.Instant; -import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; -import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -15,11 +12,9 @@ import java.util.Objects; import java.util.Set; import java.util.StringJoiner; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import com.mongodb.client.result.UpdateResult; -import com.mongodb.lang.Nullable; import dev.morphia.Datastore; import dev.morphia.DeleteOptions; @@ -29,32 +24,22 @@ import dev.morphia.annotations.Id; import dev.morphia.annotations.Indexed; import dev.morphia.annotations.PreLoad; -import dev.morphia.internal.PathTarget; import dev.morphia.query.FindOptions; -import dev.morphia.query.MorphiaCursor; import dev.morphia.query.Operations; import dev.morphia.query.Query; -import dev.morphia.query.Sort; import dev.morphia.query.ValidationException; -import dev.morphia.query.filters.Filters; -import dev.morphia.query.updates.CurrentDateOperator.TypeSpecification; import dev.morphia.query.updates.UpdateOperator; -import dev.morphia.test.models.Book; +import dev.morphia.query.updates.UpdateOperators; import dev.morphia.test.models.Circle; import dev.morphia.test.models.FacebookUser; -import dev.morphia.test.models.Grade; import dev.morphia.test.models.Hotel; -import dev.morphia.test.models.Rectangle; import dev.morphia.test.models.Shape; -import dev.morphia.test.models.Student; import dev.morphia.test.models.TestEntity; -import dev.morphia.test.models.User; import dev.morphia.test.models.generics.Child; import dev.morphia.test.query.TestQuery.CappedPic; import dev.morphia.test.query.TestQuery.ContainsPic; import dev.morphia.test.query.TestQuery.Pic; -import org.bson.BsonTimestamp; import org.bson.Document; import org.bson.codecs.configuration.CodecRegistry; import org.bson.json.JsonWriterSettings; @@ -65,11 +50,10 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import static dev.morphia.aggregation.stages.Set.set; import static dev.morphia.query.filters.Filters.eq; -import static dev.morphia.query.filters.Filters.regex; import static dev.morphia.query.updates.UpdateOperators.addToSet; import static dev.morphia.query.updates.UpdateOperators.and; +import static dev.morphia.query.updates.UpdateOperators.bit; import static dev.morphia.query.updates.UpdateOperators.currentDate; import static dev.morphia.query.updates.UpdateOperators.dec; import static dev.morphia.query.updates.UpdateOperators.inc; @@ -88,23 +72,15 @@ import static dev.morphia.query.updates.UpdateOperators.xor; import static java.lang.String.format; import static java.time.LocalDate.now; -import static java.time.temporal.ChronoUnit.DAYS; -import static java.time.temporal.ChronoUnit.MONTHS; import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.hasItem; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; import static org.testng.Assert.assertThrows; import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; @SuppressWarnings({ "ConstantConditions", "unused" }) public class TestUpdateOperations extends TestBase { @@ -173,260 +149,6 @@ public void shouldUpdateAnArrayElement() { .next().children, hasItem(new Child(childName, updatedLastName))); } - @Test - public void testAdd() { - ContainsIntArray cIntArray = new ContainsIntArray(); - getDs().save(cIntArray); - - assertThat(get(cIntArray), is(new ContainsIntArray().values)); - - Query query = getDs().find(ContainsIntArray.class); - //add 4 to array - assertUpdated(query.update(addToSet("values", 4)), - 1); - - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4 })); - - //add unique (4) -- noop - assertEquals(query.update(addToSet("values", 4)).getMatchedCount(), 1); - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4 })); - - //add dup 4 - assertUpdated(query.update(push("values", 4)), 1); - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4, 4 })); - - //cleanup for next tests - getDs().find(ContainsIntArray.class).findAndDelete(); - cIntArray = getDs().find(ContainsIntArray.class) - .filter(eq("_id", getDs().save(new ContainsIntArray()).id)) - .first(); - assertNotNull(cIntArray); - - //add [4,5] - final List newValues = new ArrayList<>(); - newValues.add(4); - newValues.add(5); - - assertUpdated(query.update(addToSet("values", newValues)), 1); - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4, 5 })); - - //add them again... noop - assertEquals(query.update(addToSet("values", newValues)).getMatchedCount(), 1); - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4, 5 })); - - //add dups [4,5] - assertUpdated(query.update(push("values", newValues)), 1); - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4, 5, 4, 5 })); - } - - @Test - public void testAddAll() { - String uuid = "4ec6ada9-081a-424f-bee0-934c0bc4fab7"; - - LogHolder logs = new LogHolder(); - logs.uuid = uuid; - getDs().save(logs); - - Query finder = getDs().find(LogHolder.class) - .filter(eq("uuid", uuid)); - - // both of these entries will have a className attribute - List latestLogs = asList(new Log(1), new Log(2)); - - finder.update(new UpdateOptions() - .upsert(true), - addToSet("logs", latestLogs)); - validateClassName(finder.first()); - - // this entry will NOT have a className attribute - Log log = new Log(3); - finder - .update(new UpdateOptions().upsert(true), addToSet("logs", log)); - validateClassName(finder.first()); - - // this entry will NOT have a className attribute - finder.update(new UpdateOptions().upsert(true), addToSet("logs", new Log(4))); - validateClassName(finder.first()); - } - - @Test - public void testAddToSet() { - ContainsIntArray cIntArray = new ContainsIntArray(); - getDs().save(cIntArray); - - Query query = getDs().find(ContainsIntArray.class) - .filter(eq("_id", cIntArray.id)); - - assertThat(query.first().values, is(new ContainsIntArray().values)); - - assertUpdated(query.update(addToSet("values", 5)), 1); - - assertThat(query.first().values, is(new Integer[] { 1, 2, 3, 5 })); - - assertUpdated(query.update(addToSet("values", 4)), 1); - assertThat(query.first().values, is(new Integer[] { 1, 2, 3, 5, 4 })); - - assertUpdated(query.update(addToSet("values", asList(8, 9))), 1); - assertThat(query.first().values, is(new Integer[] { 1, 2, 3, 5, 4, 8, 9 })); - - assertEquals(query.update(addToSet("values", asList(4, 5))).getMatchedCount(), 1); - assertThat(query.first().values, is(new Integer[] { 1, 2, 3, 5, 4, 8, 9 })); - - assertUpdated(query.update(addToSet("values", new HashSet<>(asList(10, 11)))), 1); - assertThat(query.first().values, is(new Integer[] { 1, 2, 3, 5, 4, 8, 9, 10, 11 })); - } - - @Test - public void testAnd() { - ContainsInt containsInt = new ContainsInt(); - containsInt.val = 24; - - getDs().save(containsInt); - - getDs().find(ContainsInt.class) - .update(and("val", 8)); - - ContainsInt first = getDs().find(ContainsInt.class) - .first(); - - assertEquals(first.val, 8); - } - - @Test - public void testCurrentDate() { - getDs().save(new DumbColl("currentDate")); - - getDs().find(DumbColl.class) - .update(currentDate("localDateTime")); - - Document document = getDatabase().getCollection(getDs().getCollection(DumbColl.class).getNamespace().getCollectionName()) - .find() - .first(); - assertNotNull(document.getDate("localDateTime")); - - getDs().find(DumbColl.class) - .update(currentDate("localDateTime") - .type(TypeSpecification.TIMESTAMP)); - - document = getDatabase().getCollection(getDs().getCollection(DumbColl.class).getNamespace().getCollectionName()) - .find() - .first(); - assertTrue(document.get("localDateTime") instanceof BsonTimestamp); - } - - @Test - public void testIncDec() { - final Rectangle[] array = { - new Rectangle(1, 10), - new Rectangle(1, 10), - new Rectangle(1, 10), - new Rectangle(10, 10), - new Rectangle(10, 10) }; - - for (Rectangle rect : array) { - getDs().save(rect); - } - - final Query heightOf1 = getDs().find(Rectangle.class).filter(eq("height", 1D)); - final Query heightOf2 = getDs().find(Rectangle.class).filter(eq("height", 2D)); - final Query heightOf35 = getDs().find(Rectangle.class).filter(eq("height", 3.5D)); - - assertThat(heightOf1.count(), is(3L)); - assertThat(heightOf2.count(), is(0L)); - - UpdateResult results = heightOf1 - .update(new UpdateOptions().multi(true), inc("height")); - assertUpdated(results, 3); - - assertThat(heightOf1.count(), is(0L)); - assertThat(heightOf2.count(), is(3L)); - - heightOf2.update(new UpdateOptions().multi(true), dec("height")); - assertThat(heightOf1.count(), is(3L)); - assertThat(heightOf2.count(), is(0L)); - - heightOf1.update(new UpdateOptions().multi(true), inc("height", 2.5D)); - assertThat(heightOf1.count(), is(0L)); - assertThat(heightOf35.count(), is(3L)); - - heightOf35.update(new UpdateOptions().multi(true), dec("height", 2.5D)); - assertThat(heightOf1.count(), is(3L)); - assertThat(heightOf35.count(), is(0L)); - - getDs().find(Rectangle.class) - .filter(eq("height", 1D)) - .update( - set("height", 1D), - inc("width", 20D)); - - MatcherAssert.assertThat(getDs().find(Rectangle.class).count(), is(5L)); - MatcherAssert.assertThat(getDs().find(Rectangle.class) - .filter(eq("height", 1D)).iterator(new FindOptions().limit(1)) - .next(), is(notNullValue())); - MatcherAssert.assertThat(getDs().find(Rectangle.class) - .filter(eq("width", 30D)).iterator(new FindOptions().limit(1)) - .next(), is(notNullValue())); - - getDs().find(Rectangle.class) - .filter(eq("width", 30D)) - .update( - set("height", 2D), - set("width", 2D)); - MatcherAssert.assertThat(getDs().find(Rectangle.class) - .filter(eq("width", 1D)).iterator(new FindOptions().limit(1)) - .tryNext(), is(nullValue())); - MatcherAssert.assertThat(getDs().find(Rectangle.class) - .filter(eq("width", 2D)).iterator(new FindOptions().limit(1)) - .next(), is(notNullValue())); - - heightOf35.update(dec("height", 1)); - heightOf35.update(dec("height", Long.MAX_VALUE)); - heightOf35.update(dec("height", 1.5f)); - heightOf35.update(dec("height", Double.MAX_VALUE)); - try { - heightOf35.update(dec("height", new AtomicInteger(1))); - fail("Wrong data type not recognized."); - } catch (IllegalArgumentException ignore) { - } - } - - @Test - public void testElemMatchUpdate() { - // setUp - Object id = getDs().save(new ContainsIntArray()).id; - assertThat(getDs().find(ContainsIntArray.class) - .filter(eq("_id", id)) - .first().values, arrayContaining(1, 2, 3)); - - // do patch - - getDs().find(ContainsIntArray.class) - .filter(eq("id", id), - eq("values", 2)) - .update(set("values.$", 5)); - - // expected - assertThat(getDs().find(ContainsIntArray.class) - .filter(eq("_id", id)) - .first().values, arrayContaining(1, 5, 3)); - } - - @Test - public void testExistingUpdates() { - getDs().save(new Circle(100D)); - getDs().save(new Circle(12D)); - Query circle = getDs().find(Circle.class); - assertUpdated(circle.update(inc("radius", 1D)), 1); - - assertUpdated(circle.update(new UpdateOptions().multi(true), inc("radius")), 2); - - //test possible data type change. - final Circle updatedCircle = circle.filter(eq("radius", 13)).iterator(new FindOptions().limit(1)) - .next(); - assertThat(updatedCircle, is(notNullValue())); - MatcherAssert.assertThat(updatedCircle.getRadius(), is(13D)); - } - @Test public void testInsertWithRef() { final Pic pic = new Pic(); @@ -490,130 +212,6 @@ public void testInvalidPathsInModify() { }); } - @Test - public void testMax() { - final ObjectId id = new ObjectId(); - final double originalValue = 2D; - - Datastore ds = getDs(); - Query query = ds.find(Circle.class) - .filter(eq("id", id)); - assertInserted(query.update(new UpdateOptions().upsert(true), setOnInsert(Map.of("radius", originalValue)))); - - assertEquals(query.update(new UpdateOptions().upsert(true), max("radius", 1D)) - .getMatchedCount(), 1); - - MatcherAssert.assertThat(ds.find(Circle.class) - .filter(eq("_id", id)) - .first().getRadius(), - is(originalValue)); - } - - @Test - public void testMul() { - ContainsInt containsInt = new ContainsInt(); - containsInt.val = 2; - - getDs().save(containsInt); - - getDs().find(ContainsInt.class) - .update(mul("val", 8)); - - ContainsInt first = getDs().find(ContainsInt.class) - .first(); - - assertEquals(first.val, 16); - } - - @Test - public void testMaxWithDates() { - List entities = List.of( - new User("User 1", LocalDate.of(2003, 7, 13)), - new User("User 2", LocalDate.of(2009, 12, 1)), - new User("User 3", LocalDate.of(2015, 8, 19))); - - getDs().save(entities); - UpdateResult updated = getDs().find(User.class) - .update(new UpdateOptions().multi(true), max("joined", now())); - assertEquals(updated.getModifiedCount(), 3); - - getDs().find(User.class).delete(); - getDs().save(entities); - updated = getDs().find(User.class) - .update(new UpdateOptions().multi(true), max("joined", Instant.now())); - assertEquals(updated.getModifiedCount(), 3); - - getDs().find(User.class).delete(); - getDs().save(entities); - Calendar instance = Calendar.getInstance(); - instance.set(2136, Calendar.MAY, 13); - Date date = instance.getTime(); - updated = getDs().find(User.class) - .update(new UpdateOptions().multi(true), max("joined", date)); - assertEquals(updated.getModifiedCount(), 3); - } - - @Test - public void testMinWithDates() { - List entities = List.of( - new User("User 1", now().minus(1, MONTHS)), - new User("User 2", now().minus(2, MONTHS)), - new User("User 3", now().minus(3, MONTHS))); - - getDs().save(entities); - UpdateResult updated = getDs().find(User.class) - .update(new UpdateOptions().multi(true), min("joined", LocalDate.of(1985, 10, 12))); - assertEquals(updated.getModifiedCount(), 3); - - getDs().find(User.class).delete(); - getDs().save(entities); - updated = getDs().find(User.class) - .update(new UpdateOptions().multi(true), min("joined", Instant.now().minus(70, DAYS))); - assertEquals(updated.getModifiedCount(), 2); - - getDs().find(User.class).delete(); - getDs().save(entities); - Calendar instance = Calendar.getInstance(); - instance.set(86, Calendar.MAY, 13); - Date date = instance.getTime(); - updated = getDs().find(User.class) - .update(new UpdateOptions().multi(true), min("joined", date)); - assertEquals(updated.getModifiedCount(), 3); - } - - @Test - public void testMultiUpdates() { - Query finder = getDs().find(ContainsPic.class); - - createContainsPic(0); - createContainsPic(1); - createContainsPic(2); - - finder.update(new UpdateOptions().multi(true), inc("size")); - - try (final MorphiaCursor iterator = finder.iterator(new FindOptions().sort(Sort.ascending("size")))) { - for (int i = 0; i < 3; i++) { - assertEquals(i + 1, iterator.next().getSize()); - } - } - } - - @Test - public void testOr() { - ContainsInt containsInt = new ContainsInt(); - containsInt.val = 16; - - getDs().save(containsInt); - - getDs().find(ContainsInt.class) - .update(or("val", 8)); - - ContainsInt first = getDs().find(ContainsInt.class) - .first(); - - assertEquals(first.val, 24); - } - @Test public void testPolymorphicUpsert() { withConfig(buildConfig() @@ -633,236 +231,6 @@ public void testPolymorphicUpsert() { }); } - @Test - public void testPlaceholderOperators() { - new PathTarget(getMapper(), DumbColl.class, "fromArray.$").translatedPath(); - new PathTarget(getMapper(), DumbColl.class, "fromArray.$[]").translatedPath(); - new PathTarget(getMapper(), DumbColl.class, "fromArray.$[element]").translatedPath(); - } - - @Test - public void testPull() { - DumbColl dumbColl = new DumbColl("ID"); - dumbColl.fromArray = List.of(new DumbArrayElement("something"), new DumbArrayElement("something else")); - DumbColl dumbColl2 = new DumbColl("ID2"); - dumbColl2.fromArray = singletonList(new DumbArrayElement("something")); - getDs().save(asList(dumbColl, dumbColl2)); - - Query query = getDs().find(DumbColl.class) - .filter(regex("opaqueId", "ID") - .caseInsensitive()); - - assertEquals(query.first().fromArray.size(), 2); - query.update(pull("fromArray", Filters.eq("name", "something else"))); - assertEquals(query.first().fromArray.size(), 1); - } - - @Test - public void testPullsWithNoData() { - DumbColl dumbColl = new DumbColl("ID"); - dumbColl.fromArray = singletonList(new DumbArrayElement("something")); - DumbColl dumbColl2 = new DumbColl("ID2"); - dumbColl2.fromArray = singletonList(new DumbArrayElement("something")); - getDs().save(asList(dumbColl, dumbColl2)); - - getDs().find(DumbColl.class) - .filter(regex("opaqueId", "ID") - .caseInsensitive()) - .update(pull("fromArray", Filters.eq("whereId", "not there"))); - - getDs().find(DumbColl.class) - .filter(regex("opaqueId", "ID") - .caseInsensitive()) - .update(pullAll("fromArray", List.of(new DumbArrayElement("something")))); - } - - @Test - public void testPush() { - ContainsIntArray cIntArray = new ContainsIntArray(); - getDs().save(cIntArray); - assertThat(get(cIntArray), is(new ContainsIntArray().values)); - - Query query = getDs().find(ContainsIntArray.class); - query.update(push("values", 4)); - - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4 })); - - query.update(push("values", 4)); - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4, 4 })); - - query.update(push("values", asList(5, 6))); - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 3, 4, 4, 5, 6 })); - - query.update(push("values", 12) - .position(2)); - - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 12, 3, 4, 4, 5, 6 })); - - query.update(push("values", asList(99, 98, 97)) - .position(4)); - assertThat(get(cIntArray), is(new Integer[] { 1, 2, 12, 3, 99, 98, 97, 4, 4, 5, 6 })); - } - - @Test - public void testRemoveAllList() { - LogHolder logs = new LogHolder(); - Date date = new Date(); - logs.logs.addAll(asList( - new Log(1), - new Log(2), - new Log(3), - new Log(1), - new Log(2), - new Log(3))); - - Datastore ds = getDs(); - ds.save(logs); - - UpdateResult results = ds.find(LogHolder.class) - .update(pullAll("logs", singletonList(new Log(3)))); - - assertEquals(results.getModifiedCount(), 1); - LogHolder updated = ds.find(LogHolder.class).iterator(new FindOptions().limit(1)) - .next(); - assertEquals(updated.logs.size(), 4); - assertTrue(updated.logs.stream() - .allMatch(log -> log.equals(new Log(1)) - || log.equals(new Log(2)))); - } - - @Test - public void testRemoveFirst() { - final ContainsIntArray cIntArray = new ContainsIntArray(); - getDs().save(cIntArray); - Integer[] values = get(cIntArray); - assertThat(values.length, is(3)); - assertThat(values, is(new ContainsIntArray().values)); - - Query query = getDs().find(ContainsIntArray.class); - assertUpdated(query.update(pop("values").removeFirst()), 1); - assertThat(get(cIntArray), is(new Integer[] { 2, 3 })); - - assertUpdated(query.update(pop("values")), 1); - assertThat(get(cIntArray), is(new Integer[] { 2 })); - } - - @Test - public void testRename() { - getDs().save(new DumbColl("rename")); - - getDs().find(DumbColl.class) - .update(rename("opaqueId", "anythingElse")); - - Document document = getDatabase().getCollection(getDs().getCollection(DumbColl.class).getNamespace().getCollectionName()) - .find() - .first(); - assertNull(document.getString("opaqueId")); - assertNotNull(document.getString("anythingElse")); - } - - @Test - public void testSetOnInsertWhenInserting() { - ObjectId id = new ObjectId(); - - Query query = getDs().find(Circle.class) - .filter(eq("id", id)); - assertInserted(query.update(new UpdateOptions().upsert(true), setOnInsert(Map.of("radius", 2D)))); - - final Circle updatedCircle = getDs().find(Circle.class) - .filter(eq("_id", id)) - .first(); - - assertThat(updatedCircle, is(notNullValue())); - MatcherAssert.assertThat(updatedCircle.getRadius(), is(2D)); - } - - @Test - public void testSetOnInsertWhenUpdating() { - ObjectId id = new ObjectId(); - - Query query = getDs() - .find(Circle.class) - .filter(eq("id", id)); - - assertInserted(query.update(new UpdateOptions().upsert(true), setOnInsert(Map.of("radius", 1D)))); - - assertEquals(query.update(new UpdateOptions().upsert(true), setOnInsert(Map.of("radius", 2D))) - .getMatchedCount(), 1); - - final Circle updatedCircle = getDs().find(Circle.class) - .filter(eq("_id", id)) - .first(); - - assertNotNull(updatedCircle); - assertEquals(updatedCircle.getRadius(), 1D, 0.1); - } - - @Test - public void testSetUnset() { - Datastore ds = getDs(); - final ObjectId key = ds.save(new Circle(1)).getId(); - - Query circle = ds.find(Circle.class) - .filter(eq("radius", 1D)); - assertUpdated(circle.update(set("radius", 2D)), 1); - - Query idQuery = ds.find(Circle.class) - .filter(eq("_id", key)); - MatcherAssert.assertThat(idQuery.first().getRadius(), is(2D)); - - circle = ds.find(Circle.class) - .filter(eq("radius", 2D)); - assertUpdated(circle.update(new UpdateOptions().multi(false), unset("radius")), 1); - - MatcherAssert.assertThat(idQuery.first().getRadius(), is(0D)); - - Book article = new Book(); - - ds.save(article); - - assertEquals(ds.find(Book.class).update(set("title", "Some Title")).getModifiedCount(), 1); - assertNotNull(ds.find(Book.class).filter(eq("title", "Some Title")).first()); - assertNotNull(ds.find(Book.class).filter(eq("name", "Some Title")).first()); - - assertEquals(ds.find(Book.class).update(unset("name")).getModifiedCount(), 1); - assertNull(ds.find(Book.class).filter(eq("title", "Some Title")).first()); - assertNull(ds.find(Book.class).filter(eq("name", "Some Title")).first()); - - assertEquals(ds.find(Book.class).update(set("name", "Some Title")).getModifiedCount(), 1); - assertNotNull(ds.find(Book.class).filter(eq("title", "Some Title")).first()); - assertNotNull(ds.find(Book.class).filter(eq("name", "Some Title")).first()); - - assertEquals(ds.find(Book.class).update(unset("title")).getModifiedCount(), 1); - assertNull(ds.find(Book.class).filter(eq("title", "Some Title")).first()); - assertNull(ds.find(Book.class).filter(eq("name", "Some Title")).first()); - } - - @Test - public void testUpdateFirstNoCreate() { - getDs().find(LogHolder.class).delete(new DeleteOptions().multi(true)); - List logs = new ArrayList<>(); - for (int i = 0; i < 100; i++) { - logs.add(createEntryLogs("logs" + i)); - } - LogHolder logs1 = logs.get(0); - Query query = getDs().find(LogHolder.class); - Document object = new Document("new", "value"); - query.update(set("raw", object)); - - List list = getDs().find(LogHolder.class).iterator().toList(); - for (int i = 0; i < list.size(); i++) { - final LogHolder logHolder = list.get(i); - assertEquals(logHolder.id.equals(logs1.id) ? object : logs.get(i).raw, logHolder.raw); - } - } - - @Test - public void testUpdateMap() { - final Map map = Map.of(TestEnum.ANYVAL, new EmbeddedObjTest("name", "value")); - getDs().find(TestMapWithEnumKey.class) - .update(set("map", map)); - } - @Test public void testUpdateRef() { final ContainsPic cp = new ContainsPic(); @@ -907,33 +275,13 @@ public void testUpdateWithDifferentType() { Query query = getDs().find(ContainsInt.class); final UpdateResult res = query.update(inc("val", 1.1D)); - assertUpdated(res, 1); + assertUpdated(res); assertEquals(query.iterator(new FindOptions() .limit(1)) .next().val, 22); } - @Test - public void testUpdateWithStages(/* MapperOptions options */) { - getDs().save(List.of( - new Student(1L, new Grade(80, singletonMap("name", "Homework")), - new Grade(90, singletonMap("name", "Test"))), - new Student(2L, new Grade(80, singletonMap("name", "Homework")), - new Grade(87, singletonMap("name", "Test"))), - new Student(3L, new Grade(80, singletonMap("name", "Homework")), - new Grade(63, singletonMap("name", "Test"))))); - - Query query = getDs().find(Student.class) - .filter(eq("id", 3)); - assertNull(query.first().notes); - - query.update(set() - .field("notes", "hard worker")); - - assertEquals(query.first().notes, "hard worker"); - } - @Test(expectedExceptions = ValidationException.class) public void testValidationBadFieldName() { Query query = getDs().find(Circle.class) @@ -980,34 +328,17 @@ public void testUpsert() { assertNotNull(query.first(options), query.getLoggedQuery()); } - @Test - public void testXor() { - ContainsInt containsInt = new ContainsInt(); - containsInt.val = 24; - - getDs().save(containsInt); - - getDs().find(ContainsInt.class) - .update(xor("val", 8)); - - ContainsInt first = getDs().find(ContainsInt.class) - .first(); - - assertEquals(first.val, 16); - } - private void assertInserted(UpdateResult res) { assertNotNull(res.getUpsertedId()); assertEquals(res.getModifiedCount(), 0); } - private void assertUpdated(UpdateResult res, long count) { - assertEquals(count, res.getModifiedCount()); + private void assertUpdated(UpdateResult res) { + assertEquals(1, res.getModifiedCount()); } - @SuppressWarnings("rawtypes") private void doUpdates(ContainsIntArray updated, ContainsIntArray control, UpdateResult result, Integer[] target) { - assertUpdated(result, 1); + assertUpdated(result); assertThat(getDs().find(ContainsIntArray.class) .filter(eq("_id", updated.id)) .first().values, @@ -1028,35 +359,12 @@ private void doUpdates(ContainsIntArray updated, ContainsIntArray control, Updat is(new Integer[] { 1, 2, 3 })); } - private void createContainsPic(int size) { - final ContainsPic containsPic = new ContainsPic(); - containsPic.setSize(size); - getDs().save(containsPic); - } - - private LogHolder createEntryLogs(String value) { - LogHolder logs = new LogHolder(); - logs.raw = new Document("name", value); - getDs().save(logs); - - return logs; - } - private Integer[] get(ContainsIntArray array) { return getDs().find(ContainsIntArray.class) .filter(eq("_id", array.id)) .first().values; } - @SuppressWarnings({ "unchecked" }) - private void validateClassName(@Nullable LogHolder loaded) { - assertNotNull(loaded); - List logs = (List) loaded.raw.get("logs"); - for (Document o : logs) { - assertNotNull(o.get(getMapper().getConfig().discriminatorKey()), o.toString()); - } - } - private enum TestEnum { ANYVAL, ANOTHERVAL @@ -1131,28 +439,20 @@ public Log(long value) { receivedTs = value; } - @Override - public int hashCode() { - int result = (int) (receivedTs ^ (receivedTs >>> 32)); - result = 31 * result + value.hashCode(); - return result; - } - @Override public boolean equals(Object o) { if (this == o) { return true; } - if (!(o instanceof Log)) { + if (!(o instanceof Log log)) { return false; } + return receivedTs == log.receivedTs && Objects.equals(value, log.value); + } - final Log log = (Log) o; - - if (receivedTs != log.receivedTs) { - return false; - } - return value.equals(log.value); + @Override + public int hashCode() { + return Objects.hash(receivedTs, value); } @Override @@ -1276,6 +576,7 @@ private static Iterator paths() { List list = new ArrayList<>(); list.addAll(prepParams("stars", "s")); + assertEquals(list.size(), countUpdateOperators(), "Should have checks for all UpdateOperators methods"); list.addAll(prepParams("s", "s")); list.addAll(prepParams("address.street", "addr.address_street")); @@ -1287,6 +588,11 @@ private static Iterator paths() { return list.iterator(); } + private static int countUpdateOperators() { + // dec by 1 to exclude set(Entity) since there will be no path translation to check + return UpdateOperators.class.getDeclaredMethods().length - 1; + } + @NotNull private static List prepParams(String updateName, String mappedName) { LocalTime now = LocalTime.of(15, 16, 17); @@ -1295,6 +601,7 @@ private static List prepParams(String updateName, String mapp new TranslationParams(updateName, mappedName, addToSet(updateName, "MARKER")), new TranslationParams(updateName, mappedName, addToSet(updateName, List.of("MARKER"))), new TranslationParams(updateName, mappedName, and(updateName, 42)), + new TranslationParams(updateName, mappedName, bit(updateName, 42)), new TranslationParams(updateName, mappedName, currentDate(updateName)), new TranslationParams(updateName, mappedName, dec(updateName)), new TranslationParams(updateName, mappedName, dec(updateName, 42)), @@ -1310,38 +617,30 @@ private static List prepParams(String updateName, String mapp new TranslationParams(updateName, mappedName, or(updateName, 42)), new TranslationParams(updateName, mappedName, pop(updateName)), new TranslationParams(updateName, mappedName, pull(updateName, eq("name", "MARKER"))), + new TranslationParams(updateName, mappedName, pull(updateName, "carrots")), new TranslationParams(updateName, mappedName, pullAll(updateName, List.of("MARKER"))), new TranslationParams(updateName, mappedName, push(updateName, "MARKER")), new TranslationParams(updateName, mappedName, push(updateName, List.of("MARKER"))), new TranslationParams(updateName, mappedName, rename(updateName, "MARKER")), new TranslationParams(updateName, mappedName, set(updateName, "MARKER")), new TranslationParams(updateName, mappedName, setOnInsert(Map.of(mappedName, "MARKER"))), - new TranslationParams(updateName, mappedName, unset(updateName)), + new TranslationParams(updateName, mappedName, unset(updateName, updateName, updateName, updateName)), new TranslationParams(updateName, mappedName, xor(updateName, 42))); } - public static class TranslationParams { - private String updateName; - private String mappedName; - final UpdateOperator operator; - - public TranslationParams(String updateName, String mappedName, UpdateOperator operator) { - this.updateName = updateName; - this.mappedName = mappedName; - this.operator = operator; - } + public record TranslationParams(String updateName, String mappedName, UpdateOperator operator) { } @Test(dataProvider = "paths") - public void testPathTranslations(TranslationParams params) { + public void testPathTranslations(TestUpdateOperations.TranslationParams params) { CodecRegistry registry = getDs().getCodecRegistry(); - Operations value = new Operations(getMapper().getEntityModel(Hotel.class), List.of(params.operator), false); + Operations value = new Operations(getDs(), getMapper().getEntityModel(Hotel.class), List.of(params.operator), true); - var json = value.toDocument(getDs()) - .toJson(WRITER_SETTINGS, registry.get(Document.class)); + var json = toString(value.toDocument(getDs())); String format = format("\"%s\"", params.mappedName); - assertTrue(json.contains(format), format("failed to find '%s' in:%n%s", format, json)); + boolean contains = json.contains(format); + assertTrue(contains, format("failed to find '%s' in:%n%s", format, json)); } } diff --git a/core/src/test/java/dev/morphia/test/Versions.java b/core/src/test/java/dev/morphia/test/Versions.java index a43f887b4f9..9f072cdccf2 100644 --- a/core/src/test/java/dev/morphia/test/Versions.java +++ b/core/src/test/java/dev/morphia/test/Versions.java @@ -5,54 +5,51 @@ import java.util.List; import java.util.StringJoiner; -import com.github.zafarkhaja.semver.Version; - import dev.morphia.sofia.Sofia; +import org.semver4j.Semver; import org.testcontainers.utility.DockerImageName; -import static com.github.zafarkhaja.semver.Version.forIntegers; - public enum Versions { Version7 { @Override - Version version() { - return forIntegers(7).setBuildMetadata("latest"); + Semver version() { + return Semver.of(7, 0, 0).withBuild("latest"); } }, Version6 { @Override - Version version() { - return forIntegers(6).setBuildMetadata("latest"); + Semver version() { + return Semver.of(6, 0, 0).withBuild("latest"); } }, Version5 { @Override - Version version() { - return forIntegers(5).setBuildMetadata("latest"); + Semver version() { + return Semver.of(5, 0, 0).withBuild("latest"); } }, Version44 { @Override - Version version() { - return forIntegers(4, 4, 19); + Semver version() { + return Semver.of(4, 4, 19); } }, Version42 { @Override - Version version() { - return forIntegers(4, 2, 24); + Semver version() { + return Semver.of(4, 2, 24); } }, Version40 { @Override - Version version() { - return forIntegers(4, 0, 28); + Semver version() { + return Semver.of(4, 0, 28); } }; - public static Versions find(Version target) { + public static Versions find(Semver target) { for (Versions value : values()) { if (value.matches(target)) { return value; @@ -61,10 +58,10 @@ public static Versions find(Version target) { return null; } - private boolean matches(Version target) { - boolean latest = version().getBuildMetadata().equals("latest"); - return target.getMajorVersion() == version().getMajorVersion() - && (latest || target.getMinorVersion() == version().getMinorVersion()); + private boolean matches(Semver target) { + boolean latest = version().getBuild().contains("latest"); + return target.getMajor() == version().getMajor() + && (latest || target.getMinor() == version().getMinor()); } public static Versions latest() { @@ -80,20 +77,20 @@ public static Versions bestMatch(String mongo) { for (String part : parts) { joiner.add(part); } - Version suggested = Version.valueOf(joiner.toString()); + Semver suggested = Semver.parse(joiner.toString()); return Arrays.stream(values()) - .filter(it -> it.version().getMajorVersion() == suggested.getMajorVersion() - && it.version().getMinorVersion() == suggested.getMinorVersion()) + .filter(it -> it.version().getMajor() == suggested.getMajor() + && it.version().getMinor() == suggested.getMinor()) .findFirst() .orElseThrow(() -> new IllegalArgumentException(Sofia.unknownMongoDbVersion(suggested))); } final DockerImageName dockerImage() { - Version version = version(); + Semver version = version(); String tag; - if ("latest".equals(version.getBuildMetadata())) { - tag = String.valueOf(version.getMajorVersion()); + if (version.getBuild().contains("latest")) { + tag = String.valueOf(version.getMajor()); } else { tag = version.toString(); } @@ -101,17 +98,17 @@ final DockerImageName dockerImage() { .asCompatibleSubstituteFor("mongo"); } - abstract Version version(); + abstract Semver version(); @Override public String toString() { - Version version = version(); + Semver version = version(); var numbers = new StringJoiner("."); - numbers.add(String.valueOf(version.getMajorVersion())); - if (version.getMinorVersion() != 0 || version.getPatchVersion() != 0) { - numbers.add(String.valueOf(version().getMinorVersion())) - .add(String.valueOf(version().getPatchVersion())); + numbers.add(String.valueOf(version.getMajor())); + if (version.getMinor() != 0 || version.getPatch() != 0) { + numbers.add(String.valueOf(version().getMinor())) + .add(String.valueOf(version().getPatch())); } return numbers.toString(); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/AggregationTest.java b/core/src/test/java/dev/morphia/test/aggregation/AggregationTest.java deleted file mode 100644 index 12f9d2e1269..00000000000 --- a/core/src/test/java/dev/morphia/test/aggregation/AggregationTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2008 - 2013 MongoDB, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.morphia.test.aggregation; - -import java.io.File; -import java.util.Arrays; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; - -import dev.morphia.aggregation.Aggregation; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.TemplatedTestBase; -import dev.morphia.test.aggregation.model.Martian; -import dev.morphia.test.models.User; - -import org.bson.Document; -import org.jetbrains.annotations.NotNull; -import org.testng.annotations.AfterClass; - -import static java.util.Arrays.stream; -import static org.testng.Assert.fail; - -@SuppressWarnings({ "unused", "MismatchedQueryAndUpdateOfCollection" }) -public class AggregationTest extends TemplatedTestBase { - - public AggregationTest() { - super(buildConfig(Martian.class, User.class) - .applyIndexes(true) - .codecProvider(new ZDTCodecProvider())); - } - - @AfterClass - public void testCoverage() { - var type = getClass(); - var methods = stream(type.getDeclaredMethods()) - .filter(m -> m.getName().startsWith("testExample")) - .map(m -> { - String name = m.getName().substring(4); - return Character.toLowerCase(name.charAt(0)) + name.substring(1); - }) - .toList(); - String path = type.getPackageName(); - String simpleName = type.getSimpleName().substring(4); - var operatorName = Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1); - var resourceFolder = rootToCore("src/test/resources/%s/%s".formatted(path.replace('.', '/'), operatorName)); - - if (!resourceFolder.exists()) { - throw new IllegalStateException("%s does not exist inside %s".formatted(resourceFolder, - new File(".").getAbsolutePath())); - } - List list = Arrays.stream(resourceFolder.list()) - .map(s -> new File(resourceFolder, s)) - .toList(); - - List examples = list.stream() - .filter(d -> new File(d, "expected.json").exists()) - .map(File::getName) - .toList(); - var missing = examples.stream() - .filter(example -> !methods.contains(example)) - .collect(Collectors.joining(", ")); - if (!missing.isEmpty()) { - fail("Missing test cases for $%s: %s".formatted(operatorName, missing)); - } - } - - @NotNull - public static File rootToCore(String path) { - return new File(CORE_ROOT, path); - } - - public void testPipeline(ServerVersion serverVersion, - Function, Aggregation> pipeline) { - testPipeline(serverVersion, true, true, pipeline); - } - -} diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAbs.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAbs.java index 4380cd2d502..d528b899301 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAbs.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAbs.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,13 +10,15 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.ANY; -public class TestAbs extends AggregationTest { - @Test +public class TestAbs extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/abs/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - project() - .include("delta", - abs(subtract("$startTemp", "$endTemp"))))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation + .pipeline(project().include("delta", abs(subtract("$startTemp", "$endTemp"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAccumulator.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAccumulator.java index 417fa6cc64f..023bb431c20 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAccumulator.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAccumulator.java @@ -3,74 +3,73 @@ import java.util.List; import dev.morphia.aggregation.stages.Group; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.AccumulatorExpressions.accumulator; import static dev.morphia.test.ServerVersion.ANY; -public class TestAccumulator extends AggregationTest { - @Test +public class TestAccumulator extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/accumulator/example1 + * + */ + @Test(testName = "Use ``$accumulator`` to Implement the ``$avg`` Operator") public void testExample1() { - skipPipelineCheck(); - testPipeline(ANY, false, false, aggregation -> aggregation - .pipeline(Group.group(Group.id("$author")) - .field("avgCopies", accumulator( - """ - function() { - return { count: 0, sum: 0 } - } - """, - """ - function(state, numCopies) { - return { - count: state.count + 1, - sum: state.sum + numCopies - } - }""", - List.of("$copies"), - """ - function(state1, state2) { - return { - count: state1.count + state2.count, - sum: state1.sum + state2.sum - } - }""").finalizeFunction(""" - function(state) { - return (state.sum / state.count) - }""")))); + testPipeline(new ActionTestOptions().serverVersion(ANY).orderMatters(false).skipActionCheck(true), + aggregation -> aggregation.pipeline(Group.group(Group.id("$author")).field("avgCopies", accumulator(""" + function() { + return { count: 0, sum: 0 } + } + """, """ + function(state, numCopies) { + return { + count: state.count + 1, + sum: state.sum + numCopies + } + }""", List.of("$copies"), """ + function(state1, state2) { + return { + count: state1.count + state2.count, + sum: state1.sum + state2.sum + } + }""").finalizeFunction(""" + function(state) { + return (state.sum / state.count) + }""")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/accumulator/example2 + * + */ + @Test(testName = "Use ``initArgs`` to Vary the Initial State by Group") public void testExample2() { - skipPipelineCheck(); - testPipeline(ANY, false, false, aggregation -> aggregation - .pipeline(Group.group(Group.id().field("city", "$city")) - .field("restaurants", accumulator( - """ - function(city, userProfileCity) { \s - return { - max: city === userProfileCity ? 3 : 1, \s - restaurants: [] \s - }\s - }""", + testPipeline(new ActionTestOptions().serverVersion(ANY).orderMatters(false).skipActionCheck(true), + aggregation -> aggregation.pipeline(Group.group(Group.id().field("city", "$city")).field("restaurants", + accumulator(""" + function(city, userProfileCity) { \s + return { + max: city === userProfileCity ? 3 : 1, \s + restaurants: [] \s + }\s + }""", """ + function(state, restaurantName) { \s + if (state.restaurants.length < state.max) { + state.restaurants.push(restaurantName); + } + return state; + }""", List.of("$name"), """ - function(state, restaurantName) { \s - if (state.restaurants.length < state.max) { - state.restaurants.push(restaurantName); - } - return state; - }""", - List.of("$name"), """ function(state1, state2) { \s return { max: state1.max, restaurants: state1.restaurants.concat(state2.restaurants).slice(0, state1.max) }\s }""") - .initArgs(List.of("$city", "Bettles")) - .finalizeFunction(""" + .initArgs(List.of("$city", "Bettles")).finalizeFunction(""" function(state) { return state.restaurants }""")))); diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcos.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcos.java index 96c5b000e25..449c110569f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcos.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcos.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -10,29 +11,26 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.test.ServerVersion.ANY; -public class TestAcos extends AggregationTest { - @Test +public class TestAcos extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/acos/example1 + * + */ + @Test(testName = "main :: Inverse Cosine of Value in Degrees") public void testExample1() { - testPipeline(ANY, false, true, aggregation -> aggregation - .pipeline(addFields() - .field("angle_a", - radiansToDegrees( - acos( - divide( - "$side_b", - "$hypotenuse")))))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation + .pipeline(addFields().field("angle_a", radiansToDegrees(acos(divide("$side_b", "$hypotenuse")))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/acos/example2 + * + */ + @Test(testName = "main :: Inverse Cosine of Value in Radians") public void testExample2() { - testPipeline(ANY, false, true, aggregation -> aggregation - .pipeline(addFields() - .field("angle_a", - acos( - divide( - "$side_b", - "$hypotenuse"))))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation + .pipeline(addFields().field("angle_a", acos(divide("$side_b", "$hypotenuse"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcosh.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcosh.java index c7a8045a694..5f04a7fefb8 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcosh.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcosh.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,22 +10,26 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.test.ServerVersion.ANY; -public class TestAcosh extends AggregationTest { - @Test +public class TestAcosh extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/acosh/example1 + * + */ + @Test(testName = "main :: Inverse Hyperbolic Cosine in Degrees") public void testExample1() { - testPipeline(ANY, false, true, aggregation -> aggregation - .pipeline(addFields() - .field("y-coordinate", - radiansToDegrees(acosh("$x-coordinate"))))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation + .pipeline(addFields().field("y-coordinate", radiansToDegrees(acosh("$x-coordinate"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/acosh/example2 + * + */ + @Test(testName = "main :: Inverse Hyperbolic Cosine in Radians") public void testExample2() { - testPipeline(ANY, false, true, aggregation -> aggregation - .pipeline(addFields() - .field("y-coordinate", - acosh("$x-coordinate")))); + testPipeline(new ActionTestOptions().serverVersion(ANY), + aggregation -> aggregation.pipeline(addFields().field("y-coordinate", acosh("$x-coordinate")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAdd.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAdd.java index 0763bf6f171..e542837a822 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAdd.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAdd.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -8,22 +9,25 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.ANY; -public class TestAdd extends AggregationTest { - @Test +public class TestAdd extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/add/example1 + * + */ + @Test(testName = "Add Numbers") public void testExample1() { - testPipeline(ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("total", add("$price", "$fee")))); + testPipeline(new ActionTestOptions().serverVersion(ANY), (aggregation) -> aggregation + .pipeline(project().include("item").include("total", add("$price", "$fee")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/add/example2 + * + */ + @Test(testName = "Perform Addition on a Date") public void testExample2() { - testPipeline(ANY, false, true, aggregation -> aggregation - .pipeline(project() - .include("item", 1) - .include("billing_date", - add("$date", 259200000)))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation + .pipeline(project().include("item", 1).include("billing_date", add("$date", 259200000)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAddToSet.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAddToSet.java index 26fc84de8d0..3166bd502b4 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAddToSet.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAddToSet.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.stages.Group; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -14,30 +15,33 @@ import static dev.morphia.query.Sort.ascending; import static dev.morphia.test.ServerVersion.ANY; -public class TestAddToSet extends AggregationTest { - @Test +public class TestAddToSet extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/addToSet/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(ANY, false, false, aggregation -> aggregation - .pipeline(group(Group.id() - .field("day", dayOfYear("$date")) - .field("year", year("$date"))) - .field("itemsSold", addToSet("$item"))) + testPipeline(new ActionTestOptions().serverVersion(ANY).orderMatters(false), + aggregation -> aggregation + .pipeline(group(Group.id().field("day", dayOfYear("$date")).field("year", year("$date"))) + .field("itemsSold", addToSet("$item"))) ); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/addToSet/example2 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample2() { if (1 == 1) return; - testPipeline(ANY, false, false, aggregation -> aggregation - .setWindowFields(setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("cakeTypesForState") - .operator(addToSet("$type")) - .window() - .documents("unbounded", "current")))); + testPipeline(new ActionTestOptions().serverVersion(ANY).orderMatters(false), + aggregation -> aggregation.setWindowFields(setWindowFields().partitionBy("$state") + .sortBy(ascending("orderDate")).output(output("cakeTypesForState").operator(addToSet("$type")) + .window().documents("unbounded", "current")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAllElementsTrue.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAllElementsTrue.java index 456a21c0b7b..704321549d7 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAllElementsTrue.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAllElementsTrue.java @@ -1,20 +1,23 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.stages.Projection; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.SetExpressions.allElementsTrue; import static dev.morphia.test.ServerVersion.ANY; -public class TestAllElementsTrue extends AggregationTest { - @Test +public class TestAllElementsTrue extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/allElementsTrue/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ANY, false, false, aggregation -> aggregation - .pipeline(Projection.project() - .suppressId() - .include("responses") + testPipeline(new ActionTestOptions().serverVersion(ANY).orderMatters(false), + aggregation -> aggregation.pipeline(Projection.project().suppressId().include("responses") .include("isAllTrue", allElementsTrue("$responses")))); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnd.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnd.java index c7ee93baf95..47482c433db 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnd.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnd.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -10,14 +11,15 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.ANY; -public class TestAnd extends AggregationTest { - @Test +public class TestAnd extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/and/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - project() - .include("item") - .include("qty") - .include("result", and(gt("$qty", 100), lt("$qty", 250))))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation.pipeline( + project().include("item").include("qty").include("result", and(gt("$qty", 100), lt("$qty", 250))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnyElementTrue.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnyElementTrue.java index 5fce9274321..dbc65e0d3ed 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnyElementTrue.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnyElementTrue.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -8,14 +9,15 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.ANY; -public class TestAnyElementTrue extends AggregationTest { - @Test +public class TestAnyElementTrue extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/anyElementTrue/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - project() - .suppressId() - .include("responses") - .include("isAnyTrue", anyElementTrue("$responses")))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation.pipeline( + project().suppressId().include("responses").include("isAnyTrue", anyElementTrue("$responses")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayElemAt.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayElemAt.java index d67c7b44705..01e4446f8c9 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayElemAt.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayElemAt.java @@ -1,20 +1,20 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ArrayExpressions.elementAt; import static dev.morphia.aggregation.stages.Projection.project; -public class TestArrayElemAt extends AggregationTest { - @Test +public class TestArrayElemAt extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/arrayElemAt/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name") - .include("first", elementAt("$favorites", 0)) - .include("last", elementAt("$favorites", -1)))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("name") + .include("first", elementAt("$favorites", 0)).include("last", elementAt("$favorites", -1)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayToObject.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayToObject.java index ff4f60e2e34..a1d81c06e26 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayToObject.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayToObject.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -14,28 +13,27 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Projection.project; -public class TestArrayToObject extends AggregationTest { - @Test +public class TestArrayToObject extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/arrayToObject/example1 + * + */ + @Test(testName = "``$arrayToObject`` Example") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("dimensions", arrayToObject("$dimensions")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("dimensions", arrayToObject("$dimensions")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/arrayToObject/example2 + * + */ + @Test(testName = "``$objectToArray`` + ``$arrayToObject`` Example") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("instock", objectToArray("$instock")), - addFields() - .field("instock", concatArrays( - "$instock", - array(document() - .field("k", "total") - .field("v", sum("$instock.v"))))), - addFields() - .field("instock", arrayToObject("$instock")))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("instock", objectToArray("$instock")), + addFields().field("instock", + concatArrays("$instock", array(document().field("k", "total").field("v", sum("$instock.v"))))), + addFields().field("instock", arrayToObject("$instock")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsin.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsin.java index 12c3b7d8f3b..b566c84cf4a 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsin.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsin.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,19 +9,25 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.radiansToDegrees; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestAsin extends AggregationTest { - @Test +public class TestAsin extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/asin/example1 + * + */ + @Test(testName = "main :: Inverse Sine of Value in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("angle_a", radiansToDegrees(asin(divide("$side_a", "$hypotenuse")))))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("angle_a", radiansToDegrees(asin(divide("$side_a", "$hypotenuse")))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/asin/example2 + * + */ + @Test(testName = "main :: Inverse Sine of Value in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("angle_a", asin(divide("$side_a", "$hypotenuse"))))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("angle_a", asin(divide("$side_a", "$hypotenuse"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsinh.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsinh.java index 0901bcb6d48..adea3711b59 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsinh.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsinh.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,19 +8,24 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.radiansToDegrees; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestAsinh extends AggregationTest { - @Test +public class TestAsinh extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/asinh/example1 + * + */ + @Test(testName = "main :: Inverse Hyperbolic Sine in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("y-coordinate", radiansToDegrees(asinh("$x-coordinate"))))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("y-coordinate", radiansToDegrees(asinh("$x-coordinate"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/asinh/example2 + * + */ + @Test(testName = "main :: Inverse Hyperbolic Sine in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("y-coordinate", asinh("$x-coordinate")))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("y-coordinate", asinh("$x-coordinate")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan.java index 82c322f8867..3c4d84caedd 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,19 +9,25 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.radiansToDegrees; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestAtan extends AggregationTest { - @Test +public class TestAtan extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/atan/example1 + * + */ + @Test(testName = "main :: Inverse Tangent of Value in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("angle_a", radiansToDegrees(atan(divide("$side_b", "$side_a")))))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("angle_a", radiansToDegrees(atan(divide("$side_b", "$side_a")))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/atan/example2 + * + */ + @Test(testName = "main :: Inverse Tangent of Value in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("angle_a", atan(divide("$side_b", "$side_a"))))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("angle_a", atan(divide("$side_b", "$side_a"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan2.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan2.java index 7c301bad818..33a5244fb63 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan2.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan2.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,19 +8,24 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.radiansToDegrees; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestAtan2 extends AggregationTest { - @Test +public class TestAtan2 extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/atan2/example1 + * + */ + @Test(testName = "main :: Inverse Tangent of Value in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("angle_a", radiansToDegrees(atan2("$side_b", "$side_a"))))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("angle_a", radiansToDegrees(atan2("$side_b", "$side_a"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/atan2/example2 + * + */ + @Test(testName = "main :: Inverse Tangent of Value in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("angle_a", atan2("$side_b", "$side_a")))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("angle_a", atan2("$side_b", "$side_a")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtanh.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtanh.java index bafa5434480..d69a73c3fb7 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtanh.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtanh.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,19 +8,24 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.radiansToDegrees; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestAtanh extends AggregationTest { - @Test +public class TestAtanh extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/atanh/example1 + * + */ + @Test(testName = "main :: Inverse Hyperbolic Tangent in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("y-coordinate", radiansToDegrees(atanh("$x-coordinate"))))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("y-coordinate", radiansToDegrees(atanh("$x-coordinate"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/atanh/example2 + * + */ + @Test(testName = "main :: Inverse Hyperbolic Tangent in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("y-coordinate", atanh("$x-coordinate")))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("y-coordinate", atanh("$x-coordinate")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAvg.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAvg.java index 159be8514e6..012628d6d43 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAvg.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAvg.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.stages.Projection; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -11,38 +12,45 @@ import static dev.morphia.aggregation.stages.Group.id; import static dev.morphia.test.ServerVersion.ANY; -public class TestAvg extends AggregationTest { - @Test +public class TestAvg extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/avg/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(ANY, false, false, aggregation -> aggregation - .pipeline(group(id("$item")) - .field("avgAmount", avg(multiply("$price", "$quantity"))) - .field("avgQuantity", avg("$quantity")))); + testPipeline(new ActionTestOptions().serverVersion(ANY).orderMatters(false), + aggregation -> aggregation + .pipeline(group(id("$item")).field("avgAmount", avg(multiply("$price", "$quantity"))) + .field("avgQuantity", avg("$quantity")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/avg/example2 + * + */ + @Test(testName = "Use in ``$project`` Stage") public void testExample2() { - testPipeline(ANY, false, false, aggregation -> aggregation - .project(Projection.project() - .include("quizAvg", avg("$quizzes")) - .include("labAvg", avg("$labs")) - .include("examAvg", avg("$final", "$midterm")))); + testPipeline(new ActionTestOptions().serverVersion(ANY).orderMatters(false), + aggregation -> aggregation.project(Projection.project().include("quizAvg", avg("$quizzes")) + .include("labAvg", avg("$labs")).include("examAvg", avg("$final", "$midterm")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/avg/example3 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample3() { // this has an include and throws off the parser /* - * testPipeline(v50, false, false, aggregation -> aggregation - * .setWindowFields(SetWindowFields.setWindowFields() - * .partitionBy("$state") - * .sortBy(ascending("orderDate")) - * .output(output("averageQuantityForState") - * .operator(avg("$quantity")) - * .window() - * .documents("unbounded", "current")) + * testPipeline(new dev.morphia.test.util.ActionTestOptions().serverVersion(v50) + * .orderMatters(false), aggregation -> aggregation + * .setWindowFields(SetWindowFields.setWindowFields() .partitionBy("$state") + * .sortBy(ascending("orderDate")) .output(output("averageQuantityForState") + * .operator(avg("$quantity")) .window() .documents("unbounded", "current")) * * ) * diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBinarySize.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBinarySize.java index 3b5288cece2..3b6ca840909 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBinarySize.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBinarySize.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,23 +9,26 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.aggregation.stages.Sort.sort; -public class TestBinarySize extends AggregationTest { - @Test +public class TestBinarySize extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/binarySize/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name", "$name") - .include("imageSize", binarySize("$binary")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("name", "$name").include("imageSize", binarySize("$binary")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/binarySize/example2 + * + */ + @Test(testName = "Find Largest Binary Data") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name", "$name") - .include("imageSize", binarySize("$binary")), - sort().descending("imageSize"), - limit(1))); + testPipeline((aggregation) -> aggregation.pipeline( + project().include("name", "$name").include("imageSize", binarySize("$binary")), + sort().descending("imageSize"), limit(1))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitAnd.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitAnd.java index 57135334be5..b3588b38d06 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitAnd.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitAnd.java @@ -2,30 +2,34 @@ import java.io.FileNotFoundException; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.bitAnd; import static dev.morphia.aggregation.stages.Projection.project; -import static dev.morphia.test.ServerVersion.v63; +import static dev.morphia.test.ServerVersion.v70; -public class TestBitAnd extends AggregationTest { +public class TestBitAnd extends TemplatedTestBase { - @Test - public void testExample2() throws FileNotFoundException { - testPipeline(v63, false, true, aggregation -> aggregation - .pipeline(project() - .include("result", - bitAnd("$a", "$b")))); + /** + * test data: dev/morphia/test/aggregation/expressions/bitAnd/example1 + */ + @Test(testName = "Bitwise ``AND`` with Two Integers ") + public void testExample1() { + testPipeline(new ActionTestOptions().serverVersion(v70), + aggregation -> aggregation.pipeline(project().include("result", bitAnd("$a", "$b")))); } - @Test - public void testExample3() { - testPipeline(v63, false, true, aggregation -> aggregation - .project(project() - .include("result", - bitAnd("$a", 63L)))); + /** + * test data: dev/morphia/test/aggregation/expressions/bitAnd/example2 + * + */ + @Test(testName = "Bitwise ``AND`` with a Long and Integer ") + public void testExample2() throws FileNotFoundException { + testPipeline(new ActionTestOptions().serverVersion(v70), + aggregation -> aggregation.project(project().include("result", bitAnd("$a", 63L)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitNot.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitNot.java index 43056d47868..30e6e19b3da 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitNot.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitNot.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -8,13 +9,15 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.v63; -public class TestBitNot extends AggregationTest { +public class TestBitNot extends TemplatedTestBase { - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/bitNot/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(v63, false, true, aggregation -> aggregation - .pipeline(project() - .include("result", - bitNot("$a")))); + testPipeline(new ActionTestOptions().serverVersion(v63), + aggregation -> aggregation.pipeline(project().include("result", bitNot("$a")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitOr.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitOr.java index 41a0d5e2a35..98f98229be3 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitOr.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitOr.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -8,21 +9,25 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.v63; -public class TestBitOr extends AggregationTest { +public class TestBitOr extends TemplatedTestBase { - @Test - public void testExample2() { - testPipeline(v63, false, true, aggregation -> aggregation - .pipeline(project() - .include("result", - bitOr("$a", "$b")))); + /** + * test data: dev/morphia/test/aggregation/expressions/bitOr/example1 + */ + @Test(testName = "Bitwise ``OR`` with Two Integers ") + public void testExample1() { + testPipeline(new ActionTestOptions().serverVersion(v63), + aggregation -> aggregation.pipeline(project().include("result", bitOr("$a", "$b")))); } - @Test - public void testExample3() { - testPipeline(v63, false, false, aggregation -> aggregation - .project(project() - .include("result", - bitOr("$a", 63L)))); + /** + * test data: dev/morphia/test/aggregation/expressions/bitOr/example2 + * + */ + @Test(testName = "Bitwise ``OR`` with a Long and Integer ", enabled = false, description = "this is getting odd unexpected results from the server") + public void testExample2() { + testPipeline(new ActionTestOptions().serverVersion(v63).removeIds(true).orderMatters(false), + aggregation -> aggregation.project(project().include("result", bitOr("$a", 63L)))); } + } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitXor.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitXor.java index c08cc691176..7db3bea5b79 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitXor.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitXor.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -8,13 +9,15 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.v63; -public class TestBitXor extends AggregationTest { +public class TestBitXor extends TemplatedTestBase { - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/bitXor/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(v63, false, true, aggregation -> aggregation - .pipeline(project() - .include("result", - bitXor("$a", "$b")))); + testPipeline(new ActionTestOptions().serverVersion(v63), + aggregation -> aggregation.pipeline(project().include("result", bitXor("$a", "$b")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottom.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottom.java index 81ee79502dc..9b6a0391628 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottom.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottom.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -13,25 +14,27 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.test.ServerVersion.v52; -public class TestBottom extends AggregationTest { - @Test +public class TestBottom extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/bottom/example1 + * + */ + @Test(testName = "Find the Bottom ``Score``") public void testExample1() { - testPipeline(v52, false, false, (aggregation) -> aggregation - .pipeline( - match(eq("gameId", "G1")), - group(id("$gameId")) - .field("playerId", bottom( - array("$playerId", "$score"), - descending("score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(match(eq("gameId", "G1")), group(id("$gameId")).field("playerId", + bottom(array("$playerId", "$score"), descending("score"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/bottom/example2 + * + */ + @Test(testName = "Finding the Bottom ``Score`` Across Multiple Games") public void testExample2() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id("$gameId")) - .field("playerId", - bottom(array("$playerId", "$score"), - descending("score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id("$gameId")).field("playerId", + bottom(array("$playerId", "$score"), descending("score"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottomN.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottomN.java index 7c2f340a2cd..b92699c5184 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottomN.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottomN.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.query.filters.Filters; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -16,40 +17,38 @@ import static dev.morphia.query.Sort.descending; import static dev.morphia.test.ServerVersion.v52; -public class TestBottomN extends AggregationTest { - @Test +public class TestBottomN extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/bottomN/example1 + * + */ + @Test(testName = "Find the Three Lowest ``Scores``") public void testExample1() { - testPipeline(v52, false, false, (aggregation) -> aggregation - .pipeline( - match(Filters.eq("gameId", "G1")), - group(id("$gameId")) - .field("playerId", bottomN( - 3, - array("$playerId", "$score"), - descending("score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(match(Filters.eq("gameId", "G1")), group(id("$gameId")) + .field("playerId", bottomN(3, array("$playerId", "$score"), descending("score"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/bottomN/example2 + * + */ + @Test(testName = "Finding the Three Lowest Score Documents Across Multiple Games") public void testExample2() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id("$gameId")) - .field("playerId", bottomN( - 3, - array("$playerId", "$score"), - descending("score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id("$gameId")).field("playerId", + bottomN(3, array("$playerId", "$score"), descending("score"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/bottomN/example3 + * + */ + @Test(testName = "Computing ``n`` Based on the Group Key for ``$group``") public void testExample3() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id(document("gameId", "$gameId"))) - .field("gamescores", bottomN( - condition( - eq("$gameId", "G2"), - 1, - 3), - "$score", - descending("score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id(document("gameId", "$gameId"))).field("gamescores", + bottomN(condition(eq("$gameId", "G2"), 1, 3), "$score", descending("score"))))); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBsonSize.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBsonSize.java index dd07d4fc1c0..10d7d6c61f6 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBsonSize.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBsonSize.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -14,36 +15,39 @@ import static dev.morphia.aggregation.stages.Sort.sort; import static dev.morphia.test.ServerVersion.ANY; -public class TestBsonSize extends AggregationTest { - @Test +public class TestBsonSize extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/bsonSize/example1 + * + */ + @Test(testName = "Return Sizes of Documents") public void testExample1() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - project() - .include("name") - .include("object_size", - bsonSize(ROOT)))); + testPipeline(new ActionTestOptions().serverVersion(ANY), + aggregation -> aggregation.pipeline(project().include("name").include("object_size", bsonSize(ROOT)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/bsonSize/example2 + * + */ + @Test(testName = "Return Combined Size of All Documents in a Collection") public void testExample2() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - group(id(null)) - .field("combined_object_size", - sum(bsonSize(ROOT))))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation + .pipeline(group(id(null)).field("combined_object_size", sum(bsonSize(ROOT))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/bsonSize/example3 + * + */ + @Test(testName = "Return Document with Largest Specified Field") public void testExample3() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - project() - .include("name", "$name") - .include("task_object_size", - bsonSize("$$CURRENT")), - sort() - .descending("task_object_size"), - limit(1))); + testPipeline(new ActionTestOptions().serverVersion(ANY), + aggregation -> aggregation.pipeline( + project().include("name", "$name").include("task_object_size", bsonSize("$$CURRENT")), + sort().descending("task_object_size"), limit(1))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCeil.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCeil.java index d994c050805..3deb7203d17 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCeil.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCeil.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.ceil; import static dev.morphia.aggregation.stages.Projection.project; -public class TestCeil extends AggregationTest { - @Test +public class TestCeil extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/ceil/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("value") - .include("ceilingValue", ceil("$value")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("value").include("ceilingValue", ceil("$value")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCmp.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCmp.java index 99f9f7ef222..9bd43e83aeb 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCmp.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCmp.java @@ -1,22 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ComparisonExpressions.cmp; import static dev.morphia.aggregation.stages.Projection.project; -public class TestCmp extends AggregationTest { - @Test +public class TestCmp extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/cmp/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("item") - .include("qty") - .include("cmpTo250", cmp("$qty", 250)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().suppressId().include("item").include("qty").include("cmpTo250", cmp("$qty", 250)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcat.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcat.java index 587bc0bd2e2..1350fbe4350 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcat.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcat.java @@ -1,19 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.concat; import static dev.morphia.aggregation.stages.Projection.project; -public class TestConcat extends AggregationTest { - @Test +public class TestConcat extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/concat/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("itemDescription", concat("$item", " - ", "$description")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("itemDescription", concat("$item", " - ", "$description")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcatArrays.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcatArrays.java index 99f7bb107f7..03e044a20fd 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcatArrays.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcatArrays.java @@ -1,19 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ArrayExpressions.concatArrays; import static dev.morphia.aggregation.stages.Projection.project; -public class TestConcatArrays extends AggregationTest { - @Test +public class TestConcatArrays extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/concatArrays/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("items", concatArrays("$instock", "$ordered")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("items", concatArrays("$instock", "$ordered")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCond.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCond.java index 5d43625c530..99f8ad1955e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCond.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCond.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,13 +10,15 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.ANY; -public class TestCond extends AggregationTest { - @Test +public class TestCond extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/cond/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - project() - .include("item") - .include("discount", condition(gte("$qty", 250), 30, 20)))); + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation + .pipeline(project().include("item").include("discount", condition(gte("$qty", 250), 30, 20)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConvert.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConvert.java index 4d25f9b3916..a433ffe6c9a 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConvert.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConvert.java @@ -2,7 +2,8 @@ import dev.morphia.aggregation.expressions.StringExpressions; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -17,29 +18,21 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Projection.project; -public class TestConvert extends AggregationTest { - @Test +public class TestConvert extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/convert/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("convertedPrice", convert( - "$price", DECIMAL) - .onError("Error") - .onNull(0.0)) - .field("convertedQty", convert("$qty", INT) - .onError(concat( - "Could not convert ", - StringExpressions.toString("$qty"), - " to type integer.")) - .onNull(0)), - project() - .include("totalPrice", switchExpression() - .branch(eq( - type("$convertedPrice"), - "string"), "NaN") - .branch(eq( - type("$convertedQty"), - "string"), "NaN") + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.ANY), (aggregation) -> aggregation.pipeline( + addFields().field("convertedPrice", convert("$price", DECIMAL).onError("Error").onNull(0.0)) + .field("convertedQty", + convert("$qty", INT).onError(concat("Could not convert ", + StringExpressions.toString("$qty"), " to type integer.")).onNull(0)), + project().include("totalPrice", + switchExpression().branch(eq(type("$convertedPrice"), "string"), "NaN") + .branch(eq(type("$convertedQty"), "string"), "NaN") .defaultCase(multiply("$convertedPrice", "$convertedQty"))))); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCos.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCos.java index b051c63d759..880e2adb588 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCos.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCos.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,19 +9,25 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.degreesToRadians; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestCos extends AggregationTest { - @Test +public class TestCos extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/cos/example1 + * + */ + @Test(testName = "main :: Cosine of Value in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("side_a", multiply(cos(degreesToRadians("$angle_a")), "$hypotenuse")))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("side_a", multiply(cos(degreesToRadians("$angle_a")), "$hypotenuse")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/cos/example2 + * + */ + @Test(testName = "main :: Cosine of Value in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("side_b", multiply(cos("$angle_a"), "$hypotenuse")))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("side_b", multiply(cos("$angle_a"), "$hypotenuse")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCosh.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCosh.java index 2c3aa6b75c5..ae7a19d4fcf 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCosh.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCosh.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,19 +9,25 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.degreesToRadians; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestCosh extends AggregationTest { - @Test +public class TestCosh extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/cosh/example1 + * + */ + @Test(testName = "main :: Hyperbolic Cosine in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("cosh_output", cosh(degreesToRadians("$angle"))))); + testPipeline(new ActionTestOptions().removeIds(true), (aggregation) -> aggregation + .pipeline(addFields().field("cosh_output", cosh(degreesToRadians("$angle"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/cosh/example2 + * + */ + @Test(testName = "main :: Hyperbolic Cosine in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("cosh_output", cosh("$angle")))); + testPipeline(new ActionTestOptions().removeIds(true), + (aggregation) -> aggregation.pipeline(addFields().field("cosh_output", cosh("$angle")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCount.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCount.java index 8506454d285..7a6835e2302 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCount.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCount.java @@ -3,7 +3,8 @@ import dev.morphia.aggregation.expressions.AccumulatorExpressions; import dev.morphia.aggregation.stages.Group; import dev.morphia.query.Sort; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -12,25 +13,29 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.test.ServerVersion.v50; -public class TestCount extends AggregationTest { - @Test +public class TestCount extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/count/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(v50, false, false, aggregation -> aggregation - .pipeline(group(Group.id("$state")) - .field("countNumberOfDocumentsForState", AccumulatorExpressions.count()))); + testPipeline(new ActionTestOptions().serverVersion(v50).orderMatters(false), + aggregation -> aggregation.pipeline(group(Group.id("$state")).field("countNumberOfDocumentsForState", + AccumulatorExpressions.count()))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/count/example2 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample2() { - testPipeline(v50, false, false, - aggregation -> aggregation - .setWindowFields(setWindowFields() - .partitionBy(("$state")) - .sortBy(Sort.ascending("orderDate")) - .output(output("countNumberOfDocumentsForState") - .operator(AccumulatorExpressions.count()) - .window().documents("unbounded", "current")))); + testPipeline(new ActionTestOptions().serverVersion(v50).orderMatters(false), + aggregation -> aggregation.setWindowFields(setWindowFields().partitionBy(("$state")) + .sortBy(Sort.ascending("orderDate")).output(output("countNumberOfDocumentsForState") + .operator(AccumulatorExpressions.count()).window().documents("unbounded", "current")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovariancePop.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovariancePop.java index afdcd9771eb..2708056e153 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovariancePop.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovariancePop.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,17 +10,17 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.ascending; -public class TestCovariancePop extends AggregationTest { - @Test +public class TestCovariancePop extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/covariancePop/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("covariancePopForState") - .operator(covariancePop(year("$orderDate"), "$quantity")) - .window() - .documents("unbounded", "current")))); + testPipeline((aggregation) -> aggregation + .pipeline(setWindowFields().partitionBy("$state").sortBy(ascending("orderDate")) + .output(output("covariancePopForState").operator(covariancePop(year("$orderDate"), "$quantity")) + .window().documents("unbounded", "current")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovarianceSamp.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovarianceSamp.java index be05452f7a9..fdb0d6eff1a 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovarianceSamp.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovarianceSamp.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,16 +10,17 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.ascending; -public class TestCovarianceSamp extends AggregationTest { - @Test +public class TestCovarianceSamp extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/covarianceSamp/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) + testPipeline((aggregation) -> aggregation + .pipeline(setWindowFields().partitionBy("$state").sortBy(ascending("orderDate")) .output(output("covarianceSampForState") - .operator(covarianceSamp(year("$orderDate"), "$quantity")) - .window() + .operator(covarianceSamp(year("$orderDate"), "$quantity")).window() .documents("unbounded", "current")))); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateAdd.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateAdd.java index e318feeb6a3..57f7a5e2ca6 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateAdd.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateAdd.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.TimeUnit; -import dev.morphia.test.DriverVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -12,70 +12,61 @@ import static dev.morphia.aggregation.stages.Match.match; import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.query.filters.Filters.expr; +import static dev.morphia.test.DriverVersion.v42; import static dev.morphia.test.ServerVersion.ANY; -public class TestDateAdd extends AggregationTest { - @Test +public class TestDateAdd extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dateAdd/example1 + * + */ + @Test(testName = "Add a Future Date") public void testExample1() { - minDriver = DriverVersion.v42; - testPipeline(ANY, true, true, aggregation -> aggregation.pipeline( - project() - .include("expectedDeliveryDate", - dateAdd("$purchaseDate", 3, TimeUnit.DAY)))); + testPipeline(new ActionTestOptions().serverVersion(ANY).removeIds(true).minDriver(v42), + aggregation -> aggregation.pipeline( + project().include("expectedDeliveryDate", dateAdd("$purchaseDate", 3, TimeUnit.DAY)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateAdd/example2 + * + */ + @Test(testName = "Filter on a Date Range") public void testExample2() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - match(expr( - gt("$deliveryDate", dateAdd("$purchaseDate", 5, TimeUnit.DAY)))), + testPipeline(new ActionTestOptions().serverVersion(ANY), + aggregation -> aggregation.pipeline( + match(expr(gt("$deliveryDate", dateAdd("$purchaseDate", 5, TimeUnit.DAY)))), - project() - .suppressId() - .include("custId") - .include("purchased", dateToString() - .date("$purchaseDate") - .format("%Y-%m-%d")) - .include("delivery", dateToString() - .date("$deliveryDate") - .format("%Y-%m-%d")) + project().suppressId().include("custId") + .include("purchased", dateToString().date("$purchaseDate").format("%Y-%m-%d")) + .include("delivery", dateToString().date("$deliveryDate").format("%Y-%m-%d")) - )); + )); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateAdd/example3 + * + */ + @Test(testName = "Adjust for Daylight Savings Time") public void testExample3() { - testPipeline(ANY, false, true, aggregation -> aggregation.pipeline( - project() - .suppressId() - .include("location") - .include("start", dateToString() - .date("$login") + testPipeline(new ActionTestOptions().serverVersion(ANY), aggregation -> aggregation.pipeline(project() + .suppressId().include("location") + .include("start", dateToString().date("$login").format("%Y-%m-%d %H:%M")) + .include("days", + dateToString().date(dateAdd("$login", 1, TimeUnit.DAY).timezone("$location")) .format("%Y-%m-%d %H:%M")) - .include("days", dateToString() - .date(dateAdd("$login", 1, TimeUnit.DAY) - .timezone("$location")) + .include("hours", + dateToString().date(dateAdd("$login", 24, TimeUnit.HOUR).timezone("$location")) .format("%Y-%m-%d %H:%M")) - .include("hours", dateToString() - .date(dateAdd("$login", 24, TimeUnit.HOUR) - .timezone("$location")) - .format("%Y-%m-%d %H:%M")) - .include("startTZInfo", dateToString() - .date("$login") - .format("%Y-%m-%d %H:%M") - .timeZone("$location")) - .include("daysTZInfo", dateToString() - .date(dateAdd("$login", 1, TimeUnit.DAY) - .timezone("$location")) - .format("%Y-%m-%d %H:%M") - .timeZone("$location")) - .include("hoursTZInfo", dateToString() - .date(dateAdd("$login", 24, TimeUnit.HOUR) - .timezone("$location")) - .format("%Y-%m-%d %H:%M") - .timeZone("$location"))) + .include("startTZInfo", dateToString().date("$login").format("%Y-%m-%d %H:%M").timeZone("$location")) + .include("daysTZInfo", + dateToString().date(dateAdd("$login", 1, TimeUnit.DAY).timezone("$location")) + .format("%Y-%m-%d %H:%M").timeZone("$location")) + .include("hoursTZInfo", dateToString().date(dateAdd("$login", 24, TimeUnit.HOUR).timezone("$location")) + .format("%Y-%m-%d %H:%M").timeZone("$location"))) ); diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateDiff.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateDiff.java index 1c67ad4d940..78265adab6f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateDiff.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateDiff.java @@ -1,8 +1,7 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.TimeUnit; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -19,38 +18,40 @@ import static java.time.DayOfWeek.*; import static java.time.DayOfWeek.FRIDAY; -public class TestDateDiff extends AggregationTest { - @Test +public class TestDateDiff extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dateDiff/example1 + * + */ + @Test(testName = "Elapsed Time") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - group(id(null)) - .field("averageTime", - avg(dateDiff("$purchased", "$delivered", TimeUnit.DAY))), - project() - .suppressId() - .include("numDays", trunc("$averageTime", 1)) + testPipeline((aggregation) -> aggregation.pipeline( + group(id(null)).field("averageTime", avg(dateDiff("$purchased", "$delivered", TimeUnit.DAY))), + project().suppressId().include("numDays", trunc("$averageTime", 1)) )); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateDiff/example2 + * + */ + @Test(testName = "Result Precision") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("start", "$start") - .include("end", "$end") - .include("years", dateDiff("$start", "$end", YEAR)) - .include("months", dateDiff("$start", "$end", MONTH)) - .include("days", dateDiff("$start", "$end", DAY)))); + testPipeline((aggregation) -> aggregation.pipeline(project().suppressId().include("start", "$start") + .include("end", "$end").include("years", dateDiff("$start", "$end", YEAR)) + .include("months", dateDiff("$start", "$end", MONTH)) + .include("days", dateDiff("$start", "$end", DAY)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateDiff/example3 + * + */ + @Test(testName = "Weeks Per Month") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("wks_default", dateDiff("$start", "$end", WEEK)) + testPipeline((aggregation) -> aggregation + .pipeline(project().suppressId().include("wks_default", dateDiff("$start", "$end", WEEK)) .include("wks_monday", dateDiff("$start", "$end", WEEK).startOfWeek(MONDAY)) .include("wks_friday", dateDiff("$start", "$end", WEEK).startOfWeek(FRIDAY)))); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromParts.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromParts.java index 8e6ce2444c9..8273aa13f85 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromParts.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromParts.java @@ -1,39 +1,24 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.DateExpressions.dateFromParts; import static dev.morphia.aggregation.stages.Projection.project; -public class TestDateFromParts extends AggregationTest { - @Test +public class TestDateFromParts extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dateFromParts/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("date", - dateFromParts() - .year(2017) - .month(2) - .day(8) - .hour(12)) - .include("date_iso", - dateFromParts() - .isoWeekYear(2017) - .isoWeek(6) - .isoDayOfWeek(3) - .hour(12)) - .include("date_timezone", - dateFromParts() - .year(2016) - .month(12) - .day(31) - .hour(23) - .minute(46) - .second(12) - .timezone("America/New_York")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("date", dateFromParts().year(2017).month(2).day(8).hour(12)) + .include("date_iso", dateFromParts().isoWeekYear(2017).isoWeek(6).isoDayOfWeek(3).hour(12)) + .include("date_timezone", dateFromParts().year(2016).month(12).day(31).hour(23).minute(46) + .second(12).timezone("America/New_York")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromString.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromString.java index 198013cc02f..02b39c679e4 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromString.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromString.java @@ -1,41 +1,41 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.DateExpressions.dateFromString; import static dev.morphia.aggregation.stages.Projection.project; -public class TestDateFromString extends AggregationTest { - @Test +public class TestDateFromString extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dateFromString/example1 + * + */ + @Test(testName = "Converting Dates") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("date", dateFromString() - .dateString("$date") - .timeZone("America/New_York")))); + testPipeline((aggregation) -> aggregation.pipeline( + project().include("date", dateFromString().dateString("$date").timeZone("America/New_York")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateFromString/example2 + * + */ + @Test(testName = "``onError``") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("date", dateFromString() - .dateString("$date") - .timeZone("$timezone") - .onError("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("date", + dateFromString().dateString("$date").timeZone("$timezone").onError("$date")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateFromString/example3 + * + */ + @Test(testName = "``onNull``") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("date", dateFromString() - .dateString("$date") - .timeZone("$timezone") - .onNull("oops")) + testPipeline((aggregation) -> aggregation.pipeline( + project().include("date", dateFromString().dateString("$date").timeZone("$timezone").onNull("oops")) )); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateSubtract.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateSubtract.java index 46f8d5d278c..c364949955f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateSubtract.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateSubtract.java @@ -1,8 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.DriverVersion; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -16,76 +15,62 @@ import static dev.morphia.aggregation.stages.Match.match; import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.query.filters.Filters.expr; +import static dev.morphia.test.DriverVersion.v42; import static dev.morphia.test.ServerVersion.v50; -public class TestDateSubtract extends AggregationTest { - public TestDateSubtract() { - minDriver = DriverVersion.v42; - } - - @Test +public class TestDateSubtract extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dateSubtract/example1 + * + */ + @Test(testName = "Subtract A Fixed Amount") public void testExample1() { - testPipeline(v50, true, false, (aggregation) -> aggregation.pipeline( - match( - expr(eq(year("$logout"), 2021)), - expr(eq(month("$logout"), 1))), - project() - .include("logoutTime", - dateSubtract("$logout", 3, HOUR)))); + testPipeline(new ActionTestOptions().serverVersion(v50).removeIds(true).orderMatters(false).minDriver(v42), + (aggregation) -> aggregation.pipeline( + match(expr(eq(year("$logout"), 2021)), expr(eq(month("$logout"), 1))), + project().include("logoutTime", dateSubtract("$logout", 3, HOUR)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateSubtract/example2 + * + */ + @Test(testName = "Filter by Relative Dates") public void testExample2() { // $$NOW is a little pointless /* - * testPipeline(v50, false, true, (aggregation) -> { - * var epochTime = LocalDate.of(2021, Month.FEBRUARY, 22) + * testPipeline(new dev.morphia.test.util.ActionTestOptions().serverVersion(v50) + * , (aggregation) -> { var epochTime = LocalDate.of(2021, Month.FEBRUARY, 22) * .toEpochDay(); * - * return aggregation.pipeline( - * match(expr(gt(field("logoutTime"), - * dateSubtract(value(epochTime), 1, WEEK)))), - * project() - * .suppressId() - * .include("custId") - * .include("loggedOut", dateToString() - * .format("%Y-%m-%d") - * .date(field("logoutTime")))); - * }); + * return aggregation.pipeline( match(expr(gt(field("logoutTime"), + * dateSubtract(value(epochTime), 1, WEEK)))), project() .suppressId() + * .include("custId") .include("loggedOut", dateToString() .format("%Y-%m-%d") + * .date(field("logoutTime")))); }); */ } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateSubtract/example3 + * + */ + @Test(testName = "Adjust for Daylight Savings Time") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("location") - .include("start", dateToString() - .date("$login") - .format("%Y-%m-%d %H:%M")) - .include("days", dateToString() - .date(dateSubtract("$login", 1, DAY) - .timezone("$location")) + testPipeline(new ActionTestOptions().minDriver(v42), (aggregation) -> aggregation.pipeline(project() + .suppressId().include("location") + .include("start", dateToString().date("$login").format("%Y-%m-%d %H:%M")) + .include("days", + dateToString().date(dateSubtract("$login", 1, DAY).timezone("$location")) .format("%Y-%m-%d %H:%M")) - .include("hours", dateToString() - .date(dateSubtract("$login", 24, HOUR) - .timezone("$location")) + .include("hours", + dateToString().date(dateSubtract("$login", 24, HOUR).timezone("$location")) .format("%Y-%m-%d %H:%M")) - .include("startTZInfo", dateToString() - .date("$login") - .format("%Y-%m-%d %H:%M") - .timeZone("$location")) - .include("daysTZInfo", dateToString() - .date(dateSubtract("$login", 1, DAY) - .timezone("$location")) - .format("%Y-%m-%d %H:%M") - .timeZone("$location")) - .include("hoursTZInfo", dateToString() - .date(dateSubtract("$login", 24, HOUR) - .timezone("$location")) - .format("%Y-%m-%d %H:%M") - .timeZone("$location")))); + .include("startTZInfo", dateToString().date("$login").format("%Y-%m-%d %H:%M").timeZone("$location")) + .include("daysTZInfo", + dateToString().date(dateSubtract("$login", 1, DAY).timezone("$location")) + .format("%Y-%m-%d %H:%M").timeZone("$location")) + .include("hoursTZInfo", dateToString().date(dateSubtract("$login", 24, HOUR).timezone("$location")) + .format("%Y-%m-%d %H:%M").timeZone("$location")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToParts.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToParts.java index cf6eebea4d0..0cfe0a915ae 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToParts.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToParts.java @@ -1,23 +1,22 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.DateExpressions.dateToParts; import static dev.morphia.aggregation.stages.Projection.project; -public class TestDateToParts extends AggregationTest { - @Test +public class TestDateToParts extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dateToParts/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("date", dateToParts("$date")) - .include("date_iso", dateToParts("$date") - .iso8601(true)) - .include("date_timezone", dateToParts("$date") - .timezone("America/New_York")))); + testPipeline((aggregation) -> aggregation.pipeline( + project().include("date", dateToParts("$date")).include("date_iso", dateToParts("$date").iso8601(true)) + .include("date_timezone", dateToParts("$date").timezone("America/New_York")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToString.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToString.java index 20a97d5d292..8e2144f3758 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToString.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToString.java @@ -1,23 +1,30 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.DateExpressions.dateToString; import static dev.morphia.aggregation.stages.Projection.project; -public class TestDateToString extends AggregationTest { - @Test +public class TestDateToString extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dateToString/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.v70, false, true, (aggregation) -> aggregation.pipeline( - project() + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.v70), + (aggregation) -> aggregation.pipeline(project() .include("yearMonthDayUTC", dateToString().date("$date").format("%Y-%m-%d")) .include("timewithOffsetNY", dateToString().date("$date").format("%H:%M:%S:%L%z").timeZone("America/New_York")) - .include("timewithOffset430", dateToString().date("$date").format("%H:%M:%S:%L%z").timeZone("+04:30")) - .include("minutesOffsetNY", dateToString().date("$date").format("%Z").timeZone("America/New_York")) + .include("timewithOffset430", + dateToString().date("$date").format("%H:%M:%S:%L%z").timeZone("+04:30")) + .include("minutesOffsetNY", + dateToString().date("$date").format("%Z").timeZone("America/New_York")) .include("minutesOffset430", dateToString().date("$date").format("%Z").timeZone("+04:30")) .include("abbreviated_month", dateToString().date("$date").format("%b").timeZone("+04:30")) .include("full_month", dateToString().date("$date").format("%B").timeZone("+04:30")))); diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateTrunc.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateTrunc.java index dc79ae1c55e..3a458843f23 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateTrunc.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateTrunc.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -13,24 +13,28 @@ import static dev.morphia.aggregation.stages.Projection.project; import static java.time.DayOfWeek.*; -public class TestDateTrunc extends AggregationTest { - @Test +public class TestDateTrunc extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dateTrunc/example1 + * + */ + @Test(testName = "Truncate Order Dates in a ``$project`` Pipeline Stage") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("_id") - .include("orderDate") - .include("truncatedOrderDate", dateTrunc("$orderDate", - WEEK).binSize(2) - .timezone("America/Los_Angeles") - .startOfWeek(MONDAY)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("_id").include("orderDate").include("truncatedOrderDate", + dateTrunc("$orderDate", WEEK).binSize(2).timezone("America/Los_Angeles").startOfWeek(MONDAY)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/dateTrunc/example2 + * + */ + @Test(testName = "Truncate Order Dates and Obtain Quantity Sum in a ``$group`` Pipeline Stage") public void testExample2() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - group(id().field("truncatedOrderDate", dateTrunc("$orderDate", MONTH).binSize(6))) - .field("sumQuantity", sum("$quantity")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation + .pipeline(group(id().field("truncatedOrderDate", dateTrunc("$orderDate", MONTH).binSize(6))) + .field("sumQuantity", sum("$quantity")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfMonth.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfMonth.java index 5472480eb72..1b3757340e7 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfMonth.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfMonth.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestDayOfMonth extends AggregationTest { - @Test +public class TestDayOfMonth extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dayOfMonth/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfWeek.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfWeek.java index be150cfcba0..e716cb22039 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfWeek.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfWeek.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestDayOfWeek extends AggregationTest { - @Test +public class TestDayOfWeek extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dayOfWeek/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfYear.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfYear.java index 0536e05633a..42f262ea238 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfYear.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfYear.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestDayOfYear extends AggregationTest { - @Test +public class TestDayOfYear extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/dayOfYear/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDegreesToRadians.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDegreesToRadians.java index 1c7027099d6..d3085c7a5f5 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDegreesToRadians.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDegreesToRadians.java @@ -1,19 +1,22 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.TrigonometryExpressions.degreesToRadians; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestDegreesToRadians extends AggregationTest { - @Test +public class TestDegreesToRadians extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/degreesToRadians/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("angle_a_rad", degreesToRadians("$angle_a")) + testPipeline(new ActionTestOptions().removeIds(true), + (aggregation) -> aggregation.pipeline(addFields().field("angle_a_rad", degreesToRadians("$angle_a")) .field("angle_b_rad", degreesToRadians("$angle_b")) .field("angle_c_rad", degreesToRadians("$angle_c")))); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDenseRank.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDenseRank.java index 59e3b4d250b..7afcc28e8b5 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDenseRank.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDenseRank.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,35 +9,35 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.*; -public class TestDenseRank extends AggregationTest { - @Test +public class TestDenseRank extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/denseRank/example1 + * + */ + @Test(testName = "Dense Rank Partitions by an Integer Field") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(descending("quantity")) - .output(output("denseRankQuantityForState") - .operator(denseRank())))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(descending("quantity")).output(output("denseRankQuantityForState").operator(denseRank())))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/denseRank/example2 + * + */ + @Test(testName = "Dense Rank Partitions by a Date Field") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("denseRankOrderDateForState") - .operator(denseRank())))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(ascending("orderDate")).output(output("denseRankOrderDateForState").operator(denseRank())))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/denseRank/example3 + * + */ + @Test(testName = "Dense Rank for Duplicate, Null, and Missing Values") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(descending("quantity")) - .output(output("denseRankQuantityForState") - .operator(denseRank())))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(descending("quantity")).output(output("denseRankQuantityForState").operator(denseRank())))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDerivative.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDerivative.java index b38d5174302..effcc83beba 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDerivative.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDerivative.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -14,18 +14,17 @@ import static dev.morphia.query.Sort.ascending; import static dev.morphia.query.filters.Filters.gt; -public class TestDerivative extends AggregationTest { - @Test +public class TestDerivative extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/derivative/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$truckID") - .sortBy(ascending("timeStamp")) - .output(output("truckAverageSpeed") - .operator(derivative("$miles") - .unit(HOUR)) - .window() - .range(-30, 0, SECOND)), - match(gt("truckAverageSpeed", 50)))); + testPipeline(new ActionTestOptions().removeIds(true), + (aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$truckID") + .sortBy(ascending("timeStamp")).output(output("truckAverageSpeed") + .operator(derivative("$miles").unit(HOUR)).window().range(-30, 0, SECOND)), + match(gt("truckAverageSpeed", 50)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDivide.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDivide.java index c61f6652a2e..ad352a1963e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDivide.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDivide.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.divide; import static dev.morphia.aggregation.stages.Projection.project; -public class TestDivide extends AggregationTest { - @Test +public class TestDivide extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/divide/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("city") - .include("workdays", divide("$hours", 8)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("city").include("workdays", divide("$hours", 8)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDocumentNumber.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDocumentNumber.java index 2a005ba5bce..a6cd64334fa 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDocumentNumber.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDocumentNumber.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,25 +9,25 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.*; -public class TestDocumentNumber extends AggregationTest { - @Test +public class TestDocumentNumber extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/documentNumber/example1 + * + */ + @Test(testName = "Document Number for Each State") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(descending("quantity")) - .output(output("documentNumberForState") - .operator(documentNumber())))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(descending("quantity")).output(output("documentNumberForState").operator(documentNumber())))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/documentNumber/example2 + * + */ + @Test(testName = "Document Number for Duplicate, Null, and Missing Values") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(descending("quantity")) - .output(output("documentNumberForState") - .operator(documentNumber())))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(descending("quantity")).output(output("documentNumberForState").operator(documentNumber())))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestEq.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestEq.java index d903904fa92..025797f6378 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestEq.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestEq.java @@ -1,22 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ComparisonExpressions.eq; import static dev.morphia.aggregation.stages.Projection.project; -public class TestEq extends AggregationTest { - @Test +public class TestEq extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/eq/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("item") - .include("qty") - .include("qtyEq250", eq("$qty", 250)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().suppressId().include("item").include("qty").include("qtyEq250", eq("$qty", 250)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExp.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExp.java index 035c6a3b82e..f134e47de5a 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExp.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExp.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,15 +8,15 @@ import static dev.morphia.aggregation.expressions.MathExpressions.subtract; import static dev.morphia.aggregation.stages.Projection.project; -public class TestExp extends AggregationTest { - @Test +public class TestExp extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/exp/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("effectiveRate", - subtract( - exp("$interestRate"), - 1)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("effectiveRate", subtract(exp("$interestRate"), 1)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExpMovingAvg.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExpMovingAvg.java index df230954c6e..5c11536f8e3 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExpMovingAvg.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExpMovingAvg.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -10,24 +10,26 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.*; -public class TestExpMovingAvg extends AggregationTest { - @Test +public class TestExpMovingAvg extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/expMovingAvg/example1 + * + */ + @Test(testName = "Exponential Moving Average Using ``N``") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$stock") - .sortBy(ascending("date")) - .output(output("expMovingAvgForStock") - .operator(expMovingAvg("$price", 2))))); + testPipeline(new ActionTestOptions().removeIds(true), + (aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$stock").sortBy(ascending("date")) + .output(output("expMovingAvgForStock").operator(expMovingAvg("$price", 2))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/expMovingAvg/example2 + * + */ + @Test(testName = "Exponential Moving Average Using ``alpha``") public void testExample2() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$stock") - .sortBy(ascending("date")) - .output(output("expMovingAvgForStock") - .operator(expMovingAvg("$price", 0.75))))); + testPipeline(new ActionTestOptions().removeIds(true), + (aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$stock").sortBy(ascending("date")) + .output(output("expMovingAvgForStock").operator(expMovingAvg("$price", 0.75))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFilter.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFilter.java index 93ddfb9de07..526064ed2d2 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFilter.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFilter.java @@ -1,46 +1,64 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; +import static dev.morphia.aggregation.expressions.ComparisonExpressions.eq; import static dev.morphia.aggregation.expressions.ComparisonExpressions.gte; import static dev.morphia.aggregation.expressions.Expressions.filter; +import static dev.morphia.aggregation.expressions.StringExpressions.regexMatch; import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.v52; -public class TestFilter extends AggregationTest { - @Test +public class TestFilter extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/filter/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(v52, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("items", filter("$items", - gte("$$item.price", 100)) - .as("item")))); + testPipeline(new ActionTestOptions().serverVersion(v52), (aggregation) -> aggregation + .pipeline(project().include("items", filter("$items", gte("$$item.price", 100)).as("item")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/filter/example2 + * + */ + @Test(testName = "Use the limit Field") public void testExample2() { - testPipeline(v52, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("items", filter("$items", - gte("$$item.price", 100)) - .as("item") - .limit(1)))); + testPipeline(new ActionTestOptions().serverVersion(v52), (aggregation) -> aggregation + .pipeline(project().include("items", filter("$items", gte("$$item.price", 100)).as("item").limit(1)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/filter/example3 + * + */ + @Test(testName = "limit Greater than Possible Matches") public void testExample3() { - // this example is API incompatible with morphia since limit can only be an int and not a floating point number + // this example is API incompatible with morphia since limit can only be an int + // and not a floating point number } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/filter/example4 + * + */ + @Test(testName = "Filter Based on String Equality Match") public void testExample4() { - testPipeline(v52, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("items", filter("$items", - gte("$$item.price", 100)) - .as("item") - .limit(5)))); + testPipeline(new ActionTestOptions().serverVersion(v52), (aggregation) -> aggregation + .pipeline(project().include("items", filter("$items", eq("$$item.name", "pen")).as("item")))); + } + + /** + * test data: dev/morphia/test/aggregation/expressions/filter/example5 + */ + @Test(testName = "Filter Based on Regular Expression Match") + public void testExample5() { + testPipeline(aggregation -> aggregation.pipeline( + project().include("items", filter("$items", regexMatch("$$item.name").pattern("^p")).as("item")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirst.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirst.java index 89e87d16333..98e58b70594 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirst.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirst.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -10,41 +11,45 @@ import static dev.morphia.aggregation.stages.Sort.sort; import static dev.morphia.test.ServerVersion.v50; -public class TestFirst extends AggregationTest { +public class TestFirst extends TemplatedTestBase { - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/first/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(v50, false, false, (aggregation) -> aggregation.pipeline( - sort() - .ascending("item", "date"), - group(id("$item")) - .field("firstSale", first("$date")))); + testPipeline(new ActionTestOptions().serverVersion(v50).orderMatters(false), (aggregation) -> aggregation + .pipeline(sort().ascending("item", "date"), group(id("$item")).field("firstSale", first("$date")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/first/example2 + * + */ + @Test(testName = "Missing Data") public void testExample2() { - testPipeline(v50, false, false, (aggregation) -> aggregation.pipeline( - sort() - .ascending("item", "price"), - group(id("$item")) - .field("inStock", first("$quantity")) + testPipeline(new ActionTestOptions().serverVersion(v50).orderMatters(false), (aggregation) -> aggregation + .pipeline(sort().ascending("item", "price"), group(id("$item")).field("inStock", first("$quantity")) - )); + )); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/first/example3 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample3() { - // this example starts importing a bunch of stuff and gets more complicated than I care + // this example starts importing a bunch of stuff and gets more complicated than + // I care // to make the parser support. we have working examples already. /* - * testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - * setWindowFields() - * .partitionBy("$state") - * .sortBy(Sort.ascending("orderDate")) - * .output(Output.output("firstOrderTypeForState") - * .operator(first("$type")) - * .window() - * .documents("unbounded", "current")))); + * testPipeline(new dev.morphia.test.util.ActionTestOptions(). removeIds(false), + * (aggregation) -> aggregation.pipeline( setWindowFields() + * .partitionBy("$state") .sortBy(Sort.ascending("orderDate")) + * .output(Output.output("firstOrderTypeForState") .operator(first("$type")) + * .window() .documents("unbounded", "current")))); */ } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirstN.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirstN.java index 46807b2a223..18ff4980c0f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirstN.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirstN.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.ComparisonExpressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -19,59 +19,64 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.test.ServerVersion.v52; -public class TestFirstN extends AggregationTest { - @Test +public class TestFirstN extends TemplatedTestBase { + @Test(testName = "Find the First Three Player Scores for a Single Game") public void testExample1() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - match(eq("gameId", "G1")), - group(id("$gameId")) - .field("firstThreeScores", firstN( - 3, - array("$playerId", "$score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline( + match(eq("gameId", "G1")), + group(id("$gameId")) + .field("firstThreeScores", firstN( + 3, + array("$playerId", "$score"))))); } - @Test + @Test(testName = "Finding the First Three Player Scores Across Multiple Games") public void testExample2() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id("$gameId")) - .field("playerId", firstN( - 3, - array("$playerId", "$score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline( + group(id("$gameId")) + .field("playerId", firstN( + 3, + array("$playerId", "$score"))))); } - @Test + @Test(testName = "Using ``$sort`` With ``$firstN``") public void testExample3() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - sort().descending("score"), - group(id("$gameId")) - .field("playerId", firstN( - 3, - array("$playerId", "$score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline( + sort().descending("score"), + group(id("$gameId")) + .field("playerId", firstN( + 3, + array("$playerId", "$score"))))); } - @Test + @Test(testName = "Computing ``n`` Based on the Group Key for ``$group``") public void testExample4() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id() - .field("gameId", "$gameId")) - .field("gamescores", firstN( - condition( - ComparisonExpressions.eq("$gameId", "G2"), - 1, - 3), - "$score")))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline( + group(id() + .field("gameId", "$gameId")) + .field("gamescores", firstN( + condition( + ComparisonExpressions.eq("$gameId", "G2"), + 1, + 3), + "$score")))); } @Test(enabled = false, description = "this needs to run against the db rather than a collection and that requires fixes in the agg code") public void testExample5() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - documents(document().field("array", array(10, 20, 30, 40))), - project() - .include("firstThreeElements", firstN(3, "$array")) + testPipeline( + (aggregation) -> aggregation.pipeline( + documents(document().field("array", array(10, 20, 30, 40))), + project() + .include("firstThreeElements", firstN(3, "$array")) - )); + )); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFloor.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFloor.java index c59aa129bec..65299e1eeda 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFloor.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFloor.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.floor; import static dev.morphia.aggregation.stages.Projection.project; -public class TestFloor extends AggregationTest { - @Test +public class TestFloor extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/floor/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("value") - .include("floorValue", floor("$value")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("value").include("floorValue", floor("$value")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFunction.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFunction.java index 577b0b063b0..85ca1fadedd 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFunction.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFunction.java @@ -1,31 +1,36 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.AccumulatorExpressions.function; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestFunction extends AggregationTest { - @Test +public class TestFunction extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/function/example1 + * + */ + @Test(testName = "Example 1: Usage Example") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("isFound", function(""" - function(name) { - return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad" - }""", "$name")) - .field("message", function( - """ - function(name, scores) { - let total = Array.sum(scores); - return `Hello ${name}. Your total score is ${total}.` - }""", "$name", "$scores")))); + testPipeline(new ActionTestOptions().skipActionCheck(true), + (aggregation) -> aggregation.pipeline(addFields().field("isFound", function(""" + function(name) { + return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad" + }""", "$name")).field("message", function(""" + function(name, scores) { + let total = Array.sum(scores); + return `Hello ${name}. Your total score is ${total}.` + }""", "$name", "$scores")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/function/example2 + * + */ + @Test(testName = "Example 2: Alternative to ``$where``") public void testExample2() { // example doesn't really apply to morphia } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGetField.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGetField.java index 71c00efac4e..b1847436e4e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGetField.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGetField.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.test.DriverVersion; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -13,29 +13,34 @@ import static dev.morphia.aggregation.stages.Match.match; import static dev.morphia.query.filters.Filters.expr; -public class TestGetField extends AggregationTest { - @Test +public class TestGetField extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/getField/example1 + * + */ + @Test(testName = "Query Fields that Contain Periods (``.``)") public void testExample1() { - minDriver = DriverVersion.v43; - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(expr(gt(getField("price.usd"), 200))))); + testPipeline(new ActionTestOptions().minDriver(DriverVersion.v43), + (aggregation) -> aggregation.pipeline(match(expr(gt(getField("price.usd"), 200))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/getField/example2 + * + */ + @Test(testName = "Query Fields that Start with a Dollar Sign (``$``)") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(expr(gt(getField(literal("$price")), 200))))); + testPipeline((aggregation) -> aggregation.pipeline(match(expr(gt(getField(literal("$price")), 200))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/getField/example3 + * + */ + @Test(testName = "Query a Field in a Sub-document") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match( - expr( - lte( - getField(literal("$small")) - .input("$quantity"), - 20))))); + testPipeline((aggregation) -> aggregation + .pipeline(match(expr(lte(getField(literal("$small")).input("$quantity"), 20))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGt.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGt.java index 508d6e79d32..f6029f7908b 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGt.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGt.java @@ -1,22 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ComparisonExpressions.gt; import static dev.morphia.aggregation.stages.Projection.project; -public class TestGt extends AggregationTest { - @Test +public class TestGt extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/gt/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("item") - .include("qty") - .include("qtyGt250", gt("$qty", 250)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().suppressId().include("item").include("qty").include("qtyGt250", gt("$qty", 250)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGte.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGte.java index 6c1909b2371..8a0c6a818aa 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGte.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGte.java @@ -1,22 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ComparisonExpressions.gte; import static dev.morphia.aggregation.stages.Projection.project; -public class TestGte extends AggregationTest { - @Test +public class TestGte extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/gte/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("item") - .include("qty") - .include("qtyGte250", gte("$qty", 250)))); + testPipeline((aggregation) -> aggregation.pipeline( + project().suppressId().include("item").include("qty").include("qtyGte250", gte("$qty", 250)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestHour.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestHour.java index 13d89c2ba8c..e981d4b8c38 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestHour.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestHour.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -16,20 +15,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestHour extends AggregationTest { - @Test +public class TestHour extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/hour/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIfNull.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIfNull.java index 5e3990e05de..08739976221 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIfNull.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIfNull.java @@ -1,34 +1,31 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ConditionalExpressions.ifNull; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIfNull extends AggregationTest { - @Test +public class TestIfNull extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/ifNull/example1 + * + */ + @Test(testName = "Single Input Expression") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("description", ifNull() - .target("$description") - .replacement("Unspecified")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("item").include("description", + ifNull().target("$description").replacement("Unspecified")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/ifNull/example2 + * + */ + @Test(testName = "Multiple Input Expressions") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("value", ifNull() - .input( - "$description", - "$quantity") - .replacement("Unspecified")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("item").include("value", + ifNull().input("$description", "$quantity").replacement("Unspecified")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIn.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIn.java index 8c017d211ac..4212eb176b0 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIn.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIn.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ArrayExpressions.in; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIn extends AggregationTest { - @Test +public class TestIn extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/in/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("store location", "$location") - .include("has bananas", in("bananas", "$in_stock")))); + testPipeline((aggregation) -> aggregation.pipeline( + project().include("store location", "$location").include("has bananas", in("bananas", "$in_stock")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfArray.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfArray.java index c320581851a..b59b950e88e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfArray.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfArray.java @@ -1,19 +1,20 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ArrayExpressions.indexOfArray; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIndexOfArray extends AggregationTest { - @Test +public class TestIndexOfArray extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/indexOfArray/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("index", indexOfArray("$items", 2)))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("index", indexOfArray("$items", 2)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfBytes.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfBytes.java index 82eac52f0bc..01341663701 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfBytes.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfBytes.java @@ -1,19 +1,22 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.indexOfBytes; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIndexOfBytes extends AggregationTest { - @Test +public class TestIndexOfBytes extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/indexOfBytes/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .include("byteLocation", indexOfBytes("$item", "foo")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(project().include("byteLocation", indexOfBytes("$item", "foo")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfCP.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfCP.java index d3714ec5d64..1d7882e373c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfCP.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfCP.java @@ -1,19 +1,22 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.indexOfCP; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIndexOfCP extends AggregationTest { - @Test +public class TestIndexOfCP extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/indexOfCP/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .include("cpLocation", indexOfCP("$item", "foo")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(project().include("cpLocation", indexOfCP("$item", "foo")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIntegral.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIntegral.java index 9dfc7156d83..31ac3d92061 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIntegral.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIntegral.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.query.Sort; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -11,17 +11,18 @@ import static dev.morphia.aggregation.stages.SetWindowFields.Output.output; import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; -public class TestIntegral extends AggregationTest { - @Test +public class TestIntegral extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/integral/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$powerMeterID") - .sortBy(Sort.ascending("timeStamp")) - .output(output("powerMeterKilowattHours") - .operator(integral("$kilowatts").unit(HOUR)) - .window() - .range("unbounded", "current", HOUR)))); + testPipeline(new ActionTestOptions().removeIds(true), + (aggregation) -> aggregation + .pipeline(setWindowFields().partitionBy("$powerMeterID").sortBy(Sort.ascending("timeStamp")) + .output(output("powerMeterKilowattHours").operator(integral("$kilowatts").unit(HOUR)) + .window().range("unbounded", "current", HOUR)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsArray.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsArray.java index 75c963d9d70..ee3fec1e476 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsArray.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsArray.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,15 +10,16 @@ import static dev.morphia.aggregation.expressions.ConditionalExpressions.condition; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIsArray extends AggregationTest { - @Test +public class TestIsArray extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/isArray/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("items", condition( - and(isArray("$instock"), isArray("$ordered")), - concatArrays("$instock", "$ordered"), - "One or more fields is not an array.")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("items", condition(and(isArray("$instock"), isArray("$ordered")), + concatArrays("$instock", "$ordered"), "One or more fields is not an array.")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsNumber.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsNumber.java index 62d34664f40..1d4d42eea8c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsNumber.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsNumber.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -15,30 +15,31 @@ import static dev.morphia.aggregation.stages.Group.group; import static dev.morphia.aggregation.stages.Group.id; -public class TestIsNumber extends AggregationTest { - @Test +public class TestIsNumber extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/isNumber/example1 + * + */ + @Test(testName = "Use $isNumber to Check if a Field is Numeric") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("isNumber", isNumber("$reading")) - .field("hasType", type("$reading")))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("isNumber", isNumber("$reading")).field("hasType", type("$reading")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/isNumber/example2 + * + */ + @Test(testName = "Conditionally Modify Fields using $isNumber") public void testExample2() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - addFields() - .field("points", - condition(isNumber("$grade"), - "$grade", - switchExpression() - .branch(eq("$grade", "A"), 4.0) - .branch(eq("$grade", "B"), 3.0) - .branch(eq("$grade", "C"), 2.0) - .branch(eq("$grade", "D"), 1.0) + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline( + addFields().field("points", + condition(isNumber("$grade"), "$grade", + switchExpression().branch(eq("$grade", "A"), 4.0).branch(eq("$grade", "B"), 3.0) + .branch(eq("$grade", "C"), 2.0).branch(eq("$grade", "D"), 1.0) .branch(eq("$grade", "F"), 0.0))), - group(id("$student_id")) - .field("GPA", avg("$points")))); + group(id("$student_id")).field("GPA", avg("$points")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoDayOfWeek.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoDayOfWeek.java index 87bef03888f..bb2d0e64093 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoDayOfWeek.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoDayOfWeek.java @@ -1,21 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.DateExpressions.isoDayOfWeek; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIsoDayOfWeek extends AggregationTest { - @Test +public class TestIsoDayOfWeek extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("name", "$name") - .include("dayOfWeek", isoDayOfWeek("$birthday")))); + testPipeline((aggregation) -> aggregation.pipeline( + project().suppressId().include("name", "$name").include("dayOfWeek", isoDayOfWeek("$birthday")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeek.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeek.java index c757dd33627..c17dd013124 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeek.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeek.java @@ -1,21 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.DateExpressions.isoWeek; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIsoWeek extends AggregationTest { - @Test +public class TestIsoWeek extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/isoWeek/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("city", "$city") - .include("weekNumber", isoWeek("$date")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().suppressId().include("city", "$city").include("weekNumber", isoWeek("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeekYear.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeekYear.java index c0dc3168e01..ed9cc386060 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeekYear.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeekYear.java @@ -1,19 +1,20 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.DateExpressions.isoWeekYear; import static dev.morphia.aggregation.stages.Projection.project; -public class TestIsoWeekYear extends AggregationTest { - @Test +public class TestIsoWeekYear extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/isoWeekYear/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("yearNumber", isoWeekYear("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("yearNumber", isoWeekYear("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLast.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLast.java index 132762830c6..29a6aaf94dc 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLast.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLast.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -12,29 +12,32 @@ import static dev.morphia.aggregation.stages.Sort.sort; import static dev.morphia.query.Sort.*; -public class TestLast extends AggregationTest { - @Test +public class TestLast extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/last/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - sort() - .ascending("item") - .ascending("date"), - group(id("$item")) - .field("lastSalesDate", last("$date")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(sort().ascending("item").ascending("date"), + group(id("$item")).field("lastSalesDate", last("$date")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/last/example2 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample2() { - // this example starts importing a bunch of stuff and gets more complicated than I care + // this example starts importing a bunch of stuff and gets more complicated than + // I care // to make the parser support. we have working examples already. /* - * testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - * setWindowFields() - * .partitionBy("$state") - * .sortBy(ascending("orderDate")) - * .output(output("lastOrderTypeForState") - * .operator(last("$type")) - * .window() + * testPipeline(new dev.morphia.test.util.ActionTestOptions(). removeIds(false), + * (aggregation) -> aggregation.pipeline( setWindowFields() + * .partitionBy("$state") .sortBy(ascending("orderDate")) + * .output(output("lastOrderTypeForState") .operator(last("$type")) .window() * .documents("current", "unbounded")))); */ } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLastN.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLastN.java index 9d59ea0d184..0248e767926 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLastN.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLastN.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.ComparisonExpressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -15,49 +16,53 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.test.ServerVersion.v52; -public class TestLastN extends AggregationTest { +public class TestLastN extends TemplatedTestBase { - @Test + @Test(testName = "Find the Last Three Player Scores for a Single Game") public void testExample1() { - testPipeline(v52, false, false, (aggregation) -> aggregation - .pipeline( - match(eq("gameId", "G1")), - group(id("$gameId")) - .field("lastThreeScores", lastN( - 3, - array("$playerId", "$score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation + .pipeline( + match(eq("gameId", "G1")), + group(id("$gameId")) + .field("lastThreeScores", lastN( + 3, + array("$playerId", "$score"))))); } - @Test + @Test(testName = "Finding the Last Three Player Scores Across Multiple Games") public void testExample2() { - testPipeline(v52, false, false, (aggregation) -> aggregation - .pipeline(group(id("$gameId")) - .field("playerId", lastN( - 3, - array("$playerId", "$score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation + .pipeline(group(id("$gameId")) + .field("playerId", lastN( + 3, + array("$playerId", "$score"))))); } - @Test + @Test(testName = "Using ``$sort`` With ``$lastN``") public void testExample3() { - testPipeline(v52, false, false, (aggregation) -> aggregation - .pipeline( - sort().descending("score"), - group(id("$gameId")) - .field("playerId", lastN( - 3, - array("$playerId", "$score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation + .pipeline( + sort().descending("score"), + group(id("$gameId")) + .field("playerId", lastN( + 3, + array("$playerId", "$score"))))); } - @Test + @Test(testName = "Computing ``n`` Based on the Group Key for ``$group``") public void testExample4() { - testPipeline(v52, false, false, (aggregation) -> aggregation - .pipeline(group(id().field("gameId", "$gameId")) - .field("gamescores", lastN( - condition(ComparisonExpressions.eq("$gameId", "G2"), 1, 3), - "$score")))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation + .pipeline(group(id().field("gameId", "$gameId")) + .field("gamescores", lastN( + condition(ComparisonExpressions.eq("$gameId", "G2"), 1, 3), + "$score")))); } @Test diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLet.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLet.java index 7870ea800d8..e8d55a3488b 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLet.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLet.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,15 +10,16 @@ import static dev.morphia.aggregation.expressions.VariableExpressions.let; import static dev.morphia.aggregation.stages.Projection.project; -public class TestLet extends AggregationTest { - @Test +public class TestLet extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/let/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("finalTotal", let(multiply("$$total", "$$discounted")) - .variable("total", add("$price", "$tax")) - .variable("discounted", - condition("$applyDiscount", 0.9, 1))))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("finalTotal", + let(multiply("$$total", "$$discounted")).variable("total", add("$price", "$tax")).variable("discounted", + condition("$applyDiscount", 0.9, 1))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLinearFill.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLinearFill.java index 1a7eac78631..ac6c012ad86 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLinearFill.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLinearFill.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.query.Sort; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,29 +9,31 @@ import static dev.morphia.aggregation.expressions.WindowExpressions.locf; import static dev.morphia.aggregation.stages.SetWindowFields.Output.output; import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; +import static dev.morphia.query.Sort.ascending; import static dev.morphia.test.ServerVersion.v53; -public class TestLinearFill extends AggregationTest { - @Test - public void testExample2() { - testPipeline(v53, true, false, (aggregation) -> aggregation.pipeline( - setWindowFields() - .sortBy(Sort.ascending("time")) - .output(output("price") - .operator(linearFill("$price"))))); +public class TestLinearFill extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/linearFill/example1 + */ + @Test(testName = "Fill Missing Values with Linear Interpolation") + public void testExample1() { + testPipeline(new ActionTestOptions().serverVersion(v53).removeIds(true).orderMatters(false), + (aggregation) -> aggregation.pipeline(setWindowFields().sortBy(ascending("time")) + .output(output("price").operator(linearFill("$price"))))); } - @Test - public void testExample3() { - testPipeline(v53, true, false, (aggregation) -> aggregation.pipeline( - setWindowFields() - .sortBy(Sort.ascending("time")) - .output(output("linearFillPrice") - .operator(linearFill("$price")), - output("locfPrice") - .operator(locf("$price"))))); + /** + * test data: dev/morphia/test/aggregation/expressions/linearFill/example2 + * + */ + @Test(testName = "Use Multiple Fill Methods in a Single Stage") + public void testExample2() { + testPipeline(new ActionTestOptions().serverVersion(v53).removeIds(true).orderMatters(false), + (aggregation) -> aggregation.pipeline(setWindowFields().sortBy(ascending("time")).output( + output("linearFillPrice").operator(linearFill("$price")), + output("locfPrice").operator(locf("$price"))))); } - } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLiteral.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLiteral.java index bdd730dee93..23d6e93af58 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLiteral.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLiteral.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,21 +8,25 @@ import static dev.morphia.aggregation.expressions.Expressions.literal; import static dev.morphia.aggregation.stages.Projection.project; -public class TestLiteral extends AggregationTest { - @Test +public class TestLiteral extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/literal/example1 + * + */ + @Test(testName = "Treat ``$`` as a Literal") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("costsOneDollar", - eq("$price", literal("$1"))))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("costsOneDollar", eq("$price", literal("$1"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/literal/example2 + * + */ + @Test(testName = "Project a New Field with Value ``1``") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("title") - .include("editionNumber", literal(1)))); + testPipeline( + (aggregation) -> aggregation.pipeline(project().include("title").include("editionNumber", literal(1)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLn.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLn.java index 32d9f535bf4..77e0fef5173 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLn.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLn.java @@ -1,20 +1,20 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.ln; import static dev.morphia.aggregation.stages.Projection.project; -public class TestLn extends AggregationTest { - @Test +public class TestLn extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/ln/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("x", "$year") - .include("y", ln("$sales")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("x", "$year").include("y", ln("$sales")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLocf.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLocf.java index ffad548e8ba..f8893c2ebc0 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLocf.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLocf.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -12,26 +13,28 @@ import static dev.morphia.query.Sort.ascending; import static dev.morphia.test.ServerVersion.v52; -public class TestLocf extends AggregationTest { - @Test +public class TestLocf extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/locf/example1 + * + */ + @Test(testName = "Fill Missing Values with the Last Observed Value") public void testExample1() { - testPipeline(v52, true, false, (aggregation) -> aggregation - .pipeline(setWindowFields() - .sortBy(ascending("time")) - .output(output("price") - .operator(locf("$price"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).removeIds(true).orderMatters(false), + (aggregation) -> aggregation.pipeline( + setWindowFields().sortBy(ascending("time")).output(output("price").operator(locf("$price"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/locf/example2 + * + */ + @Test(testName = "Use Multiple Fill Methods in a Single Stage") public void testExample2() { - testPipeline(ServerVersion.v52, true, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .sortBy(ascending("time")) - .output( - output("linearFillPrice") - .operator(linearFill("$price")), - output("locfPrice") - .operator(locf("$price"))))); + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.v52).removeIds(true), + (aggregation) -> aggregation.pipeline(setWindowFields().sortBy(ascending("time")).output( + output("linearFillPrice").operator(linearFill("$price")), + output("locfPrice").operator(locf("$price"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog.java index c26e99f7bce..69d85bd6fca 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog.java @@ -1,8 +1,7 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.impls.Expression; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,16 +10,16 @@ import static dev.morphia.aggregation.expressions.MathExpressions.log; import static dev.morphia.aggregation.stages.Projection.project; -public class TestLog extends AggregationTest { - @Test +public class TestLog extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/log/example1 + * + */ + @Test(testName = "main") public void testExample1() { Expression value; - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("bitsNeeded", floor( - add( - 1, - log("$int", 2)))))); + testPipeline( + (aggregation) -> aggregation.pipeline(project().include("bitsNeeded", floor(add(1, log("$int", 2)))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog10.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog10.java index fd5912351fe..b98c579e4fd 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog10.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog10.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,12 +8,14 @@ import static dev.morphia.aggregation.expressions.MathExpressions.multiply; import static dev.morphia.aggregation.stages.Projection.project; -public class TestLog10 extends AggregationTest { - @Test +public class TestLog10 extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/log10/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("pH", multiply(-1, log10("$H3O"))))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("pH", multiply(-1, log10("$H3O"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLt.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLt.java index 06a33caa86f..0d1a7407b78 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLt.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLt.java @@ -1,22 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ComparisonExpressions.lt; import static dev.morphia.aggregation.stages.Projection.project; -public class TestLt extends AggregationTest { - @Test +public class TestLt extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/lt/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("item") - .include("qty") - .include("qtyLt250", lt("$qty", 250)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().suppressId().include("item").include("qty").include("qtyLt250", lt("$qty", 250)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLte.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLte.java index 476376a9e3a..c22fa8b99d2 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLte.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLte.java @@ -1,22 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ComparisonExpressions.lte; import static dev.morphia.aggregation.stages.Projection.project; -public class TestLte extends AggregationTest { - @Test +public class TestLte extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/lte/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("item") - .include("qty") - .include("qtyLte250", lte("$qty", 250)))); + testPipeline((aggregation) -> aggregation.pipeline( + project().suppressId().include("item").include("qty").include("qtyLte250", lte("$qty", 250)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLtrim.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLtrim.java index 87c4d97865a..838fe06281e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLtrim.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLtrim.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.ltrim; import static dev.morphia.aggregation.stages.Projection.project; -public class TestLtrim extends AggregationTest { - @Test +public class TestLtrim extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/ltrim/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("description", ltrim("$description")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("description", ltrim("$description")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMap.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMap.java index 7079f3590bd..c3939813506 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMap.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMap.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -12,41 +12,35 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Projection.project; -public class TestMap extends AggregationTest { - @Test +public class TestMap extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/map/example1 + * + */ + @Test(testName = "Add to Each Element of an Array") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - project() - .include("adjustedGrades", - map("$quizzes", - add( - "$$grade", - 2)) - .as("grade")))); + testPipeline(new ActionTestOptions().removeIds(true), (aggregation) -> aggregation + .pipeline(project().include("adjustedGrades", map("$quizzes", add("$$grade", 2)).as("grade")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/map/example2 + * + */ + @Test(testName = "Truncate Each Array Element") public void testExample2() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - project() - .include("city", "$city") - .include("integerValues", - map( - "$distances", - trunc("$$decimalValue")) - .as("decimalValue")))); + testPipeline(new ActionTestOptions().removeIds(true), + (aggregation) -> aggregation.pipeline(project().include("city", "$city").include("integerValues", + map("$distances", trunc("$$decimalValue")).as("decimalValue")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/map/example3 + * + */ + @Test(testName = "Convert Celsius Temperatures to Fahrenheit") public void testExample3() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("tempsF", - map( - "$tempsC", - add( - multiply("$$tempInCelsius", 1.8), - 32)) - .as("tempInCelsius")))); + testPipeline(new ActionTestOptions().removeIds(true), (aggregation) -> aggregation.pipeline(addFields() + .field("tempsF", map("$tempsC", add(multiply("$$tempInCelsius", 1.8), 32)).as("tempInCelsius")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMax.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMax.java index 241bf12f383..bf65c23775f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMax.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMax.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -14,34 +15,39 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.ascending; -public class TestMax extends AggregationTest { - @Test +public class TestMax extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/max/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - group(id("$item")) - .field("maxTotalAmount", max(multiply("$price", "$quantity"))) - .field("maxQuantity", max("$quantity")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation + .pipeline(group(id("$item")).field("maxTotalAmount", max(multiply("$price", "$quantity"))) + .field("maxQuantity", max("$quantity")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/max/example2 + * + */ + @Test(testName = "Use in ``$project`` Stage") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("quizMax", max("$quizzes")) - .include("labMax", max("$labs")) - .include("examMax", max("$final", "$midterm")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("quizMax", max("$quizzes")) + .include("labMax", max("$labs")).include("examMax", max("$final", "$midterm")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/max/example3 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample3() { - testPipeline(ServerVersion.v50, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("maximumQuantityForState") - .operator(max("$quantity")) - .window() - .documents("unbounded", "current")))); + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.v50), + (aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(ascending("orderDate")).output(output("maximumQuantityForState") + .operator(max("$quantity")).window().documents("unbounded", "current")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMaxN.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMaxN.java index 2fadbfd6fb9..f5b65ee8eb6 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMaxN.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMaxN.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.ComparisonExpressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -15,34 +16,38 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.test.ServerVersion.v52; -public class TestMaxN extends AggregationTest { - @Test +public class TestMaxN extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/maxN/example1 + * + */ + @Test(testName = "Find the Maximum Three ``Scores`` for a Single Game") public void testExample1() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - match(eq("gameId", "G1")), - group(id("$gameId")) - .field("maxThreeScores", maxN( - 3, - array("$score", "$playerId"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(match(eq("gameId", "G1")), + group(id("$gameId")).field("maxThreeScores", maxN(3, array("$score", "$playerId"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/maxN/example2 + * + */ + @Test(testName = "Finding the Maximum Three Scores Across Multiple Games") public void testExample2() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id("$gameId")) - .field("maxScores", maxN( - 3, - array("$score", "$playerId"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), (aggregation) -> aggregation + .pipeline(group(id("$gameId")).field("maxScores", maxN(3, array("$score", "$playerId"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/maxN/example3 + * + */ + @Test(testName = "Computing ``n`` Based on the Group Key for ``$group``") public void testExample3() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id().field("gameId", "$gameId")) - .field("gamescores", maxN( - condition(ComparisonExpressions.eq("$gameId", "G2"), 1, 3), - array("$score", "$playerId"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id().field("gameId", "$gameId")).field("gamescores", maxN( + condition(ComparisonExpressions.eq("$gameId", "G2"), 1, 3), array("$score", "$playerId"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMedian.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMedian.java index 2e1d242fa5f..92d34c0d2fb 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMedian.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMedian.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -13,34 +14,37 @@ import static dev.morphia.query.Sort.ascending; import static dev.morphia.test.ServerVersion.v70; -public class TestMedian extends AggregationTest { - @Test - public void testExample2() { - testPipeline(v70, false, false, aggregation -> aggregation - .pipeline( - group().field("test01_median", median("$test01")))); +public class TestMedian extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/median/example1 + */ + @Test(testName = "Use |operatorName| as an Accumulator") + public void testExample1() { + testPipeline(new ActionTestOptions().serverVersion(v70).orderMatters(false), + aggregation -> aggregation.pipeline(group().field("test01_median", median("$test01")))); } - @Test - public void testExample3() { - testPipeline(v70, false, true, aggregation -> aggregation - .pipeline(project() - .suppressId() - .include("studentId") - .include("testMedians", median( - array("$test01", "$test02", "$test03"))))); + /** + * test data: dev/morphia/test/aggregation/expressions/median/example2 + * + */ + @Test(testName = "Use |operatorName| in a ``$project`` Stage") + public void testExample2() { + testPipeline(new ActionTestOptions().serverVersion(v70), + aggregation -> aggregation.pipeline(project().suppressId().include("studentId").include("testMedians", + median(array("$test01", "$test02", "$test03"))))); } - @Test - public void testExample4() { - testPipeline(v70, false, true, aggregation -> aggregation.pipeline( - setWindowFields() - .sortBy(ascending("test01")) - .output(output("test01_median") - .operator(median("$test01")) - .window().range(-3, 3)), - project().suppressId() - .include("studentId") - .include("test01_median"))); + /** + * test data: dev/morphia/test/aggregation/expressions/median/example3 + * + */ + @Test(testName = "Use |operatorName| in a ``$setWindowField`` Stage") + public void testExample3() { + testPipeline(new ActionTestOptions().serverVersion(v70), + aggregation -> aggregation.pipeline( + setWindowFields().sortBy(ascending("test01")) + .output(output("test01_median").operator(median("$test01")).window().range(-3, 3)), + project().suppressId().include("studentId").include("test01_median"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMergeObjects.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMergeObjects.java index 916f57479de..d99d87f9522 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMergeObjects.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMergeObjects.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -14,27 +14,27 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.aggregation.stages.ReplaceRoot.replaceRoot; -public class TestMergeObjects extends AggregationTest { - @Test +public class TestMergeObjects extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/mergeObjects/example1 + * + */ + @Test(testName = "``$mergeObjects``") public void testExample1() { loadData("items", 2); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - lookup("items") - .foreignField("item") - .localField("item") - .as("fromItems"), - replaceRoot(mergeObjects() - .add(elementAt("$fromItems", 0)) - .add(ROOT)), - project() - .exclude("fromItems"))); + testPipeline((aggregation) -> aggregation.pipeline( + lookup("items").foreignField("item").localField("item").as("fromItems"), + replaceRoot(mergeObjects().add(elementAt("$fromItems", 0)).add(ROOT)), project().exclude("fromItems"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/mergeObjects/example2 + * + */ + @Test(testName = "``$mergeObjects`` as an Accumulator") public void testExample2() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - group(id("$item")) - .field("mergedSales", mergeObjects().add("$quantity")))); + testPipeline(new ActionTestOptions().orderMatters(false), (aggregation) -> aggregation + .pipeline(group(id("$item")).field("mergedSales", mergeObjects().add("$quantity")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMeta.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMeta.java index 05e7c6d9508..33e429864bd 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMeta.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMeta.java @@ -1,7 +1,9 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.query.FindOptions; +import dev.morphia.query.Meta; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -16,29 +18,67 @@ import static dev.morphia.query.filters.Filters.gte; import static dev.morphia.query.filters.Filters.text; -public class TestMeta extends AggregationTest { - @Test +public class TestMeta extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/meta/example1 + * + */ + @Test(testName = "``$meta: \"textScore\"`` :: Aggregation") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - match(text("cake")), - group(id(meta())) - .field("count", sum(1)))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(match(text("cake")), group(id(meta())).field("count", sum(1)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/meta/example2 + * + */ + @Test(testName = "``$meta: \"textScore\"`` :: Find and Project") public void testExample2() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - match(eq("type", "apparel")), - addFields() - .field("idxKey", meta(INDEXKEY)))); + testQuery( + new ActionTestOptions().orderMatters(false) + .findOptions(new FindOptions().projection().project(Meta.textScore("score"))), + (query) -> query.filter(text("cake"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/meta/example3 + */ + @Test(testName = "``$meta: \"indexKey\"`` :: Aggregation") public void testExample3() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - match(gte("price", 10)), - addFields() - .field("idxKey", meta(INDEXKEY)))); + testPipeline(new ActionTestOptions().removeIds(true), aggregation -> aggregation + .pipeline(match(eq("type", "apparel")), addFields().field("idxKey", meta(INDEXKEY)))); + } + + /** + * test data: dev/morphia/test/aggregation/expressions/meta/example4 + */ + @Test(testName = "``$meta: \"indexKey\"`` :: Find and Project") + public void testExample4() { + testQuery( + new ActionTestOptions().orderMatters(false).removeIds(true) + .findOptions(new FindOptions().projection().project(Meta.indexKey("idxKey"))), + (query) -> query.filter(eq("type", "apparel"))); + } + + /** + * test data: dev/morphia/test/aggregation/expressions/meta/example5 + */ + @Test(testName = "``$meta: \"indexKey\"`` :: Aggregation [1]") + public void testExample5() { + testPipeline(new ActionTestOptions().removeIds(true), (aggregation) -> aggregation + .pipeline(match(gte("price", 10)), addFields().field("idxKey", meta(INDEXKEY)))); + } + + /** + * test data: dev/morphia/test/aggregation/expressions/meta/example6 + */ + @Test(testName = "``$meta: \"indexKey\"`` :: Find and Project [1]") + public void testExample6() { + testQuery( + new ActionTestOptions().orderMatters(false).removeIds(true) + .findOptions(new FindOptions().projection().project(Meta.indexKey("idxKey"))), + (query) -> query.filter(gte("price", 10))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMillisecond.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMillisecond.java index 4fc00bd8958..44b6dfd20df 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMillisecond.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMillisecond.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestMillisecond extends AggregationTest { - @Test +public class TestMillisecond extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/millisecond/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMin.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMin.java index e60e8898b91..74a6c0d3dc6 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMin.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMin.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.query.Sort; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -13,33 +14,38 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.test.ServerVersion.v50; -public class TestMin extends AggregationTest { - @Test +public class TestMin extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/min/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(v50, false, false, (aggregation) -> aggregation.pipeline( - group(id("$item")) - .field("minQuantity", min("$quantity")))); + testPipeline(new ActionTestOptions().serverVersion(v50).orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id("$item")).field("minQuantity", min("$quantity")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/min/example2 + * + */ + @Test(testName = "Use in ``$project`` Stage") public void testExample2() { - testPipeline(v50, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("quizMin", min("$quizzes")) - .include("labMin", min("$labs")) - .include("examMin", min("$final", "$midterm")))); + testPipeline(new ActionTestOptions().serverVersion(v50), + (aggregation) -> aggregation.pipeline(project().include("quizMin", min("$quizzes")) + .include("labMin", min("$labs")).include("examMin", min("$final", "$midterm")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/min/example3 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample3() { - testPipeline(v50, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(Sort.ascending("orderDate")) - .output(output("minimumQuantityForState") - .operator(min("$quantity")) - .window() - .documents("unbounded", "current")))); + testPipeline(new ActionTestOptions().serverVersion(v50), + (aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(Sort.ascending("orderDate")).output(output("minimumQuantityForState") + .operator(min("$quantity")).window().documents("unbounded", "current")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinN.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinN.java index 1680cc2a46b..06d335add13 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinN.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinN.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.ComparisonExpressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -14,35 +15,39 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.test.ServerVersion.v52; -public class TestMinN extends AggregationTest { +public class TestMinN extends TemplatedTestBase { - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/minN/example1 + * + */ + @Test(testName = "Find the Minimum Three ``Scores`` for a Single Game") public void testExample1() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - match(eq("gameId", "G1")), - group(id("$gameId")) - .field("minScores", minN( - 3, - array("$score", "$playerId"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(match(eq("gameId", "G1")), + group(id("$gameId")).field("minScores", minN(3, array("$score", "$playerId"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/minN/example2 + * + */ + @Test(testName = "Finding the Minimum Three Documents Across Multiple Games") public void testExample2() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id("$gameId")) - .field("minScores", minN( - 3, - array("$score", "$playerId"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), (aggregation) -> aggregation + .pipeline(group(id("$gameId")).field("minScores", minN(3, array("$score", "$playerId"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/minN/example3 + * + */ + @Test(testName = "Computing ``n`` Based on the Group Key for ``$group``") public void testExample3() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id().field("gameId", "$gameId")) - .field("gamescores", minN( - condition(ComparisonExpressions.eq("$gameId", "G2"), 1, 3), - array("$score", "$playerId"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id().field("gameId", "$gameId")).field("gamescores", minN( + condition(ComparisonExpressions.eq("$gameId", "G2"), 1, 3), array("$score", "$playerId"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinute.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinute.java index 74f293904a2..2ef3a0b153e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinute.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinute.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestMinute extends AggregationTest { - @Test +public class TestMinute extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/minute/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMod.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMod.java index 2741dcdecbf..70784295e32 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMod.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMod.java @@ -1,26 +1,30 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.mod; import static dev.morphia.aggregation.stages.Projection.project; -public class TestMod extends AggregationTest { - @Test +public class TestMod extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/mod/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("remainder", mod("$hours", "$tasks")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("remainder", mod("$hours", "$tasks")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/mod/example2 + * + */ + @Test(testName = "Negative Dividend") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("remainder", mod("$dividend", "$divisor")))); + testPipeline( + (aggregation) -> aggregation.pipeline(project().include("remainder", mod("$dividend", "$divisor")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMonth.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMonth.java index 98dbdeec818..d8ab50ba33f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMonth.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMonth.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestMonth extends AggregationTest { - @Test +public class TestMonth extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/month/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMultiply.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMultiply.java index d90dc4d9a13..55c21d533b0 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMultiply.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMultiply.java @@ -1,21 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.multiply; import static dev.morphia.aggregation.stages.Projection.project; -public class TestMultiply extends AggregationTest { - @Test +public class TestMultiply extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/multiply/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("date") - .include("item") - .include("total", multiply("$price", "$quantity")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("date").include("item").include("total", multiply("$price", "$quantity")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNe.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNe.java index 231c31380c2..268e8fd206c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNe.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNe.java @@ -1,22 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ComparisonExpressions.ne; import static dev.morphia.aggregation.stages.Projection.project; -public class TestNe extends AggregationTest { - @Test +public class TestNe extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/ne/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("item") - .include("qty") - .include("qtyNe250", ne("$qty", 250)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().suppressId().include("item").include("qty").include("qtyNe250", ne("$qty", 250)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNot.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNot.java index a0fa3555b50..08063e9a74c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNot.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNot.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,13 +8,15 @@ import static dev.morphia.aggregation.expressions.ComparisonExpressions.gt; import static dev.morphia.aggregation.stages.Projection.project; -public class TestNot extends AggregationTest { - @Test +public class TestNot extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/not/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("result", not(gt("$qty", 250))))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("result", not(gt("$qty", 250))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestObjectToArray.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestObjectToArray.java index ae109eabcfa..b80b1729d8b 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestObjectToArray.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestObjectToArray.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -17,37 +17,38 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.aggregation.stages.Unwind.unwind; -public class TestObjectToArray extends AggregationTest { - @Test +public class TestObjectToArray extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/objectToArray/example1 + * + */ + @Test(testName = "``$objectToArray`` Example") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("dimensions", objectToArray("$dimensions")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("dimensions", objectToArray("$dimensions")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/objectToArray/example2 + * + */ + @Test(testName = "``$objectToArray`` to Sum Nested Fields") public void testExample2() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .include("warehouses", objectToArray("$instock")), - unwind("warehouses"), - group(id("$warehouses.k")) - .field("total", sum("$warehouses.v")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(project().include("warehouses", objectToArray("$instock")), + unwind("warehouses"), group(id("$warehouses.k")).field("total", sum("$warehouses.v")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/objectToArray/example3 + * + */ + @Test(testName = "``$objectToArray`` + ``$arrayToObject`` Example") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("instock", objectToArray("$instock")), - addFields() - .field("instock", concatArrays("$instock", - array(document() - .field("k", "total") - .field("v", sum("$instock.v"))))), - addFields() - .field("instock", arrayToObject("$instock")))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("instock", objectToArray("$instock")), + addFields().field("instock", + concatArrays("$instock", array(document().field("k", "total").field("v", sum("$instock.v"))))), + addFields().field("instock", arrayToObject("$instock")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestOr.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestOr.java index 088fb7d0872..ec6777dccaa 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestOr.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestOr.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,15 +9,15 @@ import static dev.morphia.aggregation.expressions.ComparisonExpressions.lt; import static dev.morphia.aggregation.stages.Projection.project; -public class TestOr extends AggregationTest { - @Test +public class TestOr extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/or/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("result", or( - gt("$qty", 250), - lt("$qty", 200))))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("result", or(gt("$qty", 250), lt("$qty", 200))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPercentile.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPercentile.java index 53a945716ce..0c897383613 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPercentile.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPercentile.java @@ -2,7 +2,8 @@ import java.util.List; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -15,56 +16,60 @@ import static dev.morphia.test.ServerVersion.v70; import static java.util.List.of; -public class TestPercentile extends AggregationTest { - @Test +public class TestPercentile extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/percentile/example1 + */ + @Test(testName = "Calculate a Single Value as an Accumulator") + public void testExample1() { + testPipeline(new ActionTestOptions().serverVersion(v70).orderMatters(false), aggregation -> aggregation + .pipeline(group().field("test01_percentiles", percentile("$test01", of(0.95))))); + } + + /** + * test data: dev/morphia/test/aggregation/expressions/percentile/example2 + * + */ + @Test(testName = "Calculate Multiple Values as an Accumulator") public void testExample2() { - testPipeline(v70, false, false, aggregation -> aggregation - .pipeline( - group() - .field("test01_percentiles", percentile("$test01", - of(0.95))))); + testPipeline(new ActionTestOptions().serverVersion(v70).orderMatters(false), + aggregation -> aggregation + .pipeline(group().field("test01_percentiles", percentile("$test01", of(0.5, 0.75, 0.9, 0.95))) + .field("test02_percentiles", percentile("$test02", of(0.5, 0.75, 0.9, 0.95))) + .field("test03_percentiles", percentile("$test03", of(0.5, 0.75, 0.9, 0.95))) + .field("test03_percent_alt", percentile("$test03", of(0.9, 0.5, 0.75, 0.95))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/percentile/example3 + * + */ + @Test(testName = "Use |operatorName| in a ``$project`` Stage") public void testExample3() { - testPipeline(v70, false, false, aggregation -> aggregation.pipeline( - group() - .field("test01_percentiles", - percentile("$test01", of(0.5, 0.75, 0.9, 0.95))) - .field("test02_percentiles", - percentile("$test02", of(0.5, 0.75, 0.9, 0.95))) - .field("test03_percentiles", - percentile("$test03", of(0.5, 0.75, 0.9, 0.95))) - .field("test03_percent_alt", - percentile("$test03", of(0.9, 0.5, 0.75, 0.95))))); + testPipeline(new ActionTestOptions().serverVersion(v70).orderMatters(false), + aggregation -> aggregation.pipeline(project().suppressId().include("studentId").include( + "testPercentiles", percentile(List.of("$test01", "$test02", "$test03"), of(0.5, 0.95))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/percentile/example4 + * + */ + @Test(testName = "Use |operatorName| in a ``$setWindowField`` Stage") public void testExample4() { - testPipeline(v70, false, false, aggregation -> aggregation - .pipeline(project() - .suppressId() - .include("studentId") - .include("testPercentiles", - percentile(List.of("$test01", "$test02", "$test03"), - of(0.5, 0.95))))); + testPipeline(new ActionTestOptions().serverVersion(v70).orderMatters(false), + aggregation -> aggregation.pipeline( + setWindowFields().sortBy(ascending("test01")) + .output(output("test01_95percentile").operator(percentile("$test01", List.of(0.95))) + .window().range(-3, 3)), + project().suppressId().include("studentId").include("test01_95percentile") + + )); } - @Test + @Test(testName = "Use |operatorName| in a ``$setWindowField`` Stage") public void testExample5() { - testPipeline(v70, false, false, aggregation -> aggregation.pipeline( - setWindowFields() - .sortBy(ascending("test01")) - .output(output("test01_95percentile") - .operator(percentile("$test01", List.of(0.95))) - .window().range(-3, 3)), - project() - .suppressId() - .include("studentId") - .include("test01_95percentile") - - )); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPow.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPow.java index 1f2eeaac44e..e852a2a6ff3 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPow.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPow.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,12 +8,15 @@ import static dev.morphia.aggregation.expressions.WindowExpressions.stdDevPop; import static dev.morphia.aggregation.stages.Projection.project; -public class TestPow extends AggregationTest { - @Test +public class TestPow extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/pow/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("variance", pow(stdDevPop("$scores.score"), 2)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("variance", pow(stdDevPop("$scores.score"), 2)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPush.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPush.java index 8e667823f33..f11da3b5db9 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPush.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPush.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -16,33 +16,28 @@ import static dev.morphia.aggregation.stages.Sort.sort; import static dev.morphia.query.Sort.*; -public class TestPush extends AggregationTest { - @Test +public class TestPush extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/push/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - sort() - .ascending("date") - .ascending("item"), - group(id() - .field("day", - dayOfYear("$date")) - .field("year", - year("$date"))) - .field("itemsSold", push(document() - .field("item", "$item") - .field("quantity", "$quantity"))))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(sort().ascending("date").ascending("item"), + group(id().field("day", dayOfYear("$date")).field("year", year("$date"))).field("itemsSold", + push(document().field("item", "$item").field("quantity", "$quantity"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/push/example2 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("quantitiesForState") - .operator(push("$quantity")) - .window() - .documents("unbounded", "current")))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(ascending("orderDate")).output(output("quantitiesForState").operator(push("$quantity")).window() + .documents("unbounded", "current")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRadiansToDegrees.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRadiansToDegrees.java index fea4be40205..93a83209b03 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRadiansToDegrees.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRadiansToDegrees.java @@ -1,19 +1,22 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.TrigonometryExpressions.radiansToDegrees; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestRadiansToDegrees extends AggregationTest { - @Test +public class TestRadiansToDegrees extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/radiansToDegrees/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("angle_a_deg", radiansToDegrees("$angle_a")) + testPipeline(new ActionTestOptions().removeIds(true), + (aggregation) -> aggregation.pipeline(addFields().field("angle_a_deg", radiansToDegrees("$angle_a")) .field("angle_b_deg", radiansToDegrees("$angle_b")) .field("angle_c_deg", radiansToDegrees("$angle_c")))); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRand.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRand.java index f78029db47a..6efeb0aa700 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRand.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRand.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.test.DriverVersion; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -17,31 +17,29 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.query.filters.Filters.expr; -public class TestRand extends AggregationTest { - public TestRand() { - skipDataCheck(); - minDriver = DriverVersion.v43; - } - - @Test +public class TestRand extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/rand/example1 + * + */ + @Test(testName = "Generate Random Data Points") public void testExample1() { - testPipeline(ServerVersion.ANY, true, false, (aggregation) -> aggregation.pipeline( - set() - .field("amount", multiply(rand(), 100)), - set() - .field("amount", floor("$amount")), - merge("donors"))); + testPipeline( + new ActionTestOptions().removeIds(true).orderMatters(false).minDriver(DriverVersion.v43) + .skipDataCheck(true), + (aggregation) -> aggregation.pipeline(set().field("amount", multiply(rand(), 100)), + set().field("amount", floor("$amount")), merge("donors"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/rand/example2 + * + */ + @Test(testName = "Select Random Items From a Collection") public void testExample2() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - match(eq("district", 3)), - match(expr(lt(0.5, rand()))), - project() - .suppressId() - .include("name") - .include("registered"))); + testPipeline(new ActionTestOptions().orderMatters(false).minDriver(DriverVersion.v43).skipDataCheck(true), + (aggregation) -> aggregation.pipeline(match(eq("district", 3)), match(expr(lt(0.5, rand()))), + project().suppressId().include("name").include("registered"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRange.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRange.java index 574fb9a0c7c..02be3274dc4 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRange.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRange.java @@ -1,21 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ArrayExpressions.range; import static dev.morphia.aggregation.stages.Projection.project; -public class TestRange extends AggregationTest { - @Test +public class TestRange extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/range/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("city") - .include("Rest stops", range(0, "$distance").step(25)))); + testPipeline((aggregation) -> aggregation.pipeline( + project().suppressId().include("city").include("Rest stops", range(0, "$distance").step(25)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRank.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRank.java index ecd32d7a4a6..48fb1b60ad6 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRank.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRank.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,35 +10,35 @@ import static dev.morphia.query.Sort.ascending; import static dev.morphia.query.Sort.descending; -public class TestRank extends AggregationTest { - @Test +public class TestRank extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/rank/example1 + * + */ + @Test(testName = "Rank Partitions by an Integer Field") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(descending("quantity")) - .output(output("rankQuantityForState") - .operator(rank())))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(descending("quantity")).output(output("rankQuantityForState").operator(rank())))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/rank/example2 + * + */ + @Test(testName = "Rank Partitions by a Date Field") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("rankOrderDateForState") - .operator(rank())))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(ascending("orderDate")).output(output("rankOrderDateForState").operator(rank())))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/rank/example3 + * + */ + @Test(testName = "Rank Partitions Containing Duplicate Values, Nulls, or Missing Data") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(descending("quantity")) - .output(output("rankQuantityForState") - .operator(rank())))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(descending("quantity")).output(output("rankQuantityForState").operator(rank())))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReduce.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReduce.java index f447e1d5bcf..2a2ffa9a628 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReduce.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReduce.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -19,46 +19,39 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.query.filters.Filters.gt; -public class TestReduce extends AggregationTest { - @Test +public class TestReduce extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/reduce/example1 + * + */ + @Test(testName = "Multiplication") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - group(id("$experimentId")) - .field("probabilityArr", push("$probability")), - project() - .include("description") - .include("results", reduce( - "$probabilityArr", - 1, - multiply("$$value", "$$this"))))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline( + group(id("$experimentId")).field("probabilityArr", push("$probability")), + project().include("description").include("results", + reduce("$probabilityArr", 1, multiply("$$value", "$$this"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/reduce/example2 + * + */ + @Test(testName = "String Concatenation") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(gt("hobbies", array())), - project() - .include("name") - .include("bio", reduce( - "$hobbies", - "My hobbies include:", - concat( - "$$value", - condition( - eq("$$value", "My hobbies include:"), - " ", - ", "), - "$$this"))))); + testPipeline((aggregation) -> aggregation.pipeline(match(gt("hobbies", array())), + project().include("name").include("bio", reduce("$hobbies", "My hobbies include:", + concat("$$value", condition(eq("$$value", "My hobbies include:"), " ", ", "), "$$this"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/reduce/example3 + * + */ + @Test(testName = "Array Concatenation") public void testExample3() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .include("collapsed", reduce( - "$arr", - array(), - concatArrays("$$value", "$$this"))))); + testPipeline(new ActionTestOptions().orderMatters(false), (aggregation) -> aggregation + .pipeline(project().include("collapsed", reduce("$arr", array(), concatArrays("$$value", "$$this"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFind.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFind.java index b58094ece77..c399ff525de 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFind.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFind.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -18,57 +18,60 @@ import static dev.morphia.aggregation.stages.Sort.sort; import static dev.morphia.aggregation.stages.Unwind.unwind; -public class TestRegexFind extends AggregationTest { - @Test +public class TestRegexFind extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/regexFind/example1 + * + */ + @Test(testName = "``$regexFind`` and Its Options") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - addFields() - .field("returnObject", regexFind("$description") - .pattern("line")))); + testPipeline(new ActionTestOptions().orderMatters(false), (aggregation) -> aggregation + .pipeline(addFields().field("returnObject", regexFind("$description").pattern("line")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/regexFind/example2 + * + */ + @Test(testName = "Use ``$regexFind`` to Parse Email from String") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("email", regexFind("$comment") - .pattern("[a-z0-9_.+-]+@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+") - .options("i")), - set() - .field("email", "$email.match"))); + testPipeline((aggregation) -> aggregation.pipeline( + addFields().field("email", + regexFind("$comment").pattern("[a-z0-9_.+-]+@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+").options("i")), + set().field("email", "$email.match"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/regexFind/example3 + * + */ + @Test(testName = "Apply ``$regexFind`` to String Elements of an Array") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unwind("details"), + testPipeline((aggregation) -> aggregation.pipeline(unwind("details"), addFields() - .field("regexemail", regexFind("$details") - .pattern("^[a-z0-9_.+-]+@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+$") - .options("i")) - .field("regexphone", regexFind("$details") - .pattern("^[+]{0,1}[0-9]*\\-?[0-9_\\-]+$")), - project() - .include("_id") - .include("name") - .include("details", document() - .field("email", "$regexemail.match") - .field("phone", "$regexphone.match")), - group(id("$_id")) - .field("name", first("$name")) - .field("details", mergeObjects().add("$details")), + .field("regexemail", + regexFind("$details").pattern("^[a-z0-9_.+-]+@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+$") + .options("i")) + .field("regexphone", regexFind("$details").pattern("^[+]{0,1}[0-9]*\\-?[0-9_\\-]+$")), + project().include("_id").include("name").include("details", + document().field("email", "$regexemail.match").field("phone", "$regexphone.match")), + group(id("$_id")).field("name", first("$name")).field("details", mergeObjects().add("$details")), sort().ascending("_id"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/regexFind/example4 + * + */ + @Test(testName = "Use Captured Groupings to Parse User Name") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("username", regexFind("$email") - .pattern("^([a-z0-9_.+-]+)@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+$") - .options("i")), - set() - .field("username", elementAt("$username.captures", 0)))); + testPipeline( + (aggregation) -> aggregation + .pipeline( + addFields().field("username", + regexFind("$email").pattern("^([a-z0-9_.+-]+)@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+$") + .options("i")), + set().field("username", elementAt("$username.captures", 0)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFindAll.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFindAll.java index 372433dce10..41e377f3b54 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFindAll.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFindAll.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -12,35 +12,42 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Set.set; -public class TestRegexFindAll extends AggregationTest { - @Test +public class TestRegexFindAll extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/regexFindAll/example1 + * + */ + @Test(testName = "``$regexFindAll`` and Its Options") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - addFields() - .field("returnObject", regexFindAll("$description").pattern("line")))); + testPipeline(new ActionTestOptions().orderMatters(false), (aggregation) -> aggregation + .pipeline(addFields().field("returnObject", regexFindAll("$description").pattern("line")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/regexFindAll/example2 + * + */ + @Test(testName = "Use ``$regexFindAll`` to Parse Email from String") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("email", regexFindAll("$comment") - .pattern("[a-z0-9_.+-]+@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+") - .options("i")), - set() - .field("email", "$email.match"))); + testPipeline((aggregation) -> aggregation.pipeline( + addFields().field("email", + regexFindAll("$comment").pattern("[a-z0-9_.+-]+@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+").options("i")), + set().field("email", "$email.match"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/regexFindAll/example3 + * + */ + @Test(testName = "Use Captured Groupings to Parse User Name") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("names", regexFindAll("$comment") - .pattern("([a-z0-9_.+-]+)@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+") - .options("i")), - set() - .field("names", reduce("$names.captures", array(), concatArrays("$$value", "$$this"))))); + testPipeline( + (aggregation) -> aggregation.pipeline( + addFields().field("names", + regexFindAll("$comment").pattern("([a-z0-9_.+-]+)@[a-z0-9_.+-]+\\.[a-z0-9_.+-]+") + .options("i")), + set().field("names", reduce("$names.captures", array(), concatArrays("$$value", "$$this"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexMatch.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexMatch.java index 997b54c07ff..63fac344d02 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexMatch.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexMatch.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,25 +9,26 @@ import static dev.morphia.aggregation.expressions.StringExpressions.regexMatch; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestRegexMatch extends AggregationTest { - @Test +public class TestRegexMatch extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/regexMatch/example1 + * + */ + @Test(testName = "``$regexMatch`` and Its Options") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - addFields() - .field("result", regexMatch("$description").pattern("line")))); + testPipeline(new ActionTestOptions().orderMatters(false), (aggregation) -> aggregation + .pipeline(addFields().field("result", regexMatch("$description").pattern("line")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/regexMatch/example2 + * + */ + @Test(testName = "Use ``$regexMatch`` to Check Email Address") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("category", - condition( - regexMatch("$comment") - .pattern("[a-z0-9_.+-]+@mongodb.com") - .options("i"), - "Employee", "External")))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("category", condition( + regexMatch("$comment").pattern("[a-z0-9_.+-]+@mongodb.com").options("i"), "Employee", "External")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceAll.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceAll.java index a2339c76f9b..057d25ae590 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceAll.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceAll.java @@ -1,23 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.replaceAll; import static dev.morphia.aggregation.stages.Projection.project; -public class TestReplaceAll extends AggregationTest { - @Test +public class TestReplaceAll extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/replaceAll/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item", - replaceAll( - "$item", - "blue paint", - "red paint")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item", replaceAll("$item", "blue paint", "red paint")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceOne.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceOne.java index ea3e8c678c4..0a165c39b1f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceOne.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceOne.java @@ -1,23 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.replaceOne; import static dev.morphia.aggregation.stages.Projection.project; -public class TestReplaceOne extends AggregationTest { - @Test +public class TestReplaceOne extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/replaceOne/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item", - replaceOne( - "$item", - "blue paint", - "red paint")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item", replaceOne("$item", "blue paint", "red paint")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReverseArray.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReverseArray.java index cc7e1ba77ff..3aa295e5c1c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReverseArray.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReverseArray.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ArrayExpressions.reverseArray; import static dev.morphia.aggregation.stages.Projection.project; -public class TestReverseArray extends AggregationTest { - @Test +public class TestReverseArray extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/reverseArray/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name") - .include("reverseFavorites", reverseArray("$favorites")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("name").include("reverseFavorites", reverseArray("$favorites")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRound.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRound.java index 4a1cae6d432..7f1de6589c1 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRound.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRound.java @@ -1,19 +1,20 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.round; import static dev.morphia.aggregation.stages.Projection.project; -public class TestRound extends AggregationTest { - @Test +public class TestRound extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/round/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("roundedValue", round("$value", 1)))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("roundedValue", round("$value", 1)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRtrim.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRtrim.java index 3ea0141e18e..cf3fdab8710 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRtrim.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRtrim.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.rtrim; import static dev.morphia.aggregation.stages.Projection.project; -public class TestRtrim extends AggregationTest { - @Test +public class TestRtrim extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/rtrim/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("description", rtrim("$description")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("description", rtrim("$description")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSampleRate.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSampleRate.java index fa7faeb26f9..9df74c027c8 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSampleRate.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSampleRate.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.stages.Count; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -10,13 +10,15 @@ import static dev.morphia.aggregation.stages.Count.*; import static dev.morphia.aggregation.stages.Match.match; -public class TestSampleRate extends AggregationTest { - @Test +public class TestSampleRate extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/sampleRate/example1 + * + */ + @Test(testName = "main") public void testExample1() { - skipDataCheck(); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(sampleRate(0.33)), - Count.count("numMatches"))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(match(sampleRate(0.33)), Count.count("numMatches"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSecond.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSecond.java index 6a6316dc80f..36450fffaff 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSecond.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSecond.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSecond extends AggregationTest { - @Test +public class TestSecond extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/second/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetDifference.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetDifference.java index 6b151f11703..1a6e2f68830 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetDifference.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetDifference.java @@ -1,22 +1,23 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.SetExpressions.setDifference; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSetDifference extends AggregationTest { - @Test +public class TestSetDifference extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/setDifference/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("flowerFieldA") - .include("flowerFieldB") - .include("inBOnly", setDifference("$flowerFieldB", "$flowerFieldA")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(project().suppressId().include("flowerFieldA") + .include("flowerFieldB").include("inBOnly", setDifference("$flowerFieldB", "$flowerFieldA")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetEquals.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetEquals.java index 25ffde47675..f968aedd9e1 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetEquals.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetEquals.java @@ -1,22 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.SetExpressions.setEquals; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSetEquals extends AggregationTest { - @Test +public class TestSetEquals extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/setEquals/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("cakes") - .include("cupcakes") - .include("sameFlavors", setEquals("$cakes", "$cupcakes")))); + testPipeline((aggregation) -> aggregation.pipeline(project().suppressId().include("cakes").include("cupcakes") + .include("sameFlavors", setEquals("$cakes", "$cupcakes")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetField.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetField.java index 76df6c82217..2a31d783c86 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetField.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetField.java @@ -2,7 +2,8 @@ import dev.morphia.test.DriverVersion; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -14,49 +15,64 @@ import static dev.morphia.aggregation.stages.Unset.unset; import static dev.morphia.query.filters.Filters.eq; -public class TestSetField extends AggregationTest { - public TestSetField() { - minDriver = DriverVersion.v43; - } - - @Test +public class TestSetField extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/setField/example1 + * + */ + @Test(testName = "Add Fields that Contain Periods (``.``)") public void testExample1() { - testPipeline(ServerVersion.v50, false, true, (aggregation) -> aggregation.pipeline( - replaceWith(setField("price.usd", ROOT, "$price")), - unset("price"))); + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.v50).minDriver(DriverVersion.v43), + (aggregation) -> aggregation.pipeline(replaceWith(setField("price.usd", ROOT, "$price")), + unset("price"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/setField/example2 + * + */ + @Test(testName = "Add Fields that Start with a Dollar Sign (``$``)") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceWith(setField(literal("$price"), ROOT, "$price")), - unset("price"))); + testPipeline(new ActionTestOptions().minDriver(DriverVersion.v43), (aggregation) -> aggregation + .pipeline(replaceWith(setField(literal("$price"), ROOT, "$price")), unset("price"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/setField/example3 + * + */ + @Test(testName = "Update Fields that Contain Periods (``.``)") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(eq("_id", 1)), - replaceWith(setField("price.usd", ROOT, 49.99)))); + testPipeline(new ActionTestOptions().minDriver(DriverVersion.v43), (aggregation) -> aggregation + .pipeline(match(eq("_id", 1)), replaceWith(setField("price.usd", ROOT, 49.99)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/setField/example4 + * + */ + @Test(testName = "Update Fields that Start with a Dollar Sign (``$``)") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(eq("_id", 1)), - replaceWith(setField(literal("$price"), ROOT, 49.99)))); + testPipeline(new ActionTestOptions().minDriver(DriverVersion.v43), (aggregation) -> aggregation + .pipeline(match(eq("_id", 1)), replaceWith(setField(literal("$price"), ROOT, 49.99)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/setField/example5 + * + */ + @Test(testName = "Remove Fields that Contain Periods (``.``)") public void testExample5() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceWith(setField("price.usd", ROOT, REMOVE)))); + testPipeline((aggregation) -> aggregation.pipeline(replaceWith(setField("price.usd", ROOT, REMOVE)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/setField/example6 + * + */ + @Test(testName = "Remove Fields that Start with a Dollar Sign (``$``)") public void testExample6() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceWith(setField(literal("$price"), ROOT, REMOVE)))); + testPipeline((aggregation) -> aggregation.pipeline(replaceWith(setField(literal("$price"), ROOT, REMOVE)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIntersection.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIntersection.java index 615772add99..d76ec6afdc6 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIntersection.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIntersection.java @@ -1,25 +1,31 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.SetExpressions.setIntersection; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSetIntersection extends AggregationTest { - @Test +public class TestSetIntersection extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/setIntersection/example1 + * + */ + @Test(testName = "Elements Array Example") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("flowerFieldA") - .include("flowerFieldB") - .include("commonToBoth", setIntersection("$flowerFieldA", "$flowerFieldB")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation + .pipeline(project().suppressId().include("flowerFieldA").include("flowerFieldB") + .include("commonToBoth", setIntersection("$flowerFieldA", "$flowerFieldB")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/setIntersection/example2 + * + */ + @Test(testName = "Retrieve Documents for Roles Granted to the Current User") public void testExample2() { // this requires auth and roles configuration which the tests won't have } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIsSubset.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIsSubset.java index 6d9ab5d3fe4..14307a9aa5c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIsSubset.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIsSubset.java @@ -1,22 +1,23 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.SetExpressions.setIsSubset; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSetIsSubset extends AggregationTest { - @Test +public class TestSetIsSubset extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/setIsSubset/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("flowerFieldA") - .include("flowerFieldB") - .include("AisSubset", setIsSubset("$flowerFieldA", "$flowerFieldB")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(project().suppressId().include("flowerFieldA") + .include("flowerFieldB").include("AisSubset", setIsSubset("$flowerFieldA", "$flowerFieldB")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetUnion.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetUnion.java index 6c69e5b6b13..352e939c69e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetUnion.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetUnion.java @@ -1,22 +1,23 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.SetExpressions.setUnion; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSetUnion extends AggregationTest { - @Test +public class TestSetUnion extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/setUnion/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("flowerFieldA") - .include("flowerFieldB") - .include("allValues", setUnion("$flowerFieldA", "$flowerFieldB")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(project().suppressId().include("flowerFieldA") + .include("flowerFieldB").include("allValues", setUnion("$flowerFieldA", "$flowerFieldB")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestShift.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestShift.java index 0279803fd02..bf18a981b80 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestShift.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestShift.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,25 +9,27 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.descending; -public class TestShift extends AggregationTest { - @Test +public class TestShift extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/shift/example1 + * + */ + @Test(testName = "Shift Using a Positive Integer") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(descending("quantity")) - .output(output("shiftQuantityForState") - .operator(shift("$quantity", 1, "Not available"))))); + testPipeline((aggregation) -> aggregation + .pipeline(setWindowFields().partitionBy("$state").sortBy(descending("quantity")) + .output(output("shiftQuantityForState").operator(shift("$quantity", 1, "Not available"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/shift/example2 + * + */ + @Test(testName = "Shift Using a Negative Integer") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(descending("quantity")) - .output(output("shiftQuantityForState") - .operator(shift("$quantity", -1, "Not available"))))); + testPipeline((aggregation) -> aggregation + .pipeline(setWindowFields().partitionBy("$state").sortBy(descending("quantity")) + .output(output("shiftQuantityForState").operator(shift("$quantity", -1, "Not available"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSin.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSin.java index c71c2222c5b..448e20f1f4e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSin.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSin.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,19 +9,25 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.sin; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestSin extends AggregationTest { - @Test +public class TestSin extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/sin/example1 + * + */ + @Test(testName = "main :: Sine of Value in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("side_b", multiply(sin(degreesToRadians("$angle_a")), "$hypotenuse")))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("side_b", multiply(sin(degreesToRadians("$angle_a")), "$hypotenuse")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/sin/example2 + * + */ + @Test(testName = "main :: Sine of Value in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("side_b", multiply(sin("$angle_a"), "$hypotenuse")))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("side_b", multiply(sin("$angle_a"), "$hypotenuse")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSinh.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSinh.java index a94255c3854..c0504f6c6f3 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSinh.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSinh.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,19 +9,24 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.sinh; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestSinh extends AggregationTest { - @Test +public class TestSinh extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/sinh/example1 + * + */ + @Test(testName = "main :: Hyperbolic Sine of Value in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("sinh_output", sinh(degreesToRadians("$angle"))))); + testPipeline(new ActionTestOptions().removeIds(true), (aggregation) -> aggregation + .pipeline(addFields().field("sinh_output", sinh(degreesToRadians("$angle"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/sinh/example2 + * + */ + @Test(testName = "main :: Hyperbolic Sine of Value in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("sinh_output", sinh("$angle")))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("sinh_output", sinh("$angle")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSize.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSize.java index b7e1a1538a3..046ac2bce3c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSize.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSize.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,16 +9,15 @@ import static dev.morphia.aggregation.expressions.ConditionalExpressions.condition; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSize extends AggregationTest { - @Test +public class TestSize extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/size/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("numberOfColors", condition( - isArray("$colors"), - size("$colors"), - "NA")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("item").include("numberOfColors", + condition(isArray("$colors"), size("$colors"), "NA")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSlice.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSlice.java index e7178bb5c60..d86546507c2 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSlice.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSlice.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.ArrayExpressions.slice; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSlice extends AggregationTest { - @Test +public class TestSlice extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/slice/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name") - .include("threeFavorites", slice("$favorites", 3)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("name").include("threeFavorites", slice("$favorites", 3)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSortArray.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSortArray.java index 99f48a911a7..1be257be6dc 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSortArray.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSortArray.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -13,64 +14,74 @@ import static dev.morphia.query.Sort.naturalAscending; import static dev.morphia.test.ServerVersion.v52; -public class TestSortArray extends AggregationTest { - @Test +public class TestSortArray extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/sortArray/example1 + * + */ + @Test(testName = "Sort on a Field ") public void testExample1() { - testPipeline(v52, (aggregation) -> aggregation - .pipeline(project() - .suppressId() - .include("result", sortArray("$team", ascending("name"))))); + testPipeline(new ActionTestOptions().serverVersion(v52), (aggregation) -> aggregation + .pipeline(project().suppressId().include("result", sortArray("$team", ascending("name"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/sortArray/example2 + * + */ + @Test(testName = "Sort on a Subfield") public void testExample2() { - testPipeline(v52, (aggregation) -> { + testPipeline(new ActionTestOptions().serverVersion(v52), (aggregation) -> { return aggregation - .project(project() - .suppressId() - .include("result", sortArray("$team", descending("address.city")))); + .project(project().suppressId().include("result", sortArray("$team", descending("address.city")))); }); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/sortArray/example3 + * + */ + @Test(testName = "Sort on Multiple Fields") public void testExample3() { - testPipeline(v52, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("result", - sortArray("$team", - descending("age"), - ascending("name"))))); + testPipeline(new ActionTestOptions().serverVersion(v52), (aggregation) -> aggregation.pipeline( + project().suppressId().include("result", sortArray("$team", descending("age"), ascending("name"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/sortArray/example4 + * + */ + @Test(testName = "Sort an Array of Integers") public void testExample4() { - testPipeline(v52, (aggregation) -> { - return aggregation - .project(project() - .suppressId() - .include("result", sortArray(array(1, 4, 1, 6, 12, 5), - naturalAscending()))); + testPipeline(new ActionTestOptions().serverVersion(v52), (aggregation) -> { + return aggregation.project( + project().suppressId().include("result", sortArray(array(1, 4, 1, 6, 12, 5), naturalAscending()))); }); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/sortArray/example5 + * + */ + @Test(testName = "Sort on Mixed Type Fields") public void testExample5() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("result", sortArray( - array(20, 4, - document("a", "Free"), - 6, 21, 5, "Gratis", - document("a", null), - document("a", document("sale", true).field("price", 19)), - 10.23, - document("a", "On sale")), - naturalAscending())))); + testPipeline( + new ActionTestOptions().serverVersion(v52).orderMatters(false), ( + aggregation) -> aggregation + .pipeline( + project().suppressId() + .include("result", + sortArray( + array(20, 4, document("a", "Free"), 6, 21, 5, "Gratis", + document("a", null), + document("a", + document("sale", true).field("price", + 19)), + 10.23, document("a", "On sale")), + naturalAscending())))); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSplit.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSplit.java index 14bbfb9561c..af0f90325f2 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSplit.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSplit.java @@ -1,14 +1,12 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.aggregation.expressions.impls.RegexExpression; import dev.morphia.query.filters.Filters; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.AccumulatorExpressions.sum; -import static dev.morphia.aggregation.expressions.StringExpressions.regexMatch; import static dev.morphia.aggregation.expressions.StringExpressions.split; import static dev.morphia.aggregation.stages.Group.group; import static dev.morphia.aggregation.stages.Group.id; @@ -17,23 +15,19 @@ import static dev.morphia.aggregation.stages.Sort.sort; import static dev.morphia.aggregation.stages.Unwind.unwind; -public class TestSplit extends AggregationTest { - @Test +public class TestSplit extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/split/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> { - RegexExpression regex = regexMatch("$city_state").pattern("[A-Z]{2}"); - return aggregation.pipeline( - project() - .include("city_state", split("$city", ", ")) - .include("qty"), - unwind("city_state"), - match(Filters.regex("city_state", "[A-Z]{2}")), - group(id() - .field("state", "$city_state")) - .field("total_qty", sum("$qty")), - sort() - .descending("total_qty")); - }); + testPipeline(new ActionTestOptions().skipActionCheck(true), + (aggregation) -> aggregation.pipeline( + project().include("city_state", split("$city", ", ")).include("qty"), unwind("city_state"), + match(Filters.regex("city_state", "[A-Z]{2}")), + group(id().field("state", "$city_state")).field("total_qty", sum("$qty")), + sort().descending("total_qty"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSqrt.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSqrt.java index 0b53d3cb6b5..0f02e509f93 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSqrt.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSqrt.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,15 +10,15 @@ import static dev.morphia.aggregation.expressions.MathExpressions.subtract; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSqrt extends AggregationTest { - @Test +public class TestSqrt extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/sqrt/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("distance", sqrt( - add( - pow(subtract("$p2.y", "$p1.y"), 2), - pow(subtract("$p2.x", "$p1.x"), 2)))))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("distance", + sqrt(add(pow(subtract("$p2.y", "$p1.y"), 2), pow(subtract("$p2.x", "$p1.x"), 2)))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevPop.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevPop.java index c3bf1bb7350..e4a31bcdd1f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevPop.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevPop.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -13,33 +13,38 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.*; -public class TestStdDevPop extends AggregationTest { - @Test +public class TestStdDevPop extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/stdDevPop/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - group(id("$quiz")) - .field("stdDev", stdDevPop("$score")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id("$quiz")).field("stdDev", stdDevPop("$score")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/stdDevPop/example2 + * + */ + @Test(testName = "Use in ``$project`` Stage") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("stdDev", stdDevPop("$scores.score")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("stdDev", stdDevPop("$scores.score")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/stdDevPop/example3 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample3() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("stdDevPopQuantityForState") - .operator(stdDevPop("$quantity")) - .window() - .documents("unbounded", "current")) - - )); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(ascending("orderDate")).output(output("stdDevPopQuantityForState") + .operator(stdDevPop("$quantity")).window().documents("unbounded", "current")) + + )); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevSamp.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevSamp.java index b8e673c11c5..473c121b578 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevSamp.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevSamp.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -13,25 +12,26 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.*; -public class TestStdDevSamp extends AggregationTest { - @Test +public class TestStdDevSamp extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/stdDevSamp/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - sample(100), - group(id(null)) - .field("ageStdDev", stdDevSamp("$age")))); + testPipeline((aggregation) -> aggregation.pipeline(sample(100), + group(id(null)).field("ageStdDev", stdDevSamp("$age")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/stdDevSamp/example2 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("stdDevSampQuantityForState") - .operator(stdDevSamp("$quantity")) - .window() - .documents("unbounded", "current")))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(ascending("orderDate")).output(output("stdDevSampQuantityForState") + .operator(stdDevSamp("$quantity")).window().documents("unbounded", "current")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenBytes.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenBytes.java index c98a55b609b..2d0867c54c2 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenBytes.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenBytes.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.strLenBytes; import static dev.morphia.aggregation.stages.Projection.project; -public class TestStrLenBytes extends AggregationTest { - @Test +public class TestStrLenBytes extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/strLenBytes/example1 + * + */ + @Test(testName = "Single-Byte and Multibyte Character Set") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name") - .include("length", strLenBytes("$name")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("name").include("length", strLenBytes("$name")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenCP.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenCP.java index 0f71e72d5ab..6f6d56995ed 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenCP.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenCP.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.strLenCP; import static dev.morphia.aggregation.stages.Projection.project; -public class TestStrLenCP extends AggregationTest { - @Test +public class TestStrLenCP extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/strLenCP/example1 + * + */ + @Test(testName = "Single-Byte and Multibyte Character Set") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name") - .include("length", strLenCP("$name")))); + testPipeline( + (aggregation) -> aggregation.pipeline(project().include("name").include("length", strLenCP("$name")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrcasecmp.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrcasecmp.java index eb2d09925c4..f5f6e33132e 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrcasecmp.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrcasecmp.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.strcasecmp; import static dev.morphia.aggregation.stages.Projection.project; -public class TestStrcasecmp extends AggregationTest { - @Test +public class TestStrcasecmp extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/strcasecmp/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("comparisonResult", strcasecmp("$quarter", "13q4")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("comparisonResult", strcasecmp("$quarter", "13q4")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrBytes.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrBytes.java index 97575e38087..1c2efb97787 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrBytes.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrBytes.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,23 +9,26 @@ import static dev.morphia.aggregation.expressions.StringExpressions.substrBytes; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSubstrBytes extends AggregationTest { - @Test +public class TestSubstrBytes extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/substrBytes/example1 + * + */ + @Test(testName = "Single-Byte Character Set") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("yearSubstring", substrBytes("$quarter", 0, 2)) - .include("quarterSubtring", substrBytes("$quarter", 2, - subtract(strLenBytes("$quarter"), 2))))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("yearSubstring", substrBytes("$quarter", 0, 2)) + .include("quarterSubtring", substrBytes("$quarter", 2, subtract(strLenBytes("$quarter"), 2))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/substrBytes/example2 + * + */ + @Test(testName = "Single-Byte and Multibyte Character Set") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name") - .include("menuCode", substrBytes("$name", 0, 3)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("name").include("menuCode", substrBytes("$name", 0, 3)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrCP.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrCP.java index 6ad63eb181f..b94128e5ef8 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrCP.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrCP.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,23 +9,26 @@ import static dev.morphia.aggregation.expressions.StringExpressions.substrCP; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSubstrCP extends AggregationTest { - @Test +public class TestSubstrCP extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/substrCP/example1 + * + */ + @Test(testName = "Single-Byte Character Set") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("yearSubstring", substrCP("$quarter", 0, 2)) - .include("quarterSubtring", substrCP("$quarter", 2, - subtract(strLenCP("$quarter"), 2))))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("yearSubstring", substrCP("$quarter", 0, 2)) + .include("quarterSubtring", substrCP("$quarter", 2, subtract(strLenCP("$quarter"), 2))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/substrCP/example2 + * + */ + @Test(testName = "Single-Byte and Multibyte Character Set") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name") - .include("menuCode", substrCP("$name", 0, 3)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("name").include("menuCode", substrCP("$name", 0, 3)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubtract.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubtract.java index 1a1253634a5..40b1ceaf6ef 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubtract.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubtract.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,34 +9,34 @@ import static dev.morphia.aggregation.expressions.MathExpressions.subtract; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSubtract extends AggregationTest { - @Test +public class TestSubtract extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/subtract/example1 + * + */ + @Test(testName = "Subtract Numbers") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("total", subtract( - add("$price", "$fee"), - "$discount")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("total", subtract(add("$price", "$fee"), "$discount")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/subtract/example2 + * + */ + @Test(testName = "Subtract Two Dates") public void testExample2() { - skipDataCheck(); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("dateDifference", subtract( - "$$NOW", - "$date")))); + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation + .pipeline(project().include("item").include("dateDifference", subtract("$$NOW", "$date")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/subtract/example3 + * + */ + @Test(testName = "Subtract Milliseconds from a Date") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("dateDifference", - subtract("$date", 5 * 60 * 1000)))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item").include("dateDifference", subtract("$date", 5 * 60 * 1000)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSum.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSum.java index d88977bbe90..4643efa530c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSum.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSum.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.query.Sort; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -18,37 +18,38 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.test.ServerVersion.v50; -public class TestSum extends AggregationTest { - @Test +public class TestSum extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/sum/example1 + * + */ + @Test(testName = "Use in ``$group`` Stage") public void testExample1() { - testPipeline(v50, false, false, (aggregation) -> aggregation.pipeline( - group( - id(document() - .field("day", dayOfYear("$date")) - .field("year", year("$date")))) - .field("totalAmount", sum(multiply("$price", "$quantity"))) - .field("count", sum(1)))); + testPipeline(new ActionTestOptions().serverVersion(v50).orderMatters(false), + (aggregation) -> aggregation + .pipeline(group(id(document().field("day", dayOfYear("$date")).field("year", year("$date")))) + .field("totalAmount", sum(multiply("$price", "$quantity"))).field("count", sum(1)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/sum/example2 + * + */ + @Test(testName = "Use in ``$project`` Stage") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("quizTotal", sum("$quizzes")) - .include("labTotal", sum("$labs")) - .include("examTotal", sum("$final", "$midterm")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("quizTotal", sum("$quizzes")) + .include("labTotal", sum("$labs")).include("examTotal", sum("$final", "$midterm")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/sum/example3 + * + */ + @Test(testName = "Use in ``$setWindowFields`` Stage") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(Sort.ascending("orderDate")) - .output(output("sumQuantityForState") - .operator(sum("$quantity")) - .window() - .documents("unbounded", "current")))); + testPipeline((aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(Sort.ascending("orderDate")).output(output("sumQuantityForState").operator(sum("$quantity")) + .window().documents("unbounded", "current")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSwitch.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSwitch.java index 221d012063f..bacd63567f4 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSwitch.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSwitch.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -12,21 +11,17 @@ import static dev.morphia.aggregation.expressions.ConditionalExpressions.switchExpression; import static dev.morphia.aggregation.stages.Projection.project; -public class TestSwitch extends AggregationTest { - @Test +public class TestSwitch extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/switch/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("name") - .include("summary", - switchExpression() - .branch(gte(avg("$scores"), 90), "Doing great!") - .branch(and( - gte(avg("$scores"), 80), - lt(avg("$scores"), 90)), "Doing pretty well.") - .branch( - lt(avg("$scores"), 80), "Needs improvement.") - .defaultCase("No scores found.")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("name").include("summary", + switchExpression().branch(gte(avg("$scores"), 90), "Doing great!") + .branch(and(gte(avg("$scores"), 80), lt(avg("$scores"), 90)), "Doing pretty well.") + .branch(lt(avg("$scores"), 80), "Needs improvement.").defaultCase("No scores found.")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTan.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTan.java index c8aa72515f5..7ddc66ebef9 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTan.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTan.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,21 +9,25 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.tan; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestTan extends AggregationTest { - @Test +public class TestTan extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/tan/example1 + * + */ + @Test(testName = "main :: Tangent of Value in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("side_b", multiply( - tan(degreesToRadians("$angle_a")), - "$side_a")))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("side_b", multiply(tan(degreesToRadians("$angle_a")), "$side_a")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/tan/example2 + * + */ + @Test(testName = "main :: Tangent of Value in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("side_b", multiply(tan("$angle_a"), "$side_a")))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("side_b", multiply(tan("$angle_a"), "$side_a")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTanh.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTanh.java index 935e047c69f..920294297fc 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTanh.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTanh.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -9,19 +9,24 @@ import static dev.morphia.aggregation.expressions.TrigonometryExpressions.tanh; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestTanh extends AggregationTest { - @Test +public class TestTanh extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/tanh/example1 + * + */ + @Test(testName = "main :: Hyperbolic Tangent in Degrees") public void testExample1() { - testPipeline(ServerVersion.ANY, true, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("tanh_output", tanh(degreesToRadians("$angle"))))); + testPipeline(new ActionTestOptions().removeIds(true), (aggregation) -> aggregation + .pipeline(addFields().field("tanh_output", tanh(degreesToRadians("$angle"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/tanh/example2 + * + */ + @Test(testName = "main :: Hyperbolic Tangent in Radians") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("tanh_output", tanh("$angle")))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("tanh_output", tanh("$angle")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToBool.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToBool.java index 4c7459b0d2e..8477e6c5239 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToBool.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToBool.java @@ -1,8 +1,7 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.query.filters.Filters; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -12,17 +11,19 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Match.match; -public class TestToBool extends AggregationTest { - @Test +public class TestToBool extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toBool/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("convertedShippedFlag", - switchExpression() - .branch(eq("$shipped", "false"), false) - .branch(eq("$shipped", ""), false) - .defaultCase(toBool("$shipped"))), - match(Filters.eq("convertedShippedFlag", false)))); + testPipeline( + (aggregation) -> aggregation.pipeline( + addFields().field("convertedShippedFlag", + switchExpression().branch(eq("$shipped", "false"), false) + .branch(eq("$shipped", ""), false).defaultCase(toBool("$shipped"))), + match(Filters.eq("convertedShippedFlag", false)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDate.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDate.java index 86066f750b4..9fa6ae5cdf5 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDate.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDate.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,14 +8,15 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Sort.sort; -public class TestToDate extends AggregationTest { - @Test +public class TestToDate extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toDate/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("convertedDate", toDate("$order_date")), - sort() - .ascending("convertedDate"))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("convertedDate", toDate("$order_date")), + sort().ascending("convertedDate"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDecimal.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDecimal.java index 0838d10e31c..efc2ea35175 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDecimal.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDecimal.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,17 +10,16 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Projection.project; -public class TestToDecimal extends AggregationTest { - @Test +public class TestToDecimal extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toDecimal/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("convertedPrice", toDecimal("$price")) - .field("convertedQty", toInt("$qty")), - project() - .include("item") - .include("totalPrice", - multiply("$convertedPrice", "$convertedQty")))); + testPipeline((aggregation) -> aggregation.pipeline( + addFields().field("convertedPrice", toDecimal("$price")).field("convertedQty", toInt("$qty")), + project().include("item").include("totalPrice", multiply("$convertedPrice", "$convertedQty")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDouble.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDouble.java index 54d822576f7..3758e3bb450 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDouble.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDouble.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,12 +8,15 @@ import static dev.morphia.aggregation.expressions.TypeExpressions.toDouble; import static dev.morphia.aggregation.stages.AddFields.addFields; -public class TestToDouble extends AggregationTest { - @Test +public class TestToDouble extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toDouble/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("degrees", toDouble(substrBytes("$temp", 0, 4))))); + testPipeline((aggregation) -> aggregation + .pipeline(addFields().field("degrees", toDouble(substrBytes("$temp", 0, 4))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToInt.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToInt.java index b3a5c3cc8b7..0e631fb99e5 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToInt.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToInt.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -11,17 +10,16 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Projection.project; -public class TestToInt extends AggregationTest { - @Test +public class TestToInt extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toInt/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("convertedPrice", toDecimal("$price")) - .field("convertedQty", toInt("$qty")), - project() - .include("item") - .include("totalPrice", - multiply("$convertedPrice", "$convertedQty")))); + testPipeline((aggregation) -> aggregation.pipeline( + addFields().field("convertedPrice", toDecimal("$price")).field("convertedQty", toInt("$qty")), + project().include("item").include("totalPrice", multiply("$convertedPrice", "$convertedQty")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLong.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLong.java index 77a30601d5f..1f679f67191 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLong.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLong.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,14 +8,15 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Sort.sort; -public class TestToLong extends AggregationTest { - @Test +public class TestToLong extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toLong/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("convertedQty", toLong("$qty")), - sort() - .descending("convertedQty"))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("convertedQty", toLong("$qty")), + sort().descending("convertedQty"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLower.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLower.java index 8ba8b31100b..9b54cd22d01 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLower.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLower.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.toLower; import static dev.morphia.aggregation.stages.Projection.project; -public class TestToLower extends AggregationTest { - @Test +public class TestToLower extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toLower/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item", toLower("$item")) - .include("description", toLower("$description")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item", toLower("$item")).include("description", toLower("$description")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToObjectId.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToObjectId.java index 3970cd4627e..832e7e208e8 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToObjectId.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToObjectId.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -9,14 +8,15 @@ import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Sort.sort; -public class TestToObjectId extends AggregationTest { - @Test +public class TestToObjectId extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toObjectId/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("convertedId", toObjectId("$_id")), - sort() - .descending("convertedId"))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("convertedId", toObjectId("$_id")), + sort().descending("convertedId"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToString.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToString.java index f030f6a0788..3b24e9abb34 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToString.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToString.java @@ -1,22 +1,23 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.StringExpressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.AddFields.addFields; import static dev.morphia.aggregation.stages.Sort.sort; -public class TestToString extends AggregationTest { - @Test +public class TestToString extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toString/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("convertedZipCode", StringExpressions.toString("$zipcode")), - sort() - .ascending("convertedZipCode"))); + testPipeline((aggregation) -> aggregation.pipeline( + addFields().field("convertedZipCode", StringExpressions.toString("$zipcode")), + sort().ascending("convertedZipCode"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToUUID.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToUUID.java new file mode 100644 index 00000000000..6df648bccf0 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToUUID.java @@ -0,0 +1,22 @@ +package dev.morphia.test.aggregation.expressions; + +import dev.morphia.test.ServerVersion; +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.aggregation.expressions.TypeExpressions.toUuid; +import static dev.morphia.aggregation.stages.Projection.project; + +public class TestToUUID extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/aggregation/expressions/toUUID/example1 + */ + @Test(testName = "main") + public void testExample1() { + checkMinServerVersion(ServerVersion.v80); + testPipeline(aggregation -> aggregation + .pipeline(project().include("name").include("price").include("UUID", toUuid("$UUID")))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToUpper.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToUpper.java index 5cba2b8b36b..88413be5b1f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToUpper.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToUpper.java @@ -1,20 +1,21 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.toUpper; import static dev.morphia.aggregation.stages.Projection.project; -public class TestToUpper extends AggregationTest { - @Test +public class TestToUpper extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/toUpper/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("item", toUpper("$item")) - .include("description", toUpper("$description")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("item", toUpper("$item")).include("description", toUpper("$description")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTop.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTop.java index 33b00389803..e46eac999f0 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTop.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTop.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -13,24 +14,27 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.test.ServerVersion.v52; -public class TestTop extends AggregationTest { - @Test +public class TestTop extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/top/example1 + * + */ + @Test(testName = "Find the Top ``Score``") public void testExample1() { - testPipeline(v52, false, false, (aggregation) -> aggregation - .pipeline(match(eq("gameId", "G1")), - group(id("$gameId")) - .field("playerId", top( - array("$playerId", "$score"), - descending("score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(match(eq("gameId", "G1")), group(id("$gameId")).field("playerId", + top(array("$playerId", "$score"), descending("score"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/top/example2 + * + */ + @Test(testName = "Find the Top ``Score`` Across Multiple Games") public void testExample2() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - group(id("$gameId")) - .field("playerId", top( - array("$playerId", "$score"), - descending("score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id("$gameId")).field("playerId", + top(array("$playerId", "$score"), descending("score"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTopN.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTopN.java index cfc7c3653fe..1459d175366 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTopN.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTopN.java @@ -1,7 +1,8 @@ package dev.morphia.test.aggregation.expressions; import dev.morphia.aggregation.expressions.ComparisonExpressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -17,40 +18,36 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.test.ServerVersion.v52; -public class TestTopN extends AggregationTest { - @Test +public class TestTopN extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/topN/example1 + * + */ + @Test(testName = "Find the Three Highest ``Scores``") public void testExample1() { - testPipeline(v52, false, false, (aggregation) -> aggregation.pipeline( - match(eq("gameId", "G1")), - group(id("$gameId")) - .field("playerId", topN(3, array("$playerId", "$score"), - descending("score"))))); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.pipeline(match(eq("gameId", "G1")), group(id("$gameId")).field("playerId", + topN(3, array("$playerId", "$score"), descending("score"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/topN/example2 + * + */ + @Test(testName = "Finding the Three Highest Score Documents Across Multiple Games") public void testExample2() { - testPipeline(v52, false, false, (aggregation) -> { - return aggregation - .group(group(id("$gameId")) - .field("playerId", topN( - 3, - array("$playerId", "$score"), - descending("score")))); - }); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), (aggregation) -> aggregation.group( + group(id("$gameId")).field("playerId", topN(3, array("$playerId", "$score"), descending("score"))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/topN/example3 + * + */ + @Test(testName = "Computing ``n`` Based on the Group Key for ``$group``") public void testExample3() { - testPipeline(v52, false, false, (aggregation) -> { - return aggregation - .group(group(id(document("gameId", "$gameId"))) - .field("gamescores", topN( - condition( - ComparisonExpressions.eq("$gameId", "G2"), - 1, - 3), - "$score", - descending("score")))); - }); + testPipeline(new ActionTestOptions().serverVersion(v52).orderMatters(false), + (aggregation) -> aggregation.group(group(id(document("gameId", "$gameId"))).field("gamescores", topN( + condition(ComparisonExpressions.eq("$gameId", "G2"), 1, 3), "$score", descending("score"))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrim.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrim.java index ba0b08dda35..5b6dc604f81 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrim.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrim.java @@ -1,20 +1,22 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.StringExpressions.trim; import static dev.morphia.aggregation.stages.Projection.project; -public class TestTrim extends AggregationTest { - @Test +public class TestTrim extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/trim/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .include("item") - .include("description", trim("$description")))); + testPipeline(new ActionTestOptions().orderMatters(false), (aggregation) -> aggregation + .pipeline(project().include("item").include("description", trim("$description")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrunc.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrunc.java index e4a0a2bc470..c9891b2cdf1 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrunc.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrunc.java @@ -1,19 +1,20 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.MathExpressions.trunc; import static dev.morphia.aggregation.stages.Projection.project; -public class TestTrunc extends AggregationTest { - @Test +public class TestTrunc extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/trunc/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("truncatedValue", trunc("$value", 1)))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("truncatedValue", trunc("$value", 1)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsIncrement.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsIncrement.java index 16aef7c52e9..f9ba98e9458 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsIncrement.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsIncrement.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -8,13 +9,13 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.v51; -public class TestTsIncrement extends AggregationTest { - @Test +public class TestTsIncrement extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/tsIncrement/example1 + */ + @Test(testName = "Obtain the Incrementing Ordinal from a Timestamp Field") public void testExample1() { - testPipeline(v51, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("saleTimestamp") - .include("saleIncrement", tsIncrement("$saleTimestamp")))); + testPipeline(new ActionTestOptions().serverVersion(v51), (aggregation) -> aggregation.pipeline(project() + .suppressId().include("saleTimestamp").include("saleIncrement", tsIncrement("$saleTimestamp")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsSecond.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsSecond.java index 1694eba3ec3..2e2b2cc9771 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsSecond.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsSecond.java @@ -1,6 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -8,13 +9,14 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.test.ServerVersion.v51; -public class TestTsSecond extends AggregationTest { - @Test +public class TestTsSecond extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/tsSecond/example1 + * + */ + @Test(testName = "Obtain the Number of Seconds from a Timestamp Field") public void testExample1() { - testPipeline(v51, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("saleTimestamp") - .include("saleSeconds", tsSecond("$saleTimestamp")))); + testPipeline(new ActionTestOptions().serverVersion(v51), (aggregation) -> aggregation.pipeline( + project().suppressId().include("saleTimestamp").include("saleSeconds", tsSecond("$saleTimestamp")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestType.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestType.java index 0ee33939ca6..464e98777e2 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestType.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestType.java @@ -1,19 +1,22 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.TypeExpressions.type; import static dev.morphia.aggregation.stages.Projection.project; -public class TestType extends AggregationTest { - @Test +public class TestType extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/type/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - project() - .include("a", type("$a")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(project().include("a", type("$a")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestUnsetField.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestUnsetField.java index 487af13cc25..8639c43427b 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestUnsetField.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestUnsetField.java @@ -1,8 +1,7 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.DriverVersion; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -12,32 +11,37 @@ import static dev.morphia.aggregation.expressions.Miscellaneous.unsetField; import static dev.morphia.aggregation.expressions.SystemVariables.*; import static dev.morphia.aggregation.stages.ReplaceWith.replaceWith; +import static dev.morphia.test.DriverVersion.v43; -public class TestUnsetField extends AggregationTest { - @Test +public class TestUnsetField extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/unsetField/example1 + * + */ + @Test(testName = "Remove Fields that Contain Periods (``.``)") public void testExample1() { - checkMinDriverVersion(DriverVersion.v43); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceWith(unsetField("price.usd", ROOT)))); + checkMinDriverVersion(v43); + testPipeline((aggregation) -> aggregation.pipeline(replaceWith(unsetField("price.usd", ROOT)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/unsetField/example2 + * + */ + @Test(testName = "Remove Fields that Start with a Dollar Sign (``$``)") public void testExample2() { - minDriver = DriverVersion.v43; - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceWith(unsetField(literal("$price"), ROOT)))); + testPipeline(new ActionTestOptions().minDriver(v43), + (aggregation) -> aggregation.pipeline(replaceWith(unsetField(literal("$price"), ROOT)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/unsetField/example3 + * + */ + @Test(testName = "Remove A Subfield") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceWith( - setField( - "price", - ROOT, - unsetField( - "euro", - getField("price")))))); + testPipeline((aggregation) -> aggregation + .pipeline(replaceWith(setField("price", ROOT, unsetField("euro", getField("price")))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestWeek.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestWeek.java index 6f53331eb19..248b5db6274 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestWeek.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestWeek.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestWeek extends AggregationTest { - @Test +public class TestWeek extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/week/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestYear.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestYear.java index e1ec1289d48..681ab72f014 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestYear.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestYear.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,21 +16,18 @@ import static dev.morphia.aggregation.expressions.DateExpressions.year; import static dev.morphia.aggregation.stages.Projection.project; -public class TestYear extends AggregationTest { - @Test +public class TestYear extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/year/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("year", year("$date")) - .include("month", month("$date")) - .include("day", dayOfMonth("$date")) - .include("hour", hour("$date")) - .include("minutes", minute("$date")) - .include("seconds", second("$date")) - .include("milliseconds", milliseconds("$date")) - .include("dayOfYear", dayOfYear("$date")) - .include("dayOfWeek", dayOfWeek("$date")) - .include("week", week("$date")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("year", year("$date")) + .include("month", month("$date")).include("day", dayOfMonth("$date")).include("hour", hour("$date")) + .include("minutes", minute("$date")).include("seconds", second("$date")) + .include("milliseconds", milliseconds("$date")).include("dayOfYear", dayOfYear("$date")) + .include("dayOfWeek", dayOfWeek("$date")).include("week", week("$date")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestZip.java b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestZip.java index c523bce711e..d33caa38293 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/expressions/TestZip.java +++ b/core/src/test/java/dev/morphia/test/aggregation/expressions/TestZip.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.expressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -14,30 +13,28 @@ import static dev.morphia.aggregation.expressions.VariableExpressions.let; import static dev.morphia.aggregation.stages.Projection.project; -public class TestZip extends AggregationTest { - @Test +public class TestZip extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/expressions/zip/example1 + * + */ + @Test(testName = "Matrix Transposition") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("transposed", zip( - elementAt("$matrix", 0), - elementAt("$matrix", 1), - elementAt("$matrix", 2))))); + testPipeline((aggregation) -> aggregation.pipeline(project().suppressId().include("transposed", + zip(elementAt("$matrix", 0), elementAt("$matrix", 1), elementAt("$matrix", 2))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/expressions/zip/example2 + * + */ + @Test(testName = "Filtering and Preserving Indexes") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> { - return aggregation.pipeline( - project() - .suppressId() - .include("pages", filter( - zip("$pages", range(0, size("$pages"))), - let(gte("$$page.reviews", 1)) - .variable("page", - elementAt("$$pageWithIndex", 0))) - .as("pageWithIndex"))); + testPipeline((aggregation) -> { + return aggregation.pipeline(project().suppressId().include("pages", + filter(zip("$pages", range(0, size("$pages"))), + let(gte("$$page.reviews", 1)).variable("page", elementAt("$$pageWithIndex", 0))) + .as("pageWithIndex"))); }); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestAddFields.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestAddFields.java index 86b09270111..f3ed1393864 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestAddFields.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestAddFields.java @@ -2,9 +2,9 @@ import java.util.List; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import dev.morphia.test.aggregation.model.Score; +import dev.morphia.test.util.ActionTestOptions; import org.bson.Document; import org.testng.annotations.Test; @@ -19,8 +19,12 @@ import static org.bson.Document.parse; import static org.testng.Assert.assertEquals; -public class TestAddFields extends AggregationTest { - @Test +public class TestAddFields extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/addFields/example1 + * + */ + @Test(testName = "Using Two ``$addFields`` Stages") public void testExample1() { List list = List.of( parse("{ _id: 1, student: 'Maya', homework: [ 10, 5, 10 ],quiz: [ 10, 8 ],extraCredit: 0 }"), @@ -29,17 +33,12 @@ public void testExample1() { insert("scores", list); List result = getDs().aggregate(Score.class) - .addFields(addFields() - .field("totalHomework", sum("$homework")) - .field("totalQuiz", sum("$quiz"))) - .addFields(addFields() - .field("totalScore", add("$totalHomework", - "$totalQuiz", "$extraCredit"))) - .execute(Document.class) - .toList(); + .addFields(addFields().field("totalHomework", sum("$homework")).field("totalQuiz", sum("$quiz"))) + .addFields(addFields().field("totalScore", add("$totalHomework", "$totalQuiz", "$extraCredit"))) + .execute(Document.class).toList(); - list = List.of( - parse("{ '_id' : 1, 'student' : 'Maya', 'homework' : [ 10, 5, 10 ],'quiz' : [ 10, 8 ],'extraCredit' : 0, 'totalHomework' : 25," + list = List.of(parse( + "{ '_id' : 1, 'student' : 'Maya', 'homework' : [ 10, 5, 10 ],'quiz' : [ 10, 8 ],'extraCredit' : 0, 'totalHomework' : 25," + " 'totalQuiz' : 18, 'totalScore' : 43 }"), parse("{ '_id' : 2, 'student' : 'Ryan', 'homework' : [ 5, 6, 5 ],'quiz' : [ 8, 8 ],'extraCredit' : 8, 'totalHomework' : 16, " + "'totalQuiz' : 16, 'totalScore' : 40 }")); @@ -47,26 +46,33 @@ public void testExample1() { assertEquals(result, list); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/addFields/example2 + * + */ + @Test(testName = "Adding Fields to an Embedded Document") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - addFields() - .field("specs.fuel_type", "unleaded"))); + testPipeline((aggregation) -> aggregation.pipeline(addFields().field("specs.fuel_type", "unleaded"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/addFields/example3 + * + */ + @Test(testName = "Overwriting an existing field") public void testExample3() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - addFields() - .field("cats", 20))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(addFields().field("cats", 20))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/addFields/example4 + * + */ + @Test(testName = "Add Element to an Array") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(eq("_id", 1)), - addFields() - .field("homework", concatArrays("$homework", array(7))))); + testPipeline((aggregation) -> aggregation.pipeline(match(eq("_id", 1)), + addFields().field("homework", concatArrays("$homework", array(7))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucket.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucket.java index 9bf92bebd7f..af153154cda 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucket.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucket.java @@ -6,9 +6,10 @@ import dev.morphia.annotations.Entity; import dev.morphia.annotations.Id; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import dev.morphia.test.aggregation.model.Artwork; import dev.morphia.test.aggregation.model.Book; +import dev.morphia.test.util.ActionTestOptions; import org.bson.Document; import org.testng.Assert; @@ -27,48 +28,44 @@ import static org.bson.Document.parse; import static org.testng.Assert.assertEquals; -public class TestBucket extends AggregationTest { - @Test +public class TestBucket extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/bucket/example1 + * + */ + @Test(testName = "Bucket by Year and Filter by Bucket Results") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - bucket() - .groupBy("$year_born") - .boundaries(1840, 1850, 1860, 1870, 1880) - .defaultValue("Other") - .outputField("count", sum(1)) - .outputField("artists", push() - .field("name", concat("$first_name", " ", "$last_name")) - .field("year_born", "$year_born")), + testPipeline((aggregation) -> aggregation.pipeline(bucket() + .groupBy("$year_born").boundaries(1840, 1850, 1860, 1870, 1880).defaultValue("Other") + .outputField("count", sum(1)).outputField("artists", push() + .field("name", concat("$first_name", " ", "$last_name")).field("year_born", "$year_born")), match(gt("count", 3)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/bucket/example2 + * + */ + @Test(testName = "Use $bucket with $facet to Bucket by Multiple Fields") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - facet() - .field("price", bucket() - .groupBy("$price") - .boundaries(0, 200, 400) - .defaultValue("Other") - .outputField("count", sum(1)) - .outputField("artwork", push() - .field("title", "$title") - .field("price", "$price")) - .outputField("averagePrice", avg("$price"))) - .field("year", bucket() - .groupBy("$year") - .boundaries(1890, 1910, 1920, 1940) - .defaultValue("Unknown") - .outputField("count", sum(1)) - .outputField("artwork", push() - .field("title", "$title") - .field("year", "$year"))))); + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.ANY), + (aggregation) -> aggregation.pipeline(facet() + .field("price", + bucket().groupBy("$price").boundaries(0, 200, 400).defaultValue("Other") + .outputField("count", sum(1)) + .outputField("artwork", + push().field("title", "$title").field("price", "$price")) + .outputField("averagePrice", avg("$price"))) + .field("year", + bucket().groupBy("$year").boundaries(1890, 1910, 1920, 1940).defaultValue("Unknown") + .outputField("count", sum(1)).outputField("artwork", + push().field("title", "$title").field("year", "$year"))))); } @Test public void testBucket() { - List list = List.of( - parse("{'_id': 1, 'title': 'The Pillars of Society', 'artist': 'Grosz', 'year': 1926, 'price': NumberDecimal('199.99') }"), + List list = List.of(parse( + "{'_id': 1, 'title': 'The Pillars of Society', 'artist': 'Grosz', 'year': 1926, 'price': NumberDecimal('199.99') }"), parse("{'_id': 2, 'title': 'Melancholy III', 'artist': 'Munch', 'year': 1902, 'price': NumberDecimal('280.00') }"), parse("{'_id': 3, 'title': 'Dancer', 'artist': 'Miro', 'year': 1925, 'price': NumberDecimal('76.04') }"), parse("{'_id': 4, 'title': 'The Great Wave off Kanagawa', 'artist': 'Hokusai', 'price': NumberDecimal('167.30') }"), @@ -80,17 +77,12 @@ public void testBucket() { insert("artwork", list); List results = getDs().aggregate(Artwork.class) - .bucket(bucket() - .groupBy("$price") - .boundaries(0, 200, 400) - .defaultValue("Other") - .outputField("count", sum(1)) - .outputField("titles", push().single("$title"))) - .execute(Document.class) - .toList(); - - List documents = List.of( - parse("{'_id': 0, 'count': 4, 'titles': ['The Pillars of Society', 'Dancer', 'The Great Wave off Kanagawa', 'Blue Flower']}"), + .bucket(bucket().groupBy("$price").boundaries(0, 200, 400).defaultValue("Other") + .outputField("count", sum(1)).outputField("titles", push().single("$title"))) + .execute(Document.class).toList(); + + List documents = List.of(parse( + "{'_id': 0, 'count': 4, 'titles': ['The Pillars of Society', 'Dancer', 'The Great Wave off Kanagawa', 'Blue Flower']}"), parse("{'_id': 200, 'count': 2, 'titles': ['Melancholy III', 'Composition VII']}"), parse("{'_id': 'Other', 'count': 2, 'titles': ['The Persistence of Memory', 'The Scream']}")); assertEquals(results, documents); @@ -100,19 +92,13 @@ public void testBucket() { public void testBucketWithBoundariesWithSizeLessThanTwo() { homer(); - getDs().aggregate(Book.class) - .bucket(bucket() - .groupBy("$copies") - .boundaries(10) - .outputField("count", sum(1))) + getDs().aggregate(Book.class).bucket(bucket().groupBy("$copies").boundaries(10).outputField("count", sum(1))) .execute(BucketResult.class); } private void homer() { - getDs().save(asList(new Book("The Banquet", "Dante", 2), - new Book("Divine Comedy", "Dante", 1), - new Book("Eclogues", "Dante", 2), - new Book("The Odyssey", "Homer", 10), + getDs().save(asList(new Book("The Banquet", "Dante", 2), new Book("Divine Comedy", "Dante", 1), + new Book("Eclogues", "Dante", 2), new Book("The Odyssey", "Homer", 10), new Book("Iliad", "Homer", 10))); } @@ -121,11 +107,7 @@ public void testBucketWithOptions() { homer(); Iterator aggregate = getDs().aggregate(Book.class) - .bucket(bucket() - .groupBy("$copies") - .boundaries(1, 5, 10) - .defaultValue(-1) - .outputField("count", sum(1))) + .bucket(bucket().groupBy("$copies").boundaries(1, 5, 10).defaultValue(-1).outputField("count", sum(1))) .execute(BucketResult.class); BucketResult result2 = aggregate.next(); @@ -142,12 +124,8 @@ public void testBucketWithOptions() { public void testBucketWithUnsortedBoundaries() { homer(); - Iterator aggregate = getDs().aggregate(Book.class) - .bucket(bucket() - .groupBy("$copies") - .boundaries(5, 1, 10) - .defaultValue("test") - .outputField("count", sum(1))) + Iterator aggregate = getDs().aggregate(Book.class).bucket( + bucket().groupBy("$copies").boundaries(5, 1, 10).defaultValue("test").outputField("count", sum(1))) .execute(BucketResult.class); } @@ -156,10 +134,7 @@ public void testBucketWithoutOptions() { homer(); Iterator aggregate = getDs().aggregate(Book.class) - .bucket(bucket() - .groupBy("$copies") - .boundaries(1, 5, 12)) - .execute(BucketResult.class); + .bucket(bucket().groupBy("$copies").boundaries(1, 5, 12)).execute(BucketResult.class); BucketResult result1 = aggregate.next(); Assert.assertEquals(result1.getId(), 1); Assert.assertEquals(result1.getCount(), 3); @@ -194,11 +169,7 @@ public void setId(Integer id) { @Override public String toString() { - return "BucketResult{" - + "id=" - + id - + ", count=" + count - + '}'; + return "BucketResult{" + "id=" + id + ", count=" + count + '}'; } } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucketAuto.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucketAuto.java index ffd44d91941..88fb9c927c6 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucketAuto.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucketAuto.java @@ -4,8 +4,7 @@ import com.mongodb.client.model.BucketGranularity; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import dev.morphia.test.aggregation.model.Book; import dev.morphia.test.aggregation.model.BooksBucketResult; import dev.morphia.test.aggregation.model.BucketAutoResult; @@ -22,70 +21,50 @@ import static java.util.Arrays.asList; import static java.util.Collections.singleton; -public class TestBucketAuto extends AggregationTest { - @Test +public class TestBucketAuto extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/bucketAuto/example1 + * + */ + @Test(testName = "Single Facet Aggregation") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - autoBucket() - .groupBy("$price") - .buckets(4))); + testPipeline((aggregation) -> aggregation.pipeline(autoBucket().groupBy("$price").buckets(4))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/bucketAuto/example2 + * + */ + @Test(testName = "Multi-Faceted Aggregation") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - facet() - .field("price", autoBucket() - .groupBy("$price") - .buckets(4)) - .field("year", autoBucket() - .groupBy("$year") - .buckets(3) - .outputField("count", sum(1)) - .outputField("years", push("$year"))) - .field("area", autoBucket() - .groupBy(multiply("$dimensions.height", "$dimensions.width")) - .buckets(4) - .outputField("count", sum(1)) - .outputField("titles", push("$title"))))); + testPipeline( + (aggregation) -> aggregation.pipeline(facet().field("price", autoBucket().groupBy("$price").buckets(4)) + .field("year", + autoBucket().groupBy("$year").buckets(3).outputField("count", sum(1)) + .outputField("years", push("$year"))) + .field("area", autoBucket().groupBy(multiply("$dimensions.height", "$dimensions.width")) + .buckets(4).outputField("count", sum(1)).outputField("titles", push("$title"))))); } - @Test + @Test(testName = "Multi-Faceted Aggregation") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - facet() - .field("price", - autoBucket() - .groupBy("$price") - .buckets(4)) + testPipeline( + (aggregation) -> aggregation.pipeline(facet().field("price", autoBucket().groupBy("$price").buckets(4)) .field("year", - autoBucket() - .groupBy("$year") - .buckets(3) - .outputField("count", sum(1)) + autoBucket().groupBy("$year").buckets(3).outputField("count", sum(1)) .outputField("years", push("$year"))) - .field("area", - autoBucket() - .groupBy(multiply("$dimensions.height", "$dimensions.width")) - .buckets(4) - .outputField("count", sum(1)) - .outputField("titles", push("$title"))))); + .field("area", autoBucket().groupBy(multiply("$dimensions.height", "$dimensions.width")) + .buckets(4).outputField("count", sum(1)).outputField("titles", push("$title"))))); } @Test public void testWithGranularity() { - getDs().save(asList(new Book("The Banquet", "Dante", 5), - new Book("Divine Comedy", "Dante", 7), - new Book("Eclogues", "Dante", 40), - new Book("The Odyssey", "Homer", 21))); + getDs().save(asList(new Book("The Banquet", "Dante", 5), new Book("Divine Comedy", "Dante", 7), + new Book("Eclogues", "Dante", 40), new Book("The Odyssey", "Homer", 21))); Iterator aggregate = getDs().aggregate(Book.class) - .autoBucket(autoBucket() - .groupBy("$copies") - .buckets(3) - .granularity(BucketGranularity.POWERSOF2) - .outputField("authors", addToSet("$author")) - .outputField("count", sum(1))) + .autoBucket(autoBucket().groupBy("$copies").buckets(3).granularity(BucketGranularity.POWERSOF2) + .outputField("authors", addToSet("$author")).outputField("count", sum(1))) .execute(BooksBucketResult.class); BooksBucketResult result1 = aggregate.next(); Assert.assertEquals(result1.getId().getMin(), 4); @@ -110,17 +89,11 @@ public void testWithGranularity() { @Test public void testWithoutGranularity() { - getDs().save(asList( - new Book("The Banquet", "Dante", 5), - new Book("Divine Comedy", "Dante", 10), - new Book("Eclogues", "Dante", 40), - new Book("The Odyssey", "Homer", 21))); + getDs().save(asList(new Book("The Banquet", "Dante", 5), new Book("Divine Comedy", "Dante", 10), + new Book("Eclogues", "Dante", 40), new Book("The Odyssey", "Homer", 21))); Iterator aggregate = getDs().aggregate(Book.class) - .autoBucket(autoBucket() - .groupBy("$copies") - .buckets(2)) - .execute(BucketAutoResult.class); + .autoBucket(autoBucket().groupBy("$copies").buckets(2)).execute(BucketAutoResult.class); BucketAutoResult result1 = aggregate.next(); Assert.assertEquals(result1.getId().getMin(), 5); Assert.assertEquals(result1.getId().getMax(), 21); diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestChangeStream.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestChangeStream.java index 5734dcbbe2e..62cbb9ccfe0 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestChangeStream.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestChangeStream.java @@ -11,7 +11,7 @@ import dev.morphia.aggregation.stages.ChangeStream; import dev.morphia.mapping.codec.writer.DocumentWriter; import dev.morphia.query.MorphiaCursor; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.bson.Document; import org.bson.codecs.Codec; @@ -25,7 +25,7 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; -public class TestChangeStream extends AggregationTest { +public class TestChangeStream extends TemplatedTestBase { @Test @SuppressWarnings("unchecked") public void testChangeStream() { @@ -33,9 +33,9 @@ public void testChangeStream() { checkForReplicaSet(); Iterator input = loadJson(format("%s/%s/data.json", prefix(), "changeStream"), "data", true).iterator(); - MongoCollection collection = getDatabase().getCollection(AGG_TEST_COLLECTION); + MongoCollection collection = getDatabase().getCollection(EXAMPLE_TEST_COLLECTION); - try (MorphiaCursor cursor = getDs().aggregate(AGG_TEST_COLLECTION) + try (MorphiaCursor cursor = getDs().aggregate(EXAMPLE_TEST_COLLECTION) .changeStream(changeStream()) .execute(Document.class)) { while (input.hasNext()) { diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestCount.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestCount.java index e9d673feb7c..a32ff09af55 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestCount.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestCount.java @@ -1,8 +1,7 @@ package dev.morphia.test.aggregation.stages; import dev.morphia.aggregation.stages.Count; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -10,11 +9,14 @@ import static dev.morphia.aggregation.stages.Match.match; import static dev.morphia.query.filters.Filters.gt; -public class TestCount extends AggregationTest { - @Test +public class TestCount extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/count/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(gt("score", 80)), Count.count("passing_scores"))); + testPipeline((aggregation) -> aggregation.pipeline(match(gt("score", 80)), Count.count("passing_scores"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestCurrentOp.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestCurrentOp.java index 8d79d724d85..f5cefca13d0 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestCurrentOp.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestCurrentOp.java @@ -1,35 +1,70 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.CurrentOp.currentOp; import static dev.morphia.aggregation.stages.Match.match; import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.exists; -public class TestCurrentOp extends AggregationTest { - public TestCurrentOp() { - skipDataCheck(); +public class TestCurrentOp extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/currentOp/example1 + */ + @Test(testName = "Inactive Sessions :: Replica Set") + public void testExample1() { + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(currentOp().allUsers(true).idleSessions(true), + match(eq("active", false), exists("transaction")))); + } + /** + * test data: dev/morphia/test/aggregation/stages/currentOp/example2 + */ + @Test(testName = "Inactive Sessions :: Sharded Cluster (localOps: true)") + public void testExample2() { + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(currentOp().allUsers(true).idleSessions(true), + match(eq("active", false), exists("transaction")))); } - @Test - public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - currentOp() - .allUsers(true) - .idleSessions(true), - match(eq("desc", "transaction coordinator")))); + /** + * test data: dev/morphia/test/aggregation/stages/currentOp/example3 + */ + @Test(testName = "Inactive Sessions :: Sharded Cluster") + public void testExample3() { + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(currentOp().allUsers(true).idleSessions(true), + match(eq("active", false), exists("transaction")))); } - @Test - public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - currentOp() - .allUsers(true) - .localOps(true), - match(eq("desc", "query analyzer")))); + /** + * test data: dev/morphia/test/aggregation/stages/currentOp/example4 + */ + @Test(testName = "Sampled Queries :: Replica Set") + public void testExample4() { + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation + .pipeline(currentOp().allUsers(true).localOps(true), match(eq("desc", "query analyzer")))); + } + + /** + * test data: dev/morphia/test/aggregation/stages/currentOp/example5 + */ + @Test(testName = "Sampled Queries :: Sharded Cluster: mongos") + public void testExample5() { + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation + .pipeline(currentOp().allUsers(true).localOps(true), match(eq("desc", "query analyzer")))); + } + + /** + * test data: dev/morphia/test/aggregation/stages/currentOp/example6 + */ + @Test(testName = "Sampled Queries :: Sharded Cluster: mongod --shardsvr") + public void testExample6() { + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation + .pipeline(currentOp().allUsers(true).localOps(true), match(eq("desc", "query analyzer")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestDensify.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestDensify.java index 30af7c3e0a3..cdb2b0481c3 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestDensify.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestDensify.java @@ -4,28 +4,40 @@ import dev.morphia.aggregation.stages.Densify.Range; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.TimeUnit.HOUR; import static dev.morphia.aggregation.stages.Densify.densify; -public class TestDensify extends AggregationTest { - @Test +public class TestDensify extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/densify/example1 + * + */ + @Test(testName = "Densify Time Series Data") public void testExample1() { - testPipeline(ServerVersion.v51, true, true, (aggregation) -> aggregation.pipeline( - densify("timestamp", - Range.bounded(ZonedDateTime.parse("2021-05-18T00:00:00.000Z"), - ZonedDateTime.parse("2021-05-18T08:00:00.000Z"), 1) - .unit(HOUR)))); + testPipeline( + new ActionTestOptions().serverVersion(ServerVersion.v51).removeIds(true), ( + aggregation) -> aggregation + .pipeline( + densify("timestamp", + Range.bounded(ZonedDateTime.parse("2021-05-18T00:00:00.000Z"), + ZonedDateTime.parse("2021-05-18T08:00:00.000Z"), 1) + .unit(HOUR)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/densify/example2 + * + */ + @Test(testName = "Densifiction with Partitions") public void testExample2() { - testPipeline(ServerVersion.v51, true, false, (aggregation) -> aggregation.pipeline( - densify("altitude", Range.full(200)) - .partitionByFields("variety"))); + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.v51).removeIds(true).orderMatters(false), + (aggregation) -> aggregation + .pipeline(densify("altitude", Range.full(200)).partitionByFields("variety"))); } } \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestDocuments.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestDocuments.java index 55f71cabf15..680aa48cf99 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestDocuments.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestDocuments.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -11,35 +11,30 @@ import static dev.morphia.aggregation.stages.Lookup.lookup; import static dev.morphia.test.ServerVersion.v51; -public class TestDocuments extends AggregationTest { - @Test +public class TestDocuments extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/documents/example1 + * + */ + @Test(testName = "Test a Pipeline Stage") public void testExample1() { - skipDataCheck(); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - documents( - document().field("x", 10), - document().field("x", 2), - document().field("x", 5)), - autoBucket() - .groupBy("$x") - .buckets(4))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline( + documents(document().field("x", 10), document().field("x", 2), document().field("x", 5)), + autoBucket().groupBy("$x").buckets(4))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/documents/example2 + * + */ + @Test(testName = "Use a ``$documents`` Stage in a ``$lookup`` Stage") public void testExample2() { - testPipeline(v51, aggregation -> { - return aggregation - .match() - .lookup(lookup() - .localField("zip") - .foreignField("zip_id") - .as("city_state") - .pipeline( - documents( - document("zip_id", 94301) - .field("name", "Palo Alto, CA"), - document("zip_id", 10019) - .field("name", "New York, NY")))); + testPipeline(new ActionTestOptions().serverVersion(v51).removeIds(true), aggregation -> { + return aggregation.match() + .lookup(lookup().localField("zip").foreignField("zip_id").as("city_state") + .pipeline(documents(document("zip_id", 94301).field("name", "Palo Alto, CA"), + document("zip_id", 10019).field("name", "New York, NY")))); }); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestFacet.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestFacet.java index 8a21782a720..30a28535779 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestFacet.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestFacet.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.stages; import dev.morphia.aggregation.stages.Match; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -15,24 +15,19 @@ import static dev.morphia.aggregation.stages.Unwind.unwind; import static dev.morphia.query.filters.Filters.exists; -public class TestFacet extends AggregationTest { - @Test +public class TestFacet extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/facet/example1 + * + */ + @Test(testName = "main") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - facet() - .field("categorizedByTags", - unwind("tags"), - sortByCount("$tags")) - .field("categorizedByPrice", - Match.match(exists("price")), - bucket() - .groupBy("$price") - .boundaries(0, 150, 200, 300, 400) - .defaultValue("Other") - .outputField("count", sum(1)) - .outputField("titles", push().single("$title"))) - .field("categorizedByYears(Auto)", autoBucket() - .groupBy("$year") - .buckets(4)))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(facet() + .field("categorizedByTags", unwind("tags"), sortByCount("$tags")) + .field("categorizedByPrice", Match.match(exists("price")), + bucket().groupBy("$price").boundaries(0, 150, 200, 300, 400).defaultValue("Other") + .outputField("count", sum(1)).outputField("titles", push().single("$title"))) + .field("categorizedByYears(Auto)", autoBucket().groupBy("$year").buckets(4)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestFill.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestFill.java index 0726da9e4db..a37202a481f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestFill.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestFill.java @@ -2,7 +2,8 @@ import dev.morphia.aggregation.expressions.StringExpressions; import dev.morphia.aggregation.stages.Fill.Method; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -15,55 +16,62 @@ import static dev.morphia.test.DriverVersion.v42; import static dev.morphia.test.ServerVersion.v53; -public class TestFill extends AggregationTest { - @Test +public class TestFill extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/fill/example1 + * + */ + @Test(testName = "Fill Missing Field Values with a Constant Value") public void testExample1() { - minDriver = v42; - testPipeline(v53, aggregation -> aggregation.pipeline( - fill() - .field("bootsSold", 0) - .field("sandalsSold", 0) - .field("sneakersSold", 0))); + testPipeline(new ActionTestOptions().serverVersion(v53).minDriver(v42).removeIds(true), + aggregation -> aggregation + .pipeline(fill().field("bootsSold", 0).field("sandalsSold", 0).field("sneakersSold", 0))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/fill/example2 + * + */ + @Test(testName = "Fill Missing Field Values with Linear Interpolation") public void testExample2() { - testPipeline(v53, aggregation -> aggregation.pipeline( - fill() - .sortBy(ascending("time")) - .field("price", Method.LINEAR))); + testPipeline(new ActionTestOptions().serverVersion(v53).removeIds(true), + aggregation -> aggregation.pipeline(fill().sortBy(ascending("time")).field("price", Method.LINEAR))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/fill/example3 + * + */ + @Test(testName = "Fill Missing Field Values Based on the Last Observed Value") public void testExample3() { - minDriver = v42; - - testPipeline(v53, aggregation -> aggregation.pipeline( - fill() - .sortBy(ascending("date")) - .field("score", Method.LOCF))); + testPipeline(new ActionTestOptions().serverVersion(v53).minDriver(v42).removeIds(true), + aggregation -> aggregation.pipeline(fill().sortBy(ascending("date")).field("score", Method.LOCF))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/fill/example4 + * + */ + @Test(testName = "Fill Data for Distinct Partitions") public void testExample4() { - minDriver = v42; - testPipeline(v53, aggregation -> aggregation.pipeline( - fill() - .sortBy(ascending("date")) - .partitionBy(document("restaurant", "$restaurant")) - .field("score", Method.LOCF))); + testPipeline(new ActionTestOptions().serverVersion(v53).minDriver(v42).removeIds(true), + aggregation -> aggregation.pipeline(fill().sortBy(ascending("date")) + .partitionBy(document("restaurant", "$restaurant")).field("score", Method.LOCF))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/fill/example5 + * + */ + @Test(testName = "Indicate if a Field was Populated Using ``$fill``") public void testExample5() { - testPipeline(v53, true, true, (aggregation) -> aggregation.pipeline( - set() - .field("valueExisted", ifNull() - .target(toBool(StringExpressions.toString("$score"))) - .replacement(false)), - fill() - .sortBy(ascending("date")) - .field("score", Method.LOCF))); + testPipeline(new ActionTestOptions().serverVersion(v53).removeIds(true), + (aggregation) -> aggregation + .pipeline( + set().field("valueExisted", + ifNull().target(toBool(StringExpressions.toString("$score"))) + .replacement(false)), + fill().sortBy(ascending("date")).field("score", Method.LOCF))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestGeoNear.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestGeoNear.java index a32b8dea04b..16857fb972a 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestGeoNear.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestGeoNear.java @@ -4,9 +4,9 @@ import com.mongodb.client.model.geojson.Position; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; -import org.bson.Document; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.GeoNear.geoNear; @@ -15,67 +15,59 @@ import static dev.morphia.aggregation.stages.Match.match; import static dev.morphia.query.filters.Filters.eq; -public class TestGeoNear extends AggregationTest { - @Test +public class TestGeoNear extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/geoNear/example1 + * + */ + @Test(testName = "Maximum Distance") public void testExample1() { - testPipeline(ServerVersion.ANY, true, false, (aggregation) -> aggregation.pipeline( - geoNear(new Point(new Position(-73.99279, 40.719296))) - .distanceField("dist.calculated") - .maxDistance(2) - .query(eq("category", "Parks")) - .includeLocs("dist.location") - .spherical(true))); + testPipeline(new ActionTestOptions().removeIds(true).orderMatters(false), + (aggregation) -> aggregation.pipeline(geoNear(new Point(new Position(-73.99279, 40.719296))) + .distanceField("dist.calculated").maxDistance(2).query(eq("category", "Parks")) + .includeLocs("dist.location").spherical(true))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/geoNear/example2 + * + */ + @Test(testName = "Minimum Distance") public void testExample2() { // this example isn't representable in morphia as is } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/geoNear/example3 + * + */ + @Test(testName = "$geoNear with the ``let`` option") public void testExample3() { - testPipeline(ServerVersion.v60, true, true, (aggregation) -> aggregation.pipeline( - lookup(AGG_TEST_COLLECTION) - .as("joinedField") - .let("pt", "$location") - .pipeline( - geoNear("$$pt") - .distanceField("distance")), - match(eq("name", "Sara D. Roosevelt Park")))); + // let doesn't apply to morphia } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/geoNear/example4 + * + */ + @Test(testName = "$geoNear with Bound ``let`` Option") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - geoNear(new Point(new Position(-73.98142, 40.71782))) - .distanceField("dist.calculated") - .key("location") - .query(eq("category", "Parks")), - limit(5))); + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.v60).removeIds(true).orderMatters(false), + (aggregation) -> aggregation.pipeline( + lookup(EXAMPLE_TEST_COLLECTION).as("joinedField").let("pt", "$location") + .pipeline(geoNear("$$pt").distanceField("distance")), + match(eq("name", "Sara D. Roosevelt Park")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/geoNear/example3 + * + */ + @Test(testName = "Specify Which Geospatial Index to Use") public void testExample5() { - skipDataCheck(); - getDatabase().getCollection(AGG_TEST_COLLECTION).createIndex(new Document("location", "2dsphere")); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - lookup(AGG_TEST_COLLECTION) - .as("joinedField") - .let("pt", "$location") - .pipeline( - geoNear(new Point(new Position(-73.98142, 40.71782))) - .distanceField("distance")), - match(eq("name", "Sara D. Roosevelt Park")))); - } - - @Test - public void testExample6() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - geoNear(new Point(new Position(-73.98142, 40.71782))) - .distanceField("dist.calculated") - .key("location") - .query(eq("category", "Parks")), - limit(5))); + testPipeline(new ActionTestOptions().removeIds(true).orderMatters(false).skipDataCheck(true), + (aggregation) -> aggregation.pipeline(geoNear(new Point(new Position(-73.98142, 40.71782))) + .distanceField("dist.calculated").key("location").query(eq("category", "Parks")), limit(5))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestGraphLookup.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestGraphLookup.java index 9837639fea6..ed95df0584f 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestGraphLookup.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestGraphLookup.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -10,45 +10,43 @@ import static dev.morphia.aggregation.stages.Projection.project; import static dev.morphia.query.filters.Filters.eq; -public class TestGraphLookup extends AggregationTest { - @Test +public class TestGraphLookup extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/graphLookup/example1 + * + */ + @Test(testName = "Within a Single Collection") public void testExample1() { - testPipeline(ServerVersion.ANY, true, false, (aggregation) -> aggregation.pipeline( - graphLookup(AGG_TEST_COLLECTION) - .startWith("$reportsTo") - .connectFromField("reportsTo") - .connectToField("name") - .as("reportingHierarchy"))); + testPipeline(new ActionTestOptions().removeIds(true).orderMatters(false), + (aggregation) -> aggregation.pipeline(graphLookup(EXAMPLE_TEST_COLLECTION).startWith("$reportsTo") + .connectFromField("reportsTo").connectToField("name").as("reportingHierarchy"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/graphLookup/example2 + * + */ + @Test(testName = "Across Multiple Collections") public void testExample2() { loadData("airports", 2); - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - graphLookup("airports") - .startWith("$nearestAirport") - .connectFromField("connects") - .connectToField("airport") - .maxDepth(2) - .depthField("numConnections") + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(graphLookup("airports").startWith("$nearestAirport") + .connectFromField("connects").connectToField("airport").maxDepth(2).depthField("numConnections") .as("destinations"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/graphLookup/example3 + * + */ + @Test(testName = "With a Query Filter") public void testExample3() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( + testPipeline(new ActionTestOptions().orderMatters(false), (aggregation) -> aggregation.pipeline( match(eq("name", "Tanya Jordan")), - graphLookup(AGG_TEST_COLLECTION) - .startWith("$friends") - .connectFromField("friends") - .connectToField("name") - .as("golfers") - .restrict(eq("hobbies", "golf")), - project() - .include("name") - .include("friends") - .include("connections who play golf", "$golfers.name") + graphLookup(EXAMPLE_TEST_COLLECTION).startWith("$friends").connectFromField("friends") + .connectToField("name").as("golfers").restrict(eq("hobbies", "golf")), + project().include("name").include("friends").include("connections who play golf", "$golfers.name") )); } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestGroup.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestGroup.java index 9d41aa5c41b..a44f157cd83 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestGroup.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestGroup.java @@ -4,8 +4,8 @@ import java.time.Month; import dev.morphia.aggregation.expressions.AccumulatorExpressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -21,49 +21,62 @@ import static dev.morphia.query.filters.Filters.gte; import static dev.morphia.query.filters.Filters.lt; -public class TestGroup extends AggregationTest { - @Test +public class TestGroup extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/group/example1 + * + */ + @Test(testName = "Count the Number of Documents in a Collection") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - group(id(null)) - .field("count", AccumulatorExpressions.count()))); + testPipeline( + (aggregation) -> aggregation.pipeline(group(id(null)).field("count", AccumulatorExpressions.count()))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/group/example2 + * + */ + @Test(testName = "Retrieve Distinct Values") public void testExample2() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - group(id("$item")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id("$item")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/group/example3 + * + */ + @Test(testName = "Group by Item Having") public void testExample3() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - group(id("$item")) - .field("totalSaleAmount", sum(multiply("$price", "$quantity"))), - match(gte("totalSaleAmount", 100)))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline( + group(id("$item")).field("totalSaleAmount", sum(multiply("$price", "$quantity"))), + match(gte("totalSaleAmount", 100)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/group/example4 + * + */ + @Test(testName = "Calculate Count, Sum, and Average") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match( - gte("date", LocalDate.of(2014, Month.JANUARY, 1)), + testPipeline((aggregation) -> aggregation.pipeline( + match(gte("date", LocalDate.of(2014, Month.JANUARY, 1)), lt("date", LocalDate.of(2015, Month.JANUARY, 1))), - group(id(dateToString() - .date("$date") - .format("%Y-%m-%d"))) + group(id(dateToString().date("$date").format("%Y-%m-%d"))) .field("totalSaleAmount", sum(multiply("$price", "$quantity"))) - .field("averageQuantity", avg("$quantity")) - .field("count", sum(1)), - sort() - .descending("totalSaleAmount"))); + .field("averageQuantity", avg("$quantity")).field("count", sum(1)), + sort().descending("totalSaleAmount"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/group/example5 + * + */ + @Test(testName = "Pivot Data") public void testExample5() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - group(id("$author")) - .field("books", push("$title")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(group(id("$author")).field("books", push("$title")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestIndexStats.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestIndexStats.java index 1a327161065..cc430567c2a 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestIndexStats.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestIndexStats.java @@ -1,17 +1,19 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.IndexStats.indexStats; -public class TestIndexStats extends AggregationTest { - @Test +public class TestIndexStats extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/indexStats/example1 + * + */ + @Test(testName = "main") public void testExample1() { - skipDataCheck(); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - indexStats())); + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation.pipeline(indexStats())); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestLimit.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestLimit.java index d8940e7de21..4a2c0ebf7c3 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestLimit.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestLimit.java @@ -1,18 +1,20 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.Limit.limit; -public class TestLimit extends AggregationTest { +public class TestLimit extends TemplatedTestBase { - @Test + /** + * test data: dev/morphia/test/aggregation/stages/limit/example1 + * + */ + @Test(testName = "main") public void testExample1() { - skipDataCheck(); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - limit(5))); + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation.pipeline(limit(5))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestLookup.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestLookup.java index cddf945aa47..101cecff2c1 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestLookup.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestLookup.java @@ -4,9 +4,10 @@ import dev.morphia.aggregation.expressions.ComparisonExpressions; import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import dev.morphia.test.aggregation.model.Inventory; import dev.morphia.test.aggregation.model.Order; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -27,109 +28,97 @@ import static java.util.Arrays.asList; import static org.testng.Assert.assertEquals; -public class TestLookup extends AggregationTest { - @Test +public class TestLookup extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/lookup/example1 + * + */ + @Test(testName = "Perform a Single Equality Join with ``$lookup``") public void testExample1() { loadData("inventory", 2); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - lookup("inventory") - .localField("item") - .foreignField("sku") - .as("inventory_docs"))); + testPipeline((aggregation) -> aggregation + .pipeline(lookup("inventory").localField("item").foreignField("sku").as("inventory_docs"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/lookup/example2 + * + */ + @Test(testName = "Use ``$lookup`` with an Array") public void testExample2() { loadData("members", 2); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - lookup("members") - .localField("enrollmentlist") - .foreignField("name") - .as("enrollee_info"))); + testPipeline((aggregation) -> aggregation + .pipeline(lookup("members").localField("enrollmentlist").foreignField("name").as("enrollee_info"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/lookup/example3 + * + */ + @Test(testName = "Use ``$lookup`` with ``$mergeObjects``") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - lookup("items") - .localField("item") - .foreignField("item") - .as("fromItems"), - replaceRoot(mergeObjects() - .add(elementAt("$fromItems", 0)) - .add(ROOT)), - project() - .exclude("fromItems"))); + testPipeline((aggregation) -> aggregation.pipeline( + lookup("items").localField("item").foreignField("item").as("fromItems"), + replaceRoot(mergeObjects().add(elementAt("$fromItems", 0)).add(ROOT)), project().exclude("fromItems"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/lookup/example4 + * + */ + @Test(testName = "Perform Multiple Joins and a Correlated Subquery with ``$lookup``") public void testExample4() { loadData("warehouses", 2); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - lookup("warehouses") - .pipeline( - match(expr( - and( - ComparisonExpressions.eq("$stock_item", "$$order_item"), + testPipeline(new ActionTestOptions().serverVersion(ServerVersion.ANY), + (aggregation) -> aggregation + .pipeline(lookup("warehouses") + .pipeline( + match(expr(and(ComparisonExpressions.eq("$stock_item", "$$order_item"), gte("$instock", "$$order_qty")))), - project() - .suppressId() - .exclude("stock_item")) - .as("stockdata") - .let("order_item", "$item") - .let("order_qty", "$ordered"))); + project().suppressId().exclude("stock_item")) + .as("stockdata").let("order_item", "$item").let("order_qty", "$ordered"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/lookup/example5 + * + */ + @Test(testName = "Perform an Uncorrelated Subquery with ``$lookup``") public void testExample5() { loadData("holidays", 2); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - lookup("holidays") - .pipeline( - match(eq("year", 2018)), - project() - .suppressId() - .include("date", document() - .field("name", "$name") - .field("date", "$date")), - replaceRoot("$date")) - .as("holidays"))); + testPipeline((aggregation) -> aggregation.pipeline(lookup("holidays") + .pipeline(match(eq("year", 2018)), + project().suppressId().include("date", + document().field("name", "$name").field("date", "$date")), + replaceRoot("$date")) + .as("holidays"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/lookup/example6 + * + */ + @Test(testName = "Perform a Concise Correlated Subquery with ``$lookup``") public void testExample6() { loadData("restaurants", 2); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - lookup("restaurants") - .localField("restaurant_name") - .foreignField("name") - .pipeline(match(expr(in("$$orders_drink", "$beverages")))) - .let("orders_drink", "$drink") - .as("matches"))); + testPipeline((aggregation) -> aggregation.pipeline(lookup("restaurants").localField("restaurant_name") + .foreignField("name").pipeline(match(expr(in("$$orders_drink", "$beverages")))) + .let("orders_drink", "$drink").as("matches"))); } @Test public void testLookup() { - // Test data pulled from https://docs.mongodb.com/v3.2/reference/operator/aggregation/lookup/ - getDs().save(asList(new Order(1, "abc", 12, 2), - new Order(2, "jkl", 20, 1), - new Order(3))); + // Test data pulled from + // https://docs.mongodb.com/v3.2/reference/operator/aggregation/lookup/ + getDs().save(asList(new Order(1, "abc", 12, 2), new Order(2, "jkl", 20, 1), new Order(3))); List inventories = asList(new Inventory(1, "abc", "product 1", 120), - new Inventory(2, "def", "product 2", 80), - new Inventory(3, "ijk", "product 3", 60), - new Inventory(4, "jkl", "product 4", 70), - new Inventory(5, null, "Incomplete"), - new Inventory(6)); + new Inventory(2, "def", "product 2", 80), new Inventory(3, "ijk", "product 3", 60), + new Inventory(4, "jkl", "product 4", 70), new Inventory(5, null, "Incomplete"), new Inventory(6)); getDs().save(inventories); List lookups = getDs().aggregate(Order.class) - .lookup(lookup(Inventory.class) - .localField("item") - .foreignField("sku") - .as("inventoryDocs")) - .sort(sort().ascending("_id")) - .execute(Order.class) - .toList(); + .lookup(lookup(Inventory.class).localField("item").foreignField("sku").as("inventoryDocs")) + .sort(sort().ascending("_id")).execute(Order.class).toList(); assertEquals(lookups.get(0).getInventoryDocs().get(0), inventories.get(0)); assertEquals(lookups.get(1).getInventoryDocs().get(0), inventories.get(3)); assertEquals(lookups.get(2).getInventoryDocs().get(0), inventories.get(4)); diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestMatch.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestMatch.java index 9d2309cd3d1..2dac68b2dbf 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestMatch.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestMatch.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -15,24 +15,27 @@ import static dev.morphia.query.filters.Filters.gte; import static dev.morphia.query.filters.Filters.lt; import static dev.morphia.query.filters.Filters.or; +import static dev.morphia.test.ServerVersion.ANY; -public class TestMatch extends AggregationTest { - @Test - public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(eq("author", "dave")))); +public class TestMatch extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/match/example1 + */ + @Test(testName = "Equality Match") + public void testExample1() { + testPipeline(aggregation -> aggregation.pipeline(match(eq("author", "dave")))); } - @Test - public void testExample3() { - testPipeline(ServerVersion.ANY, true, false, (aggregation) -> aggregation.pipeline( - match(or( - and( - gt("score", 70), - lt("score", 90)), - gte("views", 1000))), - group(id(null)) - .field("count", sum(1)))); + /** + * test data: dev/morphia/test/aggregation/stages/match/example2 + * + */ + @Test(testName = "Perform a Count") + public void testExample2() { + testPipeline(new ActionTestOptions().serverVersion(ANY).removeIds(true).orderMatters(false), + (aggregation) -> aggregation.pipeline( + match(or(and(gt("score", 70), lt("score", 90)), gte("views", 1000))), + group(id(null)).field("count", sum(1)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestMerge.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestMerge.java index e6215018018..433ffa29b04 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestMerge.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestMerge.java @@ -3,8 +3,8 @@ import java.time.LocalDate; import java.time.Month; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -26,101 +26,104 @@ import static dev.morphia.query.filters.Filters.gte; import static dev.morphia.query.filters.Filters.lt; -public class TestMerge extends AggregationTest { - public TestMerge() { - skipDataCheck(); - } - - @Test +public class TestMerge extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/merge/example1 + * + */ + @Test(testName = "On-Demand Materialized View: Initial Creation") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - group(id() - .field("fiscal_year", "$fiscal_year") - .field("dept", "$dept")) - .field("salaries", sum("$salary")), - merge("reporting", "budgets") - .on("_id") - .whenMatched(REPLACE) - .whenNotMatched(INSERT))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline( + group(id().field("fiscal_year", "$fiscal_year").field("dept", "$dept")).field("salaries", + sum("$salary")), + merge("reporting", "budgets").on("_id").whenMatched(REPLACE).whenNotMatched(INSERT))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/merge/example2 + * + */ + @Test(testName = "On-Demand Materialized View: Update/Replace Data") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(gte("fiscal_year", 2019)), - group(id() - .field("fiscal_year", "$fiscal_year") - .field("dept", "$dept")) - .field("salaries", sum("$salary")), - merge("reporting", "budgets") - .on("_id") - .whenMatched(REPLACE) - .whenNotMatched(INSERT))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(match(gte("fiscal_year", 2019)), + group(id().field("fiscal_year", "$fiscal_year").field("dept", "$dept")).field("salaries", + sum("$salary")), + merge("reporting", "budgets").on("_id").whenMatched(REPLACE).whenNotMatched(INSERT))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/merge/example3 + * + */ + @Test(testName = "Only Insert New Data") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(eq("fiscal_year", 2019)), - group(id() - .field("fiscal_year", "$fiscal_year") - .field("dept", "$dept")) - .field("employees", push("$employee")), - project() - .suppressId() - .include("dept", "$_id.dept") - .include("fiscal_year", "$_id.fiscal_year") - .include("employees"), - merge("reporting", "orgArchive") - .on("dept", "fiscal_year") - .whenMatched(FAIL))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(match(eq("fiscal_year", 2019)), + group(id().field("fiscal_year", "$fiscal_year").field("dept", "$dept")).field("employees", + push("$employee")), + project().suppressId().include("dept", "$_id.dept").include("fiscal_year", "$_id.fiscal_year") + .include("employees"), + merge("reporting", "orgArchive").on("dept", "fiscal_year").whenMatched(FAIL))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/merge/example4 + * + */ + @Test(testName = "Merge Results from Multiple Collections") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - group() - .field("_id", "$quarter") - .field("purchased", sum("$qty")), - merge("quarterlyreport") - .on("_id") - .whenMatched(MERGE) - .whenNotMatched(INSERT))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(group().field("_id", "$quarter").field("purchased", sum("$qty")), + merge("quarterlyreport").on("_id").whenMatched(MERGE).whenNotMatched(INSERT))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/merge/example5 + * + */ + @Test(testName = "Use the Pipeline to Customize the Merge") public void testExample5() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match( - gte("date", LocalDate.of(2019, Month.MAY, 7)), - lt("date", LocalDate.of(2019, Month.MAY, 8))), - project() - .include("_id", dateToString() - .date("$date") - .format("%Y-%m")) - .include("thumbsup") - .include("thumbsdown"), - merge("monthlytotals") - .on("_id") - .whenMatched( - addFields() - .field("thumbsup", add("$thumbsup", "$$new.thumbsup")) + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline( + match(gte("date", LocalDate.of(2019, Month.MAY, 7)), + lt("date", LocalDate.of(2019, Month.MAY, 8))), + project().include("_id", dateToString().date("$date").format("%Y-%m")).include("thumbsup") + .include("thumbsdown"), + merge("monthlytotals").on("_id") + .whenMatched(addFields().field("thumbsup", add("$thumbsup", "$$new.thumbsup")) .field("thumbsdown", add("$thumbsdown", "$$new.thumbsdown"))) - .whenNotMatched(INSERT))); + .whenNotMatched(INSERT))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/merge/example6 + * + */ + @Test(testName = "Use Variables to Customize the Merge :: Merge Stage") public void testExample6() { - // merging in to another db complicates the test infra and doesn't really provide much value as another test + // merging in to another db complicates the test infra and doesn't really + // provide much value as another test } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/merge/example7 + * + */ + @Test(testName = "Use Variables to Customize the Merge :: Aggregate Command") public void testExample7() { - // merging in to another db complicates the test infra and doesn't really provide much value as another test + // merging in to another db complicates the test infra and doesn't really + // provide much value as another test } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/merge/example8 + * + */ + @Test(testName = "Use Variables to Customize the Merge :: Merge and Aggregate") public void testExample8() { - // merging in to another db complicates the test infra and doesn't really provide much value as another test + // merging in to another db complicates the test infra and doesn't really + // provide much value as another test } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestOut.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestOut.java index f515e9d691c..39234446f38 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestOut.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestOut.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import dev.morphia.test.models.Author; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -11,27 +11,25 @@ import static dev.morphia.aggregation.stages.Group.id; import static dev.morphia.aggregation.stages.Out.out; -public class TestOut extends AggregationTest { - public TestOut() { - skipDataCheck(); - } - - @Test +public class TestOut extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/out/example1 + * + */ + @Test(testName = "Output to Same Database") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - group(id("$author")) - .field("books", push() - .single("$title")), - out(Author.class))); + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation + .pipeline(group(id("$author")).field("books", push().single("$title")), out(Author.class))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/out/example2 + * + */ + @Test(testName = "Output to a Different Database") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - group(id("$author")) - .field("books", push() - .single("$title")), - out(Author.class) - .database("reporting"))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(group(id("$author")).field("books", push().single("$title")), + out(Author.class).database("reporting"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestPlanCacheStats.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestPlanCacheStats.java index 128ba124b1f..6a3776b06af 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestPlanCacheStats.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestPlanCacheStats.java @@ -2,8 +2,8 @@ import com.mongodb.client.model.IndexOptions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.bson.Document; import org.testng.annotations.Test; @@ -12,30 +12,38 @@ import static dev.morphia.aggregation.stages.PlanCacheStats.planCacheStats; import static dev.morphia.query.filters.Filters.eq; -public class TestPlanCacheStats extends AggregationTest { - public TestPlanCacheStats() { - skipDataCheck(); - } - - @Test +public class TestPlanCacheStats extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/planCacheStats/example1 + * + */ + @Test(testName = "Return Information for All Entries in the Query Cache") public void testExample1() { - Document keys = new Document("item", 1) - .append("price", 1); - var options = new IndexOptions() - .partialFilterExpression(new Document("price", new Document("$gte", 10.0))); - getDatabase().getCollection(AGG_TEST_COLLECTION).createIndex(keys, options); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - planCacheStats())); + Document keys = new Document("item", 1).append("price", 1); + var options = new IndexOptions().partialFilterExpression(new Document("price", new Document("$gte", 10.0))); + getDatabase().getCollection(EXAMPLE_TEST_COLLECTION).createIndex(keys, options); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(planCacheStats())); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/planCacheStats/example2 + * + */ + @Test(testName = "Find Cache Entry Details for a Query Hash") public void testExample2() { - Document keys = new Document("item", 1) - .append("price", 1); - var options = new IndexOptions() - .partialFilterExpression(new Document("price", new Document("$gte", 10.0))); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - planCacheStats(), - match(eq("planCacheKey", "B1435201")))); + Document keys = new Document("item", 1).append("price", 1); + var options = new IndexOptions().partialFilterExpression(new Document("price", new Document("$gte", 10.0))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(planCacheStats(), match(eq("planCacheKey", "B1435201")))); + } + + /** + * test data: dev/morphia/test/aggregation/stages/planCacheStats/example3 + */ + @Test(testName = "Find Cache Entry Details for a Query Hash") + public void testExample3() { + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(planCacheStats(), match(eq("planCacheKey", "B1435201")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestProject.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestProject.java index d66697e1eb2..930913479f2 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestProject.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestProject.java @@ -1,11 +1,10 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; -import static dev.morphia.aggregation.expressions.ArrayExpressions.array; import static dev.morphia.aggregation.expressions.ComparisonExpressions.eq; import static dev.morphia.aggregation.expressions.ConditionalExpressions.condition; import static dev.morphia.aggregation.expressions.Expressions.document; @@ -13,88 +12,97 @@ import static dev.morphia.aggregation.expressions.SystemVariables.REMOVE; import static dev.morphia.aggregation.stages.Projection.project; -public class TestProject extends AggregationTest { - @Test +public class TestProject extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/project/example1 + * + */ + @Test(testName = "Include Specific Fields in Output Documents") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("title") - .include("author"))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("title").include("author"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/project/example2 + * + */ + @Test(testName = "Suppress ``_id`` Field in the Output Documents") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("title") - .include("author"))); + testPipeline((aggregation) -> aggregation.pipeline(project().suppressId().include("title").include("author"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/project/example3 + * + */ + @Test(testName = "Exclude Fields from Output Documents") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .exclude("author.first") - .exclude("lastModified"))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(project().exclude("lastModified"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/project/example4 + * + */ + @Test(testName = "Conditionally Exclude Fields") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("title") - .include("author.first") - .include("author.last") - .include("author.middle", condition( - eq("", "$author.middle"), REMOVE, "$author.middle")))); + testPipeline((aggregation) -> aggregation + .pipeline(project().include("title").include("author.first").include("author.last") + .include("author.middle", condition(eq("", "$author.middle"), REMOVE, "$author.middle")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/project/example5 + * + */ + @Test(testName = "Include Specific Fields from Embedded Documents") public void testExample5() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("stop.title"))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("stop.title"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/project/example7 + * + */ + @Test(testName = "Include Specific Fields from Embedded Documents") public void testExample6() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("title") - .include("isbn", document() - .field("prefix", substrBytes("$isbn", 0, 3)) - .field("group", substrBytes("$isbn", 3, 2)) - .field("publisher", substrBytes("$isbn", 5, 4)) - .field("title", substrBytes("$isbn", 9, 3)) - .field("checkDigit", substrBytes("$isbn", 12, 1))) - .include("lastName", "$author.last") - .include("copiesSold", "$copies"))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("stop.title"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/project/example6 + * + */ + @Test(testName = "Include Computed Fields") public void testExample7() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .include("myArray", array("$x", "$y")))); + testPipeline((aggregation) -> aggregation.pipeline(project().include("title") + .include("isbn", document().field("prefix", substrBytes("$isbn", 0, 3)) + .field("group", substrBytes("$isbn", 3, 2)).field("publisher", substrBytes("$isbn", 5, 4)) + .field("title", substrBytes("$isbn", 9, 3)).field("checkDigit", substrBytes("$isbn", 12, 1))) + .include("lastName", "$author.last").include("copiesSold", "$copies"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/project/example8 + * + */ + @Test(testName = "Array Indexes are Unsupported") public void testExample8() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - project() - .suppressId() - .include("x", "$name"))); + testPipeline((aggregation) -> aggregation.pipeline(project().suppressId().include("x", "$name"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/project/example9 + * + */ + @Test(testName = "Array Indexes are Unsupported") public void testExample9() { // unsupported multiple examples here /* - * testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - * project() - * .suppressId() - * .include("x", "$name"))); + * testPipeline(new dev.morphia.test.util.ActionTestOptions(). removeIds(false), + * (aggregation) -> aggregation.pipeline( project() .suppressId() .include("x", + * "$name"))); */ } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestRedact.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestRedact.java index a2cdfbc4c7c..e6a1a9d5ac5 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestRedact.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestRedact.java @@ -1,8 +1,7 @@ package dev.morphia.test.aggregation.stages; import dev.morphia.aggregation.expressions.ComparisonExpressions; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -17,25 +16,25 @@ import static dev.morphia.aggregation.stages.Redact.redact; import static dev.morphia.query.filters.Filters.eq; -public class TestRedact extends AggregationTest { - @Test +public class TestRedact extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/redact/example1 + * + */ + @Test(testName = "Evaluate Access at Every Document Level") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(eq("year", 2014)), - redact( - condition( - gt(size(setIntersection("$tags", array("STLW", "G"))), 0), - DESCEND, PRUNE)))); + testPipeline((aggregation) -> aggregation.pipeline(match(eq("year", 2014)), + redact(condition(gt(size(setIntersection("$tags", array("STLW", "G"))), 0), DESCEND, PRUNE)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/redact/example2 + * + */ + @Test(testName = "Exclude All Fields at a Given Level") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(eq("status", "A")), - redact(condition( - ComparisonExpressions.eq("$level", 5), - PRUNE, - DESCEND)))); + testPipeline((aggregation) -> aggregation.pipeline(match(eq("status", "A")), + redact(condition(ComparisonExpressions.eq("$level", 5), PRUNE, DESCEND)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceRoot.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceRoot.java index c8f61ef5cfd..3ddf27d2ac1 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceRoot.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceRoot.java @@ -1,7 +1,6 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -14,44 +13,45 @@ import static dev.morphia.aggregation.stages.Unwind.unwind; import static dev.morphia.query.filters.Filters.gte; -public class TestReplaceRoot extends AggregationTest { - @Test +public class TestReplaceRoot extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/replaceRoot/example1 + * + */ + @Test(testName = "``$replaceRoot`` with an Embedded Document Field") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceRoot(mergeObjects() - .add(document() - .field("dogs", 0) - .field("cats", 0) - .field("birds", 0) - .field("fish", 0)) - .add("$pets")))); + testPipeline((aggregation) -> aggregation.pipeline(replaceRoot(mergeObjects() + .add(document().field("dogs", 0).field("cats", 0).field("birds", 0).field("fish", 0)).add("$pets")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/replaceRoot/example2 + * + */ + @Test(testName = "``$replaceRoot`` with a Document Nested in an Array") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unwind("grades"), - match(gte("grades.grade", 90)), + testPipeline((aggregation) -> aggregation.pipeline(unwind("grades"), match(gte("grades.grade", 90)), replaceRoot("$grades"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/replaceRoot/example3 + * + */ + @Test(testName = "``$replaceRoot`` with a newly created document") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceRoot() - .field("full_name", concat("$first_name", " ", "$last_name")))); + testPipeline((aggregation) -> aggregation + .pipeline(replaceRoot().field("full_name", concat("$first_name", " ", "$last_name")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/replaceRoot/example4 + * + */ + @Test(testName = "``$replaceRoot`` with a New Document Created from ``$$ROOT`` and a Default Document") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceRoot(mergeObjects() - .add(document() - .field("_id", "") - .field("name", "") - .field("email", "") - .field("cell", "") - .field("home", "")) - .add(ROOT)))); + testPipeline((aggregation) -> aggregation.pipeline(replaceRoot(mergeObjects().add( + document().field("_id", "").field("name", "").field("email", "").field("cell", "").field("home", "")) + .add(ROOT)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceWith.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceWith.java index 6040a052561..5e41811713c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceWith.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceWith.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -16,50 +16,48 @@ import static dev.morphia.query.filters.Filters.eq; import static dev.morphia.query.filters.Filters.gte; -public class TestReplaceWith extends AggregationTest { - @Test +public class TestReplaceWith extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/replaceWith/example1 + * + */ + @Test(testName = "``$replaceWith`` an Embedded Document Field") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceWith(mergeObjects() - .add(document() - .field("dogs", 0) - .field("cats", 0) - .field("birds", 0) - .field("fish", 0)) - .add("$pets")))); + testPipeline((aggregation) -> aggregation.pipeline(replaceWith(mergeObjects() + .add(document().field("dogs", 0).field("cats", 0).field("birds", 0).field("fish", 0)).add("$pets")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/replaceWith/example2 + * + */ + @Test(testName = "``$replaceWith`` a Document Nested in an Array") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unwind("grades"), - match(gte("grades.grade", 90)), + testPipeline((aggregation) -> aggregation.pipeline(unwind("grades"), match(gte("grades.grade", 90)), replaceWith("$grades"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/replaceWith/example3 + * + */ + @Test(testName = "``$replaceWith`` a Newly Created Document") public void testExample3() { - skipDataCheck(); // the "asofDate" field will always differ - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - match(eq("status", "C")), - replaceWith() - .field("_id", "$_id") - .field("item", "$item") - .field("amount", multiply("$price", "$quantity")) - .field("status", "Complete") - .field("asofDate", NOW))); + testPipeline(new ActionTestOptions().orderMatters(false).skipDataCheck(true), + (aggregation) -> aggregation.pipeline(match(eq("status", "C")), + replaceWith().field("_id", "$_id").field("item", "$item") + .field("amount", multiply("$price", "$quantity")).field("status", "Complete") + .field("asofDate", NOW))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/replaceWith/example4 + * + */ + @Test(testName = "``$replaceWith`` a New Document Created from ``$$ROOT`` and a Default Document", enabled = false, description = "failing oddly") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - replaceWith(mergeObjects() - .add(document() - .field("_id", "") - .field("name", "") - .field("email", "") - .field("cell", "") - .field("home", "")) - .add(ROOT)))); + testPipeline((aggregation) -> aggregation.pipeline(replaceWith(mergeObjects().add( + document().field("_id", "").field("name", "").field("email", "").field("cell", "").field("home", "")) + .add(ROOT)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSample.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSample.java index dd114d2caa2..e77c9a30f35 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSample.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSample.java @@ -1,17 +1,19 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.Sample.sample; -public class TestSample extends AggregationTest { - @Test +public class TestSample extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/sample/example1 + * + */ + @Test(testName = "main") public void testExample1() { - skipDataCheck(); // the results are random - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - sample(3))); + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation.pipeline(sample(3))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSet.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSet.java index 7b8ee86f512..b63bd6c7f7b 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSet.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSet.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -14,45 +14,54 @@ import static dev.morphia.aggregation.stages.Set.set; import static dev.morphia.query.filters.Filters.eq; -public class TestSet extends AggregationTest { - @Test +public class TestSet extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/set/example1 + * + */ + @Test(testName = "Using Two ``$set`` Stages") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - set() - .field("totalHomework", sum("$homework")) - .field("totalQuiz", sum("$quiz")), - set() - .field("totalScore", add("$totalHomework", - "$totalQuiz", "$extraCredit")))); + testPipeline((aggregation) -> aggregation.pipeline( + set().field("totalHomework", sum("$homework")).field("totalQuiz", sum("$quiz")), + set().field("totalScore", add("$totalHomework", "$totalQuiz", "$extraCredit")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/set/example2 + * + */ + @Test(testName = "Adding Fields to an Embedded Document") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - set() - .field("specs.fuel_type", "unleaded"))); + testPipeline((aggregation) -> aggregation.pipeline(set().field("specs.fuel_type", "unleaded"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/set/example3 + * + */ + @Test(testName = "Overwriting an existing field") public void testExample3() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - set() - .field("cats", 20))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(set().field("cats", 20))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/set/example4 + * + */ + @Test(testName = "Add Element to an Array") public void testExample4() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(eq("_id", 1)), - set() - .field("homework", concatArrays("$homework", array(7))))); + testPipeline((aggregation) -> aggregation.pipeline(match(eq("_id", 1)), + set().field("homework", concatArrays("$homework", array(7))))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/set/example5 + * + */ + @Test(testName = "Creating a New Field with Existing Fields") public void testExample5() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - set() - .field("quizAverage", avg("$quiz")))); + testPipeline((aggregation) -> aggregation.pipeline(set().field("quizAverage", avg("$quiz")))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSetWindowFields.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSetWindowFields.java index ab1fc54c6b4..1531c9b94fe 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSetWindowFields.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSetWindowFields.java @@ -1,8 +1,8 @@ package dev.morphia.test.aggregation.stages; import dev.morphia.aggregation.expressions.TimeUnit; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; @@ -12,41 +12,39 @@ import static dev.morphia.aggregation.stages.SetWindowFields.setWindowFields; import static dev.morphia.query.Sort.ascending; -public class TestSetWindowFields extends AggregationTest { - @Test +public class TestSetWindowFields extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/setWindowFields/example1 + * + */ + @Test(testName = "Documents Window Examples") public void testExample1() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("cumulativeQuantityForState") - .operator(sum("$quantity")) - .window() - .documents("unbounded", "current")))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(setWindowFields().partitionBy("$state") + .sortBy(ascending("orderDate")).output(output("cumulativeQuantityForState") + .operator(sum("$quantity")).window().documents("unbounded", "current")))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/setWindowFields/example2 + * + */ + @Test(testName = "Range Window Example") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("price")) - .output(output("quantityFromSimilarOrders") - .operator(sum("$quantity")) - .window() - .range(-10, 10)))); + testPipeline((aggregation) -> aggregation + .pipeline(setWindowFields().partitionBy("$state").sortBy(ascending("price")).output( + output("quantityFromSimilarOrders").operator(sum("$quantity")).window().range(-10, 10)))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/setWindowFields/example3 + * + */ + @Test(testName = "Time Range Window Examples") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - setWindowFields() - .partitionBy("$state") - .sortBy(ascending("orderDate")) - .output(output("recentOrders") - .operator(push("$orderDate")) - .window() - .range("unbounded", 10, TimeUnit.MONTH)))); + testPipeline((aggregation) -> aggregation.pipeline( + setWindowFields().partitionBy("$state").sortBy(ascending("orderDate")).output(output("recentOrders") + .operator(push("$orderDate")).window().range("unbounded", 10, TimeUnit.MONTH)))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSkip.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSkip.java index 21cf2fbe457..8cf13c03b49 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSkip.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSkip.java @@ -1,17 +1,19 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.Skip.skip; -public class TestSkip extends AggregationTest { - @Test +public class TestSkip extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/skip/example1 + * + */ + @Test(testName = "main") public void testExample1() { - skipDataCheck(); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - skip(5))); + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation.pipeline(skip(5))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSort.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSort.java index f0994de3244..0e6f49a51a9 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSort.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSort.java @@ -1,7 +1,7 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.bson.Document; import org.testng.annotations.Test; @@ -10,28 +10,26 @@ import static dev.morphia.aggregation.stages.Sort.sort; import static dev.morphia.query.filters.Filters.text; -public class TestSort extends AggregationTest { - public TestSort() { - skipDataCheck(); - } - - @Test +public class TestSort extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/sort/example1 + * + */ + @Test(testName = "Ascending/Descending Sort") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - sort() - .descending("age") - .ascending("posts"))); + testPipeline(new ActionTestOptions().skipDataCheck(true), + (aggregation) -> aggregation.pipeline(sort().descending("age").ascending("posts"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/sort/example2 + * + */ + @Test(testName = "Text Score Metadata Sort") public void testExample2() { - getDatabase().getCollection(AGG_TEST_COLLECTION) - .createIndex(new Document("$**", "text")); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - match(text("operating")), - sort() - .meta("score") - .descending("posts"))); + getDatabase().getCollection(EXAMPLE_TEST_COLLECTION).createIndex(new Document("$**", "text")); + testPipeline(new ActionTestOptions().skipDataCheck(true), (aggregation) -> aggregation + .pipeline(match(text("operating")), sort().meta("score").descending("posts"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSortByCount.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSortByCount.java index 036fdb9aa7b..500aca7918c 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestSortByCount.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestSortByCount.java @@ -1,19 +1,23 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.SortByCount.sortByCount; import static dev.morphia.aggregation.stages.Unwind.unwind; -public class TestSortByCount extends AggregationTest { - @Test +public class TestSortByCount extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/sortByCount/example1 + * + */ + @Test(testName = "main") public void testExample1() { - // orderMatters is false here because of the indeterminate sort order on equal values - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - unwind("$tags"), - sortByCount("$tags"))); + // orderMatters is false here because of the indeterminate sort order on equal + // values + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(unwind("$tags"), sortByCount("$tags"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnionWith.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnionWith.java index c8fac6de845..e55933049b0 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnionWith.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnionWith.java @@ -1,9 +1,7 @@ package dev.morphia.test.aggregation.stages; -import com.github.zafarkhaja.semver.Version; - import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; @@ -16,48 +14,43 @@ import static dev.morphia.aggregation.stages.Sort.sort; import static dev.morphia.aggregation.stages.UnionWith.unionWith; -public class TestUnionWith extends AggregationTest { - @Test +public class TestUnionWith extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/unionWith/example1 + */ + @Test(testName = "Report 1: All Sales by Year and Stores and Items") public void testExample1() { - loadData("sales_2018", 2); - loadData("sales_2019", 3); - loadData("sales_2020", 4); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - set().field("_id", "2017"), - unionWith("sales_2018", - set().field("_id", "2018")), - unionWith("sales_2019", - set().field("_id", "2019")), - unionWith("sales_2020", - set().field("_id", "2020")), - sort().ascending("_id", "store", "item"))); + loadData("sales_2018", 1); + loadData("sales_2019", 2); + loadData("sales_2020", 3); + testPipeline((aggregation) -> aggregation.pipeline(set().field("_id", "2017"), + unionWith("sales_2018", set().field("_id", "2018")), + unionWith("sales_2019", set().field("_id", "2019")), + unionWith("sales_2020", set().field("_id", "2020")), sort().ascending("_id", "store", "item"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/unionWith/example2 + */ + @Test(testName = "Report 2: Aggregated Sales by Items") public void testExample2() { - loadData("sales_2018", 2); - loadData("sales_2019", 3); - loadData("sales_2020", 4); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unionWith("sales_2018"), - unionWith("sales_2019"), - unionWith("sales_2020"), - group(id("$item")) - .field("total", sum("$quantity")), + loadData("sales_2018", 1); + loadData("sales_2019", 2); + loadData("sales_2020", 3); + testPipeline((aggregation) -> aggregation.pipeline(unionWith("sales_2018"), unionWith("sales_2019"), + unionWith("sales_2020"), group(id("$item")).field("total", sum("$quantity")), sort().descending("total"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/unionWith/example3 + */ + @Test(testName = "Create a Union with Specified Documents") public void testExample3() { - assumeTrue(serverIsAtLeastVersion(Version.of(6)), "Minimum server version is 6"); - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unionWith( - documents( - document("_id", 4) - .field("flavor", "orange"), - document("_id", 5) - .field("flavor", "vanilla") - .field("price", 20))))); + checkMinServerVersion(ServerVersion.v60); + testPipeline( + (aggregation) -> aggregation.pipeline(unionWith(documents(document("_id", 4).field("flavor", "orange"), + document("_id", 5).field("flavor", "vanilla").field("price", 20))))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnset.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnset.java index 66ca4ec589f..f0cbd5f4b92 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnset.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnset.java @@ -1,28 +1,36 @@ package dev.morphia.test.aggregation.stages; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import org.testng.annotations.Test; import static dev.morphia.aggregation.stages.Unset.unset; -public class TestUnset extends AggregationTest { - @Test +public class TestUnset extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/unset/example1 + * + */ + @Test(testName = "Remove a Single Field") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unset("copies"))); + testPipeline((aggregation) -> aggregation.pipeline(unset("copies"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/unset/example2 + * + */ + @Test(testName = "Remove Top-Level Fields") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unset("isbn", "copies"))); + testPipeline((aggregation) -> aggregation.pipeline(unset("isbn", "copies"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/unset/example3 + * + */ + @Test(testName = "Remove Embedded Fields") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unset("isbn", "author.first", "copies.warehouse"))); + testPipeline((aggregation) -> aggregation.pipeline(unset("isbn", "author.first", "copies.warehouse"))); } } diff --git a/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnwind.java b/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnwind.java index 62da8e0bb4a..ffc2e4e11d4 100644 --- a/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnwind.java +++ b/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnwind.java @@ -3,9 +3,9 @@ import java.time.format.DateTimeFormatter; import java.util.Iterator; -import dev.morphia.test.ServerVersion; -import dev.morphia.test.aggregation.AggregationTest; +import dev.morphia.test.TemplatedTestBase; import dev.morphia.test.models.User; +import dev.morphia.test.util.ActionTestOptions; import org.testng.Assert; import org.testng.annotations.Test; @@ -23,44 +23,54 @@ import static java.util.Arrays.asList; import static org.testng.Assert.assertEquals; -public class TestUnwind extends AggregationTest { - @Test +public class TestUnwind extends TemplatedTestBase { + /** + * test data: dev/morphia/test/aggregation/stages/unwind/example1 + * + */ + @Test(testName = "Unwind Array") public void testExample1() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unwind("sizes"))); + testPipeline((aggregation) -> aggregation.pipeline(unwind("sizes"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/unwind/example2 + * + */ + @Test(testName = "Missing or Non-array Values") public void testExample2() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unwind("sizes"))); + testPipeline((aggregation) -> aggregation.pipeline(unwind("sizes"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/unwind/example3 + * + */ + @Test(testName = "``preserveNullAndEmptyArrays`` and ``includeArrayIndex``") public void testExample3() { - testPipeline(ServerVersion.ANY, false, true, (aggregation) -> aggregation.pipeline( - unwind("sizes") - .preserveNullAndEmptyArrays(true))); + testPipeline((aggregation) -> aggregation.pipeline(unwind("sizes").preserveNullAndEmptyArrays(true))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/unwind/example4 + * + */ + @Test(testName = "Group by Unwound Values") public void testExample4() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - unwind("sizes") - .preserveNullAndEmptyArrays(true), - group(id("$sizes")) - .field("averagePrice", avg("$price")), - sort() - .descending("averagePrice"))); + testPipeline(new ActionTestOptions().orderMatters(false), + (aggregation) -> aggregation.pipeline(unwind("sizes").preserveNullAndEmptyArrays(true), + group(id("$sizes")).field("averagePrice", avg("$price")), sort().descending("averagePrice"))); } - @Test + /** + * test data: dev/morphia/test/aggregation/stages/unwind/example5 + * + */ + @Test(testName = "Unwind Embedded Arrays") public void testExample5() { - testPipeline(ServerVersion.ANY, false, false, (aggregation) -> aggregation.pipeline( - unwind("items"), + testPipeline(new ActionTestOptions().orderMatters(false), (aggregation) -> aggregation.pipeline(unwind("items"), unwind("items.tags"), - group(id("$items.tags")) - .field("totalSalesAmount", sum(multiply("$items.price", "$items.quantity"))))); + group(id("$items.tags")).field("totalSalesAmount", sum(multiply("$items.price", "$items.quantity"))))); } @Test @@ -71,11 +81,7 @@ public void testUnwind() { new User("john", parse("2012-07-02", format)))); Iterator aggregate = getDs().aggregate(User.class) - .project(project() - .include("name") - .include("joined") - .include("likes")) - .unwind(unwind("likes")) + .project(project().include("name").include("joined").include("likes")).unwind(unwind("likes")) .execute(User.class); int count = 0; while (aggregate.hasNext()) { @@ -107,14 +113,8 @@ public void testUnwind() { count++; } - aggregate = getDs().aggregate(User.class) - .project(project() - .include("name") - .include("joined") - .include("likes")) - .unwind(unwind("likes") - .preserveNullAndEmptyArrays(true)) - .execute(User.class); + aggregate = getDs().aggregate(User.class).project(project().include("name").include("joined").include("likes")) + .unwind(unwind("likes").preserveNullAndEmptyArrays(true)).execute(User.class); count = 0; while (aggregate.hasNext()) { User user = aggregate.next(); diff --git a/core/src/test/java/dev/morphia/test/mapping/TestPropertyModel.java b/core/src/test/java/dev/morphia/test/mapping/TestPropertyModel.java index 4a65d14021e..80ac1d88306 100644 --- a/core/src/test/java/dev/morphia/test/mapping/TestPropertyModel.java +++ b/core/src/test/java/dev/morphia/test/mapping/TestPropertyModel.java @@ -35,7 +35,6 @@ public void arrayFieldMapping() { final PropertyModel property = getMappedField("arrayOfInt"); Assert.assertFalse(property.isScalarValue()); - Assert.assertTrue(property.isMultipleValues()); Assert.assertTrue(property.isArray()); Assert.assertTrue(property.getType().isArray()); Assert.assertEquals(property.getName(), "arrayOfInt"); @@ -57,7 +56,6 @@ public void collectionFieldMapping() { final PropertyModel property = getMappedField("listOfString"); Assert.assertFalse(property.isScalarValue()); - Assert.assertTrue(property.isMultipleValues()); Assert.assertFalse(property.isArray()); Assert.assertSame(property.getType(), List.class); Assert.assertSame(property.getNormalizedType(), String.class); @@ -80,7 +78,6 @@ public void nestedCollectionsMapping() { final PropertyModel property = getMappedField("listOfListOfString"); Assert.assertFalse(property.isScalarValue()); - Assert.assertTrue(property.isMultipleValues()); Assert.assertFalse(property.isArray()); Assert.assertSame(property.getType(), List.class); @@ -108,7 +105,6 @@ public void nestedGenerics() { final PropertyModel property = getMappedField("nestedList"); Assert.assertFalse(property.isScalarValue()); - Assert.assertTrue(property.isMultipleValues()); Assert.assertFalse(property.isArray()); Assert.assertSame(property.getType(), List.class); Assert.assertSame(property.getNormalizedType(), Nested.class); diff --git a/core/src/test/java/dev/morphia/test/query/FiltersTest.java b/core/src/test/java/dev/morphia/test/query/FiltersTest.java index e888d8cb091..201c4e56937 100644 --- a/core/src/test/java/dev/morphia/test/query/FiltersTest.java +++ b/core/src/test/java/dev/morphia/test/query/FiltersTest.java @@ -14,34 +14,24 @@ import dev.morphia.annotations.Id; import dev.morphia.query.FindOptions; import dev.morphia.query.Meta; -import dev.morphia.query.MorphiaQuery; import dev.morphia.query.Query; import dev.morphia.query.Type; import dev.morphia.test.TemplatedTestBase; -import dev.morphia.test.aggregation.model.Inventory; import dev.morphia.test.models.Budget; import dev.morphia.test.models.User; import org.bson.Document; import org.testng.Assert; +import org.testng.annotations.AfterClass; import org.testng.annotations.Test; import static dev.morphia.aggregation.expressions.Miscellaneous.rand; import static dev.morphia.aggregation.expressions.Miscellaneous.sampleRate; import static dev.morphia.aggregation.stages.Match.match; -import static dev.morphia.query.filters.Filters.and; -import static dev.morphia.query.filters.Filters.bitsAllClear; -import static dev.morphia.query.filters.Filters.bitsAllSet; -import static dev.morphia.query.filters.Filters.bitsAnyClear; -import static dev.morphia.query.filters.Filters.bitsAnySet; import static dev.morphia.query.filters.Filters.expr; import static dev.morphia.query.filters.Filters.gt; -import static dev.morphia.query.filters.Filters.gte; -import static dev.morphia.query.filters.Filters.in; import static dev.morphia.query.filters.Filters.jsonSchema; import static dev.morphia.query.filters.Filters.lt; -import static dev.morphia.query.filters.Filters.lte; -import static dev.morphia.query.filters.Filters.mod; import static dev.morphia.query.filters.Filters.nin; import static dev.morphia.query.filters.Filters.nor; import static dev.morphia.query.filters.Filters.or; @@ -56,16 +46,12 @@ import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; +@Deprecated @SuppressWarnings("resource") public class FiltersTest extends TemplatedTestBase { - @Test - public void testAnd() { - getDs().find(Budget.class) - .filter(and(lt("budget", 10000), gt("budget", 12))) - .iterator(); - getDs().find(Budget.class) - .filter(and(lte("budget", 10000), gte("budget", 12))) - .iterator(); + @AfterClass + @Override + public void testCoverage() { } @Test @@ -81,100 +67,6 @@ public void testType() { Assert.assertTrue(query.count() > 0); } - @Test - public void testBitsAllClear() { - MongoCollection collection = getDatabase().getCollection("users"); - - String discriminator = User.class.getName(); - collection.insertMany(asList( - new Document("a", 54).append("binaryValueofA", "00110110").append("_t", discriminator), - new Document("a", 20).append("binaryValueofA", "00010100").append("_t", discriminator), - new Document("a", 20.0).append("binaryValueofA", "00010100").append("_t", discriminator))); - - FindOptions options = new FindOptions().logQuery(); - - Query query = getDs().find(User.class) - .disableValidation() - .filter(bitsAllClear("a", 35)); - assertEquals(query.iterator(options).toList().size(), 2, query.getLoggedQuery()); - - query = getDs().find(User.class) - .disableValidation() - .filter(bitsAllClear("a", new int[] { 1, 5 })); - assertEquals(query.iterator(options).toList().size(), 2, query.getLoggedQuery()); - } - - @Test - public void testBitsAllSet() { - MongoCollection collection = getDatabase().getCollection("users"); - - String discriminator = User.class.getName(); - collection.insertMany(asList( - new Document("a", 54).append("binaryValueofA", "00110110").append("_t", discriminator), - new Document("a", 20).append("binaryValueofA", "00010100").append("_t", discriminator), - new Document("a", 20.0).append("binaryValueofA", "00010100").append("_t", discriminator))); - - final FindOptions options = new FindOptions().logQuery(); - - Query query = getDs().find(User.class) - .disableValidation() - .filter(bitsAllSet("a", 50)); - assertEquals(query.iterator(options).toList().size(), 1, query.getLoggedQuery()); - - query = getDs().find(User.class) - .disableValidation() - .filter(bitsAllSet("a", new int[] { 1, 5 })); - assertEquals(query.iterator(options) - .toList().size(), 1, query.getLoggedQuery()); - } - - @Test - public void testBitsAnyClear() { - MongoCollection collection = getDatabase().getCollection("users"); - - String discriminator = User.class.getName(); - collection.insertMany(asList( - new Document("a", 54).append("binaryValueofA", "00110110").append("_t", discriminator), - new Document("a", 20).append("binaryValueofA", "00010100").append("_t", discriminator), - new Document("a", 20.0).append("binaryValueofA", "00010100").append("_t", discriminator))); - - FindOptions options = new FindOptions().logQuery(); - - Query query = getDs().find(User.class) - .disableValidation() - .filter(bitsAnyClear("a", 35)); - assertEquals(query.iterator(options).toList().size(), 3, query.getLoggedQuery()); - - query = getDs().find(User.class) - .disableValidation() - .filter(bitsAnyClear("a", new int[] { 1, 5 })); - assertEquals(query.iterator(options) - .toList().size(), 2, query.getLoggedQuery()); - } - - @Test - public void testBitsAnySet() { - MongoCollection collection = getDatabase().getCollection("users"); - - String discriminator = User.class.getName(); - collection.insertMany(asList( - new Document("a", 54).append("binaryValueofA", "00110110").append("_t", discriminator), - new Document("a", 20).append("binaryValueofA", "00010100").append("_t", discriminator), - new Document("a", 20.0).append("binaryValueofA", "00010100").append("_t", discriminator))); - - FindOptions options = new FindOptions().logQuery(); - - Query query = getDs().find(User.class) - .disableValidation() - .filter(bitsAnySet("a", 35)); - assertEquals(query.iterator(options).toList().size(), 1, query.getLoggedQuery()); - - assertEquals(getDs().find(User.class) - .disableValidation() - .filter(bitsAnySet("a", new int[] { 1, 5 })).iterator(options) - .toList().size(), 1, query.getLoggedQuery()); - } - @Test public void testExpr() { insert("budget", asList( @@ -191,13 +83,6 @@ public void testExpr() { assertEquals(budgets.size(), 3); } - @Test - public void testIn() { - getDs().find(Budget.class) - .filter(in("budget", asList(123, 234))) - .iterator(); - } - @Test public void testJsonSchema() { insert("inventory", List.of( @@ -263,15 +148,6 @@ public void testMeta() { } - @Test - public void testMod() { - var query = getDs().find(Inventory.class) - .disableValidation() - .filter(mod("qty", 4, 0)); - testQuery((MorphiaQuery) query, new FindOptions(), true); - - } - @Test public void testNin() { getDs().find(Budget.class) diff --git a/core/src/test/java/dev/morphia/test/query/QueryTest.java b/core/src/test/java/dev/morphia/test/query/QueryTest.java index bd53400eeca..9faf5cee16f 100644 --- a/core/src/test/java/dev/morphia/test/query/QueryTest.java +++ b/core/src/test/java/dev/morphia/test/query/QueryTest.java @@ -9,7 +9,6 @@ import org.testng.annotations.AfterClass; -import static dev.morphia.test.aggregation.AggregationTest.rootToCore; import static java.util.Arrays.stream; import static org.testng.Assert.fail; diff --git a/core/src/test/java/dev/morphia/test/query/TestSorts.java b/core/src/test/java/dev/morphia/test/query/TestSorts.java deleted file mode 100644 index 3db26cc5e47..00000000000 --- a/core/src/test/java/dev/morphia/test/query/TestSorts.java +++ /dev/null @@ -1,69 +0,0 @@ -package dev.morphia.test.query; - -import java.util.Objects; - -import dev.morphia.annotations.Entity; -import dev.morphia.annotations.Id; -import dev.morphia.annotations.Text; -import dev.morphia.query.FindOptions; -import dev.morphia.query.MorphiaQuery; -import dev.morphia.query.Query; -import dev.morphia.test.TemplatedTestBase; - -import org.testng.annotations.Test; - -import static dev.morphia.query.Meta.textScore; -import static dev.morphia.query.Sort.ascending; -import static dev.morphia.query.filters.Filters.text; -import static java.lang.String.format; - -public class TestSorts extends TemplatedTestBase { - - @Test - public void metaAndSorts() { - getMapper().map(Article.class); - getDs().applyIndexes(); - - Query
query = getDs().find(Article.class) - .filter(text("coffee")); - FindOptions options = new FindOptions() - .logQuery() - .sort(textScore("textScore"), - ascending("subject")); - - testQuery((MorphiaQuery) query, options, true); - } - - @Entity(useDiscriminator = false) - private static class Article { - @Id - int id; - @Text - String subject; - String author; - int views; - double textScore; - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Article article)) { - return false; - } - return id == article.id && views == article.views && Double.compare(article.textScore, textScore) == 0 && - Objects.equals(subject, article.subject) && Objects.equals(author, article.author); - } - - @Override - public int hashCode() { - return Objects.hash(id, subject, author, views, textScore); - } - - @Override - public String toString() { - return format("Article{id=%d, subject='%s', author='%s', views=%d, textScore=%s}", id, subject, author, views, textScore); - } - } -} diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestAll.java b/core/src/test/java/dev/morphia/test/query/filters/TestAll.java new file mode 100644 index 00000000000..c9be67b997e --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestAll.java @@ -0,0 +1,34 @@ +package dev.morphia.test.query.filters; + +import java.util.List; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.all; +import static dev.morphia.query.filters.Filters.elemMatch; +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.gt; + +public class TestAll extends TemplatedTestBase { + /** + * test data: dev/morphia/test/query/filters/all/example1 + * + */ + @Test(testName = "Use ``$all`` to Match Values") + public void testExample1() { + testQuery((query) -> query.filter(all("tags", List.of("appliance", "school", "book")))); + } + + /** + * test data: dev/morphia/test/query/filters/all/example2 + * + */ + @Test(testName = "Use ``$all`` with ``$elemMatch``") + public void testExample2() { + testQuery((query) -> query.filter(all("qty", + List.of(elemMatch(eq("size", "M"), gt("num", 50)), elemMatch(eq("num", 100), eq("color", "green")))))); + } + +} diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestAnd.java b/core/src/test/java/dev/morphia/test/query/filters/TestAnd.java new file mode 100644 index 00000000000..88c7b5df44c --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestAnd.java @@ -0,0 +1,35 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.and; +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.exists; +import static dev.morphia.query.filters.Filters.gt; +import static dev.morphia.query.filters.Filters.lt; +import static dev.morphia.query.filters.Filters.ne; +import static dev.morphia.query.filters.Filters.or; + +public class TestAnd extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/and/example1 + */ + @Test(testName = "``AND`` Queries With Multiple Expressions Specifying the Same Field") + public void testExample1() { + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(and(ne("price", 1.99), exists("price")))); + } + + /** + * test data: dev/morphia/test/query/filters/and/example2 + */ + @Test(testName = "``AND`` Queries With Multiple Expressions Specifying the Same Operator") + public void testExample2() { + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(and(or(lt("qty", 10), gt("qty", 50)), or(eq("sale", true), lt("price", 5))))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestBitsAllClear.java b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAllClear.java new file mode 100644 index 00000000000..07525d79a6f --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAllClear.java @@ -0,0 +1,37 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.bitsAllClear; + +public class TestBitsAllClear extends TemplatedTestBase { + /** + * test data: dev/morphia/test/query/filters/bitsAllClear/example1 + * + */ + @Test(testName = "Bit Position Array") + public void testExample1() { + testQuery((query) -> query.filter(bitsAllClear("a", new int[] { 1, 5 }))); + } + + /** + * test data: dev/morphia/test/query/filters/bitsAllClear/example2 + * + */ + @Test(testName = "Integer Bitmask") + public void testExample2() { + testQuery((query) -> query.filter(bitsAllClear("a", 35))); + } + + /** + * test data: dev/morphia/test/query/filters/bitsAllClear/example3 + * + */ + @Test(testName = "BinData Bitmask") + public void testExample3() { + testQuery((query) -> query.filter(bitsAllClear("a", new byte[] { 32 }))); + } + +} diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestBitsAllSet.java b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAllSet.java new file mode 100644 index 00000000000..a0b50689ab2 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAllSet.java @@ -0,0 +1,37 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.bitsAllSet; + +public class TestBitsAllSet extends TemplatedTestBase { + /** + * test data: dev/morphia/test/query/filters/bitsAllSet/example1 + * + */ + @Test(testName = "Bit Position Array") + public void testExample1() { + testQuery((query) -> query.filter(bitsAllSet("a", new int[] { 1, 5 }))); + } + + /** + * test data: dev/morphia/test/query/filters/bitsAllSet/example2 + * + */ + @Test(testName = "Integer Bitmask") + public void testExample2() { + testQuery((query) -> query.filter(bitsAllSet("a", 50))); + } + + /** + * test data: dev/morphia/test/query/filters/bitsAllSet/example3 + * + */ + @Test(testName = "BinData Bitmask") + public void testExample3() { + testQuery((query) -> query.filter(bitsAllSet("a", new byte[] { 48 }))); + } + +} diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnyClear.java b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnyClear.java new file mode 100644 index 00000000000..9ba83abbdf9 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnyClear.java @@ -0,0 +1,37 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.bitsAnyClear; + +public class TestBitsAnyClear extends TemplatedTestBase { + /** + * test data: dev/morphia/test/query/filters/bitsAnyClear/example1 + * + */ + @Test(testName = "Bit Position Array") + public void testExample1() { + testQuery((query) -> query.filter(bitsAnyClear("a", new int[] { 1, 5 }))); + } + + /** + * test data: dev/morphia/test/query/filters/bitsAnyClear/example2 + * + */ + @Test(testName = "Integer Bitmask") + public void testExample2() { + testQuery((query) -> query.filter(bitsAnyClear("a", 35))); + } + + /** + * test data: dev/morphia/test/query/filters/bitsAnyClear/example3 + * + */ + @Test(testName = "BinData Bitmask") + public void testExample3() { + testQuery((query) -> query.filter(bitsAnyClear("a", new byte[] { 48 }))); + } + +} diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnySet.java b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnySet.java new file mode 100644 index 00000000000..ae836b3a4b2 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnySet.java @@ -0,0 +1,37 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.bitsAnySet; + +public class TestBitsAnySet extends TemplatedTestBase { + /** + * test data: dev/morphia/test/query/filters/bitsAnySet/example1 + * + */ + @Test(testName = "Bit Position Array") + public void testExample1() { + testQuery((query) -> query.filter(bitsAnySet("a", new int[] { 1, 5 }))); + } + + /** + * test data: dev/morphia/test/query/filters/bitsAnySet/example2 + * + */ + @Test(testName = "Integer Bitmask") + public void testExample2() { + testQuery((query) -> query.filter(bitsAnySet("a", 35))); + } + + /** + * test data: dev/morphia/test/query/filters/bitsAnySet/example3 + * + */ + @Test(testName = "BinData Bitmask") + public void testExample3() { + testQuery((query) -> query.filter(bitsAnySet("a", new byte[] { 48 }))); + } + +} diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestBox.java b/core/src/test/java/dev/morphia/test/query/filters/TestBox.java new file mode 100644 index 00000000000..699d02584a7 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestBox.java @@ -0,0 +1,25 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Position; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.box; + +public class TestBox extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/box/example1 + */ + @Test(testName = "main") + public void testExample1() { + Point bottomLeft = new Point(new Position(0, 0)); + Point upperRight = new Point(new Position(100, 100)); + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(box("loc", bottomLeft, upperRight))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestCenter.java b/core/src/test/java/dev/morphia/test/query/filters/TestCenter.java new file mode 100644 index 00000000000..b820ea48994 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestCenter.java @@ -0,0 +1,23 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Position; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.center; + +public class TestCenter extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/center/example1 + */ + @Test(testName = "main") + public void testExample1() { + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(center("loc", new Point(new Position(-74, 40.74)), 10))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestCenterSphere.java b/core/src/test/java/dev/morphia/test/query/filters/TestCenterSphere.java new file mode 100644 index 00000000000..0bbc9286008 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestCenterSphere.java @@ -0,0 +1,23 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Position; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.centerSphere; + +public class TestCenterSphere extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/centerSphere/example1 + */ + @Test(testName = "main") + public void testExample1() { + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(centerSphere("loc", new Point(new Position(-88, 30)), 0.0025232135648))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestComment.java b/core/src/test/java/dev/morphia/test/query/filters/TestComment.java new file mode 100644 index 00000000000..a56a7058a9a --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestComment.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.comment; +import static dev.morphia.query.filters.Filters.mod; + +public class TestComment extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/comment/example1 + */ + @Test(testName = "Attach a Comment to ``find``") + public void testExample1() { + ActionTestOptions options = new ActionTestOptions().skipDataCheck(true); + testQuery(options, (query) -> query.filter(mod("x", 2, 0), comment("Find even values."))); + } + + /** + * test data: dev/morphia/test/query/filters/comment/example2 + */ + @Test(testName = "Attach a Comment to an Aggregation Expression") + public void testExample2() { + // this example is for an aggregation + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestElemMatch.java b/core/src/test/java/dev/morphia/test/query/filters/TestElemMatch.java new file mode 100644 index 00000000000..3176cb13b24 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestElemMatch.java @@ -0,0 +1,40 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.elemMatch; +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.gte; +import static dev.morphia.query.filters.Filters.lt; + +public class TestElemMatch extends TemplatedTestBase { + /** + * test data: dev/morphia/test/query/filters/elemMatch/example1 + * + */ + @Test(testName = "Element Match") + public void testExample1() { + testQuery((query) -> query.filter(elemMatch("results", gte(80), lt(85)))); + } + + /** + * test data: dev/morphia/test/query/filters/elemMatch/example2 + * + */ + @Test(testName = "Array of Embedded Documents") + public void testExample2() { + testQuery((query) -> query.filter(elemMatch("results", eq("product", "xyz"), gte("score", 8)))); + } + + /** + * test data: dev/morphia/test/query/filters/elemMatch/example3 + * + */ + @Test(testName = "Single Query Condition") + public void testExample3() { + testQuery((query) -> query.filter(elemMatch("results", eq("product", "xyz")))); + } + +} diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestEq.java b/core/src/test/java/dev/morphia/test/query/filters/TestEq.java new file mode 100644 index 00000000000..831594e63a6 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestEq.java @@ -0,0 +1,62 @@ +package dev.morphia.test.query.filters; + +import java.util.List; +import java.util.regex.Pattern; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; + +public class TestEq extends TemplatedTestBase { + /** + * test data: dev/morphia/test/query/filters/eq/example1 + * + */ + @Test(testName = "Equals a Specified Value") + public void testExample1() { + testQuery((query) -> query.filter(eq("qty", 20))); + } + + /** + * test data: dev/morphia/test/query/filters/eq/example2 + * + */ + @Test(testName = "Field in Embedded Document Equals a Value") + public void testExample2() { + testQuery((query) -> query.filter(eq("item.name", "ab"))); + } + + /** + * test data: dev/morphia/test/query/filters/eq/example3 + * + */ + @Test(testName = "Array Element Equals a Value") + public void testExample3() { + testQuery((query) -> query.filter(eq("tags", "B"))); + } + + /** + * test data: dev/morphia/test/query/filters/eq/example4 + * + */ + @Test(testName = "Equals an Array Value") + public void testExample4() { + testQuery((query) -> query.filter(eq("tags", List.of("A", "B")) + + )); + } + + /** + * test data: dev/morphia/test/query/filters/eq/example5 + * + */ + @Test(testName = "Regex Match Behaviour") + public void testExample5() { + testQuery(new ActionTestOptions().removeIds(true), + (query) -> query.filter(eq("company", Pattern.compile("MongoDB")))); + } + +} diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestExists.java b/core/src/test/java/dev/morphia/test/query/filters/TestExists.java new file mode 100644 index 00000000000..1b9998a7c21 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestExists.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.exists; + +public class TestExists extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/exists/example1 + */ + @Test(testName = "Exists and Not Equal To") + public void testExample1() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(exists("saffron"))); + } + + /** + * test data: dev/morphia/test/query/filters/exists/example2 + */ + @Test(testName = "Null Values") + public void testExample2() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(exists("cinnamon").not() + + )); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestExpr.java b/core/src/test/java/dev/morphia/test/query/filters/TestExpr.java new file mode 100644 index 00000000000..5682b776319 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestExpr.java @@ -0,0 +1,32 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.aggregation.expressions.ComparisonExpressions.gt; +import static dev.morphia.aggregation.expressions.ComparisonExpressions.gte; +import static dev.morphia.aggregation.expressions.ComparisonExpressions.lt; +import static dev.morphia.aggregation.expressions.ConditionalExpressions.condition; +import static dev.morphia.aggregation.expressions.MathExpressions.multiply; +import static dev.morphia.query.filters.Filters.expr; + +public class TestExpr extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/expr/example1 + */ + @Test(testName = "Compare Two Fields from A Single Document") + public void testExample1() { + testQuery((query) -> query.filter(expr(gt("$spent", "$budget")))); + } + + /** + * test data: dev/morphia/test/query/filters/expr/example2 + */ + @Test(testName = "Using ``$expr`` With Conditional Statements", enabled = false, description = "parsing bug in Document's json parsing at $cond") + public void testExample2() { + testQuery((query) -> query + .filter(expr(lt(condition(gte("qty", 100), multiply("$price", 0.5), multiply("$price", 0.75)), 5.0)))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestGeoIntersects.java b/core/src/test/java/dev/morphia/test/query/filters/TestGeoIntersects.java new file mode 100644 index 00000000000..b317134c75c --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestGeoIntersects.java @@ -0,0 +1,37 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.NamedCoordinateReferenceSystem; +import com.mongodb.client.model.geojson.Polygon; +import com.mongodb.client.model.geojson.PolygonCoordinates; +import com.mongodb.client.model.geojson.Position; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.geoIntersects; +import static java.util.List.of; + +public class TestGeoIntersects extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/geoIntersects/example1 + */ + @Test(testName = "Intersects a Polygon") + public void testExample1() { + testQuery(new ActionTestOptions().skipDataCheck(true), (query) -> query.filter(geoIntersects("loc", + new Polygon(of(new Position(0, 0), new Position(3, 6), new Position(6, 1), new Position(0, 0)))))); + } + + /** + * test data: dev/morphia/test/query/filters/geoIntersects/example2 + */ + @Test(testName = "Intersects a \"Big\" Polygon") + public void testExample2() { + var exterior = new PolygonCoordinates(of(new Position(-100, 60), new Position(-100, 0), new Position(-100, -60), + new Position(100, -60), new Position(100, 60), new Position(-100, 60))); + testQuery(new ActionTestOptions().skipDataCheck(true), (query) -> query.filter(geoIntersects("loc", new Polygon( + new NamedCoordinateReferenceSystem("urn:x-mongodb:crs:strictwinding:EPSG:4326"), exterior)))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestGeoWithin.java b/core/src/test/java/dev/morphia/test/query/filters/TestGeoWithin.java new file mode 100644 index 00000000000..964da51d2bb --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestGeoWithin.java @@ -0,0 +1,39 @@ +package dev.morphia.test.query.filters; + +import java.util.List; + +import com.mongodb.client.model.geojson.NamedCoordinateReferenceSystem; +import com.mongodb.client.model.geojson.Polygon; +import com.mongodb.client.model.geojson.PolygonCoordinates; +import com.mongodb.client.model.geojson.Position; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.geoWithin; + +public class TestGeoWithin extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/geoWithin/example1 + */ + @Test(testName = "Within a Polygon") + public void testExample1() { + var points = List.of(new Position(0, 0), new Position(3, 6), new Position(6, 1), new Position(0, 0)); + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(geoWithin("loc", new Polygon(points)))); + } + + /** + * test data: dev/morphia/test/query/filters/geoWithin/example2 + */ + @Test(testName = "Within a \"Big\" Polygon") + public void testExample2() { + var coords = new PolygonCoordinates(List.of(new Position(-100, 60), new Position(-100, 0), + new Position(-100, -60), new Position(100, -60), new Position(100, 60), new Position(-100, 60))); + testQuery(new ActionTestOptions().skipDataCheck(true), (query) -> query.filter(geoWithin("loc", + new Polygon(new NamedCoordinateReferenceSystem("urn:x-mongodb:crs:strictwinding:EPSG:4326"), coords)))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestGt.java b/core/src/test/java/dev/morphia/test/query/filters/TestGt.java new file mode 100644 index 00000000000..6bd01550ab1 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestGt.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.query.updates.UpdateOperators; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.gt; + +public class TestGt extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/gt/example1 + */ + @Test(testName = "Match Document Fields") + public void testExample1() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(gt("quantity", 20))); + } + + /** + * test data: dev/morphia/test/query/filters/gt/example2 + */ + @Test(testName = "Perform an Update Based on Embedded Document Fields") + public void testExample2() { + testUpdate(new ActionTestOptions().removeIds(true), (query) -> query.filter(gt("carrier.fee", 2)), + UpdateOperators.set("price", 9.99)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestGte.java b/core/src/test/java/dev/morphia/test/query/filters/TestGte.java new file mode 100644 index 00000000000..3932c9dc8e6 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestGte.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.gte; +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestGte extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/gte/example1 + */ + @Test(testName = "Match Document Fields") + public void testExample1() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(gte("quantity", 20))); + } + + /** + * test data: dev/morphia/test/query/filters/gte/example2 + */ + @Test(testName = "Perform an Update Based on Embedded Document Fields") + public void testExample2() { + testUpdate(new ActionTestOptions().removeIds(true), (query) -> query.filter(gte("carrier.fee", 2)), + set("price", 9.99)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestIn.java b/core/src/test/java/dev/morphia/test/query/filters/TestIn.java new file mode 100644 index 00000000000..2e430746b62 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestIn.java @@ -0,0 +1,42 @@ +package dev.morphia.test.query.filters; + +import java.util.List; +import java.util.regex.Pattern; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.in; +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestIn extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/in/example1 + */ + @Test(testName = "Use the ``$in`` Operator to Match Values") + public void testExample1() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(in("quantity", List.of(5, 15)))); + } + + /** + * test data: dev/morphia/test/query/filters/in/example2 + */ + @Test(testName = "Use the ``$in`` Operator to Match Values in an Array") + public void testExample2() { + testUpdate(new ActionTestOptions().removeIds(true).orderMatters(false), + (query) -> query.filter(in("tags", List.of("home", "school"))), set("exclude", false)); + } + + /** + * test data: dev/morphia/test/query/filters/in/example3 + * + */ + @Test(testName = "Use the ``$in`` Operator with a Regular Expression") + public void testExample3() { + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(in("tags", List.of(Pattern.compile("^be"), Pattern.compile("^st"))))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestLt.java b/core/src/test/java/dev/morphia/test/query/filters/TestLt.java new file mode 100644 index 00000000000..0f894be1456 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestLt.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.lt; +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestLt extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/lt/example1 + */ + @Test(testName = "Match Document Fields") + public void testExample1() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(lt("quantity", 20))); + } + + /** + * test data: dev/morphia/test/query/filters/lt/example2 + */ + @Test(testName = "Perform an Update Based on Embedded Document Fields") + public void testExample2() { + testUpdate(new ActionTestOptions().removeIds(true), (query) -> query.filter(lt("carrier.fee", 20)), + set("price", 9.99)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestLte.java b/core/src/test/java/dev/morphia/test/query/filters/TestLte.java new file mode 100644 index 00000000000..9cba2cc32b6 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestLte.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.lte; +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestLte extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/lte/example1 + */ + @Test(testName = "Match Document Fields") + public void testExample1() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(lte("quantity", 20))); + } + + /** + * test data: dev/morphia/test/query/filters/lte/example2 + */ + @Test(testName = "Perform an Update Based on Embedded Document Fields") + public void testExample2() { + testUpdate(new ActionTestOptions().removeIds(true), (query) -> query.filter(lte("carrier.fee", 5)), + set("price", 9.99)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestMaxDistance.java b/core/src/test/java/dev/morphia/test/query/filters/TestMaxDistance.java new file mode 100644 index 00000000000..3da564fcb75 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestMaxDistance.java @@ -0,0 +1,22 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +public class TestMaxDistance extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/maxDistance/example1 + */ + @Test(testName = "main") + public void testExample1() { + // legacy coordinates just won't be supported for now + + /* + * testQuery(new QueryTestOptions().skipDataCheck(true), (query) -> + * query.filter( near("loc", new Point(new Position(-74, 40))), + * maxDistance("loc",10.0) )); + */ + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestMinDistance.java b/core/src/test/java/dev/morphia/test/query/filters/TestMinDistance.java new file mode 100644 index 00000000000..2bbc7a28e40 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestMinDistance.java @@ -0,0 +1,24 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +public class TestMinDistance extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/minDistance/example1 + */ + @Test(testName = "Use with ``$near``") + public void testExample1() { + // already tested elsewhere + } + + /** + * test data: dev/morphia/test/query/filters/minDistance/example2 + */ + @Test(testName = "Use with ``$nearSphere``") + public void testExample2() { + // legacy coordinates just won't be supported for now + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestMod.java b/core/src/test/java/dev/morphia/test/query/filters/TestMod.java new file mode 100644 index 00000000000..0e6b0aab279 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestMod.java @@ -0,0 +1,50 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.mod; + +public class TestMod extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/mod/example1 + */ + @Test(testName = "Use ``$mod`` to Select Documents") + public void testExample1() { + testQuery((query) -> query.filter(mod("qty", 4, 0))); + } + + /** + * test data: dev/morphia/test/query/filters/mod/example2 + */ + @Test(testName = "Not Enough Elements Error") + public void testExample2() { + // ignored + } + + /** + * test data: dev/morphia/test/query/filters/mod/example3 + */ + @Test(testName = "Too Many Elements Error") + public void testExample3() { + // ignored + } + + /** + * test data: dev/morphia/test/query/filters/mod/example4 + */ + @Test(testName = "Floating Point Arguments") + public void testExample4() { + testQuery((query) -> query.filter(mod("qty", 4.0, 0.0))); + } + + /** + * test data: dev/morphia/test/query/filters/mod/example5 + */ + @Test(testName = "Negative Dividend") + public void testExample5() { + testQuery((query) -> query.filter(mod("qty", -4, -0))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestNe.java b/core/src/test/java/dev/morphia/test/query/filters/TestNe.java new file mode 100644 index 00000000000..92b368245e1 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestNe.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.ne; +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestNe extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/ne/example1 + */ + @Test(testName = "Match Document Fields That Are Not Equal") + public void testExample1() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(ne("quantity", 20))); + } + + /** + * test data: dev/morphia/test/query/filters/ne/example2 + */ + @Test(testName = "Update Based on Not Equal Embedded Document Fields") + public void testExample2() { + testUpdate(new ActionTestOptions().removeIds(true), (query) -> query.filter(ne("carrier.fee", 1)), + set("price", 9.99)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestNear.java b/core/src/test/java/dev/morphia/test/query/filters/TestNear.java new file mode 100644 index 00000000000..526f920b838 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestNear.java @@ -0,0 +1,36 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Position; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.near; + +public class TestNear extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/near/example1 + */ + @Test(testName = "Query on GeoJSON Data") + public void testExample1() { + testQuery(new ActionTestOptions().skipDataCheck(true), (query) -> query.filter( + near("location", new Point(new Position(-73.9667, 40.78))).minDistance(1000.0).maxDistance(5000.0))); + } + + /** + * test data: dev/morphia/test/query/filters/near/example2 + */ + @Test(testName = "Query on Legacy Coordinates") + public void testExample2() { + // legacy coordinates just won't be supported for now + /* + * testQuery(new QueryTestOptions().skipDataCheck(true), (query) -> + * query.filter( near("location", new Point(new Position(-73.9667, 40.78))) + * .maxDistance(0.1) )); + */ + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestNearSphere.java b/core/src/test/java/dev/morphia/test/query/filters/TestNearSphere.java new file mode 100644 index 00000000000..e749004f44b --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestNearSphere.java @@ -0,0 +1,37 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Position; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.nearSphere; + +public class TestNearSphere extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/nearSphere/example1 + */ + @Test(testName = "Specify Center Point Using GeoJSON") + public void testExample1() { + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(nearSphere("location", new Point(new Position(-73.9667, 40.78))) + .minDistance(1000.0).maxDistance(5000.0))); + } + + /** + * test data: dev/morphia/test/query/filters/nearSphere/example2 + */ + @Test(testName = "Specify Center Point Using Legacy Coordinates") + public void testExample2() { + // legacy coordinates just won't be supported for now + /* + * testQuery(new QueryTestOptions().skipDataCheck(true), (query) -> + * query.filter( nearSphere("location", new Point(new Position(-73.9667, + * 40.78))) .maxDistance(0.10) )); + */ + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestNin.java b/core/src/test/java/dev/morphia/test/query/filters/TestNin.java new file mode 100644 index 00000000000..9f36292d368 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestNin.java @@ -0,0 +1,31 @@ +package dev.morphia.test.query.filters; + +import java.util.List; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.nin; +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestNin extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/nin/example1 + */ + @Test(testName = "Select on Unmatching Documents") + public void testExample1() { + testQuery(new ActionTestOptions().removeIds(true), (query) -> query.filter(nin("quantity", List.of(5, 15)))); + } + + /** + * test data: dev/morphia/test/query/filters/nin/example2 + */ + @Test(testName = "Select on Elements Not in an Array") + public void testExample2() { + testUpdate(new ActionTestOptions().removeIds(true), (query) -> query.filter(nin("tags", List.of("school"))), + set("exclude", true)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestNor.java b/core/src/test/java/dev/morphia/test/query/filters/TestNor.java new file mode 100644 index 00000000000..12ffda880ae --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestNor.java @@ -0,0 +1,43 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.exists; +import static dev.morphia.query.filters.Filters.lt; +import static dev.morphia.query.filters.Filters.nor; + +public class TestNor extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/nor/example1 + */ + @Test(testName = "``$nor`` Query with Two Expressions") + public void testExample1() { + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(nor(eq("price", 1.99), eq("sale", true)))); + } + + /** + * test data: dev/morphia/test/query/filters/nor/example2 + */ + @Test(testName = "``$nor`` and Additional Comparisons") + public void testExample2() { + testQuery(new ActionTestOptions().skipDataCheck(true), + (query) -> query.filter(nor(eq("price", 1.99), lt("qty", 20), eq("sale", true)))); + } + + /** + * test data: dev/morphia/test/query/filters/nor/example3 + */ + @Test(testName = "``$nor`` and ``$exists``") + public void testExample3() { + testQuery(new ActionTestOptions().skipDataCheck(true), (query) -> query + .filter(nor(eq("price", 1.99), exists("price").not(), eq("sale", true), exists("sale").not()) + + )); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestPolygon.java b/core/src/test/java/dev/morphia/test/query/filters/TestPolygon.java new file mode 100644 index 00000000000..c8ce28c2e31 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestPolygon.java @@ -0,0 +1,24 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Position; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.polygon; + +public class TestPolygon extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/polygon/example1 + */ + @Test(testName = "main") + public void testExample1() { + Point[] point = new Point[] { new Point(new Position(0, 0)), new Point(new Position(3, 6)), + new Point(new Position(6, 0)), }; + testQuery(new ActionTestOptions().skipDataCheck(true), (query) -> query.filter(polygon("loc", point))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestRand.java b/core/src/test/java/dev/morphia/test/query/filters/TestRand.java new file mode 100644 index 00000000000..a655d7b4817 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestRand.java @@ -0,0 +1,38 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.query.FindOptions; +import dev.morphia.query.updates.UpdateOperators; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.aggregation.expressions.ComparisonExpressions.lt; +import static dev.morphia.aggregation.expressions.MathExpressions.floor; +import static dev.morphia.aggregation.expressions.MathExpressions.multiply; +import static dev.morphia.aggregation.expressions.Miscellaneous.rand; +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.expr; + +public class TestRand extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/rand/example1 + */ + @Test(testName = "Generate Random Data Points") + public void testExample1() { + ActionTestOptions options = new ActionTestOptions().skipDataCheck(true) + .findOptions(new FindOptions().projection().include("name", "registered")); + testUpdate(options, (query) -> query, UpdateOperators.set("amount", floor(multiply(rand(), 100)))); + } + + /** + * test data: dev/morphia/test/query/filters/rand/example2 + */ + @Test(testName = "Select Random Items From a Collection") + public void testExample2() { + ActionTestOptions options = new ActionTestOptions().orderMatters(false).removeIds(true).skipDataCheck(true) + .findOptions(new FindOptions().projection().include("name", "registered")); + testQuery(options, (query) -> query.filter(eq("district", 3), expr(lt(0.5, rand())))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestRegex.java b/core/src/test/java/dev/morphia/test/query/filters/TestRegex.java new file mode 100644 index 00000000000..59795b3adc6 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestRegex.java @@ -0,0 +1,72 @@ +package dev.morphia.test.query.filters; + +import java.util.regex.Pattern; + +import dev.morphia.test.ServerVersion; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.regex; + +public class TestRegex extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/regex/example1 + */ + @Test(testName = "Perform a ``LIKE`` Match") + public void testExample1() { + testQuery((query) -> query.filter(regex("sku", Pattern.compile("789$")))); + } + + /** + * test data: dev/morphia/test/query/filters/regex/example2 + */ + @Test(testName = "Perform Case-Insensitive Regular Expression Match") + public void testExample2() { + testQuery((query) -> query.filter(regex("sku", Pattern.compile("^ABC")).caseInsensitive())); + } + + /** + * test data: dev/morphia/test/query/filters/regex/example3 + */ + @Test(testName = "Multiline Match for Lines Starting with Specified Pattern") + public void testExample3() { + testQuery((query) -> query.filter(regex("description", Pattern.compile("^S")).multiline())); + } + + /** + * test data: dev/morphia/test/query/filters/regex/example4 + */ + @Test(testName = "Use the ``.`` Dot Character to Match New Line") + public void testExample4() { + testQuery( + (query) -> query.filter(regex("description", Pattern.compile("m.*line")).special().caseInsensitive())); + } + + /** + * test data: dev/morphia/test/query/filters/regex/example5 + */ + @Test(testName = "Ignore White Spaces in Pattern") + public void testExample5() { + testQuery(new ActionTestOptions().serverVersion(ServerVersion.v70).skipActionCheck(true), (query) -> query + .filter(regex("sku", Pattern.compile("abc #category code\n123 #item number")).extended())); + } + + /** + * test data: dev/morphia/test/query/filters/regex/example6 + */ + @Test(testName = "Use a Regular Expression to Match Case in Strings") + public void testExample6() { + testQuery((query) -> query.filter(regex("sku", Pattern.compile("(?i)a(?-i)bc")))); + } + + /** + * test data: dev/morphia/test/query/filters/regex/example7 + */ + @Test(testName = "Extend Regex Options to Match Characters Outside of ASCII") + public void testExample7() { + testQuery((query) -> query.filter(regex("artist", Pattern.compile("\\byster")))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestText.java b/core/src/test/java/dev/morphia/test/query/filters/TestText.java new file mode 100644 index 00000000000..44692b0f690 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestText.java @@ -0,0 +1,94 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.query.FindOptions; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.Meta.textScore; +import static dev.morphia.query.filters.Filters.*; + +public class TestText extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/text/example1 + */ + @Test(testName = "``$text`` with a Single Word") + public void testExample1() { + testQuery((query) -> query.filter(text("coffee"))); + } + + /** + * test data: dev/morphia/test/query/filters/text/example2 + */ + @Test(testName = "Match Any of the ``$search`` Terms") + public void testExample2() { + testQuery(new ActionTestOptions().orderMatters(false), (query) -> query.filter(text("bake coffee cake") + + )); + } + + /** + * test data: dev/morphia/test/query/filters/text/example3 + */ + @Test(testName = "``$text`` with a Phrase") + public void testExample3() { + testQuery(new ActionTestOptions().orderMatters(false), (query) -> query.filter(text("\"coffee shop\"") + + )); + } + + /** + * test data: dev/morphia/test/query/filters/text/example4 + */ + @Test(testName = "Exclude Documents That Contain a Term") + public void testExample4() { + testQuery(new ActionTestOptions().orderMatters(false), (query) -> query.filter(text("coffee -shop") + + )); + } + + /** + * test data: dev/morphia/test/query/filters/text/example5 + */ + @Test(testName = "Query a Different Language") + public void testExample5() { + testQuery(new ActionTestOptions().orderMatters(false), (query) -> query.filter(text("leche").language("es"))); + } + + /** + * test data: dev/morphia/test/query/filters/text/example6 + */ + @Test(testName = "Case and Diacritic Insensitivity") + public void testExample6() { + testQuery(new ActionTestOptions().orderMatters(false), (query) -> query.filter(text("сы́рники CAFÉS"))); + } + + /** + * test data: dev/morphia/test/query/filters/text/example7 + */ + @Test(testName = "Case Sensitivity") + public void testExample7() { + testQuery((query) -> query.filter(text("Coffee").caseSensitive(true))); + } + + /** + * test data: dev/morphia/test/query/filters/text/example8 + */ + @Test(testName = "Diacritic Sensitive Search") + public void testExample8() { + testQuery(new ActionTestOptions().orderMatters(false), + (query) -> query.filter(text("CAFÉ").diacriticSensitive(true))); + } + + /** + * test data: dev/morphia/test/query/filters/text/example9 + */ + @Test(testName = "Relevance Score Examples") + public void testExample9() { + ActionTestOptions options = new ActionTestOptions() + .findOptions(new FindOptions().projection().project(textScore("score"))); + testQuery(options, (query) -> query.filter(text("cake"))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestType.java b/core/src/test/java/dev/morphia/test/query/filters/TestType.java new file mode 100644 index 00000000000..276be10e14a --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestType.java @@ -0,0 +1,35 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.query.Type; +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.type; + +public class TestType extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/type/example1 + */ + @Test(testName = "Querying by Data Type") + public void testExample1() { + testQuery((query) -> query.filter(type("zipCode", Type.STRING))); + } + + /** + * test data: dev/morphia/test/query/filters/type/example2 + */ + @Test(testName = "Querying by Multiple Data Types") + public void testExample2() { + testQuery((query) -> query.filter(type("classAverage", Type.STRING, Type.DOUBLE))); + } + + /** + * test data: dev/morphia/test/query/filters/type/example3 + */ + @Test(testName = "Querying by MinKey and MaxKey") + public void testExample3() { + testQuery((query) -> query.filter(type("grades.grade", Type.MIN_KEY))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestWhere.java b/core/src/test/java/dev/morphia/test/query/filters/TestWhere.java new file mode 100644 index 00000000000..de6400f2d6d --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestWhere.java @@ -0,0 +1,22 @@ +package dev.morphia.test.query.filters; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.where; + +public class TestWhere extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/filters/where/example1 + */ + @Test(testName = "main") + public void testExample1() { + testQuery(new ActionTestOptions().skipActionCheck(true), (query) -> query.filter(where(""" + function() { + return (hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994") + }"""))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestAddToSet.java b/core/src/test/java/dev/morphia/test/query/updates/TestAddToSet.java new file mode 100644 index 00000000000..5ac89b3d09d --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestAddToSet.java @@ -0,0 +1,38 @@ +package dev.morphia.test.query.updates; + +import java.util.List; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.addToSet; + +public class TestAddToSet extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/addToSet/example1 + */ + @Test(testName = "Add to Array") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), addToSet("tags", "accessories")); + } + + /** + * test data: dev/morphia/test/query/updates/addToSet/example2 + */ + @Test(testName = "Value Already Exists") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 1)), addToSet("tags", "camera")); + } + + /** + * test data: dev/morphia/test/query/updates/addToSet/example3 + */ + @Test(testName = "``$each`` Modifier") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 2)), + addToSet("tags", List.of("camera", "electronics", "accessories"))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestBit.java b/core/src/test/java/dev/morphia/test/query/updates/TestBit.java new file mode 100644 index 00000000000..4332522abfc --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestBit.java @@ -0,0 +1,37 @@ +package dev.morphia.test.query.updates; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.and; +import static dev.morphia.query.updates.UpdateOperators.or; +import static dev.morphia.query.updates.UpdateOperators.xor; + +public class TestBit extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/bit/example1 + */ + @Test(testName = "Bitwise AND") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), and("expdata", 10)); + } + + /** + * test data: dev/morphia/test/query/updates/bit/example2 + */ + @Test(testName = "Bitwise OR") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 2)), or("expdata", 5)); + } + + /** + * test data: dev/morphia/test/query/updates/bit/example3 + */ + @Test(testName = "Bitwise XOR") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 3)), xor("expdata", 5)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestCurrentDate.java b/core/src/test/java/dev/morphia/test/query/updates/TestCurrentDate.java new file mode 100644 index 00000000000..325f9de8bc5 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestCurrentDate.java @@ -0,0 +1,33 @@ +package dev.morphia.test.query.updates; + +import dev.morphia.query.updates.CurrentDateOperator.TypeSpecification; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.currentDate; +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestCurrentDate extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/currentDate/example1 + */ + @Test(testName = "main") + public void testExample1() { + testUpdate(new ActionTestOptions().skipDataCheck(true), (query) -> query.filter(eq("_id", 1)), + currentDate("lastModified"), currentDate("cancellation.date").type(TypeSpecification.TIMESTAMP), + set("cancellation.reason", "user request"), set("status", "D")); + } + + /** + * test data: dev/morphia/test/query/updates/currentDate/example2 + */ + @Test(testName = "Aggregation Alternative to ``$currentDate``") + public void testExample2() { + // this one isn't an operator test as such and updates with a pipeline are + // tested elsewhere + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestEach.java b/core/src/test/java/dev/morphia/test/query/updates/TestEach.java new file mode 100644 index 00000000000..df6968e3760 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestEach.java @@ -0,0 +1,31 @@ +package dev.morphia.test.query.updates; + +import java.util.List; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.addToSet; +import static dev.morphia.query.updates.UpdateOperators.push; + +public class TestEach extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/each/example1 + */ + @Test(testName = "Use ``$each`` with ``$push`` Operator") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), push("scores", List.of(90, 92, 85))); + } + + /** + * test data: dev/morphia/test/query/updates/each/example2 + */ + @Test(testName = "Use ``$each`` with ``$addToSet`` Operator") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 2)), + addToSet("tags", List.of("camera", "electronics", "accessories"))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestInc.java b/core/src/test/java/dev/morphia/test/query/updates/TestInc.java new file mode 100644 index 00000000000..6783c16de53 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestInc.java @@ -0,0 +1,19 @@ +package dev.morphia.test.query.updates; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.inc; + +public class TestInc extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/inc/example1 + */ + @Test(testName = "main") + public void testExample1() { + testUpdate((query) -> query.filter(eq("sku", "abc123")), inc("quantity", -2), inc("metrics.orders", 1)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestMax.java b/core/src/test/java/dev/morphia/test/query/updates/TestMax.java new file mode 100644 index 00000000000..78b9a6f44b9 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestMax.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.updates; + +import java.time.LocalDate; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.max; + +public class TestMax extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/max/example1 + */ + @Test(testName = "Use ``$max`` to Compare Numbers") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), max("highScore", 950)); + } + + /** + * test data: dev/morphia/test/query/updates/max/example2 + */ + @Test(testName = "Use ``$max`` to Compare Dates") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 1)), max("dateExpired", LocalDate.of(2013, 9, 30))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestMin.java b/core/src/test/java/dev/morphia/test/query/updates/TestMin.java new file mode 100644 index 00000000000..5376c5f1de8 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestMin.java @@ -0,0 +1,29 @@ +package dev.morphia.test.query.updates; + +import java.time.LocalDate; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.min; + +public class TestMin extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/min/example1 + */ + @Test(testName = "Use ``$min`` to Compare Numbers") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), min("lowScore", 150)); + } + + /** + * test data: dev/morphia/test/query/updates/min/example2 + */ + @Test(testName = "Use ``$min`` to Compare Dates") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 1)), min("dateEntered", LocalDate.of(2013, 9, 25))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestMul.java b/core/src/test/java/dev/morphia/test/query/updates/TestMul.java new file mode 100644 index 00000000000..80cc6234893 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestMul.java @@ -0,0 +1,35 @@ +package dev.morphia.test.query.updates; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.mul; + +public class TestMul extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/mul/example1 + */ + @Test(testName = "Multiply the Value of a Field") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), mul("price", 1.25), mul("quantity", 2)); + } + + /** + * test data: dev/morphia/test/query/updates/mul/example2 + */ + @Test(testName = "Apply ``$mul`` Operator to a Non-existing Field") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 2)), mul("price", 100.0)); + } + + /** + * test data: dev/morphia/test/query/updates/mul/example3 + */ + @Test(testName = "Multiply Mixed Numeric Types") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 3)), mul("price", 5)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestPop.java b/core/src/test/java/dev/morphia/test/query/updates/TestPop.java new file mode 100644 index 00000000000..11f99746141 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestPop.java @@ -0,0 +1,27 @@ +package dev.morphia.test.query.updates; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.pop; + +public class TestPop extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/pop/example1 + */ + @Test(testName = "Remove the First Item of an Array") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), pop("scores").removeFirst()); + } + + /** + * test data: dev/morphia/test/query/updates/pop/example2 + */ + @Test(testName = "Remove the Last Item of an Array") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 10)), pop("scores")); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestPosition.java b/core/src/test/java/dev/morphia/test/query/updates/TestPosition.java new file mode 100644 index 00000000000..aad51b6e60a --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestPosition.java @@ -0,0 +1,37 @@ +package dev.morphia.test.query.updates; + +import java.util.List; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.push; + +public class TestPosition extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/position/example1 + */ + @Test(testName = "Add Elements at the Start of the Array") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), push("scores", List.of(50, 60, 70)).position(0)); + } + + /** + * test data: dev/morphia/test/query/updates/position/example2 + */ + @Test(testName = "Add Elements to the Middle of the Array") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 2)), push("scores", List.of(20, 30)).position(2)); + } + + /** + * test data: dev/morphia/test/query/updates/position/example3 + */ + @Test(testName = "Use a Negative Array Index (Position) to Add Elements to the Array") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 3)), push("scores", List.of(90, 80)).position(-2)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestPositional.java b/core/src/test/java/dev/morphia/test/query/updates/TestPositional.java new file mode 100644 index 00000000000..4c550f0579e --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestPositional.java @@ -0,0 +1,58 @@ +package dev.morphia.test.query.updates; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.elemMatch; +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.gt; +import static dev.morphia.query.filters.Filters.lte; +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestPositional extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/positional/example1 + */ + @Test(testName = "Update Values in an Array") + public void testExample1() { + testUpdate(new ActionTestOptions().skipDataCheck(true), (query) -> query.filter(eq("_id", 1), eq("grades", 80)), + set("grades.$", 82)); + } + + /** + * test data: dev/morphia/test/query/updates/positional/example2 + */ + @Test(testName = "Update Documents in an Array") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 4), eq("grades.grade", 85)), set("grades.$.std", 6)); + } + + /** + * test data: dev/morphia/test/query/updates/positional/example3 + */ + @Test(testName = "Update Embedded Documents Using Multiple Field Matches") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 5), elemMatch("grades", lte("grade", 90), gt("mean", 80))), + set("grades.$.std", 6)); + } + + /** + * test data: dev/morphia/test/query/updates/positional/example4 + */ + @Test(testName = "Update with Multiple Array Matches") + public void testExample4() { + testUpdate((query) -> query.filter(eq("activity_ids", 1), eq("grades", 95), eq("deans_list", 2021)), + set("deans_list.$", 2022)); + } + + /** + * test data: dev/morphia/test/query/updates/positional/example5 + */ + @Test(testName = "Update Nested Arrays in Conjunction with ``$[]``") + public void testExample5() { + // docs out of date? + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestPull.java b/core/src/test/java/dev/morphia/test/query/updates/TestPull.java new file mode 100644 index 00000000000..6e0fa0da360 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestPull.java @@ -0,0 +1,57 @@ +package dev.morphia.test.query.updates; + +import java.util.List; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.elemMatch; +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.gte; +import static dev.morphia.query.filters.Filters.in; +import static dev.morphia.query.updates.UpdateOperators.pull; + +public class TestPull extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/pull/example1 + */ + @Test(testName = "Remove All Items That Equal a Specified Value") + public void testExample1() { + testUpdate((query) -> query.filter(), pull("fruits", in(List.of("apples", "oranges"))), + pull("vegetables", "carrots")); + } + + /** + * test data: dev/morphia/test/query/updates/pull/example2 + */ + @Test(testName = "Remove All Items That Match a Specified ``$pull`` Condition") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 1)), pull("votes", gte(6))); + } + + /** + * test data: dev/morphia/test/query/updates/pull/example3 + */ + @Test(testName = "Remove All Items That Match a Specified ``$pull`` Condition With :method:`~db.collection.bulkWrite()`", enabled = false, description = "test is irrelevant to Morphia") + public void testExample3() { + + } + + /** + * test data: dev/morphia/test/query/updates/pull/example4 + */ + @Test(testName = "Remove Items from an Array of Documents") + public void testExample4() { + testUpdate((query) -> query.filter(), pull("results", eq("score", 8), eq("item", "B"))); + } + + /** + * test data: dev/morphia/test/query/updates/pull/example5 + */ + @Test(testName = "Remove Documents from Nested Arrays") + public void testExample5() { + testUpdate((query) -> query.filter(), pull("results", elemMatch("answers", eq("q", 2), gte("a", 8)))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestPullAll.java b/core/src/test/java/dev/morphia/test/query/updates/TestPullAll.java new file mode 100644 index 00000000000..1723e35fe49 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestPullAll.java @@ -0,0 +1,21 @@ +package dev.morphia.test.query.updates; + +import java.util.List; + +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.pullAll; + +public class TestPullAll extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/pullAll/example1 + */ + @Test(testName = "main") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), pullAll("scores", List.of(0, 5))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestPush.java b/core/src/test/java/dev/morphia/test/query/updates/TestPush.java new file mode 100644 index 00000000000..fcd677f0c70 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestPush.java @@ -0,0 +1,51 @@ +package dev.morphia.test.query.updates; + +import java.util.List; + +import dev.morphia.UpdateOptions; +import dev.morphia.test.TemplatedTestBase; + +import org.testng.annotations.Test; + +import static dev.morphia.aggregation.expressions.Expressions.document; +import static dev.morphia.query.Sort.descending; +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.push; + +public class TestPush extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/push/example1 + */ + @Test(testName = "Append a Value to an Array") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), push("scores", 89)); + } + + /** + * test data: dev/morphia/test/query/updates/push/example2 + */ + @Test(testName = "Append a Value to Arrays in Multiple Documents") + public void testExample2() { + UpdateOptions updateOptions = new UpdateOptions().multi(true); + testUpdate((query) -> query.filter(), push("scores", 95)); + } + + /** + * test data: dev/morphia/test/query/updates/push/example3 + */ + @Test(testName = "Append Multiple Values to an Array") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 1)), push("scores", List.of(90, 92, 85))); + } + + /** + * test data: dev/morphia/test/query/updates/push/example4 + */ + @Test(testName = "Use ``$push`` Operator with Multiple Modifiers") + public void testExample4() { + testUpdate((query) -> query.filter(eq("_id", 5)), + push("quizzes", List.of(document("wk", 5).field("score", 8), document("wk", 6).field("score", 7), + document("wk", 7).field("score", 6))).sort(descending("score")).slice(3)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestRename.java b/core/src/test/java/dev/morphia/test/query/updates/TestRename.java new file mode 100644 index 00000000000..b5be4bfadc2 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestRename.java @@ -0,0 +1,38 @@ +package dev.morphia.test.query.updates; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.filters.Filters.ne; +import static dev.morphia.query.updates.UpdateOperators.rename; + +public class TestRename extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/rename/example1 + */ + @Test(testName = "Rename a Field") + public void testExample1() { + testUpdate(new ActionTestOptions().skipDataCheck(true), (query) -> query.filter(ne("nmae", null)), + rename("nmae", "name")); + } + + /** + * test data: dev/morphia/test/query/updates/rename/example2 + */ + @Test(testName = "Rename a Field in an Embedded Document") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 1)), rename("name.first", "name.fname")); + } + + /** + * test data: dev/morphia/test/query/updates/rename/example3 + */ + @Test(testName = "Rename a Field That Does Not Exist") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 1)), rename("wife", "spouse")); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestSet.java b/core/src/test/java/dev/morphia/test/query/updates/TestSet.java new file mode 100644 index 00000000000..4da2395b03b --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestSet.java @@ -0,0 +1,43 @@ +package dev.morphia.test.query.updates; + +import java.util.List; +import java.util.Map; + +import dev.morphia.query.filters.Filters; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.updates.UpdateOperators.set; + +public class TestSet extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/set/example1 + */ + @Test(testName = "Set Top-Level Fields") + public void testExample1() { + // skip the action check because the Map order varies + testUpdate(new ActionTestOptions().skipActionCheck(true), (query) -> query.filter(Filters.eq("_id", 100)), + set("quantity", 500), set("details", Map.of("make", "Fashionaires", "model", "2600")), + set("tags", List.of("coats", "outerwear", "clothing"))); + } + + /** + * test data: dev/morphia/test/query/updates/set/example2 + */ + @Test(testName = "Set Fields in Embedded Documents") + public void testExample2() { + testUpdate((query) -> query.filter(Filters.eq("_id", 100)), set("details.make", "Kustom Kidz")); + } + + /** + * test data: dev/morphia/test/query/updates/set/example3 + */ + @Test(testName = "Set Elements in Arrays") + public void testExample3() { + testUpdate((query) -> query.filter(Filters.eq("_id", 100)), set("tags.1", "rain gear"), + set("ratings.0.rating", 2)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestSetOnInsert.java b/core/src/test/java/dev/morphia/test/query/updates/TestSetOnInsert.java new file mode 100644 index 00000000000..cada106405b --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestSetOnInsert.java @@ -0,0 +1,26 @@ +package dev.morphia.test.query.updates; + +import java.util.Map; + +import dev.morphia.UpdateOptions; +import dev.morphia.query.filters.Filters; +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.updates.UpdateOperators.set; +import static dev.morphia.query.updates.UpdateOperators.setOnInsert; + +public class TestSetOnInsert extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/setOnInsert/example1 + */ + @Test(testName = "main") + public void testExample1() { + var options = new ActionTestOptions().skipDataCheck(true).updateOptions(new UpdateOptions().upsert(true)); + testUpdate(options, (query) -> query.filter(Filters.eq("_id", 1)), set("item", "apple"), + setOnInsert(Map.of("defaultQty", 100))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestSlice.java b/core/src/test/java/dev/morphia/test/query/updates/TestSlice.java new file mode 100644 index 00000000000..0b90c671f9b --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestSlice.java @@ -0,0 +1,52 @@ +package dev.morphia.test.query.updates; + +import java.util.List; +import java.util.Map; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.Sort.descending; +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.push; + +public class TestSlice extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/slice/example1 + */ + @Test(testName = "Slice from the End of the Array") + public void testExample1() { + testUpdate((query) -> query.filter(eq("_id", 1)), push("scores", List.of(80, 78, 86)).slice(-5)); + } + + /** + * test data: dev/morphia/test/query/updates/slice/example2 + */ + @Test(testName = "Slice from the Front of the Array") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 2)), push("scores", List.of(100, 20)).slice(3)); + } + + /** + * test data: dev/morphia/test/query/updates/slice/example3 + */ + @Test(testName = "Update Array Using Slice Only") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 3)), push("scores", List.of()).slice(-3)); + } + + /** + * test data: dev/morphia/test/query/updates/slice/example4 + */ + @Test(testName = "Use ``$slice`` with Other ``$push`` Modifiers") + public void testExample4() { + // the Map order throws off structural checks + testUpdate(new ActionTestOptions().skipActionCheck(true), (query) -> query.filter(eq("_id", 5)), + push("quizzes", + List.of(Map.of("wk", 5, "score", 8), Map.of("wk", 6, "score", 7), Map.of("wk", 7, "score", 6))) + .sort(descending("score")).slice(3)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestSort.java b/core/src/test/java/dev/morphia/test/query/updates/TestSort.java new file mode 100644 index 00000000000..ea2a047f725 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestSort.java @@ -0,0 +1,57 @@ +package dev.morphia.test.query.updates; + +import java.util.List; +import java.util.Map; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.Sort.ascending; +import static dev.morphia.query.Sort.descending; +import static dev.morphia.query.filters.Filters.*; +import static dev.morphia.query.updates.UpdateOperators.push; + +public class TestSort extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/sort/example1 + */ + @Test(testName = "Sort Array of Documents by a Field in the Documents") + public void testExample1() { + // the Map order throws off structural checks + testUpdate(new ActionTestOptions().skipActionCheck(true), (query) -> query.filter(eq("_id", 1)), + push("quizzes", + List.of(Map.of("id", 3, "score", 8), Map.of("id", 4, "score", 7), Map.of("id", 5, "score", 6))) + .sort(ascending("score"))); + } + + /** + * test data: dev/morphia/test/query/updates/sort/example2 + */ + @Test(testName = "Sort Array Elements That Are Not Documents") + public void testExample2() { + testUpdate((query) -> query.filter(eq("_id", 2)), push("tests", List.of(40, 60)).sort(1)); + } + + /** + * test data: dev/morphia/test/query/updates/sort/example3 + */ + @Test(testName = "Update Array Using Sort Only") + public void testExample3() { + testUpdate((query) -> query.filter(eq("_id", 3)), push("tests", List.of()).sort(-1)); + } + + /** + * test data: dev/morphia/test/query/updates/sort/example4 + */ + @Test(testName = "Use ``$sort`` with Other ``$push`` Modifiers") + public void testExample4() { + // the Map order throws off structural checks + testUpdate(new ActionTestOptions().skipActionCheck(true), (query) -> query.filter(eq("_id", 5)), + push("quizzes", + List.of(Map.of("wk", 5, "score", 8), Map.of("wk", 6, "score", 7), Map.of("wk", 7, "score", 6))) + .sort(descending("score")).slice(3)); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/updates/TestUnset.java b/core/src/test/java/dev/morphia/test/query/updates/TestUnset.java new file mode 100644 index 00000000000..b14b16bd9c6 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/updates/TestUnset.java @@ -0,0 +1,21 @@ +package dev.morphia.test.query.updates; + +import dev.morphia.test.TemplatedTestBase; +import dev.morphia.test.util.ActionTestOptions; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.eq; +import static dev.morphia.query.updates.UpdateOperators.unset; + +public class TestUnset extends TemplatedTestBase { + + /** + * test data: dev/morphia/test/query/updates/unset/example1 + */ + @Test(testName = "main") + public void testExample1() { + testUpdate(new ActionTestOptions().removeIds(true).orderMatters(false), + (query) -> query.filter(eq("sku", "unknown")), unset("quantity", "instock")); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/util/ActionTestOptions.java b/core/src/test/java/dev/morphia/test/util/ActionTestOptions.java new file mode 100644 index 00000000000..63229114fa8 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/util/ActionTestOptions.java @@ -0,0 +1,98 @@ +package dev.morphia.test.util; + +import dev.morphia.UpdateOptions; +import dev.morphia.query.FindOptions; +import dev.morphia.test.DriverVersion; +import dev.morphia.test.ServerVersion; + +import static dev.morphia.test.ServerVersion.ANY; + +public class ActionTestOptions { + private FindOptions findOptions; + + private DriverVersion minDriver = DriverVersion.v41; + + private boolean orderMatters = true; + + private boolean removeIds = false; + + private ServerVersion serverVersion = ANY; + + private boolean skipActionCheck; + + private boolean skipDataCheck = false; + + private UpdateOptions updateOptions; + + public FindOptions findOptions() { + return findOptions; + } + + public ActionTestOptions findOptions(FindOptions findOptions) { + this.findOptions = findOptions; + return this; + } + + public DriverVersion minDriver() { + return minDriver; + } + + public ActionTestOptions minDriver(DriverVersion minDriver) { + this.minDriver = minDriver; + return this; + } + + public boolean orderMatters() { + return orderMatters; + } + + public ActionTestOptions orderMatters(boolean orderMatters) { + this.orderMatters = orderMatters; + return this; + } + + public boolean removeIds() { + return removeIds; + } + + public ActionTestOptions removeIds(boolean removeIds) { + this.removeIds = removeIds; + return this; + } + + public ServerVersion serverVersion() { + return serverVersion; + } + + public ActionTestOptions serverVersion(ServerVersion serverVersion) { + this.serverVersion = serverVersion; + return this; + } + + public ActionTestOptions skipActionCheck(boolean skipActionCheck) { + this.skipActionCheck = skipActionCheck; + return this; + } + + public boolean skipActionCheck() { + return skipActionCheck; + } + + public boolean skipDataCheck() { + return skipDataCheck; + } + + public ActionTestOptions skipDataCheck(boolean skipDataCheck) { + this.skipDataCheck = skipDataCheck; + return this; + } + + public UpdateOptions updateOptions() { + return updateOptions != null ? updateOptions : new UpdateOptions(); + } + + public ActionTestOptions updateOptions(UpdateOptions updateOptions) { + this.updateOptions = updateOptions; + return this; + } +} diff --git a/core/src/test/java/dev/morphia/test/util/ObjectComparanator.java b/core/src/test/java/dev/morphia/test/util/ObjectComparanator.java index 7b205d0b6e0..94e1f3dff62 100644 --- a/core/src/test/java/dev/morphia/test/util/ObjectComparanator.java +++ b/core/src/test/java/dev/morphia/test/util/ObjectComparanator.java @@ -3,7 +3,12 @@ import java.util.LinkedHashSet; import java.util.Set; +import org.bson.types.Decimal128; + +import static dev.morphia.aggregation.expressions.MathExpressions.abs; +import static java.lang.Math.abs; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; public class ObjectComparanator extends BaseComparanator { private final Object first; @@ -13,12 +18,9 @@ public class ObjectComparanator extends BaseComparanator { public ObjectComparanator(Comparanator parent, Object first, Object second, String message) { super(parent, message); if (first instanceof Number firstNumber && second instanceof Number secondNumber) { - if (first instanceof Double && !(second instanceof Double)) { - this.first = firstNumber; - this.second = secondNumber.doubleValue(); - } else if (!(first instanceof Double) && second instanceof Double) { + if (first instanceof Double || second instanceof Double) { this.first = firstNumber.doubleValue(); - this.second = secondNumber; + this.second = secondNumber.doubleValue(); } else { this.first = first; this.second = second; @@ -29,10 +31,17 @@ public ObjectComparanator(Comparanator parent, Object first, Object second, Stri } } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public boolean compare() { try { - assertEquals(first, second, message); + if (first instanceof Double firstNumber && second instanceof Double secondNumber) { + assertTrue(abs(firstNumber - secondNumber) < 0.001, message); + } else if (first instanceof Decimal128 firstComparable && second instanceof Decimal128 secondComparable) { + assertEquals(firstComparable.compareTo(secondComparable), 0, message); + } else { + assertEquals(first, second, message); + } } catch (AssertionError e) { Set messages = new LinkedHashSet<>(); messages.add(message); diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/abs/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/abs/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/abs/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/abs/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/accumulator/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/accumulator/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/accumulator/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/accumulator/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/accumulator/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/accumulator/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/accumulator/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/accumulator/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/acos/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/acos/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/acos/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/acos/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/acos/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/acos/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/acos/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/acos/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/acosh/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/acosh/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/acosh/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/acosh/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/acosh/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/acosh/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/acosh/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/acosh/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/add/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/add/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/add/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/add/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/add/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/add/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/add/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/add/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/addToSet/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/addToSet/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/addToSet/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/addToSet/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/addToSet/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/addToSet/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/addToSet/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/addToSet/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/allElementsTrue/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/allElementsTrue/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/allElementsTrue/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/allElementsTrue/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/and/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/and/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/and/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/and/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/anyElementTrue/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/anyElementTrue/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/anyElementTrue/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/anyElementTrue/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayElemAt/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayElemAt/example1/action.json similarity index 92% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayElemAt/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayElemAt/example1/action.json index a437ac169a8..c2458cc55df 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayElemAt/example1/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayElemAt/example1/action.json @@ -1,10 +1,8 @@ -[ - { +{ $project: { name: 1, first: { $arrayElemAt: [ "$favorites", 0 ] }, last: { $arrayElemAt: [ "$favorites", -1 ] } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayToObject/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayToObject/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayToObject/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayToObject/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayToObject/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayToObject/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayToObject/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/arrayToObject/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/asin/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/asin/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/asin/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/asin/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/asin/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/asin/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/asin/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/asin/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/asinh/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/asinh/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/asinh/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/asinh/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/asinh/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/asinh/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/asinh/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/asinh/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/atan/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/atan/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/atan/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/atan/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/atan/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/atan/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/atan/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/atan/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/atan2/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/atan2/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/atan2/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/atan2/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/atan2/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/atan2/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/atan2/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/atan2/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/atanh/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/atanh/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/atanh/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/atanh/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/atanh/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/atanh/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/atanh/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/atanh/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/avg/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/binarySize/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/binarySize/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/binarySize/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/binarySize/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/binarySize/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/binarySize/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/binarySize/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/binarySize/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/action.json similarity index 86% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/action.json index 83dd6f9bdcb..f8c23189ee6 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/action.json @@ -1,9 +1,7 @@ - [ - { +{ $project: { result: { $bitAnd: [ "$a", "$b" ] } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/expected.json new file mode 100644 index 00000000000..5a28e0a01e0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/expected.json @@ -0,0 +1,3 @@ +{ _id: 0, result: 0 } +{ _id: 1, result: 2 } +{ _id: 2, result: 1 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/name index 88d050b1908..17dabcbbc84 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example1/name @@ -1 +1 @@ -main \ No newline at end of file +Bitwise ``AND`` with Two Integers \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/action.json similarity index 87% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/action.json index 4bee4380dab..5025656bd73 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/action.json @@ -1,9 +1,7 @@ - [ - { +{ $project: { result: { $bitAnd: [ "$a", NumberLong("63") ] } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/expected.json index 5a28e0a01e0..3ec1d087ebb 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/expected.json @@ -1,3 +1,3 @@ -{ _id: 0, result: 0 } -{ _id: 1, result: 2 } -{ _id: 2, result: 1 } \ No newline at end of file +{ _id: 0, result: NumberLong("0") } +{ _id: 1, result: NumberLong("2") } +{ _id: 2, result: NumberLong("3") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/name index 17dabcbbc84..e9451649f4c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example2/name @@ -1 +1 @@ -Bitwise ``AND`` with Two Integers \ No newline at end of file +Bitwise ``AND`` with a Long and Integer \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/data.json deleted file mode 100644 index c5724bc8c85..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/data.json +++ /dev/null @@ -1,3 +0,0 @@ -{ _id: 0, a: NumberInt(0), b: NumberInt(127) }, -{ _id: 1, a: NumberInt(2), b: NumberInt(3) }, -{ _id: 2, a: NumberInt(3), b: NumberInt(5) } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/expected.json deleted file mode 100644 index 3ec1d087ebb..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/expected.json +++ /dev/null @@ -1,3 +0,0 @@ -{ _id: 0, result: NumberLong("0") } -{ _id: 1, result: NumberLong("2") } -{ _id: 2, result: NumberLong("3") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/name deleted file mode 100644 index e9451649f4c..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitAnd/example3/name +++ /dev/null @@ -1 +0,0 @@ -Bitwise ``AND`` with a Long and Integer \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitNot/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitNot/example1/action.json similarity index 84% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bitNot/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bitNot/example1/action.json index ae5d716e6da..22e4ec6f127 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitNot/example1/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitNot/example1/action.json @@ -1,9 +1,7 @@ - [ - { +{ $project: { result: { $bitNot: "$a" } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/action.json similarity index 85% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/action.json index 1e3f713d9ec..4ee95968f4c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/action.json @@ -1,9 +1,7 @@ - [ - { +{ $project: { result: { $bitOr: [ "$a", "$b" ] } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/expected.json new file mode 100644 index 00000000000..27ee0f99d11 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/expected.json @@ -0,0 +1,3 @@ +{ _id: 0, result: 127 }, +{ _id: 1, result: 3 }, +{ _id: 2, result: 7 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/name index 88d050b1908..800a6feb966 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example1/name @@ -1 +1 @@ -main \ No newline at end of file +Bitwise ``OR`` with Two Integers \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/action.json similarity index 87% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/action.json index acf335d2f63..bd6c0c1cac7 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/action.json @@ -1,9 +1,7 @@ - [ - { +{ $project: { result: { $bitOr: [ "$a", NumberLong("63") ] } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/expected.json index 27ee0f99d11..eb5142b5192 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/expected.json @@ -1,3 +1,3 @@ -{ _id: 0, result: 127 }, -{ _id: 1, result: 3 }, -{ _id: 2, result: 7 } \ No newline at end of file +{ _id: 0, result: NumberLong("0") }, +{ _id: 1, result: NumberLong("2") }, +{ _id: 2, result: NumberLong("3") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/name index 800a6feb966..60d573b79ec 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example2/name @@ -1 +1 @@ -Bitwise ``OR`` with Two Integers \ No newline at end of file +Bitwise ``OR`` with a Long and Integer \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/data.json deleted file mode 100644 index c5724bc8c85..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/data.json +++ /dev/null @@ -1,3 +0,0 @@ -{ _id: 0, a: NumberInt(0), b: NumberInt(127) }, -{ _id: 1, a: NumberInt(2), b: NumberInt(3) }, -{ _id: 2, a: NumberInt(3), b: NumberInt(5) } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/expected.json deleted file mode 100644 index 145ed257de6..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/expected.json +++ /dev/null @@ -1,3 +0,0 @@ -{ _id: 0, result: NumberLong("63") }, -{ _id: 1, result: NumberLong("63") }, -{ _id: 2, result: NumberLong("63") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/lock b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/lock deleted file mode 100644 index ee940333aae..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/lock +++ /dev/null @@ -1 +0,0 @@ -change the type name \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/name deleted file mode 100644 index 60d573b79ec..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitOr/example3/name +++ /dev/null @@ -1 +0,0 @@ -Bitwise ``OR`` with a Long and Integer \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitXor/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitXor/example1/action.json similarity index 85% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bitXor/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bitXor/example1/action.json index 9290bf08ed3..8c21c6ac988 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitXor/example1/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bitXor/example1/action.json @@ -1,9 +1,7 @@ - [ - { +{ $project: { result: { $bitXor: ["$a", "$b"] } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottom/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottom/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bottom/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bottom/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottom/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottom/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bottom/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bottom/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bottomN/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/bsonSize/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/ceil/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/ceil/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/ceil/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/ceil/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/cmp/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/cmp/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/cmp/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/cmp/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/concat/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/concat/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/concat/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/concat/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/data.json index ba6971d984c..2e610a11603 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/data.json @@ -1,4 +1,4 @@ -{ "_id" : 1, instock: [ "chocolate" ], ordered: [ "butter", "apples" ] } -{ "_id" : 2, instock: [ "apples", "pudding", "pie" ] } -{ "_id" : 3, instock: [ "pears", "pecans"], ordered: [ "cherries" ] } -{ "_id" : 4, instock: [ "ice cream" ], ordered: [ ] } \ No newline at end of file +{ _id : 1, instock: [ "chocolate" ], ordered: [ "butter", "apples" ] }, +{ _id : 2, instock: [ "apples", "pudding", "pie" ] }, +{ _id : 3, instock: [ "pears", "pecans" ], ordered: [ "cherries" ] }, +{ _id : 4, instock: [ "ice cream" ], ordered: [ ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/expected.json index 02b2cef1a83..8ed9d75524c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/concatArrays/example1/expected.json @@ -1,4 +1,4 @@ -{ "_id" : 1, "items" : [ "chocolate", "butter", "apples" ] } -{ "_id" : 2, "items" : null } -{ "_id" : 3, "items" : [ "pears", "pecans", "cherries" ] } -{ "_id" : 4, "items" : [ "ice cream" ] } \ No newline at end of file +{ _id : 1, items : [ "chocolate", "butter", "apples" ] } +{ _id : 2, items : null } +{ _id : 3, items : [ "pears", "pecans", "cherries" ] } +{ _id : 4, items : [ "ice cream" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/cond/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/cond/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/cond/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/cond/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/convert/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/convert/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/convert/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/convert/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/cos/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/cos/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/cos/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/cos/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/cos/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/cos/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/cos/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/cos/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/cosh/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/cosh/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/cosh/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/cosh/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/cosh/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/cosh/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/cosh/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/cosh/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/count/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/count/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/count/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/count/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/count/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/count/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/count/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/count/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/covariancePop/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/covariancePop/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/covariancePop/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/covariancePop/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/covarianceSamp/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/covarianceSamp/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/covarianceSamp/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/covarianceSamp/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateAdd/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/action.json similarity index 95% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/action.json index a2511c4bf23..4fe5d064084 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/action.json @@ -1,5 +1,4 @@ - [ - { +{ $project: { _id: 0, @@ -31,7 +30,6 @@ unit: "week", startOfWeek: "friday" } - }, + } } - } - ] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/data.json index b69d5e6b116..6140c540987 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/data.json @@ -1,3 +1,3 @@ -{month: "January", start: ISODate("2021-01-01"), end: ISODate("2021-01-31")}, -{month: "February", start: ISODate("2021-02-01"), end: ISODate("2021-02-28")}, -{month: "March", start: ISODate("2021-03-01"), end: ISODate("2021-03-31")}, \ No newline at end of file +{ month: "January", start: ISODate("2021-01-01"), end: ISODate("2021-01-31") }, +{ month: "February", start: ISODate("2021-02-01"), end: ISODate("2021-02-28") }, +{ month: "March", start: ISODate("2021-03-01"), end: ISODate("2021-03-31") }, \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/lock b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/lock new file mode 100644 index 00000000000..447eee099e9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateDiff/example3/lock @@ -0,0 +1,2 @@ +corrected case of parameter values +used full day names \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromParts/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromParts/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromParts/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromParts/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateFromString/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateSubtract/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateToParts/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateToParts/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateToParts/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateToParts/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateToString/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateToString/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateToString/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateToString/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateTrunc/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateTrunc/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateTrunc/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateTrunc/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateTrunc/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dateTrunc/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dateTrunc/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dateTrunc/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfMonth/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfMonth/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfMonth/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfMonth/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfWeek/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfWeek/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfWeek/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfWeek/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfYear/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfYear/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfYear/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/dayOfYear/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/degreesToRadians/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/degreesToRadians/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/degreesToRadians/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/degreesToRadians/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/denseRank/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/derivative/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/derivative/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/derivative/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/derivative/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/divide/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/divide/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/divide/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/divide/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/documentNumber/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/documentNumber/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/documentNumber/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/documentNumber/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/documentNumber/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/documentNumber/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/documentNumber/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/documentNumber/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/eq/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/eq/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/eq/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/eq/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/exp/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/exp/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/exp/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/exp/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/expMovingAvg/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/expMovingAvg/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/expMovingAvg/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/expMovingAvg/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/expMovingAvg/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/expMovingAvg/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/expMovingAvg/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/expMovingAvg/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/action.json new file mode 100644 index 00000000000..0e2fc7b1f7e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/action.json @@ -0,0 +1,12 @@ +{ + $project: { + items: { + $filter: { + input: "$items", + cond: { $gte: [ "$$item.price", 100 ] }, + as: "item", + limit: 1 + } + } + } + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/data.json index 9d49f2a6da2..64d203727f3 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/data.json @@ -1,3 +1,3 @@ -{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10 }, { item_id: 2, quantity: 1, price: 240 } ] }, -{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110 }, { item_id: 103, quantity: 4, price: 5 }, { item_id: 38, quantity: 1, price: 300 } ] }, -{ _id: 2, items: [ { item_id: 4, quantity: 1, price: 23 } ] } \ No newline at end of file +{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: "pen" }, { item_id: 2, quantity: 1, price: 240, name: "briefcase" } ] }, +{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: "notebook" }, { item_id: 103, quantity: 4, price: 5, name: "pen" }, { item_id: 38, quantity: 1, price: 300, name: "printer" } ] }, +{ _id: 2, items: [ { item_id: 4, quantity: 1, price: 23, name: "paper" } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/expected.json index 0ce02022739..130b3951e59 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/expected.json @@ -1,3 +1,3 @@ -{ "_id" : 0, "items" : [ { "item_id" : 2, "quantity" : 1, "price" : 240 } ]} -{ "_id" : 1, "items" : [ { "item_id" : 23, "quantity" : 3, "price" : 110 } ]} -{ "_id" : 2, "items" : [ ] } \ No newline at end of file +{ _id: 0, items: [ { item_id: 2, quantity: 1, price: 240, name: 'briefcase' } ] }, +{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: 'notebook' } ] }, +{ _id: 2, items: [] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/lock b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/lock new file mode 100644 index 00000000000..31256ed729b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/lock @@ -0,0 +1 @@ +rearrange elements \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/name index fe580d1b59d..024e635ed3c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/name @@ -1 +1 @@ -Using the ``limit`` field \ No newline at end of file +Use the limit Field \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/pipeline.json deleted file mode 100644 index 086698d0b1a..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example2/pipeline.json +++ /dev/null @@ -1,14 +0,0 @@ - [ - { - $project: { - items: { - $filter: { - input: "$items", - cond: { $gte: [ "$$item.price", 100 ] }, - as: "item", - limit: 1 - } - } - } - } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/action.json new file mode 100644 index 00000000000..02e63d9e253 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/action.json @@ -0,0 +1,12 @@ +{ + $project: { + items: { + $filter: { + input: "$items", + as: "item", + cond: { $gte: [ "$$item.price", 100] }, + limit: 5 + } + } + } + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/data.json index 9d49f2a6da2..64d203727f3 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/data.json @@ -1,3 +1,3 @@ -{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10 }, { item_id: 2, quantity: 1, price: 240 } ] }, -{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110 }, { item_id: 103, quantity: 4, price: 5 }, { item_id: 38, quantity: 1, price: 300 } ] }, -{ _id: 2, items: [ { item_id: 4, quantity: 1, price: 23 } ] } \ No newline at end of file +{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: "pen" }, { item_id: 2, quantity: 1, price: 240, name: "briefcase" } ] }, +{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: "notebook" }, { item_id: 103, quantity: 4, price: 5, name: "pen" }, { item_id: 38, quantity: 1, price: 300, name: "printer" } ] }, +{ _id: 2, items: [ { item_id: 4, quantity: 1, price: 23, name: "paper" } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/expected.json index fb9103fe91f..4c120c07650 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/expected.json @@ -1,3 +1,3 @@ -{ "_id": 0, "items": [ { "item_id": 43, "quantity": 2, "price": 10 } ] }, -{ "_id": 1, "items": [ { "item_id": 23, "quantity": 3, "price": 110 }, { "item_id": 103, "quantity": 4, "price": 5 } ] }, -{ "_id": 2, "items": [ { "item_id": 4, "quantity": 1, "price": 23 } ] } \ No newline at end of file +{ _id: 0, items: [ { item_id: 2, quantity: 1, price: 240, name: 'briefcase' } ] }, +{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: 'notebook' }, { item_id: 38, quantity: 1, price: 300, name: 'printer' } ] }, +{ _id: 2, items: [] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/name index 463b1d4d869..14d5acdaf26 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/name @@ -1 +1 @@ -``limit`` as a Numeric Expression \ No newline at end of file +limit Greater than Possible Matches \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/pipeline.json deleted file mode 100644 index 85f0d795574..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example3/pipeline.json +++ /dev/null @@ -1,14 +0,0 @@ - [ - { - $project: { - items: { - $filter: { - input: "$items", - cond: { $lte: [ "$$item.price", 150] }, - as: "item", - limit: 2.000 - } - } - } - } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/action.json new file mode 100644 index 00000000000..a6564a052d6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/action.json @@ -0,0 +1,11 @@ +{ + $project: { + items: { + $filter: { + input: "$items", + cond: { $eq: [ "$$item.name", "pen"] }, + as: "item" + } + } + } + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/data.json index 9d49f2a6da2..64d203727f3 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/data.json @@ -1,3 +1,3 @@ -{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10 }, { item_id: 2, quantity: 1, price: 240 } ] }, -{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110 }, { item_id: 103, quantity: 4, price: 5 }, { item_id: 38, quantity: 1, price: 300 } ] }, -{ _id: 2, items: [ { item_id: 4, quantity: 1, price: 23 } ] } \ No newline at end of file +{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: "pen" }, { item_id: 2, quantity: 1, price: 240, name: "briefcase" } ] }, +{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: "notebook" }, { item_id: 103, quantity: 4, price: 5, name: "pen" }, { item_id: 38, quantity: 1, price: 300, name: "printer" } ] }, +{ _id: 2, items: [ { item_id: 4, quantity: 1, price: 23, name: "paper" } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/expected.json index 3626877fc9b..7377cbca759 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/expected.json @@ -1,3 +1,3 @@ -{ "_id": 0, "items": [ { "item_id": 2, "quantity": 1, "price": 240 } ] }, -{ "_id": 1, "items": [ { "item_id": 23, "quantity": 3, "price": 110 }, { "item_id": 38, "quantity": 1, "price": 300 } ] }, -{ "_id": 2, "items": [] } \ No newline at end of file +{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: 'pen' } ] }, +{ _id: 1, items: [ { item_id: 103, quantity: 4, price: 5, name: 'pen' } ] }, +{ _id: 2, items: [] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/lock b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/lock new file mode 100644 index 00000000000..31256ed729b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/lock @@ -0,0 +1 @@ +rearrange elements \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/name index ef9918b4e32..2738affe5ed 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/name @@ -1 +1 @@ -``limit`` Greater than Possible Matches \ No newline at end of file +Filter Based on String Equality Match \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/pipeline.json deleted file mode 100644 index 78ecc34f667..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example4/pipeline.json +++ /dev/null @@ -1,14 +0,0 @@ - [ - { - $project: { - items: { - $filter: { - input: "$items", - cond: { $gte: [ "$$item.price", 100] }, - as: "item", - limit: 5 - } - } - } - } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/action.json new file mode 100644 index 00000000000..93f37616d04 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/action.json @@ -0,0 +1,13 @@ +{ + $project: { + items: { + $filter: { + input: "$items", + cond: { + $regexMatch: { input: "$$item.name", regex: /^p/ } + }, + as: "item" + } + } + } + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/data.json new file mode 100644 index 00000000000..64d203727f3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/data.json @@ -0,0 +1,3 @@ +{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: "pen" }, { item_id: 2, quantity: 1, price: 240, name: "briefcase" } ] }, +{ _id: 1, items: [ { item_id: 23, quantity: 3, price: 110, name: "notebook" }, { item_id: 103, quantity: 4, price: 5, name: "pen" }, { item_id: 38, quantity: 1, price: 300, name: "printer" } ] }, +{ _id: 2, items: [ { item_id: 4, quantity: 1, price: 23, name: "paper" } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/expected.json new file mode 100644 index 00000000000..d6e0cced9fd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/expected.json @@ -0,0 +1,3 @@ +{ _id: 0, items: [ { item_id: 43, quantity: 2, price: 10, name: 'pen' } ] }, +{ _id: 1, items: [ { item_id: 103, quantity: 4, price: 5, name: 'pen' }, { item_id: 38, quantity: 1, price: 300, name: 'printer' } ] }, +{ _id: 2, items: [ { item_id: 4, quantity: 1, price: 23, name: 'paper' } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/lock b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/lock new file mode 100644 index 00000000000..31256ed729b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/lock @@ -0,0 +1 @@ +rearrange elements \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/name new file mode 100644 index 00000000000..3bf24205ebd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/filter/example5/name @@ -0,0 +1 @@ +Filter Based on Regular Expression Match \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/first/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/firstN/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/floor/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/floor/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/floor/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/floor/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example1/action.json similarity index 91% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example1/action.json index b6cdbe66630..8ed89e6de69 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example1/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example1/action.json @@ -4,8 +4,8 @@ isFound: { $function: { - body: "function(name) {\n - return hex_md5(name) == \"15b0a220baa16331e8d80e15367677ad\"\n + body: "function(name) { + return hex_md5(name) == \"15b0a220baa16331e8d80e15367677ad\" }", args: [ "$name" ], lang: "js" diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example2/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example2/action.json new file mode 100644 index 00000000000..d1b816fc080 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example2/action.json @@ -0,0 +1,3 @@ +db.players.find( { $where: function() { + return (hex_md5(this.name) == "15b0a220baa16331e8d80e15367677ad") +} } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example2/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example2/data.json index f51f6d62e3b..3370b0c1653 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example2/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/function/example2/data.json @@ -1,3 +1,3 @@ -{ _id: 1, name: "Miss Cheevous", scores: [ 10, 5, 10 ] }, +{ _id: 1, name: "Miss Cheevous", scores: [ 10, 5, 10 ] }, { _id: 2, name: "Miss Ann Thrope", scores: [ 10, 10, 10 ] }, { _id: 3, name: "Mrs. Eppie Delta ", scores: [ 9, 8, 8 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/getField/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/gt/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/gt/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/gt/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/gt/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/gte/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/gte/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/gte/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/gte/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/hour/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/hour/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/hour/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/hour/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/ifNull/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/ifNull/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/ifNull/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/ifNull/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/ifNull/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/ifNull/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/ifNull/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/ifNull/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/in/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/in/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/in/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/in/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfArray/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfArray/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfArray/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfArray/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfBytes/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfBytes/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfBytes/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfBytes/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfCP/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfCP/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfCP/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/indexOfCP/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/integral/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/integral/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/integral/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/integral/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isArray/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isArray/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/isArray/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/isArray/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isNumber/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isNumber/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/isNumber/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/isNumber/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isNumber/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isNumber/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/isNumber/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/isNumber/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/data.json index ffa5bf6563e..48432dd1566 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/data.json @@ -1,2 +1,2 @@ -{ "_id" : 1, "name" : "Betty", "birthday" : ISODate("1993-09-21T00:00:00Z") } -{ "_id" : 2, "name" : "Veronica", "birthday" : ISODate("1981-11-07T00:00:00Z") } \ No newline at end of file +{ _id: 1, name: "Betty", birthday: ISODate("1993-09-21T00:00:00Z") }, +{ _id: 2, name: "Veronica", birthday: ISODate("1981-11-07T00:00:00Z") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/expected.json index fedd856b3f6..87194708a7c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoDayOfWeek/example1/expected.json @@ -1,2 +1,2 @@ -{ "name" : "Betty", "dayOfWeek" : 2 } -{ "name" : "Veronica", "dayOfWeek" : 6 } \ No newline at end of file +{ name: "Betty", dayOfWeek: 2 }, +{ name: "Veronica", dayOfWeek: 6 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/data.json index 7faf39f1def..c79a30d7d93 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/data.json @@ -1,2 +1,2 @@ -{ "_id" : 1, "date" : ISODate("2006-10-24T00:00:00Z"), "city" : "Boston" } -{ "_id" : 2, "date" : ISODate("2011-08-18T00:00:00Z"), "city" : "Detroit" } \ No newline at end of file +{ _id: 1, date: ISODate("2006-10-24T00:00:00Z"), city: "Boston" }, +{ _id: 2, date: ISODate("2011-08-18T00:00:00Z"), city: "Detroit" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/expected.json index e593a453c3c..037e557c487 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeek/example1/expected.json @@ -1,2 +1,2 @@ -{ "city" : "Boston", "weekNumber" : 43 } -{ "city" : "Detroit", "weekNumber" : 33 } \ No newline at end of file +{ city: "Boston", weekNumber: 43 }, +{ city: "Detroit", weekNumber: 33 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeekYear/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeekYear/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeekYear/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/isoWeekYear/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/last/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/last/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/last/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/last/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/last/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/last/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/last/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/last/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/lastN/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/let/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/let/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/let/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/let/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/action.json similarity index 92% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/action.json index c0d5f5e4130..caadc08aee1 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/action.json @@ -1,5 +1,4 @@ - [ - { +{ $setWindowFields: { sortBy: { time: 1 }, @@ -8,5 +7,4 @@ price: { $linearFill: "$price" } } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/data.json index f1c9d9490d7..6e32663ddd9 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/data.json @@ -1,6 +1,6 @@ -{ time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, -{ time: ISODate("2021-03-08T10:00:00.000Z"), }, -{ time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, -{ time: ISODate("2021-03-08T12:00:00.000Z") }, -{ time: ISODate("2021-03-08T13:00:00.000Z") }, -{ time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } \ No newline at end of file +{ time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, +{ time: ISODate("2021-03-08T10:00:00.000Z"), }, +{ time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, +{ time: ISODate("2021-03-08T12:00:00.000Z") }, +{ time: ISODate("2021-03-08T13:00:00.000Z") }, +{ time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/expected.json new file mode 100644 index 00000000000..bda0300065e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/expected.json @@ -0,0 +1,6 @@ +{ _id: ObjectId("620ad555394d47411658b5ef"), time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, +{ _id: ObjectId("620ad555394d47411658b5f0"), time: ISODate("2021-03-08T10:00:00.000Z"), price: 507.5 }, +{ _id: ObjectId("620ad555394d47411658b5f1"), time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, +{ _id: ObjectId("620ad555394d47411658b5f2"), time: ISODate("2021-03-08T12:00:00.000Z"), price: 505 }, +{ _id: ObjectId("620ad555394d47411658b5f3"), time: ISODate("2021-03-08T13:00:00.000Z"), price: 495 }, +{ _id: ObjectId("620ad555394d47411658b5f4"), time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/name index 88d050b1908..86242d7d7f5 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example1/name @@ -1 +1 @@ -main \ No newline at end of file +Fill Missing Values with Linear Interpolation \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/data.json index f1c9d9490d7..6e32663ddd9 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/data.json @@ -1,6 +1,6 @@ -{ time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, -{ time: ISODate("2021-03-08T10:00:00.000Z"), }, -{ time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, -{ time: ISODate("2021-03-08T12:00:00.000Z") }, -{ time: ISODate("2021-03-08T13:00:00.000Z") }, -{ time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } \ No newline at end of file +{ time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, +{ time: ISODate("2021-03-08T10:00:00.000Z"), }, +{ time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, +{ time: ISODate("2021-03-08T12:00:00.000Z") }, +{ time: ISODate("2021-03-08T13:00:00.000Z") }, +{ time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/expected.json index 46bd7396fd9..f4df49bb340 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/expected.json @@ -1,6 +1,6 @@ -{ _id: ObjectId("620ad555394d47411658b5ef"), time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, -{ _id: ObjectId("620ad555394d47411658b5f0"), time: ISODate("2021-03-08T10:00:00.000Z"), price: 507.5 }, -{ _id: ObjectId("620ad555394d47411658b5f1"), time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, -{ _id: ObjectId("620ad555394d47411658b5f2"), time: ISODate("2021-03-08T12:00:00.000Z"), price: 505 }, -{ _id: ObjectId("620ad555394d47411658b5f3"), time: ISODate("2021-03-08T13:00:00.000Z"), price: 495 }, -{ _id: ObjectId("620ad555394d47411658b5f4"), time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } \ No newline at end of file +{ _id: ObjectId("620ad555394d47411658b5ef"), time: ISODate("2021-03-08T09:00:00.000Z"), price: 500, linearFillPrice: 500, locfPrice: 500 }, +{ _id: ObjectId("620ad555394d47411658b5f0"), time: ISODate("2021-03-08T10:00:00.000Z"), linearFillPrice: 507.5, locfPrice: 500 }, +{ _id: ObjectId("620ad555394d47411658b5f1"), time: ISODate("2021-03-08T11:00:00.000Z"), price: 515, linearFillPrice: 515, locfPrice: 515 }, +{ _id: ObjectId("620ad555394d47411658b5f2"), time: ISODate("2021-03-08T12:00:00.000Z"), linearFillPrice: 505, locfPrice: 515 }, +{ _id: ObjectId("620ad555394d47411658b5f3"), time: ISODate("2021-03-08T13:00:00.000Z"), linearFillPrice: 495, locfPrice: 515 }, +{ _id: ObjectId("620ad555394d47411658b5f4"), time: ISODate("2021-03-08T14:00:00.000Z"), price: 485, linearFillPrice: 485, locfPrice: 485 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/name index 86242d7d7f5..b154467f096 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example2/name @@ -1 +1 @@ -Fill Missing Values with Linear Interpolation \ No newline at end of file +Use Multiple Fill Methods in a Single Stage \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/data.json deleted file mode 100644 index f1c9d9490d7..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/data.json +++ /dev/null @@ -1,6 +0,0 @@ -{ time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, -{ time: ISODate("2021-03-08T10:00:00.000Z"), }, -{ time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, -{ time: ISODate("2021-03-08T12:00:00.000Z") }, -{ time: ISODate("2021-03-08T13:00:00.000Z") }, -{ time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/expected.json deleted file mode 100644 index 496e51a1741..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/expected.json +++ /dev/null @@ -1,6 +0,0 @@ -{ _id: ObjectId("620ad555394d47411658b5ef"), time: ISODate("2021-03-08T09:00:00.000Z"), price: 500, linearFillPrice: 500, locfPrice: 500 }, -{ _id: ObjectId("620ad555394d47411658b5f0"), time: ISODate("2021-03-08T10:00:00.000Z"), linearFillPrice: 507.5, locfPrice: 500 }, -{ _id: ObjectId("620ad555394d47411658b5f1"), time: ISODate("2021-03-08T11:00:00.000Z"), price: 515, linearFillPrice: 515, locfPrice: 515 }, -{ _id: ObjectId("620ad555394d47411658b5f2"), time: ISODate("2021-03-08T12:00:00.000Z"), linearFillPrice: 505, locfPrice: 515 }, -{ _id: ObjectId("620ad555394d47411658b5f3"), time: ISODate("2021-03-08T13:00:00.000Z"), linearFillPrice: 495, locfPrice: 515 }, -{ _id: ObjectId("620ad555394d47411658b5f4"), time: ISODate("2021-03-08T14:00:00.000Z"), price: 485, linearFillPrice: 485, locfPrice: 485 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/name deleted file mode 100644 index b154467f096..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/name +++ /dev/null @@ -1 +0,0 @@ -Use Multiple Fill Methods in a Single Stage \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example2/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example2/data.json index aade1780ec1..7efdd337712 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example2/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/literal/example2/data.json @@ -1,2 +1,2 @@ -{ "_id" : 1, "title" : "Dracula", "condition": "new" } +{ "_id" : 1, "title" : "Dracula", "condition": "new" }, { "_id" : 2, "title" : "The Little Prince", "condition": "new" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/ln/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/ln/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/ln/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/ln/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example2/action.json similarity index 94% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example2/action.json index 1cc9ee8dd87..57922d444d8 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/linearFill/example3/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/locf/example2/action.json @@ -1,5 +1,4 @@ - [ - { +{ $setWindowFields: { sortBy: { time: 1 }, @@ -9,5 +8,4 @@ locfPrice: { $locf: "$price" } } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/log/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/log/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/log/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/log/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/log10/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/log10/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/log10/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/log10/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/lt/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/lt/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/lt/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/lt/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/lte/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/lte/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/lte/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/lte/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/ltrim/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/ltrim/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/ltrim/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/ltrim/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/map/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/max/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/maxN/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/action.json similarity index 92% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/action.json index 111c5c1be91..d047fccf1a9 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/action.json @@ -1,5 +1,4 @@ - [ - { +{ $group: { _id: null, test01_median: { @@ -9,5 +8,4 @@ } } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/expected.json new file mode 100644 index 00000000000..2bee6e9eefe --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/expected.json @@ -0,0 +1 @@ +{ _id: null, test01_median: 62 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/name index 88d050b1908..dddf89e6984 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example1/name @@ -1 +1 @@ -main \ No newline at end of file +Use |operatorName| as an Accumulator \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/action.json similarity index 93% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/action.json index 6c293a4c76c..12b1a84701f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/action.json @@ -1,5 +1,4 @@ - [ - { +{ $project: { _id: 0, studentId: 1, @@ -10,5 +9,4 @@ } } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/expected.json index 2bee6e9eefe..44f354cf89f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/expected.json @@ -1 +1,5 @@ -{ _id: null, test01_median: 62 } \ No newline at end of file +{ studentId: '2345', testMedians: 80 }, +{ studentId: '2356', testMedians: 79 }, +{ studentId: '2358', testMedians: 78 }, +{ studentId: '2367', testMedians: 72 }, +{ studentId: '2369', testMedians: 60 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/name index dddf89e6984..92a7ff3acb5 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example2/name @@ -1 +1 @@ -Use |operatorName| as an Accumulator \ No newline at end of file +Use |operatorName| in a ``$project`` Stage \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/action.json similarity index 96% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/action.json index 480a9c72414..bc1e8f17a1e 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/action.json @@ -1,5 +1,4 @@ - [ - { +{ $setWindowFields: { sortBy: { test01: 1 }, output: { @@ -21,5 +20,4 @@ studentId: 1, test01_median: 1 } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/expected.json index 44f354cf89f..ccb1ee02e4f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/expected.json @@ -1,5 +1,5 @@ -{ studentId: '2345', testMedians: 80 }, -{ studentId: '2356', testMedians: 79 }, -{ studentId: '2358', testMedians: 78 }, -{ studentId: '2367', testMedians: 72 }, -{ studentId: '2369', testMedians: 60 } \ No newline at end of file +{ studentId: '2356', test01_median: 60 }, +{ studentId: '2369', test01_median: 60 }, +{ studentId: '2345', test01_median: 60 }, +{ studentId: '2367', test01_median: 64 }, +{ studentId: '2358', test01_median: 64 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/name index 92a7ff3acb5..d946ed1695c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example3/name @@ -1 +1 @@ -Use |operatorName| in a ``$project`` Stage \ No newline at end of file +Use |operatorName| in a ``$setWindowField`` Stage \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/data.json deleted file mode 100644 index 262e8dd1f77..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/data.json +++ /dev/null @@ -1,5 +0,0 @@ -{ studentId: "2345", test01: 62, test02: 81, test03: 80 }, -{ studentId: "2356", test01: 60, test02: 83, test03: 79 }, -{ studentId: "2358", test01: 67, test02: 82, test03: 78 }, -{ studentId: "2367", test01: 64, test02: 72, test03: 77 }, -{ studentId: "2369", test01: 60, test02: 53, test03: 72 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/expected.json deleted file mode 100644 index ccb1ee02e4f..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/expected.json +++ /dev/null @@ -1,5 +0,0 @@ -{ studentId: '2356', test01_median: 60 }, -{ studentId: '2369', test01_median: 60 }, -{ studentId: '2345', test01_median: 60 }, -{ studentId: '2367', test01_median: 64 }, -{ studentId: '2358', test01_median: 64 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/name deleted file mode 100644 index d946ed1695c..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/median/example4/name +++ /dev/null @@ -1 +0,0 @@ -Use |operatorName| in a ``$setWindowField`` Stage \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example1/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example1/data1.json new file mode 100644 index 00000000000..7448ceeb5d2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example1/data1.json @@ -0,0 +1,3 @@ +{ "_id" : 1, "item" : "abc", description: "product 1", "instock" : 120 }, +{ "_id" : 2, "item" : "def", description: "product 2", "instock" : 80 }, +{ "_id" : 3, "item" : "jkl", description: "product 3", "instock" : 60 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/mergeObjects/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example1/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example1/data1.json new file mode 100644 index 00000000000..57558eb719a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example1/data1.json @@ -0,0 +1 @@ +{ title: "text"} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/action.json new file mode 100644 index 00000000000..88c5d84f129 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/action.json @@ -0,0 +1,4 @@ +db.articles.find( + { $text: { $search: "cake" } }, + { score: { $meta: "textScore" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/data.json index 7dccb07fda8..a3715972118 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/data.json @@ -1,3 +1,6 @@ -{ "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type": "apparel" }, -{ "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type": "electronics" }, -{ "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type": "apparel" } \ No newline at end of file +{ "_id" : 1, "title" : "cakes and ale" }, +{ "_id" : 2, "title" : "more cakes" }, +{ "_id" : 3, "title" : "bread" }, +{ "_id" : 4, "title" : "some cakes" }, +{ "_id" : 5, "title" : "two cakes to go" }, +{ "_id" : 6, "title" : "pie" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/expected.json index 39c88b133dc..fc477e4a1a2 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/expected.json @@ -1,2 +1,4 @@ -{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcde"), "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type" : "apparel", "idxKey" : { "type" : "apparel", "item" : "abc" }} -{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"), "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type" : "apparel", "idxKey" : { "type" : "apparel", "item" : "abc" }} \ No newline at end of file +{ "_id" : 4, "title" : "some cakes", "score" : 1 } +{ "_id" : 1, "title" : "cakes and ale", "score" : 0.75 } +{ "_id" : 5, "title" : "two cakes to go", "score" : 0.6666666666666666 } +{ "_id" : 2, "title" : "more cakes", "score" : 1 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/index.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/index.json index 72e01057f25..57558eb719a 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/index.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/index.json @@ -1 +1 @@ -{ type: 1, item: 1 } \ No newline at end of file +{ title: "text"} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/lock b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/lock new file mode 100644 index 00000000000..4a0c5f54b84 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/lock @@ -0,0 +1 @@ +had to massage the indexing \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/name index c3c0f856430..3cb1d10aa45 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/name @@ -1 +1 @@ -``$meta: "indexKey"`` :: Aggregation \ No newline at end of file +``$meta: "textScore"`` :: Find and Project \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/data1.json new file mode 100644 index 00000000000..72e01057f25 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/data1.json @@ -0,0 +1 @@ +{ type: 1, item: 1 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/expected.json index 0085a92fa28..39c88b133dc 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/expected.json @@ -1,3 +1,2 @@ -{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcde"), "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type" : "apparel"} -{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcdf"), "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type" : "electronics"} -{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"), "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type" : "apparel"} \ No newline at end of file +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcde"), "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type" : "apparel", "idxKey" : { "type" : "apparel", "item" : "abc" }} +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"), "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type" : "apparel", "idxKey" : { "type" : "apparel", "item" : "abc" }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/name index d7accc8f500..c3c0f856430 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/name @@ -1 +1 @@ -``$meta: "indexKey"`` :: Aggregation [1] \ No newline at end of file +``$meta: "indexKey"`` :: Aggregation \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/action.json new file mode 100644 index 00000000000..4eab40ae133 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/action.json @@ -0,0 +1 @@ +db.orders.find( { type: "apparel" }, { idxKey: { $meta: "indexKey" } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/data.json new file mode 100644 index 00000000000..7dccb07fda8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/data.json @@ -0,0 +1,3 @@ +{ "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type": "apparel" }, +{ "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type": "electronics" }, +{ "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type": "apparel" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/data1.json new file mode 100644 index 00000000000..72e01057f25 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/data1.json @@ -0,0 +1 @@ +{ type: 1, item: 1 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/expected.json new file mode 100644 index 00000000000..39c88b133dc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/expected.json @@ -0,0 +1,2 @@ +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcde"), "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type" : "apparel", "idxKey" : { "type" : "apparel", "item" : "abc" }} +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"), "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type" : "apparel", "idxKey" : { "type" : "apparel", "item" : "abc" }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/name new file mode 100644 index 00000000000..a3fc2a930df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example4/name @@ -0,0 +1 @@ +``$meta: "indexKey"`` :: Find and Project \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/data.json new file mode 100644 index 00000000000..7dccb07fda8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/data.json @@ -0,0 +1,3 @@ +{ "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type": "apparel" }, +{ "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type": "electronics" }, +{ "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type": "apparel" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/data1.json new file mode 100644 index 00000000000..72e01057f25 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/data1.json @@ -0,0 +1 @@ +{ type: 1, item: 1 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/expected.json new file mode 100644 index 00000000000..0085a92fa28 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/expected.json @@ -0,0 +1,3 @@ +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcde"), "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type" : "apparel"} +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcdf"), "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type" : "electronics"} +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"), "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type" : "apparel"} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/name new file mode 100644 index 00000000000..d7accc8f500 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example5/name @@ -0,0 +1 @@ +``$meta: "indexKey"`` :: Aggregation [1] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/action.json new file mode 100644 index 00000000000..831d5c22624 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/action.json @@ -0,0 +1,4 @@ +db.orders.find( + { price: { $gte: 10 } }, + { idxKey: { $meta: "indexKey" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/data.json new file mode 100644 index 00000000000..7dccb07fda8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/data.json @@ -0,0 +1,3 @@ +{ "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type": "apparel" }, +{ "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type": "electronics" }, +{ "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type": "apparel" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/data1.json new file mode 100644 index 00000000000..72e01057f25 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/data1.json @@ -0,0 +1 @@ +{ type: 1, item: 1 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/expected.json new file mode 100644 index 00000000000..0085a92fa28 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/expected.json @@ -0,0 +1,3 @@ +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcde"), "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type" : "apparel"} +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dcdf"), "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type" : "electronics"} +{ "_id" : ObjectId("5e98a33ceaf5e9dcf2b8dce0"), "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type" : "apparel"} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/name new file mode 100644 index 00000000000..2f208d72c93 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/meta/example6/name @@ -0,0 +1 @@ +``$meta: "indexKey"`` :: Find and Project [1] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/millisecond/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/millisecond/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/millisecond/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/millisecond/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/min/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/minN/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/minute/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/minute/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/minute/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/minute/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/mod/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/mod/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/mod/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/mod/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/mod/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/mod/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/mod/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/mod/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/month/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/month/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/month/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/month/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/multiply/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/multiply/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/multiply/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/multiply/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/ne/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/ne/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/ne/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/ne/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/not/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/not/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/not/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/not/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/objectToArray/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/or/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/or/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/or/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/or/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/action.json similarity index 93% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/action.json index e5e2f27c6c7..51167531d2c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/action.json @@ -1,5 +1,4 @@ - [ - { +{ $group: { _id: null, test01_percentiles: { @@ -10,5 +9,4 @@ } }, } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/expected.json new file mode 100644 index 00000000000..b076ad7023b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/expected.json @@ -0,0 +1 @@ +{ _id: null, test01_percentiles: [ 67 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/name index 88d050b1908..3353afad883 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example1/name @@ -1 +1 @@ -main \ No newline at end of file +Calculate a Single Value as an Accumulator \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/action.json similarity index 98% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/action.json index aec39c6793b..9d228906b1f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/action.json @@ -1,5 +1,4 @@ - [ - { +{ $group: { _id: null, test01_percentiles: { @@ -31,5 +30,4 @@ } }, } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/expected.json index b076ad7023b..48ad992bb9e 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/expected.json @@ -1 +1 @@ -{ _id: null, test01_percentiles: [ 67 ] } \ No newline at end of file +{ _id: null, test01_percentiles: [ 62, 64, 67, 67 ], test02_percentiles: [ 81, 82, 83, 83 ], test03_percentiles: [ 78, 79, 80, 80 ], test03_percent_alt: [ 80, 78, 79, 80 ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/name index 3353afad883..77102bf60d6 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example2/name @@ -1 +1 @@ -Calculate a Single Value as an Accumulator \ No newline at end of file +Calculate Multiple Values as an Accumulator \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/action.json similarity index 94% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/action.json index ed23d7584cb..36e127aa6c3 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/action.json @@ -1,5 +1,4 @@ - [ - { +{ $project: { _id: 0, studentId: 1, @@ -11,5 +10,4 @@ } } } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/expected.json index 5b025eb9244..c8bfa12e6e0 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/expected.json @@ -1 +1,5 @@ -{ _id: null, test01_percentiles: [ 62, 64, 67, 67 ], test02_percentiles: [ 81, 82, 83, 83 ], test03_percentiles: [ 78, 79, 80, 80 ], test03_percent_alt: [ 80, 78, 79, 80 ]} \ No newline at end of file +{ studentId: '2345', testPercentiles: [ 80, 81 ] }, +{ studentId: '2356', testPercentiles: [ 79, 83 ] }, +{ studentId: '2358', testPercentiles: [ 78, 82 ] }, +{ studentId: '2367', testPercentiles: [ 72, 77 ] }, +{ studentId: '2369', testPercentiles: [ 60, 72 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/name index 77102bf60d6..92a7ff3acb5 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example3/name @@ -1 +1 @@ -Calculate Multiple Values as an Accumulator \ No newline at end of file +Use |operatorName| in a ``$project`` Stage \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/action.json similarity index 97% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/action.json index a90786c5bae..17deb232b0f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/action.json @@ -1,5 +1,4 @@ - [ - { +{ $setWindowFields: { sortBy: { test01: 1 }, output: { @@ -22,5 +21,4 @@ studentId: 1, test01_95percentile: 1 } - } -] \ No newline at end of file + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/expected.json index c8bfa12e6e0..96399183ea6 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/expected.json @@ -1,5 +1,5 @@ -{ studentId: '2345', testPercentiles: [ 80, 81 ] }, -{ studentId: '2356', testPercentiles: [ 79, 83 ] }, -{ studentId: '2358', testPercentiles: [ 78, 82 ] }, -{ studentId: '2367', testPercentiles: [ 72, 77 ] }, -{ studentId: '2369', testPercentiles: [ 60, 72 ] } \ No newline at end of file +{ studentId: '2356', test01_95percentile: [ 62 ] }, +{ studentId: '2369', test01_95percentile: [ 62 ] }, +{ studentId: '2345', test01_95percentile: [ 64 ] }, +{ studentId: '2367', test01_95percentile: [ 67 ] }, +{ studentId: '2358', test01_95percentile: [ 67 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/name index 92a7ff3acb5..d946ed1695c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example4/name @@ -1 +1 @@ -Use |operatorName| in a ``$project`` Stage \ No newline at end of file +Use |operatorName| in a ``$setWindowField`` Stage \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/data.json deleted file mode 100644 index 262e8dd1f77..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/data.json +++ /dev/null @@ -1,5 +0,0 @@ -{ studentId: "2345", test01: 62, test02: 81, test03: 80 }, -{ studentId: "2356", test01: 60, test02: 83, test03: 79 }, -{ studentId: "2358", test01: 67, test02: 82, test03: 78 }, -{ studentId: "2367", test01: 64, test02: 72, test03: 77 }, -{ studentId: "2369", test01: 60, test02: 53, test03: 72 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/expected.json deleted file mode 100644 index 96399183ea6..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/expected.json +++ /dev/null @@ -1,5 +0,0 @@ -{ studentId: '2356', test01_95percentile: [ 62 ] }, -{ studentId: '2369', test01_95percentile: [ 62 ] }, -{ studentId: '2345', test01_95percentile: [ 64 ] }, -{ studentId: '2367', test01_95percentile: [ 67 ] }, -{ studentId: '2358', test01_95percentile: [ 67 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/name deleted file mode 100644 index d946ed1695c..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/percentile/example5/name +++ /dev/null @@ -1 +0,0 @@ -Use |operatorName| in a ``$setWindowField`` Stage \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/data.json index 9695e9e762e..2a61196043c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/data.json @@ -1,2 +1,2 @@ -{ "_id" : 1, "scores" : [ { "name" : "dave123", "score" : 85 }, { "name" : "dave2", "score" : 90 }, { "name" : "ahn", "score" : 71 } ]} -{ "_id" : 2, "scores" : [ { "name" : "li", "quiz" : 2, "score" : 96 }, { "name" : "annT", "score" : 77 }, { "name" : "ty", "score" : 82 } ]} \ No newline at end of file +{ _id : 1, scores : [ { name : "dave123", score : 85 }, { name : "dave2", score : 90 }, { name : "ahn", score : 71 } ] }, +{ _id : 2, scores : [ { name : "li", quiz : 2, score : 96 }, { name : "annT", score : 77 }, { name : "ty", score : 82 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/expected.json index 454cb12c359..068389a3f79 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/pow/example1/expected.json @@ -1,2 +1,2 @@ -{ "_id" : 1, "variance" : 64.66666666666667 } -{ "_id" : 2, "variance" : 64.66666666666667 } \ No newline at end of file +{ _id : 1, variance : 64.66666666666667 } +{ _id : 2, variance : 64.66666666666667 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/push/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/push/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/push/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/push/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/push/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/push/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/push/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/push/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/radiansToDegrees/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/radiansToDegrees/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/radiansToDegrees/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/radiansToDegrees/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/rand/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/rand/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/rand/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/rand/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/rand/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/rand/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/rand/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/rand/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/data.json index 955ed1c27d3..1f06a7cfb1b 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/data.json @@ -1,4 +1,4 @@ -{ _id: 0, city: "San Jose", distance: 42 } -{ _id: 1, city: "Sacramento", distance: 88 } -{ _id: 2, city: "Reno", distance: 218 } -{ _id: 3, city: "Los Angeles", distance: 383 } \ No newline at end of file +{ _id: 0, city: "San Jose", distance: 42 }, +{ _id: 1, city: "Sacramento", distance: 88 }, +{ _id: 2, city: "Reno", distance: 218 }, +{ _id: 3, city: "Los Angeles", distance: 383 } diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/lock b/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/lock new file mode 100644 index 00000000000..253d6d9f318 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/range/example1/lock @@ -0,0 +1 @@ +data file had extraneous text \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/rank/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/reduce/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFind/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexFindAll/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexMatch/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexMatch/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexMatch/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexMatch/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexMatch/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/regexMatch/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/regexMatch/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/regexMatch/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/replaceAll/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/replaceAll/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/replaceAll/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/replaceAll/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/replaceOne/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/replaceOne/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/replaceOne/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/replaceOne/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/reverseArray/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/reverseArray/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/reverseArray/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/reverseArray/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/round/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/round/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/round/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/round/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/rtrim/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/rtrim/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/rtrim/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/rtrim/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sampleRate/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sampleRate/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sampleRate/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sampleRate/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/second/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/second/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/second/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/second/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setDifference/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setDifference/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setDifference/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setDifference/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setEquals/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setEquals/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setEquals/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setEquals/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example6/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example6/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example6/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setField/example6/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/data1.json new file mode 100644 index 00000000000..b39af44e640 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/data1.json @@ -0,0 +1,2 @@ +db.createUser( { user: "John", pwd: "jn008", roles: [ { role: "Marketing", db: "test" }, { role: "Development", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ]} ) +db.createUser( { user: "Jane", pwd: "je009", roles: [ { role: "Sales", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ]} ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/data3.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/data3.json new file mode 100644 index 00000000000..dfe3d24e4ba --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/data3.json @@ -0,0 +1 @@ +db.auth( "John", "jn008" ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/expected.json index b39af44e640..c1aaf3a5920 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIntersection/example2/expected.json @@ -1,2 +1,3 @@ -db.createUser( { user: "John", pwd: "jn008", roles: [ { role: "Marketing", db: "test" }, { role: "Development", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ]} ) -db.createUser( { user: "Jane", pwd: "je009", roles: [ { role: "Sales", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ]} ) \ No newline at end of file +{ _id: 0, allowedRoles: [ 'Marketing' ], comment: 'For marketing team', yearlyBudget: 15000 }, +{ _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 }, +{ _id: 3, allowedRoles: [ 'Development' ], comment: 'For development team', yearlyBudget: 27000 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIsSubset/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setIsSubset/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setIsSubset/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setIsSubset/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/setUnion/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/setUnion/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/setUnion/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/setUnion/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/shift/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/shift/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/shift/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/shift/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/shift/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/shift/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/shift/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/shift/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sin/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sin/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sin/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sin/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sin/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sin/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sin/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sin/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sinh/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sinh/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sinh/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sinh/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sinh/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sinh/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sinh/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sinh/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/size/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/size/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/size/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/size/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/slice/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/slice/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/slice/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/slice/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sortArray/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/split/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/split/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/split/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/split/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sqrt/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sqrt/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sqrt/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sqrt/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example1/data.json index e9b35c97061..baa55fac14d 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example1/data.json @@ -1,6 +1,6 @@ -{ "_id" : 1, "name" : "dave123", "quiz" : 1, "score" : 85 } -{ "_id" : 2, "name" : "dave2", "quiz" : 1, "score" : 90 } -{ "_id" : 3, "name" : "ahn", "quiz" : 1, "score" : 71 } -{ "_id" : 4, "name" : "li", "quiz" : 2, "score" : 96 } -{ "_id" : 5, "name" : "annT", "quiz" : 2, "score" : 77 } -{ "_id" : 6, "name" : "ty", "quiz" : 2, "score" : 82 } \ No newline at end of file +{ _id : 1, name : "dave123", quiz : 1, score : 85 }, +{ _id : 2, name : "dave2", quiz : 1, score : 90 }, +{ _id : 3, name : "ahn", quiz : 1, score : 71 }, +{ _id : 4, name : "li", quiz : 2, score : 96 }, +{ _id : 5, name : "annT", quiz : 2, score : 77 }, +{ _id : 6, name : "ty", quiz : 2, score : 82 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/data.json index 2d7e14113ab..2a61196043c 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/data.json @@ -1,2 +1,2 @@ -{ "_id" : 1, "scores" : [ { "name" : "dave123", "score" : 85 }, { "name" : "dave2", "score" : 90 }, { "name" : "ahn", "score" : 71 } ] }, -{ "_id" : 2, "scores" : [ { "name" : "li", "quiz" : 2, "score" : 96 }, { "name" : "annT", "score" : 77 }, { "name" : "ty", "score" : 82 } ] } \ No newline at end of file +{ _id : 1, scores : [ { name : "dave123", score : 85 }, { name : "dave2", score : 90 }, { name : "ahn", score : 71 } ] }, +{ _id : 2, scores : [ { name : "li", quiz : 2, score : 96 }, { name : "annT", score : 77 }, { name : "ty", score : 82 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/expected.json index 3fc7cfdf611..62518e2fa8d 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example2/expected.json @@ -1,2 +1,2 @@ -{ "_id" : 1, "stdDev" : 8.04155872120988 } -{ "_id" : 2, "stdDev" : 8.04155872120988 } \ No newline at end of file +{ _id : 1, stdDev : 8.04155872120988 } +{ _id : 2, stdDev : 8.04155872120988 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example3/expected.json index 2e9ef5b9629..bcefbb4b048 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example3/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevPop/example3/expected.json @@ -1,6 +1,6 @@ -{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"), "state" : "CA", "price" : 41, "quantity" : 162, "stdDevPopQuantityForState" : 0 } -{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"), "state" : "CA", "price" : 13, "quantity" : 120, "stdDevPopQuantityForState" : 21 } -{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"), "state" : "CA", "price" : 12, "quantity" : 145, "stdDevPopQuantityForState" : 17.249798710580816 } -{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"), "state" : "WA", "price" : 43, "quantity" : 134, "stdDevPopQuantityForState" : 0 } -{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"), "state" : "WA", "price" : 13, "quantity" : 104, "stdDevPopQuantityForState" : 15 } -{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"), "state" : "WA", "price" : 14, "quantity" : 140, "stdDevPopQuantityForState" : 15.748015748023622 } \ No newline at end of file +{ _id : 4, type : "strawberry", orderDate : ISODate("2019-05-18T16:09:01Z"), state : "CA", price : 41, quantity : 162, stdDevPopQuantityForState : 0 } +{ _id : 0, type : "chocolate", orderDate : ISODate("2020-05-18T14:10:30Z"), state : "CA", price : 13, quantity : 120, stdDevPopQuantityForState : 21 } +{ _id : 2, type : "vanilla", orderDate : ISODate("2021-01-11T06:31:15Z"), state : "CA", price : 12, quantity : 145, stdDevPopQuantityForState : 17.249798710580816 } +{ _id : 5, type : "strawberry", orderDate : ISODate("2019-01-08T06:12:03Z"), state : "WA", price : 43, quantity : 134, stdDevPopQuantityForState : 0 } +{ _id : 3, type : "vanilla", orderDate : ISODate("2020-02-08T13:13:23Z"), state : "WA", price : 13, quantity : 104, stdDevPopQuantityForState : 15 } +{ _id : 1, type : "chocolate", orderDate : ISODate("2021-03-20T11:30:05Z"), state : "WA", price : 14, quantity : 140, stdDevPopQuantityForState : 15.748015748023622 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevSamp/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevSamp/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevSamp/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevSamp/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevSamp/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevSamp/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevSamp/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/stdDevSamp/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/strLenBytes/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/strLenBytes/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/strLenBytes/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/strLenBytes/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/strLenCP/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/strLenCP/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/strLenCP/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/strLenCP/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/strcasecmp/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/strcasecmp/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/strcasecmp/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/strcasecmp/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/substrBytes/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/substrBytes/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/substrBytes/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/substrBytes/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/substrBytes/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/substrBytes/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/substrBytes/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/substrBytes/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/substrCP/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/substrCP/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/substrCP/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/substrCP/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/substrCP/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/substrCP/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/substrCP/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/substrCP/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/subtract/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/sum/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/switch/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/switch/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/switch/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/switch/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/tan/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/tan/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/tan/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/tan/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/tan/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/tan/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/tan/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/tan/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/tanh/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/tanh/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/tanh/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/tanh/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/tanh/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/tanh/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/tanh/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/tanh/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toBool/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toBool/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toBool/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toBool/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toDate/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toDate/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toDate/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toDate/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toDecimal/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toDecimal/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toDecimal/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toDecimal/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toDouble/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toDouble/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toDouble/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toDouble/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toHashedIndexKey/ignored b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toHashedIndexKey/ignored new file mode 100644 index 00000000000..2d9c1ea23e8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toHashedIndexKey/ignored @@ -0,0 +1 @@ +seems ill-suited to morphia's usecase. can be persuaded otherwise. \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toInt/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toInt/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toInt/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toInt/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toLong/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toLong/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toLong/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toLong/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toLower/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toLower/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toLower/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toLower/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toObjectId/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toObjectId/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toObjectId/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toObjectId/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toString/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toString/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toString/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toString/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/action.json new file mode 100644 index 00000000000..3bc55b178c8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/action.json @@ -0,0 +1,9 @@ +{ + $project: { + name: 1, + price: 1, + UUID: { + $toUUID: "$UUID" + } + } + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/data.json new file mode 100644 index 00000000000..e65228ec84f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/data.json @@ -0,0 +1 @@ +{ name: "laptop", price: 400, UUID: "0e3b9063-8abd-4eb3-9f9f-f4c59fd30a60" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/expected.json new file mode 100644 index 00000000000..053f5d3e446 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/expected.json @@ -0,0 +1 @@ +{ _id: ObjectId('669945ab610b080391a8e2f5'), name: 'laptop', price: 400, UUID: UUID('0e3b9063-8abd-4eb3-9f9f-f4c59fd30a60') } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/name b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUUID/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUpper/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/toUpper/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/toUpper/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/toUpper/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/top/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/top/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/top/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/top/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/top/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/top/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/top/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/top/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/topN/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/trim/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/trim/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/trim/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/trim/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/trunc/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/trunc/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/trunc/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/trunc/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/tsIncrement/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/tsIncrement/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/tsIncrement/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/tsIncrement/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/tsSecond/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/tsSecond/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/tsSecond/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/tsSecond/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/type/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/type/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/type/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/type/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/unsetField/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/week/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/week/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/week/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/week/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/year/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/year/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/year/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/year/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/zip/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/zip/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/zip/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/zip/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/expressions/zip/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/expressions/zip/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/expressions/zip/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/expressions/zip/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/data.json index 9e2ff9c39b2..f7351c51420 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/data.json @@ -1,2 +1,2 @@ -{ _id: 1, student: "Maya", homework: [ 10, 5, 10 ], quiz: [ 10, 8 ], extraCredit: 0} -{ _id: 2, student: "Ryan", homework: [ 5, 6, 5 ], quiz: [ 8, 8 ], extraCredit: 8} \ No newline at end of file +{ _id: 1, student: "Maya", homework: [ 10, 5, 10 ], quiz: [ 10, 8 ], extraCredit: 0 }, +{ _id: 2, student: "Ryan", homework: [ 5, 6, 5 ], quiz: [ 8, 8 ], extraCredit: 8 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/expected.json index ff777f71222..11d8a56efa8 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example1/expected.json @@ -1,2 +1,2 @@ -{ "_id" : 1, "student" : "Maya", "homework" : [ 10, 5, 10 ], "quiz" : [ 10, 8 ], "extraCredit" : 0, "totalHomework" : 25, "totalQuiz" : 18, "totalScore" : 43} -{ "_id" : 2, "student" : "Ryan", "homework" : [ 5, 6, 5 ], "quiz" : [ 8, 8 ], "extraCredit" : 8, "totalHomework" : 16, "totalQuiz" : 16, "totalScore" : 40} \ No newline at end of file +{ _id: 1, student: "Maya", homework: [ 10, 5, 10 ], quiz: [ 10, 8 ], extraCredit: 0, totalHomework: 25, totalQuiz: 18, totalScore: 43 }, +{ _id: 2, student: "Ryan", homework: [ 5, 6, 5 ], quiz: [ 8, 8 ], extraCredit: 8, totalHomework: 16, totalQuiz: 16, totalScore: 40 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/action.json new file mode 100644 index 00000000000..aa6a202fe7a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/action.json @@ -0,0 +1 @@ +{ $addFields: { "specs.fuel_type": "unleaded" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/expected.json index a0a271c79d3..6c567843082 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/expected.json @@ -1,3 +1,3 @@ -{ _id: 1, type: "car", specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } } -{ _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } } +{ _id: 1, type: "car", specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } }, +{ _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } }, { _id: 3, type: "jet ski", specs: { fuel_type: "unleaded" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/pipeline.json deleted file mode 100644 index f86ccfa0a17..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example2/pipeline.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - $addFields: { - "specs.fuel_type": "unleaded" - } - } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example4/expected.json index 8b9a6905a0a..ef374b838d7 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example4/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/addFields/example4/expected.json @@ -1 +1 @@ -{ "_id" : 1, "student" : "Maya", "homework" : [ 10, 5, 10, 7 ], "quiz" : [ 10, 8 ], "extraCredit" : 0 } \ No newline at end of file +[ { _id: 1, student: "Maya", homework: [ 10, 5, 10, 7 ], quiz: [ 10, 8 ], extraCredit: 0 } ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/bucket/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/bucket/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/bucket/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/bucket/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/bucket/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/bucket/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/bucket/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/bucket/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/bucketAuto/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/count/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/count/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/count/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/count/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/action.json new file mode 100644 index 00000000000..65013e50979 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/action.json @@ -0,0 +1,2 @@ +{ $currentOp : { allUsers: true, idleSessions: true } }, + { $match : { active: false, transaction : { $exists: true } } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/expected.json index 33fd518c6c6..5dae814279a 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/expected.json @@ -1 +1 @@ -"stepDurations" : { "writingParticipantListMicros" : NumberLong(17801), "totalCommitDurationMicros" : NumberLong(42488463), "waitingForVotesMicros" : NumberLong(30378502), "writingDecisionMicros" : NumberLong(15015), "waitingForDecisionAcksMicros" : NumberLong(12077145), "deletingCoordinatorDocMicros" : NumberLong(6009)}, \ No newline at end of file +{ "type" : "idleSession", "host" : "example.mongodb.com:27017", "desc" : "inactive transaction", "client" : "198.51.100.1:50428", "connectionId" : NumberLong(32), "appName" : "", "clientMetadata" : { "driver" : { "name" : "PyMongo", "version" : "3.9.0" }, "os" : { "type" : "Darwin", "name" : "Darwin", "architecture" : "x86_64", "version" : "10.14.5" }, "platform" : "CPython 3.7.1.final.0" }, "lsid" : { "id" : UUID("ff21e1a9-a130-4fe0-942f-9e6b6c67ea3c"), "uid" : BinData(0,"3pxqkATNUYKV/soT7qqKE0zC0BFb0pBz1pk4xXcSHsI=") }, "transaction" : { "parameters" : { "txnNumber" : NumberLong(4), "autocommit" : false, "readConcern" : { "level" : "snapshot", "afterClusterTime" : Timestamp(1563892246, 1) } }, "readTimestamp" : Timestamp(0, 0), "startWallClockTime" : "2019-07-23T10:30:49.461-04:00", "timeOpenMicros" : NumberLong(1913590), "timeActiveMicros" : NumberLong(55), "timeInactiveMicros" : NumberLong(1913535), "expiryTime" : "2019-07-23T10:31:49.461-04:00" }, "waitingForLock" : false, "active" : false, "locks" : { "ReplicationStateTransition" : "w", "Global" : "w", "Database" : "w", "Collection" : "w" }, "lockStats" : { "ReplicationStateTransition" : { "acquireCount" : { "w" : NumberLong(5) } }, "Global" : { "acquireCount" : { "r" : NumberLong(3), "w" : NumberLong(1) } }, "Database" : { "acquireCount" : { "r" : NumberLong(2), "w" : NumberLong(1) } }, "Collection" : { "acquireCount" : { "w" : NumberLong(1) } }, "Mutex" : { "acquireCount" : { "r" : NumberLong(3) } }, "oplog" : { "acquireCount" : { "r" : NumberLong(2) } } }, "waitingForFlowControl" : false, "flowControlStats" : {},} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/name index 88d050b1908..4ef283c9b3b 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/name @@ -1 +1 @@ -main \ No newline at end of file +Inactive Sessions :: Replica Set \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/pipeline.json deleted file mode 100644 index fb528f01e46..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example1/pipeline.json +++ /dev/null @@ -1,2 +0,0 @@ -{ $currentOp: { allUsers: true, idleSessions: true } }, - { $match: { desc: "transaction coordinator" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/action.json new file mode 100644 index 00000000000..65013e50979 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/action.json @@ -0,0 +1,2 @@ +{ $currentOp : { allUsers: true, idleSessions: true } }, + { $match : { active: false, transaction : { $exists: true } } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/expected.json index 665ed6c5f36..574a284fce0 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/expected.json @@ -1 +1 @@ -{ "name" : "shardA", "coordinator" : false, "readOnly" : false} \ No newline at end of file +{ "type" : "idleSession", "host" : "example.mongodb.com:27017", "desc" : "inactive transaction", "client" : "198.51.100.1:49618", "connectionId" : NumberLong(48), "appName" : "", "clientMetadata" : { "driver" : { "name" : "PyMongo", "version" : "3.9.0" }, "os" : { "type" : "Darwin", "name" : "Darwin", "architecture" : "x86_64", "version" : "10.14.6" }, "platform" : "CPython 3.7.1.final.0", "mongos" : { "host" : "example.mongodb.com:27017", "client" : "198.51.100.1:53268", "version" : "4.2.1" } }, "lsid" : { "id" : UUID("2c9ce111-133e-45b7-a00f-a7871005cae1"), "uid" : BinData(0,"3pxqkATNUYKV/soT7qqKE0zC0BFb0pBz1pk4xXcSHsI=") }, "active" : false, "transaction" : { "parameters" : { "txnNumber" : NumberLong(2), "autocommit" : false, "readConcern" : { "level" : "snapshot", "afterClusterTime" : Timestamp(1571869019, 2) } }, "globalReadTimestamp" : Timestamp(1571869019, 2), "startWallClockTime" : "2019-10-23T18:16:59.341-04:00", "timeOpenMicros" : NumberLong(169244639), "timeActiveMicros" : NumberLong(535), "timeInactiveMicros" : NumberLong(169244104), "numParticipants" : 2, "participants" : [ { "name" : "shardB", "coordinator" : true, "readOnly" : false }, { "name" : "shardA", "coordinator" : false, "readOnly" : false } ], "numReadOnlyParticipants" : 0, "numNonReadOnlyParticipants" : 2 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/name index 2c27db5a54c..776568f7e07 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/name @@ -1 +1 @@ -Sampled Queries \ No newline at end of file +Inactive Sessions :: Sharded Cluster (localOps: true) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/pipeline.json deleted file mode 100644 index a9175a104a2..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example2/pipeline.json +++ /dev/null @@ -1,4 +0,0 @@ - [ - { $currentOp: { allUsers: true, localOps: true } }, - { $match: { desc: "query analyzer" } } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/action.json new file mode 100644 index 00000000000..65013e50979 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/action.json @@ -0,0 +1,2 @@ +{ $currentOp : { allUsers: true, idleSessions: true } }, + { $match : { active: false, transaction : { $exists: true } } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/expected.json new file mode 100644 index 00000000000..def33f10547 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/expected.json @@ -0,0 +1,2 @@ +{ "shard" : "shardB", "type" : "idleSession", "host" : "shardB.mongodb.com:27018", "desc" : "inactive transaction", "client_s" : "198.51.100.1:53961", "connectionId" : NumberLong(63), "appName" : "", "clientMetadata" : { "driver" : { "name" : "PyMongo", "version" : "3.9.0" }, "os" : { "type" : "Darwin", "name" : "Darwin", "architecture" : "x86_64", "version" : "10.14.6" }, "platform" : "CPython 3.7.1.final.0", "mongos" : { "host" : "example.mongodb.com:27017", "client" : "198.51.100.1:53976", "version" : "4.2.0" } }, "lsid" : { "id" : UUID("720d403c-8daf-40bb-b61e-329e20b0493b"), "uid" : BinData(0,"3pxqkATNUYKV/soT7qqKE0zC0BFb0pBz1pk4xXcSHsI=") }, "transaction" : { "parameters" : { "txnNumber" : NumberLong(1), "autocommit" : false, "readConcern" : { "level" : "snapshot" } }, "readTimestamp" : Timestamp(0, 0), "startWallClockTime" : "2019-10-21T18:31:12.192-04:00", "timeOpenMicros" : NumberLong(24137008), "timeActiveMicros" : NumberLong(52), "timeInactiveMicros" : NumberLong(24136956), "expiryTime" : "2019-10-21T18:32:12.192-04:00" }, "waitingForLock" : false, "active" : false, "locks" : { "ReplicationStateTransition" : "w", "Global" : "w", "Database" : "w", "Collection" : "w" }, "lockStats" : { "ReplicationStateTransition" : { "acquireCount" : { "w" : NumberLong(3) } }, "Global" : { "acquireCount" : { "r" : NumberLong(1), "w" : NumberLong(1) } }, "Database" : { "acquireCount" : { "r" : NumberLong(1), "w" : NumberLong(1) } }, "Collection" : { "acquireCount" : { "r" : NumberLong(1), "w" : NumberLong(1) } }, "Mutex" : { "acquireCount" : { "r" : NumberLong(6) } } }} +{ "shard" : "shardA", "type" : "idleSession", ...} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/name new file mode 100644 index 00000000000..37baebbfd20 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example3/name @@ -0,0 +1 @@ +Inactive Sessions :: Sharded Cluster \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/action.json new file mode 100644 index 00000000000..b86e5bbb438 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/action.json @@ -0,0 +1,2 @@ +{ $currentOp: { allUsers: true, localOps: true } }, + { $match: { desc: "query analyzer" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/expected.json new file mode 100644 index 00000000000..19b579ec1e5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/expected.json @@ -0,0 +1 @@ +{ "desc" : "query analyzer", "ns" : "testDb.testColl", "collUuid" : UUID("ed9dfb1d-5b7c-4c6b-82e9-b0f537335795"), "samplesPerSecond" : 5, "startTime" : ISODate("2023-08-08T16:23:22.846Z"), "sampledReadsCount" : NumberLong(2), "sampledReadsBytes" : NumberLong(346), "sampledWritesCount" : NumberLong(3), "sampledWritesBytes" : NumberLong(904)} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/name new file mode 100644 index 00000000000..420905f2e2c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example4/name @@ -0,0 +1 @@ +Sampled Queries :: Replica Set \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/action.json new file mode 100644 index 00000000000..b86e5bbb438 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/action.json @@ -0,0 +1,2 @@ +{ $currentOp: { allUsers: true, localOps: true } }, + { $match: { desc: "query analyzer" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/expected.json new file mode 100644 index 00000000000..0f567f6a2e7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/expected.json @@ -0,0 +1 @@ +{ "desc" : "query analyzer", "ns" : "testDb.testColl", "collUuid" : UUID("5130b4df-5966-434f-85f0-f8956b5ca74e"), "samplesPerSecond" : 5, "startTime" : ISODate("2023-08-08T16:15:07.427Z"), "sampledReadsCount" : NumberLong(2), "sampledWritesCount" : NumberLong(3)} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/name new file mode 100644 index 00000000000..e3567ddfbac --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example5/name @@ -0,0 +1 @@ +Sampled Queries :: Sharded Cluster: mongos \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/action.json new file mode 100644 index 00000000000..b86e5bbb438 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/action.json @@ -0,0 +1,2 @@ +{ $currentOp: { allUsers: true, localOps: true } }, + { $match: { desc: "query analyzer" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/expected.json new file mode 100644 index 00000000000..78dad1d7670 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/expected.json @@ -0,0 +1 @@ +{ "desc" : "query analyzer", "ns" : "testDb.testColl", "collUuid" : UUID("5130b4df-5966-434f-85f0-f8956b5ca74e"), "startTime" : ISODate("2023-08-08T16:15:07.427Z"), "sampledReadsCount" : NumberLong(2), "sampledReadsBytes" : NumberLong(346), "sampledWritesCount" : NumberLong(3), "sampledWritesBytes" : NumberLong(904)} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/name new file mode 100644 index 00000000000..7edddc1f6c0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/currentOp/example6/name @@ -0,0 +1 @@ +Sampled Queries :: Sharded Cluster: mongod --shardsvr \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/densify/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/densify/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/densify/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/densify/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/densify/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/densify/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/densify/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/densify/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/documents/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/documents/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/documents/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/documents/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/documents/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/documents/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/documents/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/documents/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/facet/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/facet/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/facet/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/facet/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/fill/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/action.json new file mode 100644 index 00000000000..628901fd63d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/action.json @@ -0,0 +1,10 @@ +{ + $geoNear: { + near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] }, + distanceField: "dist.calculated", + spherical: true, + maxDistance: 2, + query: { category: "Parks" }, + includeLocs: "dist.location" + } + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/data1.json new file mode 100644 index 00000000000..f0b431ecfb0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/data1.json @@ -0,0 +1 @@ +{ location: "2dsphere" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/pipeline.json deleted file mode 100644 index 1fdffa1f0c7..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example1/pipeline.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - $geoNear: { - near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] }, - distanceField: "dist.calculated", - spherical: true, - maxDistance: 2, - query: { category: "Parks" }, - includeLocs: "dist.location" - } - } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/action.json new file mode 100644 index 00000000000..980f427660f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/action.json @@ -0,0 +1,10 @@ +{ + $geoNear: { + near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] }, + distanceField: "dist.calculated", + minDistance: 2, + query: { category: "Parks" }, + includeLocs: "dist.location", + spherical: true + } + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/data1.json new file mode 100644 index 00000000000..f0b431ecfb0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/data1.json @@ -0,0 +1 @@ +{ location: "2dsphere" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/name index 32ffe4f7b0f..40d6d23447a 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/name @@ -1 +1 @@ -$geoNear with the ``let`` option \ No newline at end of file +Minimum Distance \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/data.json index 2dc303d4174..b85ef3d441e 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/data.json @@ -1,3 +1,3 @@ -{ _id: 1, name: "Central Park", location: { type: "Point", coordinates: [ -73.97, 40.77 ] }, category: "Parks" }, -{ _id: 2, name: "Sara D. Roosevelt Park", location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] }, category: "Parks" }, -{ _id: 3, name: "Polo Grounds", location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] }, category: "Stadiums" } \ No newline at end of file +{ name: "Central Park", location: { type: "Point", coordinates: [ -73.97, 40.77 ] }, category: "Parks" }, +{ name: "Sara D. Roosevelt Park", location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] }, category: "Parks" }, +{ name: "Polo Grounds", location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] }, category: "Stadiums" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/data1.json new file mode 100644 index 00000000000..f0b431ecfb0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/data1.json @@ -0,0 +1 @@ +{ location: "2dsphere" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/expected.json index 59ed43b7ec4..931d273649d 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/expected.json @@ -1 +1,2 @@ -{ _id: 2, name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', joinedField: [ { _id: 2, name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', distance: 0 }, { _id: 1, name: 'Central Park', location: { type: 'Point', coordinates: [ -73.97, 40.77 ] }, category: 'Parks', distance: 5962.448255235006 }, { _id: 3, name: 'Polo Grounds', location: { type: 'Point', coordinates: [ -73.9375, 40.8303 ] }, category: 'Stadiums', distance: 13206.535424939102 } ]} \ No newline at end of file +{ _id: ObjectId("61715cf9b0c1d171bb498fd7"), name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', distance: 1.4957325341976439e-7, dist: { location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] } }}, +{ _id: ObjectId("61715cf9b0c1d171bb498fd6"), name: 'Central Park', location: { type: 'Point', coordinates: [ -73.97, 40.77 ] }, category: 'Parks', distance: 0.0009348548688841822, dist: { location: { type: 'Point', coordinates: [ -73.97, 40.77 ] } }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/lock b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/lockd similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/lock rename to core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/lockd diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/name index 6d3756e916f..32ffe4f7b0f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/name @@ -1 +1 @@ -$geoNear with Bound ``let`` Option \ No newline at end of file +$geoNear with the ``let`` option \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/action.json similarity index 91% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/action.json index b15ba593060..46f2f225511 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example3/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/action.json @@ -1,6 +1,6 @@ { $lookup: { - from: "aggtest", + from: "example_test", as: "joinedField", let: { pt: "$location" }, pipeline: [ diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/data1.json new file mode 100644 index 00000000000..f0b431ecfb0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/data1.json @@ -0,0 +1 @@ +{ location: "2dsphere" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/expected.json index e693dee741c..6e7a1d825bb 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/expected.json @@ -1,2 +1 @@ -{ "_id" : 2, "name" : "Sara D. Roosevelt Park", "location" : { "type" : "Point", "coordinates" : [ -73.9928, 40.7193 ] }, "category" : "Parks", "dist" : { "calculated" : 974.175764916902 }} -{ "_id" : 1, "name" : "Central Park", "location" : { "type" : "Point", "coordinates" : [ -73.97, 40.77 ] }, "legacy" : [ -73.97, 40.77 ], "category" : "Parks", "dist" : { "calculated" : 5887.927929580962 }} \ No newline at end of file +{ _id: ObjectId("61715cf9b0c1d171bb498fd7"), name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193] }, category: 'Parks', joinedField: [ { _id: ObjectId("61715cf9b0c1d171bb498fd7"), name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', distance: 0.0 }, { _id: ObjectId("61715cf9b0c1d171bb498fd6"), name: 'Central Park', location: { type: 'Point', coordinates: [ -73.97, 40.77 ] }, category: 'Parks', distance: 5962.448255235006 }, { _id: ObjectId("61715cfab0c1d171bb498fd8"), name: 'Polo Grounds', location: { type: 'Point', coordinates: [ -73.9375, 40.8303 ] }, category: 'Stadiums', distance: 13206.535424939102 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/name index 2f0da3183b8..6d3756e916f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/name @@ -1 +1 @@ -Specify Which Geospatial Index to Use \ No newline at end of file +$geoNear with Bound ``let`` Option \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/action.json similarity index 89% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/action.json index 11da63ba185..1e05fb4a97d 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example4/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/action.json @@ -1,5 +1,4 @@ -[ - { +{ $geoNear: { near: { type: "Point", coordinates: [ -73.98142 , 40.71782 ] }, key: "location", @@ -7,5 +6,4 @@ query: { "category": "Parks" } } }, - { $limit: 5 } -] \ No newline at end of file + { $limit: 5 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/data.json index e69de29bb2d..9f570ed1650 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/data.json @@ -0,0 +1 @@ +{ "_id" : 3, "name" : "Polo Grounds", "location": { "type" : "Point", "coordinates" : [ -73.9375, 40.8303 ] }, "legacy" : [ -73.9375, 40.8303 ], "category" : "Stadiums"} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/expected.json index 8edec6f22e3..e7d42cb9399 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/expected.json @@ -1 +1,2 @@ -{ _id: ObjectId("61715cf9b0c1d171bb498fd7"), name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', joinedField: [ { _id: ObjectId("61715cf9b0c1d171bb498fd7"), name: 'Sara D. Roosevelt Park', location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] }, category: 'Parks', distance: 0 }, { _id: ObjectId("61715cf9b0c1d171bb498fd6"), name: 'Central Park', location: { type: 'Point', coordinates: [ -73.97, 40.77 ] }, category: 'Parks', distance: 5962.448255234964 }, { _id: ObjectId("61715cfab0c1d171bb498fd8"), name: 'Polo Grounds', location: { type: 'Point', coordinates: [ -73.9375, 40.8303 ] }, category: 'Stadiums', distance: 13206.535424939102 } ]} \ No newline at end of file +{ "_id" : 8, "name" : "Sara D. Roosevelt Park", "location" : { "type" : "Point", "coordinates" : [ -73.9928, 40.7193 ] }, "category" : "Parks", "dist" : { "calculated" : 974.175764916902 }} +{ "_id" : 1, "name" : "Central Park", "location" : { "type" : "Point", "coordinates" : [ -73.97, 40.77 ] }, "legacy" : [ -73.97, 40.77 ], "category" : "Parks", "dist" : { "calculated" : 5887.92792958097 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/index.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/index.json new file mode 100644 index 00000000000..f0b431ecfb0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/index.json @@ -0,0 +1 @@ +{ location: "2dsphere" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/name index 6d3756e916f..2f0da3183b8 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/name @@ -1 +1 @@ -$geoNear with Bound ``let`` Option \ No newline at end of file +Specify Which Geospatial Index to Use \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/pipeline.json deleted file mode 100644 index b88ddb16f42..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example5/pipeline.json +++ /dev/null @@ -1,23 +0,0 @@ - [ - { - $lookup: { - from: "aggtest", - as: "joinedField", - let: { pt: "$location" }, - pipeline: [ - { - $geoNear: { - near: { - "type": "Point", - "coordinates": [-73.98142, 40.71782] - }, - distanceField: "distance" - } - } - ] - } - }, - { - $match: { name: "Sara D. Roosevelt Park" } - } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/data.json deleted file mode 100644 index 1e1d7463736..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/data.json +++ /dev/null @@ -1 +0,0 @@ -{ "_id" : 3, "name" : "Polo Grounds", "location": { "type" : "Point", "coordinates" : [ -73.9375, 40.8303 ] }, "legacy" : [ -73.9375, 40.8303 ], "category" : "Stadiums"} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/expected.json deleted file mode 100644 index 885758202fb..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/expected.json +++ /dev/null @@ -1,2 +0,0 @@ -{ "_id" : 8, "name" : "Sara D. Roosevelt Park", "location" : { "type" : "Point", "coordinates" : [ -73.9928, 40.7193 ] }, "category" : "Parks", "dist" : { "calculated" : 974.175764916902 }} -{ "_id" : 1, "name" : "Central Park", "location" : { "type" : "Point", "coordinates" : [ -73.97, 40.77 ] }, "legacy" : [ -73.97, 40.77 ], "category" : "Parks", "dist" : { "calculated" : 5887.92792958097 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/name deleted file mode 100644 index 2f0da3183b8..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/name +++ /dev/null @@ -1 +0,0 @@ -Specify Which Geospatial Index to Use \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/pipeline.json deleted file mode 100644 index 11da63ba185..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/geoNear/example6/pipeline.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - $geoNear: { - near: { type: "Point", coordinates: [ -73.98142 , 40.71782 ] }, - key: "location", - distanceField: "dist.calculated", - query: { "category": "Parks" } - } - }, - { $limit: 5 } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example1/action.json similarity index 85% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example1/action.json index edffc0d9aa3..f58cd658c8d 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example1/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example1/action.json @@ -1,7 +1,7 @@ [ { $graphLookup: { - from: "aggtest", + from: "example_test", startWith: "$reportsTo", connectFromField: "reportsTo", connectToField: "name", diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example3/action.json similarity index 92% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example3/action.json index 40b6913e0ba..ac87f4f13e8 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example3/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/graphLookup/example3/action.json @@ -1,7 +1,7 @@ [ { $match: { "name": "Tanya Jordan" } }, { $graphLookup: { - from: "aggtest", + from: "example_test", startWith: "$friends", connectFromField: "friends", connectToField: "name", diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/group/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/group/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/group/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/group/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/group/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/group/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/group/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/group/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/group/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/group/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/group/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/data.json index 2b31c9954cb..830d101e882 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/data.json @@ -1,3 +1,3 @@ -{ "_id" : 1, "item" : "abc", "price" : 12, "quantity" : 2, "type": "apparel" } -{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "type": "electronics" } -{ "_id" : 3, "item" : "abc", "price" : 10, "quantity" : 5, "type": "apparel" } \ No newline at end of file +{ _id : 1, item : "abc", price : 12, quantity : 2, type: "apparel" }, +{ _id : 2, item : "jkl", price : 20, quantity : 1, type: "electronics" }, +{ _id : 3, item : "abc", price : 10, quantity : 5, type: "apparel" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/data1.json new file mode 100644 index 00000000000..f3e60da801c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/data1.json @@ -0,0 +1,4 @@ +{ item: 1, quantity: 1 } +{ type: 1, item: 1 } +{ price: 1 }, +{ partialFilterExpression: { type: "apparel" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/expected.json index e23d2abe19f..c7c45cd91c4 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/expected.json @@ -1,4 +1,4 @@ -{ "name" : "item_1_quantity_1", "key" : { "item" : 1, "quantity" : 1 }, "host" : "examplehost.local:27018", "accesses" : { "ops" : NumberLong(1), "since" : ISODate("2020-02-10T21:11:23.059Z") }, "shard" : "shardA", "spec" : { "v" : 2, "key" : { "item" : 1, "quantity" : 1 }, "name" : "item_1_quantity_1" }} -{ "name" : "item_1_price_1", "key" : { "item" : 1, "price" : 1 }, "host" : "examplehost.local:27018", "accesses" : { "ops" : NumberLong(1), "since" : ISODate("2020-02-10T21:11:23.233Z") }, "shard" : "shardA", "spec" : { "v" : 2, "key" : { "item" : 1, "price" : 1 }, "name" : "item_1_price_1" }} -{ "name" : "item_1", "key" : { "item" : 1 }, "host" : "examplehost.local:27018", "accesses" : { "ops" : NumberLong(0), "since" : ISODate("2020-02-10T21:11:22.947Z") }, "shard" : "shardA", "spec" : { "v" : 2, "key" : { "item" : 1 }, "name" : "item_1" }} -{ "name" : "_id_", "key" : { "_id" : 1 }, "host" : "examplehost.local:27018", "accesses" : { "ops" : NumberLong(0), "since" : ISODate("2020-02-10T21:11:18.298Z") }, "shard" : "shardA", "spec" : { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }} \ No newline at end of file +{ name: 'type_1_item_1', key: { type: 1, item: 1 }, host: 'examplehost.local:27018', accesses: { ops: NumberLong("1"), since: ISODate("2024-05-02T15:07:21.420Z") }, shard: "shardA", spec: { v: 2, key: { type: 1, item: 1 }, name: 'type_1_item_1' } }, +{ name: 'item_1_quantity_1', key: { item: 1, quantity: 1 }, host: 'examplehost.local:27018', accesses: { ops: NumberLong("1"), since: ISODate("2024-05-02T15:07:21.254Z") }, shard: "shardA", spec: { v: 2, key: { item: 1, quantity: 1 }, name: 'item_1_quantity_1' } }, +{ name: '_id_', key: { _id: 1 }, host: 'examplehost.local:27018', accesses: { ops: NumberLong("0"), since: ISODate("2024-05-02T15:07:13.274Z") }, shard: "shardA", spec: { v: 2, key: { _id: 1 }, name: '_id_' } }, +{ name: 'price_1', key: { price: 1 }, host: 'examplehost.local:27018', accesses: { ops: NumberLong("0"), since: ISODate("2024-05-02T15:07:54.847Z") }, shard: "shardA", spec: { v: 2, key: { price: 1 }, name: 'price_1', partialFilterExpression: { type: 'apparel' } } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/lock b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/lock new file mode 100644 index 00000000000..efc519961ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/indexStats/example1/lock @@ -0,0 +1 @@ +the example contains some extraneous data and example results that will never be the same \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/limit/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/limit/example1/action.json new file mode 100644 index 00000000000..73ccbb5dc19 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/limit/example1/action.json @@ -0,0 +1 @@ +{ $limit : 5 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/limit/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/limit/example1/pipeline.json deleted file mode 100644 index 56077ba4b64..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/limit/example1/pipeline.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - { $limit : 5 } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example6/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example6/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example6/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/lookup/example6/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/action.json new file mode 100644 index 00000000000..e85260cdc86 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/action.json @@ -0,0 +1 @@ +{ $match : { author : "dave" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/expected.json new file mode 100644 index 00000000000..0d70fb568d2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/expected.json @@ -0,0 +1,2 @@ +{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 } +{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/name index 88d050b1908..8d34f32d65f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example1/name @@ -1 +1 @@ -main \ No newline at end of file +Equality Match \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/expected.json index 0d70fb568d2..46e1a351988 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/expected.json @@ -1,2 +1 @@ -{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 } -{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 } \ No newline at end of file +{ "_id" : null, "count" : 5 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/lock b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/lock similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/lock rename to core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/lock diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/name index 8d34f32d65f..dd06cdf3e54 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/name @@ -1 +1 @@ -Equality Match \ No newline at end of file +Perform a Count \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/pipeline.json deleted file mode 100644 index 8af4093e7da..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example2/pipeline.json +++ /dev/null @@ -1 +0,0 @@ - [ { $match : { author : "dave" } } ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/data.json deleted file mode 100644 index f2e95a25510..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 } -{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 } -{ "_id" : ObjectId("55f5a192d4bede9ac365b257"), "author" : "ahn", "score" : 60, "views" : 1000 } -{ "_id" : ObjectId("55f5a192d4bede9ac365b258"), "author" : "li", "score" : 55, "views" : 5000 } -{ "_id" : ObjectId("55f5a1d3d4bede9ac365b259"), "author" : "annT", "score" : 60, "views" : 50 } -{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25a"), "author" : "li", "score" : 94, "views" : 999 } -{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25b"), "author" : "ty", "score" : 95, "views" : 1000 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/expected.json deleted file mode 100644 index 46e1a351988..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/expected.json +++ /dev/null @@ -1 +0,0 @@ -{ "_id" : null, "count" : 5 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/name deleted file mode 100644 index dd06cdf3e54..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/match/example3/name +++ /dev/null @@ -1 +0,0 @@ -Perform a Count \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/data1.json new file mode 100644 index 00000000000..b861707842a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/data1.json @@ -0,0 +1,6 @@ +{ "_id" : { "fiscal_year" : 2017, "dept" : "A" }, "salaries" : 220000 } +{ "_id" : { "fiscal_year" : 2017, "dept" : "Z" }, "salaries" : 115000 } +{ "_id" : { "fiscal_year" : 2018, "dept" : "A" }, "salaries" : 215000 } +{ "_id" : { "fiscal_year" : 2018, "dept" : "Z" }, "salaries" : 280000 } +{ "_id" : { "fiscal_year" : 2019, "dept" : "A" }, "salaries" : 125000 } +{ "_id" : { "fiscal_year" : 2019, "dept" : "Z" }, "salaries" : 310000 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/expected.json index b861707842a..9640e2b3a3a 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example2/expected.json @@ -2,5 +2,6 @@ { "_id" : { "fiscal_year" : 2017, "dept" : "Z" }, "salaries" : 115000 } { "_id" : { "fiscal_year" : 2018, "dept" : "A" }, "salaries" : 215000 } { "_id" : { "fiscal_year" : 2018, "dept" : "Z" }, "salaries" : 280000 } -{ "_id" : { "fiscal_year" : 2019, "dept" : "A" }, "salaries" : 125000 } -{ "_id" : { "fiscal_year" : 2019, "dept" : "Z" }, "salaries" : 310000 } \ No newline at end of file +{ "_id" : { "fiscal_year" : 2019, "dept" : "A" }, "salaries" : 275000 } +{ "_id" : { "fiscal_year" : 2019, "dept" : "Z" }, "salaries" : 410000 } +{ "_id" : { "fiscal_year" : 2020, "dept" : "Z" }, "salaries" : 240000 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data1.json new file mode 100644 index 00000000000..1ef4c1f3456 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data1.json @@ -0,0 +1,4 @@ +{ "_id" : ObjectId("5cd8c68261baa09e9f3622be"), "employees" : [ "Ant", "Gecko" ], "dept" : "A", "fiscal_year" : 2018 } +{ "_id" : ObjectId("5cd8c68261baa09e9f3622bf"), "employees" : [ "Ant", "Bee" ], "dept" : "A", "fiscal_year" : 2017 } +{ "_id" : ObjectId("5cd8c68261baa09e9f3622c0"), "employees" : [ "Bee", "Cat" ], "dept" : "Z", "fiscal_year" : 2018 } +{ "_id" : ObjectId("5cd8c68261baa09e9f3622c1"), "employees" : [ "Cat" ], "dept" : "Z", "fiscal_year" : 2017 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data2.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data2.json new file mode 100644 index 00000000000..334c390884e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data2.json @@ -0,0 +1 @@ +{ fiscal_year: 1, dept: 1 }, { unique: true } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data3.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data3.json new file mode 100644 index 00000000000..07407be5de1 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/data3.json @@ -0,0 +1,14 @@ +{ "_id" : 1, "employee" : "Ant", "dept" : "A", "salary" : 100000, "fiscal_year" : 2017 } +{ "_id" : 2, "employee" : "Bee", "dept" : "A", "salary" : 120000, "fiscal_year" : 2017 } +{ "_id" : 3, "employee" : "Cat", "dept" : "Z", "salary" : 115000, "fiscal_year" : 2017 } +{ "_id" : 4, "employee" : "Ant", "dept" : "A", "salary" : 115000, "fiscal_year" : 2018 } +{ "_id" : 5, "employee" : "Bee", "dept" : "Z", "salary" : 145000, "fiscal_year" : 2018 } +{ "_id" : 6, "employee" : "Cat", "dept" : "Z", "salary" : 135000, "fiscal_year" : 2018 } +{ "_id" : 7, "employee" : "Gecko", "dept" : "A", "salary" : 100000, "fiscal_year" : 2018 } +{ "_id" : 8, "employee" : "Ant", "dept" : "A", "salary" : 125000, "fiscal_year" : 2019 } +{ "_id" : 9, "employee" : "Bee", "dept" : "Z", "salary" : 160000, "fiscal_year" : 2019 } +{ "_id" : 10, "employee" : "Cat", "dept" : "Z", "salary" : 150000, "fiscal_year" : 2019 } +{ "_id" : 11, "employee" : "Wren", "dept" : "Z", "salary" : 100000, "fiscal_year" : 2019 } +{ "_id" : 12, "employee" : "Zebra", "dept" : "A", "salary" : 150000, "fiscal_year" : 2019 } +{ "_id" : 13, "employee" : "headcount1", "dept" : "Z", "salary" : 120000, "fiscal_year" : 2020 } +{ "_id" : 14, "employee" : "headcount2", "dept" : "Z", "salary" : 120000, "fiscal_year" : 2020 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/expected.json index 1ef4c1f3456..81874054f24 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example3/expected.json @@ -1,4 +1,6 @@ -{ "_id" : ObjectId("5cd8c68261baa09e9f3622be"), "employees" : [ "Ant", "Gecko" ], "dept" : "A", "fiscal_year" : 2018 } -{ "_id" : ObjectId("5cd8c68261baa09e9f3622bf"), "employees" : [ "Ant", "Bee" ], "dept" : "A", "fiscal_year" : 2017 } -{ "_id" : ObjectId("5cd8c68261baa09e9f3622c0"), "employees" : [ "Bee", "Cat" ], "dept" : "Z", "fiscal_year" : 2018 } -{ "_id" : ObjectId("5cd8c68261baa09e9f3622c1"), "employees" : [ "Cat" ], "dept" : "Z", "fiscal_year" : 2017 } \ No newline at end of file +{ "_id" : ObjectId("5caccc6a66b22dd8a8cc419f"), "employees" : [ "Ahn", "Bess" ], "dept" : "A", "fiscal_year" : 2017 } +{ "_id" : ObjectId("5caccc6a66b22dd8a8cc419e"), "employees" : [ "Ahn", "Gee" ], "dept" : "A", "fiscal_year" : 2018 } +{ "_id" : ObjectId("5caccd0b66b22dd8a8cc438e"), "employees" : [ "Ahn", "Zeb" ], "dept" : "A", "fiscal_year" : 2019 } +{ "_id" : ObjectId("5caccc6a66b22dd8a8cc41a0"), "employees" : [ "Carl" ], "dept" : "Z", "fiscal_year" : 2017 } +{ "_id" : ObjectId("5caccc6a66b22dd8a8cc41a1"), "employees" : [ "Bess", "Carl" ], "dept" : "Z", "fiscal_year" : 2018 } +{ "_id" : ObjectId("5caccd0b66b22dd8a8cc438d"), "employees" : [ "Bess", "Carl", "Wen" ], "dept" : "Z", "fiscal_year" : 2019 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/data1.json new file mode 100644 index 00000000000..6cd0b3ca19d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/data1.json @@ -0,0 +1,4 @@ +{ _id: 1, quarter: "2019Q1", region: "A", qty: 400, reportDate: ISODate("2019-04-02") }, +{ _id: 2, quarter: "2019Q1", region: "B", qty: 550, reportDate: ISODate("2019-04-02") }, +{ _id: 3, quarter: "2019Q1", region: "C", qty: 1000, reportDate: ISODate("2019-04-05") }, +{ _id: 4, quarter: "2019Q2", region: "B", qty: 500, reportDate: ISODate("2019-07-02") }, \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/data2.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/data2.json index 6cd0b3ca19d..c7fdf1de210 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/data2.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/data2.json @@ -1,4 +1,2 @@ -{ _id: 1, quarter: "2019Q1", region: "A", qty: 400, reportDate: ISODate("2019-04-02") }, -{ _id: 2, quarter: "2019Q1", region: "B", qty: 550, reportDate: ISODate("2019-04-02") }, -{ _id: 3, quarter: "2019Q1", region: "C", qty: 1000, reportDate: ISODate("2019-04-05") }, -{ _id: 4, quarter: "2019Q2", region: "B", qty: 500, reportDate: ISODate("2019-07-02") }, \ No newline at end of file +{ "_id" : "2019Q1", "sales" : 1950, "purchased" : 1200 } +{ "_id" : "2019Q2", "sales" : 500, "purchased" : 1700 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/expected.json index c7fdf1de210..1bc349eafdf 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example4/expected.json @@ -1,2 +1,2 @@ -{ "_id" : "2019Q1", "sales" : 1950, "purchased" : 1200 } -{ "_id" : "2019Q2", "sales" : 500, "purchased" : 1700 } \ No newline at end of file +{ "_id" : "2019Q2", "purchased" : 1700 } +{ "_id" : "2019Q1", "purchased" : 1200 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/action.json new file mode 100644 index 00000000000..dd68677330b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/action.json @@ -0,0 +1,18 @@ +db.cakeSales.insertOne( [ + { _id: 1, flavor: "chocolate", salesTotal: 1580, + salesTrend: "up" } +] ) +db.runCommand( { + aggregate: db.cakeSales.getName(), + pipeline: [ { + $merge: { + into: db.cakeSales.getName(), + let : { year: "2020" }, + whenMatched: [ { + $addFields: { "salesYear": "$$year" } + } ] + } + } ], + cursor: {} +} ) +db.cakeSales.find() \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/data.json index 3ed52d33c68..fb07bdf96cb 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/data.json @@ -1,17 +1,10 @@ - [ - { _id: 1, flavor: "chocolate", salesTotal: 1580, - salesTrend: "up" } -] ) -db.runCommand( { - aggregate: db.cakeSales.getName(), - pipeline: [ { - $merge: { - into: db.cakeSales.getName(), - let : { year: "2020" }, - whenMatched: [ { - $addFields: { "salesYear": "$$year" } - } ] - } - } ], - cursor: {} -} ) \ No newline at end of file +{ "_id" : 1, employee: "Ant", dept: "A", salary: 100000, fiscal_year: 2017 }, +{ "_id" : 2, employee: "Bee", dept: "A", salary: 120000, fiscal_year: 2017 }, +{ "_id" : 3, employee: "Cat", dept: "Z", salary: 115000, fiscal_year: 2017 }, +{ "_id" : 4, employee: "Ant", dept: "A", salary: 115000, fiscal_year: 2018 }, +{ "_id" : 5, employee: "Bee", dept: "Z", salary: 145000, fiscal_year: 2018 }, +{ "_id" : 6, employee: "Cat", dept: "Z", salary: 135000, fiscal_year: 2018 }, +{ "_id" : 7, employee: "Gecko", dept: "A", salary: 100000, fiscal_year: 2018 }, +{ "_id" : 8, employee: "Ant", dept: "A", salary: 125000, fiscal_year: 2019 }, +{ "_id" : 9, employee: "Bee", dept: "Z", salary: 160000, fiscal_year: 2019 }, +{ "_id" : 10, employee: "Cat", dept: "Z", salary: 150000, fiscal_year: 2019 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/pipeline.json deleted file mode 100644 index 564f8ac5a5d..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example6/pipeline.json +++ /dev/null @@ -1,4 +0,0 @@ - [ - { $group: { _id: { fiscal_year: "$fiscal_year", dept: "$dept" }, salaries: { $sum: "$salary" } } }, - { $merge : { into: { db: "reporting", coll: "budgets" }, on: "_id", whenMatched: "replace", whenNotMatched: "insert" } } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/action.json new file mode 100644 index 00000000000..5530ae967c6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/action.json @@ -0,0 +1,18 @@ +db.cakeSales.insertOne( + { _id: 1, flavor: "chocolate", salesTotal: 1580, + salesTrend: "up" } +) +db.runCommand( { + aggregate: db.cakeSales.getName(), + pipeline: [ { + $merge: { + into: db.cakeSales.getName(), + whenMatched: [ { + $addFields: { "salesYear": "$$year" } } + ] } + } + ], + cursor: {}, + let : { year: "2020" } +} ) +db.cakeSales.find() \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/data.json index 8e71348088e..fb07bdf96cb 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/data.json @@ -1,16 +1,10 @@ - { _id: 1, flavor: "chocolate", salesTotal: 1580, - salesTrend: "up" } -) -db.runCommand( { - aggregate: db.cakeSales.getName(), - pipeline: [ { - $merge: { - into: db.cakeSales.getName(), - whenMatched: [ { - $addFields: { "salesYear": "$$year" } } - ] } - } - ], - cursor: {}, - let : { year: "2020" } -} ) \ No newline at end of file +{ "_id" : 1, employee: "Ant", dept: "A", salary: 100000, fiscal_year: 2017 }, +{ "_id" : 2, employee: "Bee", dept: "A", salary: 120000, fiscal_year: 2017 }, +{ "_id" : 3, employee: "Cat", dept: "Z", salary: 115000, fiscal_year: 2017 }, +{ "_id" : 4, employee: "Ant", dept: "A", salary: 115000, fiscal_year: 2018 }, +{ "_id" : 5, employee: "Bee", dept: "Z", salary: 145000, fiscal_year: 2018 }, +{ "_id" : 6, employee: "Cat", dept: "Z", salary: 135000, fiscal_year: 2018 }, +{ "_id" : 7, employee: "Gecko", dept: "A", salary: 100000, fiscal_year: 2018 }, +{ "_id" : 8, employee: "Ant", dept: "A", salary: 125000, fiscal_year: 2019 }, +{ "_id" : 9, employee: "Bee", dept: "Z", salary: 160000, fiscal_year: 2019 }, +{ "_id" : 10, employee: "Cat", dept: "Z", salary: 150000, fiscal_year: 2019 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/pipeline.json deleted file mode 100644 index 564f8ac5a5d..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example7/pipeline.json +++ /dev/null @@ -1,4 +0,0 @@ - [ - { $group: { _id: { fiscal_year: "$fiscal_year", dept: "$dept" }, salaries: { $sum: "$salary" } } }, - { $merge : { into: { db: "reporting", coll: "budgets" }, on: "_id", whenMatched: "replace", whenNotMatched: "insert" } } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/action.json new file mode 100644 index 00000000000..1c66222c303 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/action.json @@ -0,0 +1,19 @@ +db.cakeSales.insertOne( + { _id: 1, flavor: "chocolate", salesTotal: 1580, + salesTrend: "up" } +) +db.runCommand( { + aggregate: db.cakeSales.getName(), + pipeline: [ { + $merge: { + into: db.cakeSales.getName(), + let : { year: "2020" }, + whenMatched: [ { + $addFields: { "salesYear": "$$year" } + } ] + } + } ], + cursor: {}, + let : { year: "2019" } +} ) +db.cakeSales.find() \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/data.json index 01a7b8153ca..fb07bdf96cb 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/data.json @@ -1,17 +1,10 @@ - { _id: 1, flavor: "chocolate", salesTotal: 1580, - salesTrend: "up" } -) -db.runCommand( { - aggregate: db.cakeSales.getName(), - pipeline: [ { - $merge: { - into: db.cakeSales.getName(), - let : { year: "2020" }, - whenMatched: [ { - $addFields: { "salesYear": "$$year" } - } ] - } - } ], - cursor: {}, - let : { year: "2019" } -} ) \ No newline at end of file +{ "_id" : 1, employee: "Ant", dept: "A", salary: 100000, fiscal_year: 2017 }, +{ "_id" : 2, employee: "Bee", dept: "A", salary: 120000, fiscal_year: 2017 }, +{ "_id" : 3, employee: "Cat", dept: "Z", salary: 115000, fiscal_year: 2017 }, +{ "_id" : 4, employee: "Ant", dept: "A", salary: 115000, fiscal_year: 2018 }, +{ "_id" : 5, employee: "Bee", dept: "Z", salary: 145000, fiscal_year: 2018 }, +{ "_id" : 6, employee: "Cat", dept: "Z", salary: 135000, fiscal_year: 2018 }, +{ "_id" : 7, employee: "Gecko", dept: "A", salary: 100000, fiscal_year: 2018 }, +{ "_id" : 8, employee: "Ant", dept: "A", salary: 125000, fiscal_year: 2019 }, +{ "_id" : 9, employee: "Bee", dept: "Z", salary: 160000, fiscal_year: 2019 }, +{ "_id" : 10, employee: "Cat", dept: "Z", salary: 150000, fiscal_year: 2019 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/pipeline.json deleted file mode 100644 index 564f8ac5a5d..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/merge/example8/pipeline.json +++ /dev/null @@ -1,4 +0,0 @@ - [ - { $group: { _id: { fiscal_year: "$fiscal_year", dept: "$dept" }, salaries: { $sum: "$salary" } } }, - { $merge : { into: { db: "reporting", coll: "budgets" }, on: "_id", whenMatched: "replace", whenNotMatched: "insert" } } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/out/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/out/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/out/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/out/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/out/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/out/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/out/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/out/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/action.json new file mode 100644 index 00000000000..4b38a368c2d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/action.json @@ -0,0 +1,2 @@ +{ $planCacheStats: { } }, + { $match: { planCacheKey: "B1435201"} } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/data.json new file mode 100644 index 00000000000..83c0158ca79 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/data.json @@ -0,0 +1,5 @@ +{ "_id" : 1, "item" : "abc", "price" : NumberDecimal("12"), "quantity" : 2, "type": "apparel" }, +{ "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : 1, "type": "electronics" }, +{ "_id" : 3, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : 5, "type": "apparel" }, +{ "_id" : 4, "item" : "abc", "price" : NumberDecimal("8"), "quantity" : 10, "type": "apparel" }, +{ "_id" : 5, "item" : "jkl", "price" : NumberDecimal("15"), "quantity" : 15, "type": "electronics" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/data1.json new file mode 100644 index 00000000000..081a140be1a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/data1.json @@ -0,0 +1,7 @@ +{ item: 1 } +{ item: 1, quantity: 1 } +{ quantity: 1 } +{ quantity: 1, type: 1 } +{ item: 1, price: 1 }, +{ partialFilterExpression: { price: { $gte: NumberDecimal("10")} } } +); \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/expected.json new file mode 100644 index 00000000000..9f44dcd9664 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/expected.json @@ -0,0 +1 @@ +{ version: '2', queryHash: '478AD696', planCacheKey: 'B1435201', isActive: true, works: NumberLong("5"), timeOfCreation: ISODate("2023-05-22T20:33:49.009Z"), cachedPlan: { slots: '$$RESULT=s11 env: { s3 = 1684787629009 (NOW), s6 = Nothing, s5 = Nothing, s1 = TimeZoneDatabase(Asia/Kuwait...Etc/UCT) (timeZoneDB), s10 = {"item" : 1, "price" : 1}, s2 = Nothing (SEARCH_META) }', stages: '[2] nlj inner [] [s4, s7, s8, s9, s10] \n' + ' left \n' + ' [1] cfilter {(exists(s5) && exists(s6))} \n' + ' [1] ixseek s5 s6 s9 s4 s7 s8 [] @"358822b7-c129-47b7-ad7f-40017a51b03c" @"item_1_price_1" true \n' + ' right \n' + ' [2] limit 1 \n' + ' [2] seek s4 s11 s12 s7 s8 s9 s10 none none [] @"358822b7-c129-47b7-ad7f-40017a51b03c" true false \n' }, indexFilterSet: false, isPinned: false, estimatedSizeBytes: NumberLong("7415"), host: 'mongodb1.example.net:27018' } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/name new file mode 100644 index 00000000000..0b36cce0f22 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/planCacheStats/example3/name @@ -0,0 +1 @@ +Find Cache Entry Details for a Query Hash \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/project/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/project/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/project/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/project/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/action.json new file mode 100644 index 00000000000..e66f8f875e4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/action.json @@ -0,0 +1 @@ +{ $project : { "lastModified": 0 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/name index 00bdb8bae08..706585b91fc 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/name @@ -1 +1 @@ -Exclude Fields from Embedded Documents \ No newline at end of file +Exclude Fields from Output Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/pipeline.json deleted file mode 100644 index bf72b1de125..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example3/pipeline.json +++ /dev/null @@ -1 +0,0 @@ -{ $project : { "author.first" : 0, "lastModified" : 0 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/project/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/project/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/project/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/project/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/action.json new file mode 100644 index 00000000000..478b37b1ecd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/action.json @@ -0,0 +1 @@ +{ $project: { "stop.title": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/data.json index 322cd0382f6..f12a10a5bf7 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/data.json @@ -1 +1,2 @@ -{ "_id" : 1, title: "abc123", isbn: "0001122223334", author: { last: "zzz", first: "aaa" }, copies: 5} \ No newline at end of file +{ _id: 1, user: "1234", stop: { title: "book1", author: "xyz", page: 32 } } +{ _id: 2, user: "7890", stop: [ { title: "book2", author: "abc", page: 5 }, { title: "book3", author: "ijk", page: 100 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/expected.json index 2a561971eb0..5cda8f7b424 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/expected.json @@ -1 +1,2 @@ -{ "_id" : 1, "title" : "abc123", "isbn" : { "prefix" : "000", "group" : "11", "publisher" : "2222", "title" : "333", "checkDigit" : "4" }, "lastName" : "zzz", "copiesSold" : 5} \ No newline at end of file +{ "_id" : 1, "stop" : { "title" : "book1" } } +{ "_id" : 2, "stop" : [ { "title" : "book2" }, { "title" : "book3" } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/name index 734ceca487b..d3fa62ed8c6 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/name @@ -1 +1 @@ -Include Computed Fields \ No newline at end of file +Include Specific Fields from Embedded Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/project/example6/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/data.json index 69355343bac..322cd0382f6 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/data.json @@ -1 +1 @@ -{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "x" : 1, "y" : 1 } \ No newline at end of file +{ "_id" : 1, title: "abc123", isbn: "0001122223334", author: { last: "zzz", first: "aaa" }, copies: 5} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/expected.json index a18d531727f..2a561971eb0 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/expected.json @@ -1 +1 @@ -{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1 ] } \ No newline at end of file +{ "_id" : 1, "title" : "abc123", "isbn" : { "prefix" : "000", "group" : "11", "publisher" : "2222", "title" : "333", "checkDigit" : "4" }, "lastName" : "zzz", "copiesSold" : 5} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/name b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/name index 7ca085b97cf..734ceca487b 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/name +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/name @@ -1 +1 @@ -Project New Array Fields \ No newline at end of file +Include Computed Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/pipeline.json deleted file mode 100644 index 05b5fee08c6..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example7/pipeline.json +++ /dev/null @@ -1 +0,0 @@ -{ $project: { myArray: [ "$x", "$y" ] } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example8/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example8/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/project/example8/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/project/example8/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/action.json new file mode 100644 index 00000000000..d88f70f7961 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/action.json @@ -0,0 +1 @@ +{ $project: { x: '$name', _id: 0 } }, \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/data.json index 7c238b3b608..d7d7c29a213 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/data.json @@ -1 +1,2 @@ -{ _id: 0, name: [ 'Pepperoni' ] } \ No newline at end of file +db.pizzas.insert( [ +{ _id: 0, name: [ 'Pepperoni' ] }, \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/pipeline.json deleted file mode 100644 index 071bfa12eff..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/project/example9/pipeline.json +++ /dev/null @@ -1,3 +0,0 @@ - [ - { $project: { x: '$name', _id: 0 } }, -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/querySettings/ignored b/core/src/test/resources/dev/morphia/test/aggregation/stages/querySettings/ignored new file mode 100644 index 00000000000..955e17fc76c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/querySettings/ignored @@ -0,0 +1 @@ +for now \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/redact/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/redact/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/redact/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/redact/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/redact/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/redact/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/redact/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/redact/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/replaceRoot/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/replaceWith/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/action.json new file mode 100644 index 00000000000..0a40cc10e21 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/action.json @@ -0,0 +1 @@ +{ $sample: { size: 3 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/data.json index c07011536c5..9ce6b202a80 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/data.json @@ -1,7 +1,7 @@ -{ "_id" : 1, "name" : "dave123", "q1" : true, "q2" : true } -{ "_id" : 2, "name" : "dave2", "q1" : false, "q2" : false } -{ "_id" : 3, "name" : "ahn", "q1" : true, "q2" : true } -{ "_id" : 4, "name" : "li", "q1" : true, "q2" : false } -{ "_id" : 5, "name" : "annT", "q1" : false, "q2" : true } -{ "_id" : 6, "name" : "li", "q1" : true, "q2" : true } -{ "_id" : 7, "name" : "ty", "q1" : false, "q2" : true } \ No newline at end of file +{ _id : 1, name : "dave123", q1 : true, q2 : true }, +{ _id : 2, name : "dave2", q1 : false, q2 : false }, +{ _id : 3, name : "ahn", q1 : true, q2 : true }, +{ _id : 4, name : "li", q1 : true, q2 : false }, +{ _id : 5, name : "annT", q1 : false, q2 : true }, +{ _id : 6, name : "li", q1 : true, q2 : true }, +{ _id : 7, name : "ty", q1 : false, q2 : true } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/pipeline.json deleted file mode 100644 index 24169c3a923..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/sample/example1/pipeline.json +++ /dev/null @@ -1 +0,0 @@ - [ { $sample: { size: 3 } } ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/action.json similarity index 78% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/action.json index fcdfeb3672c..28fe5e0bc7f 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/pipeline.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/action.json @@ -1,10 +1,11 @@ { - $set: { + $set: { totalHomework: { $sum: "$homework" }, totalQuiz: { $sum: "$quiz" } } - }, - { + }, + { $set: { - totalScore: { $add: [ "$totalHomework", "$totalQuiz", "$extraCredit" ] } } - } \ No newline at end of file + totalScore: { $add: [ "$totalHomework", "$totalQuiz", "$extraCredit" ] } + } + } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/lock b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/lock new file mode 100644 index 00000000000..515b2cda2a5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example1/lock @@ -0,0 +1 @@ +moved a trailing brace to a new line where it belongs \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/set/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/set/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example2/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example2/expected.json index a0a271c79d3..6c567843082 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example2/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example2/expected.json @@ -1,3 +1,3 @@ -{ _id: 1, type: "car", specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } } -{ _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } } +{ _id: 1, type: "car", specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } }, +{ _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } }, { _id: 3, type: "jet ski", specs: { fuel_type: "unleaded" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/set/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/set/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/set/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/set/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example4/expected.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example4/expected.json index 8b9a6905a0a..ef374b838d7 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example4/expected.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example4/expected.json @@ -1 +1 @@ -{ "_id" : 1, "student" : "Maya", "homework" : [ 10, 5, 10, 7 ], "quiz" : [ 10, 8 ], "extraCredit" : 0 } \ No newline at end of file +[ { _id: 1, student: "Maya", homework: [ 10, 5, 10, 7 ], quiz: [ 10, 8 ], extraCredit: 0 } ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/set/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/set/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/set/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/setWindowFields/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/skip/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/skip/example1/action.json new file mode 100644 index 00000000000..e1fd8bf95fe --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/skip/example1/action.json @@ -0,0 +1 @@ +{ $skip : 5 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/skip/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/skip/example1/pipeline.json deleted file mode 100644 index e9fb6fae4ef..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/skip/example1/pipeline.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - { $skip : 5 } -] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example1/action.json new file mode 100644 index 00000000000..1d8ed7aeec3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example1/action.json @@ -0,0 +1 @@ +{ $sort : { age : -1, posts: 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example1/pipeline.json deleted file mode 100644 index f0126f95ab0..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example1/pipeline.json +++ /dev/null @@ -1,3 +0,0 @@ - [ - { $sort : { age : -1, posts: 1 } } - ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example2/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example2/action.json new file mode 100644 index 00000000000..0f8d9b6901b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example2/action.json @@ -0,0 +1,2 @@ +{ $match: { $text: { $search: "operating" } } }, + { $sort: { score: { $meta: "textScore" }, posts: -1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example2/pipeline.json deleted file mode 100644 index 46e6462476b..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/sort/example2/pipeline.json +++ /dev/null @@ -1,4 +0,0 @@ - [ - { $match: { $text: { $search: "operating" } } }, - { $sort: { score: { $meta: "textScore" }, posts: -1 } } - ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/sortByCount/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/sortByCount/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/sortByCount/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/sortByCount/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data1.json new file mode 100644 index 00000000000..95141c0e4e3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data1.json @@ -0,0 +1,9 @@ +{ store: "General Store", item: "Cheese", quantity: 30 }, +{ store: "ShopMart", item: "Cheese", quantity: 50 }, +{ store: "General Store", item: "Chocolates", quantity: 125 }, +{ store: "ShopMart", item: "Chocolates", quantity: 150 }, +{ store: "General Store", item: "Cookies", quantity: 200 }, +{ store: "ShopMart", item: "Cookies", quantity: 100 }, +{ store: "ShopMart", item: "Nuts", quantity: 100 }, +{ store: "General Store", item: "Pie", quantity: 30 }, +{ store: "ShopMart", item: "Pie", quantity: 25 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data2.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data2.json index 95141c0e4e3..1a9bb44908e 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data2.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data2.json @@ -1,9 +1,10 @@ -{ store: "General Store", item: "Cheese", quantity: 30 }, -{ store: "ShopMart", item: "Cheese", quantity: 50 }, +{ store: "General Store", item: "Cheese", quantity: 50 }, +{ store: "ShopMart", item: "Cheese", quantity: 20 }, { store: "General Store", item: "Chocolates", quantity: 125 }, { store: "ShopMart", item: "Chocolates", quantity: 150 }, { store: "General Store", item: "Cookies", quantity: 200 }, { store: "ShopMart", item: "Cookies", quantity: 100 }, -{ store: "ShopMart", item: "Nuts", quantity: 100 }, -{ store: "General Store", item: "Pie", quantity: 30 }, -{ store: "ShopMart", item: "Pie", quantity: 25 } \ No newline at end of file +{ store: "General Store", item: "Nuts", quantity: 80 }, +{ store: "ShopMart", item: "Nuts", quantity: 30 }, +{ store: "General Store", item: "Pie", quantity: 50 }, +{ store: "ShopMart", item: "Pie", quantity: 75 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data3.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data3.json index 1a9bb44908e..90785581ce3 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data3.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data3.json @@ -1,10 +1,10 @@ -{ store: "General Store", item: "Cheese", quantity: 50 }, -{ store: "ShopMart", item: "Cheese", quantity: 20 }, -{ store: "General Store", item: "Chocolates", quantity: 125 }, -{ store: "ShopMart", item: "Chocolates", quantity: 150 }, -{ store: "General Store", item: "Cookies", quantity: 200 }, -{ store: "ShopMart", item: "Cookies", quantity: 100 }, -{ store: "General Store", item: "Nuts", quantity: 80 }, -{ store: "ShopMart", item: "Nuts", quantity: 30 }, -{ store: "General Store", item: "Pie", quantity: 50 }, -{ store: "ShopMart", item: "Pie", quantity: 75 } \ No newline at end of file +{ store: "General Store", item: "Cheese", quantity: 100, }, +{ store: "ShopMart", item: "Cheese", quantity: 100}, +{ store: "General Store", item: "Chocolates", quantity: 200 }, +{ store: "ShopMart", item: "Chocolates", quantity: 300 }, +{ store: "General Store", item: "Cookies", quantity: 500 }, +{ store: "ShopMart", item: "Cookies", quantity: 400 }, +{ store: "General Store", item: "Nuts", quantity: 100 }, +{ store: "ShopMart", item: "Nuts", quantity: 200 }, +{ store: "General Store", item: "Pie", quantity: 100 }, +{ store: "ShopMart", item: "Pie", quantity: 100 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data4.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data4.json deleted file mode 100644 index 90785581ce3..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example1/data4.json +++ /dev/null @@ -1,10 +0,0 @@ -{ store: "General Store", item: "Cheese", quantity: 100, }, -{ store: "ShopMart", item: "Cheese", quantity: 100}, -{ store: "General Store", item: "Chocolates", quantity: 200 }, -{ store: "ShopMart", item: "Chocolates", quantity: 300 }, -{ store: "General Store", item: "Cookies", quantity: 500 }, -{ store: "ShopMart", item: "Cookies", quantity: 400 }, -{ store: "General Store", item: "Nuts", quantity: 100 }, -{ store: "ShopMart", item: "Nuts", quantity: 200 }, -{ store: "General Store", item: "Pie", quantity: 100 }, -{ store: "ShopMart", item: "Pie", quantity: 100 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data1.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data1.json new file mode 100644 index 00000000000..95141c0e4e3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data1.json @@ -0,0 +1,9 @@ +{ store: "General Store", item: "Cheese", quantity: 30 }, +{ store: "ShopMart", item: "Cheese", quantity: 50 }, +{ store: "General Store", item: "Chocolates", quantity: 125 }, +{ store: "ShopMart", item: "Chocolates", quantity: 150 }, +{ store: "General Store", item: "Cookies", quantity: 200 }, +{ store: "ShopMart", item: "Cookies", quantity: 100 }, +{ store: "ShopMart", item: "Nuts", quantity: 100 }, +{ store: "General Store", item: "Pie", quantity: 30 }, +{ store: "ShopMart", item: "Pie", quantity: 25 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data2.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data2.json index 95141c0e4e3..1a9bb44908e 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data2.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data2.json @@ -1,9 +1,10 @@ -{ store: "General Store", item: "Cheese", quantity: 30 }, -{ store: "ShopMart", item: "Cheese", quantity: 50 }, +{ store: "General Store", item: "Cheese", quantity: 50 }, +{ store: "ShopMart", item: "Cheese", quantity: 20 }, { store: "General Store", item: "Chocolates", quantity: 125 }, { store: "ShopMart", item: "Chocolates", quantity: 150 }, { store: "General Store", item: "Cookies", quantity: 200 }, { store: "ShopMart", item: "Cookies", quantity: 100 }, -{ store: "ShopMart", item: "Nuts", quantity: 100 }, -{ store: "General Store", item: "Pie", quantity: 30 }, -{ store: "ShopMart", item: "Pie", quantity: 25 } \ No newline at end of file +{ store: "General Store", item: "Nuts", quantity: 80 }, +{ store: "ShopMart", item: "Nuts", quantity: 30 }, +{ store: "General Store", item: "Pie", quantity: 50 }, +{ store: "ShopMart", item: "Pie", quantity: 75 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data3.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data3.json index 1a9bb44908e..90785581ce3 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data3.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data3.json @@ -1,10 +1,10 @@ -{ store: "General Store", item: "Cheese", quantity: 50 }, -{ store: "ShopMart", item: "Cheese", quantity: 20 }, -{ store: "General Store", item: "Chocolates", quantity: 125 }, -{ store: "ShopMart", item: "Chocolates", quantity: 150 }, -{ store: "General Store", item: "Cookies", quantity: 200 }, -{ store: "ShopMart", item: "Cookies", quantity: 100 }, -{ store: "General Store", item: "Nuts", quantity: 80 }, -{ store: "ShopMart", item: "Nuts", quantity: 30 }, -{ store: "General Store", item: "Pie", quantity: 50 }, -{ store: "ShopMart", item: "Pie", quantity: 75 } \ No newline at end of file +{ store: "General Store", item: "Cheese", quantity: 100, }, +{ store: "ShopMart", item: "Cheese", quantity: 100}, +{ store: "General Store", item: "Chocolates", quantity: 200 }, +{ store: "ShopMart", item: "Chocolates", quantity: 300 }, +{ store: "General Store", item: "Cookies", quantity: 500 }, +{ store: "ShopMart", item: "Cookies", quantity: 400 }, +{ store: "General Store", item: "Nuts", quantity: 100 }, +{ store: "ShopMart", item: "Nuts", quantity: 200 }, +{ store: "General Store", item: "Pie", quantity: 100 }, +{ store: "ShopMart", item: "Pie", quantity: 100 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data4.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data4.json deleted file mode 100644 index 90785581ce3..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example2/data4.json +++ /dev/null @@ -1,10 +0,0 @@ -{ store: "General Store", item: "Cheese", quantity: 100, }, -{ store: "ShopMart", item: "Cheese", quantity: 100}, -{ store: "General Store", item: "Chocolates", quantity: 200 }, -{ store: "ShopMart", item: "Chocolates", quantity: 300 }, -{ store: "General Store", item: "Cookies", quantity: 500 }, -{ store: "ShopMart", item: "Cookies", quantity: 400 }, -{ store: "General Store", item: "Nuts", quantity: 100 }, -{ store: "ShopMart", item: "Nuts", quantity: 200 }, -{ store: "General Store", item: "Pie", quantity: 100 }, -{ store: "ShopMart", item: "Pie", quantity: 100 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unionWith/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example1/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example1/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example1/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unset/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/action.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/action.json new file mode 100644 index 00000000000..ccc84a11798 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/action.json @@ -0,0 +1 @@ +{ $unwind : "$sizes" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/data.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/data.json index be90e07b7e5..e62369b2247 100644 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/data.json +++ b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/data.json @@ -1 +1 @@ -{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }) \ No newline at end of file +{ "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/pipeline.json deleted file mode 100644 index 20b8a59df3f..00000000000 --- a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example1/pipeline.json +++ /dev/null @@ -1 +0,0 @@ - [ { $unwind : "$sizes" } ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example2/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example2/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example2/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example2/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example3/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example3/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example3/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example3/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example4/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example4/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example4/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example4/action.json diff --git a/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example5/pipeline.json b/core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example5/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example5/pipeline.json rename to core/src/test/resources/dev/morphia/test/aggregation/stages/unwind/example5/action.json diff --git a/core/src/test/resources/dev/morphia/test/query/filters/all/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/all/example1/action.json new file mode 100644 index 00000000000..7ae87585820 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/all/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { tags: { $all: [ "appliance", "school", "book" ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/all/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/all/example1/data.json new file mode 100644 index 00000000000..ff7a6af2373 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/all/example1/data.json @@ -0,0 +1,4 @@ +{ _id: ObjectId("5234cc89687ea597eabee675"), code: "xyz", tags: [ "school", "book", "bag", "headphone", "appliance" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 45, color: "blue" }, { size: "L", num: 100, color: "green" } ]} +{ _id: ObjectId("5234cc8a687ea597eabee676"), code: "abc", tags: [ "appliance", "school", "book" ], qty: [ { size: "6", num: 100, color: "green" }, { size: "6", num: 50, color: "blue" }, { size: "8", num: 100, color: "brown" } ]} +{ _id: ObjectId("5234ccb7687ea597eabee677"), code: "efg", tags: [ "school", "book" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 100, color: "blue" }, { size: "L", num: 100, color: "green" } ]} +{ _id: ObjectId("52350353b2eff1353b349de9"), code: "ijk", tags: [ "electronics", "school" ], qty: [ { size: "M", num: 100, color: "green" } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/all/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/all/example1/expected.json new file mode 100644 index 00000000000..eecddcb4b85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/all/example1/expected.json @@ -0,0 +1,2 @@ +{ _id: ObjectId("5234cc89687ea597eabee675"), code: "xyz", tags: [ "school", "book", "bag", "headphone", "appliance" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 45, color: "blue" }, { size: "L", num: 100, color: "green" } ]} +{ _id: ObjectId("5234cc8a687ea597eabee676"), code: "abc", tags: [ "appliance", "school", "book" ], qty: [ { size: "6", num: 100, color: "green" }, { size: "6", num: 50, color: "blue" }, { size: "8", num: 100, color: "brown" } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/all/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/all/example1/name new file mode 100644 index 00000000000..1efca7d9b61 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/all/example1/name @@ -0,0 +1 @@ +Use ``$all`` to Match Values \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/all/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/all/example2/action.json new file mode 100644 index 00000000000..7d4e29ab955 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/all/example2/action.json @@ -0,0 +1,6 @@ +db.inventory.find( { + qty: { $all: [ + { "$elemMatch" : { size: "M", num: { $gt: 50} } }, + { "$elemMatch" : { num : 100, color: "green" } } + ] } + } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/all/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/all/example2/data.json new file mode 100644 index 00000000000..ff7a6af2373 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/all/example2/data.json @@ -0,0 +1,4 @@ +{ _id: ObjectId("5234cc89687ea597eabee675"), code: "xyz", tags: [ "school", "book", "bag", "headphone", "appliance" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 45, color: "blue" }, { size: "L", num: 100, color: "green" } ]} +{ _id: ObjectId("5234cc8a687ea597eabee676"), code: "abc", tags: [ "appliance", "school", "book" ], qty: [ { size: "6", num: 100, color: "green" }, { size: "6", num: 50, color: "blue" }, { size: "8", num: 100, color: "brown" } ]} +{ _id: ObjectId("5234ccb7687ea597eabee677"), code: "efg", tags: [ "school", "book" ], qty: [ { size: "S", num: 10, color: "blue" }, { size: "M", num: 100, color: "blue" }, { size: "L", num: 100, color: "green" } ]} +{ _id: ObjectId("52350353b2eff1353b349de9"), code: "ijk", tags: [ "electronics", "school" ], qty: [ { size: "M", num: 100, color: "green" } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/all/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/all/example2/expected.json new file mode 100644 index 00000000000..9014a72b98e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/all/example2/expected.json @@ -0,0 +1,2 @@ +{ "_id" : ObjectId("5234ccb7687ea597eabee677"), "code" : "efg", "tags" : [ "school", "book"], "qty" : [ { "size" : "S", "num" : 10, "color" : "blue" }, { "size" : "M", "num" : 100, "color" : "blue" }, { "size" : "L", "num" : 100, "color" : "green" } ]} +{ "_id" : ObjectId("52350353b2eff1353b349de9"), "code" : "ijk", "tags" : [ "electronics", "school" ], "qty" : [ { "size" : "M", "num" : 100, "color" : "green" } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/all/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/all/example2/name new file mode 100644 index 00000000000..0ad656002a6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/all/example2/name @@ -0,0 +1 @@ +Use ``$all`` with ``$elemMatch`` \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/and/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/and/example1/action.json new file mode 100644 index 00000000000..934e6547c9b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/and/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/and/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/and/example1/name new file mode 100644 index 00000000000..0c02148d662 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/and/example1/name @@ -0,0 +1 @@ +``AND`` Queries With Multiple Expressions Specifying the Same Field \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/and/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/and/example2/action.json new file mode 100644 index 00000000000..1cb82566930 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/and/example2/action.json @@ -0,0 +1,6 @@ +db.inventory.find( { + $and: [ + { $or: [ { qty: { $lt : 10 } }, { qty : { $gt: 50 } } ] }, + { $or: [ { sale: true }, { price : { $lt : 5 } } ] } + ] +} ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/and/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/and/example2/name new file mode 100644 index 00000000000..9a4b39ada0c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/and/example2/name @@ -0,0 +1 @@ +``AND`` Queries With Multiple Expressions Specifying the Same Operator \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/action.json new file mode 100644 index 00000000000..fdbb2b9b290 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAllClear: [ 1, 5 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/expected.json new file mode 100644 index 00000000000..b9cc57d1293 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" } +{ "_id" : 3, "a" : 20, "binaryValueofA" : "00010100" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/name new file mode 100644 index 00000000000..bbb596dbc4a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example1/name @@ -0,0 +1 @@ +Bit Position Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/action.json new file mode 100644 index 00000000000..4a269db5bbd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAllClear: 35 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/expected.json new file mode 100644 index 00000000000..b9cc57d1293 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" } +{ "_id" : 3, "a" : 20, "binaryValueofA" : "00010100" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/name new file mode 100644 index 00000000000..45884820524 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example2/name @@ -0,0 +1 @@ +Integer Bitmask \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/action.json new file mode 100644 index 00000000000..e9debd4cba9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAllClear: BinData(0, "IA==") } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/expected.json new file mode 100644 index 00000000000..b9cc57d1293 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" } +{ "_id" : 3, "a" : 20, "binaryValueofA" : "00010100" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/name new file mode 100644 index 00000000000..a90b4622323 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllClear/example3/name @@ -0,0 +1 @@ +BinData Bitmask \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/action.json new file mode 100644 index 00000000000..7bd459dfc1a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAllSet: [ 1, 5 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/expected.json new file mode 100644 index 00000000000..83ffee53965 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" } +{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/name new file mode 100644 index 00000000000..bbb596dbc4a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example1/name @@ -0,0 +1 @@ +Bit Position Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/action.json new file mode 100644 index 00000000000..7e1b739e3b6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAllSet: 50 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/expected.json new file mode 100644 index 00000000000..971efc37fa5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/name new file mode 100644 index 00000000000..45884820524 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example2/name @@ -0,0 +1 @@ +Integer Bitmask \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/action.json new file mode 100644 index 00000000000..8354ae26864 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAllSet: BinData(0, "MA==") } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/expected.json new file mode 100644 index 00000000000..eb962595dfd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/expected.json @@ -0,0 +1 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/name new file mode 100644 index 00000000000..a90b4622323 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAllSet/example3/name @@ -0,0 +1 @@ +BinData Bitmask \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/action.json new file mode 100644 index 00000000000..f12cfa0ba94 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAnyClear: [ 1, 5 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/expected.json new file mode 100644 index 00000000000..ec3159cfb03 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" } +{ "_id" : 3, "a" : 20.0, "binaryValueofA" : "00010100" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/name new file mode 100644 index 00000000000..bbb596dbc4a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example1/name @@ -0,0 +1 @@ +Bit Position Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/action.json new file mode 100644 index 00000000000..c180f788a81 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAnyClear: 35 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/expected.json new file mode 100644 index 00000000000..7ebf78fabd6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/expected.json @@ -0,0 +1,4 @@ +{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" } +{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" } +{ "_id" : 3, "a" : 20.0, "binaryValueofA" : "00010100" } +{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/name new file mode 100644 index 00000000000..45884820524 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example2/name @@ -0,0 +1 @@ +Integer Bitmask \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/action.json new file mode 100644 index 00000000000..a3804b9c95f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAnyClear: BinData(0, "MA==") } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/expected.json new file mode 100644 index 00000000000..d8cdaa01ff1 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/expected.json @@ -0,0 +1,3 @@ +{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" } +{ "_id" : 3, "a" : 20.0, "binaryValueofA" : "00010100" } +{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/name new file mode 100644 index 00000000000..a90b4622323 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnyClear/example3/name @@ -0,0 +1 @@ +BinData Bitmask \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/action.json new file mode 100644 index 00000000000..ffbae961cd3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAnySet: [ 1, 5 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/expected.json new file mode 100644 index 00000000000..83ffee53965 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" } +{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/name new file mode 100644 index 00000000000..bbb596dbc4a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example1/name @@ -0,0 +1 @@ +Bit Position Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/action.json new file mode 100644 index 00000000000..c003a373ebe --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAnySet: 35 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/expected.json new file mode 100644 index 00000000000..83ffee53965 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" } +{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/name new file mode 100644 index 00000000000..45884820524 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example2/name @@ -0,0 +1 @@ +Integer Bitmask \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/action.json new file mode 100644 index 00000000000..17bfee88edd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/action.json @@ -0,0 +1 @@ +db.collection.find( { a: { $bitsAnySet: BinData(0, "MA==") } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/data.json new file mode 100644 index 00000000000..ec9a9173fff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/data.json @@ -0,0 +1,4 @@ +{ _id: 1, a: 54, binaryValueofA: "00110110" }, +{ _id: 2, a: 20, binaryValueofA: "00010100" }, +{ _id: 3, a: 20.0, binaryValueofA: "00010100" }, +{ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/expected.json new file mode 100644 index 00000000000..7ebf78fabd6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/expected.json @@ -0,0 +1,4 @@ +{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" } +{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" } +{ "_id" : 3, "a" : 20.0, "binaryValueofA" : "00010100" } +{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/name new file mode 100644 index 00000000000..a90b4622323 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/bitsAnySet/example3/name @@ -0,0 +1 @@ +BinData Bitmask \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/box/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/action.json new file mode 100644 index 00000000000..526415b934d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/action.json @@ -0,0 +1,3 @@ +db.places.find( { + loc: { $geoWithin: { $box: [ [ 0.0, 0.0 ], [ 100.0, 100.0 ] ] } } +} ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/box/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/box/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/center/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/center/example1/action.json new file mode 100644 index 00000000000..81722197d62 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/center/example1/action.json @@ -0,0 +1,3 @@ +db.places.find( + { loc: { $geoWithin: { $center: [ [-74.0, 40.74], 10.0 ] } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/center/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/center/example1/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/center/example1/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/center/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/center/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/center/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/action.json new file mode 100644 index 00000000000..cc2cf1cd4b6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/action.json @@ -0,0 +1,3 @@ +db.places.find( { + loc: { $geoWithin: { $centerSphere: [ [ -88.0, 30.0 ], 0.0025232135648 ] } } +} ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/lock new file mode 100644 index 00000000000..499a6af414f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/lock @@ -0,0 +1,2 @@ +adjust the number format to doubles +do the math \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/centerSphere/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/action.json new file mode 100644 index 00000000000..5d058389656 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/action.json @@ -0,0 +1,6 @@ +db.records.find( + { + x: { $mod: [ 2, 0 ] }, + $comment: "Find even values." + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/expected.json new file mode 100644 index 00000000000..0aea6b69464 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/expected.json @@ -0,0 +1 @@ +{ "op" : "query", "ns" : "test.records", "command" : { "find" : "records", "filter" : { "x" : { "$mod" : [ 2, 0 ] }, "$comment" : "Find even values." }, "comment" : "Find even values.", ... \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/name new file mode 100644 index 00000000000..84991581dd9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/comment/example1/name @@ -0,0 +1 @@ +Attach a Comment to ``find`` \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/comment/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/comment/example2/action.json new file mode 100644 index 00000000000..ab0a50f4697 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/comment/example2/action.json @@ -0,0 +1,2 @@ +{ $match: { x: { $gt: 0 }, $comment: "Don't allow negative inputs." } }, + { $group : { _id: { $mod: [ "$x", 2 ] }, total: { $sum: "$x" } } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/comment/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/comment/example2/name new file mode 100644 index 00000000000..7c8c424be75 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/comment/example2/name @@ -0,0 +1 @@ +Attach a Comment to an Aggregation Expression \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/action.json new file mode 100644 index 00000000000..f3cd67eb857 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/action.json @@ -0,0 +1,3 @@ +db.scores.find( + { results: { $elemMatch: { $gte: 80, $lt: 85 } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/data.json new file mode 100644 index 00000000000..c522b354d38 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/data.json @@ -0,0 +1,2 @@ +{ _id: 1, results: [ 82, 85, 88 ] } +{ _id: 2, results: [ 75, 88, 89 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/expected.json new file mode 100644 index 00000000000..f3bad0a59ae --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, results: [ 82, 85, 88 ] } diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/lock new file mode 100644 index 00000000000..db0fd8b17cb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/lock @@ -0,0 +1 @@ +example's expected didn't match reality \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/name new file mode 100644 index 00000000000..c0339a48525 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example1/name @@ -0,0 +1 @@ +Element Match \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/action.json new file mode 100644 index 00000000000..3b9fc80c06a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/action.json @@ -0,0 +1,3 @@ +db.survey.find( + { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/data.json new file mode 100644 index 00000000000..33c6757efde --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/data.json @@ -0,0 +1,5 @@ +{ "_id": 1, "results": [ { "product": "abc", "score": 10 }, { "product": "xyz", "score": 5 } ] }, +{ "_id": 2, "results": [ { "product": "abc", "score": 8 }, { "product": "xyz", "score": 7 } ] }, +{ "_id": 3, "results": [ { "product": "abc", "score": 7 }, { "product": "xyz", "score": 8 } ] }, +{ "_id": 4, "results": [ { "product": "abc", "score": 7 }, { "product": "def", "score": 8 } ] }, +{ "_id": 5, "results": { "product": "xyz", "score": 7 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/expected.json new file mode 100644 index 00000000000..70891b269e3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/expected.json @@ -0,0 +1 @@ +{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, { "product" : "xyz", "score" : 8 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/name new file mode 100644 index 00000000000..235e77538ee --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example2/name @@ -0,0 +1 @@ +Array of Embedded Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/action.json new file mode 100644 index 00000000000..4bcd0ea272c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/action.json @@ -0,0 +1,3 @@ +db.survey.find( + { results: { $elemMatch: { product: "xyz" } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/data.json new file mode 100644 index 00000000000..33c6757efde --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/data.json @@ -0,0 +1,5 @@ +{ "_id": 1, "results": [ { "product": "abc", "score": 10 }, { "product": "xyz", "score": 5 } ] }, +{ "_id": 2, "results": [ { "product": "abc", "score": 8 }, { "product": "xyz", "score": 7 } ] }, +{ "_id": 3, "results": [ { "product": "abc", "score": 7 }, { "product": "xyz", "score": 8 } ] }, +{ "_id": 4, "results": [ { "product": "abc", "score": 7 }, { "product": "def", "score": 8 } ] }, +{ "_id": 5, "results": { "product": "xyz", "score": 7 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/expected.json new file mode 100644 index 00000000000..d6e34c00390 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/expected.json @@ -0,0 +1,3 @@ +{ _id: 1, results: [ { product: 'abc', score: 10 }, { product: 'xyz', score: 5 } ] }, +{ _id: 2, results: [ { product: 'abc', score: 8 }, { product: 'xyz', score: 7 } ] }, +{ _id: 3, results: [ { product: 'abc', score: 7 }, { product: 'xyz', score: 8 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/lock b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/lock new file mode 100644 index 00000000000..2b754ab3e17 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/lock @@ -0,0 +1 @@ +had to copy over the data from example 2 rather than use example1's \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/name new file mode 100644 index 00000000000..0f88d362296 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/elemMatch/example3/name @@ -0,0 +1 @@ +Single Query Condition \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/action.json new file mode 100644 index 00000000000..f055b1ce211 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { qty: 20 } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/data.json new file mode 100644 index 00000000000..63bef893f08 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/data.json @@ -0,0 +1,5 @@ +{ _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }, +{ _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] }, +{ _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] }, +{ _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] }, +{ _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/expected.json new file mode 100644 index 00000000000..20e865cc454 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/expected.json @@ -0,0 +1,2 @@ +{ _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] }, +{ _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/lock new file mode 100644 index 00000000000..7ba0e19b920 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/lock @@ -0,0 +1 @@ +update action to use shortened version of $eq \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/name new file mode 100644 index 00000000000..82ae664759d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example1/name @@ -0,0 +1 @@ +Equals a Specified Value \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/action.json new file mode 100644 index 00000000000..b1b5ed1351c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/action.json @@ -0,0 +1 @@ +db.inventory.find( { "item.name": "ab" } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/data.json new file mode 100644 index 00000000000..63bef893f08 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/data.json @@ -0,0 +1,5 @@ +{ _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }, +{ _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] }, +{ _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] }, +{ _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] }, +{ _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/expected.json new file mode 100644 index 00000000000..d6055fc1b10 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/expected.json @@ -0,0 +1 @@ +[ { _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] } ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/lock new file mode 100644 index 00000000000..7ba0e19b920 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/lock @@ -0,0 +1 @@ +update action to use shortened version of $eq \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/name new file mode 100644 index 00000000000..1057b49417f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example2/name @@ -0,0 +1 @@ +Field in Embedded Document Equals a Value \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/action.json new file mode 100644 index 00000000000..b93cdfc19fd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/action.json @@ -0,0 +1 @@ +db.inventory.find( { tags: "B" } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/data.json new file mode 100644 index 00000000000..63bef893f08 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/data.json @@ -0,0 +1,5 @@ +{ _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }, +{ _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] }, +{ _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] }, +{ _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] }, +{ _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/expected.json new file mode 100644 index 00000000000..0985e354d5a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/expected.json @@ -0,0 +1,4 @@ +{ _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }, +{ _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] }, +{ _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] }, +{ _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/lock b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/lock new file mode 100644 index 00000000000..7ba0e19b920 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/lock @@ -0,0 +1 @@ +update action to use shortened version of $eq \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/name new file mode 100644 index 00000000000..e0af3dac8bc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example3/name @@ -0,0 +1 @@ +Array Element Equals a Value \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/action.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/action.json new file mode 100644 index 00000000000..e255e8440d2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/action.json @@ -0,0 +1 @@ +db.inventory.find( { tags: [ "A", "B" ] } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/data.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/data.json new file mode 100644 index 00000000000..63bef893f08 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/data.json @@ -0,0 +1,5 @@ +{ _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }, +{ _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] }, +{ _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] }, +{ _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] }, +{ _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/expected.json new file mode 100644 index 00000000000..b7a048a5239 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/expected.json @@ -0,0 +1,2 @@ +{ _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] }, +{ _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/lock b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/lock new file mode 100644 index 00000000000..7ba0e19b920 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/lock @@ -0,0 +1 @@ +update action to use shortened version of $eq \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/name b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/name new file mode 100644 index 00000000000..0f44890042a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example4/name @@ -0,0 +1 @@ +Equals an Array Value \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/action.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/action.json new file mode 100644 index 00000000000..7812b9b7eb4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/action.json @@ -0,0 +1 @@ +db.companies.find( { company: /MongoDB/ }, {_id: 0 }) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/data.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/data.json new file mode 100644 index 00000000000..778fe1bf045 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/data.json @@ -0,0 +1,2 @@ +{ _id: 001, company: "MongoDB" }, +{ _id: 002, company: "MongoDB2" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/expected.json new file mode 100644 index 00000000000..3b499c6d955 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/expected.json @@ -0,0 +1,2 @@ +{ company: "MongoDB" }, +{ company: "MongoDB2" } diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/lock b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/lock new file mode 100644 index 00000000000..1d36c1b2640 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/lock @@ -0,0 +1,2 @@ +pull data manually since there are multiple cases here but only the one interesting case +unwrap the multiple results \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/name b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/name new file mode 100644 index 00000000000..515f5fc6811 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/eq/example5/name @@ -0,0 +1 @@ +Regex Match Behaviour \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/action.json new file mode 100644 index 00000000000..d70eafd0a54 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { saffron: { $exists: true } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/data.json new file mode 100644 index 00000000000..4082a1ddc8f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/data.json @@ -0,0 +1,10 @@ +{ saffron: 5, cinnamon: 5, mustard: null }, +{ saffron: 3, cinnamon: null, mustard: 8 }, +{ saffron: null, cinnamon: 3, mustard: 9 }, +{ saffron: 1, cinnamon: 2, mustard: 3 }, +{ saffron: 2, mustard: 5 }, +{ saffron: 3, cinnamon: 2 }, +{ saffron: 4 }, +{ cinnamon: 2, mustard: 4 }, +{ cinnamon: 2 }, +{ mustard: 6 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/expected.json new file mode 100644 index 00000000000..d80d9eeb3f8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/expected.json @@ -0,0 +1,7 @@ +{ saffron: 5, cinnamon: 5, mustard: null } +{ saffron: 3, cinnamon: null, mustard: 8 } +{ saffron: null, cinnamon: 3, mustard: 9 } +{ saffron: 1, cinnamon: 2, mustard: 3 } +{ saffron: 2, mustard: 5 } +{ saffron: 3, cinnamon: 2 } +{ saffron: 4 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/lock new file mode 100644 index 00000000000..a6ded86c830 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/lock @@ -0,0 +1 @@ +this example is convoluted so i had to manually collect the inputs \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/name new file mode 100644 index 00000000000..f4c2958729d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example1/name @@ -0,0 +1 @@ +Exists and Not Equal To \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/action.json new file mode 100644 index 00000000000..0c61b371b27 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/action.json @@ -0,0 +1 @@ +db.spices.find( { cinnamon: { $exists: false } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/data.json new file mode 100644 index 00000000000..4082a1ddc8f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/data.json @@ -0,0 +1,10 @@ +{ saffron: 5, cinnamon: 5, mustard: null }, +{ saffron: 3, cinnamon: null, mustard: 8 }, +{ saffron: null, cinnamon: 3, mustard: 9 }, +{ saffron: 1, cinnamon: 2, mustard: 3 }, +{ saffron: 2, mustard: 5 }, +{ saffron: 3, cinnamon: 2 }, +{ saffron: 4 }, +{ cinnamon: 2, mustard: 4 }, +{ cinnamon: 2 }, +{ mustard: 6 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/expected.json new file mode 100644 index 00000000000..b8b029a714f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/expected.json @@ -0,0 +1,3 @@ +{ saffron: 2, mustard: 5 } +{ saffron: 4 } +{ mustard: 6 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/lock new file mode 100644 index 00000000000..a6ded86c830 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/lock @@ -0,0 +1 @@ +this example is convoluted so i had to manually collect the inputs \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/name new file mode 100644 index 00000000000..dfafb01e169 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/exists/example2/name @@ -0,0 +1 @@ +Null Values \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/action.json new file mode 100644 index 00000000000..70ae9256736 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/action.json @@ -0,0 +1 @@ +db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/data.json new file mode 100644 index 00000000000..04f7556fd3a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/data.json @@ -0,0 +1,5 @@ +{ _id : 1, category : "food", budget : 400, spent : 450 }, +{ _id : 2, category : "drinks", budget : 100, spent : 150 }, +{ _id : 3, category : "clothes", budget : 100, spent : 50 }, +{ _id : 4, category : "misc", budget : 500, spent : 300 }, +{ _id : 5, category : "travel", budget : 200, spent : 650 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/expected.json new file mode 100644 index 00000000000..945d517b8e7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/expected.json @@ -0,0 +1,3 @@ +{ _id : 1, category : "food", budget : 400, spent : 450 } +{ _id : 2, category : "drinks", budget : 100, spent : 150 } +{ _id : 5, category : "travel", budget : 200, spent : 650 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/lock new file mode 100644 index 00000000000..c3765d343ed --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/lock @@ -0,0 +1 @@ +wrapped the variable refs in quotes \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/name new file mode 100644 index 00000000000..4252ff682de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example1/name @@ -0,0 +1 @@ +Compare Two Fields from A Single Document \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/action.json new file mode 100644 index 00000000000..2604efba004 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/action.json @@ -0,0 +1,8 @@ +let discountedPrice = { + $cond: { + if: { $gte: ["$qty", 100] }, + then: { $multiply: ["$price", 0.50] }, + else: { $multiply: ["$price", 0.75] } + } +}; +db.supplies.find( { $expr: { $lt:[ discountedPrice, 5 ] } }) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/data.json new file mode 100644 index 00000000000..3c4cb8c7b47 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/data.json @@ -0,0 +1,5 @@ +{ _id : 1, item : "binder", qty : NumberInt("100"), price : NumberDecimal("12") }, +{ _id : 2, item : "notebook", qty : NumberInt("200"), price : NumberDecimal("8") }, +{ _id : 3, item : "pencil", qty : NumberInt("50"), price : NumberDecimal("6") }, +{ _id : 4, item : "eraser", qty : NumberInt("150"), price : NumberDecimal("3") }, +{ _id : 5, item : "legal pad", qty : NumberInt("42"), price : NumberDecimal("10") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/expected.json new file mode 100644 index 00000000000..5cbb54c183c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/expected.json @@ -0,0 +1,3 @@ +{ _id : 2, item : "notebook", qty : 200 , price : NumberDecimal("8") } +{ _id : 3, item : "pencil", qty : 50 , price : NumberDecimal("6") } +{ _id : 4, item : "eraser", qty : 150 , price : NumberDecimal("3") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/name new file mode 100644 index 00000000000..becd7bb62da --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/expr/example2/name @@ -0,0 +1 @@ +Using ``$expr`` With Conditional Statements \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/action.json new file mode 100644 index 00000000000..8010d124ad5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/action.json @@ -0,0 +1,14 @@ +db.places.find( + { + loc: { + $geoIntersects: { + $geometry: { + type: "Polygon" , + coordinates: [ + [ [ 0.0, 0.0 ], [ 3.0, 6.0 ], [ 6.0, 1.0 ], [ 0.0, 0.0 ] ] + ] + } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/name new file mode 100644 index 00000000000..a4b07b53684 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example1/name @@ -0,0 +1 @@ +Intersects a Polygon \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/action.json new file mode 100644 index 00000000000..8ff60f77e01 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/action.json @@ -0,0 +1,20 @@ +db.places.find( + { + loc: { + $geoIntersects: { + $geometry: { + type : "Polygon", + coordinates: [ + [ + [ -100.0, 60.0 ], [ -100.0, 0.0 ], [ -100.0, -60.0 ], [ 100.0, -60.0 ], [ 100.0, 60.0 ], [ -100.0, 60.0 ] + ] + ], + crs: { + type: "name", + properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" } + } + } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/name new file mode 100644 index 00000000000..7818b8760e6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoIntersects/example2/name @@ -0,0 +1 @@ +Intersects a "Big" Polygon \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/action.json new file mode 100644 index 00000000000..f4f09153ae4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/action.json @@ -0,0 +1,12 @@ +db.places.find( + { + loc: { + $geoWithin: { + $geometry: { + type : "Polygon" , + coordinates: [ [ [ 0.0, 0.0 ], [ 3.0, 6.0 ], [ 6.0, 1.0 ], [ 0.0, 0.0 ] ] ] + } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/name new file mode 100644 index 00000000000..c6c78533878 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/name @@ -0,0 +1 @@ +Within a Polygon \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/action.json new file mode 100644 index 00000000000..4b0b9f23f57 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/action.json @@ -0,0 +1,20 @@ +db.places.find( + { + loc: { + $geoWithin: { + $geometry: { + type : "Polygon" , + coordinates: [ + [ + [ -100.0, 60.0 ], [ -100.0, 0.0 ], [ -100.0, -60.0 ], [ 100.0, -60.0 ], [ 100.0, 60.0 ], [ -100.0, 60.0 ] + ] + ], + crs: { + type: "name", + properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" } + } + } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/name new file mode 100644 index 00000000000..8dedd8cb80c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/name @@ -0,0 +1 @@ +Within a "Big" Polygon \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/action.json new file mode 100644 index 00000000000..646a46eec7b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { quantity: { $gt: 20 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/expected.json new file mode 100644 index 00000000000..b74d8405248 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/expected.json @@ -0,0 +1,2 @@ +{ _id: ObjectId("61ba25cbfe687fce2f042414"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 }}, +{ _id: ObjectId("61ba25cbfe687fce2f042415"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/name new file mode 100644 index 00000000000..f19ec4ead4e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/name @@ -0,0 +1 @@ +Match Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/action.json new file mode 100644 index 00000000000..37ad372c1ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/action.json @@ -0,0 +1,3 @@ +db.inventory.updateOne( + { "carrier.fee": { $gt: 2 } }, { $set: { "price": 9.99 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/expected.json new file mode 100644 index 00000000000..50ea92968a5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/expected.json @@ -0,0 +1,2 @@ +{ _id: ObjectId("61ba3ec9fe687fce2f042417"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 }, price: 9.99}, +{ _id: ObjectId("61ba3ec9fe687fce2f042418"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 }}, diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/lock new file mode 100644 index 00000000000..62fdea5c79b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/lock @@ -0,0 +1 @@ +update expected to only show docs selected by the query \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/name new file mode 100644 index 00000000000..92e2ac251da --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example2/name @@ -0,0 +1 @@ +Perform an Update Based on Embedded Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/action.json new file mode 100644 index 00000000000..c4496fc1665 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { quantity: { $gte: 20 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/expected.json new file mode 100644 index 00000000000..e4badf9959f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/expected.json @@ -0,0 +1,2 @@ +{ _id: ObjectId("61bb51211b83c864e3bbe037"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 }}, +{ _id: ObjectId("61bb51211b83c864e3bbe038"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/lock new file mode 100644 index 00000000000..97fccb2fa08 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/lock @@ -0,0 +1 @@ +missing a closing brace \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/name new file mode 100644 index 00000000000..f19ec4ead4e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example1/name @@ -0,0 +1 @@ +Match Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/action.json new file mode 100644 index 00000000000..afe9f7db30c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/action.json @@ -0,0 +1,3 @@ +db.inventory.updateMany( + { "carrier.fee": { $gte: 2 } }, { $set: { "price": 9.99 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/expected.json new file mode 100644 index 00000000000..380ed05de60 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/expected.json @@ -0,0 +1,2 @@ +{ _id: ObjectId("61bb51211b83c864e3bbe037"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 }, price: 9.99}, +{ _id: ObjectId("61bb51211b83c864e3bbe038"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 }, price: 9.99} diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/lock new file mode 100644 index 00000000000..80ba47668ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/lock @@ -0,0 +1 @@ +code block had extra text in it diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/name new file mode 100644 index 00000000000..92e2ac251da --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gte/example2/name @@ -0,0 +1 @@ +Perform an Update Based on Embedded Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/in/example1/action.json new file mode 100644 index 00000000000..a1e99ecb675 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { quantity: { $in: [ 5, 15 ] } }, { _id: 0 } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/in/example1/data.json new file mode 100644 index 00000000000..24cc1e141ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example1/data.json @@ -0,0 +1,4 @@ +{ "item": "Pens", "quantity": 350, "tags": [ "school", "office" ] }, +{ "item": "Erasers", "quantity": 15, "tags": [ "school", "home" ] }, +{ "item": "Maps", "tags": [ "office", "storage" ] }, +{ "item": "Books", "quantity": 5, "tags": [ "school", "storage", "home" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/in/example1/expected.json new file mode 100644 index 00000000000..0a40e67d2be --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example1/expected.json @@ -0,0 +1,2 @@ +{ item: 'Erasers', quantity: 15, tags: [ 'school', 'home' ] }, +{ item: 'Books', quantity: 5, tags: [ 'school', 'storage', 'home' ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/in/example1/name new file mode 100644 index 00000000000..ad07067a10b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example1/name @@ -0,0 +1 @@ +Use the ``$in`` Operator to Match Values \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/action.json new file mode 100644 index 00000000000..c320aec9576 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/action.json @@ -0,0 +1,4 @@ +db.inventory.updateMany( + { tags: { $in: [ "home", "school" ] } }, + { $set: { exclude: false } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/data.json new file mode 100644 index 00000000000..24cc1e141ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/data.json @@ -0,0 +1,4 @@ +{ "item": "Pens", "quantity": 350, "tags": [ "school", "office" ] }, +{ "item": "Erasers", "quantity": 15, "tags": [ "school", "home" ] }, +{ "item": "Maps", "tags": [ "office", "storage" ] }, +{ "item": "Books", "quantity": 5, "tags": [ "school", "storage", "home" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/expected.json new file mode 100644 index 00000000000..556bf801ae2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/expected.json @@ -0,0 +1,3 @@ +{ item: 'Pens', quantity: 350, tags: [ 'school', 'office' ], exclude: false }, +{ item: 'Erasers', quantity: 15, tags: [ 'school', 'home' ], exclude: false }, +{ item: 'Books', quantity: 5, tags: [ 'school', 'storage', 'home' ], exclude: false } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/lock new file mode 100644 index 00000000000..80ba47668ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/lock @@ -0,0 +1 @@ +code block had extra text in it diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/name new file mode 100644 index 00000000000..690c38d9430 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example2/name @@ -0,0 +1 @@ +Use the ``$in`` Operator to Match Values in an Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/in/example3/action.json new file mode 100644 index 00000000000..cd0f68a5d2e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example3/action.json @@ -0,0 +1 @@ +db.inventory.find( { tags: { $in: [ /^be/, /^st/ ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/in/example3/data.json new file mode 100644 index 00000000000..24cc1e141ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example3/data.json @@ -0,0 +1,4 @@ +{ "item": "Pens", "quantity": 350, "tags": [ "school", "office" ] }, +{ "item": "Erasers", "quantity": 15, "tags": [ "school", "home" ] }, +{ "item": "Maps", "tags": [ "office", "storage" ] }, +{ "item": "Books", "quantity": 5, "tags": [ "school", "storage", "home" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/in/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/in/example3/name new file mode 100644 index 00000000000..46162d39436 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/in/example3/name @@ -0,0 +1 @@ +Use the ``$in`` Operator with a Regular Expression \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/action.json new file mode 100644 index 00000000000..63df13e3a85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { quantity: { $lt: 20 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/expected.json new file mode 100644 index 00000000000..63066caffe8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/expected.json @@ -0,0 +1 @@ +{ _id: ObjectId("61ba634dfe687fce2f04241f"), item: 'washers', quantity: 10, carrier: { name: 'Shipit', fee: 1 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/name new file mode 100644 index 00000000000..f19ec4ead4e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lt/example1/name @@ -0,0 +1 @@ +Match Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/action.json new file mode 100644 index 00000000000..6081b00c60a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/action.json @@ -0,0 +1 @@ +db.inventory.updateMany( { "carrier.fee": { $lt: 20 } }, { $set: { price: 9.99 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/expected.json new file mode 100644 index 00000000000..570db7b6598 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/expected.json @@ -0,0 +1,3 @@ +{ _id: ObjectId("61ba634dfe687fce2f04241d"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 }, price: 9.99}, +{ _id: ObjectId("61ba634dfe687fce2f04241e"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 }, price: 9.99}, +{ _id: ObjectId("61ba634dfe687fce2f04241f"), item: 'washers', quantity: 10, carrier: { name: 'Shipit', fee: 1 }, price: 9.99} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/name new file mode 100644 index 00000000000..92e2ac251da --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lt/example2/name @@ -0,0 +1 @@ +Perform an Update Based on Embedded Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/action.json new file mode 100644 index 00000000000..b5b71fc86b4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { quantity: { $lte: 20 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/expected.json new file mode 100644 index 00000000000..40834dfc07f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/expected.json @@ -0,0 +1 @@ +{ _id: ObjectId("61ba453ffe687fce2f04241c"), item: 'washers', quantity: 10, carrier: { name: 'Shipit', fee: 1 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/name new file mode 100644 index 00000000000..f19ec4ead4e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lte/example1/name @@ -0,0 +1 @@ +Match Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/action.json new file mode 100644 index 00000000000..2097f2ba669 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/action.json @@ -0,0 +1,3 @@ +db.inventory.updateMany( + { "carrier.fee": { $lte: 5 } }, { $set: { price: 9.99 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/expected.json new file mode 100644 index 00000000000..1ae78cbb33a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/expected.json @@ -0,0 +1,3 @@ +{ _id: ObjectId("61ba453ffe687fce2f04241a"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 }, price: 9.99}, +{ _id: ObjectId("61ba453ffe687fce2f04241b"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 }, price: 9.99}, +{ _id: ObjectId("61ba453ffe687fce2f04241c"), item: 'washers', quantity: 10, carrier: { name: 'Shipit', fee: 1 }, price: 9.99} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/name new file mode 100644 index 00000000000..92e2ac251da --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/lte/example2/name @@ -0,0 +1 @@ +Perform an Update Based on Embedded Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/action.json new file mode 100644 index 00000000000..8ac0ddce7b5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/action.json @@ -0,0 +1,13 @@ + loc: { + "$near": { + "$geometry": { + "type": "Point", + "coordinates": [ + -74.0, + 40.0 + ] + } + }, + $maxDistance: 10.0 + } +} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/lock new file mode 100644 index 00000000000..e0aafd56c27 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/lock @@ -0,0 +1,2 @@ +change distances to floating point +changed form of $near to not use legacy coordinate form \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/maxDistance/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example1/action.json new file mode 100644 index 00000000000..0340d09a95d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example1/action.json @@ -0,0 +1,12 @@ +db.places.find( + { + location: + { $near : + { + $geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, + $minDistance: 1000, + $maxDistance: 5000 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example1/name new file mode 100644 index 00000000000..d79735b7cac --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example1/name @@ -0,0 +1 @@ +Use with ``$near`` \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example2/action.json new file mode 100644 index 00000000000..9e0107d4f94 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example2/action.json @@ -0,0 +1,14 @@ +db.places.find( + { + location: { + $nearSphere: { + $geometry: { + type : "Point", + coordinates : [ -73.9667, 40.78 ] + }, + $minDistance: 1000, + $maxDistance: 5000 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example2/name new file mode 100644 index 00000000000..52269f784be --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/minDistance/example2/name @@ -0,0 +1 @@ +Use with ``$nearSphere`` \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/data.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/data.json deleted file mode 100644 index 501ad468365..00000000000 --- a/core/src/test/resources/dev/morphia/test/query/filters/mod/data.json +++ /dev/null @@ -1,3 +0,0 @@ -{ "_id" : 1, "item" : "abc123", "qty" : 0 } -{ "_id" : 2, "item" : "xyz123", "qty" : 5 } -{ "_id" : 3, "item" : "ijk123", "qty" : 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/action.json new file mode 100644 index 00000000000..9bbbeaf441b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { qty: { $mod: [ 4, 0 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/data.json new file mode 100644 index 00000000000..59bd56cc2eb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/data.json @@ -0,0 +1,3 @@ +{ "_id" : 1, "item" : "abc123", "qty" : 0 }, +{ "_id" : 2, "item" : "xyz123", "qty" : 5 }, +{ "_id" : 3, "item" : "ijk123", "qty" : 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/expected.json new file mode 100644 index 00000000000..a3e9140aaba --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/expected.json @@ -0,0 +1,2 @@ +{ '_id' : 1, 'item' : 'abc123', 'qty' : 0 }, +{ '_id' : 3, 'item' : 'ijk123', 'qty' : 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/name new file mode 100644 index 00000000000..f14cf3506ed --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example1/name @@ -0,0 +1 @@ +Use ``$mod`` to Select Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/action.json new file mode 100644 index 00000000000..cced5f3f734 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/action.json @@ -0,0 +1 @@ +db.inventory.find( { qty: { $mod: [ 4 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/data.json new file mode 100644 index 00000000000..59bd56cc2eb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/data.json @@ -0,0 +1,3 @@ +{ "_id" : 1, "item" : "abc123", "qty" : 0 }, +{ "_id" : 2, "item" : "xyz123", "qty" : 5 }, +{ "_id" : 3, "item" : "ijk123", "qty" : 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/expected.json new file mode 100644 index 00000000000..8525f3cce4e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/expected.json @@ -0,0 +1 @@ +MongoServerError: malformed mod, not enough elements \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/name new file mode 100644 index 00000000000..d3120521b87 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example2/name @@ -0,0 +1 @@ +Not Enough Elements Error \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/action.json new file mode 100644 index 00000000000..ce132bf3b50 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/action.json @@ -0,0 +1 @@ +db.inventory.find( { qty: { $mod: [ 4, 1, 2, 3 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/data.json new file mode 100644 index 00000000000..59bd56cc2eb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/data.json @@ -0,0 +1,3 @@ +{ "_id" : 1, "item" : "abc123", "qty" : 0 }, +{ "_id" : 2, "item" : "xyz123", "qty" : 5 }, +{ "_id" : 3, "item" : "ijk123", "qty" : 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/expected.json new file mode 100644 index 00000000000..10820e3640f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/expected.json @@ -0,0 +1 @@ +MongoServerError: malformed mod, too many elements \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/name new file mode 100644 index 00000000000..e7231f89bdd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example3/name @@ -0,0 +1 @@ +Too Many Elements Error \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/action.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/action.json new file mode 100644 index 00000000000..4cf58e82e68 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/action.json @@ -0,0 +1 @@ +db.inventory.find( { qty: { $mod: [ 4.0, 0.0 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/data.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/data.json new file mode 100644 index 00000000000..59bd56cc2eb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/data.json @@ -0,0 +1,3 @@ +{ "_id" : 1, "item" : "abc123", "qty" : 0 }, +{ "_id" : 2, "item" : "xyz123", "qty" : 5 }, +{ "_id" : 3, "item" : "ijk123", "qty" : 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/expected.json new file mode 100644 index 00000000000..b5eaca93370 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/expected.json @@ -0,0 +1,2 @@ +{ _id: 1, item: 'abc123', qty: 0 }, +{ _id: 3, item: 'ijk123', qty: 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/lock b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/lock new file mode 100644 index 00000000000..982ce43de7d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/lock @@ -0,0 +1 @@ +made the 0 a floating point to work the Java's type system \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/name b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/name new file mode 100644 index 00000000000..177a3dd274b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example4/name @@ -0,0 +1 @@ +Floating Point Arguments \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/action.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/action.json new file mode 100644 index 00000000000..f6b751d724e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/action.json @@ -0,0 +1 @@ +db.inventory.find( { qty: { $mod: [ -4, -0 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/data.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/data.json new file mode 100644 index 00000000000..59bd56cc2eb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/data.json @@ -0,0 +1,3 @@ +{ "_id" : 1, "item" : "abc123", "qty" : 0 }, +{ "_id" : 2, "item" : "xyz123", "qty" : 5 }, +{ "_id" : 3, "item" : "ijk123", "qty" : 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/expected.json new file mode 100644 index 00000000000..b5eaca93370 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/expected.json @@ -0,0 +1,2 @@ +{ _id: 1, item: 'abc123', qty: 0 }, +{ _id: 3, item: 'ijk123', qty: 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/name b/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/name new file mode 100644 index 00000000000..fe8f477dffd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/mod/example5/name @@ -0,0 +1 @@ +Negative Dividend \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/expected.json deleted file mode 100644 index 504bcd1519b..00000000000 --- a/core/src/test/resources/dev/morphia/test/query/filters/mod/expected.json +++ /dev/null @@ -1,2 +0,0 @@ -{ "_id" : 1, "item" : "abc123", "qty" : 0 } -{ "_id" : 3, "item" : "ijk123", "qty" : 12 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/mod/query.json b/core/src/test/resources/dev/morphia/test/query/filters/mod/query.json deleted file mode 100644 index 83e6604a8d4..00000000000 --- a/core/src/test/resources/dev/morphia/test/query/filters/mod/query.json +++ /dev/null @@ -1 +0,0 @@ -{ qty: { $mod: [ 4, 0 ] } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/action.json new file mode 100644 index 00000000000..b7f3c2bc7cc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/action.json @@ -0,0 +1 @@ + db.inventory.find( { quantity: { $ne: 20 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/expected.json new file mode 100644 index 00000000000..1857fb38f90 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/expected.json @@ -0,0 +1,3 @@ +{ _id: ObjectId("61ba667dfe687fce2f042420"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 } }, +{ _id: ObjectId("61ba667dfe687fce2f042421"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 } }, +{ _id: ObjectId("61ba667dfe687fce2f042422"), item: 'washers', quantity: 10, carrier: { name: 'Shipit', fee: 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/name new file mode 100644 index 00000000000..28e30903ac0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example1/name @@ -0,0 +1 @@ +Match Document Fields That Are Not Equal \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/action.json new file mode 100644 index 00000000000..18c22a86fc8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/action.json @@ -0,0 +1,4 @@ + db.inventory.updateMany( + { "carrier.fee" : { $ne: 1 } }, + { $set: { "price": 9.99 } } + ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/expected.json new file mode 100644 index 00000000000..9182777cb14 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/expected.json @@ -0,0 +1,2 @@ +{ _id: ObjectId("61ba66e2fe687fce2f042423"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 }, price: 9.99 }, +{ _id: ObjectId("61ba66e2fe687fce2f042424"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 }, price: 9.99 }, diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/lock new file mode 100644 index 00000000000..62fdea5c79b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/lock @@ -0,0 +1 @@ +update expected to only show docs selected by the query \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/name new file mode 100644 index 00000000000..b6afc8e2e51 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/ne/example2/name @@ -0,0 +1 @@ +Update Based on Not Equal Embedded Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/near/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/near/example1/action.json new file mode 100644 index 00000000000..fb0bf3f42f4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/near/example1/action.json @@ -0,0 +1,12 @@ +db.places.find( + { + location: + { $near : + { + $geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, + $minDistance: 1000.0, + $maxDistance: 5000.0 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/near/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/near/example1/lock new file mode 100644 index 00000000000..c18abb162ae --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/near/example1/lock @@ -0,0 +1 @@ +use floating point values \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/near/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/near/example1/name new file mode 100644 index 00000000000..96f9817864a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/near/example1/name @@ -0,0 +1 @@ +Query on GeoJSON Data \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/near/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/near/example2/action.json new file mode 100644 index 00000000000..88a21102f12 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/near/example2/action.json @@ -0,0 +1,3 @@ +db.legacy2d.find( + { location : { $near : [ -73.9667, 40.78 ], $maxDistance: 0.10 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/near/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/near/example2/name new file mode 100644 index 00000000000..22b6a71a053 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/near/example2/name @@ -0,0 +1 @@ +Query on Legacy Coordinates \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/action.json new file mode 100644 index 00000000000..9bc09cb89cb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/action.json @@ -0,0 +1,14 @@ +db.places.find( + { + location: { + $nearSphere: { + $geometry: { + type : "Point", + coordinates : [ -73.9667, 40.78 ] + }, + $minDistance: 1000.0, + $maxDistance: 5000.0 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/lock new file mode 100644 index 00000000000..855d8a1f6f7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/lock @@ -0,0 +1 @@ +change distances to floating point \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/name new file mode 100644 index 00000000000..adecb62cb69 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example1/name @@ -0,0 +1 @@ +Specify Center Point Using GeoJSON \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example2/action.json new file mode 100644 index 00000000000..29303bd7c2e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example2/action.json @@ -0,0 +1,3 @@ +db.legacyPlaces.find( + { location : { $nearSphere : [ -73.9667, 40.78 ], $maxDistance: 0.10 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example2/name new file mode 100644 index 00000000000..3d04cff4ff5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nearSphere/example2/name @@ -0,0 +1 @@ +Specify Center Point Using Legacy Coordinates \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/action.json new file mode 100644 index 00000000000..f83197250fa --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { quantity: { $nin: [ 5, 15 ] } }, { _id: 0 } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/data.json new file mode 100644 index 00000000000..24cc1e141ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/data.json @@ -0,0 +1,4 @@ +{ "item": "Pens", "quantity": 350, "tags": [ "school", "office" ] }, +{ "item": "Erasers", "quantity": 15, "tags": [ "school", "home" ] }, +{ "item": "Maps", "tags": [ "office", "storage" ] }, +{ "item": "Books", "quantity": 5, "tags": [ "school", "storage", "home" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/expected.json new file mode 100644 index 00000000000..af8adf3ff7b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/expected.json @@ -0,0 +1,2 @@ +{ item: 'Pens', quantity: 350, tags: [ 'school', 'office' ] }, +{ item: 'Maps', tags: [ 'office', 'storage' ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/name new file mode 100644 index 00000000000..6d7a4559113 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example1/name @@ -0,0 +1 @@ +Select on Unmatching Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/action.json new file mode 100644 index 00000000000..114d6d9a98d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/action.json @@ -0,0 +1,4 @@ +db.inventory.updateMany( + { tags: { $nin: [ "school" ] } }, + { $set: { exclude: true } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/data.json new file mode 100644 index 00000000000..24cc1e141ff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/data.json @@ -0,0 +1,4 @@ +{ "item": "Pens", "quantity": 350, "tags": [ "school", "office" ] }, +{ "item": "Erasers", "quantity": 15, "tags": [ "school", "home" ] }, +{ "item": "Maps", "tags": [ "office", "storage" ] }, +{ "item": "Books", "quantity": 5, "tags": [ "school", "storage", "home" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/expected.json new file mode 100644 index 00000000000..bf33637ccea --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/expected.json @@ -0,0 +1 @@ +{ "item": "Maps", "tags": [ "office", "storage" ], exclude: true }, diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/lock new file mode 100644 index 00000000000..62fdea5c79b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/lock @@ -0,0 +1 @@ +update expected to only show docs selected by the query \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/name new file mode 100644 index 00000000000..3d4de7cae29 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nin/example2/name @@ -0,0 +1 @@ +Select on Elements Not in an Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nor/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/nor/example1/action.json new file mode 100644 index 00000000000..439225848ef --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nor/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { $nor: [ { price: 1.99 }, { sale: true } ] } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nor/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/nor/example1/name new file mode 100644 index 00000000000..8b964c9b854 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nor/example1/name @@ -0,0 +1 @@ +``$nor`` Query with Two Expressions \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nor/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/nor/example2/action.json new file mode 100644 index 00000000000..622eb984257 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nor/example2/action.json @@ -0,0 +1 @@ +db.inventory.find( { $nor: [ { price: 1.99 }, { qty: { $lt: 20 } }, { sale: true } ] } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nor/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/nor/example2/name new file mode 100644 index 00000000000..9bb6bf169ec --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nor/example2/name @@ -0,0 +1 @@ +``$nor`` and Additional Comparisons \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nor/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/nor/example3/action.json new file mode 100644 index 00000000000..89b9b12d24f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nor/example3/action.json @@ -0,0 +1,2 @@ +db.inventory.find( { $nor: [ { price: 1.99 }, { price: { $exists: false } }, + { sale: true }, { sale: { $exists: false } } ] } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/nor/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/nor/example3/name new file mode 100644 index 00000000000..6f77fbb61ee --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/nor/example3/name @@ -0,0 +1 @@ +``$nor`` and ``$exists`` \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/action.json new file mode 100644 index 00000000000..513ba08de93 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/action.json @@ -0,0 +1,7 @@ +db.places.find( + { + loc: { + $geoWithin: { $polygon: [ [ 0.0 , 0.0 ], [ 3.0 , 6.0 ], [ 6.0 , 0.0 ] ] } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/action.json new file mode 100644 index 00000000000..6b696af74c4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/action.json @@ -0,0 +1,10 @@ +db.donors.updateMany( + {}, + { $set: + { amount: + { $floor: + { $multiply: [ { $rand: {} }, 100 ] } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/data.json new file mode 100644 index 00000000000..58830508e89 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/data.json @@ -0,0 +1,5 @@ +{ donorId: 1000, amount: 0, frequency: 1 }, +{ donorId: 1001, amount: 0, frequency: 2 }, +{ donorId: 1002, amount: 0, frequency: 1 }, +{ donorId: 1003, amount: 0, frequency: 2 }, +{ donorId: 1004, amount: 0, frequency: 1 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/expected.json new file mode 100644 index 00000000000..694ce104ffc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/expected.json @@ -0,0 +1,5 @@ +{ "donorId" : 1000, "amount" : 2, "frequency" : 1 } +{ "donorId" : 1001, "amount" : 58, "frequency" : 2 } +{ "donorId" : 1002, "amount" : 27, "frequency" : 1 } +{ "donorId" : 1003, "amount" : 26, "frequency" : 2 } +{ "donorId" : 1004, "amount" : 42, "frequency" : 1 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/lock new file mode 100644 index 00000000000..061f167f206 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/lock @@ -0,0 +1 @@ +unwrap the operators from the array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/name new file mode 100644 index 00000000000..a9a376762cc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example1/name @@ -0,0 +1 @@ +Generate Random Data Points \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/action.json new file mode 100644 index 00000000000..3078b59707e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/action.json @@ -0,0 +1,6 @@ +db.voters.find( + { district: 3, + $expr: { $lt: [0.5, {$rand: {} } ] } + }, + { _id: 0, name: 1, registered: 1 } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/data.json new file mode 100644 index 00000000000..554d94c67fd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/data.json @@ -0,0 +1,10 @@ +{ name: "Archibald", voterId: 4321, district: 3, registered: true }, +{ name: "Beckham", voterId: 4331, district: 3, registered: true }, +{ name: "Carolin", voterId: 5321, district: 4, registered: true }, +{ name: "Debarge", voterId: 4343, district: 3, registered: false }, +{ name: "Eckhard", voterId: 4161, district: 3, registered: false }, +{ name: "Faberge", voterId: 4300, district: 1, registered: true }, +{ name: "Grimwald", voterId: 4111, district: 3, registered: true }, +{ name: "Humphrey", voterId: 2021, district: 3, registered: true }, +{ name: "Idelfon", voterId: 1021, district: 4, registered: true }, +{ name: "Justo", voterId: 9891, district: 3, registered: false } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/expected.json new file mode 100644 index 00000000000..1e4c3738697 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/expected.json @@ -0,0 +1,4 @@ +{ "name" : "Beckham", "registered" : true } +{ "name" : "Eckhard", "registered" : false } +{ "name" : "Grimwald", "registered" : true } +{ "name" : "Humphrey", "registered" : true } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/name new file mode 100644 index 00000000000..d113a4d5147 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/rand/example2/name @@ -0,0 +1 @@ +Select Random Items From a Collection \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/action.json new file mode 100644 index 00000000000..187058efaaa --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/action.json @@ -0,0 +1 @@ +db.products.find( { sku: { $regex: /789$/ } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/data.json new file mode 100644 index 00000000000..14d2f33d3b3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/data.json @@ -0,0 +1,5 @@ +{ _id: 100, sku: "abc123", description: "Single line description." }, +{ _id: 101, sku: "abc789", description: "First line\nSecond line" }, +{ _id: 102, sku: "xyz456", description: "Many spaces before line" }, +{ _id: 103, sku: "xyz789", description: "Multiple\nline description" }, +{ _id: 104, sku: "Abc789", description: "SKU starts with A" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/expected.json new file mode 100644 index 00000000000..e56a6251c2b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/expected.json @@ -0,0 +1,3 @@ +{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, +{ _id: 103, sku: 'xyz789', description: 'Multiple\nline description' }, +{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/lock new file mode 100644 index 00000000000..52f657c2264 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/lock @@ -0,0 +1 @@ +expected text has extraneous examples \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/name new file mode 100644 index 00000000000..a46d298efb6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example1/name @@ -0,0 +1 @@ +Perform a ``LIKE`` Match \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/action.json new file mode 100644 index 00000000000..aaa8c1a4864 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/action.json @@ -0,0 +1 @@ +db.products.find( { sku: { $regex: /^ABC/i } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/data.json new file mode 100644 index 00000000000..14d2f33d3b3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/data.json @@ -0,0 +1,5 @@ +{ _id: 100, sku: "abc123", description: "Single line description." }, +{ _id: 101, sku: "abc789", description: "First line\nSecond line" }, +{ _id: 102, sku: "xyz456", description: "Many spaces before line" }, +{ _id: 103, sku: "xyz789", description: "Multiple\nline description" }, +{ _id: 104, sku: "Abc789", description: "SKU starts with A" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/expected.json new file mode 100644 index 00000000000..6562bd63ec6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/expected.json @@ -0,0 +1,3 @@ +{ _id: 100, sku: 'abc123', description: 'Single line description.' }, +{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, +{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/name new file mode 100644 index 00000000000..90b47c77bf4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example2/name @@ -0,0 +1 @@ +Perform Case-Insensitive Regular Expression Match \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/action.json new file mode 100644 index 00000000000..f10d993d9c9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/action.json @@ -0,0 +1 @@ +db.products.find( { description: { $regex: /^S/m } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/data.json new file mode 100644 index 00000000000..14d2f33d3b3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/data.json @@ -0,0 +1,5 @@ +{ _id: 100, sku: "abc123", description: "Single line description." }, +{ _id: 101, sku: "abc789", description: "First line\nSecond line" }, +{ _id: 102, sku: "xyz456", description: "Many spaces before line" }, +{ _id: 103, sku: "xyz789", description: "Multiple\nline description" }, +{ _id: 104, sku: "Abc789", description: "SKU starts with A" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/expected.json new file mode 100644 index 00000000000..6562bd63ec6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/expected.json @@ -0,0 +1,3 @@ +{ _id: 100, sku: 'abc123', description: 'Single line description.' }, +{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, +{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/lock b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/lock new file mode 100644 index 00000000000..350a856c9b9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/lock @@ -0,0 +1 @@ +change the form of regex used \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/name new file mode 100644 index 00000000000..3a79c19c60a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example3/name @@ -0,0 +1 @@ +Multiline Match for Lines Starting with Specified Pattern \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/action.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/action.json new file mode 100644 index 00000000000..e28d7d004bf --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/action.json @@ -0,0 +1 @@ +db.products.find( { description: { $regex: /m.*line/is } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/data.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/data.json new file mode 100644 index 00000000000..14d2f33d3b3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/data.json @@ -0,0 +1,5 @@ +{ _id: 100, sku: "abc123", description: "Single line description." }, +{ _id: 101, sku: "abc789", description: "First line\nSecond line" }, +{ _id: 102, sku: "xyz456", description: "Many spaces before line" }, +{ _id: 103, sku: "xyz789", description: "Multiple\nline description" }, +{ _id: 104, sku: "Abc789", description: "SKU starts with A" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/expected.json new file mode 100644 index 00000000000..b3727258f0f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/expected.json @@ -0,0 +1,2 @@ +{ _id: 102, sku: 'xyz456', description: 'Many spaces before line' }, +{ _id: 103, sku: 'xyz789', description: 'Multiple\nline description' } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/lock b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/lock new file mode 100644 index 00000000000..e88d74c3b9a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/lock @@ -0,0 +1,2 @@ +change the form of regex used +alphabetize the flags \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/name b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/name new file mode 100644 index 00000000000..4e230193c21 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example4/name @@ -0,0 +1 @@ +Use the ``.`` Dot Character to Match New Line \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/action.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/action.json new file mode 100644 index 00000000000..d7f717514d3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/action.json @@ -0,0 +1,3 @@ +db.products.find( { sku: { $regex: /abc #category code + +123 #item number/x } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/data.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/data.json new file mode 100644 index 00000000000..14d2f33d3b3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/data.json @@ -0,0 +1,5 @@ +{ _id: 100, sku: "abc123", description: "Single line description." }, +{ _id: 101, sku: "abc789", description: "First line\nSecond line" }, +{ _id: 102, sku: "xyz456", description: "Many spaces before line" }, +{ _id: 103, sku: "xyz789", description: "Multiple\nline description" }, +{ _id: 104, sku: "Abc789", description: "SKU starts with A" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/expected.json new file mode 100644 index 00000000000..caa9f2bdcbb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/expected.json @@ -0,0 +1 @@ +{ _id: 100, sku: 'abc123', description: 'Single line description.' } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/lock b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/lock new file mode 100644 index 00000000000..4eb792008a6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/lock @@ -0,0 +1 @@ +change the form of regex used diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/name b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/name new file mode 100644 index 00000000000..4494d4b8736 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example5/name @@ -0,0 +1 @@ +Ignore White Spaces in Pattern \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/action.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/action.json new file mode 100644 index 00000000000..87783f8c164 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/action.json @@ -0,0 +1 @@ +db.products.find( { sku: { $regex: /(?i)a(?-i)bc/ } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/data.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/data.json new file mode 100644 index 00000000000..14d2f33d3b3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/data.json @@ -0,0 +1,5 @@ +{ _id: 100, sku: "abc123", description: "Single line description." }, +{ _id: 101, sku: "abc789", description: "First line\nSecond line" }, +{ _id: 102, sku: "xyz456", description: "Many spaces before line" }, +{ _id: 103, sku: "xyz789", description: "Multiple\nline description" }, +{ _id: 104, sku: "Abc789", description: "SKU starts with A" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/expected.json new file mode 100644 index 00000000000..6562bd63ec6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/expected.json @@ -0,0 +1,3 @@ +{ _id: 100, sku: 'abc123', description: 'Single line description.' }, +{ _id: 101, sku: 'abc789', description: 'First line\nSecond line' }, +{ _id: 104, sku: 'Abc789', description: 'SKU starts with A' } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/lock b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/lock new file mode 100644 index 00000000000..4eb792008a6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/lock @@ -0,0 +1 @@ +change the form of regex used diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/name b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/name new file mode 100644 index 00000000000..1662b187eb2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example6/name @@ -0,0 +1 @@ +Use a Regular Expression to Match Case in Strings \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/action.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/action.json new file mode 100644 index 00000000000..697b13bc134 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/action.json @@ -0,0 +1 @@ +db.songs.find( { artist: { $regex: /\byster/ } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/data.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/data.json new file mode 100644 index 00000000000..c5ee0cf2779 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/data.json @@ -0,0 +1,3 @@ +{ _id: 0, "artist" : "Blue Öyster Cult", "title": "The Reaper" }, +{ _id: 1, "artist": "Blue Öyster Cult", "title": "Godzilla" }, +{ _id: 2, "artist" : "Blue Oyster Cult", "title": "Take Me Away" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/expected.json new file mode 100644 index 00000000000..23587381782 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/expected.json @@ -0,0 +1,2 @@ +{ _id: 0, artist: 'Blue Öyster Cult', title: 'The Reaper' }, +{ _id: 1, artist: 'Blue Öyster Cult', title: 'Godzilla' } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/lock b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/lock new file mode 100644 index 00000000000..4eb792008a6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/lock @@ -0,0 +1 @@ +change the form of regex used diff --git a/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/name b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/name new file mode 100644 index 00000000000..1641548f2f5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/regex/example7/name @@ -0,0 +1 @@ +Extend Regex Options to Match Characters Outside of ASCII \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/action.json new file mode 100644 index 00000000000..9f614d371b7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/action.json @@ -0,0 +1 @@ +db.articles.find( { $text: { $search: "coffee" } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/expected.json new file mode 100644 index 00000000000..a8b4f001bed --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/expected.json @@ -0,0 +1,3 @@ +{ _id: 1, subject: 'coffee', author: 'xyz', views: 50 }, +{ _id: 7, subject: 'coffee and cream', author: 'efg', views: 10 }, +{ _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example1/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/name new file mode 100644 index 00000000000..9bcf58ca547 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example1/name @@ -0,0 +1 @@ +``$text`` with a Single Word \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/action.json new file mode 100644 index 00000000000..964ceaa755f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/action.json @@ -0,0 +1 @@ +db.articles.find( { $text: { $search: "bake coffee cake" } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/expected.json new file mode 100644 index 00000000000..ea61d38dc8d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/expected.json @@ -0,0 +1,5 @@ +{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 } +{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 } +{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 } +{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90 } +{ "_id" : 4, "subject" : "baking", "author" : "xyz", "views" : 100 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example2/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/name new file mode 100644 index 00000000000..909a353e976 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example2/name @@ -0,0 +1 @@ +Match Any of the ``$search`` Terms \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/action.json new file mode 100644 index 00000000000..8ebaefffe40 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/action.json @@ -0,0 +1 @@ +db.articles.find( { $text: { $search: "\"coffee shop\"" } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/expected.json new file mode 100644 index 00000000000..2aea5df5fcb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/expected.json @@ -0,0 +1 @@ +{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example3/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/name new file mode 100644 index 00000000000..d37d37486c9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example3/name @@ -0,0 +1 @@ +``$text`` with a Phrase \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example4/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/action.json new file mode 100644 index 00000000000..4a60953d284 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/action.json @@ -0,0 +1 @@ +db.articles.find( { $text: { $search: "coffee -shop" } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example4/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/expected.json new file mode 100644 index 00000000000..41d1e84a768 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 } +{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example4/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example4/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/name new file mode 100644 index 00000000000..c81b1af7a8c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example4/name @@ -0,0 +1 @@ +Exclude Documents That Contain a Term \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example5/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/action.json new file mode 100644 index 00000000000..c9373fd065e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/action.json @@ -0,0 +1,3 @@ +db.articles.find( + { $text: { $search: "leche", $language: "es" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example5/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example5/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/expected.json new file mode 100644 index 00000000000..8c05c76ac91 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/expected.json @@ -0,0 +1,2 @@ +{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 } +{ "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz", "views" : 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example5/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example5/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/name new file mode 100644 index 00000000000..d67c8a66835 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example5/name @@ -0,0 +1 @@ +Query a Different Language \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example6/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/action.json new file mode 100644 index 00000000000..639213bc3f2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/action.json @@ -0,0 +1 @@ +db.articles.find( { $text: { $search: "сы́рники CAFÉS" } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example6/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example6/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/expected.json new file mode 100644 index 00000000000..143de8595b2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/expected.json @@ -0,0 +1,3 @@ +{ "_id" : 6, "subject" : "Сырники", "author" : "jkl", "views" : 80 } +{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 } +{ "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz", "views" : 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example6/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example6/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/name new file mode 100644 index 00000000000..7528893a283 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example6/name @@ -0,0 +1 @@ +Case and Diacritic Insensitivity \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example7/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/action.json new file mode 100644 index 00000000000..5714033b71c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/action.json @@ -0,0 +1 @@ +db.articles.find( { $text: { $search: "Coffee", $caseSensitive: true } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example7/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example7/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/expected.json new file mode 100644 index 00000000000..2aea5df5fcb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/expected.json @@ -0,0 +1 @@ +{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example7/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example7/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/name new file mode 100644 index 00000000000..132c3145494 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example7/name @@ -0,0 +1 @@ +Case Sensitivity \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example8/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/action.json new file mode 100644 index 00000000000..901a8e9c19e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/action.json @@ -0,0 +1 @@ +db.articles.find( { $text: { $search: "CAFÉ", $diacriticSensitive: true } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example8/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example8/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/expected.json new file mode 100644 index 00000000000..ce9dfd00d3a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/expected.json @@ -0,0 +1 @@ +{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", views: 200 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example8/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example8/lock b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/lock new file mode 100644 index 00000000000..83e6a22e87e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/lock @@ -0,0 +1 @@ +expected data was missing a field \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example8/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/name new file mode 100644 index 00000000000..a3ec10ed138 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example8/name @@ -0,0 +1 @@ +Diacritic Sensitive Search \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example9/action.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/action.json new file mode 100644 index 00000000000..88c5d84f129 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/action.json @@ -0,0 +1,4 @@ +db.articles.find( + { $text: { $search: "cake" } }, + { score: { $meta: "textScore" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example9/data.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/data.json new file mode 100644 index 00000000000..460579147df --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/data.json @@ -0,0 +1,8 @@ +{ _id: 1, subject: "coffee", author: "xyz", views: 50 }, +{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, +{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, +{ _id: 4, subject: "baking", author: "xyz", views: 100 }, +{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, +{ _id: 6, subject: "Сырники", author: "jkl", views: 80 }, +{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, +{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example9/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/expected.json new file mode 100644 index 00000000000..85bf2545093 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/expected.json @@ -0,0 +1 @@ +{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90, "score" : 0.75 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example9/index.json b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/index.json new file mode 100644 index 00000000000..dc1043aa156 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/index.json @@ -0,0 +1 @@ +{ subject: "text" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/text/example9/name b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/name new file mode 100644 index 00000000000..90e79e95fbd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/text/example9/name @@ -0,0 +1 @@ +Relevance Score Examples \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/action.json new file mode 100644 index 00000000000..1dad012113e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/action.json @@ -0,0 +1 @@ +db.addressBook.find( { zipCode : { $type : "string" } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/data.json new file mode 100644 index 00000000000..c9d7276cdaa --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/data.json @@ -0,0 +1,5 @@ +{ _id : 1, address : "2030 Martian Way", zipCode : "90698345" }, +{ _id : 2, address : "156 Lunar Place", zipCode : 43339374 }, +{ _id : 3, address : "2324 Pluto Place", zipCode : NumberLong(3921412) }, +{ _id : 4, address : "55 Saturn Ring" , zipCode : NumberInt(88602117) }, +{ _id : 5, address : "104 Venus Drive", zipCode : ["834847278", "1893289032"] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/expected.json new file mode 100644 index 00000000000..f8527188411 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/expected.json @@ -0,0 +1,2 @@ +{ _id : 1, address : "2030 Martian Way", zipCode : "90698345" } +{ _id : 5, address : "104 Venus Drive", zipCode : [ "834847278", "1893289032" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/lock new file mode 100644 index 00000000000..45e89813e31 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/lock @@ -0,0 +1 @@ +the docs had two actions showing the two forms. picked the form morphia uses. \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/name new file mode 100644 index 00000000000..b6f9cec4e98 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example1/name @@ -0,0 +1 @@ +Querying by Data Type \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/action.json new file mode 100644 index 00000000000..6596cad47c6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/action.json @@ -0,0 +1 @@ +db.grades.find( { classAverage : { $type : [ "string" , "double" ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example2/data.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/data.json new file mode 100644 index 00000000000..a566abbed93 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/data.json @@ -0,0 +1,4 @@ +{ _id : 1, name : "Alice King" , classAverage : 87.333333333333333 }, +{ _id : 2, name : "Bob Jenkins", classAverage : "83.52" }, +{ _id : 3, name : "Cathy Hart", classAverage: "94.06" }, +{ _id : 4, name : "Drew Williams" , classAverage : NumberInt("93") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/expected.json new file mode 100644 index 00000000000..4149fd0ba3b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/expected.json @@ -0,0 +1,3 @@ +{ _id : 1, name : "Alice King", classAverage : 87.33333333333333 } +{ _id : 2, name : "Bob Jenkins", classAverage : "83.52" } +{ _id : 3, name : "Cathy Hart", classAverage : "94.06" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example2/lock b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/lock new file mode 100644 index 00000000000..45e89813e31 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/lock @@ -0,0 +1 @@ +the docs had two actions showing the two forms. picked the form morphia uses. \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/name new file mode 100644 index 00000000000..aa965a3b113 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example2/name @@ -0,0 +1 @@ +Querying by Multiple Data Types \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example3/action.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/action.json new file mode 100644 index 00000000000..f92c6aa39ac --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/action.json @@ -0,0 +1,3 @@ +db.restaurants.find( + { "grades.grade" : { $type : "minKey" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example3/data.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/data.json new file mode 100644 index 00000000000..93c8c942869 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/data.json @@ -0,0 +1 @@ +{ _id: 1, address: { building: "230", coord: [ -73.996089, 40.675018 ], street: "Huntington St", zipcode: "11231" }, borough: "Brooklyn", cuisine: "Bakery", grades: [ { date : ISODate("2014-03-03T00:00:00Z"), grade : "C", score : 15 }, { date : ISODate("2013-09-11T00:00:00Z"), grade : "C", score : 16 }, { date : ISODate("2013-01-24T00:00:00Z"), grade : MinKey(), score : 30 }, { date : ISODate("2011-11-23T00:00:00Z"), grade : "C", score : 15 } ], name : "Dirty Dan's Donuts", restaurant_id : "30075445" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/expected.json new file mode 100644 index 00000000000..7c1aebbc5aa --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/expected.json @@ -0,0 +1 @@ +{ _id : 1, address : { building : "230", coord : [ -73.996089, 40.675018 ], street : "Huntington St", zipcode : "11231" }, borough : "Brooklyn", cuisine : "Bakery", grades : [ { date : ISODate("2014-03-03T00:00:00Z"), grade : "C", score : 15 }, { date : ISODate("2013-09-11T00:00:00Z"), grade : "C", score : 16 }, { date : ISODate("2013-01-24T00:00:00Z"), grade : { "$minKey" : 1 }, score : 30 }, { date : ISODate("2011-11-23T00:00:00Z"), grade : "C", score : 15 } ], name : "Dirty Dan's Donuts", restaurant_id : "30075445"} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example3/lock b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/lock new file mode 100644 index 00000000000..3bb475b3fa5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/lock @@ -0,0 +1 @@ +multiple examples in one \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/type/example3/name b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/name new file mode 100644 index 00000000000..5daa49af004 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/type/example3/name @@ -0,0 +1 @@ +Querying by MinKey and MaxKey \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/where/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/where/example1/action.json new file mode 100644 index 00000000000..b6e0660337f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/where/example1/action.json @@ -0,0 +1,3 @@ +db.players.find( { $where: function() { + return (hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994") +} } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/where/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/where/example1/data.json new file mode 100644 index 00000000000..6f81084467e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/where/example1/data.json @@ -0,0 +1,2 @@ +{ _id: 12378, name: "Steve", username: "steveisawesome", first_login: "2017-01-01" }, +{ _id: 2, name: "Anya", username: "anya", first_login: "2001-02-02" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/where/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/where/example1/expected.json new file mode 100644 index 00000000000..518b801dcec --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/where/example1/expected.json @@ -0,0 +1 @@ +{ "_id" : 2, "name" : "Anya", "username" : "anya", "first_login" : "2001-02-02"} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/where/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/where/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/where/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/action.json new file mode 100644 index 00000000000..024ba70930b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/action.json @@ -0,0 +1,4 @@ +db.inventory.updateOne( + { _id: 1 }, + { $addToSet: { tags: "accessories" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/data.json new file mode 100644 index 00000000000..36216e7722b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/expected.json new file mode 100644 index 00000000000..7ddd72b47ae --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" , "accessories" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/name new file mode 100644 index 00000000000..1792cdc87b1 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example1/name @@ -0,0 +1 @@ +Add to Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/action.json new file mode 100644 index 00000000000..ffff1c04eb7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/action.json @@ -0,0 +1,4 @@ +db.inventory.updateOne( + { _id: 1 }, + { $addToSet: { tags: "camera" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/data.json new file mode 100644 index 00000000000..121be0fbcd2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/data.json @@ -0,0 +1 @@ +{ _id: 1, item: "polarizing_filter", tags: [ "electronics" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/expected.json new file mode 100644 index 00000000000..36216e7722b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/expected.json @@ -0,0 +1 @@ +{ _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/lock b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/lock new file mode 100644 index 00000000000..d46139afef2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/lock @@ -0,0 +1,2 @@ +was missing expected.json +data.json already had the mutated document \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/name new file mode 100644 index 00000000000..f3d0f266f01 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example2/name @@ -0,0 +1 @@ +Value Already Exists \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/action.json new file mode 100644 index 00000000000..058dd106bfb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/action.json @@ -0,0 +1,4 @@ +db.inventory.updateOne( + { _id: 2 }, + { $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } } + ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/data.json new file mode 100644 index 00000000000..5abb0e50645 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/data.json @@ -0,0 +1 @@ +{ _id: 2, item: "cable", tags: [ "electronics", "supplies" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/expected.json new file mode 100644 index 00000000000..344818db567 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/expected.json @@ -0,0 +1 @@ +{ _id: 2, item: "cable", tags: [ "electronics", "supplies", "camera", "accessories" ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/name new file mode 100644 index 00000000000..df99a76d3af --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/addToSet/example3/name @@ -0,0 +1 @@ +``$each`` Modifier \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/action.json new file mode 100644 index 00000000000..35e5a839da0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/action.json @@ -0,0 +1,4 @@ +db.switches.updateOne( + { _id: 1 }, + { $bit: { expdata: { and: NumberInt( 10 ) } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/data.json new file mode 100644 index 00000000000..57f18c38c75 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/data.json @@ -0,0 +1,3 @@ +{ _id: 1, expdata: NumberInt(13) }, +{ _id: 2, expdata: NumberInt(3) }, +{ _id: 3, expdata: NumberInt(1) } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/expected.json new file mode 100644 index 00000000000..4ee00857f20 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "expdata" : 8 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/lock b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/lock new file mode 100644 index 00000000000..368e907b558 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/lock @@ -0,0 +1 @@ +the expected had some exposition to sift through \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/name new file mode 100644 index 00000000000..9bb2dc984b8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example1/name @@ -0,0 +1 @@ +Bitwise AND \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/action.json new file mode 100644 index 00000000000..aa6f811dac5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/action.json @@ -0,0 +1,4 @@ +db.switches.updateOne( + { _id: 2 }, + { $bit: { expdata: { or: NumberInt( 5 ) } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/data.json new file mode 100644 index 00000000000..57f18c38c75 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/data.json @@ -0,0 +1,3 @@ +{ _id: 1, expdata: NumberInt(13) }, +{ _id: 2, expdata: NumberInt(3) }, +{ _id: 3, expdata: NumberInt(1) } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/expected.json new file mode 100644 index 00000000000..c56f8064415 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/expected.json @@ -0,0 +1 @@ +{ "_id" : 2, "expdata" : 7 } diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/lock b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/lock new file mode 100644 index 00000000000..368e907b558 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/lock @@ -0,0 +1 @@ +the expected had some exposition to sift through \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/name new file mode 100644 index 00000000000..19ed1758a73 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example2/name @@ -0,0 +1 @@ +Bitwise OR \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/action.json new file mode 100644 index 00000000000..a95db4046a7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/action.json @@ -0,0 +1,4 @@ +db.switches.updateOne( + { _id: 3 }, + { $bit: { expdata: { xor: NumberInt( 5 ) } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/data.json new file mode 100644 index 00000000000..57f18c38c75 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/data.json @@ -0,0 +1,3 @@ +{ _id: 1, expdata: NumberInt(13) }, +{ _id: 2, expdata: NumberInt(3) }, +{ _id: 3, expdata: NumberInt(1) } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/expected.json new file mode 100644 index 00000000000..7398926ee90 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/expected.json @@ -0,0 +1 @@ +{ "_id" : 3, "expdata" : 4 } diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/lock b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/lock new file mode 100644 index 00000000000..f16261aa121 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/lock @@ -0,0 +1,2 @@ +the expected had some exposition to sift through +expected had _id wrong \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/name new file mode 100644 index 00000000000..3506ae86e2c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/bit/example3/name @@ -0,0 +1 @@ +Bitwise XOR \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/action.json new file mode 100644 index 00000000000..48c3596cbff --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/action.json @@ -0,0 +1,13 @@ +db.customers.updateOne( + { _id: 1 }, + { + $currentDate: { + lastModified: true, + "cancellation.date": { $type: "timestamp" } + }, + $set: { + "cancellation.reason": "user request", + status: "D" + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/data.json new file mode 100644 index 00000000000..881b61a373e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, status: "a", lastModified: ISODate("2013-10-02T01:11:18.965Z") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/expected.json new file mode 100644 index 00000000000..6edd70b6e9e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "status" : "D", "lastModified" : ISODate("2020-01-22T21:21:41.052Z"), "cancellation" : { "date" : Timestamp(1579728101, 1), "reason" : "user request" }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/action.json new file mode 100644 index 00000000000..598f159bdbe --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/action.json @@ -0,0 +1,6 @@ +db.customers.updateOne( + { _id: 1 }, + [ + { $set: { lastModified: "$$NOW", cancellation: {date: "$$CLUSTER_TIME", reason: "user request"}, status: "D" } } + ] +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/data.json new file mode 100644 index 00000000000..881b61a373e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/data.json @@ -0,0 +1 @@ +{ _id: 1, status: "a", lastModified: ISODate("2013-10-02T01:11:18.965Z") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/expected.json new file mode 100644 index 00000000000..a453bfb0051 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "status" : "D", "lastModified" : ISODate("2020-01-22T21:02:18.994Z"), "cancellation" : { "date" : Timestamp(1579726934, 2), "reason" : "user request" }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/name new file mode 100644 index 00000000000..bf6ee8f4ed2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/currentDate/example2/name @@ -0,0 +1 @@ +Aggregation Alternative to ``$currentDate`` \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/action.json new file mode 100644 index 00000000000..2f69ee2080f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/action.json @@ -0,0 +1,4 @@ +db.students.updateOne( + { _id: 1 }, + { $push: { scores: { $each: [ 90, 92, 85 ] } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/data.json new file mode 100644 index 00000000000..deb3f5361ea --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 44, 78, 38, 80 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/expected.json new file mode 100644 index 00000000000..9bbbaeee52c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 44, 78, 38, 80, 90, 92, 85 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example1/lock b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/lock new file mode 100644 index 00000000000..6edfb3f3f03 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/lock @@ -0,0 +1 @@ +example lacked expected data \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/name new file mode 100644 index 00000000000..8dd41fc0a5a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example1/name @@ -0,0 +1 @@ +Use ``$each`` with ``$push`` Operator \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/each/example2/action.json new file mode 100644 index 00000000000..058dd106bfb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example2/action.json @@ -0,0 +1,4 @@ +db.inventory.updateOne( + { _id: 2 }, + { $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } } + ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/each/example2/data.json new file mode 100644 index 00000000000..5abb0e50645 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example2/data.json @@ -0,0 +1 @@ +{ _id: 2, item: "cable", tags: [ "electronics", "supplies" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/each/example2/expected.json new file mode 100644 index 00000000000..344818db567 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example2/expected.json @@ -0,0 +1 @@ +{ _id: 2, item: "cable", tags: [ "electronics", "supplies", "camera", "accessories" ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/each/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/each/example2/name new file mode 100644 index 00000000000..c48f9ed03ea --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/each/example2/name @@ -0,0 +1 @@ +Use ``$each`` with ``$addToSet`` Operator \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/action.json new file mode 100644 index 00000000000..f46db70682b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/action.json @@ -0,0 +1,4 @@ +db.products.updateOne( + { sku: "abc123" }, + { $inc: { quantity: -2, "metrics.orders": 1 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/data.json new file mode 100644 index 00000000000..e5d1793a8eb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, sku: "abc123", quantity: 10, metrics: { orders: 2, ratings: 3.5 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/expected.json new file mode 100644 index 00000000000..b434b4af114 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, sku: 'abc123', quantity: 8, metrics: { orders: 3, ratings: 3.5 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/inc/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/max/example1/action.json new file mode 100644 index 00000000000..bf9ce73378d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example1/action.json @@ -0,0 +1 @@ +db.scores.updateOne( { _id: 1 }, { $max: { highScore: 950 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/max/example1/data.json new file mode 100644 index 00000000000..b0c74e4d4dc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, highScore: 800, lowScore: 200 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/max/example1/expected.json new file mode 100644 index 00000000000..38580f6f282 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, highScore: 950, lowScore: 200 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/max/example1/name new file mode 100644 index 00000000000..9183b14e909 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example1/name @@ -0,0 +1 @@ +Use ``$max`` to Compare Numbers \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/action.json new file mode 100644 index 00000000000..f409e83d8e9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/action.json @@ -0,0 +1,4 @@ +db.tags.updateOne( + { _id: 1 }, + { $max: { dateExpired: ISODate("2013-09-30") } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/data.json new file mode 100644 index 00000000000..4d32ac614d9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/data.json @@ -0,0 +1 @@ +{ _id: 1, desc: "crafts", dateEntered: ISODate("2013-10-01T05:00:00Z"), dateExpired: ISODate("2013-10-01T16:38:16.163Z") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/expected.json new file mode 100644 index 00000000000..4d32ac614d9 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/expected.json @@ -0,0 +1 @@ +{ _id: 1, desc: "crafts", dateEntered: ISODate("2013-10-01T05:00:00Z"), dateExpired: ISODate("2013-10-01T16:38:16.163Z") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example2/lock b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/lock new file mode 100644 index 00000000000..8789e014fa2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/lock @@ -0,0 +1 @@ +examples had a complete different doc in expected \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/max/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/name new file mode 100644 index 00000000000..08bb60601cd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/max/example2/name @@ -0,0 +1 @@ +Use ``$max`` to Compare Dates \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/min/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/min/example1/action.json new file mode 100644 index 00000000000..173f918db60 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/min/example1/action.json @@ -0,0 +1 @@ +db.scores.updateOne( { _id: 1 }, { $min: { lowScore: 150 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/min/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/min/example1/data.json new file mode 100644 index 00000000000..b0c74e4d4dc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/min/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, highScore: 800, lowScore: 200 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/min/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/min/example1/expected.json new file mode 100644 index 00000000000..bc4a90a54d8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/min/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, highScore: 800, lowScore: 150 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/min/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/min/example1/name new file mode 100644 index 00000000000..e8307c15200 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/min/example1/name @@ -0,0 +1 @@ +Use ``$min`` to Compare Numbers \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/min/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/min/example2/action.json new file mode 100644 index 00000000000..a82a7ab84a7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/min/example2/action.json @@ -0,0 +1,4 @@ +db.tags.updateOne( + { _id: 1 }, + { $min: { dateEntered: ISODate("2013-09-25") } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/min/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/min/example2/data.json new file mode 100644 index 00000000000..a7233fee1c7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/min/example2/data.json @@ -0,0 +1 @@ +{ _id: 1, desc: "crafts", dateEntered: ISODate("2013-10-01T05:00:00Z"), dateExpired: ISODate("2013-10-01T16:38:16Z") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/min/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/min/example2/expected.json new file mode 100644 index 00000000000..684c87c5ad6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/min/example2/expected.json @@ -0,0 +1 @@ +{ _id: 1, desc: "crafts", dateEntered: ISODate("2013-09-25T00:00:00Z"), dateExpired: ISODate("2013-10-01T16:38:16Z")} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/min/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/min/example2/name new file mode 100644 index 00000000000..95de5c8dfa5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/min/example2/name @@ -0,0 +1 @@ +Use ``$min`` to Compare Dates \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/action.json new file mode 100644 index 00000000000..b406f29632a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/action.json @@ -0,0 +1,9 @@ +db.products.updateOne( + { _id: 1 }, + { $mul: + { + price: 1.25, + quantity: 2 + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/data.json new file mode 100644 index 00000000000..235b97d4e6b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/data.json @@ -0,0 +1 @@ +{ "_id" : 1, "item" : "Hats", "price" : NumberDecimal("10.99"), "quantity" : 25 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/expected.json new file mode 100644 index 00000000000..67f91ffcf0b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, item: 'Hats', price: NumberDecimal("13.7375"), quantity: 50 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/lock b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/lock new file mode 100644 index 00000000000..42e4a953dcf --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/lock @@ -0,0 +1 @@ +sync the represenation of the double value with morphia's \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/name new file mode 100644 index 00000000000..3ad9c4352d8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example1/name @@ -0,0 +1 @@ +Multiply the Value of a Field \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/action.json new file mode 100644 index 00000000000..30ede106525 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/action.json @@ -0,0 +1,4 @@ +db.products.updateOne( + { _id: 2 }, + { $mul: { price: 100.0 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/data.json new file mode 100644 index 00000000000..4f94ed34a6e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/data.json @@ -0,0 +1 @@ +{ _id: 2, item: "Unknown" } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/expected.json new file mode 100644 index 00000000000..3b30f252c4c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/expected.json @@ -0,0 +1 @@ +{ "_id" : 2, "item" : "Unknown", "price" : NumberLong(0) } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/lock b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/lock new file mode 100644 index 00000000000..42e4a953dcf --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/lock @@ -0,0 +1 @@ +sync the represenation of the double value with morphia's \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/name new file mode 100644 index 00000000000..3de91a96265 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example2/name @@ -0,0 +1 @@ +Apply ``$mul`` Operator to a Non-existing Field \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/action.json new file mode 100644 index 00000000000..19dd3843581 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/action.json @@ -0,0 +1,4 @@ +db.products.updateOne( + { _id: 3 }, + { $mul: { price: NumberInt(5) } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/data.json new file mode 100644 index 00000000000..0cb18aff0b2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/data.json @@ -0,0 +1 @@ +{ _id: 3, item: "Scarf", price: NumberDecimal("10") } diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/expected.json new file mode 100644 index 00000000000..a9f8b11f638 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/expected.json @@ -0,0 +1 @@ +{ _id: 3, item: 'Scarf', price: NumberDecimal("50") } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/lock b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/lock new file mode 100644 index 00000000000..49c38f98969 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/lock @@ -0,0 +1 @@ +parser extracts incorrectly \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/name new file mode 100644 index 00000000000..8ffc6cf31d6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/mul/example3/name @@ -0,0 +1 @@ +Multiply Mixed Numeric Types \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/action.json new file mode 100644 index 00000000000..3924f9e3a47 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/action.json @@ -0,0 +1 @@ +db.students.updateOne( { _id: 1 }, { $pop: { scores: -1 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/data.json new file mode 100644 index 00000000000..5e6cebbce92 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 8, 9, 10 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/expected.json new file mode 100644 index 00000000000..2142b794517 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 9, 10 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/name new file mode 100644 index 00000000000..35e4721b9a6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pop/example1/name @@ -0,0 +1 @@ +Remove the First Item of an Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/action.json new file mode 100644 index 00000000000..4aab62b7ecc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/action.json @@ -0,0 +1 @@ +db.students.updateOne( { _id: 10 }, { $pop: { scores: 1 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/data.json new file mode 100644 index 00000000000..c3b8b3bff17 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/data.json @@ -0,0 +1 @@ +{ _id: 10, scores: [ 9, 10 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/expected.json new file mode 100644 index 00000000000..43580d4bb02 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/expected.json @@ -0,0 +1 @@ +{ _id: 10, scores: [ 9 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/name new file mode 100644 index 00000000000..90d7c705b6d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pop/example2/name @@ -0,0 +1 @@ +Remove the Last Item of an Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example1/action.json new file mode 100644 index 00000000000..89acd6ff462 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example1/action.json @@ -0,0 +1,11 @@ +db.students.updateOne( + { _id: 1 }, + { + $push: { + scores: { + $each: [ 50, 60, 70 ], + $position: 0 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example1/data.json new file mode 100644 index 00000000000..48baa7d757c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example1/data.json @@ -0,0 +1 @@ +{ "_id" : 1, "scores" : [ 100 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example1/expected.json new file mode 100644 index 00000000000..565b1c4d446 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example1/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "scores" : [ 50, 60, 70, 100 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/position/example1/name new file mode 100644 index 00000000000..98240e43a18 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example1/name @@ -0,0 +1 @@ +Add Elements at the Start of the Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example2/action.json new file mode 100644 index 00000000000..4d16b0e7fe1 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example2/action.json @@ -0,0 +1,11 @@ +db.students.updateOne( + { _id: 2 }, + { + $push: { + scores: { + $each: [ 20, 30 ], + $position: 2 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example2/data.json new file mode 100644 index 00000000000..54fe53ee624 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example2/data.json @@ -0,0 +1 @@ +{ "_id" : 2, "scores" : [ 50, 60, 70, 100 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example2/expected.json new file mode 100644 index 00000000000..fdb62f8a006 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example2/expected.json @@ -0,0 +1 @@ +{ "_id" : 2, "scores" : [ 50, 60, 20, 30, 70, 100 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/position/example2/name new file mode 100644 index 00000000000..664d162be71 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example2/name @@ -0,0 +1 @@ +Add Elements to the Middle of the Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example3/action.json new file mode 100644 index 00000000000..577dc3e5e85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example3/action.json @@ -0,0 +1,11 @@ +db.students.updateOne( + { _id: 3 }, + { + $push: { + scores: { + $each: [ 90, 80 ], + $position: -2 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example3/data.json new file mode 100644 index 00000000000..2c7c89148ad --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example3/data.json @@ -0,0 +1 @@ +{ "_id" : 3, "scores" : [ 50, 60, 20, 30, 70, 100 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/position/example3/expected.json new file mode 100644 index 00000000000..2c85d50d0d0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example3/expected.json @@ -0,0 +1 @@ +{ "_id" : 3, "scores" : [ 50, 60, 20, 30, 90, 80, 70, 100 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/position/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/position/example3/name new file mode 100644 index 00000000000..4e86ec91923 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/position/example3/name @@ -0,0 +1 @@ +Use a Negative Array Index (Position) to Add Elements to the Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/action.json new file mode 100644 index 00000000000..57879569161 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/action.json @@ -0,0 +1,4 @@ +db.students.updateOne( + { _id: 1, grades: 80 }, + { $set: { "grades.$" : 82 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/data.json new file mode 100644 index 00000000000..cd23899e8dd --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/data.json @@ -0,0 +1,3 @@ +{ "_id" : 1, "grades" : [ 85, 80, 80 ] }, +{ "_id" : 2, "grades" : [ 88, 90, 92 ] }, +{ "_id" : 3, "grades" : [ 85, 100, 90 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/expected.json new file mode 100644 index 00000000000..d77321eaaee --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/expected.json @@ -0,0 +1,3 @@ +{ "_id" : 1, "grades" : [ 85, 82, 80 ] } +{ "_id" : 2, "grades" : [ 88, 90, 92 ] } +{ "_id" : 3, "grades" : [ 85, 100, 90 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/name new file mode 100644 index 00000000000..3f60467ad22 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example1/name @@ -0,0 +1 @@ +Update Values in an Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/action.json new file mode 100644 index 00000000000..54234d74b5f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/action.json @@ -0,0 +1,4 @@ +db.students.updateOne( +{ _id: 4, "grades.grade": 85 }, +{ $set: { "grades.$.std" : 6 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/data.json new file mode 100644 index 00000000000..2b7654493a7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/data.json @@ -0,0 +1 @@ +{_id: 4, grades: [{ grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 85, mean: 85, std: 8 }]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/expected.json new file mode 100644 index 00000000000..8bca9858dc7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/expected.json @@ -0,0 +1 @@ +{"_id" : 4, "grades" : [{ "grade" : 80, "mean" : 75, "std" : 8 }, { "grade" : 85, "mean" : 90, "std" : 6 }, { "grade" : 85, "mean" : 85, "std" : 8 }]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/lock b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/lock new file mode 100644 index 00000000000..46ed5df7262 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/lock @@ -0,0 +1 @@ +the example had exposition before the actual example \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/name new file mode 100644 index 00000000000..a40bd4ab744 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example2/name @@ -0,0 +1 @@ +Update Documents in an Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/action.json new file mode 100644 index 00000000000..1852ab72e98 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/action.json @@ -0,0 +1,7 @@ +db.students.updateOne( + { + _id: 5, + grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } } + }, + { $set: { "grades.$.std" : 6 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/data.json new file mode 100644 index 00000000000..19979dad2f4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/data.json @@ -0,0 +1 @@ +{ _id: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/expected.json new file mode 100644 index 00000000000..9b18c513c82 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/expected.json @@ -0,0 +1 @@ +{ _id: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 6 }, { grade: 90, mean: 85, std: 3 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/name new file mode 100644 index 00000000000..b3884091b1b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example3/name @@ -0,0 +1 @@ +Update Embedded Documents Using Multiple Field Matches \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/action.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/action.json new file mode 100644 index 00000000000..86c243a9a92 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/action.json @@ -0,0 +1,4 @@ +db.students_deans_list.updateOne( + { activity_ids: 1, grades: 95, deans_list: 2021 }, + { $set: { "deans_list.$": 2022 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/data.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/data.json new file mode 100644 index 00000000000..ab6db9011aa --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/data.json @@ -0,0 +1 @@ +{ _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2020 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/expected.json new file mode 100644 index 00000000000..ecee564c21d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/expected.json @@ -0,0 +1 @@ +{ _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2022 ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/name b/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/name new file mode 100644 index 00000000000..3c9c75a96de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example4/name @@ -0,0 +1 @@ +Update with Multiple Array Matches \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/action.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/action.json new file mode 100644 index 00000000000..b05726f371d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/action.json @@ -0,0 +1,5 @@ +db.students4.updateMany( + {}, + { $inc: { "grades.$[t].questions.$[score]": 2 } }, + { arrayFilters: [ { "t.type": "quiz" }, { "score": { $gte: 8 } } ] } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/data.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/data.json new file mode 100644 index 00000000000..c80d72ba076 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/data.json @@ -0,0 +1 @@ +{ "_id" : 1, "grades" : [ { type: "quiz", questions: [ 10, 8, 5 ] }, { type: "quiz", questions: [ 8, 9, 6 ] }, { type: "hw", questions: [ 5, 4, 3 ] }, { type: "exam", questions: [ 25, 10, 23, 0 ] }, ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/expected.json new file mode 100644 index 00000000000..423802c66ad --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "grades" : [ { "type" : "quiz", "questions" : [ 12, 10, 5 ] }, { "type" : "quiz", "questions" : [ 10, 11, 6 ] }, { "type" : "hw", "questions" : [ 5, 4, 3 ] }, { "type" : "exam", "questions" : [ 25, 10, 23, 0 ] } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/name b/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/name new file mode 100644 index 00000000000..572423e18c4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/positional/example5/name @@ -0,0 +1 @@ +Update Nested Arrays in Conjunction with ``$[]`` \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/action.json new file mode 100644 index 00000000000..c19329f8846 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/action.json @@ -0,0 +1,4 @@ +db.stores.updateMany( + { }, + { $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/data.json new file mode 100644 index 00000000000..09894b56207 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/data.json @@ -0,0 +1,2 @@ +{ _id: 1, fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ], vegetables: [ "carrots", "celery", "squash", "carrots" ] }, +{ _id: 2, fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ], vegetables: [ "broccoli", "zucchini", "carrots", "onions" ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/expected.json new file mode 100644 index 00000000000..7eb09556a5b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/expected.json @@ -0,0 +1,2 @@ +{ _id: 1, fruits: [ 'pears', 'grapes', 'bananas' ], vegetables: [ 'celery', 'squash' ]}, +{ _id: 2, fruits: [ 'plums', 'kiwis', 'bananas' ], vegetables: [ 'broccoli', 'zucchini', 'onions' ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/name new file mode 100644 index 00000000000..4af3bf3ab04 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example1/name @@ -0,0 +1 @@ +Remove All Items That Equal a Specified Value \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/action.json new file mode 100644 index 00000000000..dd75f36824c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/action.json @@ -0,0 +1 @@ +db.profiles.updateOne( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/data.json new file mode 100644 index 00000000000..bc8bb5f4fab --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/data.json @@ -0,0 +1 @@ +{ _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/expected.json new file mode 100644 index 00000000000..453a59f74ad --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/expected.json @@ -0,0 +1 @@ +{ _id: 1, votes: [ 3, 5 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/name new file mode 100644 index 00000000000..86e987a1591 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example2/name @@ -0,0 +1 @@ +Remove All Items That Match a Specified ``$pull`` Condition \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/action.json new file mode 100644 index 00000000000..75ae8cb2b94 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/action.json @@ -0,0 +1 @@ +db.profilesBulkWrite.find() \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/data.json new file mode 100644 index 00000000000..38d131a2190 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/data.json @@ -0,0 +1 @@ +try { db.profilesBulkWrite.bulkWrite( [ { insertOne: { "document": { _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] } } }, { updateOne: { "filter": { _id: 1 }, "update": { $pull: { votes: { $gte: 6 } } } } }, { updateOne: { "filter": {_id: 1}, "update": { $pull: { votes: { $lte: 3 } } } } } ] );} catch (e) { print(e);} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/expected.json new file mode 100644 index 00000000000..13279a2f7e1 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/expected.json @@ -0,0 +1 @@ +[ { _id: 1, votes: [ 5 ] } ] \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/name new file mode 100644 index 00000000000..14f201ca491 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example3/name @@ -0,0 +1 @@ +Remove All Items That Match a Specified ``$pull`` Condition With :method:`~db.collection.bulkWrite()` \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/action.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/action.json new file mode 100644 index 00000000000..850897b7cd3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/action.json @@ -0,0 +1,4 @@ +db.survey.updateMany( + { }, + { $pull: { results: { score: 8 , item: "B" } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/data.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/data.json new file mode 100644 index 00000000000..09d600629cb --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/data.json @@ -0,0 +1,2 @@ +{ _id: 1, results: [ { item: "A", score: 5 }, { item: "B", score: 8 } ] }, +{ _id: 2, results: [ { item: "C", score: 8 }, { item: "B", score: 4 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/expected.json new file mode 100644 index 00000000000..e737b7e09bc --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/expected.json @@ -0,0 +1,2 @@ +{ _id: 1, results: [ { item: 'A', score: 5 } ] }, +{ _id: 2, results: [ { item: 'C', score: 8 }, { item: 'B', score: 4 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/name b/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/name new file mode 100644 index 00000000000..add3e3446c6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example4/name @@ -0,0 +1 @@ +Remove Items from an Array of Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/action.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/action.json new file mode 100644 index 00000000000..6adad4a1555 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/action.json @@ -0,0 +1,12 @@ +db.survey.updateMany( + { }, + { + $pull: + { + results: + { + answers: { $elemMatch: { q: 2, a: { $gte: 8 } } } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/data.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/data.json new file mode 100644 index 00000000000..e8eb8657641 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/data.json @@ -0,0 +1,2 @@ +{ _id: 1, results: [ { item: "A", score: 5, answers: [ { q: 1, a: 4 }, { q: 2, a: 6 } ] }, { item: "B", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 9 } ] } ] }, +{ _id: 2, results: [ { item: "C", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 7 } ] }, { item: "B", score: 4, answers: [ { q: 1, a: 0 }, { q: 2, a: 8 } ] } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/expected.json new file mode 100644 index 00000000000..6765e4c9d3c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/expected.json @@ -0,0 +1,2 @@ +{ _id: 1, results: [ { item: 'A', score: 5, answers: [ { q: 1, a: 4 }, { q: 2, a: 6 } ] } ]}, +{ _id: 2, results: [ { item: 'C', score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 7 } ] } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/lock b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/lock new file mode 100644 index 00000000000..7377b162e40 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/lock @@ -0,0 +1 @@ +data had a drop() command in it \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/name b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/name new file mode 100644 index 00000000000..56a4d20e591 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pull/example5/name @@ -0,0 +1 @@ +Remove Documents from Nested Arrays \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/action.json new file mode 100644 index 00000000000..dfafaabbf92 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/action.json @@ -0,0 +1 @@ +db.survey.updateOne( { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/data.json new file mode 100644 index 00000000000..b41e62af548 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 0, 2, 5, 5, 1, 0 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/expected.json new file mode 100644 index 00000000000..e83df555c8d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "scores" : [ 2, 1 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/pullAll/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example1/action.json new file mode 100644 index 00000000000..97f018b41f3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example1/action.json @@ -0,0 +1,4 @@ +db.students.updateOne( + { _id: 1 }, + { $push: { scores: 89 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example1/data.json new file mode 100644 index 00000000000..deb3f5361ea --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example1/data.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 44, 78, 38, 80 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example1/expected.json new file mode 100644 index 00000000000..fe9ae687a8d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example1/expected.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 44, 78, 38, 80, 89 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/push/example1/name new file mode 100644 index 00000000000..3c4f4fac912 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example1/name @@ -0,0 +1 @@ +Append a Value to an Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/action.json new file mode 100644 index 00000000000..94828e107a4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/action.json @@ -0,0 +1,4 @@ +db.students.updateMany( + { }, + { $push: { scores: 95 } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/data.json new file mode 100644 index 00000000000..58daf4c2566 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/data.json @@ -0,0 +1,4 @@ +{ _id: 1, scores: [ 44, 78, 38, 80, 89 ] }, +{ _id: 2, scores: [ 45, 78, 38, 80, 89 ] } , +{ _id: 3, scores: [ 46, 78, 38, 80, 89 ] } , +{ _id: 4, scores: [ 47, 78, 38, 80, 89 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/expected.json new file mode 100644 index 00000000000..597c04efeb0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/expected.json @@ -0,0 +1,4 @@ +{ _id: 1, scores: [ 44, 78, 38, 80, 89, 95 ] }, +{ _id: 2, scores: [ 45, 78, 38, 80, 89, 95 ] }, +{ _id: 3, scores: [ 46, 78, 38, 80, 89, 95 ] }, +{ _id: 4, scores: [ 47, 78, 38, 80, 89, 95 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example2/lock b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/lock new file mode 100644 index 00000000000..a53c07f8fc1 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/lock @@ -0,0 +1 @@ +input data was missing a row \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/name new file mode 100644 index 00000000000..1add395df08 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example2/name @@ -0,0 +1 @@ +Append a Value to Arrays in Multiple Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/action.json new file mode 100644 index 00000000000..2f69ee2080f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/action.json @@ -0,0 +1,4 @@ +db.students.updateOne( + { _id: 1 }, + { $push: { scores: { $each: [ 90, 92, 85 ] } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/data.json new file mode 100644 index 00000000000..deb3f5361ea --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/data.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 44, 78, 38, 80 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/expected.json new file mode 100644 index 00000000000..9bbbaeee52c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/expected.json @@ -0,0 +1 @@ +{ _id: 1, scores: [ 44, 78, 38, 80, 90, 92, 85 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example3/lock b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/lock new file mode 100644 index 00000000000..6edfb3f3f03 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/lock @@ -0,0 +1 @@ +example lacked expected data \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/name new file mode 100644 index 00000000000..26fba28233b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example3/name @@ -0,0 +1 @@ +Append Multiple Values to an Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example4/action.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example4/action.json new file mode 100644 index 00000000000..4915ef36776 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example4/action.json @@ -0,0 +1,12 @@ +db.students.updateOne( + { _id: 5 }, + { + $push: { + quizzes: { + $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ], + $sort: { score: -1 }, + $slice: 3 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example4/data.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example4/data.json new file mode 100644 index 00000000000..2931697610b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example4/data.json @@ -0,0 +1 @@ +{ "_id" : 5, "quizzes" : [ { "wk": 1, "score" : 10 }, { "wk": 2, "score" : 8 }, { "wk": 3, "score" : 5 }, { "wk": 4, "score" : 6 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/push/example4/expected.json new file mode 100644 index 00000000000..68075fe3dce --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example4/expected.json @@ -0,0 +1 @@ +{ "_id" : 5, "quizzes" : [ { "wk" : 1, "score" : 10 }, { "wk" : 2, "score" : 8 }, { "wk" : 5, "score" : 8 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/push/example4/name b/core/src/test/resources/dev/morphia/test/query/updates/push/example4/name new file mode 100644 index 00000000000..8d4e02d9a5e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/push/example4/name @@ -0,0 +1 @@ +Use ``$push`` Operator with Multiple Modifiers \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/action.json new file mode 100644 index 00000000000..d95570d18b6 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/action.json @@ -0,0 +1,4 @@ +db.students.updateMany( + { "nmae": { $ne: null } }, + { $rename: { "nmae": "name" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/data.json new file mode 100644 index 00000000000..826d783b938 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/data.json @@ -0,0 +1,3 @@ +{ "_id": 1, "alias": [ "The American Cincinnatus", "The American Fabius" ], "mobile": "555-555-5555", "nmae": { "first" : "george", "last" : "washington" } }, +{ "_id": 2, "alias": [ "My dearest friend" ], "mobile": "222-222-2222", "nmae": { "first" : "abigail", "last" : "adams" } }, +{ "_id": 3, "alias": [ "Amazing grace" ], "mobile": "111-111-1111", "nmae": { "first" : "grace", "last" : "hopper" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/expected.json new file mode 100644 index 00000000000..e8ee6ec99a5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/expected.json @@ -0,0 +1,3 @@ +{ "_id": 1, "alias": [ "The American Cincinnatus", "The American Fabius" ], "mobile": "555-555-5555", "name": { "first" : "george", "last" : "washington" }} +{ "_id" : 2, "alias" : [ "My dearest friend" ], "mobile" : "222-222-2222", "name" : { "first" : "abigail", "last" : "adams" }} +{ "_id" : 3, "alias" : [ "Amazing grace" ], "mobile" : "111-111-1111", "name" : { "first" : "grace", "last" : "hopper" }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/name new file mode 100644 index 00000000000..5eeff21a516 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example1/name @@ -0,0 +1 @@ +Rename a Field \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/action.json new file mode 100644 index 00000000000..034b1dbaa54 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/action.json @@ -0,0 +1 @@ +db.students.updateOne( { _id: 1 }, { $rename: { "name.first": "name.fname" } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/data.json new file mode 100644 index 00000000000..5521715019c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/data.json @@ -0,0 +1,3 @@ +{ "_id": 1, "alias": [ "The American Cincinnatus", "The American Fabius" ], "mobile": "555-555-5555", "name": { "first" : "george", "last" : "washington" } }, +{ "_id": 2, "alias": [ "My dearest friend" ], "mobile": "222-222-2222", "name": { "first" : "abigail", "last" : "adams" } }, +{ "_id": 3, "alias": [ "Amazing grace" ], "mobile": "111-111-1111", "name": { "first" : "grace", "last" : "hopper" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/expected.json new file mode 100644 index 00000000000..34875bd59ed --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/expected.json @@ -0,0 +1 @@ +{ _id: 1, alias: [ 'The American Cincinnatus', 'The American Fabius' ], mobile: '555-555-5555', name: { last: 'washington', fname: 'george' }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/lock b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/lock new file mode 100644 index 00000000000..84e12164d0f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/lock @@ -0,0 +1 @@ +the input data had the same misspelling of name from the first example \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/name new file mode 100644 index 00000000000..140cb8dd7e4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example2/name @@ -0,0 +1 @@ +Rename a Field in an Embedded Document \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/action.json new file mode 100644 index 00000000000..caf386f611c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/action.json @@ -0,0 +1 @@ +db.students.updateOne( { _id: 1 }, { $rename: { 'wife': 'spouse' } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/data.json new file mode 100644 index 00000000000..5521715019c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/data.json @@ -0,0 +1,3 @@ +{ "_id": 1, "alias": [ "The American Cincinnatus", "The American Fabius" ], "mobile": "555-555-5555", "name": { "first" : "george", "last" : "washington" } }, +{ "_id": 2, "alias": [ "My dearest friend" ], "mobile": "222-222-2222", "name": { "first" : "abigail", "last" : "adams" } }, +{ "_id": 3, "alias": [ "Amazing grace" ], "mobile": "111-111-1111", "name": { "first" : "grace", "last" : "hopper" } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/expected.json new file mode 100644 index 00000000000..d54b63e6fce --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/expected.json @@ -0,0 +1 @@ +{ "_id": 1, "alias": [ "The American Cincinnatus", "The American Fabius" ], "mobile": "555-555-5555", "name": { "first" : "george", "last" : "washington" } }, diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/lock b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/lock new file mode 100644 index 00000000000..cd26a60b4ee --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/lock @@ -0,0 +1,2 @@ +the input data had the same misspelling of name from the first example +no expected data in the docs \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/name new file mode 100644 index 00000000000..57535b748a7 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/rename/example3/name @@ -0,0 +1 @@ +Rename a Field That Does Not Exist \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example1/action.json new file mode 100644 index 00000000000..8dd2bb20c60 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example1/action.json @@ -0,0 +1,10 @@ +db.products.updateOne( + { _id: 100 }, + { $set: + { + quantity: 500, + details: { model: "2600", make: "Fashionaires" }, + tags: [ "coats", "outerwear", "clothing" ] + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example1/data.json new file mode 100644 index 00000000000..b2e02591d20 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example1/data.json @@ -0,0 +1 @@ +{ _id: 100, quantity: 250, instock: true, reorder: false, details: { model: "14QQ", make: "Clothes Corp" }, tags: [ "apparel", "clothing" ], ratings: [ { by: "Customer007", rating: 4 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example1/expected.json new file mode 100644 index 00000000000..cf95ebd78a2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example1/expected.json @@ -0,0 +1 @@ +{ _id: 100, quantity: 500, instock: true, reorder: false, details: { model: '2600', make: 'Fashionaires' }, tags: [ 'coats', 'outerwear', 'clothing' ], ratings: [ { by: 'Customer007', rating: 4 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/set/example1/name new file mode 100644 index 00000000000..ecbd09128a4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example1/name @@ -0,0 +1 @@ +Set Top-Level Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/action.json new file mode 100644 index 00000000000..f4e7dc67379 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/action.json @@ -0,0 +1,4 @@ +db.products.updateOne( + { _id: 100 }, + { $set: { "details.make": "Kustom Kidz" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/data.json new file mode 100644 index 00000000000..b2e02591d20 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/data.json @@ -0,0 +1 @@ +{ _id: 100, quantity: 250, instock: true, reorder: false, details: { model: "14QQ", make: "Clothes Corp" }, tags: [ "apparel", "clothing" ], ratings: [ { by: "Customer007", rating: 4 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/expected.json new file mode 100644 index 00000000000..83eb9fb69fe --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/expected.json @@ -0,0 +1 @@ +{ _id: 100, quantity: 250, instock: true, reorder: false, details: { model: "14QQ", make: "Kustom Kidz" }, tags: [ "apparel", "clothing" ], ratings: [ { by: "Customer007", rating: 4 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example2/lock b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/lock new file mode 100644 index 00000000000..8378b8f5a59 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/lock @@ -0,0 +1,2 @@ +expected data didn't match input data where it wasn't modified by the update +the example assumes the updates from the previous example still exist \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/name new file mode 100644 index 00000000000..9ff2cddea00 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example2/name @@ -0,0 +1 @@ +Set Fields in Embedded Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/action.json new file mode 100644 index 00000000000..8752764b4fe --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/action.json @@ -0,0 +1,9 @@ +db.products.updateOne( + { _id: 100 }, + { $set: + { + "tags.1": "rain gear", + "ratings.0.rating": 2 + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/data.json new file mode 100644 index 00000000000..b2e02591d20 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/data.json @@ -0,0 +1 @@ +{ _id: 100, quantity: 250, instock: true, reorder: false, details: { model: "14QQ", make: "Clothes Corp" }, tags: [ "apparel", "clothing" ], ratings: [ { by: "Customer007", rating: 4 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/expected.json new file mode 100644 index 00000000000..77cb175ef93 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/expected.json @@ -0,0 +1 @@ +{ _id: 100, quantity: 250, instock: true, reorder: false, details: { model: "14QQ", make: "Clothes Corp" }, tags: [ "apparel", "rain gear" ], ratings: [ { by: "Customer007", rating: 2 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example3/lock b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/lock new file mode 100644 index 00000000000..8378b8f5a59 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/lock @@ -0,0 +1,2 @@ +expected data didn't match input data where it wasn't modified by the update +the example assumes the updates from the previous example still exist \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/set/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/name new file mode 100644 index 00000000000..8b0f24c5c6d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/set/example3/name @@ -0,0 +1 @@ +Set Elements in Arrays \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/action.json new file mode 100644 index 00000000000..43a393d2bf8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/action.json @@ -0,0 +1,8 @@ +db.products.updateOne( + { _id: 1 }, + { + $set: { item: "apple" }, + $setOnInsert: { defaultQty: 100 } + }, + { upsert: true } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/expected.json new file mode 100644 index 00000000000..d3e0a4db1d3 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "item" : "apple", "defaultQty" : 100 } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/setOnInsert/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/action.json new file mode 100644 index 00000000000..45d004442ac --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/action.json @@ -0,0 +1,11 @@ +db.students.updateOne( + { _id: 1 }, + { + $push: { + scores: { + $each: [ 80, 78, 86 ], + $slice: -5 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/data.json new file mode 100644 index 00000000000..684a9de8e74 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/data.json @@ -0,0 +1 @@ +{ "_id" : 1, "scores" : [ 40, 50, 60 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/expected.json new file mode 100644 index 00000000000..2199e40ad26 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "scores" : [ 50, 60, 80, 78, 86 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/name new file mode 100644 index 00000000000..96bdd645c33 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example1/name @@ -0,0 +1 @@ +Slice from the End of the Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/action.json new file mode 100644 index 00000000000..3be54ae7e90 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/action.json @@ -0,0 +1,11 @@ +db.students.updateOne( + { _id: 2 }, + { + $push: { + scores: { + $each: [ 100, 20 ], + $slice: 3 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/data.json new file mode 100644 index 00000000000..75462d33dec --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/data.json @@ -0,0 +1 @@ +{ "_id" : 2, "scores" : [ 89, 90 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/expected.json new file mode 100644 index 00000000000..116f905af7b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/expected.json @@ -0,0 +1 @@ +{ "_id" : 2, "scores" : [ 89, 90, 100 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/name new file mode 100644 index 00000000000..fa8f3ba8740 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example2/name @@ -0,0 +1 @@ +Slice from the Front of the Array \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/action.json new file mode 100644 index 00000000000..f20cf1415f1 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/action.json @@ -0,0 +1,11 @@ +db.students.updateOne( + { _id: 3 }, + { + $push: { + scores: { + $each: [ ], + $slice: -3 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/data.json new file mode 100644 index 00000000000..0a895aceec0 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/data.json @@ -0,0 +1 @@ +{ "_id" : 3, "scores" : [ 89, 70, 100, 20 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/expected.json new file mode 100644 index 00000000000..3c135766520 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/expected.json @@ -0,0 +1 @@ +{ "_id" : 3, "scores" : [ 70, 100, 20 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/name new file mode 100644 index 00000000000..f7d1f365c5e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example3/name @@ -0,0 +1 @@ +Update Array Using Slice Only \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/action.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/action.json new file mode 100644 index 00000000000..4915ef36776 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/action.json @@ -0,0 +1,12 @@ +db.students.updateOne( + { _id: 5 }, + { + $push: { + quizzes: { + $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ], + $sort: { score: -1 }, + $slice: 3 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/data.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/data.json new file mode 100644 index 00000000000..2931697610b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/data.json @@ -0,0 +1 @@ +{ "_id" : 5, "quizzes" : [ { "wk": 1, "score" : 10 }, { "wk": 2, "score" : 8 }, { "wk": 3, "score" : 5 }, { "wk": 4, "score" : 6 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/expected.json new file mode 100644 index 00000000000..68075fe3dce --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/expected.json @@ -0,0 +1 @@ +{ "_id" : 5, "quizzes" : [ { "wk" : 1, "score" : 10 }, { "wk" : 2, "score" : 8 }, { "wk" : 5, "score" : 8 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/name b/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/name new file mode 100644 index 00000000000..fe8535fb830 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/slice/example4/name @@ -0,0 +1 @@ +Use ``$slice`` with Other ``$push`` Modifiers \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/action.json new file mode 100644 index 00000000000..0b52f335c1f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/action.json @@ -0,0 +1,11 @@ +db.students.updateOne( + { _id: 1 }, + { + $push: { + quizzes: { + $each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ], + $sort: { score: 1 } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/data.json new file mode 100644 index 00000000000..df0a0eedc93 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/data.json @@ -0,0 +1 @@ +{ "_id": 1, "quizzes": [ { "id" : 1, "score" : 6 }, { "id" : 2, "score" : 9 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/expected.json new file mode 100644 index 00000000000..4a936466eec --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/expected.json @@ -0,0 +1 @@ +{ "_id" : 1, "quizzes" : [ { "id" : 1, "score" : 6 }, { "id" : 5, "score" : 6 }, { "id" : 4, "score" : 7 }, { "id" : 3, "score" : 8 }, { "id" : 2, "score" : 9 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/name new file mode 100644 index 00000000000..d8f3feb8ec5 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example1/name @@ -0,0 +1 @@ +Sort Array of Documents by a Field in the Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/action.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/action.json new file mode 100644 index 00000000000..59c0bcf4dc4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/action.json @@ -0,0 +1,4 @@ +db.students.updateOne( + { _id: 2 }, + { $push: { tests: { $each: [ 40, 60 ], $sort: 1 } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/data.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/data.json new file mode 100644 index 00000000000..c2b9071faec --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/data.json @@ -0,0 +1 @@ +{ "_id" : 2, "tests" : [ 89, 70, 89, 50 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/expected.json new file mode 100644 index 00000000000..b9be6be6ca4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/expected.json @@ -0,0 +1 @@ +{ "_id" : 2, "tests" : [ 40, 50, 60, 70, 89, 89 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/name b/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/name new file mode 100644 index 00000000000..676d5b3332c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example2/name @@ -0,0 +1 @@ +Sort Array Elements That Are Not Documents \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/action.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/action.json new file mode 100644 index 00000000000..16b2e9fe235 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/action.json @@ -0,0 +1,4 @@ +db.students.updateOne( + { _id: 3 }, + { $push: { tests: { $each: [ ], $sort: -1 } } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/data.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/data.json new file mode 100644 index 00000000000..746c005047f --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/data.json @@ -0,0 +1 @@ +{ "_id" : 3, "tests" : [ 89, 70, 100, 20 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/expected.json new file mode 100644 index 00000000000..a0e8bd8af12 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/expected.json @@ -0,0 +1 @@ +{ "_id" : 3, "tests" : [ 100, 89, 70, 20 ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/name b/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/name new file mode 100644 index 00000000000..f41d06095ac --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example3/name @@ -0,0 +1 @@ +Update Array Using Sort Only \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/action.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/action.json new file mode 100644 index 00000000000..4915ef36776 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/action.json @@ -0,0 +1,12 @@ +db.students.updateOne( + { _id: 5 }, + { + $push: { + quizzes: { + $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ], + $sort: { score: -1 }, + $slice: 3 + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/data.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/data.json new file mode 100644 index 00000000000..2931697610b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/data.json @@ -0,0 +1 @@ +{ "_id" : 5, "quizzes" : [ { "wk": 1, "score" : 10 }, { "wk": 2, "score" : 8 }, { "wk": 3, "score" : 5 }, { "wk": 4, "score" : 6 } ] } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/expected.json new file mode 100644 index 00000000000..68075fe3dce --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/expected.json @@ -0,0 +1 @@ +{ "_id" : 5, "quizzes" : [ { "wk" : 1, "score" : 10 }, { "wk" : 2, "score" : 8 }, { "wk" : 5, "score" : 8 } ]} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/name b/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/name new file mode 100644 index 00000000000..117f50fc6f8 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/sort/example4/name @@ -0,0 +1 @@ +Use ``$sort`` with Other ``$push`` Modifiers \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/action.json b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/action.json new file mode 100644 index 00000000000..53f3c1453c2 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/action.json @@ -0,0 +1,4 @@ +db.products.updateOne( + { sku: "unknown" }, + { $unset: { quantity: "", instock: "" } } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/data.json b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/data.json new file mode 100644 index 00000000000..51b554cc2c4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/data.json @@ -0,0 +1,3 @@ +{ "item": "chisel", "sku": "C001", "quantity": 4, "instock": true }, +{ "item": "hammer", "sku": "unknown", "quantity": 3, "instock": true }, +{ "item": "nails", "sku": "unknown", "quantity": 100, "instock": true } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/expected.json new file mode 100644 index 00000000000..77b96d15d8c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/expected.json @@ -0,0 +1,2 @@ +{ item: "hammer", sku: "unknown"}, +{ item: "nails", sku: "unknown", quantity: 100, instock: true} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/lock b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/lock new file mode 100644 index 00000000000..c0d48ad988a --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/lock @@ -0,0 +1 @@ +updated expected to only contain documents matched by the query \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/name b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/updates/unset/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/transactions/aggregation/pipeline.json b/core/src/test/resources/dev/morphia/test/transactions/aggregation/action.json similarity index 100% rename from core/src/test/resources/dev/morphia/test/transactions/aggregation/pipeline.json rename to core/src/test/resources/dev/morphia/test/transactions/aggregation/action.json diff --git a/core/src/test/resources/dev/morphia/test/transactions/aggregation/name b/core/src/test/resources/dev/morphia/test/transactions/aggregation/name new file mode 100644 index 00000000000..c71324b7f9b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/transactions/aggregation/name @@ -0,0 +1 @@ +transactional aggregations \ No newline at end of file diff --git a/critter/core/pom.xml b/critter/core/pom.xml index b1b7608a2e6..008d85b2cd4 100644 --- a/critter/core/pom.xml +++ b/critter/core/pom.xml @@ -13,32 +13,39 @@ critter-core - - 2.29.0.Final - - dev.morphia.morphia morphia-core - io.github.dmlloyd - jdk-classfile-preview - 23.beta3 + dev.morphia.morphia + build-plugins + ${project.version} + compile - io.quarkus.gizmo - gizmo - 1.8.0 + com.squareup + javapoet + + + + org.ow2.asm + asm-tree + + + org.ow2.asm + asm-util org.jetbrains.kotlin kotlin-stdlib + ${kotlin.version} org.jetbrains.kotlin kotlin-reflect + ${kotlin.version} org.testng @@ -47,30 +54,49 @@ com.google.devtools.ksp symbol-processing-api - 2.0.0-1.0.21 + 2.0.21-1.0.25 com.google.devtools.ksp symbol-processing-common-deps - 2.0.0-1.0.21 + 2.0.21-1.0.25 com.google.devtools.ksp symbol-processing-aa-embeddable - 2.0.0-1.0.21 + 2.0.21-1.0.25 + + + org.jboss.forge.roaster + roaster-jdt + 2.29.0.Final + compile + + + io.quarkus.gizmo + gizmo + 1.8.0 + + + ch.qos.logback + logback-classic - org.apache.maven.plugins - maven-compiler-plugin - 3.13.0 - - - -proc:none - + ${project.groupId} + build-plugins + ${project.version} + + + morphia-annotations-asm + + morphia-annotation-node + + + diff --git a/critter/core/src/main/java/.hide b/critter/core/src/main/java/.hide new file mode 100644 index 00000000000..e69de29bb2d diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/Critter.kt b/critter/core/src/main/kotlin/dev/morphia/critter/Critter.kt index d4efff1e929..09212d4356a 100644 --- a/critter/core/src/main/kotlin/dev/morphia/critter/Critter.kt +++ b/critter/core/src/main/kotlin/dev/morphia/critter/Critter.kt @@ -1,16 +1,28 @@ package dev.morphia.critter -import com.google.devtools.ksp.impl.KotlinSymbolProcessing import com.google.devtools.ksp.processing.KSPConfig import com.google.devtools.ksp.processing.KSPJvmConfig.Builder -import com.google.devtools.ksp.processing.KspGradleLogger import dev.morphia.annotations.Entity -import dev.morphia.critter.parser.CritterProcessorProvider +import dev.morphia.annotations.Property +import dev.morphia.critter.parser.java.CritterClassLoader +import dev.morphia.mapping.codec.pojo.PropertyModel import java.io.File +import org.objectweb.asm.Type class Critter(val root: File) { + companion object { + var outputDirectory = File("target/generated-sources/morphia") + val critterClassLoader = CritterClassLoader(PropertyModel::class.java.classLoader) + val propertyAnnotations = mutableListOf(Type.getType(Property::class.java)) + val transientAnnotations = mutableListOf(Type.getType(Transient::class.java)) + + fun critterPackage(entity: Class<*>): String { + return "${entity.packageName}.__morphia.${entity.simpleName.lowercase()}" + } + } private val outputDir = File(root, "target") + private val ksp = File(outputDir, "ksp") fun build(): KSPConfig { @@ -27,16 +39,21 @@ class Critter(val root: File) { outputBaseDir = outputDir projectBaseDir = root resourceOutputDir = File(ksp, "resource-output") - sourceRoots = listOf(File(root, "src/test/kotlin")) + sourceRoots = listOf(File(root, "src/test/java"), File(root, "src/test/kotlin")) libraries = listOf(File(Entity::class.java.loadPath())) } return builder.build() } - fun process() { - KotlinSymbolProcessing(build(), listOf(CritterProcessorProvider()), KspGradleLogger(KspGradleLogger.LOGGING_LEVEL_WARN)).execute() - } + private fun Class.loadPath() = + getProtectionDomain().getCodeSource().getLocation().toURI() +} + +fun String.titleCase(): String { + return first().uppercase() + substring(1) +} - private fun Class.loadPath() = getProtectionDomain().getCodeSource().getLocation().toURI() -} \ No newline at end of file +fun String.identifierCase(): String { + return first().lowercase() + substring(1) +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/conventions/CritterConvention.kt b/critter/core/src/main/kotlin/dev/morphia/critter/conventions/CritterConvention.kt deleted file mode 100644 index ef8d2eaa06c..00000000000 --- a/critter/core/src/main/kotlin/dev/morphia/critter/conventions/CritterConvention.kt +++ /dev/null @@ -1,9 +0,0 @@ -package dev.morphia.critter.conventions - -import dev.morphia.mapping.Mapper -import io.github.dmlloyd.classfile.ClassBuilder -import io.github.dmlloyd.classfile.ClassModel - -interface CritterConvention { - fun apply(mapper: Mapper, builder: ClassBuilder, model: ClassModel) -} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/conventions/CritterDefaultsConvention.kt b/critter/core/src/main/kotlin/dev/morphia/critter/conventions/CritterDefaultsConvention.kt deleted file mode 100644 index ec551dbb466..00000000000 --- a/critter/core/src/main/kotlin/dev/morphia/critter/conventions/CritterDefaultsConvention.kt +++ /dev/null @@ -1,100 +0,0 @@ -@file:Suppress("UNCHECKED_CAST") - -package dev.morphia.critter.conventions - -import dev.morphia.annotations.Entity -import dev.morphia.annotations.ExternalEntity -import dev.morphia.annotations.internal.AnnotationFactory -import dev.morphia.annotations.internal.EntityBuilder -import dev.morphia.annotations.internal.MorphiaInternal -import dev.morphia.critter.parser.booleanMethod -import dev.morphia.critter.parser.stringMethod -import dev.morphia.mapping.Mapper -import dev.morphia.mapping.MappingException -import io.github.dmlloyd.classfile.AnnotationValue.OfBoolean -import io.github.dmlloyd.classfile.AnnotationValue.OfByte -import io.github.dmlloyd.classfile.AnnotationValue.OfCharacter -import io.github.dmlloyd.classfile.AnnotationValue.OfDouble -import io.github.dmlloyd.classfile.AnnotationValue.OfFloat -import io.github.dmlloyd.classfile.AnnotationValue.OfInteger -import io.github.dmlloyd.classfile.AnnotationValue.OfLong -import io.github.dmlloyd.classfile.AnnotationValue.OfString -import io.github.dmlloyd.classfile.ClassBuilder -import io.github.dmlloyd.classfile.ClassModel -import io.github.dmlloyd.classfile.attribute.RuntimeVisibleAnnotationsAttribute -import java.lang.constant.ClassDesc -import java.lang.reflect.Proxy - -/** A set of conventions to apply to Morphia entities */ -@MorphiaInternal -class CritterDefaultsConvention : CritterConvention { - override fun apply(mapper: Mapper, builder: ClassBuilder, model: ClassModel) { - val entity = - model.getAnnotation(ExternalEntity::class.java)?.let { externalEntity -> - EntityBuilder.entityBuilder() - .cap(externalEntity.cap) - .concern(externalEntity.concern) - .discriminator(externalEntity.discriminator) - .discriminatorKey(externalEntity.discriminatorKey) - .value(externalEntity.value) - .useDiscriminator(externalEntity.useDiscriminator) - .build() - } - ?: model.getAnnotation(Entity::class.java) as Entity? - ?: throw MappingException("no @Entity or @ExternalEntity") - - val config = mapper.config - builder.booleanMethod("discriminatorEnabled", entity.useDiscriminator) - builder.stringMethod( - "discriminatorKey", - applyDefaults(entity.discriminatorKey, config.discriminatorKey()) - ) - - // - // config.discriminator().apply(model) - } - - fun applyDefaults(configured: String, defaultValue: String): String { - return if (configured != Mapper.IGNORED_FIELDNAME) { - configured - } else { - defaultValue - } - } -} - -private fun ClassModel.getAnnotation(annotation: Class): A? { - val ann = - this.attributes() - .filterIsInstance() - .map { a -> - a.annotations().firstOrNull { - it.classSymbol() - .equals(ClassDesc.of(annotation.packageName, annotation.simpleName)) - } - } - .firstOrNull() - - return ann?.let { - val defaults = AnnotationFactory.build(annotation) - Proxy.newProxyInstance(javaClass.getClassLoader(), arrayOf(annotation)) { - proxy, - method, - args -> - val attr = ann.elements().firstOrNull { it.name().stringValue() == method.name } - attr?.value()?.let { value -> - when (method.returnType) { - String::class.java -> (value as OfString).stringValue() - Boolean::class.java -> (value as OfBoolean).booleanValue() - Int::class.java -> (value as OfInteger).intValue() - Long::class.java -> (value as OfLong).longValue() - Float::class.java -> (value as OfFloat).floatValue() - Double::class.java -> (value as OfDouble).doubleValue() - Char::class.java -> (value as OfCharacter).charValue() - Byte::class.java -> (value as OfByte).byteValue() - else -> TODO("Unsupported method: ${method.returnType}") - } - } ?: method.invoke(defaults) - } - } as A? -} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/conventions/PropertyConvention.kt b/critter/core/src/main/kotlin/dev/morphia/critter/conventions/PropertyConvention.kt new file mode 100644 index 00000000000..473a65ea88e --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/conventions/PropertyConvention.kt @@ -0,0 +1,44 @@ +package dev.morphia.critter.conventions + +import dev.morphia.annotations.Id +import dev.morphia.annotations.Property +import dev.morphia.annotations.Reference +import dev.morphia.annotations.Transient +import dev.morphia.annotations.Version +import dev.morphia.annotations.internal.MorphiaInternal +import dev.morphia.config.MorphiaConfig +import dev.morphia.mapping.Mapper + +/** + * @since 3.0 + * @hidden @morphia.internal + */ +@MorphiaInternal +object PropertyConvention { + fun transientAnnotations(): List> { + return listOf( + Transient::class.java, + kotlin.jvm.Transient::class.java, + java.beans.Transient::class.java + ) + } + + @MorphiaInternal + fun mappedName( + config: MorphiaConfig, + annotations: Map, + modelName: String + ): String { + val property = annotations.get(Property::class.java.getName()) as Property? + val reference = annotations.get(Reference::class.java.getName()) as Reference? + val version = annotations.get(Version::class.java.getName()) as Version? + val id = annotations.get(Id::class.java.getName()) as Id? + return when { + id != null -> "_id" + property != null && property.value != Mapper.IGNORED_FIELDNAME -> property.value + reference != null && reference.value != Mapper.IGNORED_FIELDNAME -> reference.value + version != null && version.value != Mapper.IGNORED_FIELDNAME -> version.value + else -> config.propertyNaming().apply(modelName) + } + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/conventions/PropertyDiscovery.kt b/critter/core/src/main/kotlin/dev/morphia/critter/conventions/PropertyDiscovery.kt deleted file mode 100644 index b68536f5c53..00000000000 --- a/critter/core/src/main/kotlin/dev/morphia/critter/conventions/PropertyDiscovery.kt +++ /dev/null @@ -1,109 +0,0 @@ -package dev.morphia.critter.conventions - -import com.mongodb.lang.NonNull -import com.mongodb.lang.Nullable -import dev.morphia.annotations.Id -import dev.morphia.annotations.Property -import dev.morphia.annotations.Reference -import dev.morphia.annotations.Transient -import dev.morphia.annotations.Version -import dev.morphia.annotations.internal.MorphiaInternal -import dev.morphia.mapping.Mapper -import dev.morphia.mapping.MappingException -import dev.morphia.mapping.codec.ArrayFieldAccessor -import dev.morphia.mapping.codec.FieldAccessor -import dev.morphia.mapping.codec.pojo.EntityModel -import dev.morphia.mapping.codec.pojo.PropertyModel -import dev.morphia.mapping.codec.pojo.TypeData -import dev.morphia.sofia.Sofia -import io.github.dmlloyd.classfile.ClassBuilder -import io.github.dmlloyd.classfile.ClassModel -import java.lang.reflect.Field -import java.lang.reflect.Modifier -import org.bson.codecs.pojo.PropertyAccessor - -@MorphiaInternal -class PropertyDiscovery : CritterConvention { - override fun apply(mapper: Mapper, builder: ClassBuilder, model: ClassModel) { - TODO() - /* - if (model.properties.isEmpty()) { - val list: MutableSet> = LinkedHashSet() - list.add(model.type) - list.addAll(model.classHierarchy()) - - for (type in list) { - for (field in type.declaredFields) { - if (!Modifier.isStatic(field.modifiers) && !isTransient(field)) { - val typeData = model.getTypeData(type, TypeData.get(field), field.genericType) - val externalEntity = type.getAnnotation( - ExternalEntity::class.java - ) - val target: Class<*>? = externalEntity?.target - val propertyModel = PropertyModel(model) - model.addProperty( - propertyModel - .name(field.name) - .typeData(typeData) - .annotations(List.of(*field.declaredAnnotations)) - .isFinal(Modifier.isFinal(field.modifiers)) - .accessor(getAccessor(getTargetField(model, target, field), typeData)) - .mappedName(discoverMappedName(mapper, propertyModel)) - ) - } - } - } - } - */ - } - - @NonNull - private fun getTargetField( - model: EntityModel, - @Nullable target: Class<*>?, - @NonNull field: Field - ): Field { - try { - return if (target == null) field else target.getDeclaredField(field.name) - } catch (e: NoSuchFieldException) { - throw MappingException( - Sofia.mismatchedFieldOnExternalType(field.name, model.type.name, model.type.name) - ) - } - } - - private fun getAccessor(field: Field, typeData: TypeData<*>): PropertyAccessor { - return if (field.type.isArray && field.type.componentType != Byte::class.javaPrimitiveType) - ArrayFieldAccessor(typeData, field) - else FieldAccessor(field) - } - - companion object { - fun isTransient(field: Field): Boolean { - return field.getDeclaredAnnotation(Transient::class.java) != null || - field.getDeclaredAnnotation(java.beans.Transient::class.java) != null || - Modifier.isTransient(field.modifiers) - } - - @MorphiaInternal - fun discoverMappedName(mapper: Mapper, model: PropertyModel): String { - val config = mapper.config - val property = model.getAnnotation(Property::class.java) - val reference = model.getAnnotation(Reference::class.java) - val version = model.getAnnotation(Version::class.java) - val mappedName = - if (model.hasAnnotation(Id::class.java)) { - "_id" - } else if (property != null && property.value != Mapper.IGNORED_FIELDNAME) { - property.value - } else if (reference != null && reference.value != Mapper.IGNORED_FIELDNAME) { - reference.value - } else if (version != null && version.value != Mapper.IGNORED_FIELDNAME) { - version.value - } else { - config.propertyNaming().apply(model.name) - } - return mappedName - } - } -} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/model/CritterClass.kt b/critter/core/src/main/kotlin/dev/morphia/critter/model/CritterClass.kt deleted file mode 100644 index 5b99f2c766f..00000000000 --- a/critter/core/src/main/kotlin/dev/morphia/critter/model/CritterClass.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.morphia.critter.model - -sealed class CritterClass(val name: String) { - override fun toString(): String { - return "CritterClass(name='$name')" - } -} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/model/JavaClass.kt b/critter/core/src/main/kotlin/dev/morphia/critter/model/JavaClass.kt deleted file mode 100644 index dcaae1f2305..00000000000 --- a/critter/core/src/main/kotlin/dev/morphia/critter/model/JavaClass.kt +++ /dev/null @@ -1,3 +0,0 @@ -package dev.morphia.critter.model - -class JavaClass(name: String) : CritterClass(name) {} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/ClassBuilderExtensions.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/ClassBuilderExtensions.kt deleted file mode 100644 index ee3047d987a..00000000000 --- a/critter/core/src/main/kotlin/dev/morphia/critter/parser/ClassBuilderExtensions.kt +++ /dev/null @@ -1,42 +0,0 @@ -package dev.morphia.critter.parser - -import io.github.dmlloyd.classfile.ClassBuilder -import io.github.dmlloyd.classfile.ClassFile.ACC_PUBLIC -import io.github.dmlloyd.classfile.constantpool.ConstantPoolBuilder -import java.lang.constant.ClassDesc -import java.lang.constant.ConstantDescs.CD_String -import java.lang.constant.ConstantDescs.CD_boolean -import java.lang.constant.MethodTypeDesc - -val INIT = "" -val OBJECT = ClassDesc.of("java.lang", "Object") -val NO_ARG_VOID = MethodTypeDesc.ofDescriptor("()V") -val constantPoolBuilder = ConstantPoolBuilder.of() - -fun ClassBuilder.noArgCtor() { - withMethod(INIT, NO_ARG_VOID, ACC_PUBLIC) { method -> - method.withCode { code -> - code.aload(0) - code.invokespecial(OBJECT, INIT, NO_ARG_VOID) - code.return_() - } - } -} - -fun ClassBuilder.booleanMethod(name: String, value: Boolean) { - withMethod(name, MethodTypeDesc.of(CD_boolean), ACC_PUBLIC) { method -> - method.withCode { code -> - if (value) code.iconst_1() else code.iconst_0() - code.ireturn() - } - } -} - -fun ClassBuilder.stringMethod(name: String, value: String) { - withMethod(name, MethodTypeDesc.of(CD_String), ACC_PUBLIC) { method -> - method.withCode { code -> - code.ldc(constantPoolBuilder.stringEntry(value)) - code.areturn() - } - } -} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/CritterProcessor.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/CritterProcessor.kt deleted file mode 100644 index 9d5e77f6f0a..00000000000 --- a/critter/core/src/main/kotlin/dev/morphia/critter/parser/CritterProcessor.kt +++ /dev/null @@ -1,37 +0,0 @@ -package dev.morphia.critter.parser - -import com.google.devtools.ksp.KspExperimental -import com.google.devtools.ksp.isAnnotationPresent -import com.google.devtools.ksp.processing.Resolver -import com.google.devtools.ksp.processing.SymbolProcessor -import com.google.devtools.ksp.processing.SymbolProcessorEnvironment -import com.google.devtools.ksp.symbol.ClassKind.CLASS -import com.google.devtools.ksp.symbol.ClassKind.INTERFACE -import com.google.devtools.ksp.symbol.KSAnnotated -import com.google.devtools.ksp.symbol.KSClassDeclaration -import com.google.devtools.ksp.symbol.Nullability -import dev.morphia.annotations.Entity -import dev.morphia.annotations.ExternalEntity - -@OptIn(KspExperimental::class) -class CritterProcessor(val environment: SymbolProcessorEnvironment) : SymbolProcessor { - - override fun process(resolver: Resolver): List { - val classes = - resolver - .getNewFiles() - .flatMap { - it.declarations.filterIsInstance().filter { klass -> - klass.classKind == CLASS || klass.classKind == INTERFACE - } - } - .filter { it.isAnnotationPresent(Entity::class) || it.isAnnotationPresent(ExternalEntity::class) } - .toList() - -// println("**************** files[1].declarations.toList() = ${klass.declarations.toList()}") - println("**************** classes = ${classes}") - - return listOf() - } - -} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/CritterProcessorProvider.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/CritterProcessorProvider.kt deleted file mode 100644 index 7a27b750d0e..00000000000 --- a/critter/core/src/main/kotlin/dev/morphia/critter/parser/CritterProcessorProvider.kt +++ /dev/null @@ -1,11 +0,0 @@ -package dev.morphia.critter.parser - -import com.google.devtools.ksp.processing.SymbolProcessor -import com.google.devtools.ksp.processing.SymbolProcessorEnvironment -import com.google.devtools.ksp.processing.SymbolProcessorProvider - -class CritterProcessorProvider : SymbolProcessorProvider { - override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { - return CritterProcessor(environment) - } -} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/ExtensionFunctions.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/ExtensionFunctions.kt index d4fe5a04cdd..cc8143ee640 100644 --- a/critter/core/src/main/kotlin/dev/morphia/critter/parser/ExtensionFunctions.kt +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/ExtensionFunctions.kt @@ -2,6 +2,7 @@ package dev.morphia.critter.parser import com.google.devtools.ksp.symbol.KSDeclaration import com.google.devtools.ksp.symbol.KSTypeReference +import java.util.Locale fun KSDeclaration.packageName() = packageName.asString() @@ -16,3 +17,17 @@ fun KSTypeReference.packageName(): String { fun KSTypeReference.simpleName(): String { return resolve().declaration.simpleName() } + +fun String.titleCase(): String { + return first().uppercase(Locale.getDefault()) + substring(1) +} + +fun String.methodCase(): String { + return first().lowercase(Locale.getDefault()) + substring(1) +} + +private val snakeCaseRegex = Regex("(?<=.)[A-Z]") + +fun String.snakeCase(): String { + return snakeCaseRegex.replace(this, "_$0").lowercase(Locale.getDefault()) +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/Generators.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/Generators.kt new file mode 100644 index 00000000000..e8570a35089 --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/Generators.kt @@ -0,0 +1,66 @@ +package dev.morphia.critter.parser + +import dev.morphia.config.MorphiaConfig +import dev.morphia.config.MorphiaConfigHelper.MORPHIA_CONFIG_PROPERTIES +import dev.morphia.mapping.Mapper +import dev.morphia.mapping.conventions.MorphiaDefaultsConvention +import org.objectweb.asm.Type +import org.objectweb.asm.Type.ARRAY + +object Generators { + var configFile = MORPHIA_CONFIG_PROPERTIES + + val config: MorphiaConfig by lazy { MorphiaConfig.load(configFile) } + + val mapper: Mapper by lazy { Mapper(config) } + + var convention = MorphiaDefaultsConvention() + + fun wrap(fieldType: Type): Type { + return when (fieldType) { + Type.VOID_TYPE -> Type.getType(Void::class.java) + Type.BOOLEAN_TYPE -> Type.getType(Boolean::class.java) + Type.CHAR_TYPE -> Type.getType(Char::class.java) + Type.BYTE_TYPE -> Type.getType(Byte::class.java) + Type.SHORT_TYPE -> Type.getType(Short::class.java) + Type.INT_TYPE -> Type.getType(Int::class.java) + Type.FLOAT_TYPE -> Type.getType(Float::class.java) + Type.LONG_TYPE -> Type.getType(Long::class.java) + Type.DOUBLE_TYPE -> Type.getType(Double::class.java) + else -> fieldType + } + } + + fun Type.isArray(): Boolean = sort == ARRAY + + fun Type.asClass(): Class<*> { + if (isArray()) return arrayAsClass() + return when (this) { + Type.BOOLEAN_TYPE -> Boolean::class.java + Type.CHAR_TYPE -> Char::class.java + Type.BYTE_TYPE -> Byte::class.java + Type.SHORT_TYPE -> Short::class.java + Type.INT_TYPE -> Int::class.java + Type.FLOAT_TYPE -> Float::class.java + Type.LONG_TYPE -> Long::class.java + Type.DOUBLE_TYPE -> Double::class.java + else -> Class.forName(className) + } + } + + private fun Type.arrayAsClass(): Class<*> { + val klass: Class<*> = + when (this.elementType) { + Type.BOOLEAN_TYPE -> Array::class.java + Type.CHAR_TYPE -> Array::class.java + Type.BYTE_TYPE -> Array::class.java + Type.SHORT_TYPE -> Array::class.java + Type.INT_TYPE -> Array::class.java + Type.FLOAT_TYPE -> Array::class.java + Type.LONG_TYPE -> Array::class.java + Type.DOUBLE_TYPE -> Array::class.java + else -> TODO() + } + return klass + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/PropertyFinder.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/PropertyFinder.kt new file mode 100644 index 00000000000..2a43ceb18c2 --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/PropertyFinder.kt @@ -0,0 +1,57 @@ +package dev.morphia.critter.parser + +import dev.morphia.critter.parser.gizmo.CritterGizmoGenerator.accessor +import dev.morphia.critter.parser.gizmo.CritterGizmoGenerator.fieldAccessors +import dev.morphia.critter.parser.gizmo.CritterGizmoGenerator.propertyModelGenerator +import dev.morphia.critter.parser.gizmo.PropertyModelGenerator +import dev.morphia.critter.parser.java.CritterClassLoader +import dev.morphia.critter.parser.java.CritterParser +import dev.morphia.mapping.Mapper +import org.objectweb.asm.Type +import org.objectweb.asm.tree.AnnotationNode +import org.objectweb.asm.tree.ClassNode + +class PropertyFinder(mapper: Mapper, val classLoader: CritterClassLoader) { + private val providerMap = + mapper.config.propertyAnnotationProviders().associateBy { it.provides() } + + fun find(entityType: Class<*>, classNode: ClassNode): List { + val models = mutableListOf() + val methods = discoverPropertyMethods(classNode) + if (methods.isEmpty()) { + val fields = discoverFields(classNode) + classLoader.register(entityType.name, fieldAccessors(entityType, fields)) + fields.forEach { field -> + accessor(entityType, field) + models += propertyModelGenerator(entityType, field) + } + } else { + TODO() + } + + return models + } + + private fun isPropertyAnnotated( + annotationNodes: MutableList?, + allowUnannotated: Boolean + ): Boolean { + val annotations = annotationNodes ?: listOf() + val keys = providerMap.keys.map { Type.getType(it).descriptor } + return allowUnannotated || annotations.any { a -> a.desc in keys } + } + + private fun discoverFields(classNode: ClassNode) = + classNode.fields + .filter { field -> + (field.visibleAnnotations ?: listOf()) + .map { a -> a.desc } + .none { desc -> desc in CritterParser.transientAnnotations() } + } + .filter { isPropertyAnnotated(it.visibleAnnotations, true) } + + private fun discoverPropertyMethods(classNode: ClassNode) = + classNode.methods + .filter { it.name.startsWith("get") && it.parameters.isEmpty() } + .filter { isPropertyAnnotated(it.visibleAnnotations, false) } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/AddFieldAccessorMethods.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/AddFieldAccessorMethods.kt new file mode 100644 index 00000000000..510ba4d2f0f --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/AddFieldAccessorMethods.kt @@ -0,0 +1,87 @@ +package dev.morphia.critter.parser.asm + +import dev.morphia.critter.titleCase +import org.objectweb.asm.ClassReader +import org.objectweb.asm.Label +import org.objectweb.asm.Opcodes.ACC_PUBLIC +import org.objectweb.asm.Opcodes.ACC_SYNTHETIC +import org.objectweb.asm.Opcodes.ALOAD +import org.objectweb.asm.Opcodes.GETFIELD +import org.objectweb.asm.Opcodes.ILOAD +import org.objectweb.asm.Opcodes.IRETURN +import org.objectweb.asm.Opcodes.PUTFIELD +import org.objectweb.asm.Opcodes.RETURN +import org.objectweb.asm.Type +import org.objectweb.asm.tree.FieldNode + +class AddFieldAccessorMethods(entity: Class<*>, var fields: List) : + BaseGenerator(entity) { + + init { + ClassReader(entity.name).accept(classWriter, 0) + } + + override fun emit(): ByteArray { + fields.forEach { field -> + val name = field.name + val type = Type.getType(field.desc) + reader(name, type) + writer(name, type) + } + + classWriter.visitEnd() + return classWriter.toByteArray() + } + + private fun writer(field: String, fieldType: Type) { + val mv = + classWriter.visitMethod( + ACC_PUBLIC or ACC_SYNTHETIC, + "__write${field.titleCase()}", + "(${fieldType.descriptor})V", + null, + null + ) + mv.visitCode() + val label0 = Label() + mv.visitLabel(label0) + mv.visitLineNumber(18, label0) + mv.visitVarInsn(ALOAD, 0) + mv.visitVarInsn(fieldType.getOpcode(ILOAD), 1) + mv.visitFieldInsn(PUTFIELD, entityType.internalName, field, fieldType.descriptor) + val label1 = Label() + mv.visitLabel(label1) + mv.visitLineNumber(19, label1) + mv.visitInsn(RETURN) + val label2 = Label() + mv.visitLabel(label2) + mv.visitLocalVariable("this", entityType.descriptor, null, label0, label2, 0) + mv.visitLocalVariable("value", fieldType.descriptor, null, label0, label2, 1) + mv.visitMaxs(2, 2) + mv.visitEnd() + } + + private fun reader(field: String, fieldType: Type) { + val name = "__read${field.titleCase()}" + val mv = + classWriter.visitMethod( + ACC_PUBLIC or ACC_SYNTHETIC, + name, + "()${fieldType.descriptor}", + null, + null + ) + mv.visitCode() + val label0 = Label() + mv.visitLabel(label0) + mv.visitLineNumber(14, label0) + mv.visitVarInsn(ALOAD, 0) + mv.visitFieldInsn(GETFIELD, entityType.internalName, field, fieldType.descriptor) + mv.visitInsn(fieldType.getOpcode(IRETURN)) + val label1 = Label() + mv.visitLabel(label1) + mv.visitLocalVariable("this", entityType.descriptor, null, label0, label1, 0) + mv.visitMaxs(1, 1) + mv.visitEnd() + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/BaseGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/BaseGenerator.kt new file mode 100644 index 00000000000..086a2feadbb --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/BaseGenerator.kt @@ -0,0 +1,49 @@ +package dev.morphia.critter.parser.asm + +import org.objectweb.asm.ClassWriter +import org.objectweb.asm.ClassWriter.COMPUTE_FRAMES +import org.objectweb.asm.ClassWriter.COMPUTE_MAXS +import org.objectweb.asm.Label +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes.ACC_PUBLIC +import org.objectweb.asm.Opcodes.ACC_SUPER +import org.objectweb.asm.Type + +abstract class BaseGenerator(entity: Class<*>) { + var classWriter = ClassWriter(COMPUTE_MAXS or COMPUTE_FRAMES) + val entityType: Type = Type.getType(entity) + var lineNumber = 0 + + lateinit var generatedType: Type + + abstract fun emit(): ByteArray + + protected open fun accessFlags() = ACC_PUBLIC or ACC_SUPER + + protected fun method( + access: Int, + name: String, + descriptor: String, + signature: String?, + exceptions: Array?, + lineNumber: Int + ): MethodVisitor { + this.lineNumber = lineNumber + return classWriter.visitMethod(access, name, descriptor, signature, exceptions) + } + + protected fun label( + mv: MethodVisitor, + lineNumber: Int = this.lineNumber, + visit: Boolean = true + ): Label { + val label0 = Label() + if (visit) { + mv.visitLabel(label0) + mv.visitLineNumber(lineNumber, label0) + this.lineNumber = lineNumber + 1 + } + + return label0 + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/CritterEntityModelGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/CritterEntityModelGenerator.kt new file mode 100644 index 00000000000..b9e041aaca8 --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/CritterEntityModelGenerator.kt @@ -0,0 +1,390 @@ +package dev.morphia.critter.parser.asm + +import dev.morphia.annotations.Entity +import dev.morphia.critter.Critter.Companion.critterPackage +import dev.morphia.mapping.codec.pojo.critter.CritterEntityModel +import java.lang.reflect.InvocationHandler +import java.lang.reflect.Method +import java.lang.reflect.Modifier +import java.lang.reflect.Proxy +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes.* +import org.objectweb.asm.Type +import org.objectweb.asm.tree.ClassNode + +class CritterEntityModelGenerator(val entity: Class<*>, val models: List) : + BaseGenerator(entity) { + companion object { + private val baseType = Type.getType(CritterEntityModel::class.java) + } + + init { + val generatorName = "${critterPackage(entity)}.${entity.simpleName}EntityModel" + generatedType = Type.getType("L${generatorName};") + } + + override fun emit(): ByteArray { + classWriter.visit( + V17, + accessFlags(), + generatedType.internalName, + null, + baseType.internalName, + null + ) + + constructor() + colllectionName() + discriminator() + discriminatorKey() + useDiscriminator() + getEntityAnnotation() + getType() + isAbstract() + isInterface() + + classWriter.visitEnd() + + return classWriter.toByteArray() + } + + fun constructor() { + val mv = method(ACC_PUBLIC, "", "(Ldev/morphia/mapping/Mapper;)V", null, null, 24) + mv.visitCode() + val label0 = label(mv) + mv.visitVarInsn(ALOAD, 0) + mv.visitVarInsn(ALOAD, 1) + mv.visitLdcInsn(Type.getType(entityType.descriptor)) + mv.visitMethodInsn( + INVOKESPECIAL, + "dev/morphia/critter/CritterEntityModel", + "", + "(Ldev/morphia/mapping/Mapper;Ljava/lang/Class;)V", + false + ) + + propertyModels(mv, models) + + val label1 = label(mv) + mv.visitInsn(RETURN) + val label2 = label(mv) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label2, 0) + mv.visitLocalVariable("mapper", "Ldev/morphia/mapping/Mapper;", null, label0, label2, 1) + // mv.visitMaxs(4, 2) + mv.visitEnd() + } + + private fun propertyModels(mv: MethodVisitor, models: List) { + models.forEach { + val model = it.replace('.', '/') + var label = label(mv) + mv.visitVarInsn(ALOAD, 0) + mv.visitTypeInsn(NEW, model) + mv.visitInsn(DUP) + mv.visitVarInsn(ALOAD, 0) + mv.visitMethodInsn( + INVOKESPECIAL, + model, + "", + "(Ldev/morphia/mapping/codec/pojo/EntityModel;)V", + false + ) + mv.visitMethodInsn( + INVOKEVIRTUAL, + generatedType.internalName, + "addProperty", + "(Ldev/morphia/mapping/codec/pojo/PropertyModel;)Z", + false + ) + mv.visitInsn(POP) + } + } + + fun colllectionName() { + val mv = method(ACC_PUBLIC, "collectionName", "()Ljava/lang/String;", null, null, 37) + mv.visitCode() + val label0 = label(mv, 37) + mv.visitVarInsn(ALOAD, 0) + mv.visitFieldInsn( + GETFIELD, + generatedType.internalName, + "mapper", + "Ldev/morphia/mapping/Mapper;" + ) + mv.visitMethodInsn( + INVOKEVIRTUAL, + "dev/morphia/mapping/Mapper", + "getConfig", + "()Ldev/morphia/config/MorphiaConfig;", + false + ) + mv.visitMethodInsn( + INVOKEINTERFACE, + "dev/morphia/config/MorphiaConfig", + "collectionNaming", + "()Ldev/morphia/mapping/NamingStrategy;", + true + ) + mv.visitLdcInsn(entityType.internalName.substringAfterLast("/")) + mv.visitMethodInsn( + INVOKEVIRTUAL, + "dev/morphia/mapping/NamingStrategy", + "apply", + "(Ljava/lang/String;)Ljava/lang/String;", + false + ) + mv.visitInsn(ARETURN) + val label1 = label(mv) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + // mv.visitMaxs(2, 1) + mv.visitEnd() + } + + fun discriminator() { + val mv = method(ACC_PUBLIC, "discriminator", "()Ljava/lang/String;", null, null, 47) + mv.visitCode() + val label0 = label(mv) + mv.visitVarInsn(ALOAD, 0) + mv.visitFieldInsn( + GETFIELD, + generatedType.internalName, + "mapper", + "Ldev/morphia/mapping/Mapper;" + ) + mv.visitMethodInsn( + INVOKEVIRTUAL, + "dev/morphia/mapping/Mapper", + "getConfig", + "()Ldev/morphia/config/MorphiaConfig;", + false + ) + mv.visitMethodInsn( + INVOKEINTERFACE, + "dev/morphia/config/MorphiaConfig", + "discriminator", + "()Ldev/morphia/mapping/DiscriminatorFunction;", + true + ) + mv.visitLdcInsn(entityType) + mv.visitLdcInsn(entity.getAnnotation(Entity::class.java).discriminator) + mv.visitMethodInsn( + INVOKEVIRTUAL, + "dev/morphia/mapping/DiscriminatorFunction", + "apply", + "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/String;", + false + ) + mv.visitInsn(ARETURN) + val label1 = label(mv) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + mv.visitMaxs(3, 1) + mv.visitEnd() + } + + fun discriminatorKey() { + val mv = method(ACC_PUBLIC, "discriminatorKey", "()Ljava/lang/String;", null, null, 52) + mv.visitCode() + val label0 = label(mv) + mv.visitLdcInsn(entity.getAnnotation(Entity::class.java).discriminatorKey) + mv.visitVarInsn(ALOAD, 0) + mv.visitFieldInsn( + GETFIELD, + generatedType.internalName, + "mapper", + "Ldev/morphia/mapping/Mapper;" + ) + mv.visitMethodInsn( + INVOKEVIRTUAL, + "dev/morphia/mapping/Mapper", + "getConfig", + "()Ldev/morphia/config/MorphiaConfig;", + false + ) + mv.visitMethodInsn( + INVOKEINTERFACE, + "dev/morphia/config/MorphiaConfig", + "discriminatorKey", + "()Ljava/lang/String;", + true + ) + mv.visitMethodInsn( + INVOKESTATIC, + "dev/morphia/mapping/conventions/MorphiaDefaultsConvention", + "applyDefaults", + "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", + false + ) + mv.visitInsn(ARETURN) + val label1 = label(mv) + mv.visitLocalVariable( + "this", + "Ldev/morphia/critter/sources/ExampleEntityModel;", + null, + label0, + label1, + 0 + ) + mv.visitMaxs(2, 1) + mv.visitEnd() + } + + fun useDiscriminator() { + val mv = classWriter.visitMethod(ACC_PUBLIC, "useDiscriminator", "()Z", null, null) + mv.visitCode() + val label0 = label(mv) + mv.visitLineNumber(137, label0) + mv.visitInsn( + if (entity.getAnnotation(Entity::class.java).useDiscriminator) ICONST_1 else ICONST_0 + ) + mv.visitInsn(IRETURN) + val label1 = label(mv) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + mv.visitMaxs(1, 1) + mv.visitEnd() + } + + fun getEntityAnnotation() { + val mv = + method( + ACC_PUBLIC, + "getEntityAnnotation", + "()Ldev/morphia/annotations/Entity;", + null, + null, + 57 + ) + mv.visitCode() + val label0 = label(mv) + mv.visitVarInsn(ALOAD, 0) + mv.visitFieldInsn( + GETFIELD, + generatedType.internalName, + "entityAnnotation", + "Ldev/morphia/annotations/Entity;" + ) + val label1 = label(mv, visit = false) + mv.visitJumpInsn(IFNONNULL, label1) + val label2 = label(mv) + mv.visitVarInsn(ALOAD, 0) + mv.visitLdcInsn(Type.getType(entityType.descriptor)) + mv.visitLdcInsn(Type.getType("Ldev/morphia/annotations/Entity;")) + val label3 = label(mv) + mv.visitMethodInsn( + INVOKEVIRTUAL, + "java/lang/Class", + "getAnnotation", + "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;", + false + ) + mv.visitTypeInsn(CHECKCAST, "dev/morphia/annotations/Entity") + mv.visitMethodInsn( + INVOKESTATIC, + "dev/morphia/annotations/internal/EntityBuilder", + "entityBuilder", + "(Ldev/morphia/annotations/Entity;)Ldev/morphia/annotations/internal/EntityBuilder;", + false + ) + val label4 = label(mv) + mv.visitMethodInsn( + INVOKEVIRTUAL, + "dev/morphia/annotations/internal/EntityBuilder", + "build", + "()Ldev/morphia/annotations/Entity;", + false + ) + mv.visitFieldInsn( + PUTFIELD, + generatedType.internalName, + "entityAnnotation", + "Ldev/morphia/annotations/Entity;" + ) + mv.visitLabel(label1) + mv.visitLineNumber(62, label1) + mv.visitFrame(F_SAME, 0, null, 0, null) + mv.visitVarInsn(ALOAD, 0) + mv.visitFieldInsn( + GETFIELD, + generatedType.internalName, + "entityAnnotation", + "Ldev/morphia/annotations/Entity;" + ) + mv.visitInsn(ARETURN) + val label5 = label(mv) + mv.visitLocalVariable( + "this", + "Ldev/morphia/critter/sources/ExampleEntityModel;", + null, + label0, + label5, + 0 + ) + mv.visitMaxs(3, 1) + mv.visitEnd() + } + + fun getType() { + val mv = + method( + ACC_PUBLIC, + "getType", + "()Ljava/lang/Class;", + "()Ljava/lang/Class<*>;", + null, + 107 + ) + mv.visitCode() + val label0 = label(mv) + mv.visitLdcInsn(Type.getType(entityType.descriptor)) + mv.visitInsn(ARETURN) + val label1 = label(mv) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + mv.visitMaxs(1, 1) + mv.visitEnd() + } + + private fun isAbstract() { + val mv = method(ACC_PUBLIC, "isAbstract", "()Z", null, null, 127) + mv.visitCode() + val label0 = label(mv) + mv.visitInsn(if (Modifier.isAbstract(entity.modifiers)) ICONST_1 else ICONST_0) + mv.visitInsn(IRETURN) + val label1 = label(mv) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + mv.visitMaxs(1, 1) + mv.visitEnd() + } + + private fun isInterface() { + val mv = method(ACC_PUBLIC, "isInterface", "()Z", null, null, 132) + mv.visitCode() + val label0 = label(mv) + mv.visitInsn(if (entity.isInterface) ICONST_1 else ICONST_0) + mv.visitInsn(IRETURN) + val label1 = label(mv) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + mv.visitMaxs(1, 1) + mv.visitEnd() + } + + @Suppress("UNCHECKED_CAST") + private fun ClassNode.getAnnotation(type: Class): A? { + val node = visibleAnnotations.firstOrNull { a -> a.desc == Type.getType(type).descriptor } + return node?.let { + Proxy.newProxyInstance( + ClassLoader.getSystemClassLoader(), + arrayOf(type), + object : InvocationHandler { + override fun invoke(proxy: Any, method: Method, args: Array?): Any { + try { + node + return method.invoke(node) as A + } catch (e: Exception) { + e.printStackTrace() + throw e + } + } + } + ) as A + } + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/CritterPropertyModelGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/CritterPropertyModelGenerator.kt new file mode 100644 index 00000000000..8f04b89111f --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/CritterPropertyModelGenerator.kt @@ -0,0 +1,186 @@ +package dev.morphia.critter.parser.asm + +import dev.morphia.critter.Critter.Companion.critterPackage +import dev.morphia.critter.identifierCase +import dev.morphia.critter.titleCase +import dev.morphia.mapping.codec.pojo.critter.CritterPropertyModel +import org.objectweb.asm.FieldVisitor +import org.objectweb.asm.Label +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes.ACC_PRIVATE +import org.objectweb.asm.Opcodes.ACC_PUBLIC +import org.objectweb.asm.Opcodes.ALOAD +import org.objectweb.asm.Opcodes.ARETURN +import org.objectweb.asm.Opcodes.DUP +import org.objectweb.asm.Opcodes.GETFIELD +import org.objectweb.asm.Opcodes.INVOKESPECIAL +import org.objectweb.asm.Opcodes.NEW +import org.objectweb.asm.Opcodes.PUTFIELD +import org.objectweb.asm.Opcodes.RETURN +import org.objectweb.asm.Opcodes.V17 +import org.objectweb.asm.Type +import org.objectweb.asm.tree.AnnotationNode +import org.objectweb.asm.tree.FieldNode +import org.objectweb.asm.tree.MethodNode + +class CritterPropertyModelGenerator(val entity: Class<*>, propertyName: String) : + BaseGenerator(entity) { + constructor(entity: Class<*>, field: FieldNode) : this(entity, field.name) { + annotations = field.visibleAnnotations ?: listOf() + } + + constructor( + entity: Class<*>, + method: MethodNode + ) : this(entity, method.name.drop(3).identifierCase()) { + annotations = method.visibleAnnotations ?: listOf() + } + + companion object { + private val baseType = Type.getType(CritterPropertyModel::class.java) + } + + lateinit var methodVisitor: MethodVisitor + lateinit var fieldVisitor: FieldVisitor + val accessorType: Type + lateinit var annotations: List + + init { + val baseName = "L${critterPackage(entity)}${entity.simpleName}${propertyName.titleCase()}" + generatedType = Type.getType("${baseName}PropertyModel;") + accessorType = Type.getType("${baseName}Accessor;") + } + + override fun emit(): ByteArray { + classWriter.visit( + V17, + accessFlags(), + generatedType.internalName, + null, + baseType.internalName, + null + ) + + fields() + constructor() + getAccessor() + // getAnnotation(); + classWriter.visitEnd() + + return classWriter.toByteArray() + } + + private fun fields() { + fieldVisitor = + classWriter.visitField( + ACC_PRIVATE, + "accessor", + "Lorg/bson/codecs/pojo/PropertyAccessor;", + "Lorg/bson/codecs/pojo/PropertyAccessor<*>;", + null + ) + fieldVisitor.visitEnd() + } + + private fun getAccessor() { + methodVisitor = + classWriter.visitMethod( + ACC_PUBLIC, + "getAccessor", + "()Lorg/bson/codecs/pojo/PropertyAccessor;", + "()Lorg/bson/codecs/pojo/PropertyAccessor;", + null + ) + methodVisitor.visitCode() + val label0 = Label() + methodVisitor.visitLabel(label0) + methodVisitor.visitLineNumber(22, label0) + methodVisitor.visitVarInsn(ALOAD, 0) + methodVisitor.visitFieldInsn( + GETFIELD, + generatedType.internalName, + "accessor", + "Lorg/bson/codecs/pojo/PropertyAccessor;" + ) + methodVisitor.visitInsn(ARETURN) + val label1 = Label() + methodVisitor.visitLabel(label1) + methodVisitor.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + methodVisitor.visitMaxs(1, 1) + methodVisitor.visitEnd() + } + + private fun constructor() { + methodVisitor = + classWriter.visitMethod( + ACC_PUBLIC, + "", + "(Ldev/morphia/mapping/codec/pojo/EntityModel;)V", + null, + null + ) + methodVisitor.visitCode() + val label0 = Label() + methodVisitor.visitLabel(label0) + methodVisitor.visitLineNumber(23, label0) + methodVisitor.visitVarInsn(ALOAD, 0) + methodVisitor.visitVarInsn(ALOAD, 1) + methodVisitor.visitMethodInsn( + INVOKESPECIAL, + "dev/morphia/mapping/codec/pojo/critter/CritterPropertyModel", + "", + "(Ldev/morphia/mapping/codec/pojo/EntityModel;)V", + false + ) + val label1 = Label() + methodVisitor.visitLabel(label1) + methodVisitor.visitLineNumber(20, label1) + methodVisitor.visitVarInsn(ALOAD, 0) + methodVisitor.visitTypeInsn(NEW, accessorType.internalName) + methodVisitor.visitInsn(DUP) + methodVisitor.visitMethodInsn( + INVOKESPECIAL, + accessorType.internalName, + "", + "()V", + false + ) + methodVisitor.visitFieldInsn( + PUTFIELD, + generatedType.internalName, + "accessor", + "Lorg/bson/codecs/pojo/PropertyAccessor;" + ) + + registerAnnotations() + val label2 = Label() + methodVisitor.visitLabel(label2) + methodVisitor.visitInsn(RETURN) + val label3 = Label() + methodVisitor.visitLabel(label3) + methodVisitor.visitLocalVariable("this", generatedType.descriptor, null, label0, label3, 0) + methodVisitor.visitLocalVariable( + "entityModel", + "Ldev/morphia/mapping/codec/pojo/EntityModel;", + null, + label0, + label3, + 1 + ) + methodVisitor.visitMaxs(3, 2) + methodVisitor.visitEnd() + } + + private fun registerAnnotations() { + annotations.forEach { annotation + -> /* AnnotationAsmFactory.build(methodVisitor, annotation)*/ + } + } + + private fun lookupBuilder(annotation: AnnotationNode): Type { + val type = Type.getType(annotation.desc) + val pkg = type.internalName.substringBeforeLast("/") + val name = type.internalName.substringAfterLast("/") + return Type.getType("L$pkg/internal/${name}Builder;") + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/EntityAccessorGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/EntityAccessorGenerator.kt new file mode 100644 index 00000000000..63f3b3b258d --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/asm/EntityAccessorGenerator.kt @@ -0,0 +1,207 @@ +package dev.morphia.critter.parser.asm + +import dev.morphia.critter.Critter.Companion.critterPackage +import dev.morphia.critter.parser.Generators.wrap +import dev.morphia.critter.titleCase +import org.objectweb.asm.Label +import org.objectweb.asm.Opcodes.* +import org.objectweb.asm.Type +import org.objectweb.asm.tree.FieldNode + +class EntityAccessorGenerator(entity: Class<*>) : BaseGenerator(entity) { + constructor(entity: Class<*>, field: FieldNode) : this(entity) { + propertyName = field.name + propertyType = Type.getType(field.desc) + generatedType = Type.getType("L$accessorName;") + } + + val wrapped: Type by lazy { wrap(propertyType) } + val accessorName by lazy { + "${critterPackage(entity)}${entity.simpleName}${propertyName.titleCase()}Accessor" + } + lateinit var propertyName: String + lateinit var propertyType: Type + + override fun emit(): ByteArray { + classWriter.visit( + V17, + accessFlags(), + generatedType.internalName, + "Ljava/lang/Object;Lorg/bson/codecs/pojo/PropertyAccessor<${wrap(propertyType).descriptor}>;", + "java/lang/Object", + arrayOf("org/bson/codecs/pojo/PropertyAccessor") + ) + + constructor() + get() + set() + setBridge() + getBridge() + classWriter.visitEnd() + + return classWriter.toByteArray() + } + + private fun getBridge() { + val methodVisitor = + classWriter.visitMethod( + ACC_PUBLIC or ACC_BRIDGE or ACC_SYNTHETIC, + "get", + "(Ljava/lang/Object;)Ljava/lang/Object;", + null, + null + ) + methodVisitor.visitCode() + val label0 = Label() + methodVisitor.visitLabel(label0) + methodVisitor.visitLineNumber(5, label0) + methodVisitor.visitVarInsn(ALOAD, 0) + methodVisitor.visitVarInsn(ALOAD, 1) + methodVisitor.visitMethodInsn( + INVOKEVIRTUAL, + generatedType.internalName, + "get", + "(Ljava/lang/Object;)${wrapped.descriptor}", + false + ) + methodVisitor.visitInsn(ARETURN) + val label1 = Label() + methodVisitor.visitLabel(label1) + methodVisitor.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + methodVisitor.visitMaxs(2, 2) + methodVisitor.visitEnd() + } + + private fun setBridge() { + val mv = + classWriter.visitMethod( + ACC_PUBLIC or ACC_BRIDGE or ACC_SYNTHETIC, + "set", + "(Ljava/lang/Object;Ljava/lang/Object;)V", + null, + null + ) + mv.visitCode() + val label0 = Label() + mv.visitLabel(label0) + mv.visitLineNumber(5, label0) + mv.visitVarInsn(ALOAD, 0) + mv.visitVarInsn(ALOAD, 1) + mv.visitVarInsn(ALOAD, 2) + mv.visitTypeInsn(CHECKCAST, wrapped.internalName) + mv.visitMethodInsn( + INVOKEVIRTUAL, + generatedType.internalName, + "set", + "(Ljava/lang/Object;${wrapped.descriptor})V", + false + ) + mv.visitInsn(RETURN) + val label1 = Label() + mv.visitLabel(label1) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + mv.visitMaxs(3, 3) + mv.visitEnd() + } + + private fun set() { + val mv = + classWriter.visitMethod( + ACC_PUBLIC, + "set", + "(Ljava/lang/Object;${wrapped.descriptor})V", + "(TS;${wrapped.descriptor})V", + null + ) + mv.visitCode() + val label0 = Label() + mv.visitLabel(label0) + mv.visitLineNumber(13, label0) + mv.visitVarInsn(ALOAD, 1) + mv.visitTypeInsn(CHECKCAST, entityType.internalName) + mv.visitVarInsn(ALOAD, 2) + if (!wrapped.equals(propertyType)) { + mv.visitMethodInsn( + INVOKEVIRTUAL, + wrapped.internalName, + "${propertyType.className}Value", + "()${propertyType.descriptor}", + false + ) + } + mv.visitMethodInsn( + INVOKEVIRTUAL, + entityType.internalName, + "__write${propertyName.titleCase()}", + "(${propertyType.descriptor})V", + false + ) + val label1 = Label() + mv.visitLabel(label1) + mv.visitLineNumber(14, label1) + mv.visitInsn(RETURN) + val label2 = Label() + mv.visitLabel(label2) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label2, 0) + mv.visitLocalVariable("entity", "Ljava/lang/Object;", "TS;", label0, label2, 1) + mv.visitLocalVariable("value", propertyType.descriptor, null, label0, label2, 2) + mv.visitMaxs(2, 3) + mv.visitEnd() + } + + private fun get() { + val mv = + classWriter.visitMethod( + ACC_PUBLIC, + "get", + "(Ljava/lang/Object;)${wrapped.descriptor}", + "(TS;)${wrapped.descriptor}", + null + ) + mv.visitCode() + val label0 = Label() + mv.visitLabel(label0) + mv.visitLineNumber(8, label0) + mv.visitVarInsn(ALOAD, 1) + mv.visitTypeInsn(CHECKCAST, entityType.internalName) + mv.visitMethodInsn( + INVOKEVIRTUAL, + entityType.internalName, + "__read${propertyName.titleCase()}", + "()${propertyType.descriptor}", + false + ) + if (!wrapped.equals(propertyType)) { + mv.visitMethodInsn( + INVOKESTATIC, + wrapped.internalName, + "valueOf", + "(${propertyType.descriptor})${wrapped.descriptor}", + false + ) + } + mv.visitInsn(ARETURN) + val label1 = Label() + mv.visitLabel(label1) + mv.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + mv.visitLocalVariable("entity", "Ljava/lang/Object;", "TS;", label0, label1, 1) + mv.visitMaxs(1, 2) + mv.visitEnd() + } + + fun constructor() { + val methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "", "()V", null, null) + methodVisitor.visitCode() + val label0 = Label() + methodVisitor.visitLabel(label0) + methodVisitor.visitLineNumber(5, label0) + methodVisitor.visitVarInsn(ALOAD, 0) + methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false) + methodVisitor.visitInsn(RETURN) + val label1 = Label() + methodVisitor.visitLabel(label1) + methodVisitor.visitLocalVariable("this", generatedType.descriptor, null, label0, label1, 0) + methodVisitor.visitMaxs(1, 1) + methodVisitor.visitEnd() + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/BaseGizmoGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/BaseGizmoGenerator.kt new file mode 100644 index 00000000000..2df08e8dfec --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/BaseGizmoGenerator.kt @@ -0,0 +1,17 @@ +package dev.morphia.critter.parser.gizmo + +import dev.morphia.critter.Critter.Companion.critterClassLoader +import dev.morphia.critter.Critter.Companion.critterPackage +import io.quarkus.gizmo.ClassCreator + +open class BaseGizmoGenerator(val entity: Class<*>) { + lateinit var generatedType: String + + val baseName = critterPackage(entity) + val builder: ClassCreator.Builder by lazy { + ClassCreator.builder() + .classOutput { name, data -> critterClassLoader.register(name.replace('/', '.'), data) } + .className(generatedType) + } + val creator: ClassCreator by lazy { builder.build() } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.kt new file mode 100644 index 00000000000..cc1c008b12c --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.kt @@ -0,0 +1,36 @@ +package dev.morphia.critter.parser.gizmo + +import dev.morphia.critter.Critter +import dev.morphia.critter.parser.Generators +import dev.morphia.critter.parser.PropertyFinder +import dev.morphia.critter.parser.asm.AddFieldAccessorMethods +import org.objectweb.asm.ClassReader +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.FieldNode + +object CritterGizmoGenerator { + fun generate(type: Class<*>): GizmoEntityModelGenerator { + val classNode = ClassNode() + ClassReader(type.name).accept(classNode, 0) + val propertyFinder = PropertyFinder(Generators.mapper, Critter.Companion.critterClassLoader) + + return entityModel(type, classNode, propertyFinder.find(type, classNode)) + } + + fun fieldAccessors(entityType: Class<*>, fields: List) = + AddFieldAccessorMethods(entityType, fields).emit() + + fun accessor(entityType: Class<*>, field: FieldNode) = + PropertyAccessorGenerator(entityType, field).emit() + + fun propertyModelGenerator(entityType: Class<*>, field: FieldNode) = + PropertyModelGenerator(Generators.config, entityType, field).emit() + + fun entityModel( + type: Class<*>, + classNode: ClassNode, + properties: List + ): GizmoEntityModelGenerator { + return GizmoEntityModelGenerator(type, classNode, properties).emit() + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.kt new file mode 100644 index 00000000000..30020b5c5e2 --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.kt @@ -0,0 +1,146 @@ +package dev.morphia.critter.parser.gizmo + +import dev.morphia.annotations.Entity +import dev.morphia.annotations.internal.AnnotationNodeExtensions.toMorphiaAnnotation +import dev.morphia.critter.parser.Generators.config +import dev.morphia.mapping.Mapper +import dev.morphia.mapping.codec.pojo.EntityModel +import dev.morphia.mapping.codec.pojo.PropertyModel +import dev.morphia.mapping.codec.pojo.critter.CritterEntityModel +import io.quarkus.gizmo.MethodCreator +import io.quarkus.gizmo.MethodDescriptor +import io.quarkus.gizmo.MethodDescriptor.ofMethod +import java.lang.reflect.Modifier +import kotlin.use +import org.objectweb.asm.tree.AnnotationNode +import org.objectweb.asm.tree.ClassNode + +class GizmoEntityModelGenerator( + type: Class<*>, + val classNode: ClassNode, + val properties: List +) : BaseGizmoGenerator(type) { + var annotations: List + var morphiaAnnotations: List + + init { + generatedType = "${baseName}.${entity.simpleName}EntityModel" + annotations = classNode.visibleAnnotations ?: emptyList() + morphiaAnnotations = annotations.map { it.toMorphiaAnnotation() } + } + + fun annotation(type: Class) = morphiaAnnotations.filterIsInstance(type).firstOrNull() + + fun emit(): GizmoEntityModelGenerator { + builder.superClass(CritterEntityModel::class.java) + + creator.use { + ctor() + collectionName() + discriminator() + discriminatorKey() + isAbstract() + isInterface() + useDiscriminator() + } + + return this + } + + private fun useDiscriminator() { + creator.getMethodCreator("useDiscriminator", "boolean").use { + it.returnValue(it.load(annotation(Entity::class.java)!!.useDiscriminator)) + } + } + + private fun isInterface() { + creator.getMethodCreator("isInterface", "boolean").use { + it.returnValue(it.load(entity.isInterface)) + } + } + + private fun isAbstract() { + creator.getMethodCreator("isAbstract", "boolean").use { + it.returnValue(it.load(Modifier.isAbstract(entity.modifiers))) + } + } + + private fun discriminatorKey() { + creator.getMethodCreator("discriminatorKey", String::class.java).use { + val key = annotation(Entity::class.java)!!.discriminator + it.returnValue( + it.load(if (key == Mapper.IGNORED_FIELDNAME) config.discriminatorKey() else key) + ) + } + } + + private fun discriminator() { + creator.getMethodCreator("discriminator", String::class.java).use { + val discriminator = + config.discriminator().apply(entity, annotation(Entity::class.java)!!.discriminator) + it.returnValue(it.load(discriminator)) + } + } + + private fun collectionName() { + creator.getMethodCreator("collectionName", String::class.java).use { + val key = annotation(Entity::class.java)!!.value + it.returnValue( + it.load( + if (key == Mapper.IGNORED_FIELDNAME) + config.collectionNaming().apply(entity.simpleName) + else key + ) + ) + } + } + + private fun ctor() { + creator.getConstructorCreator(Mapper::class.java).use { constructor -> + constructor.invokeSpecialMethod( + MethodDescriptor.ofConstructor( + CritterEntityModel::class.java, + Mapper::class.java, + Class::class.java, + ), + constructor.getThis(), + constructor.getMethodParam(0), + constructor.loadClass(entity) + ) + constructor.setParameterNames(arrayOf("mapper")) + + constructor.invokeVirtualMethod( + ofMethod(generatedType, "setType", "void", Class::class.java), + constructor.`this`, + constructor.loadClass(entity) + ) + loadProperties(constructor) + registerAnnotations(constructor) + + constructor.returnVoid() + } + } + + private fun loadProperties(creator: MethodCreator) { + val addProperty = + ofMethod(generatedType, "addProperty", "boolean", PropertyModel::class.java) + properties.forEach { property -> + val modelCtor = + MethodDescriptor.ofConstructor(property.generatedType, EntityModel::class.java) + + val model = creator.newInstance(modelCtor, creator.`this`) + creator.invokeVirtualMethod(addProperty, creator.`this`, model) + } + } + + private fun registerAnnotations(constructor: MethodCreator) { + val annotationMethod = ofMethod(generatedType, "annotation", "void", Annotation::class.java) + annotations.forEach { annotation -> + constructor.invokeVirtualMethod( + annotationMethod, + constructor.`this`, + annotation.annotationBuilder(constructor) + ) + } + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/GizmoExtensions.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/GizmoExtensions.kt new file mode 100644 index 00000000000..cb195ea9f69 --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/GizmoExtensions.kt @@ -0,0 +1,137 @@ +package dev.morphia.critter.parser.gizmo + +import dev.morphia.annotations.internal.AnnotationNodeExtensions.setBuilderValues +import dev.morphia.critter.parser.Generators.asClass +import dev.morphia.critter.parser.methodCase +import dev.morphia.mapping.codec.pojo.TypeData +import io.quarkus.gizmo.FieldDescriptor +import io.quarkus.gizmo.MethodCreator +import io.quarkus.gizmo.MethodDescriptor +import io.quarkus.gizmo.ResultHandle +import java.lang.reflect.GenericArrayType +import java.lang.reflect.ParameterizedType +import kotlin.reflect.KClass +import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.jvm.javaType +import org.objectweb.asm.Type +import org.objectweb.asm.tree.AnnotationNode + +fun AnnotationNode.annotationBuilder(creator: MethodCreator): ResultHandle { + val type = Type.getType(desc) + val classPackage = type.className.substringBeforeLast('.') + val className = type.className.substringAfterLast('.') + val builderType = + Type.getType("L${classPackage}.internal.${className}Builder;".replace('.', '/')) + val builder = + MethodDescriptor.ofMethod( + builderType.className, + "${className.methodCase()}Builder", + builderType.className + ) + val local = creator.invokeStaticMethod(builder) + + setBuilderValues(creator, local) + + return creator.invokeVirtualMethod( + MethodDescriptor.ofMethod(builderType.className, "build", type.className), + local + ) +} + +fun TypeData<*>.emitTypeData(methodCreator: MethodCreator): ResultHandle { + var array = methodCreator.newArray(TypeData::class.java, typeParameters.size) + + typeParameters.forEachIndexed { index, typeParameter -> + methodCreator.writeArrayValue(array, index, typeParameter.emitTypeData(methodCreator)) + } + val list = listOf(methodCreator.loadClass(type), array) + val descriptor = + MethodDescriptor.ofConstructor( + TypeData::class.java, + Class::class.java, + "[${Type.getType(TypeData::class.java).descriptor}" + ) + return methodCreator.newInstance(descriptor, *list.toTypedArray()) +} + +fun rawType(type: java.lang.reflect.Type) = + when (type) { + is GenericArrayType -> { + val type1 = type.genericComponentType as ParameterizedType + Type.getType("[" + Type.getType(type1.rawType as Class<*>).descriptor) + } + else -> Type.getType(type as Class<*>) + }.descriptor + +fun attributeType(type: KClass<*>, name: String): java.lang.reflect.Type { + val map = + type.declaredMemberProperties + .filter { it.name == name } + .map { it.returnType.javaType } + .first() + return map +} + +@Suppress("UNCHECKED_CAST") +fun load(creator: MethodCreator, type: java.lang.reflect.Type, `value`: Any): ResultHandle { + fun extractComponentType(arrayType: GenericArrayType) = + (arrayType.genericComponentType as ParameterizedType).rawType.typeName + + return when (type) { + is Class<*> -> load(creator, type, value) + is GenericArrayType -> { + val genericComponentType = extractComponentType(type) + val newArray = creator.newArray(genericComponentType, (value as List).size) + newArray.apply { + value.forEachIndexed { index: Int, element: Any -> + creator.writeArrayValue( + this, + index, + load(creator, Class.forName((element as Type).className), element) + ) + } + } + newArray + } + else -> TODO("unknown type: $type") + } +} + +@Suppress("UNCHECKED_CAST") +fun load(creator: MethodCreator, type: Class<*>, `value`: Any): ResultHandle { + return when (type) { + String::class.java -> creator.load(value as String) + Int::class.java -> creator.load(value as Int) + Long::class.java -> creator.load(value as Long) + Boolean::class.java -> creator.load(value as Boolean) + AnnotationNode::class.java -> (value as AnnotationNode).annotationBuilder(creator) + else -> { + when { + type.isAnnotation -> (value as AnnotationNode).annotationBuilder(creator) + type.isArray -> + creator.newArray(type.componentType, (value as List).size).apply< + ResultHandle + > { + value.forEachIndexed { index: Int, element: Any -> + creator.writeArrayValue( + this, + index, + load(creator, element.javaClass, element) + ) + } + } + type.isEnum -> + return creator.readStaticField( + FieldDescriptor.of(type, (value as Array)[1], type) + ) + value is Type -> { + creator.loadClass(value.className) + } + else -> TODO("$type is not yet supported") + } + } + } +} + +fun Type.typeData(typeParameters: List> = listOf()) = + TypeData(asClass(), typeParameters) diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/PropertyAccessorGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/PropertyAccessorGenerator.kt new file mode 100644 index 00000000000..07b7979f833 --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/PropertyAccessorGenerator.kt @@ -0,0 +1,89 @@ +package dev.morphia.critter.parser.gizmo + +import dev.morphia.critter.titleCase +import io.quarkus.gizmo.MethodDescriptor.ofConstructor +import io.quarkus.gizmo.MethodDescriptor.ofMethod +import io.quarkus.gizmo.SignatureBuilder.* +import io.quarkus.gizmo.Type.* +import org.bson.codecs.pojo.PropertyAccessor +import org.objectweb.asm.Type.getReturnType +import org.objectweb.asm.Type.getType +import org.objectweb.asm.tree.FieldNode +import org.objectweb.asm.tree.MethodNode + +class PropertyAccessorGenerator : BaseGizmoGenerator { + constructor(entity: Class<*>, field: FieldNode) : super(entity) { + propertyName = field.name + propertyType = getType(field.desc).className + generatedType = "${baseName}.${propertyName.titleCase()}Accessor" + } + + constructor(entity: Class<*>, method: MethodNode) : super(entity) { + propertyName = method.name + propertyType = getReturnType(method.signature).className + generatedType = "${baseName}.${propertyName.titleCase()}Accessor" + } + + val propertyName: String + val propertyType: String + + fun emit(): PropertyAccessorGenerator { + builder.signature( + forClass() + .addInterface( + parameterizedType( + classType(PropertyAccessor::class.java), + classType(propertyType) + ) + ) + ) + + creator.use { + ctor() + get() + set() + } + + return this + } + + private fun get() { + val method = + creator.getMethodCreator(ofMethod(generatedType, "get", propertyType, entity.name)) + method.signature = + forMethod() + .addTypeParameter(typeVariable("S")) + .setReturnType(classType(propertyType)) + .addParameterType(classType(entity)) + .build() + method.setParameterNames(arrayOf("model")) + val toInvoke = ofMethod(entity, "__read${propertyName.titleCase()}", propertyType) + method.returnValue(method.invokeVirtualMethod(toInvoke, method.getMethodParam(0))) + } + + private fun set() { + val method = + creator.getMethodCreator( + ofMethod(generatedType, "set", "void", entity.name, propertyType) + ) + method.signature = + forMethod() + .addTypeParameter(typeVariable("S")) + .setReturnType(voidType()) + .addParameterType(classType(entity)) + .addParameterType(classType(propertyType)) + .build() + method.setParameterNames(arrayOf("model", "value")) + val toInvoke = ofMethod(entity, "__write${propertyName.titleCase()}", "void", propertyType) + method.invokeVirtualMethod(toInvoke, method.getMethodParam(0), method.getMethodParam(1)) + method.returnValue(null) + } + + private fun ctor() { + val constructor = creator.getConstructorCreator(*arrayOf()) + constructor.invokeSpecialMethod(ofConstructor(Object::class.java), constructor.`this`) + constructor.returnVoid() + + constructor.close() + } +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/PropertyModelGenerator.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/PropertyModelGenerator.kt new file mode 100644 index 00000000000..f72ea944c74 --- /dev/null +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/gizmo/PropertyModelGenerator.kt @@ -0,0 +1,340 @@ +package dev.morphia.critter.parser.gizmo + +import com.mongodb.DBRef +import dev.morphia.annotations.AlsoLoad +import dev.morphia.annotations.Reference +import dev.morphia.annotations.internal.AnnotationNodeExtensions.toMorphiaAnnotation +import dev.morphia.config.MorphiaConfig +import dev.morphia.critter.conventions.PropertyConvention +import dev.morphia.critter.parser.Generators.isArray +import dev.morphia.critter.parser.methodCase +import dev.morphia.critter.titleCase +import dev.morphia.mapping.codec.pojo.EntityModel +import dev.morphia.mapping.codec.pojo.PropertyModel +import dev.morphia.mapping.codec.pojo.PropertyModel.normalize +import dev.morphia.mapping.codec.pojo.TypeData +import dev.morphia.mapping.codec.pojo.critter.CritterPropertyModel +import io.quarkus.gizmo.MethodCreator +import io.quarkus.gizmo.MethodDescriptor +import io.quarkus.gizmo.MethodDescriptor.ofMethod +import io.quarkus.gizmo.ResultHandle +import org.bson.codecs.pojo.PropertyAccessor +import org.objectweb.asm.Opcodes +import org.objectweb.asm.Type +import org.objectweb.asm.Type.ARRAY +import org.objectweb.asm.Type.getReturnType +import org.objectweb.asm.tree.AnnotationNode +import org.objectweb.asm.tree.FieldNode +import org.objectweb.asm.tree.MethodNode + +class PropertyModelGenerator private constructor(val config: MorphiaConfig, entity: Class<*>) : + BaseGizmoGenerator(entity) { + constructor(config: MorphiaConfig, entity: Class<*>, field: FieldNode) : this(config, entity) { + this.field = field + propertyName = field.name.methodCase() + propertyType = Type.getType(field.desc) + val signature = field.signature + typeArguments = + signature?.let { + typeData(it) + Type.getArgumentTypes("()$it") + } ?: arrayOf() + generatedType = "${baseName}.${propertyName.titleCase()}Model" + accessorType = "${baseName}.${propertyName.titleCase()}Accessor" + annotations = field.visibleAnnotations ?: emptyList() + } + + constructor( + config: MorphiaConfig, + entity: Class<*>, + method: MethodNode, + ) : this(config, entity) { + this.method = method + propertyName = method.name.methodCase() + propertyType = getReturnType(method.desc) + typeArguments = Type.getArgumentTypes(method.signature) + generatedType = "${baseName}.${propertyName.titleCase()}Model" + accessorType = "${baseName}.${propertyName.titleCase()}Accessor" + annotations = method.visibleAnnotations + } + + private var typeArguments: Array = arrayOf() + var field: FieldNode? = null + var method: MethodNode? = null + lateinit var propertyName: String + lateinit var propertyType: Type + lateinit var accessorType: String + lateinit var annotations: List + val annotationMap: Map by lazy { + annotations + .map { it.toMorphiaAnnotation() as Annotation } + .associateBy { it.annotationClass.qualifiedName!! } + } + val accessValue by lazy { field?.access ?: method!!.access } + val typeData by lazy { + val input = + field?.let { it.signature ?: it.desc } + ?: method!!.let { it.signature ?: it.desc } + typeData(input)[0] + } + val model by lazy { creator.getFieldCreator("entityModel", EntityModel::class.java) } + + fun emit(): PropertyModelGenerator { + builder.superClass(CritterPropertyModel::class.java) + + creator.use { + ctor() + getAccessor() + getFullName() + getLoadNames() + getMappedName() + getName() + getNormalizedType() + isArray() + isFinal() + isReference() + isTransient() + isMap() + isSet() + isCollection() + getType() + getTypeData() + getEntityModel() + } + return this + } + + private fun isArray() { + creator.getMethodCreator("isArray", Boolean::class.java).use { methodCreator -> + methodCreator.returnValue(methodCreator.load(propertyType.isArray())) + } + } + + private fun isMap() { + creator.getMethodCreator("isMap", Boolean::class.java).use { methodCreator -> + methodCreator.returnValue( + methodCreator.load(Map::class.java.isAssignableFrom(typeData.type)) + ) + } + } + + private fun isSet() { + creator.getMethodCreator("isSet", Boolean::class.java).use { methodCreator -> + methodCreator.returnValue( + methodCreator.load(Set::class.java.isAssignableFrom(typeData.type)) + ) + } + } + + private fun getType() { + creator.getMethodCreator("getType", Class::class.java).use { methodCreator -> + methodCreator.returnValue(methodCreator.loadClass(typeData.type)) + } + } + + private fun getEntityModel() { + creator.getMethodCreator("getEntityModel", EntityModel::class.java).use { methodCreator -> + methodCreator.returnValue( + methodCreator.readInstanceField(model.fieldDescriptor, methodCreator.`this`) + ) + } + } + + private fun getTypeData() { + creator.getMethodCreator("getTypeData", TypeData::class.java).use { methodCreator -> + methodCreator.returnValue(emitTypeData(methodCreator, this.typeData)) + } + } + + private fun emitTypeData(methodCreator: MethodCreator, data: TypeData<*>): ResultHandle { + var array = methodCreator.newArray(TypeData::class.java, data.typeParameters.size) + + data.typeParameters.forEachIndexed { index, typeParameter -> + methodCreator.writeArrayValue(array, index, emitTypeData(methodCreator, typeParameter)) + } + val list = listOf(methodCreator.loadClass(data.type), array) + val descriptor = + MethodDescriptor.ofConstructor( + TypeData::class.java, + Class::class.java, + "[${Type.getType(TypeData::class.java).descriptor}" + ) + return methodCreator.newInstance(descriptor, *list.toTypedArray()) + } + + private fun isCollection() { + creator.getMethodCreator("isCollection", Boolean::class.java).use { methodCreator -> + methodCreator.returnValue( + methodCreator.load(Collection::class.java.isAssignableFrom(typeData.type)) + ) + } + } + + private fun extractType(type: Type): Any { + return when { + type.sort == ARRAY -> extractType(type.elementType) + else -> type + } + } + + private fun isFinal() { + creator.getMethodCreator("isFinal", Boolean::class.java).use { methodCreator -> + methodCreator.returnValue(methodCreator.load(checkMask(Opcodes.ACC_FINAL))) + } + } + + private fun isTransient() { + creator.getMethodCreator("isTransient", Boolean::class.java).use { methodCreator -> + val transient = + checkMask(Opcodes.ACC_TRANSIENT) or + PropertyConvention.transientAnnotations().any { + annotationMap.containsKey(it.name) + } + methodCreator.returnValue(methodCreator.load(transient)) + } + } + + private fun isReference() { + creator.getMethodCreator("isReference", Boolean::class.java).use { methodCreator -> + methodCreator.returnValue( + methodCreator.load( + propertyType.equals(Type.getType(DBRef::class.java)) or + annotationMap.containsKey(Reference::class.java.name) + ) + ) + } + } + + private fun checkMask(mask: Int) = (accessValue and mask) == mask + + private fun getNormalizedType() { + creator.getMethodCreator("getNormalizedType", Class::class.java).use { methodCreator -> + methodCreator.returnValue(methodCreator.loadClass(normalize(typeData))) + } + } + + private fun getLoadNames() { + creator.getMethodCreator("getLoadNames", Array::class.java).use { methodCreator -> + val alsoLoad: AlsoLoad? = annotationMap[AlsoLoad::class.java.name] as AlsoLoad? + val size = alsoLoad?.value?.size ?: 0 + val names = methodCreator.newArray(String::class.java, size) + alsoLoad?.value?.forEachIndexed { index, it -> + methodCreator.writeArrayValue(names, index, methodCreator.load(it)) + } + methodCreator.returnValue(names) + } + } + + private fun getName() { + creator.getMethodCreator("getName", String::class.java).use { methodCreator -> + methodCreator.returnValue(methodCreator.load(propertyName)) + } + } + + private fun getMappedName() { + creator.getMethodCreator("getMappedName", String::class.java).use { methodCreator -> + methodCreator.returnValue( + methodCreator.load( + PropertyConvention.mappedName(config, annotationMap, propertyName) + ) + ) + } + } + + private fun getFullName() { + creator.getMethodCreator("getFullName", String::class.java).use { methodCreator -> + methodCreator.returnValue(methodCreator.load("${entity.name}#${propertyName}")) + } + } + + private fun ctor() { + creator.getConstructorCreator(EntityModel::class.java).use { constructor -> + constructor.invokeSpecialMethod( + MethodDescriptor.ofConstructor( + CritterPropertyModel::class.java, + EntityModel::class.java + ), + constructor.getThis(), + constructor.getMethodParam(0) + ) + constructor.setParameterNames(arrayOf("model")) + constructor.writeInstanceField( + model.fieldDescriptor, + constructor.`this`, + constructor.getMethodParam(0) + ) + registerAnnotations(constructor) + constructor.returnVoid() + } + } + + private fun registerAnnotations(constructor: MethodCreator) { + val annotationMethod = + ofMethod( + PropertyModel::class.java.name, + "annotation", + PropertyModel::class.java.name, + Annotation::class.java + ) + annotations.forEach { annotation -> + constructor.invokeVirtualMethod( + annotationMethod, + constructor.`this`, + annotation.annotationBuilder(constructor) + ) + } + } + + private fun getAccessor() { + val field = creator.getFieldCreator("accessor", accessorType) + val method = + creator.getMethodCreator( + ofMethod(creator.className, "getAccessor", PropertyAccessor::class.java.name) + ) + + method.returnValue(method.readInstanceField(field.fieldDescriptor, method.`this`)) + + method.close() + } +} + +private fun String.balanced(): String { + if (!contains("<")) return "" + val start = indexOf('<') + 1 + var index = start + var count = 1 + + while (index < length && count != 0) { + when (this[++index]) { + '>' -> count-- + '<' -> count++ + } + } + + return substring(start, index) +} + +fun typeData(input: String): List> { + if (input.isEmpty()) return emptyList() + val types = mutableListOf>() + var value = input + + while (value.isNotEmpty()) { + val bracket = value.indexOf('<') + if (bracket == -1 || bracket > value.indexOf(';')) { + var type = value.substringBefore(';') + if (type.length > 2) { + type += ";" + } + value = value.substring(type.length) + val type1 = Type.getType(type) + types += type1.typeData() + } else { + val paramString = value.balanced() + value = value.replace("<$paramString>", "") + types += Type.getType(value).typeData(typeData(paramString)) + value = value.substringAfter(';') + } + } + return types +} diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/java/CritterClassLoader.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/java/CritterClassLoader.kt index 0049198e2d0..224c18f0c0b 100644 --- a/critter/core/src/main/kotlin/dev/morphia/critter/parser/java/CritterClassLoader.kt +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/java/CritterClassLoader.kt @@ -1,14 +1,80 @@ package dev.morphia.critter.parser.java -import io.quarkus.gizmo.ClassOutput -import net.bytebuddy.dynamic.loading.ByteArrayClassLoader +import dev.morphia.critter.parser.java.CritterParser.asmify +import java.io.File +import java.io.FileOutputStream +import java.io.FileWriter +import net.bytebuddy.dynamic.loading.ByteArrayClassLoader.ChildFirst +import org.jboss.forge.roaster.Roaster +import org.jboss.forge.roaster.model.source.JavaClassSource +import org.objectweb.asm.Type + +class CritterClassLoader(parent: ClassLoader?) : + // URLClassLoader(arrayOf(File("target/critter").toURI().toURL()), parent) + ChildFirst(parent, mapOf()) { + companion object { + var output = "target/critter" + var asm = false + } -class CritterClassLoader(parent: ClassLoader) : ByteArrayClassLoader(parent, mapOf()), ClassOutput { fun register(name: String, bytes: ByteArray) { typeDefinitions[name] = bytes + dump(name) + } + + override fun loadClass(name: String?): Class<*> { + return super.loadClass(name) } - override fun write(name: String, data: ByteArray) { - register(name, data) + fun dump(name: String, mappings: Map = mapOf()) { + File(output).mkdirs() + val outputFolder = File(output, File(name.replace('.', '/')).parent) + val fileName = name.substringAfterLast('.') + outputFolder.mkdirs() + val bytes = + typeDefinitions[name] + ?: getResourceAsStream("${name.replace('.', '/')}.class")?.readBytes() + + if (bytes != null) { + FileOutputStream(File(outputFolder, "$fileName.class")).use { it.write(bytes) } + asmify(bytes, mappings, name, outputFolder, fileName) + } else { + throw ClassNotFoundException("Could not find $name") + } + } + + private fun asmify( + bytes: ByteArray, + mappings: Map, + name: String, + outputFolder: File, + fileName: String + ) { + if (!asm) return + + var asm = asmify(bytes) + mappings.forEach { (type, mapping) -> + asm = + asm.replace(type.internalName, mapping.internalName) + .replace(type.descriptor, mapping.descriptor) + .replace(type.className, mapping.className) + } + if (!name.contains("__morphia")) { + asm = + asm.replace("Template", "") + .replace(".sources", ".sources.__morphia.example") + .replace("/sources", "/sources/__morphia/example") + } + val source = Roaster.parse(JavaClassSource::class.java, asm) + FileWriter(File(outputFolder, "$fileName.asm")).use { it.write(source.toString()) } + } + + override fun findClass(name: String): Class<*> { + val findClass = super.findClass(name) + getResource(name.replace('.', '/') + ".class")?.let { resource -> + register(name, resource.readBytes()) + } + + return findClass } } diff --git a/critter/core/src/main/kotlin/dev/morphia/critter/parser/java/CritterParser.kt b/critter/core/src/main/kotlin/dev/morphia/critter/parser/java/CritterParser.kt index 6018aa3ef61..357f50e2f94 100644 --- a/critter/core/src/main/kotlin/dev/morphia/critter/parser/java/CritterParser.kt +++ b/critter/core/src/main/kotlin/dev/morphia/critter/parser/java/CritterParser.kt @@ -1,110 +1,31 @@ package dev.morphia.critter.parser.java -import dev.morphia.config.MorphiaConfig -import dev.morphia.critter.conventions.CritterDefaultsConvention -import dev.morphia.critter.parser.noArgCtor -import dev.morphia.mapping.Mapper -import io.github.dmlloyd.classfile.ClassBuilder -import io.github.dmlloyd.classfile.ClassFile -import io.github.dmlloyd.classfile.attribute.InnerClassInfo -import io.github.dmlloyd.classfile.attribute.InnerClassesAttribute -import io.github.dmlloyd.classfile.extras.reflect.AccessFlag.SYNTHETIC -import io.github.dmlloyd.classfile.extras.reflect.ClassFileFormatVersion.RELEASE_17 -import io.quarkus.gizmo.ClassCreator +import dev.morphia.critter.Critter.Companion.propertyAnnotations +import dev.morphia.critter.Critter.Companion.transientAnnotations import java.io.File -import java.io.FileOutputStream -import java.lang.constant.ClassDesc -import java.util.Optional +import java.io.PrintWriter +import java.io.StringWriter +import org.objectweb.asm.ClassReader +import org.objectweb.asm.util.ASMifier +import org.objectweb.asm.util.TraceClassVisitor object CritterParser { var outputGenerated: File? = null - val critterClassLoader = CritterClassLoader(Thread.currentThread().contextClassLoader) - fun gizmo(input: File): Class<*> { - val model = ClassFile.of().parse(input.readBytes()) - val modelName = model.thisClass().name().stringValue() - val name = "${modelName}_InternalCritter" - val innerClassDesc = ClassDesc.of(name.replace('/', '.')) - val outerClassDesc = ClassDesc.of(modelName.replace('/', '.')) - val conventions = listOf(CritterDefaultsConvention() /*, - if (mapper.getConfig().propertyDiscovery() == FIELDS) FieldDiscovery() else MethodDiscovery(), - ConfigureProperties()*/) - val creator = - ClassCreator.builder() - .classOutput(critterClassLoader) - .className(name) - .superClass(Annotation::class.javaObjectType) - - val b = - ClassFile.of().build(innerClassDesc) { builder: ClassBuilder -> - builder.withVersion(RELEASE_17.major(), 0) - builder.with( - InnerClassesAttribute.of( - InnerClassInfo.of( - innerClassDesc, - Optional.of(outerClassDesc), - Optional.of(innerClassDesc.displayName()), - SYNTHETIC - ) - ) - ) - builder.noArgCtor() - conventions.forEach { convention -> - convention.apply(Mapper(MorphiaConfig.load()), builder, model) - } - model.fields().forEach {} - } - - println("**************** b = ${b.size}") - outputGenerated?.let { - val file = - File(outputGenerated, "${name.substringAfterLast("/").replace("$", "\\\$")}.class") - println("**************** file = ${file.absoluteFile}") - file.parentFile.mkdirs() - FileOutputStream(file).use { it.write(b) } - } - critterClassLoader.register(name.replace('/', '.'), b) - return critterClassLoader.loadClass(name.replace('/', '.')) + fun asmify(bytes: ByteArray): String { + val classReader = ClassReader(bytes) + val traceWriter = StringWriter() + val printWriter = PrintWriter(traceWriter) + val traceClassVisitor = TraceClassVisitor(null, ASMifier(), printWriter) + classReader.accept(traceClassVisitor, 0) + return traceWriter.toString() } - fun parser(input: File): Class<*> { - val model = ClassFile.of().parse(input.readBytes()) - val modelName = model.thisClass().name().stringValue() - val name = "${modelName}_InternalCritter" - val innerClassDesc = ClassDesc.of(name.replace('/', '.')) - val outerClassDesc = ClassDesc.of(modelName.replace('/', '.')) - val conventions = listOf(CritterDefaultsConvention() /*, - if (mapper.getConfig().propertyDiscovery() == FIELDS) FieldDiscovery() else MethodDiscovery(), - ConfigureProperties()*/) - val b = - ClassFile.of().build(innerClassDesc) { builder: ClassBuilder -> - builder.withVersion(RELEASE_17.major(), 0) - builder.with( - InnerClassesAttribute.of( - InnerClassInfo.of( - innerClassDesc, - Optional.of(outerClassDesc), - Optional.of(innerClassDesc.displayName()), - SYNTHETIC - ) - ) - ) - builder.noArgCtor() - conventions.forEach { convention -> - convention.apply(Mapper(MorphiaConfig.load()), builder, model) - } - model.fields().forEach {} - } + fun propertyAnnotations(): List { + return propertyAnnotations.map { it.descriptor } + } - println("**************** b = ${b.size}") - outputGenerated?.let { - val file = - File(outputGenerated, "${name.substringAfterLast("/").replace("$", "\\\$")}.class") - println("**************** file = ${file.absoluteFile}") - file.parentFile.mkdirs() - FileOutputStream(file).use { it.write(b) } - } - critterClassLoader.register(name.replace('/', '.'), b) - return critterClassLoader.loadClass(name.replace('/', '.')) + fun transientAnnotations(): List { + return transientAnnotations.map { it.descriptor } } } diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/Example.java b/critter/core/src/test/java/dev/morphia/critter/sources/Example.java new file mode 100644 index 00000000000..7f8aebf1940 --- /dev/null +++ b/critter/core/src/test/java/dev/morphia/critter/sources/Example.java @@ -0,0 +1,83 @@ +package dev.morphia.critter.sources; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.mongodb.client.model.CollationCaseFirst; + +import dev.morphia.annotations.AlsoLoad; +import dev.morphia.annotations.Collation; +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.EntityListeners; +import dev.morphia.annotations.Field; +import dev.morphia.annotations.Id; +import dev.morphia.annotations.Index; +import dev.morphia.annotations.IndexOptions; +import dev.morphia.annotations.Indexes; +import dev.morphia.annotations.Property; +import dev.morphia.annotations.Reference; +import dev.morphia.annotations.Transient; +import dev.morphia.mapping.lifecycle.EntityListenerAdapter; + +import org.bson.types.ObjectId; + +@Entity("examples") +@EntityListeners(EntityListenerAdapter.class) +@Indexes(@Index(fields = @Field(value = "name", weight = 42), options = @IndexOptions(partialFilter = "partial filter", collation = @Collation(caseFirst = CollationCaseFirst.LOWER)))) +public class Example { + @Id + private ObjectId id; + @Property(value = "myName") + @AlsoLoad({ "name1", "name2" }) + private String name; + + @Transient + @Reference + private final int[] temp = new int[0]; + + private Map map; + + private List> list; + + private Set> set; + + @Reference(idOnly = true) + private int age = 21; + + @Property + private Long salary = 2L; + + public String __readNameTemplate() { + return name; + } + + public void __writeNameTemplate(final String name) { + this.name = name; + } + + public int __readAgeTemplate() { + return age; + } + + public void __writeAgeTemplate(final int age) { + this.age = age; + } + + public Long __readSalaryTemplate() { + return salary; + } + + public void __writeSalaryTemplate(final Long salary) { + this.salary = salary; + } + + @Override + public String toString() { + return "Example{" + + "name='" + name + '\'' + + ", age=" + age + + ", salary=" + salary + + '}'; + } +} diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgeAccessorTemplate.java b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgeAccessorTemplate.java new file mode 100644 index 00000000000..5858b4cfb24 --- /dev/null +++ b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgeAccessorTemplate.java @@ -0,0 +1,14 @@ +package dev.morphia.critter.sources; + +import org.bson.codecs.pojo.PropertyAccessor; + +public class ExampleAgeAccessorTemplate implements PropertyAccessor { + @Override + public Integer get(S entity) { + return ((Example) entity).__readAgeTemplate(); + } + + public void set(S entity, Integer value) { + ((Example) entity).__writeAgeTemplate(value); + } +} diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgePropertyModelTemplate.java b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgePropertyModelTemplate.java new file mode 100644 index 00000000000..ca51b0607bf --- /dev/null +++ b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgePropertyModelTemplate.java @@ -0,0 +1,89 @@ +package dev.morphia.critter.sources; + +import java.util.List; + +import dev.morphia.mapping.codec.pojo.EntityModel; +import dev.morphia.mapping.codec.pojo.TypeData; +import dev.morphia.mapping.codec.pojo.critter.CritterPropertyModel; + +import org.bson.codecs.pojo.PropertyAccessor; + +public class ExampleAgePropertyModelTemplate extends CritterPropertyModel { + + private PropertyAccessor accessor = new ExampleAgeAccessorTemplate(); + + public ExampleAgePropertyModelTemplate(EntityModel entityModel) { + super(entityModel); + + } + + @Override + public PropertyAccessor getAccessor() { + return (PropertyAccessor) accessor; + } + + @Override + public boolean isFinal() { + return false; + } + + @Override + public String getFullName() { + return "dev.morphia.critter.sources.Example#age"; + } + + @Override + public List getLoadNames() { + return List.of(); + } + + @Override + public String getMappedName() { + return "age"; + } + + @Override + public String getName() { + return "age"; + } + + @Override + public Class getNormalizedType() { + return int.class; + } + + @Override + public Class getType() { + return int.class; + } + + @Override + public TypeData getTypeData() { + return TypeData.get(int.class); + } + + @Override + public boolean isArray() { + return false; + } + + @Override + public boolean isMap() { + return false; + } + + @Override + public boolean isReference() { + return false; + } + + @Override + public boolean isSet() { + return false; + } + + @Override + public boolean isTransient() { + return false; + } +} diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleEntityModelTemplate.java b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleEntityModelTemplate.java new file mode 100644 index 00000000000..64e7e8401f3 --- /dev/null +++ b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleEntityModelTemplate.java @@ -0,0 +1,131 @@ +package dev.morphia.critter.sources; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Set; + +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.internal.EntityBuilder; +import dev.morphia.mapping.Mapper; +import dev.morphia.mapping.codec.MorphiaInstanceCreator; +import dev.morphia.mapping.codec.pojo.EntityModel; +import dev.morphia.mapping.codec.pojo.PropertyModel; +import dev.morphia.mapping.codec.pojo.TypeData; +import dev.morphia.mapping.codec.pojo.critter.CritterEntityModel; +import dev.morphia.mapping.conventions.MorphiaDefaultsConvention; + +public class ExampleEntityModelTemplate extends CritterEntityModel { + + public ExampleEntityModelTemplate(Mapper mapper) { + super(mapper, Example.class); + addProperty(new ExampleNamePropertyModelTemplate(this)); + addProperty(new ExampleAgePropertyModelTemplate(this)); + addProperty(new ExampleSalaryPropertyModelTemplate(this)); + } + + @Override + public Set> classHierarchy() { + return Set.of(); + } + + @Override + public String collectionName() { + return mapper.getConfig().collectionNaming().apply("Example"); + } + + @Override + public List getShardKeys() { + return List.of(); + } + + @Override + public String discriminator() { + return mapper.getConfig().discriminator().apply(Example.class, "."); + } + + @Override + public String discriminatorKey() { + return MorphiaDefaultsConvention.applyDefaults(".", mapper.getConfig().discriminatorKey()); + } + + @Override + public Entity getEntityAnnotation() { + if (entityAnnotation == null) { + entityAnnotation = EntityBuilder + .entityBuilder(Example.class.getAnnotation(Entity.class)) + .build(); + } + return entityAnnotation; + } + + @Override + public PropertyModel getIdProperty() { + return null; + } + + @Override + public MorphiaInstanceCreator getInstanceCreator() { + return null; + } + + @Override + public List getProperties(Class type) { + return List.of(); + } + + @Override + public List getProperties() { + return List.of(); + } + + @Override + public Set getSubtypes() { + return Set.of(); + } + + @Override + public void addSubtype(EntityModel subtype) { + + } + + @Override + public EntityModel getSuperClass() { + return null; + } + + @Override + public Class getType() { + return Example.class; + } + + @Override + public TypeData getTypeData(Class type, TypeData suggested, Type genericType) { + return null; + } + + @Override + public PropertyModel getVersionProperty() { + return null; + } + + @Override + public boolean hasLifecycle(Class type) { + return false; + } + + @Override + public boolean isAbstract() { + return false; + } + + @Override + public boolean isInterface() { + return false; + } + + @Override + public boolean useDiscriminator() { + return true; + } +} diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleNameAccessorTemplate.java b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleNameAccessorTemplate.java new file mode 100644 index 00000000000..5e972da4ee2 --- /dev/null +++ b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleNameAccessorTemplate.java @@ -0,0 +1,15 @@ +package dev.morphia.critter.sources; + +import org.bson.codecs.pojo.PropertyAccessor; + +public class ExampleNameAccessorTemplate implements PropertyAccessor { + @Override + public String get(S entity) { + return ((Example) entity).__readNameTemplate(); + } + + @Override + public void set(S entity, String value) { + ((Example) entity).__writeNameTemplate(value); + } +} diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleNamePropertyModelTemplate.java b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleNamePropertyModelTemplate.java new file mode 100644 index 00000000000..3e44b6d12f3 --- /dev/null +++ b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleNamePropertyModelTemplate.java @@ -0,0 +1,97 @@ +package dev.morphia.critter.sources; + +import java.util.List; + +import dev.morphia.mapping.codec.pojo.EntityModel; +import dev.morphia.mapping.codec.pojo.TypeData; +import dev.morphia.mapping.codec.pojo.critter.CritterPropertyModel; + +import org.bson.codecs.pojo.PropertyAccessor; + +public class ExampleNamePropertyModelTemplate extends CritterPropertyModel { + + private PropertyAccessor accessor = new ExampleNameAccessorTemplate(); + + public ExampleNamePropertyModelTemplate(EntityModel entityModel) { + super(entityModel); + /* + * annotation(propertyBuilder() + * .value("myName") + * .concreteClass(String.class) + * .build()); + * annotation(alsoLoadBuilder() + * .value("name1", "name2") + * .build()); + */ + } + + @Override + public PropertyAccessor getAccessor() { + return (PropertyAccessor) accessor; + } + + @Override + public boolean isFinal() { + return false; + } + + @Override + public String getFullName() { + return "dev.morphia.critter.sources.Example#name"; + } + + @Override + public List getLoadNames() { + return List.of("name1", "name2"); + } + + @Override + public String getMappedName() { + return "myName"; + } + + @Override + public String getName() { + return "name"; + } + + @Override + public Class getNormalizedType() { + return String.class; + } + + @Override + public Class getType() { + return String.class; + } + + @Override + public TypeData getTypeData() { + return TypeData.get(String.class); + } + + @Override + public boolean isArray() { + return false; + } + + @Override + public boolean isMap() { + return false; + } + + @Override + public boolean isReference() { + return false; + } + + @Override + public boolean isSet() { + return false; + } + + @Override + public boolean isTransient() { + return false; + } +} diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryAccessorTemplate.java b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryAccessorTemplate.java new file mode 100644 index 00000000000..ff1451ef68b --- /dev/null +++ b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryAccessorTemplate.java @@ -0,0 +1,14 @@ +package dev.morphia.critter.sources; + +import org.bson.codecs.pojo.PropertyAccessor; + +public class ExampleSalaryAccessorTemplate implements PropertyAccessor { + @Override + public Long get(S entity) { + return ((Example) entity).__readSalaryTemplate(); + } + + public void set(S entity, Long value) { + ((Example) entity).__writeSalaryTemplate(value); + } +} diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryPropertyModelTemplate.java b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryPropertyModelTemplate.java new file mode 100644 index 00000000000..d1a3c8a350b --- /dev/null +++ b/critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryPropertyModelTemplate.java @@ -0,0 +1,92 @@ +package dev.morphia.critter.sources; + +import java.util.List; + +import dev.morphia.mapping.codec.pojo.EntityModel; +import dev.morphia.mapping.codec.pojo.TypeData; +import dev.morphia.mapping.codec.pojo.critter.CritterPropertyModel; + +import org.bson.codecs.pojo.PropertyAccessor; + +import static dev.morphia.annotations.internal.PropertyBuilder.propertyBuilder; + +public class ExampleSalaryPropertyModelTemplate extends CritterPropertyModel { + + private PropertyAccessor accessor = new ExampleSalaryAccessorTemplate(); + + public ExampleSalaryPropertyModelTemplate(EntityModel entityModel) { + super(entityModel); + annotation(propertyBuilder() + .build()); + } + + @Override + public PropertyAccessor getAccessor() { + return (PropertyAccessor) accessor; + } + + @Override + public boolean isFinal() { + return false; + } + + @Override + public String getFullName() { + return "dev.morphia.critter.sources.Example#salary"; + } + + @Override + public List getLoadNames() { + return List.of(); + } + + @Override + public String getMappedName() { + return "salary"; + } + + @Override + public String getName() { + return "salary"; + } + + @Override + public Class getNormalizedType() { + return Long.class; + } + + @Override + public Class getType() { + return Long.class; + } + + @Override + public TypeData getTypeData() { + return TypeData.get(Long.class); + } + + @Override + public boolean isArray() { + return false; + } + + @Override + public boolean isMap() { + return false; + } + + @Override + public boolean isReference() { + return false; + } + + @Override + public boolean isSet() { + return false; + } + + @Override + public boolean isTransient() { + return false; + } +} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/parser/BaseCritterTest.kt b/critter/core/src/test/kotlin/dev/morphia/critter/parser/BaseCritterTest.kt new file mode 100644 index 00000000000..30165117d66 --- /dev/null +++ b/critter/core/src/test/kotlin/dev/morphia/critter/parser/BaseCritterTest.kt @@ -0,0 +1,7 @@ +package dev.morphia.critter.parser + +import dev.morphia.mapping.codec.pojo.EntityModel + +open class BaseCritterTest { + var exampleEntityModel = EntityModel(String::class.java) // GeneratorTest.entityModel +} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/parser/GeneratorTest.kt b/critter/core/src/test/kotlin/dev/morphia/critter/parser/GeneratorTest.kt new file mode 100644 index 00000000000..34429bf82fc --- /dev/null +++ b/critter/core/src/test/kotlin/dev/morphia/critter/parser/GeneratorTest.kt @@ -0,0 +1,92 @@ +package dev.morphia.critter.parser + +import dev.morphia.critter.Critter.Companion.critterClassLoader +import dev.morphia.critter.parser.Generators.mapper +import dev.morphia.critter.parser.gizmo.CritterGizmoGenerator as generator +import dev.morphia.critter.parser.java.CritterParser.asmify +import dev.morphia.critter.sources.Example +import dev.morphia.mapping.codec.pojo.critter.CritterEntityModel +import io.github.classgraph.ClassGraph +import java.lang.reflect.Modifier +import org.objectweb.asm.Type + +object GeneratorTest { + var entityModel: CritterEntityModel + + init { + val classGraph = ClassGraph().addClassLoader(critterClassLoader).enableAllInfo() + classGraph.acceptPackages("dev.morphia.critter.sources") + + classGraph.scan().use { scanResult -> + for (classInfo in scanResult.allClasses) { + try { + val name = classInfo.name + critterClassLoader.dump(name) + } catch (_: Throwable) {} + } + } + val generator = generator.generate(Example::class.java) + + entityModel = + critterClassLoader + .loadClass(generator.generatedType) + .constructors[0] + .newInstance(mapper) as CritterEntityModel + } + + fun methodNames(clazz: Class<*>): Array> { + return methods(clazz) + .map { arrayOf(it.name, it) } + .sortedBy { it[0].toString() } + .toTypedArray() + } + + fun methods(clazz: Class<*>) = + clazz.methods + .filterNot { method -> Modifier.isFinal(method.modifiers) } + .filter { method -> method.parameterCount == 0 } + .filter { method -> method.declaringClass == clazz } + + fun process(resourceName: String, entity: Type, generated: Type): String { + var asm = asmify(critterClassLoader.getResourceAsStream(resourceName).readAllBytes()) + + val lines = asm.lines() + val imports = lines.filter { it.startsWith("import ") } + val pkg = + Regex("^(package )(?.*);\$").find(lines.first())!!.groups[2]!!.value + ".__morphia" + val body = + asm.substringAfter("{") + .substringBeforeLast("}") + .substringAfter("{") + .substringBeforeLast("}") + var header = body.substringBefore("{") + val methods = extractMethodDefinitions(body).map { bind(it) }.toMap(LinkedHashMap()) + return "" + // return "package ;"}\n" + + // lines.drop(1) + // .map { it.replace("dev/morphia/critter/sources/ExampleEntityModel", + // "generatedType.internalName") } + // .joinToString("\n") + //// .replace() + } + + private fun bind(methodBody: String): Pair { + fun extractMethodName(line: String): String { + return line.split("\"")[1] + } + + val lines = methodBody.lines().drop(1).dropLast(1) + + return extractMethodName(lines.first()) to lines.joinToString("\n") + } + + private fun extractMethodDefinitions(body: String): List { + val methodBody = body.substring(body.indexOf('{')).lines().toMutableList() + var methods = listOf() + while (methodBody.first().startsWith("{")) { + methods += methodBody.removeWhile { it.trim() != "}" } + } + + return methods + } +} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/parser/KspJvmMain.kt b/critter/core/src/test/kotlin/dev/morphia/critter/parser/KspJvmMain.kt deleted file mode 100644 index fb86a8fc724..00000000000 --- a/critter/core/src/test/kotlin/dev/morphia/critter/parser/KspJvmMain.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.morphia.critter.parser - -import dev.morphia.critter.Critter -import java.io.File - -fun main() { - Critter(File(".", "critter/core").canonicalFile) - .process() -} - diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestAccessorsMutators.kt b/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestAccessorsMutators.kt new file mode 100644 index 00000000000..c8c9194fa7e --- /dev/null +++ b/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestAccessorsMutators.kt @@ -0,0 +1,58 @@ +package dev.morphia.critter.parser + +import dev.morphia.critter.Critter.Companion.critterClassLoader +import dev.morphia.critter.Critter.Companion.critterPackage +import dev.morphia.critter.parser.java.CritterClassLoader +import dev.morphia.critter.sources.Example +import dev.morphia.critter.titleCase +import org.bson.codecs.pojo.PropertyAccessor +import org.testng.Assert.assertEquals +import org.testng.Assert.assertTrue +import org.testng.annotations.DataProvider + +class TestAccessorsMutators : BaseCritterTest() { + // @Test(dataProvider = "classes") + fun testPropertyAccessors(type: Class<*>) { + val testFields = + listOf( + listOf("name", String::class.java, "set externally"), + listOf("age", Int::class.java, 100), + listOf("salary", java.lang.Long::class.java, 100_000L) + ) + + val entity = critterClassLoader.loadClass(type.name).getConstructor().newInstance() + + testFields.forEach { field -> + testAccessor(type, critterClassLoader, entity, field[0] as String, field[2]) + } + } + + @Suppress("UNCHECKED_CAST") + private fun testAccessor( + type: Class<*>, + critterClassLoader: CritterClassLoader, + entity: Any, + fieldName: String, + testValue: Any, + ) { + val accessor = + (critterClassLoader.loadClass( + "${critterPackage(type)}${type.simpleName}${fieldName.titleCase()}Accessor" + ) as Class>) + .getConstructor() + .newInstance() + + accessor.set(entity, testValue) + + assertEquals(accessor.get(entity), testValue) + assertTrue( + entity.toString().contains(testValue.toString()), + "Could not find '$testValue` in :${entity}" + ) + } + + @DataProvider(name = "classes") + fun names(): Array> { + return arrayOf(Example::class.java /*, KotlinDummyEntity::class.java*/) + } +} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestEntityModelGenerator.kt b/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestEntityModelGenerator.kt new file mode 100644 index 00000000000..9f85511f9d5 --- /dev/null +++ b/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestEntityModelGenerator.kt @@ -0,0 +1,43 @@ +package dev.morphia.critter.parser + +import dev.morphia.critter.Critter.Companion.critterClassLoader +import dev.morphia.critter.parser.GeneratorTest.entityModel +import dev.morphia.critter.parser.GeneratorTest.methodNames +import dev.morphia.mapping.Mapper +import dev.morphia.mapping.codec.pojo.critter.CritterEntityModel +import java.lang.reflect.Method +import org.testng.Assert.assertEquals +import org.testng.annotations.DataProvider +import org.testng.annotations.NoInjection + +class TestEntityModelGenerator { + val control: CritterEntityModel + val mapper = Mapper(Generators.config) + + init { + control = + critterClassLoader + .loadClass("dev.morphia.critter.sources.ExampleEntityModelTemplate") + .getConstructor(Mapper::class.java) + .newInstance(mapper) as CritterEntityModel + critterClassLoader.dump("dev.morphia.critter.sources.ExampleEntityModelTemplate") + } + + // @Test(dataProvider = "methods") + fun testEntityModel(name: String, @NoInjection method: Method) { + val expected = method.invoke(control) + val actual = method.invoke(entityModel) + assertEquals(actual, expected, "${method.name} should return the same value") + } + + @DataProvider(name = "methods") fun methods() = methodNames(CritterEntityModel::class.java) +} + +fun MutableList.removeWhile(function: (String) -> Boolean): kotlin.String { + val removed = mutableListOf() + while (isNotEmpty() && function(first())) { + removed += removeFirst() + } + + return (removed + removeFirst()).joinToString("\n") +} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestParsing.kt b/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestParsing.kt deleted file mode 100644 index e457642446a..00000000000 --- a/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestParsing.kt +++ /dev/null @@ -1,71 +0,0 @@ -package dev.morphia.critter.parser - -import dev.morphia.critter.parser.java.CritterParser -import java.io.File -import java.lang.reflect.Method -import org.testng.annotations.DataProvider -import org.testng.annotations.Test - -class TestParsing { - init { - System.setProperty("org.openrewrite.adapt.dumpClass", "true") - } - - @Test(dataProvider = "sources") - fun basicClass(file: File) { - CritterParser.outputGenerated = File("target/basicClass/") - val klass = CritterParser.parser(file) - val newInstance = klass.newInstance() - println("**************** klass::class.java = ${newInstance::class.java}") - klass.declaredMethods.forEach { method -> - val message = method.invoke(newInstance) - println(message) - } - // assertEquals(klass.name, "BasicClass") - } - /* - @Test(enabled = false, description = "dead end test. might revive later.") - fun testCreateClass() { - val s = "i'm manually created" - val sub = object : CritterEntityModel(Mapper(MorphiaConfig.load()), JavaBasicClass::class.java) { - override fun getEntityAnnotation(): Entity { - val entity = entityBuilder() - .value(s) - .build() - - return entity - } - } - val subName = sub.javaClass.name.replace('.', '/') + ".class" - val resourceAsStream = javaClass.classLoader.getResourceAsStream(subName) - - resourceAsStream?.use { input -> - val cl = object : ClassLoader("critter", getSystemClassLoader()) { - override fun findClass(name: String?): Class<*> { - val buffer = input.readBytes() - return defineClass(name, buffer, 0, buffer.size) - } - } - val loadClass = cl.loadClass(sub.javaClass.name) - loadClass - } - } - */ - - @DataProvider - fun sources(testMethod: Method): Array { - val name = testMethod.name.titleCase() - - return arrayOf(load(name, "Java") /*, load(name, "Kotlin")*/) - } - - private fun load(name: String, type: String): File { - val resource = "/dev/morphia/critter/sources/$type$name.class" - val url = javaClass.getResource(resource) ?: throw AssertionError("$resource not found") - return File(url.file) - } - - private fun String.titleCase(): String { - return first().uppercase() + substring(1) - } -} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestPropertyModelGenerator.kt b/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestPropertyModelGenerator.kt new file mode 100644 index 00000000000..4cb713799a2 --- /dev/null +++ b/critter/core/src/test/kotlin/dev/morphia/critter/parser/TestPropertyModelGenerator.kt @@ -0,0 +1,46 @@ +package dev.morphia.critter.parser + +import dev.morphia.critter.Critter.Companion.critterClassLoader +import dev.morphia.critter.parser.GeneratorTest.entityModel +import dev.morphia.critter.parser.GeneratorTest.methodNames +import dev.morphia.mapping.codec.pojo.EntityModel +import dev.morphia.mapping.codec.pojo.PropertyModel +import dev.morphia.mapping.codec.pojo.critter.CritterPropertyModel +import java.lang.reflect.Method +import org.testng.Assert.assertEquals +import org.testng.annotations.DataProvider +import org.testng.annotations.NoInjection + +class TestPropertyModelGenerator : BaseCritterTest() { + // @Test(dataProvider = "properties", testName = "") + fun testProperty(control: String, methodName: String, @NoInjection method: Method) { + val propertyModel = getModel(control) + + println("exampleModel = [${control}], methodName = [${methodName}], method = [${method}]") + val expected = method.invoke(control) + val actual = method.invoke(propertyModel) + assertEquals(actual, expected, "${method.name} should return the same value") + } + + private fun getModel(name: String): CritterPropertyModel { + return entityModel.getProperty(name) as CritterPropertyModel + } + + @DataProvider(name = "properties") + fun methods(): Array> { + val methods = methodNames(CritterPropertyModel::class.java) + return listOf("dev.morphia.critter.sources.ExampleNamePropertyModelTemplate") + .map { loadModel(it) } + .flatMap { propertyModel -> + methods.map { method -> arrayOf(propertyModel.name, method[0], method[1]) } + } + .toTypedArray() + } + + private fun loadModel(type: String): PropertyModel { + return critterClassLoader + .loadClass(type) + .getConstructor(EntityModel::class.java) + .newInstance(entityModel) as PropertyModel + } +} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.kt b/critter/core/src/test/kotlin/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.kt new file mode 100644 index 00000000000..4e3594e5aee --- /dev/null +++ b/critter/core/src/test/kotlin/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.kt @@ -0,0 +1,310 @@ +package dev.morphia.critter.parser.gizmo + +import com.mongodb.client.model.CollationCaseFirst.LOWER +import dev.morphia.annotations.Entity +import dev.morphia.annotations.EntityListeners +import dev.morphia.annotations.Indexes +import dev.morphia.annotations.internal.CollationBuilder.collationBuilder +import dev.morphia.annotations.internal.EntityBuilder.entityBuilder +import dev.morphia.annotations.internal.EntityListenersBuilder.entityListenersBuilder +import dev.morphia.annotations.internal.FieldBuilder.fieldBuilder +import dev.morphia.annotations.internal.IndexBuilder.indexBuilder +import dev.morphia.annotations.internal.IndexOptionsBuilder.indexOptionsBuilder +import dev.morphia.annotations.internal.IndexesBuilder.indexesBuilder +import dev.morphia.critter.Critter.Companion.critterClassLoader +import dev.morphia.critter.parser.Generators.mapper +import dev.morphia.critter.parser.gizmo.CritterGizmoGenerator as generator +import dev.morphia.critter.sources.Example +import dev.morphia.mapping.codec.pojo.EntityModel +import dev.morphia.mapping.codec.pojo.PropertyModel +import dev.morphia.mapping.codec.pojo.TypeData +import dev.morphia.mapping.lifecycle.EntityListenerAdapter +import io.quarkus.gizmo.ClassCreator +import io.quarkus.gizmo.MethodDescriptor +import io.quarkus.gizmo.MethodDescriptor.ofMethod +import java.lang.reflect.Modifier +import kotlin.reflect.KClass +import org.objectweb.asm.Type +import org.objectweb.asm.tree.AnnotationNode +import org.testng.Assert.assertEquals +import org.testng.Assert.assertFalse +import org.testng.Assert.assertNotNull +import org.testng.Assert.assertTrue +import org.testng.Assert.fail +import org.testng.annotations.Test + +class TestGizmoGeneration { + @Test + fun testMapStringExample() { + var descString = "Ljava/util/Map;" + var descriptor = + descriptor( + Map::class.java, + descriptor(String::class.java), + descriptor(Example::class.java) + ) + + assertEquals(descriptor, descString) + var typeData = typeData(descString)[0] + assertEquals( + typeData, + Map::class.typeData(String::class.typeData(), Example::class.typeData()) + ) + } + + @Test + fun testListMapStringExample() { + val descString = + "Ljava/util/List;>;" + val descriptor = + descriptor( + List::class.java, + descriptor( + Map::class.java, + descriptor(String::class.java), + descriptor(Example::class.java) + ) + ) + assertEquals(descriptor, descString) + + val typeData = typeData(descString)[0] + assertEquals( + typeData, + List::class.typeData( + Map::class.typeData(String::class.typeData(), Example::class.typeData()) + ) + ) + } + + @Test + fun testMapOfList() { + val descString = + "Ljava/util/Map;>;" + val descriptor = + descriptor( + Map::class.java, + descriptor(String::class.java), + descriptor(List::class.java, descriptor(Example::class.java)) + ) + assertEquals(descriptor, descString) + val typeData = typeData(descriptor)[0] + assertEquals( + typeData, + Map::class.typeData( + String::class.typeData(), + List::class.typeData(Example::class.typeData()) + ) + ) + } + + @Test + fun testPrimitiveArray() { + val typeData = typeData("[I")[0] + assertTrue(typeData.array) + } + + private fun descriptor(type: Class<*>, vararg typeParameters: String): String { + var desc = Type.getDescriptor(type) + if (typeParameters.isNotEmpty()) { + desc = + desc.dropLast(1) + + typeParameters.joinToString("", prefix = "<", postfix = ">") + + ";" + } + + return desc + } + + private fun KClass<*>.typeData(vararg typeParameters: TypeData<*>): TypeData<*> { + return TypeData(this.java, listOf(*typeParameters)) + } + + @Test + fun testAnnotationBuilding() { + val index = AnnotationNode("Ldev/morphia/annotations/Index;") + val field = AnnotationNode("Ldev/morphia/annotations/Field;") + // field.values = listOf("value", "name") + index.values = listOf("fields", listOf(field)) + ClassCreator.builder() + .className("critter.AnnotationTest") + .superClass(EntityModel::class.java) + .classOutput { name, data -> critterClassLoader.register(name.replace('/', '.'), data) } + .build() + .use { + val creator = it.getMethodCreator("test", Void::class.java) + val annotationMethod = + ofMethod( + EntityModel::class.java.name, + "annotation", + EntityModel::class.java.name, + Annotation::class.java + ) + + creator.invokeVirtualMethod( + annotationMethod, + creator.`this`, + index.annotationBuilder(creator) + ) + } + } + + @Test + fun testGizmo() { + generator.generate(Example::class.java) + critterClassLoader.loadClass("dev.morphia.critter.sources.__morphia.example.AgeModel") + val nameModel = + critterClassLoader.loadClass("dev.morphia.critter.sources.__morphia.example.NameModel") + invokeAll(PropertyModel::class.java, nameModel) + critterClassLoader.loadClass("dev.morphia.critter.sources.__morphia.example.SalaryModel") + critterClassLoader + .loadClass("dev.morphia.critter.sources.__morphia.example.AgeAccessor") + .getConstructor() + .newInstance() + critterClassLoader + .loadClass("dev.morphia.critter.sources.__morphia.example.NameAccessor") + .getConstructor() + .newInstance() + critterClassLoader + .loadClass("dev.morphia.critter.sources.__morphia.example.SalaryAccessor") + .getConstructor() + .newInstance() + val loadClass = + critterClassLoader.loadClass( + "dev.morphia.critter.sources.__morphia.example.ExampleEntityModel" + ) + val constructors = loadClass.constructors + val model: EntityModel = constructors[0].newInstance(mapper) as EntityModel + validate(model) + } + + private fun validate(model: EntityModel) { + val annotation = model.getAnnotation(EntityListeners::class.java) + assertEquals( + annotation, + entityListenersBuilder().value(EntityListenerAdapter::class.java).build() + ) + + assertEquals( + model.getAnnotation(Entity::class.java), + entityBuilder().value("examples").build() + ) + + assertEquals( + model.getAnnotation(Indexes::class.java), + indexesBuilder() + .value( + indexBuilder() + .fields(fieldBuilder().value("name").weight(42).build()) + .options( + indexOptionsBuilder() + .partialFilter("partial filter") + .collation(collationBuilder().caseFirst(LOWER).build()) + .build() + ) + .build() + ) + .build() + ) + + assertEquals(model.collectionName(), "examples") + assertEquals(model.discriminator(), "Example") + assertEquals(model.discriminatorKey(), "_t") + assertEquals(model.type.name, Example::class.java.name) + assertFalse(model.properties.isEmpty(), "Should have properties") + assertNotNull(model.idProperty, "Should have an ID property") + assertFalse(model.isAbstract(), "Should not be abstract") + assertFalse(model.isInterface(), "Should not be an interface") + assertTrue(model.useDiscriminator(), "Should use the discriminator") + assertTrue(model.classHierarchy().isEmpty(), "Should not have a class hierarchy") + } + + private fun invokeAll(type: Class<*>, klass: Class<*>) { + val instance = klass.constructors[0].newInstance(null) + val results = + type.declaredMethods + .filter { + Modifier.isPublic(it.modifiers) && + !Modifier.isFinal(it.modifiers) && + it.parameterCount == 0 + } + .filter { it.name !in listOf("hashCode", "toString") } + .sortedBy { it.name } + .map { method -> + try { + klass.getDeclaredMethod(method.name, *method.parameterTypes) + null + } catch (e: Exception) { + e.message + } + } + .filterNotNull() + + if (results.isNotEmpty()) { + fail("Missing methods from ${type.name}: \n${results.joinToString("\n")}") + } + } + + @Test + fun testConstructors() { + val className = "dev.morphia.critter.GizmoSubclass" + val constructorCall = + ClassCreator.builder() + .classOutput { name, data -> + critterClassLoader.register(name.replace('/', '.'), data) + } + .className("dev.morphia.critter.ConstructorCall") + .build() + val fieldCreator = + constructorCall + .getFieldCreator("name", String::class.java) + .setModifiers(Modifier.PUBLIC) + val constructorCreator = constructorCall.getConstructorCreator(String::class.java) + constructorCreator.invokeSpecialMethod( + MethodDescriptor.ofConstructor(Object::class.java), + constructorCreator.`this` + ) + constructorCreator.setParameterNames(arrayOf("name")) + constructorCreator.writeInstanceField( + fieldCreator.fieldDescriptor, + constructorCreator.`this`, + constructorCreator.getMethodParam(0) + ) + + constructorCreator.returnVoid() + constructorCall.close() + val newInstance = + critterClassLoader + .loadClass("dev.morphia.critter.ConstructorCall") + .getConstructor(String::class.java) + .newInstance("here i am") + + val creator = + ClassCreator.builder() + .classOutput { name, data -> + critterClassLoader.register(name.replace('/', '.'), data) + } + .className(className) + .superClass("dev.morphia.critter.ConstructorCall") + .build() + val constructor = creator.getConstructorCreator(String::class.java) + constructor.invokeSpecialMethod( + MethodDescriptor.ofConstructor( + "dev.morphia.critter.ConstructorCall", + String::class.java + ), + constructor.getThis(), + constructor.getMethodParam(0) + ) + constructor.setParameterNames(arrayOf("subName")) + constructor.returnVoid() + constructor.close() + creator.close() + val instance = + critterClassLoader + .loadClass(className) + .getConstructor(String::class.java) + .newInstance("This is my name") + + assertNotNull(instance) + } +} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/sources/JavaBasicClass.java b/critter/core/src/test/kotlin/dev/morphia/critter/sources/JavaBasicClass.java deleted file mode 100644 index 1c82b62a282..00000000000 --- a/critter/core/src/test/kotlin/dev/morphia/critter/sources/JavaBasicClass.java +++ /dev/null @@ -1,21 +0,0 @@ -package dev.morphia.critter.sources; - -import dev.morphia.annotations.Entity; -import org.jetbrains.annotations.NotNull; - -@Entity(value = "basicJava", useDiscriminator = false) -public class JavaBasicClass { - public JavaBasicClass() { - } - - public String nothing() { - return "hi"; - } - - @NotNull - public boolean useDiscriminator() { - return false; - } - - public Integer imAMethodYo(){ return 0;} -} \ No newline at end of file diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/sources/KotlinBasicClass.kt b/critter/core/src/test/kotlin/dev/morphia/critter/sources/KotlinBasicClass.kt deleted file mode 100644 index 4e9d3ef057d..00000000000 --- a/critter/core/src/test/kotlin/dev/morphia/critter/sources/KotlinBasicClass.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.morphia.critter.sources - -import dev.morphia.annotations.Entity - -@Entity(value = "basicKotlin ", useDiscriminator = false) -class KotlinBasicClass { - var count = 42 -} diff --git a/critter/core/src/test/kotlin/dev/morphia/critter/sources/OuterClass.java b/critter/core/src/test/kotlin/dev/morphia/critter/sources/OuterClass.java deleted file mode 100644 index 0009ec3c209..00000000000 --- a/critter/core/src/test/kotlin/dev/morphia/critter/sources/OuterClass.java +++ /dev/null @@ -1,10 +0,0 @@ -package dev.morphia.critter.sources; - -public class OuterClass { - - public class InnerClass { - public String innerMethod() { - return "hi"; - } - } -} diff --git a/critter/core/src/test/resources/logback-test.xml b/critter/core/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..25b91634a7a --- /dev/null +++ b/critter/core/src/test/resources/logback-test.xml @@ -0,0 +1,22 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{40} - %msg%n + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/critter/pom.xml b/critter/pom.xml index 9625d0d5352..40988367992 100644 --- a/critter/pom.xml +++ b/critter/pom.xml @@ -17,24 +17,8 @@ true - true - - - - dev.morphia.morphia - morphia-core - ${project.version} - - - org.jetbrains.kotlin - kotlin-stdlib - ${kotlin.version} - - - - core diff --git a/design/GeneratedCode.adoc b/design/GeneratedCode.adoc index 96b32d97add..25f558d02d0 100644 --- a/design/GeneratedCode.adoc +++ b/design/GeneratedCode.adoc @@ -42,4 +42,4 @@ Not every project will need or want them. . It's been on the issues list for a while but, perhaps in light of the last point, generate index builders, validation builders, etc. for each entity type. -This would solve the configuration problem of trying to specify *all* of that in a pom file. +This would solve the configuration problem of trying to specify *TestPositional* of that in a pom file. diff --git a/docs/modules/ROOT/examples/complete-morphia-config.properties b/docs/modules/ROOT/examples/complete-morphia-config.properties index 1989217a202..a7278be201d 100644 --- a/docs/modules/ROOT/examples/complete-morphia-config.properties +++ b/docs/modules/ROOT/examples/complete-morphia-config.properties @@ -50,6 +50,10 @@ morphia.ignore-finals=false ###### morphia.packages=.* ###### +# default=dev.morphia.config.MorphiaPropertyAnnotationProvider +###### +morphia.property-annotation-providers=dev.morphia.config.MorphiaPropertyAnnotationProvider +###### # default=fields # possible values=fields, methods ###### diff --git a/docs/modules/ROOT/pages/aggregation-expressions.adoc b/docs/modules/ROOT/pages/aggregation-expressions.adoc index 3720262c583..b8d876ed165 100644 --- a/docs/modules/ROOT/pages/aggregation-expressions.adoc +++ b/docs/modules/ROOT/pages/aggregation-expressions.adoc @@ -1,560 +1,865 @@ -[%header,cols="1,2"] +[%header,cols="1,2,3"] |=== -|Operator|Docs +|Operator|Docs|Test Examples | http://docs.mongodb.org/manual/reference/operator/aggregation/abs[$abs] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#abs(java.lang.Object)[MathExpressions#abs(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAbs.java[TestAbs] + | http://docs.mongodb.org/manual/reference/operator/aggregation/accumulator[$accumulator] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#accumulator(java.lang.String,java.lang.String,java.util.List,java.lang.String)[AccumulatorExpressions#accumulator(String,String,List,String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAccumulator.java[TestAccumulator] + | http://docs.mongodb.org/manual/reference/operator/aggregation/acos[$acos] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#acos(java.lang.Object)[TrigonometryExpressions#acos(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcos.java[TestAcos] + | http://docs.mongodb.org/manual/reference/operator/aggregation/acosh[$acosh] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#acosh(java.lang.Object)[TrigonometryExpressions#acosh(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAcosh.java[TestAcosh] + | http://docs.mongodb.org/manual/reference/operator/aggregation/add[$add] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#add(java.lang.Object,java.lang.Object%2E%2E%2E)[MathExpressions#add(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAdd.java[TestAdd] + | http://docs.mongodb.org/manual/reference/operator/aggregation/addToSet[$addToSet] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#addToSet(java.lang.Object)[AccumulatorExpressions#addToSet(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAddToSet.java[TestAddToSet] + | http://docs.mongodb.org/manual/reference/operator/aggregation/allElementsTrue[$allElementsTrue] | link:javadoc/dev/morphia/aggregation/expressions/SetExpressions.html#allElementsTrue(java.lang.Object,java.lang.Object%2E%2E%2E)[SetExpressions#allElementsTrue(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAllElementsTrue.java[TestAllElementsTrue] -| http://docs.mongodb.org/manual/reference/operator/aggregation/and[$and] -a| - * link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#and(java.lang.Object,java.lang.Object%2E%2E%2E)[BooleanExpressions#and(Object,Object...)] - * link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#and()[BooleanExpressions#and()] +| http://docs.mongodb.org/manual/reference/operator/aggregation/and[$and] +a| link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#and(java.lang.Object,java.lang.Object%2E%2E%2E)[BooleanExpressions#and(Object,Object...)] + +link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#and()[BooleanExpressions#and()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnd.java[TestAnd] | http://docs.mongodb.org/manual/reference/operator/aggregation/anyElementTrue[$anyElementTrue] | link:javadoc/dev/morphia/aggregation/expressions/SetExpressions.html#anyElementTrue(java.lang.Object,java.lang.Object%2E%2E%2E)[SetExpressions#anyElementTrue(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAnyElementTrue.java[TestAnyElementTrue] + | http://docs.mongodb.org/manual/reference/operator/aggregation/arrayElemAt[$arrayElemAt] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#elementAt(java.lang.Object,java.lang.Object)[ArrayExpressions#elementAt(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayElemAt.java[TestArrayElemAt] + | http://docs.mongodb.org/manual/reference/operator/aggregation/arrayToObject[$arrayToObject] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#arrayToObject(java.lang.Object)[ArrayExpressions#arrayToObject(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestArrayToObject.java[TestArrayToObject] + | http://docs.mongodb.org/manual/reference/operator/aggregation/asin[$asin] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#asin(java.lang.Object)[TrigonometryExpressions#asin(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsin.java[TestAsin] + | http://docs.mongodb.org/manual/reference/operator/aggregation/asinh[$asinh] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#asinh(java.lang.Object)[TrigonometryExpressions#asinh(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAsinh.java[TestAsinh] + | http://docs.mongodb.org/manual/reference/operator/aggregation/atan[$atan] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#atan(java.lang.Object)[TrigonometryExpressions#atan(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan.java[TestAtan] + | http://docs.mongodb.org/manual/reference/operator/aggregation/atan2[$atan2] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#atan2(java.lang.Object,java.lang.Object)[TrigonometryExpressions#atan2(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtan2.java[TestAtan2] + | http://docs.mongodb.org/manual/reference/operator/aggregation/atanh[$atanh] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#atanh(java.lang.Object)[TrigonometryExpressions#atanh(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAtanh.java[TestAtanh] + | http://docs.mongodb.org/manual/reference/operator/aggregation/avg[$avg] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#avg(java.lang.Object,java.lang.Object%2E%2E%2E)[AccumulatorExpressions#avg(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestAvg.java[TestAvg] + | http://docs.mongodb.org/manual/reference/operator/aggregation/binarySize[$binarySize] | link:javadoc/dev/morphia/aggregation/expressions/DataSizeExpressions.html#binarySize(java.lang.Object)[DataSizeExpressions#binarySize(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBinarySize.java[TestBinarySize] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bitAnd[$bitAnd] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#bitAnd(java.lang.Object,java.lang.Object)[MathExpressions#bitAnd(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitAnd.java[TestBitAnd] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bitNot[$bitNot] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#bitNot(java.lang.Object)[MathExpressions#bitNot(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitNot.java[TestBitNot] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bitOr[$bitOr] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#bitOr(java.lang.Object,java.lang.Object)[MathExpressions#bitOr(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitOr.java[TestBitOr] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bitXor[$bitXor] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#bitXor(java.lang.Object,java.lang.Object)[MathExpressions#bitXor(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBitXor.java[TestBitXor] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bottom[$bottom] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#bottom(java.lang.Object,dev.morphia.query.Sort%2E%2E%2E)[AccumulatorExpressions#bottom(Object,Sort...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottom.java[TestBottom] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bottomN[$bottomN] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#bottomN(java.lang.Object,java.lang.Object,dev.morphia.query.Sort%2E%2E%2E)[AccumulatorExpressions#bottomN(Object,Object,Sort...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBottomN.java[TestBottomN] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bsonSize[$bsonSize] | link:javadoc/dev/morphia/aggregation/expressions/DataSizeExpressions.html#bsonSize(java.lang.Object)[DataSizeExpressions#bsonSize(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestBsonSize.java[TestBsonSize] + | http://docs.mongodb.org/manual/reference/operator/aggregation/ceil[$ceil] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#ceil(java.lang.Object)[MathExpressions#ceil(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCeil.java[TestCeil] + | http://docs.mongodb.org/manual/reference/operator/aggregation/cmp[$cmp] | link:javadoc/dev/morphia/aggregation/expressions/ComparisonExpressions.html#cmp(java.lang.Object,java.lang.Object)[ComparisonExpressions#cmp(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCmp.java[TestCmp] + | http://docs.mongodb.org/manual/reference/operator/aggregation/concat[$concat] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#concat(java.lang.Object,java.lang.Object%2E%2E%2E)[StringExpressions#concat(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcat.java[TestConcat] + | http://docs.mongodb.org/manual/reference/operator/aggregation/concatArrays[$concatArrays] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#concatArrays(java.lang.Object,java.lang.Object%2E%2E%2E)[ArrayExpressions#concatArrays(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConcatArrays.java[TestConcatArrays] + | http://docs.mongodb.org/manual/reference/operator/aggregation/cond[$cond] | link:javadoc/dev/morphia/aggregation/expressions/ConditionalExpressions.html#condition(java.lang.Object,java.lang.Object,java.lang.Object)[ConditionalExpressions#condition(Object,Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCond.java[TestCond] + | http://docs.mongodb.org/manual/reference/operator/aggregation/convert[$convert] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#convert(java.lang.Object,dev.morphia.aggregation.expressions.impls.ConvertType)[TypeExpressions#convert(Object,ConvertType)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestConvert.java[TestConvert] + | http://docs.mongodb.org/manual/reference/operator/aggregation/cos[$cos] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#cos(java.lang.Object)[TrigonometryExpressions#cos(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCos.java[TestCos] + | http://docs.mongodb.org/manual/reference/operator/aggregation/cosh[$cosh] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#cosh(java.lang.Object)[TrigonometryExpressions#cosh(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCosh.java[TestCosh] + | http://docs.mongodb.org/manual/reference/operator/aggregation/count[$count] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#count()[AccumulatorExpressions#count()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCount.java[TestCount] + | http://docs.mongodb.org/manual/reference/operator/aggregation/covariancePop[$covariancePop] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#covariancePop(java.lang.Object,java.lang.Object)[WindowExpressions#covariancePop(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovariancePop.java[TestCovariancePop] + | http://docs.mongodb.org/manual/reference/operator/aggregation/covarianceSamp[$covarianceSamp] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#covarianceSamp(java.lang.Object,java.lang.Object)[WindowExpressions#covarianceSamp(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestCovarianceSamp.java[TestCovarianceSamp] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dateAdd[$dateAdd] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dateAdd(java.lang.Object,long,dev.morphia.aggregation.expressions.TimeUnit)[DateExpressions#dateAdd(Object,long,TimeUnit)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateAdd.java[TestDateAdd] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dateDiff[$dateDiff] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dateDiff(java.lang.Object,java.lang.Object,dev.morphia.aggregation.expressions.TimeUnit)[DateExpressions#dateDiff(Object,Object,TimeUnit)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateDiff.java[TestDateDiff] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dateFromParts[$dateFromParts] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dateFromParts()[DateExpressions#dateFromParts()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromParts.java[TestDateFromParts] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dateFromString[$dateFromString] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dateFromString()[DateExpressions#dateFromString()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateFromString.java[TestDateFromString] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dateSubtract[$dateSubtract] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dateSubtract(java.lang.Object,long,dev.morphia.aggregation.expressions.TimeUnit)[DateExpressions#dateSubtract(Object,long,TimeUnit)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateSubtract.java[TestDateSubtract] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dateToParts[$dateToParts] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dateToParts(java.lang.Object)[DateExpressions#dateToParts(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToParts.java[TestDateToParts] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dateToString[$dateToString] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dateToString()[DateExpressions#dateToString()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateToString.java[TestDateToString] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dateTrunc[$dateTrunc] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dateTrunc(java.lang.Object,dev.morphia.aggregation.expressions.TimeUnit)[DateExpressions#dateTrunc(Object,TimeUnit)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDateTrunc.java[TestDateTrunc] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfMonth[$dayOfMonth] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dayOfMonth(java.lang.Object)[DateExpressions#dayOfMonth(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfMonth.java[TestDayOfMonth] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfWeek[$dayOfWeek] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dayOfWeek(java.lang.Object)[DateExpressions#dayOfWeek(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfWeek.java[TestDayOfWeek] + | http://docs.mongodb.org/manual/reference/operator/aggregation/dayOfYear[$dayOfYear] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#dayOfYear(java.lang.Object)[DateExpressions#dayOfYear(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDayOfYear.java[TestDayOfYear] + | http://docs.mongodb.org/manual/reference/operator/aggregation/degreesToRadians[$degreesToRadians] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#degreesToRadians(java.lang.Object)[TrigonometryExpressions#degreesToRadians(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDegreesToRadians.java[TestDegreesToRadians] + | http://docs.mongodb.org/manual/reference/operator/aggregation/denseRank[$denseRank] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#denseRank()[WindowExpressions#denseRank()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDenseRank.java[TestDenseRank] + | http://docs.mongodb.org/manual/reference/operator/aggregation/derivative[$derivative] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#derivative(java.lang.Object)[WindowExpressions#derivative(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDerivative.java[TestDerivative] + | http://docs.mongodb.org/manual/reference/operator/aggregation/divide[$divide] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#divide(java.lang.Object,java.lang.Object)[MathExpressions#divide(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDivide.java[TestDivide] + | http://docs.mongodb.org/manual/reference/operator/aggregation/documentNumber[$documentNumber] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#documentNumber()[WindowExpressions#documentNumber()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestDocumentNumber.java[TestDocumentNumber] + | http://docs.mongodb.org/manual/reference/operator/aggregation/eq[$eq] | link:javadoc/dev/morphia/aggregation/expressions/ComparisonExpressions.html#eq(java.lang.Object,java.lang.Object)[ComparisonExpressions#eq(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestEq.java[TestEq] + | http://docs.mongodb.org/manual/reference/operator/aggregation/exp[$exp] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#exp(java.lang.Object)[MathExpressions#exp(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExp.java[TestExp] -| http://docs.mongodb.org/manual/reference/operator/aggregation/expMovingAvg[$expMovingAvg] -a| - * link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#expMovingAvg(java.lang.Object,int)[WindowExpressions#expMovingAvg(Object,int)] - * link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#expMovingAvg(java.lang.Object,double)[WindowExpressions#expMovingAvg(Object,double)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/expMovingAvg[$expMovingAvg] +a| link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#expMovingAvg(java.lang.Object,int)[WindowExpressions#expMovingAvg(Object,int)] + +link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#expMovingAvg(java.lang.Object,double)[WindowExpressions#expMovingAvg(Object,double)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestExpMovingAvg.java[TestExpMovingAvg] | http://docs.mongodb.org/manual/reference/operator/aggregation/filter[$filter] | link:javadoc/dev/morphia/aggregation/expressions/Expressions.html#filter(java.lang.Object,java.lang.Object)[Expressions#filter(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFilter.java[TestFilter] + | http://docs.mongodb.org/manual/reference/operator/aggregation/first[$first] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#first(java.lang.Object)[AccumulatorExpressions#first(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirst.java[TestFirst] + | http://docs.mongodb.org/manual/reference/operator/aggregation/firstN[$firstN] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#firstN(java.lang.Object,java.lang.Object)[AccumulatorExpressions#firstN(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFirstN.java[TestFirstN] + | http://docs.mongodb.org/manual/reference/operator/aggregation/floor[$floor] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#floor(java.lang.Object)[MathExpressions#floor(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFloor.java[TestFloor] + | http://docs.mongodb.org/manual/reference/operator/aggregation/function[$function] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#function(java.lang.String,java.lang.Object%2E%2E%2E)[AccumulatorExpressions#function(String,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestFunction.java[TestFunction] -| http://docs.mongodb.org/manual/reference/operator/aggregation/getField[$getField] -a| - * link:javadoc/dev/morphia/aggregation/expressions/Miscellaneous.html#getField(java.lang.String)[Miscellaneous#getField(String)] - * link:javadoc/dev/morphia/aggregation/expressions/Miscellaneous.html#getField(java.lang.Object)[Miscellaneous#getField(Object)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/getField[$getField] +a| link:javadoc/dev/morphia/aggregation/expressions/Miscellaneous.html#getField(java.lang.String)[Miscellaneous#getField(String)] + +link:javadoc/dev/morphia/aggregation/expressions/Miscellaneous.html#getField(java.lang.Object)[Miscellaneous#getField(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGetField.java[TestGetField] | http://docs.mongodb.org/manual/reference/operator/aggregation/gt[$gt] | link:javadoc/dev/morphia/aggregation/expressions/ComparisonExpressions.html#gt(java.lang.Object,java.lang.Object)[ComparisonExpressions#gt(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGt.java[TestGt] + | http://docs.mongodb.org/manual/reference/operator/aggregation/gte[$gte] | link:javadoc/dev/morphia/aggregation/expressions/ComparisonExpressions.html#gte(java.lang.Object,java.lang.Object)[ComparisonExpressions#gte(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestGte.java[TestGte] + | http://docs.mongodb.org/manual/reference/operator/aggregation/hour[$hour] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#hour(java.lang.Object)[DateExpressions#hour(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestHour.java[TestHour] + | http://docs.mongodb.org/manual/reference/operator/aggregation/ifNull[$ifNull] | link:javadoc/dev/morphia/aggregation/expressions/ConditionalExpressions.html#ifNull()[ConditionalExpressions#ifNull()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIfNull.java[TestIfNull] + | http://docs.mongodb.org/manual/reference/operator/aggregation/in[$in] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#in(java.lang.Object,java.lang.Object)[ArrayExpressions#in(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIn.java[TestIn] + | http://docs.mongodb.org/manual/reference/operator/aggregation/indexOfArray[$indexOfArray] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#indexOfArray(java.lang.Object,java.lang.Object)[ArrayExpressions#indexOfArray(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfArray.java[TestIndexOfArray] + | http://docs.mongodb.org/manual/reference/operator/aggregation/indexOfBytes[$indexOfBytes] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#indexOfBytes(java.lang.Object,java.lang.Object)[StringExpressions#indexOfBytes(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfBytes.java[TestIndexOfBytes] + | http://docs.mongodb.org/manual/reference/operator/aggregation/indexOfCP[$indexOfCP] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#indexOfCP(java.lang.Object,java.lang.Object)[StringExpressions#indexOfCP(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIndexOfCP.java[TestIndexOfCP] + | http://docs.mongodb.org/manual/reference/operator/aggregation/integral[$integral] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#integral(java.lang.Object)[WindowExpressions#integral(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIntegral.java[TestIntegral] + | http://docs.mongodb.org/manual/reference/operator/aggregation/isArray[$isArray] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#isArray(java.lang.Object)[ArrayExpressions#isArray(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsArray.java[TestIsArray] + | http://docs.mongodb.org/manual/reference/operator/aggregation/isNumber[$isNumber] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#isNumber(java.lang.Object)[TypeExpressions#isNumber(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsNumber.java[TestIsNumber] + | http://docs.mongodb.org/manual/reference/operator/aggregation/isoDayOfWeek[$isoDayOfWeek] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#isoDayOfWeek(java.lang.Object)[DateExpressions#isoDayOfWeek(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoDayOfWeek.java[TestIsoDayOfWeek] + | http://docs.mongodb.org/manual/reference/operator/aggregation/isoWeek[$isoWeek] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#isoWeek(java.lang.Object)[DateExpressions#isoWeek(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeek.java[TestIsoWeek] + | http://docs.mongodb.org/manual/reference/operator/aggregation/isoWeekYear[$isoWeekYear] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#isoWeekYear(java.lang.Object)[DateExpressions#isoWeekYear(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestIsoWeekYear.java[TestIsoWeekYear] + | http://docs.mongodb.org/manual/reference/operator/aggregation/last[$last] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#last(java.lang.Object)[AccumulatorExpressions#last(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLast.java[TestLast] + | http://docs.mongodb.org/manual/reference/operator/aggregation/lastN[$lastN] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#lastN(java.lang.Object,java.lang.Object)[AccumulatorExpressions#lastN(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLastN.java[TestLastN] + | http://docs.mongodb.org/manual/reference/operator/aggregation/let[$let] | link:javadoc/dev/morphia/aggregation/expressions/VariableExpressions.html#let(dev.morphia.aggregation.expressions.impls.Expression)[VariableExpressions#let(Expression)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLet.java[TestLet] + | http://docs.mongodb.org/manual/reference/operator/aggregation/linearFill[$linearFill] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#linearFill(java.lang.Object)[WindowExpressions#linearFill(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLinearFill.java[TestLinearFill] + | http://docs.mongodb.org/manual/reference/operator/aggregation/literal[$literal] | link:javadoc/dev/morphia/aggregation/expressions/Expressions.html#literal(java.lang.Object)[Expressions#literal(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLiteral.java[TestLiteral] + | http://docs.mongodb.org/manual/reference/operator/aggregation/ln[$ln] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#ln(java.lang.Object)[MathExpressions#ln(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLn.java[TestLn] + | http://docs.mongodb.org/manual/reference/operator/aggregation/locf[$locf] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#locf(java.lang.Object)[WindowExpressions#locf(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLocf.java[TestLocf] + | http://docs.mongodb.org/manual/reference/operator/aggregation/log[$log] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#log(java.lang.Object,java.lang.Object)[MathExpressions#log(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog.java[TestLog] + | http://docs.mongodb.org/manual/reference/operator/aggregation/log10[$log10] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#log10(java.lang.Object)[MathExpressions#log10(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLog10.java[TestLog10] + | http://docs.mongodb.org/manual/reference/operator/aggregation/lt[$lt] | link:javadoc/dev/morphia/aggregation/expressions/ComparisonExpressions.html#lt(java.lang.Object,java.lang.Object)[ComparisonExpressions#lt(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLt.java[TestLt] + | http://docs.mongodb.org/manual/reference/operator/aggregation/lte[$lte] | link:javadoc/dev/morphia/aggregation/expressions/ComparisonExpressions.html#lte(java.lang.Object,java.lang.Object)[ComparisonExpressions#lte(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLte.java[TestLte] + | http://docs.mongodb.org/manual/reference/operator/aggregation/ltrim[$ltrim] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#ltrim(java.lang.Object)[StringExpressions#ltrim(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestLtrim.java[TestLtrim] + | http://docs.mongodb.org/manual/reference/operator/aggregation/map[$map] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#map(java.lang.Object,java.lang.Object)[ArrayExpressions#map(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMap.java[TestMap] + | http://docs.mongodb.org/manual/reference/operator/aggregation/max[$max] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#max(java.lang.Object,java.lang.Object%2E%2E%2E)[AccumulatorExpressions#max(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMax.java[TestMax] + | http://docs.mongodb.org/manual/reference/operator/aggregation/maxN[$maxN] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#maxN(java.lang.Object,java.lang.Object)[AccumulatorExpressions#maxN(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMaxN.java[TestMaxN] + | http://docs.mongodb.org/manual/reference/operator/aggregation/median[$median] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#median(java.lang.Object)[MathExpressions#median(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMedian.java[TestMedian] + | http://docs.mongodb.org/manual/reference/operator/aggregation/mergeObjects[$mergeObjects] | link:javadoc/dev/morphia/aggregation/expressions/ObjectExpressions.html#mergeObjects()[ObjectExpressions#mergeObjects()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMergeObjects.java[TestMergeObjects] -| http://docs.mongodb.org/manual/reference/operator/aggregation/meta[$meta] -a| - * link:javadoc/dev/morphia/aggregation/expressions/Expressions.html#meta()[Expressions#meta()] - * link:javadoc/dev/morphia/aggregation/expressions/Expressions.html#meta(dev.morphia.aggregation.expressions.MetadataKeyword.MetadataKeyword)[Expressions#meta(MetadataKeyword)] - * link:javadoc/dev/morphia/query/Meta.html#indexKey(java.lang.String)[Meta#indexKey(String)] - * link:javadoc/dev/morphia/query/Meta.html#searchHighlights(java.lang.String)[Meta#searchHighlights(String)] - * link:javadoc/dev/morphia/query/Meta.html#searchScore(java.lang.String)[Meta#searchScore(String)] - * link:javadoc/dev/morphia/query/Meta.html#textScore(java.lang.String)[Meta#textScore(String)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/meta[$meta] +a| link:javadoc/dev/morphia/aggregation/expressions/Expressions.html#meta()[Expressions#meta()] + +link:javadoc/dev/morphia/aggregation/expressions/Expressions.html#meta(dev.morphia.aggregation.expressions.MetadataKeyword.MetadataKeyword)[Expressions#meta(MetadataKeyword)] + +link:javadoc/dev/morphia/query/Meta.html#indexKey(java.lang.String)[Meta#indexKey(String)] + +link:javadoc/dev/morphia/query/Meta.html#searchHighlights(java.lang.String)[Meta#searchHighlights(String)] + +link:javadoc/dev/morphia/query/Meta.html#searchScore(java.lang.String)[Meta#searchScore(String)] + +link:javadoc/dev/morphia/query/Meta.html#textScore(java.lang.String)[Meta#textScore(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMeta.java[TestMeta] | http://docs.mongodb.org/manual/reference/operator/aggregation/millisecond[$millisecond] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#milliseconds(java.lang.Object)[DateExpressions#milliseconds(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMillisecond.java[TestMillisecond] + | http://docs.mongodb.org/manual/reference/operator/aggregation/min[$min] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#min(java.lang.Object,java.lang.Object%2E%2E%2E)[AccumulatorExpressions#min(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMin.java[TestMin] + | http://docs.mongodb.org/manual/reference/operator/aggregation/minN[$minN] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#minN(java.lang.Object,java.lang.Object)[AccumulatorExpressions#minN(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinN.java[TestMinN] + | http://docs.mongodb.org/manual/reference/operator/aggregation/minute[$minute] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#minute(java.lang.Object)[DateExpressions#minute(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMinute.java[TestMinute] + | http://docs.mongodb.org/manual/reference/operator/aggregation/mod[$mod] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#mod(java.lang.Object,java.lang.Object)[MathExpressions#mod(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMod.java[TestMod] + | http://docs.mongodb.org/manual/reference/operator/aggregation/month[$month] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#month(java.lang.Object)[DateExpressions#month(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMonth.java[TestMonth] + | http://docs.mongodb.org/manual/reference/operator/aggregation/multiply[$multiply] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#multiply(java.lang.Object,java.lang.Object%2E%2E%2E)[MathExpressions#multiply(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestMultiply.java[TestMultiply] + | http://docs.mongodb.org/manual/reference/operator/aggregation/ne[$ne] | link:javadoc/dev/morphia/aggregation/expressions/ComparisonExpressions.html#ne(java.lang.Object,java.lang.Object)[ComparisonExpressions#ne(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNe.java[TestNe] + | http://docs.mongodb.org/manual/reference/operator/aggregation/not[$not] | link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#not(java.lang.Object)[BooleanExpressions#not(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestNot.java[TestNot] + | http://docs.mongodb.org/manual/reference/operator/aggregation/objectToArray[$objectToArray] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#objectToArray(java.lang.Object)[ArrayExpressions#objectToArray(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestObjectToArray.java[TestObjectToArray] -| http://docs.mongodb.org/manual/reference/operator/aggregation/or[$or] -a| - * link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#or(java.lang.Object,java.lang.Object%2E%2E%2E)[BooleanExpressions#or(Object,Object...)] - * link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#or()[BooleanExpressions#or()] +| http://docs.mongodb.org/manual/reference/operator/aggregation/or[$or] +a| link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#or(java.lang.Object,java.lang.Object%2E%2E%2E)[BooleanExpressions#or(Object,Object...)] + +link:javadoc/dev/morphia/aggregation/expressions/BooleanExpressions.html#or()[BooleanExpressions#or()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestOr.java[TestOr] | http://docs.mongodb.org/manual/reference/operator/aggregation/percentile[$percentile] -a| - - * link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#percentile(java.lang.Object,java.util.List)[MathExpressions#percentile(Object,List)] - * link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#percentile(java.util.List,java.util.List)[MathExpressions#percentile(List,List)] +a| link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#percentile(java.lang.Object,java.util.List)[MathExpressions#percentile(Object,List)] + +link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#percentile(java.util.List,java.util.List)[MathExpressions#percentile(List,List)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPercentile.java[TestPercentile] | http://docs.mongodb.org/manual/reference/operator/aggregation/pow[$pow] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#pow(java.lang.Object,java.lang.Object)[MathExpressions#pow(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPow.java[TestPow] -| http://docs.mongodb.org/manual/reference/operator/aggregation/push[$push] -a| - * link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#push(java.lang.Object)[AccumulatorExpressions#push(Object)] - * link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#push()[AccumulatorExpressions#push()] +| http://docs.mongodb.org/manual/reference/operator/aggregation/push[$push] +a| link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#push(java.lang.Object)[AccumulatorExpressions#push(Object)] + +link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#push()[AccumulatorExpressions#push()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestPush.java[TestPush] | http://docs.mongodb.org/manual/reference/operator/aggregation/radiansToDegrees[$radiansToDegrees] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#radiansToDegrees(java.lang.Object)[TrigonometryExpressions#radiansToDegrees(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRadiansToDegrees.java[TestRadiansToDegrees] + | http://docs.mongodb.org/manual/reference/operator/aggregation/rand[$rand] | link:javadoc/dev/morphia/aggregation/expressions/Miscellaneous.html#rand()[Miscellaneous#rand()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRand.java[TestRand] -| http://docs.mongodb.org/manual/reference/operator/aggregation/range[$range] -a| - * link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#range(int,int)[ArrayExpressions#range(int,int)] - * link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#range(java.lang.Object,java.lang.Object)[ArrayExpressions#range(Object,Object)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/range[$range] +a| link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#range(int,int)[ArrayExpressions#range(int,int)] + +link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#range(java.lang.Object,java.lang.Object)[ArrayExpressions#range(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRange.java[TestRange] | http://docs.mongodb.org/manual/reference/operator/aggregation/rank[$rank] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#rank()[WindowExpressions#rank()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRank.java[TestRank] + | http://docs.mongodb.org/manual/reference/operator/aggregation/reduce[$reduce] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#reduce(java.lang.Object,java.lang.Object,java.lang.Object)[ArrayExpressions#reduce(Object,Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReduce.java[TestReduce] + | http://docs.mongodb.org/manual/reference/operator/aggregation/regexFind[$regexFind] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#regexFind(java.lang.Object)[StringExpressions#regexFind(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFind.java[TestRegexFind] + | http://docs.mongodb.org/manual/reference/operator/aggregation/regexFindAll[$regexFindAll] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#regexFindAll(java.lang.Object)[StringExpressions#regexFindAll(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexFindAll.java[TestRegexFindAll] + | http://docs.mongodb.org/manual/reference/operator/aggregation/regexMatch[$regexMatch] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#regexMatch(java.lang.Object)[StringExpressions#regexMatch(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRegexMatch.java[TestRegexMatch] + | http://docs.mongodb.org/manual/reference/operator/aggregation/replaceAll[$replaceAll] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#replaceAll(java.lang.Object,java.lang.Object,java.lang.Object)[StringExpressions#replaceAll(Object,Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceAll.java[TestReplaceAll] + | http://docs.mongodb.org/manual/reference/operator/aggregation/replaceOne[$replaceOne] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#replaceOne(java.lang.Object,java.lang.Object,java.lang.Object)[StringExpressions#replaceOne(Object,Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReplaceOne.java[TestReplaceOne] + | http://docs.mongodb.org/manual/reference/operator/aggregation/reverseArray[$reverseArray] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#reverseArray(java.lang.Object)[ArrayExpressions#reverseArray(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestReverseArray.java[TestReverseArray] + | http://docs.mongodb.org/manual/reference/operator/aggregation/round[$round] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#round(java.lang.Object,java.lang.Object)[MathExpressions#round(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRound.java[TestRound] + | http://docs.mongodb.org/manual/reference/operator/aggregation/rtrim[$rtrim] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#rtrim(java.lang.Object)[StringExpressions#rtrim(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestRtrim.java[TestRtrim] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sampleRate[$sampleRate] | link:javadoc/dev/morphia/aggregation/expressions/Miscellaneous.html#sampleRate(double)[Miscellaneous#sampleRate(double)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSampleRate.java[TestSampleRate] + | http://docs.mongodb.org/manual/reference/operator/aggregation/second[$second] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#second(java.lang.Object)[DateExpressions#second(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSecond.java[TestSecond] + | http://docs.mongodb.org/manual/reference/operator/aggregation/setDifference[$setDifference] | link:javadoc/dev/morphia/aggregation/expressions/SetExpressions.html#setDifference(java.lang.Object,java.lang.Object)[SetExpressions#setDifference(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetDifference.java[TestSetDifference] + | http://docs.mongodb.org/manual/reference/operator/aggregation/setEquals[$setEquals] | link:javadoc/dev/morphia/aggregation/expressions/SetExpressions.html#setEquals(java.lang.Object,java.lang.Object%2E%2E%2E)[SetExpressions#setEquals(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetEquals.java[TestSetEquals] + | http://docs.mongodb.org/manual/reference/operator/aggregation/setField[$setField] | link:javadoc/dev/morphia/aggregation/expressions/Miscellaneous.html#setField(java.lang.Object,java.lang.Object,java.lang.Object)[Miscellaneous#setField(Object,Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetField.java[TestSetField] + | http://docs.mongodb.org/manual/reference/operator/aggregation/setIntersection[$setIntersection] | link:javadoc/dev/morphia/aggregation/expressions/SetExpressions.html#setIntersection(java.lang.Object,java.lang.Object%2E%2E%2E)[SetExpressions#setIntersection(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIntersection.java[TestSetIntersection] + | http://docs.mongodb.org/manual/reference/operator/aggregation/setIsSubset[$setIsSubset] | link:javadoc/dev/morphia/aggregation/expressions/SetExpressions.html#setIsSubset(java.lang.Object,java.lang.Object)[SetExpressions#setIsSubset(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetIsSubset.java[TestSetIsSubset] + | http://docs.mongodb.org/manual/reference/operator/aggregation/setUnion[$setUnion] | link:javadoc/dev/morphia/aggregation/expressions/SetExpressions.html#setUnion(java.lang.Object,java.lang.Object%2E%2E%2E)[SetExpressions#setUnion(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSetUnion.java[TestSetUnion] + | http://docs.mongodb.org/manual/reference/operator/aggregation/shift[$shift] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#shift(java.lang.Object,long,java.lang.Object)[WindowExpressions#shift(Object,long,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestShift.java[TestShift] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sin[$sin] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#sin(java.lang.Object)[TrigonometryExpressions#sin(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSin.java[TestSin] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sinh[$sinh] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#sinh(java.lang.Object)[TrigonometryExpressions#sinh(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSinh.java[TestSinh] + | http://docs.mongodb.org/manual/reference/operator/aggregation/size[$size] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#size(java.lang.Object)[ArrayExpressions#size(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSize.java[TestSize] + | http://docs.mongodb.org/manual/reference/operator/aggregation/slice[$slice] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#slice(java.lang.Object,int)[ArrayExpressions#slice(Object,int)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSlice.java[TestSlice] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sortArray[$sortArray] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#sortArray(java.lang.Object,dev.morphia.query.Sort%2E%2E%2E)[ArrayExpressions#sortArray(Object,Sort...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSortArray.java[TestSortArray] + | http://docs.mongodb.org/manual/reference/operator/aggregation/split[$split] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#split(java.lang.Object,java.lang.Object)[StringExpressions#split(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSplit.java[TestSplit] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sqrt[$sqrt] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#sqrt(java.lang.Object)[MathExpressions#sqrt(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSqrt.java[TestSqrt] + | http://docs.mongodb.org/manual/reference/operator/aggregation/stdDevPop[$stdDevPop] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#stdDevPop(java.lang.Object,java.lang.Object%2E%2E%2E)[WindowExpressions#stdDevPop(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevPop.java[TestStdDevPop] + | http://docs.mongodb.org/manual/reference/operator/aggregation/stdDevSamp[$stdDevSamp] | link:javadoc/dev/morphia/aggregation/expressions/WindowExpressions.html#stdDevSamp(java.lang.Object,java.lang.Object%2E%2E%2E)[WindowExpressions#stdDevSamp(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStdDevSamp.java[TestStdDevSamp] + | http://docs.mongodb.org/manual/reference/operator/aggregation/strLenBytes[$strLenBytes] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#strLenBytes(java.lang.Object)[StringExpressions#strLenBytes(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenBytes.java[TestStrLenBytes] + | http://docs.mongodb.org/manual/reference/operator/aggregation/strLenCP[$strLenCP] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#strLenCP(java.lang.Object)[StringExpressions#strLenCP(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrLenCP.java[TestStrLenCP] + | http://docs.mongodb.org/manual/reference/operator/aggregation/strcasecmp[$strcasecmp] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#strcasecmp(java.lang.Object,java.lang.Object)[StringExpressions#strcasecmp(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestStrcasecmp.java[TestStrcasecmp] -| http://docs.mongodb.org/manual/reference/operator/aggregation/substrBytes[$substrBytes] -a| - * link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#substrBytes(java.lang.Object,int,int)[StringExpressions#substrBytes(Object,int,int)] - * link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#substrBytes(java.lang.Object,java.lang.Object,java.lang.Object)[StringExpressions#substrBytes(Object,Object,Object)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/substrBytes[$substrBytes] +a| link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#substrBytes(java.lang.Object,int,int)[StringExpressions#substrBytes(Object,int,int)] + +link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#substrBytes(java.lang.Object,java.lang.Object,java.lang.Object)[StringExpressions#substrBytes(Object,Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrBytes.java[TestSubstrBytes] | http://docs.mongodb.org/manual/reference/operator/aggregation/substrCP[$substrCP] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#substrCP(java.lang.Object,java.lang.Object,java.lang.Object)[StringExpressions#substrCP(Object,Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubstrCP.java[TestSubstrCP] + | http://docs.mongodb.org/manual/reference/operator/aggregation/subtract[$subtract] | link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#subtract(java.lang.Object,java.lang.Object)[MathExpressions#subtract(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSubtract.java[TestSubtract] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sum[$sum] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#sum(java.lang.Object,java.lang.Object%2E%2E%2E)[AccumulatorExpressions#sum(Object,Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSum.java[TestSum] + | http://docs.mongodb.org/manual/reference/operator/aggregation/switch[$switch] | link:javadoc/dev/morphia/aggregation/expressions/ConditionalExpressions.html#switchExpression()[ConditionalExpressions#switchExpression()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestSwitch.java[TestSwitch] + | http://docs.mongodb.org/manual/reference/operator/aggregation/tan[$tan] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#tan(java.lang.Object)[TrigonometryExpressions#tan(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTan.java[TestTan] + | http://docs.mongodb.org/manual/reference/operator/aggregation/tanh[$tanh] | link:javadoc/dev/morphia/aggregation/expressions/TrigonometryExpressions.html#tanh(java.lang.Object)[TrigonometryExpressions#tanh(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTanh.java[TestTanh] + | http://docs.mongodb.org/manual/reference/operator/aggregation/toBool[$toBool] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#toBool(java.lang.Object)[TypeExpressions#toBool(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToBool.java[TestToBool] + | http://docs.mongodb.org/manual/reference/operator/aggregation/toDate[$toDate] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#toDate(java.lang.Object)[DateExpressions#toDate(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDate.java[TestToDate] + | http://docs.mongodb.org/manual/reference/operator/aggregation/toDecimal[$toDecimal] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#toDecimal(java.lang.Object)[TypeExpressions#toDecimal(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDecimal.java[TestToDecimal] + | http://docs.mongodb.org/manual/reference/operator/aggregation/toDouble[$toDouble] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#toDouble(java.lang.Object)[TypeExpressions#toDouble(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToDouble.java[TestToDouble] + | http://docs.mongodb.org/manual/reference/operator/aggregation/toInt[$toInt] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#toInt(java.lang.Object)[TypeExpressions#toInt(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToInt.java[TestToInt] + | http://docs.mongodb.org/manual/reference/operator/aggregation/toLong[$toLong] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#toLong(java.lang.Object)[TypeExpressions#toLong(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLong.java[TestToLong] + | http://docs.mongodb.org/manual/reference/operator/aggregation/toLower[$toLower] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#toLower(java.lang.Object)[StringExpressions#toLower(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToLower.java[TestToLower] + | http://docs.mongodb.org/manual/reference/operator/aggregation/toObjectId[$toObjectId] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#toObjectId(java.lang.Object)[TypeExpressions#toObjectId(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToObjectId.java[TestToObjectId] -| http://docs.mongodb.org/manual/reference/operator/aggregation/toString[$toString] -a| - * link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#toString(java.lang.Object)[StringExpressions#toString(Object)] - * link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#toString(java.lang.Object)[TypeExpressions#toString(Object)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/toString[$toString] +a| link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#toString(java.lang.Object)[StringExpressions#toString(Object)] + +link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#toString(java.lang.Object)[TypeExpressions#toString(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToString.java[TestToString] | http://docs.mongodb.org/manual/reference/operator/aggregation/toUpper[$toUpper] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#toUpper(java.lang.Object)[StringExpressions#toUpper(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestToUpper.java[TestToUpper] + | http://docs.mongodb.org/manual/reference/operator/aggregation/top[$top] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#top(java.lang.Object,dev.morphia.query.Sort%2E%2E%2E)[AccumulatorExpressions#top(Object,Sort...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTop.java[TestTop] + | http://docs.mongodb.org/manual/reference/operator/aggregation/topN[$topN] | link:javadoc/dev/morphia/aggregation/expressions/AccumulatorExpressions.html#topN(java.lang.Object,java.lang.Object,dev.morphia.query.Sort%2E%2E%2E)[AccumulatorExpressions#topN(Object,Object,Sort...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTopN.java[TestTopN] + | http://docs.mongodb.org/manual/reference/operator/aggregation/trim[$trim] | link:javadoc/dev/morphia/aggregation/expressions/StringExpressions.html#trim(java.lang.Object)[StringExpressions#trim(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrim.java[TestTrim] -| http://docs.mongodb.org/manual/reference/operator/aggregation/trunc[$trunc] -a| - * link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#trunc(java.lang.Object)[MathExpressions#trunc(Object)] - * link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#trunc(java.lang.Object,java.lang.Object)[MathExpressions#trunc(Object,Object)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/trunc[$trunc] +a| link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#trunc(java.lang.Object)[MathExpressions#trunc(Object)] + +link:javadoc/dev/morphia/aggregation/expressions/MathExpressions.html#trunc(java.lang.Object,java.lang.Object)[MathExpressions#trunc(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTrunc.java[TestTrunc] | http://docs.mongodb.org/manual/reference/operator/aggregation/tsIncrement[$tsIncrement] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#tsIncrement(java.lang.Object)[DateExpressions#tsIncrement(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsIncrement.java[TestTsIncrement] + | http://docs.mongodb.org/manual/reference/operator/aggregation/tsSecond[$tsSecond] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#tsSecond(java.lang.Object)[DateExpressions#tsSecond(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestTsSecond.java[TestTsSecond] + | http://docs.mongodb.org/manual/reference/operator/aggregation/type[$type] | link:javadoc/dev/morphia/aggregation/expressions/TypeExpressions.html#type(java.lang.Object)[TypeExpressions#type(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestType.java[TestType] + | http://docs.mongodb.org/manual/reference/operator/aggregation/unsetField[$unsetField] | link:javadoc/dev/morphia/aggregation/expressions/Miscellaneous.html#unsetField(java.lang.Object,java.lang.Object)[Miscellaneous#unsetField(Object,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestUnsetField.java[TestUnsetField] + | http://docs.mongodb.org/manual/reference/operator/aggregation/week[$week] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#week(java.lang.Object)[DateExpressions#week(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestWeek.java[TestWeek] + | http://docs.mongodb.org/manual/reference/operator/aggregation/year[$year] | link:javadoc/dev/morphia/aggregation/expressions/DateExpressions.html#year(java.lang.Object)[DateExpressions#year(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestYear.java[TestYear] + | http://docs.mongodb.org/manual/reference/operator/aggregation/zip[$zip] | link:javadoc/dev/morphia/aggregation/expressions/ArrayExpressions.html#zip(java.lang.Object%2E%2E%2E)[ArrayExpressions#zip(Object...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/expressions/TestZip.java[TestZip] + |=== diff --git a/docs/modules/ROOT/pages/aggregation-stages.adoc b/docs/modules/ROOT/pages/aggregation-stages.adoc index b3c22075918..7b741ad306b 100644 --- a/docs/modules/ROOT/pages/aggregation-stages.adoc +++ b/docs/modules/ROOT/pages/aggregation-stages.adoc @@ -1,138 +1,186 @@ -[%header,cols="1,2"] +[%header,cols="1,2,3"] |=== -|Operator|Docs +|Operator|Docs|Test Examples | http://docs.mongodb.org/manual/reference/operator/aggregation/addFields[$addFields] | link:javadoc/dev/morphia/aggregation/stages/AddFields.html#addFields()[AddFields#addFields()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestAddFields.java[TestAddFields] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bucket[$bucket] | link:javadoc/dev/morphia/aggregation/stages/Bucket.html#bucket()[Bucket#bucket()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucket.java[TestBucket] + | http://docs.mongodb.org/manual/reference/operator/aggregation/bucketAuto[$bucketAuto] | link:javadoc/dev/morphia/aggregation/stages/AutoBucket.html#autoBucket()[AutoBucket#autoBucket()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestBucketAuto.java[TestBucketAuto] + | http://docs.mongodb.org/manual/reference/operator/aggregation/changeStream[$changeStream] | link:javadoc/dev/morphia/aggregation/stages/ChangeStream.html#changeStream()[ChangeStream#changeStream()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestChangeStream.java[TestChangeStream] + | http://docs.mongodb.org/manual/reference/operator/aggregation/collStats[$collStats] | link:javadoc/dev/morphia/aggregation/stages/CollectionStats.html#collStats()[CollectionStats#collStats()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestCollStats.java[TestCollStats] + | http://docs.mongodb.org/manual/reference/operator/aggregation/count[$count] | link:javadoc/dev/morphia/aggregation/stages/Count.html#count(java.lang.String)[Count#count(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestCount.java[TestCount] + | http://docs.mongodb.org/manual/reference/operator/aggregation/currentOp[$currentOp] | link:javadoc/dev/morphia/aggregation/stages/CurrentOp.html#currentOp()[CurrentOp#currentOp()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestCurrentOp.java[TestCurrentOp] + | http://docs.mongodb.org/manual/reference/operator/aggregation/densify[$densify] | link:javadoc/dev/morphia/aggregation/stages/Densify.html#densify(java.lang.String,dev.morphia.aggregation.stages.Range)[Densify#densify(String,Range)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestDensify.java[TestDensify] + | http://docs.mongodb.org/manual/reference/operator/aggregation/documents[$documents] | link:javadoc/dev/morphia/aggregation/stages/Documents.html#documents(dev.morphia.aggregation.expressions.impls.DocumentExpression%2E%2E%2E)[Documents#documents(DocumentExpression...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestDocuments.java[TestDocuments] + | http://docs.mongodb.org/manual/reference/operator/aggregation/facet[$facet] | link:javadoc/dev/morphia/aggregation/stages/Facet.html#facet()[Facet#facet()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestFacet.java[TestFacet] + | http://docs.mongodb.org/manual/reference/operator/aggregation/fill[$fill] | link:javadoc/dev/morphia/aggregation/stages/Fill.html#fill()[Fill#fill()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestFill.java[TestFill] -| http://docs.mongodb.org/manual/reference/operator/aggregation/geoNear[$geoNear] -a| - * link:javadoc/dev/morphia/aggregation/stages/GeoNear.html#geoNear(java.lang.String)[GeoNear#geoNear(String)] - * link:javadoc/dev/morphia/aggregation/stages/GeoNear.html#geoNear(com.mongodb.client.model.geojson.Point)[GeoNear#geoNear(Point)] - * link:javadoc/dev/morphia/aggregation/stages/GeoNear.html#geoNear(double)[GeoNear#geoNear(double)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/geoNear[$geoNear] +a| link:javadoc/dev/morphia/aggregation/stages/GeoNear.html#geoNear(java.lang.String)[GeoNear#geoNear(String)] + +link:javadoc/dev/morphia/aggregation/stages/GeoNear.html#geoNear(com.mongodb.client.model.geojson.Point)[GeoNear#geoNear(Point)] + +link:javadoc/dev/morphia/aggregation/stages/GeoNear.html#geoNear(double)[GeoNear#geoNear(double)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestGeoNear.java[TestGeoNear] | http://docs.mongodb.org/manual/reference/operator/aggregation/graphLookup[$graphLookup] -a| - - * link:javadoc/dev/morphia/aggregation/stages/GraphLookup.html#graphLookup(java.lang.String)[GraphLookup#graphLookup(String)] - * link:javadoc/dev/morphia/aggregation/stages/GraphLookup.html#graphLookup(java.lang.Class)[GraphLookup#graphLookup(Class)] +a| link:javadoc/dev/morphia/aggregation/stages/GraphLookup.html#graphLookup(java.lang.String)[GraphLookup#graphLookup(String)] + +link:javadoc/dev/morphia/aggregation/stages/GraphLookup.html#graphLookup(java.lang.Class)[GraphLookup#graphLookup(Class)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestGraphLookup.java[TestGraphLookup] | http://docs.mongodb.org/manual/reference/operator/aggregation/group[$group] -a| - - * link:javadoc/dev/morphia/aggregation/stages/Group.html#group(dev.morphia.aggregation.stages.GroupId)[Group#group(GroupId)] - * link:javadoc/dev/morphia/aggregation/stages/Group.html#group()[Group#group()] +a| link:javadoc/dev/morphia/aggregation/stages/Group.html#group(dev.morphia.aggregation.stages.GroupId)[Group#group(GroupId)] + +link:javadoc/dev/morphia/aggregation/stages/Group.html#group()[Group#group()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestGroup.java[TestGroup] | http://docs.mongodb.org/manual/reference/operator/aggregation/indexStats[$indexStats] | link:javadoc/dev/morphia/aggregation/stages/IndexStats.html#indexStats()[IndexStats#indexStats()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestIndexStats.java[TestIndexStats] + | http://docs.mongodb.org/manual/reference/operator/aggregation/limit[$limit] | link:javadoc/dev/morphia/aggregation/stages/Limit.html#limit(long)[Limit#limit(long)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestLimit.java[TestLimit] -| http://docs.mongodb.org/manual/reference/operator/aggregation/lookup[$lookup] -a| - * link:javadoc/dev/morphia/aggregation/stages/Lookup.html#lookup(java.lang.Class)[Lookup#lookup(Class)] - * link:javadoc/dev/morphia/aggregation/stages/Lookup.html#lookup(java.lang.String)[Lookup#lookup(String)] - * link:javadoc/dev/morphia/aggregation/stages/Lookup.html#lookup()[Lookup#lookup()] +| http://docs.mongodb.org/manual/reference/operator/aggregation/lookup[$lookup] +a| link:javadoc/dev/morphia/aggregation/stages/Lookup.html#lookup(java.lang.Class)[Lookup#lookup(Class)] + +link:javadoc/dev/morphia/aggregation/stages/Lookup.html#lookup(java.lang.String)[Lookup#lookup(String)] + +link:javadoc/dev/morphia/aggregation/stages/Lookup.html#lookup()[Lookup#lookup()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestLookup.java[TestLookup] | http://docs.mongodb.org/manual/reference/operator/aggregation/match[$match] | link:javadoc/dev/morphia/aggregation/stages/Match.html#match(dev.morphia.query.filters.Filter%2E%2E%2E)[Match#match(Filter...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestMatch.java[TestMatch] -| http://docs.mongodb.org/manual/reference/operator/aggregation/merge[$merge] -a| - * link:javadoc/dev/morphia/aggregation/Aggregation.html#merge(dev.morphia.aggregation.stages.Merge)[Aggregation#merge(Merge)] - * link:javadoc/dev/morphia/aggregation/Aggregation.html#merge(dev.morphia.aggregation.stages.Merge,dev.morphia.aggregation.AggregationOptions)[Aggregation#merge(Merge,AggregationOptions)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/merge[$merge] +a| link:javadoc/dev/morphia/aggregation/Aggregation.html#merge(dev.morphia.aggregation.stages.Merge)[Aggregation#merge(Merge)] + +link:javadoc/dev/morphia/aggregation/Aggregation.html#merge(dev.morphia.aggregation.stages.Merge,dev.morphia.aggregation.AggregationOptions)[Aggregation#merge(Merge,AggregationOptions)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestMerge.java[TestMerge] | http://docs.mongodb.org/manual/reference/operator/aggregation/out[$out] -a| - - * link:javadoc/dev/morphia/aggregation/Aggregation.html#out(dev.morphia.aggregation.stages.Out)[Aggregation#out(Out)] - * link:javadoc/dev/morphia/aggregation/Aggregation.html#out(dev.morphia.aggregation.stages.Out,dev.morphia.aggregation.AggregationOptions)[Aggregation#out(Out,AggregationOptions)] +a| link:javadoc/dev/morphia/aggregation/Aggregation.html#out(dev.morphia.aggregation.stages.Out)[Aggregation#out(Out)] + +link:javadoc/dev/morphia/aggregation/Aggregation.html#out(dev.morphia.aggregation.stages.Out,dev.morphia.aggregation.AggregationOptions)[Aggregation#out(Out,AggregationOptions)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestOut.java[TestOut] | http://docs.mongodb.org/manual/reference/operator/aggregation/planCacheStats[$planCacheStats] | link:javadoc/dev/morphia/aggregation/stages/PlanCacheStats.html#planCacheStats()[PlanCacheStats#planCacheStats()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestPlanCacheStats.java[TestPlanCacheStats] + | http://docs.mongodb.org/manual/reference/operator/aggregation/project[$project] | link:javadoc/dev/morphia/aggregation/stages/Projection.html#project()[Projection#project()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestProject.java[TestProject] + | http://docs.mongodb.org/manual/reference/operator/aggregation/redact[$redact] | link:javadoc/dev/morphia/aggregation/stages/Redact.html#redact(dev.morphia.aggregation.expressions.impls.Expression)[Redact#redact(Expression)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestRedact.java[TestRedact] + | http://docs.mongodb.org/manual/reference/operator/aggregation/replaceRoot[$replaceRoot] | link:javadoc/dev/morphia/aggregation/stages/ReplaceRoot.html#replaceRoot()[ReplaceRoot#replaceRoot()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceRoot.java[TestReplaceRoot] + | http://docs.mongodb.org/manual/reference/operator/aggregation/replaceWith[$replaceWith] | link:javadoc/dev/morphia/aggregation/stages/ReplaceWith.html#replaceWith()[ReplaceWith#replaceWith()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestReplaceWith.java[TestReplaceWith] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sample[$sample] | link:javadoc/dev/morphia/aggregation/stages/Sample.html#sample(long)[Sample#sample(long)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestSample.java[TestSample] + | http://docs.mongodb.org/manual/reference/operator/aggregation/set[$set] | link:javadoc/dev/morphia/aggregation/stages/Set.html#set()[Set#set()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestSet.java[TestSet] + | http://docs.mongodb.org/manual/reference/operator/aggregation/setWindowFields[$setWindowFields] | link:javadoc/dev/morphia/aggregation/stages/SetWindowFields.html#setWindowFields()[SetWindowFields#setWindowFields()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestSetWindowFields.java[TestSetWindowFields] + | http://docs.mongodb.org/manual/reference/operator/aggregation/skip[$skip] | link:javadoc/dev/morphia/aggregation/stages/Skip.html#skip(long)[Skip#skip(long)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestSkip.java[TestSkip] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sort[$sort] | link:javadoc/dev/morphia/aggregation/stages/Sort.html#sort()[Sort#sort()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestSort.java[TestSort] + | http://docs.mongodb.org/manual/reference/operator/aggregation/sortByCount[$sortByCount] | link:javadoc/dev/morphia/aggregation/stages/SortByCount.html#sortByCount(java.lang.Object)[SortByCount#sortByCount(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestSortByCount.java[TestSortByCount] -| http://docs.mongodb.org/manual/reference/operator/aggregation/unionWith[$unionWith] -a| - * link:javadoc/dev/morphia/aggregation/stages/UnionWith.html#unionWith(java.lang.Class,dev.morphia.aggregation.stages.Stage%2E%2E%2E)[UnionWith#unionWith(Class,Stage...)] - * link:javadoc/dev/morphia/aggregation/stages/UnionWith.html#unionWith(java.lang.String,dev.morphia.aggregation.stages.Stage%2E%2E%2E)[UnionWith#unionWith(String,Stage...)] - * link:javadoc/dev/morphia/aggregation/Aggregation.html#unionWith(java.lang.String,dev.morphia.aggregation.stages.Stage%2E%2E%2E)[Aggregation#unionWith(String,Stage...)] +| http://docs.mongodb.org/manual/reference/operator/aggregation/unionWith[$unionWith] +a| link:javadoc/dev/morphia/aggregation/stages/UnionWith.html#unionWith(dev.morphia.aggregation.stages.Stage%2E%2E%2E)[UnionWith#unionWith(Stage...)] + +link:javadoc/dev/morphia/aggregation/stages/UnionWith.html#unionWith(java.lang.Class,dev.morphia.aggregation.stages.Stage%2E%2E%2E)[UnionWith#unionWith(Class,Stage...)] + +link:javadoc/dev/morphia/aggregation/stages/UnionWith.html#unionWith(java.lang.String,dev.morphia.aggregation.stages.Stage%2E%2E%2E)[UnionWith#unionWith(String,Stage...)] + +link:javadoc/dev/morphia/aggregation/Aggregation.html#unionWith(java.lang.String,dev.morphia.aggregation.stages.Stage%2E%2E%2E)[Aggregation#unionWith(String,Stage...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnionWith.java[TestUnionWith] | http://docs.mongodb.org/manual/reference/operator/aggregation/unset[$unset] | link:javadoc/dev/morphia/aggregation/stages/Unset.html#unset(java.lang.String,java.lang.String%2E%2E%2E)[Unset#unset(String,String...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnset.java[TestUnset] + | http://docs.mongodb.org/manual/reference/operator/aggregation/unwind[$unwind] | link:javadoc/dev/morphia/aggregation/stages/Unwind.html#unwind(java.lang.String)[Unwind#unwind(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/aggregation/stages/TestUnwind.java[TestUnwind] + |=== diff --git a/docs/modules/ROOT/pages/aggregations.adoc b/docs/modules/ROOT/pages/aggregations.adoc index ede1b3d8c06..a24ef907aa4 100644 --- a/docs/modules/ROOT/pages/aggregations.adoc +++ b/docs/modules/ROOT/pages/aggregations.adoc @@ -5,7 +5,7 @@ These pipelines can be used for analytics or they can be used to convert your da This guide will not go in to the details of how aggregation works, however. The official MongoDB {docsRef}/aggregation[documentation] has extensive tutorials on such details. Rather, this guide will focus on the Morphia API. The examples shown here are taken from the -{srcRef}/morphia/src/test/java/dev/morphia/aggregation/AggregationTest.java[tests] in Morphia itself. +{srcRef}/morphia/src/test/java/dev/morphia/aggregation/AggregationTest.java[tests] in Morphia itself. You can find the full list in the <> section. Writing an aggregation pipeline starts just like writing a standard query. As with querying, we start with the `Datastore`: @@ -89,7 +89,9 @@ new documents in to the collection. Other options are defined on `com.mongodb.c === Supported Operators Every effort is made to provide 100% coverage of all the operators offered by MongoDB. A select handful of operators have been excluded for reasons of suitability in Morphia. In short, some operators just don't make sense in Morphia. Below is listed all the currently -supported operators. If an operator is missing and you think it should be included, please file an https://github.com/MorphiaOrg/morphia/issues[issue] for that operator. +supported operators. To see an example of an operator in action, click through to see the test cases for that operator. + +If an operator is missing and you think it should be included, please file an https://github.com/MorphiaOrg/morphia/issues[issue] for that operator. .Stages include::aggregation-stages.adoc[] diff --git a/docs/modules/ROOT/pages/queries.adoc b/docs/modules/ROOT/pages/queries.adoc index 186ee99840c..ea14205341a 100644 --- a/docs/modules/ROOT/pages/queries.adoc +++ b/docs/modules/ROOT/pages/queries.adoc @@ -15,7 +15,8 @@ Query query = datastore.find(Product.class); The most significant method `filter(Filter...)`. This method takes a number of filters to apply to the query being built. The filters are added to any existing, previously defined filters so you needn't add them all at once. -There are dozens of filters predefined in Morphia and can be found in the `dev.morphia.query.filters` package. +There are dozens of filters predefined in Morphia and can be found in the `dev.morphia.query.filters` package. You can find the full +list in the <> section. The filters can be accessed via the link:javadoc/dev/morphia/query/filters/Filters.html[Filters] class. The method names largely match the operation name you would use querying via the mongo shell so this should help you translate queries in to Morphia's API. @@ -169,4 +170,13 @@ link:++javadoc/dev/morphia/config/MorphiaConfig.html#enablePolymorphicQueries()+ ==== Queries by ID will ignore this setting since such queries are filtering by a specific, unique value and polymorphic queries do incur potential performance hits due to the wider scope of the query filter. -==== \ No newline at end of file +==== + +=== Supported Operators +Every effort is made to provide 100% coverage of all the operators offered by MongoDB. Below is listed all the currently supported +operators. To see an example of an operator in action, click through to see the test cases for that operator. + +If an operator is missing and you think it should be included, please file an https://github.com/MorphiaOrg/morphia/issues[issue] for that operator. + +.Filters +include::query-filters.adoc[] diff --git a/docs/modules/ROOT/pages/query-filters.adoc b/docs/modules/ROOT/pages/query-filters.adoc new file mode 100644 index 00000000000..d9f5870d418 --- /dev/null +++ b/docs/modules/ROOT/pages/query-filters.adoc @@ -0,0 +1,227 @@ +[%header,cols="1,2,3"] +|=== +|Operator|Docs|Test Examples + +| http://docs.mongodb.org/manual/reference/operator/query/all[$all] +| link:javadoc/dev/morphia/query/filters/Filters.html#all(java.lang.String,java.lang.Object)[Filters#all(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestAll.java[TestAll] + + +| http://docs.mongodb.org/manual/reference/operator/query/and[$and] +| link:javadoc/dev/morphia/query/filters/Filters.html#and(dev.morphia.query.filters.Filter%2E%2E%2E)[Filters#and(Filter...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestAnd.java[TestAnd] + + +| http://docs.mongodb.org/manual/reference/operator/query/bitsAllClear[$bitsAllClear] +| link:javadoc/dev/morphia/query/filters/Filters.html#bitsAllClear(java.lang.String,java.lang.Object)[Filters#bitsAllClear(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestBitsAllClear.java[TestBitsAllClear] + + +| http://docs.mongodb.org/manual/reference/operator/query/bitsAllSet[$bitsAllSet] +| link:javadoc/dev/morphia/query/filters/Filters.html#bitsAllSet(java.lang.String,java.lang.Object)[Filters#bitsAllSet(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestBitsAllSet.java[TestBitsAllSet] + + +| http://docs.mongodb.org/manual/reference/operator/query/bitsAnyClear[$bitsAnyClear] +| link:javadoc/dev/morphia/query/filters/Filters.html#bitsAnyClear(java.lang.String,java.lang.Object)[Filters#bitsAnyClear(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnyClear.java[TestBitsAnyClear] + + +| http://docs.mongodb.org/manual/reference/operator/query/bitsAnySet[$bitsAnySet] +| link:javadoc/dev/morphia/query/filters/Filters.html#bitsAnySet(java.lang.String,java.lang.Object)[Filters#bitsAnySet(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnySet.java[TestBitsAnySet] + + +| http://docs.mongodb.org/manual/reference/operator/query/box[$box] +| link:javadoc/dev/morphia/query/filters/Filters.html#box(java.lang.String,com.mongodb.client.model.geojson.Point,com.mongodb.client.model.geojson.Point)[Filters#box(String,Point,Point)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestBox.java[TestBox] + + +| http://docs.mongodb.org/manual/reference/operator/query/center[$center] +| link:javadoc/dev/morphia/query/filters/Filters.html#center(java.lang.String,com.mongodb.client.model.geojson.Point,double)[Filters#center(String,Point,double)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestCenter.java[TestCenter] + + +| http://docs.mongodb.org/manual/reference/operator/query/centerSphere[$centerSphere] +| link:javadoc/dev/morphia/query/filters/Filters.html#centerSphere(java.lang.String,com.mongodb.client.model.geojson.Point,double)[Filters#centerSphere(String,Point,double)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestCenterSphere.java[TestCenterSphere] + + +| http://docs.mongodb.org/manual/reference/operator/query/comment[$comment] +| link:javadoc/dev/morphia/query/filters/Filters.html#comment(java.lang.String)[Filters#comment(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestComment.java[TestComment] + + +| http://docs.mongodb.org/manual/reference/operator/query/elemMatch[$elemMatch] +a| link:javadoc/dev/morphia/query/filters/Filters.html#elemMatch(dev.morphia.query.filters.Filter%2E%2E%2E)[Filters#elemMatch(Filter...)] + +link:javadoc/dev/morphia/query/filters/Filters.html#elemMatch(java.lang.String,dev.morphia.query.filters.Filter%2E%2E%2E)[Filters#elemMatch(String,Filter...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestElemMatch.java[TestElemMatch] + + +| http://docs.mongodb.org/manual/reference/operator/query/eq[$eq] +| link:javadoc/dev/morphia/query/filters/Filters.html#eq(java.lang.String,java.lang.Object)[Filters#eq(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestEq.java[TestEq] + + +| http://docs.mongodb.org/manual/reference/operator/query/exists[$exists] +| link:javadoc/dev/morphia/query/filters/Filters.html#exists(java.lang.String)[Filters#exists(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestExists.java[TestExists] + + +| http://docs.mongodb.org/manual/reference/operator/query/expr[$expr] +| link:javadoc/dev/morphia/query/filters/Filters.html#expr(dev.morphia.aggregation.expressions.impls.Expression)[Filters#expr(Expression)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestExpr.java[TestExpr] + + +| http://docs.mongodb.org/manual/reference/operator/query/geoIntersects[$geoIntersects] +| link:javadoc/dev/morphia/query/filters/Filters.html#geoIntersects(java.lang.String,com.mongodb.client.model.geojson.Geometry)[Filters#geoIntersects(String,Geometry)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestGeoIntersects.java[TestGeoIntersects] + + +| http://docs.mongodb.org/manual/reference/operator/query/geoWithin[$geoWithin] +a| link:javadoc/dev/morphia/query/filters/Filters.html#geoWithin(java.lang.String,com.mongodb.client.model.geojson.Polygon)[Filters#geoWithin(String,Polygon)] + +link:javadoc/dev/morphia/query/filters/Filters.html#geoWithin(java.lang.String,com.mongodb.client.model.geojson.MultiPolygon)[Filters#geoWithin(String,MultiPolygon)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestGeoWithin.java[TestGeoWithin] + + +| http://docs.mongodb.org/manual/reference/operator/query/geometry[$geometry] +| link:javadoc/dev/morphia/query/filters/Filters.html#geometry(java.lang.String,java.lang.Object)[Filters#geometry(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestGeometry.java[TestGeometry] + + +| http://docs.mongodb.org/manual/reference/operator/query/gt[$gt] +a| link:javadoc/dev/morphia/query/filters/Filters.html#gt(java.lang.Object)[Filters#gt(Object)] + +link:javadoc/dev/morphia/query/filters/Filters.html#gt(java.lang.String,java.lang.Object)[Filters#gt(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestGt.java[TestGt] + + +| http://docs.mongodb.org/manual/reference/operator/query/gte[$gte] +a| link:javadoc/dev/morphia/query/filters/Filters.html#gte(java.lang.String,java.lang.Object)[Filters#gte(String,Object)] + +link:javadoc/dev/morphia/query/filters/Filters.html#gte(java.lang.Object)[Filters#gte(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestGte.java[TestGte] + + +| http://docs.mongodb.org/manual/reference/operator/query/in[$in] +a| link:javadoc/dev/morphia/query/filters/Filters.html#in(java.lang.String,java.lang.Iterable)[Filters#in(String,Iterable)] + +link:javadoc/dev/morphia/query/filters/Filters.html#in(java.lang.Iterable)[Filters#in(Iterable)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestIn.java[TestIn] + + +| http://docs.mongodb.org/manual/reference/operator/query/jsonSchema[$jsonSchema] +| link:javadoc/dev/morphia/query/filters/Filters.html#jsonSchema(org.bson.Document)[Filters#jsonSchema(Document)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestJsonSchema.java[TestJsonSchema] + + +| http://docs.mongodb.org/manual/reference/operator/query/lt[$lt] +a| link:javadoc/dev/morphia/query/filters/Filters.html#lt(java.lang.Object)[Filters#lt(Object)] + +link:javadoc/dev/morphia/query/filters/Filters.html#lt(java.lang.String,java.lang.Object)[Filters#lt(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestLt.java[TestLt] + + +| http://docs.mongodb.org/manual/reference/operator/query/lte[$lte] +a| link:javadoc/dev/morphia/query/filters/Filters.html#lte(java.lang.Object)[Filters#lte(Object)] + +link:javadoc/dev/morphia/query/filters/Filters.html#lte(java.lang.String,java.lang.Object)[Filters#lte(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestLte.java[TestLte] + + +| http://docs.mongodb.org/manual/reference/operator/query/maxDistance[$maxDistance] +| link:javadoc/dev/morphia/query/filters/Filters.html#maxDistance(java.lang.String,java.lang.Object)[Filters#maxDistance(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestMaxDistance.java[TestMaxDistance] + + +| http://docs.mongodb.org/manual/reference/operator/query/meta[$meta] +a| link:javadoc/dev/morphia/query/Meta.html#indexKey(java.lang.String)[Meta#indexKey(String)] + +link:javadoc/dev/morphia/query/Meta.html#searchHighlights(java.lang.String)[Meta#searchHighlights(String)] + +link:javadoc/dev/morphia/query/Meta.html#searchScore(java.lang.String)[Meta#searchScore(String)] + +link:javadoc/dev/morphia/query/Meta.html#textScore(java.lang.String)[Meta#textScore(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestMeta.java[TestMeta] + + +| http://docs.mongodb.org/manual/reference/operator/query/minDistance[$minDistance] +| link:javadoc/dev/morphia/query/filters/Filters.html#minDistance(java.lang.String,java.lang.Object)[Filters#minDistance(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestMinDistance.java[TestMinDistance] + + +| http://docs.mongodb.org/manual/reference/operator/query/mod[$mod] +a| link:javadoc/dev/morphia/query/filters/Filters.html#mod(java.lang.String,long,long)[Filters#mod(String,long,long)] + +link:javadoc/dev/morphia/query/filters/Filters.html#mod(java.lang.String,double,double)[Filters#mod(String,double,double)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestMod.java[TestMod] + + +| http://docs.mongodb.org/manual/reference/operator/query/ne[$ne] +| link:javadoc/dev/morphia/query/filters/Filters.html#ne(java.lang.String,java.lang.Object)[Filters#ne(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestNe.java[TestNe] + + +| http://docs.mongodb.org/manual/reference/operator/query/near[$near] +| link:javadoc/dev/morphia/query/filters/Filters.html#near(java.lang.String,com.mongodb.client.model.geojson.Point)[Filters#near(String,Point)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestNear.java[TestNear] + + +| http://docs.mongodb.org/manual/reference/operator/query/nearSphere[$nearSphere] +| link:javadoc/dev/morphia/query/filters/Filters.html#nearSphere(java.lang.String,com.mongodb.client.model.geojson.Point)[Filters#nearSphere(String,Point)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestNearSphere.java[TestNearSphere] + + +| http://docs.mongodb.org/manual/reference/operator/query/nin[$nin] +| link:javadoc/dev/morphia/query/filters/Filters.html#nin(java.lang.String,java.lang.Object)[Filters#nin(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestNin.java[TestNin] + + +| http://docs.mongodb.org/manual/reference/operator/query/nor[$nor] +| link:javadoc/dev/morphia/query/filters/Filters.html#nor(dev.morphia.query.filters.Filter%2E%2E%2E)[Filters#nor(Filter...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestNor.java[TestNor] + + +| http://docs.mongodb.org/manual/reference/operator/query/not[$not] +| link:javadoc/dev/morphia/query/filters/Filter.html#not()[Filter#not()] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestNot.java[TestNot] + + +| http://docs.mongodb.org/manual/reference/operator/query/or[$or] +| link:javadoc/dev/morphia/query/filters/Filters.html#or(dev.morphia.query.filters.Filter%2E%2E%2E)[Filters#or(Filter...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestOr.java[TestOr] + + +| http://docs.mongodb.org/manual/reference/operator/query/polygon[$polygon] +| link:javadoc/dev/morphia/query/filters/Filters.html#polygon(java.lang.String,com.mongodb.client.model.geojson.Point%2E%2E%2E)[Filters#polygon(String,Point...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestPolygon.java[TestPolygon] + + +| http://docs.mongodb.org/manual/reference/operator/query/regex[$regex] +a| link:javadoc/dev/morphia/query/filters/Filters.html#regex(java.lang.String,java.lang.String)[Filters#regex(String,String)] + +link:javadoc/dev/morphia/query/filters/Filters.html#regex(java.lang.String,java.util.regex.Pattern)[Filters#regex(String,Pattern)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestRegex.java[TestRegex] + + +| http://docs.mongodb.org/manual/reference/operator/query/size[$size] +| link:javadoc/dev/morphia/query/filters/Filters.html#size(java.lang.String,int)[Filters#size(String,int)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestSize.java[TestSize] + + +| http://docs.mongodb.org/manual/reference/operator/query/slice[$slice] +| link:javadoc/dev/morphia/query/ArraySlice.html#limit(int)[ArraySlice#limit(int)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestSlice.java[TestSlice] + + +| http://docs.mongodb.org/manual/reference/operator/query/text[$text] +| link:javadoc/dev/morphia/query/filters/Filters.html#text(java.lang.String)[Filters#text(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestText.java[TestText] + + +| http://docs.mongodb.org/manual/reference/operator/query/type[$type] +| link:javadoc/dev/morphia/query/filters/Filters.html#type(java.lang.String,dev.morphia.query.Type%2E%2E%2E)[Filters#type(String,Type...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestType.java[TestType] + + +| http://docs.mongodb.org/manual/reference/operator/query/uniqueDocs[$uniqueDocs] +| link:javadoc/dev/morphia/query/filters/Filters.html#uniqueDocs(java.lang.String,java.lang.Object)[Filters#uniqueDocs(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestUniqueDocs.java[TestUniqueDocs] + + +| http://docs.mongodb.org/manual/reference/operator/query/where[$where] +| link:javadoc/dev/morphia/query/filters/Filters.html#where(java.lang.String)[Filters#where(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/filters/TestWhere.java[TestWhere] + + +|=== diff --git a/docs/modules/ROOT/pages/update-operators.adoc b/docs/modules/ROOT/pages/update-operators.adoc new file mode 100644 index 00000000000..186b138adec --- /dev/null +++ b/docs/modules/ROOT/pages/update-operators.adoc @@ -0,0 +1,102 @@ +[%header,cols="1,2,3"] +|=== +|Operator|Docs|Test Examples + +| http://docs.mongodb.org/manual/reference/operator/query/addToSet[$addToSet] +a| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#addToSet(java.lang.String,java.lang.Object)[UpdateOperators#addToSet(String,Object)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#addToSet(java.lang.String,java.util.List)[UpdateOperators#addToSet(String,List)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestAddToSet.java[TestAddToSet] + + +| http://docs.mongodb.org/manual/reference/operator/query/bit[$bit] +a| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#and(java.lang.String,int)[UpdateOperators#and(String,int)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#bit(java.lang.String,java.lang.Number)[UpdateOperators#bit(String,Number)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#or(java.lang.String,int)[UpdateOperators#or(String,int)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#xor(java.lang.String,int)[UpdateOperators#xor(String,int)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestBit.java[TestBit] + + +| http://docs.mongodb.org/manual/reference/operator/query/currentDate[$currentDate] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#currentDate(java.lang.String)[UpdateOperators#currentDate(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestCurrentDate.java[TestCurrentDate] + + +| http://docs.mongodb.org/manual/reference/operator/query/dec[$dec] +a| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#dec(java.lang.String)[UpdateOperators#dec(String)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#dec(java.lang.String,java.lang.Number)[UpdateOperators#dec(String,Number)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestDec.java[TestDec] + + +| http://docs.mongodb.org/manual/reference/operator/query/each[$each] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#push(java.lang.String,java.util.List)[UpdateOperators#push(String,List)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestEach.java[TestEach] + + +| http://docs.mongodb.org/manual/reference/operator/query/inc[$inc] +a| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#inc(java.lang.String,java.lang.Number)[UpdateOperators#inc(String,Number)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#inc(java.lang.String)[UpdateOperators#inc(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestInc.java[TestInc] + + +| http://docs.mongodb.org/manual/reference/operator/query/max[$max] +a| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#max(java.lang.String,java.lang.Number)[UpdateOperators#max(String,Number)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#max(java.lang.String,java.time.temporal.Temporal)[UpdateOperators#max(String,Temporal)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#max(java.lang.String,java.util.Date)[UpdateOperators#max(String,Date)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestMax.java[TestMax] + + +| http://docs.mongodb.org/manual/reference/operator/query/min[$min] +a| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#min(java.lang.String,java.lang.Number)[UpdateOperators#min(String,Number)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#min(java.lang.String,java.time.temporal.Temporal)[UpdateOperators#min(String,Temporal)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#min(java.lang.String,java.util.Date)[UpdateOperators#min(String,Date)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestMin.java[TestMin] + + +| http://docs.mongodb.org/manual/reference/operator/query/mul[$mul] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#mul(java.lang.String,java.lang.Number)[UpdateOperators#mul(String,Number)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestMul.java[TestMul] + + +| http://docs.mongodb.org/manual/reference/operator/query/pop[$pop] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#pop(java.lang.String)[UpdateOperators#pop(String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestPop.java[TestPop] + + +| http://docs.mongodb.org/manual/reference/operator/query/pull[$pull] +a| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#pull(java.lang.String,dev.morphia.query.filters.Filter%2E%2E%2E)[UpdateOperators#pull(String,Filter...)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#pull(java.lang.String,java.lang.Object)[UpdateOperators#pull(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestPull.java[TestPull] + + +| http://docs.mongodb.org/manual/reference/operator/query/pullAll[$pullAll] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#pullAll(java.lang.String,java.util.List)[UpdateOperators#pullAll(String,List)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestPullAll.java[TestPullAll] + + +| http://docs.mongodb.org/manual/reference/operator/query/push[$push] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#push(java.lang.String,java.lang.Object)[UpdateOperators#push(String,Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestPush.java[TestPush] + + +| http://docs.mongodb.org/manual/reference/operator/query/rename[$rename] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#rename(java.lang.String,java.lang.String)[UpdateOperators#rename(String,String)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestRename.java[TestRename] + + +| http://docs.mongodb.org/manual/reference/operator/query/set[$set] +a| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#set(java.lang.String,java.lang.Object)[UpdateOperators#set(String,Object)] + +link:javadoc/dev/morphia/query/updates/UpdateOperators.html#set(java.lang.Object)[UpdateOperators#set(Object)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestSet.java[TestSet] + + +| http://docs.mongodb.org/manual/reference/operator/query/setOnInsert[$setOnInsert] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#setOnInsert(java.util.Map)[UpdateOperators#setOnInsert(Map)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestSetOnInsert.java[TestSetOnInsert] + + +| http://docs.mongodb.org/manual/reference/operator/query/unset[$unset] +| link:javadoc/dev/morphia/query/updates/UpdateOperators.html#unset(java.lang.String,java.lang.String%2E%2E%2E)[UpdateOperators#unset(String,String...)] +| https://github.com/MorphiaOrg/morphia/blob/master/core/src/test/java/dev/morphia/test/query/updates/TestUnset.java[TestUnset] + + +|=== diff --git a/docs/modules/ROOT/pages/updates.adoc b/docs/modules/ROOT/pages/updates.adoc index f8d546647f9..606957f0860 100644 --- a/docs/modules/ROOT/pages/updates.adoc +++ b/docs/modules/ROOT/pages/updates.adoc @@ -155,3 +155,11 @@ Regardless of whether this value is set, `merge()` will issue a `find()` for tha Without using `unsetMissing()`, this is useful for merging the in memory state with what's in the database. With this value set, the two should be identical, of course. +=== Supported Operators +Every effort is made to provide 100% coverage of all the operators offered by MongoDB. Below is listed all the currently supported +operators. To see an example of an operator in action, click through to see the test cases for that operator. + +If an operator is missing and you think it should be included, please file an https://github.com/MorphiaOrg/morphia/issues[issue] for that operator. + +.Filters +include::update-operators.adoc[] diff --git a/examples/pom.xml b/examples/pom.xml index 44a7f666773..b942fe66a90 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -15,6 +15,20 @@ true + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + -parameters + + + + + dev.morphia.morphia @@ -22,8 +36,8 @@ ${project.version} - com.github.zafarkhaja - java-semver + org.semver4j + semver4j org.testcontainers diff --git a/kotlin/pom.xml b/kotlin/pom.xml index 76c41c30bb3..c8c1e2769c4 100644 --- a/kotlin/pom.xml +++ b/kotlin/pom.xml @@ -43,8 +43,8 @@ test - com.github.zafarkhaja - java-semver + org.semver4j + semver4j diff --git a/mvnw.cmd b/mvnw.cmd old mode 100755 new mode 100644 diff --git a/pom.xml b/pom.xml index 47a079c1e8d..9b9398734ca 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.antwerkz antwerkz-parent - 39 + 44 dev.morphia.morphia @@ -42,27 +42,32 @@ - 2.0.0 + 2.0.21 1.7.0 - 5.1.0 - 5.1 - 2.17.1 - 1.5.1 - 1.5.6 - 3.9.7 + 5.2.0 + 5.2 + 2.18.0 + 1.5.3 + 1.13.0 + 1.19.1 + 1.5.11 + 3.9.9 0.15.0 0.28.1 - 2.28.0.Final - 2.0.13 + 2.29.0.Final + 2.0.16 0.25 3.1.0 7.10.2 + 1.0.5 1.12 17 17 UTF-8 17 + 9.7.1 + 2.0.21-1.0.25 @@ -78,6 +83,9 @@ 17 -proc:none -Xlint:deprecation + + -parameters + @@ -145,6 +153,11 @@ + + dev.morphia.morphia + morphia-core + ${project.version} + org.slf4j slf4j-api @@ -168,6 +181,12 @@ ${testng.version} test + + org.junit.support + testng-engine + ${junit.testng.engine.version} + test + org.apache.maven maven-model @@ -182,7 +201,7 @@ io.smallrye.config smallrye-config - 3.8.2 + 3.10.0 @@ -198,7 +217,7 @@ org.testcontainers mongodb - 1.19.8 + 1.20.2 test @@ -221,14 +240,13 @@ org.awaitility awaitility - 4.2.1 + 4.2.2 test - com.github.zafarkhaja - java-semver - 0.10.2 - test + org.semver4j + semver4j + 5.4.1 org.zeroturnaround @@ -257,22 +275,27 @@ org.kohsuke github-api - 1.321 + 1.326 org.ow2.asm asm-tree - 9.7 + ${asm.version} + + + org.ow2.asm + asm-util + ${asm.version} org.jsoup jsoup - 1.17.2 + 1.18.1 org.asciidoctor asciidoctorj - 2.5.13 + 3.0.0 org.jboss.forge.roaster @@ -288,19 +311,40 @@ com.github.spotbugs spotbugs-annotations - 4.8.5 + 4.8.6 compile net.bytebuddy byte-buddy - 1.14.17 + 1.15.5 io.github.classgraph classgraph - 4.8.173 + 4.8.177 + + + com.google.devtools.ksp + symbol-processing-api + ${ksp.version} + + com.google.devtools.ksp + symbol-processing-common-deps + ${ksp.version} + + + com.google.devtools.ksp + symbol-processing-aa-embeddable + ${ksp.version} + + + com.squareup + javapoet + ${javapoet.version} + + @@ -323,6 +367,7 @@ critter + false critter @@ -331,6 +376,19 @@ critter + + + rewrite + + true + + rewrite + + + + rewrite + + @@ -341,6 +399,5 @@ kotlin validation examples - rewrite diff --git a/rewrite/pom.xml b/rewrite/pom.xml index bd3eb1be3d7..c323673cff1 100644 --- a/rewrite/pom.xml +++ b/rewrite/pom.xml @@ -24,7 +24,7 @@ org.openrewrite.recipe rewrite-recipe-bom - 2.11.1 + 2.21.0 pom import @@ -36,7 +36,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.6.1 + 3.8.0 @@ -67,7 +67,7 @@ com.fasterxml.jackson.core jackson-annotations - 2.17.1 + 2.18.0 diff --git a/util/pom.xml b/util/pom.xml index 330f220933a..f3a330c3e59 100644 --- a/util/pom.xml +++ b/util/pom.xml @@ -14,5 +14,7 @@ true true + 17 + 17 diff --git a/validation/pom.xml b/validation/pom.xml index 97cd58c0186..c1dd6983896 100644 --- a/validation/pom.xml +++ b/validation/pom.xml @@ -63,8 +63,8 @@ provided - com.github.zafarkhaja - java-semver + org.semver4j + semver4j