// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed 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.

package adaptorlib.examples;

import static org.junit.Assert.*;

import adaptorlib.TransformException;

import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Tests for {@link TableGeneratorTransform}.
 */
public class TableGeneratorTransformTest {
  @Test
  public void testNoInput() throws IOException, TransformException {
    TableGeneratorTransform transform = new TableGeneratorTransform();
    ByteArrayOutputStream contentIn = new ByteArrayOutputStream();
    ByteArrayOutputStream contentOut = new ByteArrayOutputStream();
    Map<String, String> metadata = new HashMap<String, String>();
    Map<String, String> params = new HashMap<String, String>();
    params.put("key1", "value1");
    transform.transform(contentIn, contentOut, metadata, params);

    assertEquals("<HTML><HEAD></HEAD><BODY></BODY></HTML>", contentOut.toString());
    assertEquals(0, metadata.size());
    assertEquals("value1", params.get("key1"));
    assertEquals(1, params.keySet().size());
  }

  @Test
  public void testFull() throws IOException, TransformException {
    TableGeneratorTransform transform = new TableGeneratorTransform();
    ByteArrayOutputStream contentIn = new ByteArrayOutputStream();
    ByteArrayOutputStream contentOut = new ByteArrayOutputStream();
    Map<String, String> metadata = new HashMap<String, String>();
    Map<String, String> params = new HashMap<String, String>();
    params.put("key1", "value1");

    String csv = "header1,\"\"\"header2\"\"\",\"This is a header\n" +
        "with a newline\",header4\n" +
        "This is the first field of the second record,\"This field has\n" +
        "a newline\",,field4";
    String goldenOutput =
        "<HTML><HEAD></HEAD><BODY><table border=\"1\">\n" +
        "<tr>\n" +
        "<td>header1</td>\n" +
        "<td>\"header2\"</td>\n" +
        "<td>This is a header\n" +
        "with a newline</td>\n" +
        "<td>header4</td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        "<td>This is the first field of the second record</td>\n" +
        "<td>This field has\n" +
        "a newline</td>\n" +
        "<td></td>\n" +
        "<td>field4</td>\n" +
        "</tr>\n" +
        "</table></BODY></HTML>";
    contentIn.write(csv.getBytes());
    transform.transform(contentIn, contentOut, metadata, params);

    assertEquals(goldenOutput, contentOut.toString());
    assertEquals(0, metadata.size());
    assertEquals("value1", params.get("key1"));
    assertEquals(1, params.keySet().size());
  }
}
