/*
 * StringConverter02StrTest class.
 *
 * Copyright (C) 2007 SATOH Takayuki All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package ts.util.text;

import ts.tester.function.FunctionTester;
import java.util.*;

/**
 * {@link ts.util.text.StringConverter StringConverter}クラスの機能試験クラス。
 *
 * @author  佐藤隆之.
 * @version $Revision: 1.1.1.1 $, $Date: 2010-10-16 00:03:53 $
 */
public class StringConverter02StrTest extends FunctionTester
{
  public static void main(String[] args)
  {
    try {
      run(StringConverter02StrTest.class, (args.length == 0) ? null : args[0]);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /* -- test case -- */

  public void fromReadString_str_esc_spec()
  {
    MSG("引数がヌルの場合。");

    try {
      StringConverter.fromReadString(null, "\\", Arrays.asList(","));
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      StringConverter.fromReadString("abc", null, Arrays.asList(","));
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      StringConverter.fromReadString("abc", "|", null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void fromReadString_str_esc_spec_0()
  {
    MSG("エスケープ文字列が空の場合。");

    try {
      StringConverter.fromReadString("abc", "", Arrays.asList(",", "\""));
      NG();
    } catch (IllegalArgumentException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void fromReadString_str_esc_spec_1()
  {
    MSG("特殊文字列にヌルや空文字列が含まれている場合。");

    try {
      StringConverter.fromReadString("abc", "\\", Arrays.asList(",",null,"\""));
      NG();
    } catch (IllegalArgumentException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      StringConverter.fromReadString("abc", "\\", Arrays.asList(",","\"",""));
      NG();
    } catch (IllegalArgumentException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void fromReadString_str_esc_spec_2()
  {
    MSG("通常の場合。");

    List<String> sL = Arrays.asList(",\"");
    try {
      EQUAL(StringConverter.fromReadString("abcdefg", "\\", sL), "abcdefg");
      EQUAL(StringConverter.fromReadString("   defg", "\\", sL), "defg");
      EQUAL(StringConverter.fromReadString(" \\ defg", "\\", sL), " defg");
      EQUAL(StringConverter.fromReadString(" defg  ", "\\", sL), "defg");

      EQUAL(StringConverter.fromReadString("a\\,bc", "\\", sL), "a,bc");
      EQUAL(StringConverter.fromReadString("ab\\\"c", "\\", sL), "ab\"c");
      EQUAL(StringConverter.fromReadString("ab\\\\c", "\\", sL), "ab\\c");

      EQUAL(StringConverter.fromReadString("", "\\", sL), "");
    } catch (Exception e) {
      NG(e);
    }
  }

  public void fromReadString_str_esc_spec_3()
  {
    MSG("特殊文字列がエスケープされていない場合。");

    List<String> sL = Arrays.asList(",", "\"");

    try {
      StringConverter.fromReadString("a,bc", "\\", sL);
      NG();
    } catch (SpecialCharNotEscapedException e) {
      OK(e);
      EQUAL(e.getStoppedIndex(), 1);
      EQUAL(e.convertedString(), "a");
      EQUAL(e.getSpecialChar(), ",");
    } catch (Exception e) {
      NG(e);
    }

    try {
      StringConverter.fromReadString("ab\"c", "\\", sL);
      NG();
    } catch (SpecialCharNotEscapedException e) {
      OK(e);
      EQUAL(e.getStoppedIndex(), 2);
      EQUAL(e.convertedString(), "ab");
      EQUAL(e.getSpecialChar(), "\"");
    } catch (Exception e) {
      NG(e);
    }
  }

  public void fromReadString_str_esc_spec_4()
  {
    MSG("エスケープ文字列で終了している場合。");
    
    List<String> sL = Arrays.asList(",", "\"");

    try {
      StringConverter.fromReadString("\\", "\\", sL);
      NG();
    } catch (EndWithEscapeCharException e) {
      OK(e);
      EQUAL(e.getStoppedIndex(), 0);
    } catch (Exception e) {
      NG(e);
    }

    try {
      StringConverter.fromReadString("abc\\", "\\", sL);
      NG();
    } catch (EndWithEscapeCharException e) {
      OK(e);
      EQUAL(e.getStoppedIndex(), 3);
    } catch (Exception e) {
      NG(e);
    }

    try {
      StringConverter.fromReadString("abc \\", "\\", sL);
      NG();
    } catch (EndWithEscapeCharException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      EQUAL(StringConverter.fromReadString("abc \\    ", "\\", sL), "abc  ");
    } catch (Exception e) {
      NG(e);
    } 
  }

  public void fromReadString_str_esc_spec_5()
  {
    MSG("ファイルからの読込を想定。");

    List<String> sL = new ArrayList<String>();

    String[] lines = {
      "This is a  ",
      " \\ red pen.  "
    };

    StringBuilder buf = new StringBuilder();
    try {
      for (int i=0; i<lines.length; i++) {
        buf.append(StringConverter.fromReadString(lines[i], "\\", sL));
      }
      EQUAL(buf.toString(), "This is a red pen.");
    } catch (Exception e) {
      NG(e);
    }

    lines[0] = "This is a\\ ";
    lines[1] = "red pen. ";

    buf = new StringBuilder();
    try {
      for (int i=0; i<lines.length; i++) {
        buf.append(StringConverter.fromReadString(lines[i], "\\", sL));
      }
      EQUAL(buf.toString(), "This is a red pen.");
    } catch (Exception e) {
      NG(e);
    }

    lines[0] = "This is a \\";
    lines[1] = "red pen.  ";

    buf = new StringBuilder();
    try {
      for (int i=0; i<lines.length; i++) {
        try {
          buf.append(StringConverter.fromReadString(lines[i], "\\", sL));
        } catch (EndWithEscapeCharException e) {
          buf.append(e.convertedString());
          continue;
        }
      }
      EQUAL(buf.toString(), "This is a red pen.");
    } catch (Exception e) {
      NG(e);
    }

    lines[0] = "This is a $";
    lines[1] = "red pen.  ";
    sL.add("$");

    buf = new StringBuilder();
    try {
      for (int i=0; i<lines.length; i++) {
        try {
          buf.append(StringConverter.fromReadString(lines[i], "\\", sL));
        } catch (SpecialCharNotEscapedException e) {
          int len = StringOperation.length(lines[i]);
          int specLen = StringOperation.length(e.getSpecialChar());
          if (e.getSpecialChar().equals("$") &&
              e.getStoppedIndex() == len - specLen) {
            buf.append(e.convertedString());
            continue;
          }
          throw e;
        }
      }
      EQUAL(buf.toString(), "This is a red pen.");
    } catch (StringConvertException e) {
      NG(e);
    }
  }

  public void fromReadString_str_esc_spec_6()
  {
    MSG("エスケープ文字列の文字数が２以上の場合。");

    List<String> sL = Arrays.asList(",", "\"");

    try {
      EQUAL(StringConverter.fromReadString("a$#@,bc", "$#@", sL), "a,bc");
      EQUAL(StringConverter.fromReadString("ab$#@\"c", "$#@", sL), "ab\"c");
      EQUAL(StringConverter.fromReadString("ab$#@\\c", "$#@", sL), "ab\\c");
    } catch (Exception e) {
      NG(e);
    }
  }

  public void fromReadString_str_esc_spec_7()
  {
    MSG("特殊文字列の文字数が２以上複数の場合。");

    List<String> sL = Arrays.asList("|||", "@@@");

    try {
      EQUAL(StringConverter.fromReadString("a$$|||b$$@@@c", "$$", sL),
        "a|||b@@@c");
    } catch (Exception e) {
      NG(e);
    }
  }

  public void fromReadString_str_esc_spec_8()
  {
    MSG("補助文字が含まれている場合。");

    List<String> sL = Arrays.asList(",", "\"");

    try {
      EQUAL(StringConverter.fromReadString(
        "  \uD800\uDC32////\uD800\uDC33あ  ", "//", sL),
        "\uD800\uDC32//\uD800\uDC33あ");
    } catch (Exception e) {
      NG(e);
    }

    try {
      EQUAL(StringConverter.fromReadString(
        "あ\uD800\uDC32いう\uD800\uDC32えお", "\uD800\uDC32", sL),
        "あいうえお");
    } catch (Exception e) {
      NG(e);
    }
  }

  public void fromReadString_readStr_escapeStr_specialChars_9()
  {
    MSG("エスケープ文字が連続して続く場合。");

    List<String> spL = Arrays.asList("#");
    try {
        EQUAL(StringConverter.fromReadString("############", "##", spL),
          "####");
    } catch (Exception e) {
      NG(e);
    }
  }

  public void toWriteString_str_esc_spec()
  {
    MSG("引数がヌルの場合。");

    List<String> sL = Arrays.asList(",", "\"");
 
    try {
      StringConverter.toWriteString(null, "\\", sL);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      StringConverter.toWriteString("abc", null, sL);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    try {
      StringConverter.toWriteString("abc", "\\", null);
      NG();
    } catch (AssertionError e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }

  public void toWriteString_str_esc_spec_0()
  {
    MSG("通常の操作。");

    List<String> sL = Arrays.asList(",", "\"");

    EQUAL(StringConverter.toWriteString("", "\\", sL), "");
    EQUAL(StringConverter.toWriteString("abc", "\\", sL), "abc");
    EQUAL(StringConverter.toWriteString("a,bc", "\\", sL), "a\\,bc");
    EQUAL(StringConverter.toWriteString("ab\"c", "\\", sL), "ab\\\"c");
    EQUAL(StringConverter.toWriteString("abc\\", "\\", sL), "abc\\\\");

    EQUAL(StringConverter.toWriteString("a,b,c", "!#$%&@|?\\", sL),
      "a!#$%&@|?\\,b!#$%&@|?\\,c");

    try {
      EQUAL(StringConverter.fromReadString(
        "a!#$%&@|?\\,b!#$%&@|?\\,c", "!#$%&@|?\\", sL), "a,b,c");
    } catch (Exception e) {
      NG(e);
    }
  }

  public void toWriteString_str_esc_spec_1()
  {
    MSG("先頭または末尾が空白の場合。");

    List<String> sL = Arrays.asList(",", "\"");

    EQUAL(StringConverter.toWriteString("  abc", "#", sL), "#  abc");
    EQUAL(StringConverter.toWriteString("a bc  ", "#", sL), "a bc # ");
    EQUAL(StringConverter.toWriteString(" abc ", "#", sL), "# abc# ");
    EQUAL(StringConverter.toWriteString(" ", "#", sL), "# ");
  }

  public void toWriteString_str_esc_spec_2()
  {
    MSG("fromReadString で元に戻るか。");
    
    try {
      String esc = "\\";
      List<String> sL = Arrays.asList(",", "\"");
      StringConverter SC = new StringConverter();
  
      String s = "";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);
  
      s = "abc";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);
  
      s = "a,bc";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);

      s = "ab\"c";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);

      s = "abc\\";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);

      s = "  abc";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);

      s = "a bc  ";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);

      s = " abc  ";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);

      s = " ";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);

      s = "a,b,c";
      esc = "!#$%&@|?\\";
      EQUAL(SC.fromReadString(SC.toWriteString(s, esc, sL), esc, sL), s);

    } catch (Exception e) {
      NG(e);
    }
  }

  public void toWriteString_3()
  {
    MSG("エスケープ文字や特殊文字が空の場合。");
    
    List<String> spL = Arrays.asList(",", "");

    try {
      StringConverter.toWriteString("abc", "$", spL);
      NG();
    } catch (IllegalArgumentException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    spL = Arrays.asList(",", null);

    try {
      StringConverter.toWriteString("abc", "$", spL);
      NG();
    } catch (IllegalArgumentException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }

    spL = Arrays.asList(",", "#");

    try {
      StringConverter.toWriteString("abc", "", spL);
      NG();
    } catch (IllegalArgumentException e) {
      OK(e);
    } catch (Exception e) {
      NG(e);
    }
  }
}
