Repository: sqoop
Updated Branches:
  refs/heads/sqoop2 806e4b75e -> 2a9ae314e


SQOOP-2648: Sqoop2: Add tests for ConfigFiller

(Dian Fu via Jarek Jarcec Cecho)


Project: http://git-wip-us.apache.org/repos/asf/sqoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/sqoop/commit/2a9ae314
Tree: http://git-wip-us.apache.org/repos/asf/sqoop/tree/2a9ae314
Diff: http://git-wip-us.apache.org/repos/asf/sqoop/diff/2a9ae314

Branch: refs/heads/sqoop2
Commit: 2a9ae314e3ea456a7da82b4f6bed53734b255ac2
Parents: 806e4b7
Author: Jarek Jarcec Cecho <[email protected]>
Authored: Wed Nov 4 17:24:36 2015 -0800
Committer: Jarek Jarcec Cecho <[email protected]>
Committed: Wed Nov 4 17:24:36 2015 -0800

----------------------------------------------------------------------
 .../apache/sqoop/shell/utils/ConfigFiller.java  |  64 +--
 .../sqoop/shell/utils/TestConfigFiller.java     | 479 +++++++++++++++++++
 2 files changed, 515 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sqoop/blob/2a9ae314/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java 
b/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java
index 6a2a96d..3a4a18d 100644
--- a/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java
+++ b/shell/src/main/java/org/apache/sqoop/shell/utils/ConfigFiller.java
@@ -21,7 +21,6 @@ import jline.ConsoleReader;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.lang.StringUtils;
-import org.apache.sqoop.common.Direction;
 import org.apache.sqoop.model.InputEditable;
 import org.apache.sqoop.model.MBooleanInput;
 import org.apache.sqoop.model.MDateTimeInput;
@@ -36,7 +35,6 @@ import org.apache.sqoop.model.MMapInput;
 import org.apache.sqoop.model.MJob;
 import org.apache.sqoop.model.MNamedElement;
 import org.apache.sqoop.model.MStringInput;
-import org.apache.sqoop.model.MValidatedElement;
 import org.apache.sqoop.validation.Message;
 import org.apache.sqoop.validation.Status;
 import org.joda.time.DateTime;
