Browse Source

DATAMONGO-479 - Polishing.

Removed ServersideJavaScript abstraction as we still had to resort on instanceof checks and it created more ambiguities than it helped (e.g. in a script with name and code, which of the two get's executed?). We now have an ExecutableMongoScript which is code only and a NamedMongoScript, which basically is the former assigned to a name. Execution can be triggered on the former or a name.

ScriptOperations.exists(…) now returns a primitive boolean to avoid null checks. JavaDoc.

Original pull request: #254.
pull/271/merge
Oliver Gierke 11 years ago
parent
commit
39d9312005
  1. 94
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultScriptOperations.java
  2. 32
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScriptOperations.java
  3. 8
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java
  4. 18
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java
  5. 18
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/ExecutableMongoScript.java
  6. 54
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/NamedMongoScript.java
  7. 30
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/ServerSideJavaScript.java
  8. 41
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultScriptOperationsTests.java
  9. 32
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultScriptOperationsUnitTests.java
  10. 58
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/NamedMongoScriptConvertsUnitTests.java
  11. 21
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/script/NamedMongoScriptUnitTests.java

94
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultScriptOperations.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,8 +27,8 @@ import java.util.Set; @@ -27,8 +27,8 @@ import java.util.Set;
import org.bson.types.ObjectId;
import org.springframework.dao.DataAccessException;
import org.springframework.data.mongodb.core.script.CallableMongoScript;
import org.springframework.data.mongodb.core.script.ServerSideJavaScript;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
@ -41,12 +41,14 @@ import com.mongodb.MongoException; @@ -41,12 +41,14 @@ import com.mongodb.MongoException;
* Default implementation of {@link ScriptOperations} capable of saving and executing {@link ServerSideJavaScript}.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class DefaultScriptOperations implements ScriptOperations {
class DefaultScriptOperations implements ScriptOperations {
private static final String SCRIPT_COLLECTION_NAME = "system.js";
private static final String SCRIPT_NAME_PREFIX = "func_";
private final MongoOperations mongoOperations;
/**
@ -63,39 +65,39 @@ public class DefaultScriptOperations implements ScriptOperations { @@ -63,39 +65,39 @@ public class DefaultScriptOperations implements ScriptOperations {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#save(org.springframework.data.mongodb.core.script.MongoScript)
* @see org.springframework.data.mongodb.core.ScriptOperations#register(org.springframework.data.mongodb.core.script.ExecutableMongoScript)
*/
@Override
public NamedMongoScript register(ExecutableMongoScript script) {
return register(new NamedMongoScript(generateScriptName(), script));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#register(org.springframework.data.mongodb.core.script.NamedMongoScript)
*/
@Override
public CallableMongoScript register(ServerSideJavaScript script) {
public NamedMongoScript register(NamedMongoScript script) {
Assert.notNull(script, "Script must not be null!");
CallableMongoScript callableScript = (script instanceof CallableMongoScript) ? (CallableMongoScript) script
: new CallableMongoScript(generateScriptName(), script);
mongoOperations.save(callableScript, SCRIPT_COLLECTION_NAME);
return callableScript;
mongoOperations.save(script, SCRIPT_COLLECTION_NAME);
return script;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#execute(org.springframework.data.mongodb.core.script.MongoScript, java.lang.Object[])
* @see org.springframework.data.mongodb.core.ScriptOperations#execute(org.springframework.data.mongodb.core.script.ExecutableMongoScript, java.lang.Object[])
*/
@Override
public Object execute(final ServerSideJavaScript script, final Object... args) {
public Object execute(final ExecutableMongoScript script, final Object... args) {
Assert.notNull(script, "Script must not be null!");
if (script instanceof CallableMongoScript) {
return call(((CallableMongoScript) script).getName(), args);
}
return mongoOperations.execute(new DbCallback<Object>() {
@Override
public Object doInDB(DB db) throws MongoException, DataAccessException {
Assert.notNull(script.getCode(), "Script.code must not be null!");
return db.eval(script.getCode(), convertScriptArgs(args));
}
});
@ -114,9 +116,7 @@ public class DefaultScriptOperations implements ScriptOperations { @@ -114,9 +116,7 @@ public class DefaultScriptOperations implements ScriptOperations {
@Override
public Object doInDB(DB db) throws MongoException, DataAccessException {
String evalString = scriptName + "(" + convertAndJoinScriptArgs(args) + ")";
return db.eval(evalString);
return db.eval(String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args)));
}
});
}
@ -126,43 +126,33 @@ public class DefaultScriptOperations implements ScriptOperations { @@ -126,43 +126,33 @@ public class DefaultScriptOperations implements ScriptOperations {
* @see org.springframework.data.mongodb.core.ScriptOperations#exists(java.lang.String)
*/
@Override
public Boolean exists(String scriptName) {
public boolean exists(String scriptName) {
Assert.hasText(scriptName, "ScriptName must not be null or empty!");
return mongoOperations.exists(query(where("name").is(scriptName)), CallableMongoScript.class,
SCRIPT_COLLECTION_NAME);
return mongoOperations.exists(query(where("name").is(scriptName)), NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#scriptNames()
* @see org.springframework.data.mongodb.core.ScriptOperations#getScriptNames()
*/
@Override
public Set<String> scriptNames() {
public Set<String> getScriptNames() {
List<CallableMongoScript> scripts = (mongoOperations.findAll(CallableMongoScript.class, SCRIPT_COLLECTION_NAME));
List<NamedMongoScript> scripts = mongoOperations.findAll(NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
if (CollectionUtils.isEmpty(scripts)) {
return Collections.emptySet();
}
Set<String> scriptNames = new HashSet<String>();
for (CallableMongoScript script : scripts) {
for (NamedMongoScript script : scripts) {
scriptNames.add(script.getName());
}
return scriptNames;
}
/**
* Generate a valid name for the {@literal JavaScript}. MongoDB requires an id of type String for scripts. Calling
* scripts having {@link ObjectId} as id fails. Therefore we create a random UUID without {@code -} (as this won't
* work) an prefix the result with {@link #SCRIPT_NAME_PREFIX}.
*
* @return
*/
private String generateScriptName() {
return SCRIPT_NAME_PREFIX + randomUUID().toString().replaceAll("-", "");
return scriptNames;
}
private Object[] convertScriptArgs(Object... args) {
@ -172,23 +162,27 @@ public class DefaultScriptOperations implements ScriptOperations { @@ -172,23 +162,27 @@ public class DefaultScriptOperations implements ScriptOperations {
}
List<Object> convertedValues = new ArrayList<Object>(args.length);
for (Object arg : args) {
if (arg instanceof String) {
convertedValues.add("'" + arg + "'");
} else {
convertedValues.add(this.mongoOperations.getConverter().convertToMongoType(arg));
}
convertedValues.add(arg instanceof String ? String.format("'%s'", arg) : this.mongoOperations.getConverter()
.convertToMongoType(arg));
}
return convertedValues.toArray();
}
private String convertAndJoinScriptArgs(Object... args) {
if (ObjectUtils.isEmpty(args)) {
return "";
return ObjectUtils.isEmpty(args) ? "" : StringUtils.arrayToCommaDelimitedString(convertScriptArgs(args));
}
return StringUtils.arrayToCommaDelimitedString(convertScriptArgs(args));
/**
* Generate a valid name for the {@literal JavaScript}. MongoDB requires an id of type String for scripts. Calling
* scripts having {@link ObjectId} as id fails. Therefore we create a random UUID without {@code -} (as this won't
* work) an prefix the result with {@link #SCRIPT_NAME_PREFIX}.
*
* @return
*/
private static String generateScriptName() {
return SCRIPT_NAME_PREFIX + randomUUID().toString().replaceAll("-", "");
}
}

32
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScriptOperations.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,27 +17,36 @@ package org.springframework.data.mongodb.core; @@ -17,27 +17,36 @@ package org.springframework.data.mongodb.core;
import java.util.Set;
import org.springframework.data.mongodb.core.script.CallableMongoScript;
import org.springframework.data.mongodb.core.script.ServerSideJavaScript;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import com.mongodb.DB;
/**
* Script operations on {@link com.mongodb.DB} level. Allows interaction with server side {@literal JavaScript}
* functions.
* Script operations on {@link com.mongodb.DB} level. Allows interaction with server side JavaScript functions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public interface ScriptOperations {
/**
* Store given {@literal script} to {@link com.mongodb.DB} so it can be called via its name.
* Store given {@link ExecutableMongoScript} generating a syntheitcal name so that it can be called by it
* subsequently.
*
* @param script must not be {@literal null}.
* @return {@link CallableMongoScript} with name under which the {@literal JavaScript} function can be called.
* @return {@link NamedMongoScript} with name under which the {@code JavaScript} function can be called.
*/
CallableMongoScript register(ServerSideJavaScript script);
NamedMongoScript register(ExecutableMongoScript script);
/**
* Registers the given {@link NamedMongoScript} in the database.
*
* @param script the {@link NamedMongoScript} to be registered.
* @return
*/
NamedMongoScript register(NamedMongoScript script);
/**
* Executes the {@literal script} by either calling it via its {@literal name} or directly sending it.
@ -47,7 +56,7 @@ public interface ScriptOperations { @@ -47,7 +56,7 @@ public interface ScriptOperations {
* @return the script evaluation result.
* @throws org.springframework.dao.DataAccessException
*/
Object execute(ServerSideJavaScript script, Object... args);
Object execute(ExecutableMongoScript script, Object... args);
/**
* Call the {@literal JavaScript} by its name.
@ -64,13 +73,12 @@ public interface ScriptOperations { @@ -64,13 +73,12 @@ public interface ScriptOperations {
* @param scriptName must not be {@literal null} or empty.
* @return false if no {@link ServerSideJavaScript} with given name exists.
*/
Boolean exists(String scriptName);
boolean exists(String scriptName);
/**
* Returns names of {@literal JavaScript} functions that can be called.
*
* @return empty {@link Set} if no scripts found.
*/
Set<String> scriptNames();
Set<String> getScriptNames();
}

8
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java

@ -44,8 +44,8 @@ import org.springframework.data.convert.WritingConverter; @@ -44,8 +44,8 @@ import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.CallableMongoScriptToDBObjectConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToCallableMongoScriptCoverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.NamedMongoScriptToDBObjectConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToNamedMongoScriptCoverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
@ -120,8 +120,8 @@ public class CustomConversions { @@ -120,8 +120,8 @@ public class CustomConversions {
toRegister.add(StringToURLConverter.INSTANCE);
toRegister.add(DBObjectToStringConverter.INSTANCE);
toRegister.add(TermToStringConverter.INSTANCE);
toRegister.add(CallableMongoScriptToDBObjectConverter.INSTANCE);
toRegister.add(DBObjectToCallableMongoScriptCoverter.INSTANCE);
toRegister.add(NamedMongoScriptToDBObjectConverter.INSTANCE);
toRegister.add(DBObjectToNamedMongoScriptCoverter.INSTANCE);
toRegister.addAll(JodaTimeConverters.getConvertersToRegister());
toRegister.addAll(GeoConverters.getConvertersToRegister());

18
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2011-2014 the original author or authors.
* Copyright 2011-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,7 +28,7 @@ import org.springframework.core.convert.converter.Converter; @@ -28,7 +28,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.core.query.Term;
import org.springframework.data.mongodb.core.script.CallableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
@ -187,13 +187,12 @@ abstract class MongoConverters { @@ -187,13 +187,12 @@ abstract class MongoConverters {
* @author Christoph Strobl
* @since 1.7
*/
@ReadingConverter
public static enum DBObjectToCallableMongoScriptCoverter implements Converter<DBObject, CallableMongoScript> {
public static enum DBObjectToNamedMongoScriptCoverter implements Converter<DBObject, NamedMongoScript> {
INSTANCE;
@Override
public CallableMongoScript convert(DBObject source) {
public NamedMongoScript convert(DBObject source) {
if (source == null) {
return null;
@ -202,7 +201,7 @@ abstract class MongoConverters { @@ -202,7 +201,7 @@ abstract class MongoConverters {
String id = source.get("_id").toString();
Object rawValue = source.get("value");
return new CallableMongoScript(id, ((Code) rawValue).getCode());
return new NamedMongoScript(id, ((Code) rawValue).getCode());
}
}
@ -210,13 +209,12 @@ abstract class MongoConverters { @@ -210,13 +209,12 @@ abstract class MongoConverters {
* @author Christoph Strobl
* @since 1.7
*/
@WritingConverter
public static enum CallableMongoScriptToDBObjectConverter implements Converter<CallableMongoScript, DBObject> {
public static enum NamedMongoScriptToDBObjectConverter implements Converter<NamedMongoScript, DBObject> {
INSTANCE;
@Override
public DBObject convert(CallableMongoScript source) {
public DBObject convert(NamedMongoScript source) {
if (source == null) {
return new BasicDBObject();
@ -225,9 +223,7 @@ abstract class MongoConverters { @@ -225,9 +223,7 @@ abstract class MongoConverters {
BasicDBObjectBuilder builder = new BasicDBObjectBuilder();
builder.append("_id", source.getName());
if (source.getCode() != null) {
builder.append("value", new Code(source.getCode()));
}
return builder.get();
}

18
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/ExecutableMongoScript.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,19 +18,20 @@ package org.springframework.data.mongodb.core.script; @@ -18,19 +18,20 @@ package org.springframework.data.mongodb.core.script;
import org.springframework.util.Assert;
/**
* {@link ServerSideJavaScript} implementation that can be saved or directly executed.
* Value object for MongoDB JavaScript functions implementation that can be saved or directly executed.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class ExecutableMongoScript implements ServerSideJavaScript {
public class ExecutableMongoScript {
private final String code;
/**
* Creates new {@link ExecutableMongoScript}.
*
* @param code must not be {@literal null} or {@literal empty}.
* @param code must not be {@literal null} or empty.
*/
public ExecutableMongoScript(String code) {
@ -38,13 +39,12 @@ public class ExecutableMongoScript implements ServerSideJavaScript { @@ -38,13 +39,12 @@ public class ExecutableMongoScript implements ServerSideJavaScript {
this.code = code;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.script.MongoScript#getCode()
/**
* Returns the actual script code.
*
* @return will never be {@literal null} or empty.
*/
@Override
public String getCode() {
return this.code;
}
}

54
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/CallableMongoScript.java → spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/NamedMongoScript.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,62 +19,68 @@ import org.springframework.data.annotation.Id; @@ -19,62 +19,68 @@ import org.springframework.data.annotation.Id;
import org.springframework.util.Assert;
/**
* A {@link ServerSideJavaScript} implementation that allows calling the function by its {@literal name} once it has
* been saved to the {@link com.mongodb.DB} instance.
* An {@link ExecutableMongoScript} assigned to a name that allows calling the function by its {@literal name} once it
* has been saved to the {@link com.mongodb.DB} instance.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class CallableMongoScript implements ServerSideJavaScript {
public class NamedMongoScript {
private final @Id String name;
private final ServerSideJavaScript script;
private final ExecutableMongoScript script;
/**
* Creates new {@link CallableMongoScript} that can be saved to the {@link com.mongodb.DB} instance.
* Creates new {@link NamedMongoScript} that can be saved to the {@link com.mongodb.DB} instance.
*
* @param name must not be {@literal null} or {@literal empty}.
* @param name must not be {@literal null} or empty.
* @param rawScript the {@link String} representation of the {@literal JavaScript} function. Must not be
* {@literal null} or {@literal empty}.
* {@literal null} or empty.
*/
public CallableMongoScript(String name, String rawScript) {
public NamedMongoScript(String name, String rawScript) {
this(name, new ExecutableMongoScript(rawScript));
}
/**
* Creates new {@link CallableMongoScript}.
* Creates new {@link NamedMongoScript}.
*
* @param name must not be {@literal null} or {@literal empty}.
* @param script can be {@literal null}.
* @param name must not be {@literal null} or empty.
* @param script must not be {@literal null}.
*/
public CallableMongoScript(String name, ServerSideJavaScript script) {
public NamedMongoScript(String name, ExecutableMongoScript script) {
Assert.hasText(name, "Name must not be null or empty!");
Assert.notNull(script, "ExecutableMongoScript must not be null!");
this.name = name;
this.script = script;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.script.MongoScript#getCode()
/**
* Returns the actual script code.
*
* @return will never be {@literal null}.
*/
@Override
public String getCode() {
if (script == null) {
return null;
return script.getCode();
}
return script.getCode();
/**
* Returns the underlying {@link ExecutableMongoScript}.
*
* @return will never be {@literal null}.
*/
public ExecutableMongoScript getScript() {
return script;
}
/**
* Get the name of the {@link CallableMongoScript} script.
* Returns the name of the script.
*
* @return
* @return will never be {@literal null} or empty.
*/
public String getName() {
return name;
}
}

30
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/script/ServerSideJavaScript.java

@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
/*
* Copyright 2014 the original author or authors.
*
* 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 org.springframework.data.mongodb.core.script;
/**
* @author Christoph Strobl
* @since 1.7
*/
public interface ServerSideJavaScript {
/**
* Get the {@link String} representation of the JavaScript code.
*
* @return {@literal null} when no code available.
*/
String getCode();
}

41
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultScriptOperationsTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,26 +15,22 @@ @@ -15,26 +15,22 @@
*/
package org.springframework.data.mongodb.core;
import static org.hamcrest.collection.IsEmptyCollection.*;
import static org.hamcrest.core.Is.*;
import static org.hamcrest.core.IsCollectionContaining.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import org.hamcrest.core.Is;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.UncategorizedDataAccessException;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.script.CallableMongoScript;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ -43,7 +39,11 @@ import com.mongodb.Mongo; @@ -43,7 +39,11 @@ import com.mongodb.Mongo;
import com.mongodb.MongoClient;
/**
* Integration tests for {@link DefaultScriptOperations}.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@ -70,7 +70,7 @@ public class DefaultScriptOperationsTests { @@ -70,7 +70,7 @@ public class DefaultScriptOperationsTests {
static final String SCRIPT_NAME = "echo";
static final String JS_FUNCTION = "function(x) { return x; }";
static final ExecutableMongoScript EXECUTABLE_SCRIPT = new ExecutableMongoScript(JS_FUNCTION);
static final CallableMongoScript CALLABLE_SCRIPT = new CallableMongoScript(SCRIPT_NAME, JS_FUNCTION);
static final NamedMongoScript CALLABLE_SCRIPT = new NamedMongoScript(SCRIPT_NAME, JS_FUNCTION);
@Autowired MongoTemplate template;
DefaultScriptOperations scriptOps;
@ -87,18 +87,7 @@ public class DefaultScriptOperationsTests { @@ -87,18 +87,7 @@ public class DefaultScriptOperationsTests {
*/
@Test
public void executeShouldDirectlyRunExecutableMongoScript() {
Object result = scriptOps.execute(EXECUTABLE_SCRIPT, 10);
assertThat(result, Is.<Object> is(10D));
}
/**
* @see DATAMONGO-479
*/
@Test(expected = DataAccessException.class)
public void executeThowsDataAccessExceptionWhenRunningCallableScriptThatHasNotBeenSavedBefore() {
scriptOps.execute(CALLABLE_SCRIPT, 10);
assertThat(scriptOps.execute(EXECUTABLE_SCRIPT, 10), is((Object) 10D));
}
/**
@ -121,7 +110,7 @@ public class DefaultScriptOperationsTests { @@ -121,7 +110,7 @@ public class DefaultScriptOperationsTests {
@Test
public void saveShouldStoreExecutableScriptCorrectly() {
CallableMongoScript script = scriptOps.register(EXECUTABLE_SCRIPT);
NamedMongoScript script = scriptOps.register(EXECUTABLE_SCRIPT);
Query query = query(where("_id").is(script.getName()));
assumeThat(template.exists(query, JAVASCRIPT_COLLECTION_NAME), is(true));
@ -138,9 +127,9 @@ public class DefaultScriptOperationsTests { @@ -138,9 +127,9 @@ public class DefaultScriptOperationsTests {
Query query = query(where("_id").is(SCRIPT_NAME));
assumeThat(template.exists(query, JAVASCRIPT_COLLECTION_NAME), is(true));
Object result = scriptOps.execute(CALLABLE_SCRIPT, 10);
Object result = scriptOps.call(CALLABLE_SCRIPT.getName(), 10);
assertThat(result, Is.<Object> is(10D));
assertThat(result, is((Object) 10D));
}
/**
@ -172,7 +161,7 @@ public class DefaultScriptOperationsTests { @@ -172,7 +161,7 @@ public class DefaultScriptOperationsTests {
Object result = scriptOps.call(SCRIPT_NAME, 10);
assertThat(result, Is.<Object> is(10D));
assertThat(result, is((Object) 10D));
}
/**
@ -191,7 +180,7 @@ public class DefaultScriptOperationsTests { @@ -191,7 +180,7 @@ public class DefaultScriptOperationsTests {
scriptOps.register(CALLABLE_SCRIPT);
assertThat(scriptOps.scriptNames(), hasItems("echo"));
assertThat(scriptOps.getScriptNames(), hasItems("echo"));
}
/**
@ -199,6 +188,6 @@ public class DefaultScriptOperationsTests { @@ -199,6 +188,6 @@ public class DefaultScriptOperationsTests {
*/
@Test
public void scriptNamesShouldReturnEmptySetWhenNoScriptRegistered() {
assertThat(scriptOps.scriptNames(), empty());
assertThat(scriptOps.getScriptNames(), is(empty()));
}
}

32
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DefaultScriptOperationsUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,30 +26,41 @@ import org.junit.runner.RunWith; @@ -26,30 +26,41 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.mongodb.core.script.CallableMongoScript;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
/**
* Unit tests for {@link DefaultScriptOperations}.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
@RunWith(MockitoJUnitRunner.class)
public class DefaultScriptOperationsUnitTests {
DefaultScriptOperations scriptOps;
@Mock MongoOperations mongoOperationsMock;
@Mock MongoOperations mongoOperations;
@Before
public void setUp() {
this.scriptOps = new DefaultScriptOperations(mongoOperationsMock);
this.scriptOps = new DefaultScriptOperations(mongoOperations);
}
/**
* @see DATAMONGO-479
*/
@Test(expected = IllegalArgumentException.class)
public void rejectsNullExecutableMongoScript() {
scriptOps.register((ExecutableMongoScript) null);
}
/**
* @see DATAMONGO-479
*/
@Test(expected = IllegalArgumentException.class)
public void saveShouldThrowExceptionWhenCalledWithNullValue() {
scriptOps.register(null);
public void rejectsNullNamedMongoScript() {
scriptOps.register((NamedMongoScript) null);
}
/**
@ -58,9 +69,9 @@ public class DefaultScriptOperationsUnitTests { @@ -58,9 +69,9 @@ public class DefaultScriptOperationsUnitTests {
@Test
public void saveShouldUseCorrectCollectionName() {
scriptOps.register(new CallableMongoScript("foo", "function..."));
scriptOps.register(new NamedMongoScript("foo", "function..."));
verify(mongoOperationsMock, times(1)).save(any(CallableMongoScript.class), eq("system.js"));
verify(mongoOperations, times(1)).save(any(NamedMongoScript.class), eq("system.js"));
}
/**
@ -71,9 +82,9 @@ public class DefaultScriptOperationsUnitTests { @@ -71,9 +82,9 @@ public class DefaultScriptOperationsUnitTests {
scriptOps.register(new ExecutableMongoScript("function..."));
ArgumentCaptor<CallableMongoScript> captor = ArgumentCaptor.forClass(CallableMongoScript.class);
ArgumentCaptor<NamedMongoScript> captor = ArgumentCaptor.forClass(NamedMongoScript.class);
verify(mongoOperationsMock, times(1)).save(captor.capture(), eq("system.js"));
verify(mongoOperations, times(1)).save(captor.capture(), eq("system.js"));
Assert.assertThat(captor.getValue().getName(), notNullValue());
}
@ -116,5 +127,4 @@ public class DefaultScriptOperationsUnitTests { @@ -116,5 +127,4 @@ public class DefaultScriptOperationsUnitTests {
public void callShouldThrowExceptionWhenScriptNameIsEmpty() {
scriptOps.call("");
}
}

58
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CallableMongoScriptConvertsUnitTests.java → spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/NamedMongoScriptConvertsUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,53 +15,55 @@ @@ -15,53 +15,55 @@
*/
package org.springframework.data.mongodb.core.convert;
import static org.hamcrest.core.IsEqual.*;
import static org.hamcrest.core.IsInstanceOf.*;
import static org.hamcrest.core.IsNull.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import org.bson.types.Code;
import org.hamcrest.core.IsEqual;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import org.springframework.data.mongodb.core.convert.CallableMongoScriptConvertsUnitTests.CallableMongoScriptToDboConverterUnitTests;
import org.springframework.data.mongodb.core.convert.CallableMongoScriptConvertsUnitTests.DboToCallableMongoScriptConverterUnitTests;
import org.springframework.data.mongodb.core.convert.MongoConverters.CallableMongoScriptToDBObjectConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToCallableMongoScriptCoverter;
import org.springframework.data.mongodb.core.script.CallableMongoScript;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToNamedMongoScriptCoverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.NamedMongoScriptToDBObjectConverter;
import org.springframework.data.mongodb.core.convert.NamedMongoScriptConvertsUnitTests.DboToNamedMongoScriptConverterUnitTests;
import org.springframework.data.mongodb.core.convert.NamedMongoScriptConvertsUnitTests.NamedMongoScriptToDboConverterUnitTests;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject;
/**
* Unit tests for {@link Converter} implementations for {@link NamedMongoScript}.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
@RunWith(Suite.class)
@SuiteClasses({ CallableMongoScriptToDboConverterUnitTests.class, DboToCallableMongoScriptConverterUnitTests.class })
public class CallableMongoScriptConvertsUnitTests {
@SuiteClasses({ NamedMongoScriptToDboConverterUnitTests.class, DboToNamedMongoScriptConverterUnitTests.class })
public class NamedMongoScriptConvertsUnitTests {
static final String FUNCTION_NAME = "echo";
static final String JS_FUNCTION = "function(x) { return x; }";
static final CallableMongoScript ECHO_SCRIPT = new CallableMongoScript(FUNCTION_NAME, JS_FUNCTION);
static final NamedMongoScript ECHO_SCRIPT = new NamedMongoScript(FUNCTION_NAME, JS_FUNCTION);
static final DBObject FUNCTION = new BasicDBObjectBuilder().add("_id", FUNCTION_NAME)
.add("value", new Code(JS_FUNCTION)).get();
/**
* @author Christoph Strobl
*/
public static class CallableMongoScriptToDboConverterUnitTests {
public static class NamedMongoScriptToDboConverterUnitTests {
CallableMongoScriptToDBObjectConverter converter = CallableMongoScriptToDBObjectConverter.INSTANCE;
NamedMongoScriptToDBObjectConverter converter = NamedMongoScriptToDBObjectConverter.INSTANCE;
/**
* @see DATAMONGO-479
*/
@Test
public void convertShouldReturnEmptyDboWhenScriptIsNull() {
assertThat(converter.convert(null), IsEqual.<DBObject> equalTo(new BasicDBObject()));
assertThat(converter.convert(null), is((DBObject) new BasicDBObject()));
}
/**
@ -73,8 +75,8 @@ public class CallableMongoScriptConvertsUnitTests { @@ -73,8 +75,8 @@ public class CallableMongoScriptConvertsUnitTests {
DBObject dbo = converter.convert(ECHO_SCRIPT);
Object id = dbo.get("_id");
assertThat(id, instanceOf(String.class));
assertThat(id, IsEqual.<Object> equalTo(FUNCTION_NAME));
assertThat(id, is(instanceOf(String.class)));
assertThat(id, is((Object) FUNCTION_NAME));
}
/**
@ -86,24 +88,24 @@ public class CallableMongoScriptConvertsUnitTests { @@ -86,24 +88,24 @@ public class CallableMongoScriptConvertsUnitTests {
DBObject dbo = converter.convert(ECHO_SCRIPT);
Object code = dbo.get("value");
assertThat(code, instanceOf(Code.class));
assertThat(code, equalTo((Object) new Code(JS_FUNCTION)));
assertThat(code, is(instanceOf(Code.class)));
assertThat(code, is((Object) new Code(JS_FUNCTION)));
}
}
/**
* @author Christoph Strobl
*/
public static class DboToCallableMongoScriptConverterUnitTests {
public static class DboToNamedMongoScriptConverterUnitTests {
DBObjectToCallableMongoScriptCoverter converter = DBObjectToCallableMongoScriptCoverter.INSTANCE;
DBObjectToNamedMongoScriptCoverter converter = DBObjectToNamedMongoScriptCoverter.INSTANCE;
/**
* @see DATAMONGO-479
*/
@Test
public void convertShouldReturnNullIfSourceIsNull() {
assertThat(converter.convert(null), nullValue());
assertThat(converter.convert(null), is(nullValue()));
}
/**
@ -112,9 +114,9 @@ public class CallableMongoScriptConvertsUnitTests { @@ -112,9 +114,9 @@ public class CallableMongoScriptConvertsUnitTests {
@Test
public void convertShouldConvertIdCorreclty() {
CallableMongoScript script = converter.convert(FUNCTION);
NamedMongoScript script = converter.convert(FUNCTION);
assertThat(script.getName(), equalTo(FUNCTION_NAME));
assertThat(script.getName(), is(FUNCTION_NAME));
}
/**
@ -123,10 +125,10 @@ public class CallableMongoScriptConvertsUnitTests { @@ -123,10 +125,10 @@ public class CallableMongoScriptConvertsUnitTests {
@Test
public void convertShouldConvertScriptValueCorreclty() {
CallableMongoScript script = converter.convert(FUNCTION);
NamedMongoScript script = converter.convert(FUNCTION);
assertThat(script.getCode(), notNullValue());
assertThat(script.getCode(), equalTo(JS_FUNCTION));
assertThat(script.getCode(), is(notNullValue()));
assertThat(script.getCode(), is(JS_FUNCTION));
}
}

21
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/script/CallableMongoScriptUnitTests.java → spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/script/NamedMongoScriptUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,22 +15,26 @@ @@ -15,22 +15,26 @@
*/
package org.springframework.data.mongodb.core.script;
import static org.hamcrest.core.IsEqual.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* Unit tests for {@link NamedMongoScript}.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class CallableMongoScriptUnitTests {
public class NamedMongoScriptUnitTests {
/**
* @see DATAMONGO-479
*/
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenScriptNameIsNull() {
new CallableMongoScript(null, "return 1;");
new NamedMongoScript(null, "return 1;");
}
/**
@ -38,7 +42,7 @@ public class CallableMongoScriptUnitTests { @@ -38,7 +42,7 @@ public class CallableMongoScriptUnitTests {
*/
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenScriptNameIsEmptyString() {
new CallableMongoScript("", "return 1");
new NamedMongoScript("", "return 1");
}
/**
@ -46,7 +50,7 @@ public class CallableMongoScriptUnitTests { @@ -46,7 +50,7 @@ public class CallableMongoScriptUnitTests {
*/
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenRawScriptIsEmptyString() {
new CallableMongoScript("foo", "");
new NamedMongoScript("foo", "");
}
/**
@ -57,9 +61,6 @@ public class CallableMongoScriptUnitTests { @@ -57,9 +61,6 @@ public class CallableMongoScriptUnitTests {
String jsFunction = "function(x) { return x; }";
CallableMongoScript script = new CallableMongoScript("echo", jsFunction);
assertThat(script.getCode(), equalTo(jsFunction));
assertThat(new NamedMongoScript("echo", jsFunction).getCode(), is(jsFunction));
}
}
Loading…
Cancel
Save