Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[Wtp-wst-dev] XPath2 - bugs + tests (2)

Hello,

Some other bugs:

5. FnRoundHalfToEven in case of 2 arguments

http://www.w3.org/TR/xquery-operators/#func-round-half-to-even

Function requires ‘number?’ what means that either empty sequence and node should be considered as correct arguments. It required to use already corrected function (bug 1) to atomize argument – FnRoundHalfToEven:93-97. Tests:

TestBugs:testNumericFunctionOnEmptySequence() and TestBugs:testFunctionAtomization2()

 

6. Aggregations with nil=’true’. By now they throw exceptions.

TypePromoter needed changes to take empty sequences as possible arguments.

Since count was not changed and avg=sum div count - fix takes empty nodes to average:

http://www.w3.org/TR/xquery-operators/#func-avg

Please also note that $zero (second argument) in function needed to be used in empty nodes:

http://www.w3.org/TR/xquery-operators/#func-sum

Tests:

TestBugs:testNumberAggregationWithNill()

 

Tests are accumulative but I think it’s not a problem since they are single methods in on class.

 

Regards,

Wojciech Diakowski
and Łukasz Wycisk

Index: src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnRoundHalfToEven.java
===================================================================
RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnRoundHalfToEven.java,v
retrieving revision 1.6
diff -u -r1.6 FnRoundHalfToEven.java
--- src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnRoundHalfToEven.java	19 Apr 2011 22:00:23 -0000	1.6
+++ src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnRoundHalfToEven.java	13 Oct 2011 13:29:02 -0000
@@ -90,7 +90,12 @@
 		ResultSequence rsArg1 =  (ResultSequence) argIt.next();
 		ResultSequence rsPrecision = (ResultSequence) argIt.next();
 		
-		NumericType nt = (NumericType) rsArg1.first();
+		NumericType nt = FnAbs.get_single_numeric_arg(rsArg1);
+
+		// empty arg
+		if (nt == null)
+			return ResultBuffer.EMPTY;
+		
 		NumericType ntPrecision = (NumericType) rsPrecision.first();
 		
 		return nt.round_half_to_even(Integer.parseInt(ntPrecision.getStringValue()));
