public function testDataTableCustomProperties()
 {
     $data = new DataTable('first', ValueType::STRING);
     $data->setCustomProperty('a', 'foo');
     $properties = $data->getCustomProperties();
     $this->assertTrue(is_array($properties), "properties must be an array");
     $this->assertArrayHasKey('a', $properties, "properties[a] must exist");
     $this->assertSame('foo', $data->getCustomProperty('a'), "getCustomProperty must return expected value");
 }
 /**
  * @param DataTable $dataTable
  * @param bool $includeValues [optional]
  * @param bool $includeFormatting [optional]
  * @param bool $renderDateAsDateConstructor [optional]
  * @return string JSON encoded string describing $dataTable
  */
 public function renderDataTable(DataTable $dataTable, $includeValues = true, $includeFormatting = true, $renderDateAsDateConstructor = true)
 {
     $numColumns = $dataTable->getNumberOfColumns();
     $columns = $dataTable->getColumnDescriptions();
     $output = "{";
     $output .= "\"cols\":[";
     for ($i = 0; $i < $numColumns; $i++) {
         $column = $columns[$i];
         $output .= $this->renderColumnDescriptionJson($column);
         if ($i + 1 < $numColumns) {
             $output .= ",";
         }
     }
     $output .= "]";
     if ($includeValues) {
         $numRows = $dataTable->getNumberOfRows();
         $output .= ",\"rows\":[";
         for ($ri = 0; $ri < $numRows; $ri++) {
             $row = $dataTable->getRow($ri);
             $numCells = $row->getNumberOfCells();
             $output .= "{\"c\":[";
             for ($ci = 0; $ci < $numCells; $ci++) {
                 $cell = $row->getCell($ci);
                 if ($ci + 1 < $numCells) {
                     // For fields that are NOT the last field, renderCellJson() may return
                     // an empty string if the value is NULL
                     // @see https://code.google.com/p/google-visualization-java/source/browse/trunk/src/main/java/com/google/visualization/datasource/render/JsonRenderer.java
                     $cellOutput = $this->renderCellJson($cell, $includeFormatting, $this->optimizeNullValues, $renderDateAsDateConstructor);
                     $cellOutput .= ",";
                 } else {
                     // For fields that ARE the last field, a JSON string is returned
                     // even for NULL values
                     $cellOutput = $this->renderCellJson($cell, $includeFormatting, false, $renderDateAsDateConstructor);
                 }
                 $output .= $cellOutput;
             }
             $output .= "]";
             // Row properties
             $customProperties = $this->renderCustomPropertiesString($row->getCustomProperties());
             if ($customProperties !== null) {
                 $output .= ",\"p\":" . $customProperties;
             }
             $output .= "}";
             if ($ri + 1 < $numRows) {
                 $output .= ",";
             }
         }
         $output .= "]";
     }
     // Table properties
     $customProperties = $this->renderCustomPropertiesString($dataTable->getCustomProperties());
     if ($customProperties !== null) {
         $output .= ",\"p\":" . $customProperties;
     }
     $output .= "}";
     return $output;
 }