text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    TestStringToNumeric.cxx
  
    Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
    All rights reserved.
    See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  
       This software is distributed WITHOUT ANY WARRANTY; without even
       the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
       PURPOSE.  See the above copyright notice for more information.
  
  =========================================================================*/
  /*-------------------------------------------------------------------------
    Copyright 2008 Sandia Corporation.
    Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
    the U.S. Government retains certain rights in this software.
  -------------------------------------------------------------------------*/
  
  #include "vtkDelimitedTextReader.h"
  #include "vtkDoubleArray.h"
  #include "vtkIntArray.h"
  #include "vtkStringArray.h"
  #include "vtkStringToNumeric.h"
  #include "vtkTable.h"
  #include "vtkTestUtilities.h"
  #include "vtkMath.h"
  
  #include "vtkNew.h"
  
  namespace
  {
  
  int ArrayTypesTest(int argc, char* argv[])
  {
    char* file = vtkTestUtilities::ExpandDataFileName(argc, argv,
                                                      "Data/authors.csv");
  
    vtkNew<vtkDelimitedTextReader> reader;
    reader->SetFileName(file);
    reader->SetHaveHeaders(true);
  
    delete [] file;
  
    vtkNew<vtkStringToNumeric> numeric;
    numeric->SetInputConnection(reader->GetOutputPort());
    numeric->Update();
  
    vtkTable* table = vtkTable::SafeDownCast(numeric->GetOutput());
  
    cerr << "Testing array types..." << endl;
    int errors = 0;
    if (!vtkStringArray::SafeDownCast(table->GetColumnByName("Author")))
      {
      cerr << "ERROR: Author array missing" << endl;
      ++errors;
      }
    if (!vtkStringArray::SafeDownCast(table->GetColumnByName("Affiliation")))
      {
      cerr << "ERROR: Affiliation array missing" << endl;
      ++errors;
      }
    if (!vtkStringArray::SafeDownCast(table->GetColumnByName("Alma Mater")))
      {
      cerr << "ERROR: Alma Mater array missing" << endl;
      ++errors;
      }
    if (!vtkStringArray::SafeDownCast(table->GetColumnByName("Categories")))
      {
      cerr << "ERROR: Categories array missing" << endl;
      ++errors;
      }
    if (!vtkIntArray::SafeDownCast(table->GetColumnByName("Age")))
      {
      cerr << "ERROR: Age array missing or not converted to int" << endl;
      ++errors;
      }
    else
      {
      vtkIntArray* age = vtkIntArray::SafeDownCast(table->GetColumnByName("Age"));
      int sum = 0;
      for (vtkIdType i = 0; i < age->GetNumberOfTuples(); i++)
        {
        sum += age->GetValue(i);
        }
      if (sum != 181)
        {
        cerr << "ERROR: Age sum is incorrect" << endl;
        ++errors;
        }
      }
    if (!vtkDoubleArray::SafeDownCast(table->GetColumnByName("Coolness")))
      {
      cerr << "ERROR: Coolness array missing or not converted to double" << endl;
      ++errors;
      }
    else
      {
      vtkDoubleArray* cool = vtkDoubleArray::SafeDownCast(table->GetColumnByName("Coolness"));
      double sum = 0;
      for (vtkIdType i = 0; i < cool->GetNumberOfTuples(); i++)
        {
        sum += cool->GetValue(i);
        }
      double eps = 10e-8;
      double diff = (2.35 > sum) ? (2.35 - sum) : (sum - 2.35);
      if (diff > eps)
        {
        cerr << "ERROR: Coolness sum is incorrect" << endl;
        ++errors;
        }
      }
  
    cerr << "Testing force double..." << endl;
    numeric->ForceDoubleOn();
    numeric->Update();
    table = vtkTable::SafeDownCast(numeric->GetOutput());
    if (!vtkDoubleArray::SafeDownCast(table->GetColumnByName("Age")))
      {
      cerr << "ERROR: Arrays should have been forced to double" << endl;
      ++errors;
      }
  
    return errors;
  }
  
  int WhitespaceAndEmptyCellsTest()
  {
    // Setup a table of string columns, which is to get converted to numeric
    vtkNew<vtkTable> inputTable;
    vtkNew<vtkStringArray> integerColumn;
    integerColumn->SetName("IntegerColumn");
    integerColumn->SetNumberOfTuples(2);
    integerColumn->SetValue(0, " ");
    integerColumn->SetValue(1, " 1 ");
  
    vtkNew<vtkStringArray> doubleColumn;
    doubleColumn->SetName("DoubleColumn");
    doubleColumn->SetNumberOfTuples(2);
    doubleColumn->SetValue(0, " ");
    doubleColumn->SetValue(1, " 1.1 ");
  
    inputTable->AddColumn(integerColumn.GetPointer());
    inputTable->AddColumn(doubleColumn.GetPointer());
  
    // Setup the vtkStringToNumeric which is under test
    vtkNew<vtkStringToNumeric> numeric;
    int const defaultIntValue = 100;
    numeric->SetDefaultIntegerValue(defaultIntValue);
    numeric->SetDefaultDoubleValue(vtkMath::Nan());
    numeric->SetTrimWhitespacePriorToNumericConversion(true);
    numeric->SetInput(inputTable.GetPointer());
    numeric->Update();
    vtkTable* table = vtkTable::SafeDownCast(numeric->GetOutput());
    table->Dump();
  
    cerr << "Testing handling whitespace and empty cells..." << endl;
    int errors = 0;
    if (!vtkIntArray::SafeDownCast(table->GetColumnByName("IntegerColumn")))
      {
      cerr << "ERROR: IntegerColumn array missing or not converted to int" << endl;
      ++errors;
      }
    else
      {
      vtkIntArray* column =
          vtkIntArray::SafeDownCast(table->GetColumnByName("IntegerColumn"));
      if (defaultIntValue != column->GetValue(0))
        {
        cerr << "ERROR: Empty cell value is: " << column->GetValue(0)
             << ". Expected: " << defaultIntValue;
        ++errors;
        }
      if (1 != column->GetValue(1))
        {
        cerr << "ERROR: Cell with whitespace value is: "
             << column->GetValue(1) << ". Expected: 1";
        ++errors;
        }
      }
  
    if (!vtkDoubleArray::SafeDownCast(table->GetColumnByName("DoubleColumn")))
      {
      cerr << "ERROR: DoubleColumn array missing or not converted to double"
           << endl;
      ++errors;
      }
    else
      {
      vtkDoubleArray* column =
          vtkDoubleArray::SafeDownCast(table->GetColumnByName("DoubleColumn"));
      if (!vtkMath::IsNan(column->GetValue(0)))
        {
        cerr << "ERROR: Empty cell value is: " << column->GetValue(0)
             << ". Expected: " << vtkMath::Nan();
        ++errors;
        }
      if (1.1 != column->GetValue(1))
        {
        cerr << "ERROR: Cell with whitespace value is: "
             << column->GetValue(1) << ". Expected: 1.1";
        ++errors;
        }
      }
    return errors;
  }
  }
  
  int TestStringToNumeric(int argc, char* argv[])
  {
    int errors = ArrayTypesTest(argc, argv);
    errors += WhitespaceAndEmptyCellsTest();
  
    cerr << "...done testing" << endl;
    cerr << errors << " errors found." << endl;
  
    return errors;
  }
  