| Index: source/test/intltest/dcfmtest.cpp
|
| diff --git a/source/test/intltest/dcfmtest.cpp b/source/test/intltest/dcfmtest.cpp
|
| deleted file mode 100644
|
| index d931fdd1288f844a26d3bf99590106103763aac7..0000000000000000000000000000000000000000
|
| --- a/source/test/intltest/dcfmtest.cpp
|
| +++ /dev/null
|
| @@ -1,551 +0,0 @@
|
| -/********************************************************************
|
| - * COPYRIGHT:
|
| - * Copyright (c) 2002-2014, International Business Machines Corporation and
|
| - * others. All Rights Reserved.
|
| - ********************************************************************/
|
| -
|
| -//
|
| -// dcfmtest.cpp
|
| -//
|
| -// Decimal Formatter tests, data driven.
|
| -//
|
| -
|
| -#include "intltest.h"
|
| -
|
| -#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_REGULAR_EXPRESSIONS
|
| -
|
| -#include "unicode/regex.h"
|
| -#include "unicode/uchar.h"
|
| -#include "unicode/ustring.h"
|
| -#include "unicode/unistr.h"
|
| -#include "unicode/dcfmtsym.h"
|
| -#include "unicode/decimfmt.h"
|
| -#include "unicode/locid.h"
|
| -#include "cmemory.h"
|
| -#include "dcfmtest.h"
|
| -#include "util.h"
|
| -#include "cstring.h"
|
| -#include <stdlib.h>
|
| -#include <string.h>
|
| -#include <stdio.h>
|
| -
|
| -#if !defined(_MSC_VER)
|
| -namespace std { class type_info; } // WORKAROUND: http://llvm.org/bugs/show_bug.cgi?id=13364
|
| -#endif
|
| -
|
| -#include <string>
|
| -#include <iostream>
|
| -
|
| -//---------------------------------------------------------------------------
|
| -//
|
| -// Test class boilerplate
|
| -//
|
| -//---------------------------------------------------------------------------
|
| -DecimalFormatTest::DecimalFormatTest()
|
| -{
|
| -}
|
| -
|
| -
|
| -DecimalFormatTest::~DecimalFormatTest()
|
| -{
|
| -}
|
| -
|
| -
|
| -
|
| -void DecimalFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
|
| -{
|
| - if (exec) logln("TestSuite DecimalFormatTest: ");
|
| - switch (index) {
|
| -
|
| -#if !UCONFIG_NO_FILE_IO
|
| - case 0: name = "DataDrivenTests";
|
| - if (exec) DataDrivenTests();
|
| - break;
|
| -#else
|
| - case 0: name = "skip";
|
| - break;
|
| -#endif
|
| -
|
| - default: name = "";
|
| - break; //needed to end loop
|
| - }
|
| -}
|
| -
|
| -
|
| -//---------------------------------------------------------------------------
|
| -//
|
| -// Error Checking / Reporting macros used in all of the tests.
|
| -//
|
| -//---------------------------------------------------------------------------
|
| -#define DF_CHECK_STATUS {if (U_FAILURE(status)) \
|
| - {dataerrln("DecimalFormatTest failure at line %d. status=%s", \
|
| - __LINE__, u_errorName(status)); return 0;}}
|
| -
|
| -#define DF_ASSERT(expr) {if ((expr)==FALSE) {errln("DecimalFormatTest failure at line %d.\n", __LINE__);};}
|
| -
|
| -#define DF_ASSERT_FAIL(expr, errcode) {UErrorCode status=U_ZERO_ERROR; (expr);\
|
| -if (status!=errcode) {dataerrln("DecimalFormatTest failure at line %d. Expected status=%s, got %s", \
|
| - __LINE__, u_errorName(errcode), u_errorName(status));};}
|
| -
|
| -#define DF_CHECK_STATUS_L(line) {if (U_FAILURE(status)) {errln( \
|
| - "DecimalFormatTest failure at line %d, from %d. status=%d\n",__LINE__, (line), status); }}
|
| -
|
| -#define DF_ASSERT_L(expr, line) {if ((expr)==FALSE) { \
|
| - errln("DecimalFormatTest failure at line %d, from %d.", __LINE__, (line)); return;}}
|
| -
|
| -
|
| -
|
| -//
|
| -// InvariantStringPiece
|
| -// Wrap a StringPiece around the extracted invariant data of a UnicodeString.
|
| -// The data is guaranteed to be nul terminated. (This is not true of StringPiece
|
| -// in general, but is true of InvariantStringPiece)
|
| -//
|
| -class InvariantStringPiece: public StringPiece {
|
| - public:
|
| - InvariantStringPiece(const UnicodeString &s);
|
| - ~InvariantStringPiece() {};
|
| - private:
|
| - MaybeStackArray<char, 20> buf;
|
| -};
|
| -
|
| -InvariantStringPiece::InvariantStringPiece(const UnicodeString &s) {
|
| - int32_t len = s.length();
|
| - if (len+1 > buf.getCapacity()) {
|
| - buf.resize(len+1);
|
| - }
|
| - // Buffer size is len+1 so that s.extract() will nul-terminate the string.
|
| - s.extract(0, len, buf.getAlias(), len+1, US_INV);
|
| - this->set(buf.getAlias(), len);
|
| -}
|
| -
|
| -
|
| -// UnicodeStringPiece
|
| -// Wrap a StringPiece around the extracted (to the default charset) data of
|
| -// a UnicodeString. The extracted data is guaranteed to be nul terminated.
|
| -// (This is not true of StringPiece in general, but is true of UnicodeStringPiece)
|
| -//
|
| -class UnicodeStringPiece: public StringPiece {
|
| - public:
|
| - UnicodeStringPiece(const UnicodeString &s);
|
| - ~UnicodeStringPiece() {};
|
| - private:
|
| - MaybeStackArray<char, 20> buf;
|
| -};
|
| -
|
| -UnicodeStringPiece::UnicodeStringPiece(const UnicodeString &s) {
|
| - int32_t len = s.length();
|
| - int32_t capacity = buf.getCapacity();
|
| - int32_t requiredCapacity = s.extract(0, len, buf.getAlias(), capacity) + 1;
|
| - if (capacity < requiredCapacity) {
|
| - buf.resize(requiredCapacity);
|
| - capacity = requiredCapacity;
|
| - s.extract(0, len, buf.getAlias(), capacity);
|
| - }
|
| - this->set(buf.getAlias(), requiredCapacity - 1);
|
| -}
|
| -
|
| -
|
| -
|
| -//---------------------------------------------------------------------------
|
| -//
|
| -// DataDrivenTests
|
| -// The test cases are in a separate data file,
|
| -//
|
| -//---------------------------------------------------------------------------
|
| -
|
| -// Translate a Formattable::type enum value to a string, for error message formatting.
|
| -static const char *formattableType(Formattable::Type typ) {
|
| - static const char *types[] = {"kDate",
|
| - "kDouble",
|
| - "kLong",
|
| - "kString",
|
| - "kArray",
|
| - "kInt64",
|
| - "kObject"
|
| - };
|
| - if (typ<0 || typ>Formattable::kObject) {
|
| - return "Unknown";
|
| - }
|
| - return types[typ];
|
| -}
|
| -
|
| -const char *
|
| -DecimalFormatTest::getPath(char *buffer, const char *filename) {
|
| - UErrorCode status=U_ZERO_ERROR;
|
| - const char *testDataDirectory = IntlTest::getSourceTestData(status);
|
| - DF_CHECK_STATUS;
|
| -
|
| - strcpy(buffer, testDataDirectory);
|
| - strcat(buffer, filename);
|
| - return buffer;
|
| -}
|
| -
|
| -void DecimalFormatTest::DataDrivenTests() {
|
| - char tdd[2048];
|
| - const char *srcPath;
|
| - UErrorCode status = U_ZERO_ERROR;
|
| - int32_t lineNum = 0;
|
| -
|
| - //
|
| - // Open and read the test data file.
|
| - //
|
| - srcPath=getPath(tdd, "dcfmtest.txt");
|
| - if(srcPath==NULL) {
|
| - return; /* something went wrong, error already output */
|
| - }
|
| -
|
| - int32_t len;
|
| - UChar *testData = ReadAndConvertFile(srcPath, len, status);
|
| - if (U_FAILURE(status)) {
|
| - return; /* something went wrong, error already output */
|
| - }
|
| -
|
| - //
|
| - // Put the test data into a UnicodeString
|
| - //
|
| - UnicodeString testString(FALSE, testData, len);
|
| -
|
| - RegexMatcher parseLineMat(UnicodeString(
|
| - "(?i)\\s*parse\\s+"
|
| - "\"([^\"]*)\"\\s+" // Capture group 1: input text
|
| - "([ild])\\s+" // Capture group 2: expected parsed type
|
| - "\"([^\"]*)\"\\s+" // Capture group 3: expected parsed decimal
|
| - "\\s*(?:#.*)?"), // Trailing comment
|
| - 0, status);
|
| -
|
| - RegexMatcher formatLineMat(UnicodeString(
|
| - "(?i)\\s*format\\s+"
|
| - "(\\S+)\\s+" // Capture group 1: pattern
|
| - "(ceiling|floor|down|up|halfeven|halfdown|halfup|default|unnecessary)\\s+" // Capture group 2: Rounding Mode
|
| - "\"([^\"]*)\"\\s+" // Capture group 3: input
|
| - "\"([^\"]*)\"" // Capture group 4: expected output
|
| - "\\s*(?:#.*)?"), // Trailing comment
|
| - 0, status);
|
| -
|
| - RegexMatcher commentMat (UNICODE_STRING_SIMPLE("\\s*(#.*)?$"), 0, status);
|
| - RegexMatcher lineMat(UNICODE_STRING_SIMPLE("(?m)^(.*?)$"), testString, 0, status);
|
| -
|
| - if (U_FAILURE(status)){
|
| - dataerrln("Construct RegexMatcher() error.");
|
| - delete [] testData;
|
| - return;
|
| - }
|
| -
|
| - //
|
| - // Loop over the test data file, once per line.
|
| - //
|
| - while (lineMat.find()) {
|
| - lineNum++;
|
| - if (U_FAILURE(status)) {
|
| - dataerrln("File dcfmtest.txt, line %d: ICU Error \"%s\"", lineNum, u_errorName(status));
|
| - }
|
| -
|
| - status = U_ZERO_ERROR;
|
| - UnicodeString testLine = lineMat.group(1, status);
|
| - // printf("%s\n", UnicodeStringPiece(testLine).data());
|
| - if (testLine.length() == 0) {
|
| - continue;
|
| - }
|
| -
|
| - //
|
| - // Parse the test line. Skip blank and comment only lines.
|
| - // Separate out the three main fields - pattern, flags, target.
|
| - //
|
| -
|
| - commentMat.reset(testLine);
|
| - if (commentMat.lookingAt(status)) {
|
| - // This line is a comment, or blank.
|
| - continue;
|
| - }
|
| -
|
| -
|
| - //
|
| - // Handle "parse" test case line from file
|
| - //
|
| - parseLineMat.reset(testLine);
|
| - if (parseLineMat.lookingAt(status)) {
|
| - execParseTest(lineNum,
|
| - parseLineMat.group(1, status), // input
|
| - parseLineMat.group(2, status), // Expected Type
|
| - parseLineMat.group(3, status), // Expected Decimal String
|
| - status
|
| - );
|
| - continue;
|
| - }
|
| -
|
| - //
|
| - // Handle "format" test case line
|
| - //
|
| - formatLineMat.reset(testLine);
|
| - if (formatLineMat.lookingAt(status)) {
|
| - execFormatTest(lineNum,
|
| - formatLineMat.group(1, status), // Pattern
|
| - formatLineMat.group(2, status), // rounding mode
|
| - formatLineMat.group(3, status), // input decimal number
|
| - formatLineMat.group(4, status), // expected formatted result
|
| - kFormattable,
|
| - status);
|
| -
|
| - execFormatTest(lineNum,
|
| - formatLineMat.group(1, status), // Pattern
|
| - formatLineMat.group(2, status), // rounding mode
|
| - formatLineMat.group(3, status), // input decimal number
|
| - formatLineMat.group(4, status), // expected formatted result
|
| - kStringPiece,
|
| - status);
|
| - continue;
|
| - }
|
| -
|
| - //
|
| - // Line is not a recognizable test case.
|
| - //
|
| - errln("Badly formed test case at line %d.\n%s\n",
|
| - lineNum, UnicodeStringPiece(testLine).data());
|
| -
|
| - }
|
| -
|
| - delete [] testData;
|
| -}
|
| -
|
| -
|
| -
|
| -void DecimalFormatTest::execParseTest(int32_t lineNum,
|
| - const UnicodeString &inputText,
|
| - const UnicodeString &expectedType,
|
| - const UnicodeString &expectedDecimal,
|
| - UErrorCode &status) {
|
| -
|
| - if (U_FAILURE(status)) {
|
| - return;
|
| - }
|
| -
|
| - DecimalFormatSymbols symbols(Locale::getUS(), status);
|
| - UnicodeString pattern = UNICODE_STRING_SIMPLE("####");
|
| - DecimalFormat format(pattern, symbols, status);
|
| - Formattable result;
|
| - if (U_FAILURE(status)) {
|
| - dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
|
| - lineNum, u_errorName(status));
|
| - return;
|
| - }
|
| -
|
| - ParsePosition pos;
|
| - int32_t expectedParseEndPosition = inputText.length();
|
| -
|
| - format.parse(inputText, result, pos);
|
| -
|
| - if (expectedParseEndPosition != pos.getIndex()) {
|
| - errln("file dcfmtest.txt, line %d: Expected parse position afeter parsing: %d. "
|
| - "Actual parse position: %d", expectedParseEndPosition, pos.getIndex());
|
| - return;
|
| - }
|
| -
|
| - char expectedTypeC[2];
|
| - expectedType.extract(0, 1, expectedTypeC, 2, US_INV);
|
| - Formattable::Type expectType = Formattable::kDate;
|
| - switch (expectedTypeC[0]) {
|
| - case 'd': expectType = Formattable::kDouble; break;
|
| - case 'i': expectType = Formattable::kLong; break;
|
| - case 'l': expectType = Formattable::kInt64; break;
|
| - default:
|
| - errln("file dcfmtest.tx, line %d: unrecongized expected type \"%s\"",
|
| - lineNum, InvariantStringPiece(expectedType).data());
|
| - return;
|
| - }
|
| - if (result.getType() != expectType) {
|
| - errln("file dcfmtest.txt, line %d: expectedParseType(%s) != actual parseType(%s)",
|
| - lineNum, formattableType(expectType), formattableType(result.getType()));
|
| - return;
|
| - }
|
| -
|
| - StringPiece decimalResult = result.getDecimalNumber(status);
|
| - if (U_FAILURE(status)) {
|
| - errln("File %s, line %d: error %s. Line in file dcfmtest.txt: %d:",
|
| - __FILE__, __LINE__, u_errorName(status), lineNum);
|
| - return;
|
| - }
|
| -
|
| - InvariantStringPiece expectedResults(expectedDecimal);
|
| - if (decimalResult != expectedResults) {
|
| - errln("file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
|
| - lineNum, expectedResults.data(), decimalResult.data());
|
| - }
|
| -
|
| - return;
|
| -}
|
| -
|
| -
|
| -void DecimalFormatTest::execFormatTest(int32_t lineNum,
|
| - const UnicodeString &pattern, // Pattern
|
| - const UnicodeString &round, // rounding mode
|
| - const UnicodeString &input, // input decimal number
|
| - const UnicodeString &expected, // expected formatted result
|
| - EFormatInputType inType, // input number type
|
| - UErrorCode &status) {
|
| - if (U_FAILURE(status)) {
|
| - return;
|
| - }
|
| -
|
| - DecimalFormatSymbols symbols(Locale::getUS(), status);
|
| - // printf("Pattern = %s\n", UnicodeStringPiece(pattern).data());
|
| - DecimalFormat fmtr(pattern, symbols, status);
|
| - if (U_FAILURE(status)) {
|
| - dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
|
| - lineNum, u_errorName(status));
|
| - return;
|
| - }
|
| - if (round=="ceiling") {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundCeiling);
|
| - } else if (round=="floor") {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
|
| - } else if (round=="down") {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundDown);
|
| - } else if (round=="up") {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundUp);
|
| - } else if (round=="halfeven") {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundHalfEven);
|
| - } else if (round=="halfdown") {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundHalfDown);
|
| - } else if (round=="halfup") {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundHalfUp);
|
| - } else if (round=="default") {
|
| - // don't set any value.
|
| - } else if (round=="unnecessary") {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundUnnecessary);
|
| - } else {
|
| - fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
|
| - errln("file dcfmtest.txt, line %d: Bad rounding mode \"%s\"",
|
| - lineNum, UnicodeStringPiece(round).data());
|
| - }
|
| -
|
| - const char *typeStr = "Unknown";
|
| - UnicodeString result;
|
| - UnicodeStringPiece spInput(input);
|
| -
|
| - switch (inType) {
|
| - case kFormattable:
|
| - {
|
| - typeStr = "Formattable";
|
| - Formattable fmtbl;
|
| - fmtbl.setDecimalNumber(spInput, status);
|
| - fmtr.format(fmtbl, result, NULL, status);
|
| - }
|
| - break;
|
| - case kStringPiece:
|
| - typeStr = "StringPiece";
|
| - fmtr.format(spInput, result, NULL, status);
|
| - break;
|
| - }
|
| -
|
| - if ((status == U_FORMAT_INEXACT_ERROR) && (result == "") && (expected == "Inexact")) {
|
| - // Test succeeded.
|
| - status = U_ZERO_ERROR;
|
| - return;
|
| - }
|
| -
|
| - if (U_FAILURE(status)) {
|
| - errln("[%s] file dcfmtest.txt, line %d: format() returned %s.",
|
| - typeStr, lineNum, u_errorName(status));
|
| - status = U_ZERO_ERROR;
|
| - return;
|
| - }
|
| -
|
| - if (result != expected) {
|
| - errln("[%s] file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
|
| - typeStr, lineNum, UnicodeStringPiece(expected).data(), UnicodeStringPiece(result).data());
|
| - }
|
| -}
|
| -
|
| -
|
| -//-------------------------------------------------------------------------------
|
| -//
|
| -// Read a text data file, convert it from UTF-8 to UChars, and return the data
|
| -// in one big UChar * buffer, which the caller must delete.
|
| -//
|
| -// (Lightly modified version of a similar function in regextst.cpp)
|
| -//
|
| -//--------------------------------------------------------------------------------
|
| -UChar *DecimalFormatTest::ReadAndConvertFile(const char *fileName, int32_t &ulen,
|
| - UErrorCode &status) {
|
| - UChar *retPtr = NULL;
|
| - char *fileBuf = NULL;
|
| - const char *fileBufNoBOM = NULL;
|
| - FILE *f = NULL;
|
| -
|
| - ulen = 0;
|
| - if (U_FAILURE(status)) {
|
| - return retPtr;
|
| - }
|
| -
|
| - //
|
| - // Open the file.
|
| - //
|
| - f = fopen(fileName, "rb");
|
| - if (f == 0) {
|
| - dataerrln("Error opening test data file %s\n", fileName);
|
| - status = U_FILE_ACCESS_ERROR;
|
| - return NULL;
|
| - }
|
| - //
|
| - // Read it in
|
| - //
|
| - int32_t fileSize;
|
| - int32_t amtRead;
|
| - int32_t amtReadNoBOM;
|
| -
|
| - fseek( f, 0, SEEK_END);
|
| - fileSize = ftell(f);
|
| - fileBuf = new char[fileSize];
|
| - fseek(f, 0, SEEK_SET);
|
| - amtRead = fread(fileBuf, 1, fileSize, f);
|
| - if (amtRead != fileSize || fileSize <= 0) {
|
| - errln("Error reading test data file.");
|
| - goto cleanUpAndReturn;
|
| - }
|
| -
|
| - //
|
| - // Look for a UTF-8 BOM on the data just read.
|
| - // The test data file is UTF-8.
|
| - // The BOM needs to be there in the source file to keep the Windows &
|
| - // EBCDIC machines happy, so force an error if it goes missing.
|
| - // Many Linux editors will silently strip it.
|
| - //
|
| - fileBufNoBOM = fileBuf + 3;
|
| - amtReadNoBOM = amtRead - 3;
|
| - if (fileSize<3 || uprv_strncmp(fileBuf, "\xEF\xBB\xBF", 3) != 0) {
|
| - // TODO: restore this check.
|
| - errln("Test data file %s is missing its BOM", fileName);
|
| - fileBufNoBOM = fileBuf;
|
| - amtReadNoBOM = amtRead;
|
| - }
|
| -
|
| - //
|
| - // Find the length of the input in UTF-16 UChars
|
| - // (by preflighting the conversion)
|
| - //
|
| - u_strFromUTF8(NULL, 0, &ulen, fileBufNoBOM, amtReadNoBOM, &status);
|
| -
|
| - //
|
| - // Convert file contents from UTF-8 to UTF-16
|
| - //
|
| - if (status == U_BUFFER_OVERFLOW_ERROR) {
|
| - // Buffer Overflow is expected from the preflight operation.
|
| - status = U_ZERO_ERROR;
|
| - retPtr = new UChar[ulen+1];
|
| - u_strFromUTF8(retPtr, ulen+1, NULL, fileBufNoBOM, amtReadNoBOM, &status);
|
| - }
|
| -
|
| -cleanUpAndReturn:
|
| - fclose(f);
|
| - delete[] fileBuf;
|
| - if (U_FAILURE(status)) {
|
| - errln("ICU Error \"%s\"\n", u_errorName(status));
|
| - delete retPtr;
|
| - retPtr = NULL;
|
| - };
|
| - return retPtr;
|
| -}
|
| -
|
| -#endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */
|
| -
|
|
|