blob: ce5a0b85508654348e1e427f9dc99f3e019cda25 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/*
* $Id$
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include "XMLHarnessHandlers.hpp"
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/sax/SAXException.hpp>
#include <xercesc/validators/common/Grammar.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/util/BinInputStream.hpp>
// ---------------------------------------------------------------------------
// XMLHarnessHandlers: Constructors and Destructor
// ---------------------------------------------------------------------------
XMLHarnessHandlers::XMLHarnessHandlers(const XMLCh* baseURL, const XMLCh* scanner) : BaseHarnessHandlers(baseURL)
, fTestBaseURL(5)
{
fParser = XMLReaderFactory::createXMLReader();
fParser->setProperty(XMLUni::fgXercesScannerName, (void*)scanner);
fParser->setFeature(XMLUni::fgSAX2CoreValidation, true);
fParser->setFeature(XMLUni::fgXercesDynamic, false);
fParser->setErrorHandler(&fErrorHandler);
fTestBaseURL.push(new XMLURL(fBaseURL));
}
XMLHarnessHandlers::~XMLHarnessHandlers()
{
delete fParser;
}
static XMLCh szTest[]={ chLatin_T, chLatin_E, chLatin_S, chLatin_T, chNull };
static XMLCh szTestCases[]={ chLatin_T, chLatin_E, chLatin_S, chLatin_T, chLatin_C, chLatin_A, chLatin_S, chLatin_E, chLatin_S, chNull };
static XMLCh szID[]={ chLatin_I, chLatin_D, chNull };
static XMLCh szURI[]={ chLatin_U, chLatin_R, chLatin_I, chNull };
static XMLCh szType[]={ chLatin_T, chLatin_Y, chLatin_P, chLatin_E, chNull };
static XMLCh szValid[]={ chLatin_v, chLatin_a, chLatin_l, chLatin_i, chLatin_d, chNull };
static XMLCh szInvalid[]={ chLatin_i, chLatin_n, chLatin_v, chLatin_a, chLatin_l, chLatin_i, chLatin_d, chNull };
static XMLCh szNotWellFormed[]={ chLatin_n, chLatin_o, chLatin_t, chDash, chLatin_w, chLatin_f, chNull };
static XMLCh szError[]={ chLatin_e, chLatin_r, chLatin_r, chLatin_o, chLatin_r, chNull };
static XMLCh szBase[]={ chLatin_x, chLatin_m, chLatin_l, chColon, chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull };
static XMLCh szNamespace[]={ chLatin_N, chLatin_A, chLatin_M, chLatin_E, chLatin_S, chLatin_P, chLatin_A, chLatin_C, chLatin_E, chNull };
static XMLCh szNO[]={ chLatin_n, chLatin_o, chNull };
static XMLCh szVersion[] = { chLatin_V, chLatin_E, chLatin_R, chLatin_S, chLatin_I, chLatin_O, chLatin_N, chNull };
static XMLCh szEdition[] = { chLatin_E, chLatin_D, chLatin_I, chLatin_T, chLatin_I, chLatin_O, chLatin_N, chNull };
static XMLCh szFive[]={ chDigit_5, chNull };
// ---------------------------------------------------------------------------
// XMLHarnessHandlers: Implementation of the SAX DocumentHandler interface
// ---------------------------------------------------------------------------
void XMLHarnessHandlers::startElement(const XMLCh* const /* uri */
, const XMLCh* const localname
, const XMLCh* const /* qname */
, const Attributes& attrs)
{
if(XMLString::equals(localname, szTestCases))
{
const XMLCh* baseUrl=attrs.getValue(szBase);
XMLURL newBase;
XMLURL prevBase=*fTestBaseURL.peek();
if(baseUrl!=NULL)
newBase.setURL(prevBase, baseUrl);
else
newBase=prevBase;
fTestBaseURL.push(new XMLURL(newBase));
}
else if(XMLString::equals(localname, szTest))
{
const XMLCh* useNS=attrs.getValue(szNamespace);
const XMLCh* testName=attrs.getValue(szID);
const XMLCh* version=attrs.getValue(szVersion);
if(version == NULL || XMLString::equals(version, XMLUni::fgVersion1_0))
{
const XMLCh* editions=attrs.getValue(szEdition);
// skip tests that don't apply to v.1.0 5th Edition
if(editions)
{
BaseRefVectorOf<XMLCh>* tokens = XMLString::tokenizeString(editions);
bool appliesTo5 = false;
for (XMLSize_t i = 0; i < tokens->size(); i++) {
if (XMLString::equals(tokens->elementAt(i), szFive)) {
appliesTo5 = true;
break;
}
}
delete tokens;
if(!appliesTo5)
return;
}
}
XMLURL testSet;
testSet.setURL(*fTestBaseURL.peek(), attrs.getValue(szURI));
bool success=true, fatalFailure=false;
try
{
if(useNS!=NULL && XMLString::equals(useNS, szNO))
{
fParser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);
fParser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, false);
}
else
{
fParser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
fParser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, true);
}
fErrorHandler.resetErrors();
fParser->parse(testSet.getURLText());
}
catch (const OutOfMemoryException&)
{
fatalFailure=true;
std::cout << "Test " << StrX(testName) << " ran out of memory" << std::endl;
success=false;
}
catch(const XMLException& exc)
{
std::cout << "Test " << StrX(testName) << " threw " << StrX(exc.getMessage()) << std::endl;
success=false;
}
catch (...)
{
fatalFailure=true;
std::cout << "Test " << StrX(testName) << " crashed" << std::endl;
success=false;
exit(1);
}
fTests++;
if(fatalFailure)
{
fFailures++;
printFile(testSet);
}
else
{
ValidityOutcome expResult=unknown;
const XMLCh* validity=attrs.getValue(szType);
if(XMLString::equals(validity, szValid))
expResult=valid;
else if(XMLString::equals(validity, szInvalid) || XMLString::equals(validity, szNotWellFormed) || XMLString::equals(validity, szError) )
expResult=invalid;
else
std::cerr << "Unknown result type " << StrX(validity) << std::endl;
if(success && !fErrorHandler.getSawErrors())
{
if(expResult!=valid)
{
fFailures++;
std::cout << "Test " << StrX(testName) << " succeeded but was expected to fail" << std::endl;
printFile(testSet);
}
}
else
{
if(expResult!=invalid)
{
fFailures++;
std::cout << "Test " << StrX(testName) << " failed but was expected to pass" << std::endl;
std::cout << "Reported error: " << StrX(fErrorHandler.getErrorText()) << std::endl;
printFile(testSet);
}
}
}
}
}
void XMLHarnessHandlers::endElement(const XMLCh* const /* uri */, const XMLCh* const localname, const XMLCh* const /* qname */)
{
if(XMLString::equals(localname, szTestCases))
{
fTestBaseURL.pop();
}
}