// Copyright (C) 2012 The Android Open Source Project
//
// 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 com.google.gerrit.server.ioutil;

import com.google.gerrit.testing.GerritBaseTests;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.junit.Assert;
import org.junit.Test;

public class ColumnFormatterTest extends GerritBaseTests {
  /**
   * Holds an in-memory {@link java.io.PrintWriter} object and allows comparisons of its contents to
   * a supplied string via an assert statement.
   */
  static class PrintWriterComparator {
    private PrintWriter printWriter;
    private StringWriter stringWriter;

    PrintWriterComparator() {
      stringWriter = new StringWriter();
      printWriter = new PrintWriter(stringWriter);
    }

    public void assertEquals(String str) {
      printWriter.flush();
      Assert.assertEquals(stringWriter.toString(), str);
    }

    public PrintWriter getPrintWriter() {
      return printWriter;
    }
  }

  /** Test that only lines with at least one column of text emit output. */
  @Test
  public void emptyLine() {
    final PrintWriterComparator comparator = new PrintWriterComparator();
    final ColumnFormatter formatter = new ColumnFormatter(comparator.getPrintWriter(), '\t');
    formatter.addColumn("foo");
    formatter.addColumn("bar");
    formatter.nextLine();
    formatter.nextLine();
    formatter.nextLine();
    formatter.addColumn("foo");
    formatter.addColumn("bar");
    formatter.finish();
    comparator.assertEquals("foo\tbar\nfoo\tbar\n");
  }

  /** Test that there is no output if no columns are ever added. */
  @Test
  public void emptyOutput() {
    final PrintWriterComparator comparator = new PrintWriterComparator();
    final ColumnFormatter formatter = new ColumnFormatter(comparator.getPrintWriter(), '\t');
    formatter.nextLine();
    formatter.nextLine();
    formatter.finish();
    comparator.assertEquals("");
  }

  /**
   * Test that there is no output (nor any exceptions) if we finalize the output immediately after
   * the creation of the {@link ColumnFormatter}.
   */
  @Test
  public void noNextLine() {
    final PrintWriterComparator comparator = new PrintWriterComparator();
    final ColumnFormatter formatter = new ColumnFormatter(comparator.getPrintWriter(), '\t');
    formatter.finish();
    comparator.assertEquals("");
  }

  /**
   * Test that the text in added columns is escaped while the column separator (which of course
   * shouldn't be escaped) is left alone.
   */
  @Test
  public void escapingTakesPlace() {
    final PrintWriterComparator comparator = new PrintWriterComparator();
    final ColumnFormatter formatter = new ColumnFormatter(comparator.getPrintWriter(), '\t');
    formatter.addColumn("foo");
    formatter.addColumn("\tan indented multi-line\ntext");
    formatter.nextLine();
    formatter.finish();
    comparator.assertEquals("foo\t\\tan indented multi-line\\ntext\n");
  }

  /**
   * Test that we get the correct output with multi-line input where the number of columns in each
   * line varies.
   */
  @Test
  public void multiLineDifferentColumnCount() {
    final PrintWriterComparator comparator = new PrintWriterComparator();
    final ColumnFormatter formatter = new ColumnFormatter(comparator.getPrintWriter(), '\t');
    formatter.addColumn("foo");
    formatter.addColumn("bar");
    formatter.addColumn("baz");
    formatter.nextLine();
    formatter.addColumn("foo");
    formatter.addColumn("bar");
    formatter.nextLine();
    formatter.finish();
    comparator.assertEquals("foo\tbar\tbaz\nfoo\tbar\n");
  }

  /** Test that we get the correct output with a single column of input. */
  @Test
  public void oneColumn() {
    final PrintWriterComparator comparator = new PrintWriterComparator();
    final ColumnFormatter formatter = new ColumnFormatter(comparator.getPrintWriter(), '\t');
    formatter.addColumn("foo");
    formatter.nextLine();
    formatter.finish();
    comparator.assertEquals("foo\n");
  }
}