Index: src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnAvg.java
===================================================================
RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnAvg.java,v
retrieving revision 1.15
diff -u -r1.15 FnAvg.java
--- src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnAvg.java	19 Apr 2011 22:00:22 -0000	1.15
+++ src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnAvg.java	14 Oct 2011 10:11:50 -0000
@@ -86,14 +86,16 @@
 		for (Iterator i = arg.iterator(); i.hasNext();) {
 			++elems;
 			AnyAtomicType conv = tp.promote((AnyType) i.next());
-			
-			if (conv instanceof XSDouble && ((XSDouble)conv).nan() || conv instanceof XSFloat && ((XSFloat)conv).nan()) {
-				return ResultSequenceFactory.create_new(tp.promote(new XSFloat(Float.NaN)));
-			}
-			if (total == null) {
-				total = (MathPlus)conv; 
-			} else {
-				total = (MathPlus)total.plus(ResultSequenceFactory.create_new(conv)).first();
+			if( conv != null ){
+				
+				if (conv instanceof XSDouble && ((XSDouble)conv).nan() || conv instanceof XSFloat && ((XSFloat)conv).nan()) {
+					return ResultSequenceFactory.create_new(tp.promote(new XSFloat(Float.NaN)));
+				}
+				if (total == null) {
+					total = (MathPlus)conv; 
+				} else {
+					total = (MathPlus)total.plus(ResultSequenceFactory.create_new(conv)).first();
+				}
 			}
 		}
 
Index: src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnMax.java
===================================================================
RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnMax.java,v
retrieving revision 1.8
diff -u -r1.8 FnMax.java
--- src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnMax.java	19 Apr 2011 22:00:23 -0000	1.8
+++ src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnMax.java	14 Oct 2011 10:11:50 -0000
@@ -83,11 +83,14 @@
 		for (Iterator i = arg.iterator(); i.hasNext();) {
 			AnyAtomicType conv = tp.promote((AnyType) i.next());
 			
-			if (conv instanceof XSDouble && ((XSDouble)conv).nan() || conv instanceof XSFloat && ((XSFloat)conv).nan()) {
-				return ResultSequenceFactory.create_new(tp.promote(new XSFloat(Float.NaN)));
-			}
-			if (max == null || ((CmpGt)conv).gt((AnyType)max, dynamicContext)) {
-				max = (CmpGt)conv;
+			if( conv != null ){
+				
+				if (conv instanceof XSDouble && ((XSDouble)conv).nan() || conv instanceof XSFloat && ((XSFloat)conv).nan()) {
+					return ResultSequenceFactory.create_new(tp.promote(new XSFloat(Float.NaN)));
+				}
+				if (max == null || ((CmpGt)conv).gt((AnyType)max, dynamicContext)) {
+					max = (CmpGt)conv;
+				}
 			}
 		}
 		return ResultSequenceFactory.create_new((AnyType) max);
Index: src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnMin.java
===================================================================
RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnMin.java,v
retrieving revision 1.8
diff -u -r1.8 FnMin.java
--- src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnMin.java	19 Apr 2011 22:00:22 -0000	1.8
+++ src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnMin.java	14 Oct 2011 10:11:50 -0000
@@ -83,11 +83,14 @@
 		for (Iterator i = arg.iterator(); i.hasNext();) {
 			AnyAtomicType conv = tp.promote((AnyType) i.next());
 			
-			if (conv instanceof XSDouble && ((XSDouble)conv).nan() || conv instanceof XSFloat && ((XSFloat)conv).nan()) {
-				return ResultSequenceFactory.create_new(tp.promote(new XSFloat(Float.NaN)));
-			}
-			if (max == null || ((CmpLt)conv).lt((AnyType)max, context)) {
-				max = (CmpLt)conv;
+			if( conv != null ){
+				
+				if (conv instanceof XSDouble && ((XSDouble)conv).nan() || conv instanceof XSFloat && ((XSFloat)conv).nan()) {
+					return ResultSequenceFactory.create_new(tp.promote(new XSFloat(Float.NaN)));
+				}
+				if (max == null || ((CmpLt)conv).lt((AnyType)max, context)) {
+					max = (CmpLt)conv;
+				}
 			}
 		}
 		return ResultSequenceFactory.create_new((AnyType) max);
Index: src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnSum.java
===================================================================
RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnSum.java,v
retrieving revision 1.7
diff -u -r1.7 FnSum.java
--- src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnSum.java	19 Apr 2011 22:00:22 -0000	1.7
+++ src/org/eclipse/wst/xml/xpath2/processor/internal/function/FnSum.java	14 Oct 2011 10:11:50 -0000
@@ -96,6 +96,10 @@
 		for (Iterator i = arg.iterator(); i.hasNext();) {
 			AnyAtomicType conv = tp.promote((AnyType) i.next());
 			
+			if(conv == null){
+				conv = zero;
+			}
+			
 			if (conv instanceof XSDouble && ((XSDouble)conv).nan() || conv instanceof XSFloat && ((XSFloat)conv).nan()) {
 				return ResultSequenceFactory.create_new(tp.promote(new XSFloat(Float.NaN)));
 			}
@@ -105,6 +109,7 @@
 				total = (MathPlus)total.plus(ResultSequenceFactory.create_new(conv)).first();
 			}
 		}
+		
 		return ResultSequenceFactory.create_new((AnyType) total);
 	}
 }
Index: src/org/eclipse/wst/xml/xpath2/processor/internal/utils/TypePromoter.java
===================================================================
RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.xml.xpath2.processor/src/org/eclipse/wst/xml/xpath2/processor/internal/utils/TypePromoter.java,v
retrieving revision 1.6
diff -u -r1.6 TypePromoter.java
--- src/org/eclipse/wst/xml/xpath2/processor/internal/utils/TypePromoter.java	19 Apr 2011 22:00:25 -0000	1.6
+++ src/org/eclipse/wst/xml/xpath2/processor/internal/utils/TypePromoter.java	14 Oct 2011 10:11:50 -0000
@@ -35,7 +35,12 @@
 		// This is a short cut, really
 		if (value.getClass() == getTargetType()) return (AnyAtomicType)value;
 