@@ -229,7 +227,7 @@ public final class ConfigFiller {
    * @return
    * @throws IOException
    */
-  private static boolean fillInputDateTime(String prefix,
+  static boolean fillInputDateTime(String prefix,
                                        MDateTimeInput input,
                                        CommandLine line)
                                        throws IOException {
@@ -250,14 +248,13 @@ public final class ConfigFiller {
   private static DateTime parseDateTime(String value) {
     DateTime dt = null;
     try {
-      dt = DateTime.parse(value);
-    } catch (IllegalArgumentException iae) {
-      // value is not valid ISO8601 format
+      dt = new DateTime(Long.parseLong(value));
+    } catch (NumberFormatException nfe) {
+      // value is not numeric string
       try {
-        long a  = Long.parseLong(value);
-        dt = new DateTime(a);
-      } catch (NumberFormatException nfe) {
-        // value is not numeric string
+        dt = DateTime.parse(value);
+      } catch (IllegalArgumentException iae) {
+        // value is not valid ISO8601 format
       }
     }
     return dt;
@@ -274,7 +271,7 @@ public final class ConfigFiller {
    * @return
    * @throws IOException
    */
-  private static boolean fillInputList(String prefix,
+  static boolean fillInputList(String prefix,
                                        MListInput input,
                                        CommandLine line)
                                        throws IOException {
@@ -303,7 +300,7 @@ public final class ConfigFiller {
    * @return
    * @throws IOException
    */
-  private static boolean fillInputEnum(String prefix,
+  static boolean fillInputEnum(String prefix,
                                        MEnumInput input,
                                        CommandLine line)
                                        throws IOException {
@@ -335,7 +332,7 @@ public final class ConfigFiller {
    * @return
    * @throws IOException
    */
-  private static boolean fillInputMap(String prefix,
+  static boolean fillInputMap(String prefix,
                                       MMapInput input,
                                       CommandLine line)
                                       throws IOException {
@@ -343,9 +340,9 @@ public final class ConfigFiller {
     if (line.hasOption(opt)) {
       String value = line.getOptionValue(opt);
       Map<String, String> values = new HashMap<String, String>();
-      String[] keyValue = null;
       String[] entries = value.split("&");
       for (String entry : entries) {
+        String[] keyValue = null;
         if (entry.contains("=")) {
           keyValue = entry.split("=", 2);
         }
@@ -372,7 +369,7 @@ public final class ConfigFiller {
    * @return
    * @throws IOException
    */
-  private static boolean fillInputInteger(String prefix,
+  static boolean fillInputInteger(String prefix,
                                           MIntegerInput input,
                                           CommandLine line)
                                           throws IOException {
@@ -402,7 +399,7 @@ public final class ConfigFiller {
    * @return
    * @throws IOException
    */
-  private static boolean fillInputLong(String prefix, MLongInput input, 
CommandLine line) throws IOException {
+  static boolean fillInputLong(String prefix, MLongInput input, CommandLine 
line) throws IOException {
     String opt = ConfigOptions.getOptionKey(prefix, input);
     if (line.hasOption(opt)) {
       try {
@@ -426,7 +423,7 @@ public final class ConfigFiller {
    * @return
    * @throws IOException
    */
-  public static boolean fillInputString(String prefix,
+  static boolean fillInputString(String prefix,
                                         MStringInput input,
                                         CommandLine line)
                                         throws IOException {
@@ -436,6 +433,7 @@ public final class ConfigFiller {
       if((input.getMaxLength() >= 0) && (value.length() > 
input.getMaxLength())) {
         errorMessage(input, "Size of input exceeds allowance for this input"
           + " field. Maximal allowed size is " + input.getMaxLength());
+        return false;
       }
       input.setValue(value);
     } else {
@@ -453,7 +451,7 @@ public final class ConfigFiller {
    * @return
    * @throws IOException
    */
-  public static boolean fillInputBoolean(String prefix,
+  static boolean fillInputBoolean(String prefix,
                                          MBooleanInput input,
                                          CommandLine line)
                                          throws IOException {
@@ -586,9 +584,9 @@ public final class ConfigFiller {
       case STRING:
         return fillInputStringWithBundle((MStringInput) input, reader, bundle);
       case INTEGER:
-        return fillInputInteger((MIntegerInput) input, reader, bundle);
+        return fillInputIntegerWithBundle((MIntegerInput) input, reader, 
bundle);
       case LONG:
-        return fillInputLong((MLongInput) input, reader, bundle);
+        return fillInputLongWithBundle((MLongInput) input, reader, bundle);
       case BOOLEAN:
         return fillInputBooleanWithBundle((MBooleanInput) input, reader, 
bundle);
       case MAP:
@@ -622,7 +620,7 @@ public final class ConfigFiller {
    * @return True if user wish to continue with loading additional inputs
    * @throws IOException
    */
-  private static boolean fillInputDateTimeWithBundle(MDateTimeInput input,
+  static boolean fillInputDateTimeWithBundle(MDateTimeInput input,
                                                      ConsoleReader reader,
                                                      ResourceBundle bundle)
                                                      throws IOException {
@@ -669,7 +667,7 @@ public final class ConfigFiller {
    * @return True if user wish to continue with loading additional inputs
    * @throws IOException
    */
-  private static boolean fillInputListWithBundle(MListInput input,
+  static boolean fillInputListWithBundle(MListInput input,
                                        ConsoleReader reader,
                                        ResourceBundle bundle)
                                        throws IOException {
@@ -735,7 +733,7 @@ public final class ConfigFiller {
    * @return True if user with to continue with loading addtional inputs
    * @throws IOException
    */
-  private static boolean fillInputEnumWithBundle(MEnumInput input,
+  static boolean fillInputEnumWithBundle(MEnumInput input,
                                        ConsoleReader reader,
                                        ResourceBundle bundle)
                                        throws IOException {
@@ -767,6 +765,7 @@ public final class ConfigFiller {
     }
 
     reader.flushConsole();
+
     String userTyped;
     if(input.isSensitive()) {
       userTyped = reader.readLine('*');
@@ -816,7 +815,7 @@ public final class ConfigFiller {
    * @return True if user wish to continue with loading additional inputs
    * @throws IOException
    */
-  private static boolean fillInputMapWithBundle(MMapInput input,
+  static boolean fillInputMapWithBundle(MMapInput input,
                                       ConsoleReader reader,
                                       ResourceBundle bundle)
                                       throws IOException {
@@ -924,7 +923,7 @@ public final class ConfigFiller {
     return input;
   }
 
-  private static boolean fillInputInteger(MIntegerInput input,
+  static boolean fillInputIntegerWithBundle(MIntegerInput input,
                                           ConsoleReader reader,
                                           ResourceBundle bundle)
                                           throws IOException {
@@ -955,7 +954,7 @@ public final class ConfigFiller {
         input.setValue(value);
       } catch (NumberFormatException ex) {
         errorMessage("Input is not valid integer number");
-        return fillInputInteger(input, reader, bundle);
+        return fillInputIntegerWithBundle(input, reader, bundle);
       }
 
       input.setValue(Integer.valueOf(userTyped));
@@ -964,7 +963,7 @@ public final class ConfigFiller {
     return true;
   }
 
-  private static boolean fillInputLong(MLongInput input, ConsoleReader reader, 
ResourceBundle bundle) throws IOException {
+  static boolean fillInputLongWithBundle(MLongInput input, ConsoleReader 
reader, ResourceBundle bundle) throws IOException {
     generatePrompt(reader, bundle, input);
 
     if (!input.isEmpty() && !input.isSensitive()) {
@@ -990,7 +989,7 @@ public final class ConfigFiller {
         input.setValue(value);
       } catch (NumberFormatException ex) {
         errorMessage("Input is not a valid long");
-        return fillInputLong(input, reader, bundle);
+        return fillInputLongWithBundle(input, reader, bundle);
       }
 
       input.setValue(Long.valueOf(userTyped));
@@ -1085,6 +1084,15 @@ public final class ConfigFiller {
       // Empty input in case that nothing was given
       input.setEmpty();
     } else {
+      Boolean value;
+      try {
+        value = Boolean.valueOf(userTyped);
+        input.setValue(value);
+      } catch (NumberFormatException ex) {
+        errorMessage("Input is not a valid boolean");
+        return fillInputBooleanWithBundle(input, reader, bundle);
+      }
+
       // Set value that user has entered
       input.setValue(Boolean.valueOf(userTyped));
     }

http://git-wip-us.apache.org/repos/asf/sqoop/blob/2a9ae314/shell/src/test/java/org/apache/sqoop/shell/utils/TestConfigFiller.java
----------------------------------------------------------------------
diff --git 
a/shell/src/test/java/org/apache/sqoop/shell/utils/TestConfigFiller.java 
b/shell/src/test/java/org/apache/sqoop/shell/utils/TestConfigFiller.java
new file mode 100644
index 0000000..1917a1d
--- /dev/null
+++ b/shell/src/test/java/org/apache/sqoop/shell/utils/TestConfigFiller.java
@@ -0,0 +1,479 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.sqoop.shell.utils;
+
+import static org.apache.sqoop.shell.utils.ConfigFiller.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.ResourceBundle;
+
+import jline.ConsoleReader;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.lang.StringUtils;
+import org.apache.sqoop.model.InputEditable;
+import org.apache.sqoop.model.MBooleanInput;
+import org.apache.sqoop.model.MDateTimeInput;
+import org.apache.sqoop.model.MEnumInput;
+import org.apache.sqoop.model.MIntegerInput;
+import org.apache.sqoop.model.MListInput;
+import org.apache.sqoop.model.MLongInput;
+import org.apache.sqoop.model.MMapInput;
+import org.apache.sqoop.model.MStringInput;
+import org.apache.sqoop.shell.ShellEnvironment;
+import org.codehaus.groovy.tools.shell.Groovysh;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+public class TestConfigFiller {
+  CommandLine line;
+  ConsoleReader reader;
+  ResourceBundle resourceBundle;
+  ByteArrayInputStream in;
+  byte[] data;
+
+  @BeforeTest(alwaysRun = true)
+  public void setup() throws IOException {
+    Groovysh shell = new Groovysh();
+    ShellEnvironment.setIo(shell.getIo());
+    line = mock(CommandLine.class);
+    data = new byte[1000];
+    in = new ByteArrayInputStream(data);
+    reader = new ConsoleReader(in, new OutputStreamWriter(System.out));
+    resourceBundle = new ResourceBundle() {
+      @Override
+      protected Object handleGetObject(String key) {
+        return "fake_translated_value";
+      }
+
+      @Override
+      public Enumeration<String> getKeys() {
+        return Collections.emptyEnumeration();
+      }
+    };
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputString() throws IOException {
+    MStringInput input = new MStringInput("String", false, InputEditable.ANY, 
StringUtils.EMPTY, (short)30, Collections.EMPTY_LIST);
+    when(line.hasOption("prefix-String")).thenReturn(false);
+    assertTrue(fillInputString("prefix", input, line));
+    assertNull(input.getValue());
+
+    input.setEmpty();
+    when(line.hasOption("prefix-String")).thenReturn(true);
+    when(line.getOptionValue("prefix-String")).thenReturn("abc");
+    assertTrue(fillInputString("prefix", input, line));
+    assertEquals(input.getValue(), "abc");
+
+    input.setEmpty();
+    String lengthExceeds30 = 
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
+    when(line.getOptionValue("prefix-String")).thenReturn(lengthExceeds30);
+    assertFalse(fillInputString("prefix", input, line));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputStringWithBundle() throws IOException {
+    initEnv();
+    // End of the process
+    MStringInput input = new MStringInput("String", false, InputEditable.ANY, 
StringUtils.EMPTY, (short)30, Collections.EMPTY_LIST);
+    assertFalse(fillInputStringWithBundle(input, reader, resourceBundle));
+
+    // Empty input
+    initData("\r");
+    input.setEmpty();
+    assertTrue(fillInputStringWithBundle(input, reader, resourceBundle));
+    assertNull(input.getValue());
+
+    // Normal input
+    initData("abc\r");
+    input.setEmpty();
+    assertTrue(fillInputStringWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue(), "abc");
+
+    // Retry when the given input exceeds maximal allowance
+    String lengthExceeds30 = 
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
+    String remove30characters = 
"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
+    String lengthBelowLimit = "abcdefg";
+    initData(lengthExceeds30 + "\r" + remove30characters + lengthBelowLimit + 
"\r");
+    input.setEmpty();
+    assertTrue(fillInputStringWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue(), lengthBelowLimit);
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputInteger() throws IOException {
+    MIntegerInput input = new MIntegerInput("Integer", false, 
InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    when(line.hasOption("prefix-Integer")).thenReturn(false);
+    assertTrue(fillInputInteger("prefix", input, line));
+    assertNull(input.getValue());
+
+    // Valid integer number
+    input.setEmpty();
+    when(line.hasOption("prefix-Integer")).thenReturn(true);
+    when(line.getOptionValue("prefix-Integer")).thenReturn("12345");
+    assertTrue(fillInputInteger("prefix", input, line));
+    assertEquals(input.getValue().intValue(), 12345);
+
+    // Invalid integer number
+    input.setEmpty();
+    when(line.hasOption("prefix-Integer")).thenReturn(true);
+    when(line.getOptionValue("prefix-Integer")).thenReturn("abc");
+    assertFalse(fillInputInteger("prefix", input, line));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputIntegerWithBundle() throws IOException {
+    initEnv();
+    // End of the process
+    MIntegerInput input = new MIntegerInput("Integer", false, 
InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    assertFalse(fillInputIntegerWithBundle(input, reader, resourceBundle));
+
+    // Empty input
+    initData("\r");
+    input.setEmpty();
+    assertTrue(fillInputIntegerWithBundle(input, reader, resourceBundle));
+    assertNull(input.getValue());
+
+    // Normal input
+    initData("12345\r");
+    input.setEmpty();
+    assertTrue(fillInputIntegerWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue().intValue(), 12345);
+
+    // Retry when the given input is not a valid integer number
+    initData("abc\r12345\r");
+    input.setEmpty();
+    assertTrue(fillInputIntegerWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue().intValue(), 12345);
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputLong() throws IOException {
+    MLongInput input = new MLongInput("Long", false, InputEditable.ANY, 
StringUtils.EMPTY, Collections.EMPTY_LIST);
+    when(line.hasOption("prefix-Long")).thenReturn(false);
+    assertTrue(fillInputLong("prefix", input, line));
+    assertNull(input.getValue());
+
+    // Valid long number
+    input.setEmpty();
+    when(line.hasOption("prefix-Long")).thenReturn(true);
+    when(line.getOptionValue("prefix-Long")).thenReturn("12345");
+    assertTrue(fillInputLong("prefix", input, line));
+    assertEquals(input.getValue().longValue(), 12345);
+
+    // Invalid long number
+    input.setEmpty();
+    when(line.hasOption("prefix-Long")).thenReturn(true);
+    when(line.getOptionValue("prefix-Long")).thenReturn("abc");
+    assertFalse(fillInputLong("prefix", input, line));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputLongWithBundle() throws IOException {
+    initEnv();
+    // End of the process
+    MLongInput input = new MLongInput("Long", false, InputEditable.ANY, 
StringUtils.EMPTY, Collections.EMPTY_LIST);
+    assertFalse(fillInputLongWithBundle(input, reader, resourceBundle));
+
+    // Empty input
+    initData("\r");
+    input.setEmpty();
+    assertTrue(fillInputLongWithBundle(input, reader, resourceBundle));
+    assertNull(input.getValue());
+
+    // Normal input
+    initData("12345\r");
+    input.setEmpty();
+    assertTrue(fillInputLongWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue().intValue(), 12345);
+
+    // Retry when the given input is not a valid long number
+    initData("abc\r12345\r");
+    input.setEmpty();
+    assertTrue(fillInputLongWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue().intValue(), 12345);
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputBoolean() throws IOException {
+    MBooleanInput input = new MBooleanInput("Boolean", false, 
InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    when(line.hasOption("prefix-Boolean")).thenReturn(false);
+    assertTrue(fillInputBoolean("prefix", input, line));
+    assertNull(input.getValue());
+
+    // true
+    input.setEmpty();
+    when(line.hasOption("prefix-Boolean")).thenReturn(true);
+    when(line.getOptionValue("prefix-Boolean")).thenReturn("true");
+    assertTrue(fillInputBoolean("prefix", input, line));
+    assertTrue(input.getValue());
+
+    // false
+    input.setEmpty();
+    when(line.hasOption("prefix-Boolean")).thenReturn(true);
+    when(line.getOptionValue("prefix-Boolean")).thenReturn("false");
+    assertTrue(fillInputBoolean("prefix", input, line));
+    assertFalse(input.getValue());
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputBooleanWithBundle() throws IOException {
+    initEnv();
+    // End of the process
+    MBooleanInput input = new MBooleanInput("Boolean", false, 
InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    assertFalse(fillInputBooleanWithBundle(input, reader, resourceBundle));
+
+    // true
+    initData("true\r");
+    input.setEmpty();
+    assertTrue(fillInputBooleanWithBundle(input, reader, resourceBundle));
+    assertTrue(input.getValue());
+
+    // false
+    initData("false\r");
+    input.setEmpty();
+    assertTrue(fillInputBooleanWithBundle(input, reader, resourceBundle));
+    assertFalse(input.getValue());
+
+    // Retry when the given input is not a valid boolean number
+    initData("abc\rfalse\r");
+    input.setEmpty();
+    assertTrue(fillInputBooleanWithBundle(input, reader, resourceBundle));
+    assertFalse(input.getValue());
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputMap() throws IOException {
+    MMapInput input = new MMapInput("Map", false, InputEditable.ANY, 
StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    when(line.hasOption("prefix-Map")).thenReturn(false);
+    assertTrue(fillInputMap("prefix", input, line));
+
+    // Normal input
+    input.setEmpty();
+    when(line.hasOption("prefix-Map")).thenReturn(true);
+    when(line.getOptionValue("prefix-Map")).thenReturn("k1=v1&k2=v2");
+    assertTrue(fillInputMap("prefix", input, line));
+    HashMap<String, String> map = new HashMap<String, String>();
+    map.put("k1", "v1");
+    map.put("k2", "v2");
+    assertEquals(input.getValue(), map);
+
+    // Invalid input
+    input.setEmpty();
+    when(line.hasOption("prefix-Map")).thenReturn(true);
+    when(line.getOptionValue("prefix-Map")).thenReturn("k1=v1&k2");
+    assertFalse(fillInputMap("prefix", input, line));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputMapWithBundle() throws IOException {
+    initEnv();
+    // End of the process
+    MMapInput input = new MMapInput("Map", false, InputEditable.ANY, 
StringUtils.EMPTY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    assertFalse(fillInputMapWithBundle(input, reader, resourceBundle));
+
+    // empty
+    initData("\r");
+    input.setEmpty();
+    assertTrue(fillInputMapWithBundle(input, reader, resourceBundle));
+
+    // Add k1=v1 and k2=v2
+    initData("k1=v1\rk2=v2\r\r");
+    input.setEmpty();
+    assertTrue(fillInputMapWithBundle(input, reader, resourceBundle));
+    HashMap<String, String> map = new HashMap<String, String>();
+    map.put("k1", "v1");
+    map.put("k2", "v2");
+    assertEquals(input.getValue(), map);
+
+    // Remove k2
+    initData("k2\r\r");
+    assertTrue(fillInputMapWithBundle(input, reader, resourceBundle));
+    map.remove("k2");
+    assertEquals(input.getValue(), map);
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputEnum() throws IOException {
+    MEnumInput input = new MEnumInput("Enum", false, InputEditable.ANY, 
StringUtils.EMPTY, new String[] {"YES", "NO"}, Collections.EMPTY_LIST);
+    when(line.hasOption("prefix-Enum")).thenReturn(false);
+    assertTrue(fillInputEnum("prefix", input, line));
+    assertNull(input.getValue());
+
+    // Normal input
+    input.setEmpty();
+    when(line.hasOption("prefix-Enum")).thenReturn(true);
+    when(line.getOptionValue("prefix-Enum")).thenReturn("YES");
+    assertTrue(fillInputEnum("prefix", input, line));
+    assertEquals(input.getValue(), "YES");
+
+    // Invalid input
+    input.setEmpty();
+    when(line.hasOption("prefix-Enum")).thenReturn(true);
+    when(line.getOptionValue("prefix-Enum")).thenReturn("NONEXISTVALUE");
+    assertFalse(fillInputEnum("prefix", input, line));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputEnumWithBundle() throws IOException {
+    initEnv();
+    // End of the process
+    MEnumInput input = new MEnumInput("Enum", false, InputEditable.ANY, 
StringUtils.EMPTY, new String[] {"YES", "NO"}, Collections.EMPTY_LIST);
+    assertFalse(fillInputEnumWithBundle(input, reader, resourceBundle));
+
+    // empty
+    initData("\r");
+    input.setEmpty();
+    assertTrue(fillInputEnumWithBundle(input, reader, resourceBundle));
+
+    // YES
+    initData("0\r");
+    input.setEmpty();
+    assertTrue(fillInputEnumWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue(), "YES");
+
+    // Retry when the given input is not a valid boolean number
+    initData("a\r1\r");
+    input.setEmpty();
+    assertTrue(fillInputEnumWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue(), "NO");
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputList() throws IOException {
+    MListInput input = new MListInput("List", false, InputEditable.ANY, 
StringUtils.EMPTY, Collections.EMPTY_LIST);
+    when(line.hasOption("prefix-List")).thenReturn(false);
+    assertTrue(fillInputList("prefix", input, line));
+    assertNull(input.getValue());
+
+    // Normal input
+    input.setEmpty();
+    when(line.hasOption("prefix-List")).thenReturn(true);
+    when(line.getOptionValue("prefix-List")).thenReturn("l1&l2&l3");
+    assertTrue(fillInputList("prefix", input, line));
+    assertEquals(StringUtils.join(input.getValue(), "&"), "l1&l2&l3");
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputListWithBundle() throws IOException {
+    initEnv();
+    // End of the process
+    MListInput input = new MListInput("List", false, InputEditable.ANY, 
StringUtils.EMPTY, Collections.EMPTY_LIST);
+    assertFalse(fillInputListWithBundle(input, reader, resourceBundle));
+
+    // empty
+    initData("\r");
+    input.setEmpty();
+    assertTrue(fillInputListWithBundle(input, reader, resourceBundle));
+
+    // Normal input
+    initData("l1\rl2\rl3\r\r");
+    input.setEmpty();
+    assertTrue(fillInputListWithBundle(input, reader, resourceBundle));
+    assertEquals(StringUtils.join(input.getValue(), "&"), "l1&l2&l3");
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputDateTime() throws IOException {
+    MDateTimeInput input = new MDateTimeInput("DateTime", false, 
InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    when(line.hasOption("prefix-DateTime")).thenReturn(false);
+    assertTrue(fillInputDateTime("prefix", input, line));
+    assertNull(input.getValue());
+
+    // Normal input
+    input.setEmpty();
+    when(line.hasOption("prefix-DateTime")).thenReturn(true);
+    when(line.getOptionValue("prefix-DateTime")).thenReturn("123456789");
+    assertTrue(fillInputDateTime("prefix", input, line));
+    assertEquals(input.getValue().getMillis(), 123456789);
+
+    // Invalid input
+    input.setEmpty();
+    when(line.hasOption("prefix-DateTime")).thenReturn(true);
+    when(line.getOptionValue("prefix-DateTime")).thenReturn("abcd");
+    assertFalse(fillInputDateTime("prefix", input, line));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void testFillInputDateTimeWithBundle() throws IOException {
+    initEnv();
+    // End of the process
+    MDateTimeInput input = new MDateTimeInput("DateTime", false, 
InputEditable.ANY, StringUtils.EMPTY, Collections.EMPTY_LIST);
+    assertFalse(fillInputDateTimeWithBundle(input, reader, resourceBundle));
+
+    // empty
+    initData("\r");
+    input.setEmpty();
+    assertTrue(fillInputDateTimeWithBundle(input, reader, resourceBundle));
+
+    // Normal input
+    initData("123456789\r");
+    input.setEmpty();
+    assertTrue(fillInputDateTimeWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue().getMillis(), 123456789);
+
+    // Retry when the given input is not valid datetime
+    initData("abc\r123456789\r");
+    input.setEmpty();
+    assertTrue(fillInputDateTimeWithBundle(input, reader, resourceBundle));
+    assertEquals(input.getValue().getMillis(), 123456789);
+  }
+
+  private void initData(String destData) {
+    byte[] destDataBytes = destData.getBytes();
+    System.arraycopy(destDataBytes, 0, data, 0, destDataBytes.length);
+    in.reset();
+  }
+
+  private void initEnv() {
+    in.reset();
+    for (int i = 0; i < data.length; i++) {
+      data[i] = '\0';
+    }
+  }
+}

Reply via email to