/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-services/src/test/org/sakaiproject/tool/assessment/services/GradingServiceTest.java $
* $Id: GradingServiceTest.java 124673 2013-05-20 15:40:31Z azeckoski@unicon.net $
***********************************************************************************
*
* Copyright (c) 2004, 2005, 2006, 2008 The Sakai Foundation
*
* Licensed under the Educational Community 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.opensource.org/licenses/ECL-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.sakaiproject.tool.assessment.services;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.sakaiproject.tool.assessment.services.GradingService;
import org.sakaiproject.tool.assessment.util.SamigoExpressionError;
import org.springframework.test.AbstractTransactionalSpringContextTests;
public class GradingServiceTest extends AbstractTransactionalSpringContextTests {
GradingService gradingService;
String sampleItemText1 = "Alice has {A} apples, Bob has {B} apples, and Charles has {C} apples. Of the total apples among the group, what percent are Bob's? {{SOLUTION}}";
String sampleSolutionFormula = "({B} / ({A} + {B} + {C}))*100";
String sampleItemText1WithCalc = "Alice has {A} apples, Bob has {B} apples, and Charles has {C} apples. Of the [[{A} + {B} + {C}]] apples among the group, {{SOLUTION}} percent are Bob's.";
String sampleItemText2 = "Sample (1) {var1} * {var2} + {var3} = {{formula1}}, and also {var1} + {var2} - {var3} = {{formula2}}, more [random] text";
String sampleFormula2a = "{var1} * {var2} + {var3}";
String sampleFormula2b = "{var1 + {var2} - {var3}";
String sampleItemText3 = "{var0} Sample (1) {var1} + {var2} + {var3} = {{formula1}}, calc=[[{var0}+{var1}+{var2}+{var3}+{var4}]] more [random] text, dblvar1=[[{var1}*2]] f2={{{formula2}}} and c3=[[[{var2}]]] and not calc=[[plain text]] and {var4}";
String sampleFormula3 = "{var1}+{var2}+{var3}";
@Override
protected void onSetUp() throws Exception {
super.onSetUp();
gradingService = new GradingService();
}
// CALCULATED_QUESTION tests
public void testMatchPatterns() {
List<String> results = null;
results = gradingService.extractVariables(sampleItemText1);
assertNotNull(results);
assertEquals(3, results.size());
assertEquals("A", results.get(0));
assertEquals("B", results.get(1));
assertEquals("C", results.get(2));
results = gradingService.extractFormulas(sampleItemText1);
assertNotNull(results);
assertEquals("SOLUTION", results.get(0));
assertEquals(1, results.size());
results = gradingService.extractCalculations(sampleItemText1);
assertNotNull(results);
assertEquals(0, results.size());
results = gradingService.extractVariables(sampleItemText2);
assertNotNull(results);
assertEquals(3, results.size());
assertEquals("var1", results.get(0));
assertEquals("var2", results.get(1));
assertEquals("var3", results.get(2));
results = gradingService.extractFormulas(sampleItemText2);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("formula1", results.get(0));
assertEquals("formula2", results.get(1));
results = gradingService.extractCalculations(sampleItemText2);
assertNotNull(results);
assertEquals(0, results.size());
results = gradingService.extractVariables(sampleItemText1WithCalc);
assertNotNull(results);
assertEquals(3, results.size());
assertEquals("A", results.get(0));
assertEquals("B", results.get(1));
assertEquals("C", results.get(2));
results = gradingService.extractFormulas(sampleItemText1WithCalc);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("SOLUTION", results.get(0));
results = gradingService.extractCalculations(sampleItemText1WithCalc);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("{A} + {B} + {C}", results.get(0));
results = gradingService.extractVariables(sampleItemText3);
assertNotNull(results);
assertEquals(5, results.size());
assertEquals("var0", results.get(0));
assertEquals("var1", results.get(1));
assertEquals("var2", results.get(2));
assertEquals("var3", results.get(3));
assertEquals("var4", results.get(4));
results = gradingService.extractFormulas(sampleItemText3);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("formula1", results.get(0));
assertEquals("formula2", results.get(1));
results = gradingService.extractCalculations(sampleItemText3);
assertNotNull(results);
assertEquals(3, results.size());
assertEquals("{var0}+{var1}+{var2}+{var3}+{var4}", results.get(0));
assertEquals("{var1}*2", results.get(1));
assertEquals("{var2}", results.get(2));
}
public void testExtractVariablesFormulas() {
List<String> results = null;
String text = null;
text = "{A}+{B}={{D}} Hint: [[{A}-{B}]]";
results = gradingService.extractVariables(text);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("A", results.get(0));
assertEquals("B", results.get(1));
results = gradingService.extractFormulas(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("D", results.get(0));
text = "{aaa11}+{bbb}={{dAnSw_3r}} Hint: [[{aaa11}-{bbb}]]";
results = gradingService.extractVariables(text);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("aaa11", results.get(0));
assertEquals("bbb", results.get(1));
results = gradingService.extractFormulas(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("dAnSw_3r", results.get(0));
text = "{A} + {B} = {{D}} Hint: [[ {A} + {B} ]]";
results = gradingService.extractVariables(text);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("A", results.get(0));
assertEquals("B", results.get(1));
results = gradingService.extractFormulas(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("D", results.get(0));
text = "{A}*{B}={{D}} Hint: [[{A}*{B}]]";
results = gradingService.extractVariables(text);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("A", results.get(0));
assertEquals("B", results.get(1));
results = gradingService.extractFormulas(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("D", results.get(0));
text = "{A}-{B}={{D}} Hint: [[{A}-{B}]]";
results = gradingService.extractVariables(text);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("A", results.get(0));
assertEquals("B", results.get(1));
results = gradingService.extractFormulas(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("D", results.get(0));
text = "{A}/{B}={{D}} Hint: [[{A}/{B}]]";
results = gradingService.extractVariables(text);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("A", results.get(0));
assertEquals("B", results.get(1));
results = gradingService.extractFormulas(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("D", results.get(0));
// single variable
text = "{A}={{D}} Hint: [[{A}]]";
results = gradingService.extractVariables(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("A", results.get(0));
results = gradingService.extractFormulas(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("D", results.get(0));
// 3 variables
text = "{A}+{B}+{C}={{D}} Hint: [[{A}+{B}+{C}]]";
results = gradingService.extractVariables(text);
assertNotNull(results);
assertEquals(3, results.size());
assertEquals("A", results.get(0));
assertEquals("B", results.get(1));
assertEquals("C", results.get(2));
results = gradingService.extractFormulas(text);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals("D", results.get(0));
}
public void testExtractInstructionSegments() {
List<String> results = null;
results = gradingService.extractInstructionSegments(sampleItemText1);
assertNotNull(results);
assertEquals(2, results.size());
assertEquals("", results.get(1)); // when formula is at the end it adds an empty string
results = gradingService.extractInstructionSegments(sampleItemText2);
assertNotNull(results);
assertEquals(3, results.size());
}
public void testCalculationsToValues() throws SamigoExpressionError {
String result = null;
result = gradingService.replaceCalculationsWithValues("four=[[2+2]]", 0);
assertNotNull(result);
assertEquals("four=4", result);
result = gradingService.replaceCalculationsWithValues("four=[[2.2+2]]", 1);
assertNotNull(result);
assertEquals("four=4.2", result);
result = gradingService.replaceCalculationsWithValues("four=[[2+2]]", -1);
assertNotNull(result);
assertEquals("four=4", result);
result = gradingService.replaceCalculationsWithValues("four=[[2+2]], four=[[2*2]], four=[[(10-2)/2]]", 0);
assertNotNull(result);
assertEquals("four=4, four=4, four=4", result);
result = gradingService.replaceCalculationsWithValues("test=[[\n 2 + 10 + 2]]", 0);
assertNotNull(result);
assertEquals("test=14", result);
// blanks and line returns in formulas cause problems for the parser
result = gradingService.processFormulaIntoValue("\n 2 + 10 + 2", 0);
assertNotNull(result);
assertEquals("14", result);
result = gradingService.processFormulaIntoValue("\n 2 + 10 + 2", 0);
assertNotNull(result);
assertEquals("14", result);
result = gradingService.processFormulaIntoValue("\n 5 \n + 2.0\n + 3 ", 0);
assertNotNull(result);
assertEquals("10", result);
// https://jira.sakaiproject.org/browse/SAM-2157
// 500 formula processor error occurs when either ^ or / is entered in a Formula (at any time)
result = gradingService.processFormulaIntoValue("2^2", 0);
assertNotNull(result);
assertEquals("4", result);
result = gradingService.processFormulaIntoValue("2^1", 0);
assertNotNull(result);
assertEquals("2", result);
result = gradingService.processFormulaIntoValue("2^0", 0);
assertNotNull(result);
assertEquals("1", result);
result = gradingService.processFormulaIntoValue("10^1", 0);
assertNotNull(result);
assertEquals("10", result);
result = gradingService.processFormulaIntoValue("1^10", 0);
assertNotNull(result);
assertEquals("1", result);
result = gradingService.processFormulaIntoValue("2 ^ 2", 0); // with spaces
assertNotNull(result);
assertEquals("4", result);
result = gradingService.processFormulaIntoValue("2/2", 0);
assertNotNull(result);
assertEquals("1", result);
result = gradingService.processFormulaIntoValue("2/1", 0);
assertNotNull(result);
assertEquals("2", result);
result = gradingService.processFormulaIntoValue("0/2", 0);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.processFormulaIntoValue("10/2", 0);
assertNotNull(result);
assertEquals("5", result);
result = gradingService.processFormulaIntoValue("2/10", 1);
assertNotNull(result);
assertEquals("0.2", result);
result = gradingService.processFormulaIntoValue("2 / 2", 0); // with spaces
assertNotNull(result);
assertEquals("1", result);
// 500 error occurs when when asin or acos is entered in the formula fields
result = gradingService.processFormulaIntoValue("sin(0)", 2);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.processFormulaIntoValue("cos(0)", 2);
assertNotNull(result);
assertEquals("1", result);
result = gradingService.processFormulaIntoValue("tan(0)", 2);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.processFormulaIntoValue("sin(PI)", 2);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.processFormulaIntoValue("cos(PI)", 2);
assertNotNull(result);
assertEquals("-1", result);
result = gradingService.processFormulaIntoValue("tan(PI)", 2);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.processFormulaIntoValue("sin(1)", 2);
assertNotNull(result);
assertEquals("0.84", result);
result = gradingService.processFormulaIntoValue("cos(1)", 2);
assertNotNull(result);
assertEquals("0.54", result);
result = gradingService.processFormulaIntoValue("tan(1)", 2);
assertNotNull(result);
assertEquals("1.56", result);
result = gradingService.processFormulaIntoValue("asin(0)", 2);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.processFormulaIntoValue("acos(0)", 2);
assertNotNull(result);
assertEquals("1.57", result);
result = gradingService.processFormulaIntoValue("atan(0)", 2);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.processFormulaIntoValue("asin(1)", 2);
assertNotNull(result);
assertEquals("1.57", result);
result = gradingService.processFormulaIntoValue("acos(1)", 2);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.processFormulaIntoValue("atan(1)", 2);
assertNotNull(result);
assertEquals("0.78", result);
}
public void testReplaceMappedVariablesWithNumbers() throws Exception {
String input = null;
String result = null;
String expected = null;
String expected2 = null;
Map<String, String> map = null;
input = "this is {var1}";
map = new HashMap<String, String>() {{
put("var1", "simple");
}};
result = gradingService.replaceMappedVariablesWithNumbers(input, map);
assertNotNull(result);
assertEquals("this is simple", result);
input = "this is {var1} + {var2} + {var3} = {{formula1}}";
map = new HashMap<String, String>() {{
put("var1", "10");
put("var2", "5");
put("var3", "1");
}};
result = gradingService.replaceMappedVariablesWithNumbers(input, map);
assertNotNull(result);
assertEquals("this is 10 + 5 + 1 = {{formula1}}", result);
input = "this is {var1} + {var2} + {var3} = {{formula1}}, total=[[{var1}+{var2}+{var3}]]";
expected = "this is 10 + 5 + 1 = {{formula1}}, total=[[10+5+1]]";
expected2 = "this is 10 + 5 + 1 = {{formula1}}, total=16";
map = new HashMap<String, String>() {{
put("var1", "10");
put("var2", "5");
put("var3", "1");
}};
result = gradingService.replaceMappedVariablesWithNumbers(input, map);
assertNotNull(result);
assertEquals(expected, result);
result = gradingService.replaceCalculationsWithValues(expected, 2);
assertNotNull(result);
assertEquals(expected2, result);
input = "<p> SAMPLE 1 for testing:<br /> {A} + {B} = {{answer1}}<br /> {B} + {C} = {{answer2}}<br /> {C} + {D} = {{answer3}}<br /> Total: [[{A} + {B} + {C} + {D}]]</p>";
expected = "<p> SAMPLE 1 for testing:<br /> 1 + 2 = {{answer1}}<br /> 2 + 3 = {{answer2}}<br /> 3 + 4 = {{answer3}}<br /> Total: [[1 + 2 + 3 + 4]]</p>";
expected2 = "<p> SAMPLE 1 for testing:<br /> 1 + 2 = {{answer1}}<br /> 2 + 3 = {{answer2}}<br /> 3 + 4 = {{answer3}}<br /> Total: 10</p>";
map = new HashMap<String, String>() {{
put("A", "1");
put("B", "2");
put("C", "3");
put("D", "4");
}};
result = gradingService.replaceMappedVariablesWithNumbers(input, map);
assertNotNull(result);
assertEquals(expected, result);
result = gradingService.replaceCalculationsWithValues(expected, 2);
assertNotNull(result);
assertEquals(expected2, result);
}
public void testApplyPrecisionToNumberString() {
String result;
result = gradingService.applyPrecisionToNumberString("123", 4);
assertNotNull(result);
assertEquals("123", result);
result = gradingService.applyPrecisionToNumberString("1.0", 0);
assertNotNull(result);
assertEquals("1", result);
result = gradingService.applyPrecisionToNumberString("0", 1);
assertNotNull(result);
assertEquals("0", result);
result = gradingService.applyPrecisionToNumberString("123.000", 0);
assertNotNull(result);
assertEquals("123", result);
result = gradingService.applyPrecisionToNumberString("123.000", 4);
assertNotNull(result);
assertEquals("123", result);
result = gradingService.applyPrecisionToNumberString("123.0102000", 4);
assertNotNull(result);
assertEquals("123.0102", result);
result = gradingService.applyPrecisionToNumberString("123.0102000", 3);
assertNotNull(result);
assertEquals("123.01", result);
}
}