-		return doPromote(atomize(value));
+		AnyAtomicType atomized = atomize(value);
+		if( atomized == null )
+		{// empty sequence
+			return null;
+		}
+		return doPromote(atomized);
 	}
 
 	/**
@@ -85,7 +90,11 @@
 
 	public AnyAtomicType atomize(Item at) {
 		if (at instanceof NodeType) {
-			return (AnyAtomicType)((NodeType)at).typed_value().first();
+			ResultSequence nodeValues = ((NodeType)at).typed_value();
+			if(nodeValues.empty()){
+				return null;
+			}
+			return (AnyAtomicType)nodeValues.first();
 		}
 		else {
 			return (AnyAtomicType)at;
@@ -93,7 +102,11 @@
 	}
 	
 	public void considerValue(Item at) throws DynamicError {
-		considerType(atomize(at).getClass());
+		final AnyAtomicType atomize = this.atomize(at);
+		if( atomize != null )
+		{// we known that it is not empty sequence
+			this.considerType(atomize.getClass());
+		}
 	}
 
 
Index: src/org/eclipse/wst/xml/xpath2/processor/test/TestBugs.java
===================================================================
RCS file: /cvsroot/webtools/sourceediting/tests/org.eclipse.wst.xml.xpath2.processor.tests/src/org/eclipse/wst/xml/xpath2/processor/test/TestBugs.java,v
retrieving revision 1.73
diff -u -r1.73 TestBugs.java
--- src/org/eclipse/wst/xml/xpath2/processor/test/TestBugs.java	8 Oct 2011 11:50:45 -0000	1.73
+++ src/org/eclipse/wst/xml/xpath2/processor/test/TestBugs.java	14 Oct 2011 11:34:12 -0000
@@ -1163,6 +1163,79 @@
 
 		assertEquals("Don't try this at \"home\", she said", resultValue);
 	}
+	
+	public void testNumericFunctionOnEmptySequence() throws Exception {
+
+		bundle = Platform.getBundle("org.w3c.xqts.testsuite");
+		URL fileURL = bundle.getEntry("/TestSources/emptydoc.xml");
+		loadDOMDocument(fileURL);
+
+		// Get XML Schema Information for the Document
+		XSModel schema = getGrammar();
+
+		setupDynamicContext(schema);
+		
+		String xpath = null;
+		ResultSequence rs = null;
+				
+		//a)
+		xpath = "fn:abs(())";
+          compileXPath(xpath);
+          rs = evaluate(domDoc);
+		assertEquals(0,rs.size());
+		
+		//b)
+		xpath = "fn:ceiling(())";
+          compileXPath(xpath);
+          rs = evaluate(domDoc);
+		assertEquals(0,rs.size());
+
+		//c)
+		xpath = "fn:floor(())";
+          compileXPath(xpath);
+          rs = evaluate(domDoc);
+		assertEquals(0,rs.size());
+		
+		//d)
+		xpath = "fn:round(())";
+          compileXPath(xpath);
+          rs = evaluate(domDoc);
+		assertEquals(0,rs.size());
+		
+		//e)
+		xpath = "fn:round-half-to-even(())";
+          compileXPath(xpath);
+          rs = evaluate(domDoc);
+		assertEquals(0,rs.size());
+		
+		//f)
+		xpath = "fn:round-half-to-even((),1)";
+          compileXPath(xpath);
+          rs = evaluate(domDoc);
+		assertEquals(0,rs.size());
+	}
+	
+	public void testSequenceAggregationOnEmpty() throws Exception {
+
+		bundle = Platform.getBundle("org.w3c.xqts.testsuite");
+		URL fileURL = bundle.getEntry("/TestSources/emptydoc.xml");
+		loadDOMDocument(fileURL);
+
+		// Get XML Schema Information for the Document
+		XSModel schema = getGrammar();
+
+		setupDynamicContext(schema);
+		
+		String xpath = null;
+		ResultSequence rs = null;
+				
+		//a)
+		xpath = "fn:sum((1,2,3,() ))";
+          compileXPath(xpath);
+          rs = evaluate(domDoc);
+          XSDecimal val = (XSDecimal)rs.first();
+		assertEquals("6",val.string_value());
+	}
 
 	public void testBug280555_collations() throws Exception {
 		// Setup context
@@ -1829,6 +1902,54 @@
 		assertEquals("true", actual);
 	}
 	
+	public void testFunctionAtomization() throws Exception {
+		// Bug 318313
+		URL fileURL = bundle.getEntry("/bugTestFiles/bug318313.xml");
+		URL schemaURL = bundle.getEntry("/bugTestFiles/bug318313.xsd");
+
+		loadDOMDocument(fileURL, schemaURL);
+
+		// Get XSModel object for the Schema
+		XSModel schema = getGrammar(schemaURL);
+
+		setupDynamicContext(schema);
+
+		String xpath = "abs(X)";
+          compileXPath(xpath);
+          ResultSequence rs = evaluate(domDoc);
+
+
+          XSInteger result = (XSInteger) rs.first();
+
+		String actual = result.getStringValue();
+
+		assertEquals("100", actual);
+	}
+	
+	public void testFunctionAtomization2() throws Exception {
+		// Bug 318313
+		URL fileURL = bundle.getEntry("/bugTestFiles/bug318313.xml");
+		URL schemaURL = bundle.getEntry("/bugTestFiles/bug318313.xsd");
+
+		loadDOMDocument(fileURL, schemaURL);
+
+		// Get XSModel object for the Schema
+		XSModel schema = getGrammar(schemaURL);
+
+		setupDynamicContext(schema);
+
+		String xpath = "fn:round-half-to-even(X,1)";
+          compileXPath(xpath);
+          ResultSequence rs = evaluate(domDoc);
+
+
+          XSDecimal result = (XSDecimal) rs.first();
+
+		String actual = result.getStringValue();
+
+		assertEquals("100", actual);
+	}
+	
 	public void testTypedValueEnhancement_Bug323900_1() throws Exception {
 		// Bug 323900
 		URL fileURL = bundle.getEntry("/bugTestFiles/bug323900_1.xml");
@@ -2351,6 +2472,119 @@
 		assertEquals("true", actual);
 	}
 	
+	public void testFnIndexOf_onQName() throws Exception {
+		// bug 338999
+		URL fileURL = bundle.getEntry("/bugTestFiles/bug338999.xml");
+		URL schemaURL = bundle.getEntry("/bugTestFiles/bug338999.xsd");
+
+		loadDOMDocument(fileURL, schemaURL);
+
+		// Get XSModel object for the Schema
+		XSModel schema = getGrammar(schemaURL);
+
+		setupDynamicContext(schema);
+		
+		String xpath = "fn:index-of( for $e in X/* return fn:node-name($e), fn:node-name(X/b) )";
+		compileXPath(xpath);
+		ResultSequence rs = evaluate(domDoc);
+		
+		assertTrue( rs.size()>0 );
+		String actual = ((XSInteger) rs.first()).getStringValue();
+		assertEquals("2", actual);
+	}
+	
+	public void testFnIndexOf_onQName2() throws Exception {
+		// bug 338999
+		URL fileURL = bundle.getEntry("/bugTestFiles/bug338999.xml");
+		URL schemaURL = bundle.getEntry("/bugTestFiles/bug338999.xsd");
+
+		loadDOMDocument(fileURL, schemaURL);
+
+		// Get XSModel object for the Schema
+		XSModel schema = getGrammar(schemaURL);
+
+		setupDynamicContext(schema);
+		
+		String xpath = "fn:index-of( for $e in X/* return fn:node-name($e), fn:QName('','b') )";
+		compileXPath(xpath);
+		ResultSequence rs = evaluate(domDoc);
+		
+		assertTrue( rs.size()>0 );
+		String actual = ((XSInteger) rs.first()).getStringValue();
+		assertEquals("2", actual);
+	}
+	
+	public void testNumberAggregationWithNill() throws Exception {
+
+		URL fileURL = bundle.getEntry("/bugTestFiles/bugNilled.xml");
+		URL schemaURL = bundle.getEntry("/bugTestFiles/bugNilled.xsd");
+
+		loadDOMDocument(fileURL, schemaURL);
+
+		// Get XSModel object for the Schema
+		XSModel schema = getGrammar(schemaURL);
+
+		setupDynamicContext(schema);
+		
+		String xpath = null;
+		ResultSequence rs = null;
+		String actual = null;
+		
+		//a
+		xpath = "fn:count(( /root/element1, /root/element2, /root/element3 ))";
+		compileXPath(xpath);
+		rs = evaluate(domDoc);
+		
+		assertTrue( rs.size()>0 );
+		actual = ((XSDecimal) rs.first()).getStringValue();
+		assertEquals("3", actual);
+		
+		//b
+		xpath = "fn:sum(( /root/element1, /root/element2, /root/element3 ))";
+		compileXPath(xpath);
+		rs = evaluate(domDoc);
+		
+		assertTrue( rs.size()>0 );
+		actual = ((XSDecimal) rs.first()).getStringValue();
+		assertEquals("43", actual);
+		
+		//b2
+		xpath = "fn:sum(( /root/element1, /root/element2, /root/element3 ), 100)";
+		compileXPath(xpath);
+		rs = evaluate(domDoc);
+		
+		assertTrue( rs.size()>0 );
+		actual = ((XSDecimal) rs.first()).getStringValue();
+		assertEquals("143", actual);
+		
+		//c
+		xpath = "fn:avg(( /root/element1, /root/element2, /root/element3, 1 ))";
+		compileXPath(xpath);
+		rs = evaluate(domDoc);
+		
+		assertTrue( rs.size()>0 );
+		actual = ((XSDecimal) rs.first()).getStringValue();
+		assertEquals("11", actual);
+		
+		//d
+		xpath = "fn:max(( /root/element1, /root/element2, /root/element3 ))";
+		compileXPath(xpath);
+		rs = evaluate(domDoc);
+		
+		assertTrue( rs.size()>0 );
+		actual = ((XSDecimal) rs.first()).getStringValue();
+		assertEquals("42", actual);
+		
+		//e
+		xpath = "fn:min(( /root/element1, /root/element2, /root/element3 ))";
+		compileXPath(xpath);
+		rs = evaluate(domDoc);
+		
+		assertTrue( rs.size()>0 );
+		actual = ((XSDecimal) rs.first()).getStringValue();
+		assertEquals("1", actual);
+	}
+	
 	public void testBug339025_distinctValuesOnNodeSequence() throws Exception {
 		// bug 339025
 		URL fileURL = bundle.getEntry("/bugTestFiles/bug339025.xml");

Back to the top