From 674d374c15be741230724abd802576db04552831 Mon Sep 17 00:00:00 2001 From: viiviii Date: Thu, 5 May 2022 22:52:49 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20Boolean=20=EC=9D=B8=EC=88=98?= =?UTF-8?q?=EB=A7=8C=20=EC=A7=80=EC=9B=90=ED=95=98=EB=8D=98=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=20=EB=B2=84=EC=A0=84=20/=20=EB=AA=A9=EB=A1=9D=2014-9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chapter14/Application.java | 15 +++ src/main/java/chapter14/Args.java | 121 +++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/main/java/chapter14/Application.java create mode 100644 src/main/java/chapter14/Args.java diff --git a/src/main/java/chapter14/Application.java b/src/main/java/chapter14/Application.java new file mode 100644 index 0000000..c1c30e3 --- /dev/null +++ b/src/main/java/chapter14/Application.java @@ -0,0 +1,15 @@ +package chapter14; + +public class Application { + + public static void main(String[] args) { + Args arg = new Args("l", args); + boolean logging = arg.getBoolean('l'); + executeApplication(logging); + } + + // stub + private static void executeApplication(boolean logging) { + System.out.printf("logging: %b\n", logging); + } +} diff --git a/src/main/java/chapter14/Args.java b/src/main/java/chapter14/Args.java new file mode 100644 index 0000000..f4a8687 --- /dev/null +++ b/src/main/java/chapter14/Args.java @@ -0,0 +1,121 @@ +package chapter14; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +public class Args { + private String scheme; + private String[] args; + private boolean valid; + private Set unexpectedArguments = new TreeSet<>(); + private Map booleanArgs = new HashMap<>(); + private int numberOfArguments = 0; + + public Args(String schema, String[] args) { + this.scheme = schema; + this.args = args; + valid = parse(); + } + + public boolean isValid() { + return valid; + } + + private boolean parse() { + if (scheme.length() == 0 && args.length == 0) + return true; + parseSchema(); + parseArguments(); + return unexpectedArguments.size() == 0; + } + + private boolean parseSchema() { + for (String element : scheme.split(",")) { + parseSchemaElement(element); + } + return true; + } + + private void parseSchemaElement(String element) { + if (element.length() == 1) { + parseBooleanSchemeElement(element); + } + } + + private void parseBooleanSchemeElement(String element) { + char c = element.charAt(0); + if (Character.isLetter(c)) { + booleanArgs.put(c, false); + } + } + + private boolean parseArguments() { + for (String arg : args) { + parseArgument(arg); + } + return true; + } + + private void parseArgument(String arg) { + if (arg.startsWith("-")) + parseElements(arg); + } + + private void parseElements(String arg) { + for (int i = 1; i < arg.length(); i++) { + parseElement(arg.charAt(i)); + } + } + + private void parseElement(char argChar) { + if (isBoolean(argChar)) { + numberOfArguments++; + setBooleanArg(argChar, true); + } else { + unexpectedArguments.add(argChar); + } + } + + private void setBooleanArg(char argChar, boolean value) { + booleanArgs.put(argChar, value); + } + + private boolean isBoolean(char argChar) { + return booleanArgs.containsKey(argChar); + } + + public int cardinality() { + return numberOfArguments; + } + + public String usage() { + if (scheme.length() > 0) + return "-[" + scheme + "]"; + else + return ""; + } + + public String errorMessage() { + if (unexpectedArguments.size() > 0) { + return unexpectedArgumentMessage(); + } else { + return ""; + } + } + + private String unexpectedArgumentMessage() { + StringBuffer message = new StringBuffer("Argument(s) -"); + for (char c : unexpectedArguments) { + message.append(c); + } + message.append(" unexpected."); + + return message.toString(); + } + + public boolean getBoolean(char arg) { + return booleanArgs.get(arg); + } +} From ef819de66ee16a2bf2a6ea0b1f41c35281393601 Mon Sep 17 00:00:00 2001 From: viiviii Date: Fri, 6 May 2022 12:56:25 +0900 Subject: [PATCH 2/3] =?UTF-8?q?test:=20Boolean=20=EC=9D=B8=EC=88=98?= =?UTF-8?q?=EB=A7=8C=20=EC=A7=80=EC=9B=90=ED=95=98=EB=8D=98=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=20=EB=B2=84=EC=A0=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/chapter14/ApplicationTest.java | 37 ++++++ src/test/java/chapter14/ArgsTest.java | 123 +++++++++++++++++++ src/test/java/chapter14/MainMethodTest.java | 39 ++++++ 3 files changed, 199 insertions(+) create mode 100644 src/test/java/chapter14/ApplicationTest.java create mode 100644 src/test/java/chapter14/ArgsTest.java create mode 100644 src/test/java/chapter14/MainMethodTest.java diff --git a/src/test/java/chapter14/ApplicationTest.java b/src/test/java/chapter14/ApplicationTest.java new file mode 100644 index 0000000..101aeb8 --- /dev/null +++ b/src/test/java/chapter14/ApplicationTest.java @@ -0,0 +1,37 @@ +package chapter14; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ApplicationTest extends MainMethodTest { + + @Test + void validBooleanArgs() { + //given + String arg = "-l"; + + //when + runMain(arg); + + //then + assertThat(output()).contains("logging: true"); + } + + @Test + void invalidBooleanArgs() { + //given + String notStartWithHyphen = "l"; + + //when + runMain(notStartWithHyphen); + + //then + assertThat(output()).contains("logging: false"); + } + + @Override + protected void runMain(String... args) { + Application.main(args); + } +} \ No newline at end of file diff --git a/src/test/java/chapter14/ArgsTest.java b/src/test/java/chapter14/ArgsTest.java new file mode 100644 index 0000000..64d7843 --- /dev/null +++ b/src/test/java/chapter14/ArgsTest.java @@ -0,0 +1,123 @@ +package chapter14; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ArgsTest { + + @DisplayName("scheme와 arguments가 없는 경우") + @Test + void noSchemaAndArguments() { + //given + String schema = ""; + String[] arguments = new String[0]; + + //when + Args args = new Args(schema, arguments); + + //then + assertThat(args.isValid()).isTrue(); + assertThat(args.cardinality()).isZero(); + } + + @DisplayName("scheme가 없고 argument가 1개 있는 경우") + @Test + void noSchemaButWithOneArgument() { + //given + String schema = ""; + String[] arguments = new String[]{"-x"}; + + //when + Args args = new Args(schema, arguments); + + //then + assertThat(args.isValid()).isFalse(); + assertThat(args.cardinality()).isZero(); + assertThat(args.errorMessage()).isEqualTo("Argument(s) -x unexpected."); + } + + @DisplayName("scheme가 없고 argument가 여러 개 있는 경우") + @Test + void noSchemaButWithMultipleArguments() { + //given + String schema = ""; + String[] arguments = new String[]{"-x", "-y"}; + + //when + Args args = new Args(schema, arguments); + + //then + assertThat(args.isValid()).isFalse(); + assertThat(args.cardinality()).isZero(); + assertThat(args.errorMessage()).isEqualTo("Argument(s) -xy unexpected."); + } + + @DisplayName("boolean 값이 없는 경우") + @Test + void simpleBooleanNotPresent() { + //given + String schema = "x"; + String[] arguments = new String[]{}; + + //when + Args args = new Args(schema, arguments); + + //then + assertThat(args.isValid()).isTrue(); + assertThat(args.cardinality()).isZero(); + assertThat(args.getBoolean('x')).isFalse(); + } + + @DisplayName("boolean 값이 있는 경우") + @Test + void simpleBooleanPresent() { + //given + String schema = "x"; + String[] arguments = new String[]{"-x"}; + + //when + Args args = new Args(schema, arguments); + + //then + assertThat(args.isValid()).isTrue(); + assertThat(args.cardinality()).isOne(); + assertThat(args.getBoolean('x')).isTrue(); + } + + @DisplayName("boolean 값이 여러 개 있는 경우") + @Test + void simpleBooleanMultiplePresent() { + //given + String schema = "x,y"; + String[] arguments = new String[]{"-x", "-y"}; + + //when + Args args = new Args(schema, arguments); + + //then + assertThat(args.isValid()).isTrue(); + assertThat(args.cardinality()).isEqualTo(2); + assertThat(args.getBoolean('x')).isTrue(); + assertThat(args.getBoolean('y')).isTrue(); + } + + @DisplayName("boolean 값이 여러 개 중 하나만 있는 경우") + @Test + void simpleBooleanOnlyOnePresent() { + //given + String schema = "x,y,z"; + String[] arguments = new String[]{"-z"}; + + //when + Args args = new Args(schema, arguments); + + //then + assertThat(args.isValid()).isTrue(); + assertThat(args.cardinality()).isOne(); + assertThat(args.getBoolean('x')).isFalse(); + assertThat(args.getBoolean('y')).isFalse(); + assertThat(args.getBoolean('z')).isTrue(); + } +} \ No newline at end of file diff --git a/src/test/java/chapter14/MainMethodTest.java b/src/test/java/chapter14/MainMethodTest.java new file mode 100644 index 0000000..e0bf861 --- /dev/null +++ b/src/test/java/chapter14/MainMethodTest.java @@ -0,0 +1,39 @@ +package chapter14; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.io.PrintStream; + +abstract class MainMethodTest { + private final PrintStream standardOut = System.out; + private OutputStream captor; + + @BeforeEach + protected final void init() { + setSystemOutToMyPrintStreamForCaptor(); + } + + private void setSystemOutToMyPrintStreamForCaptor() { + captor = new ByteArrayOutputStream(); + System.setOut(new PrintStream(captor)); + } + + @AfterEach + protected final void printOutput() { + setSystemOutToStandard(); + System.out.println(output()); + } + + private void setSystemOutToStandard() { + System.setOut(standardOut); + } + + protected final String output() { + return captor.toString().trim(); + } + + protected abstract void runMain(String... args); +} From 040749bc32e2086a24d4aedced00b5bb8c3cf899 Mon Sep 17 00:00:00 2001 From: viiviii Date: Fri, 6 May 2022 13:08:49 +0900 Subject: [PATCH 3/3] =?UTF-8?q?:truck:=20Args=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=95=88=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chapter14/Application.java | 4 +++- src/main/java/chapter14/{ => args}/Args.java | 2 +- src/test/java/chapter14/{ => args}/ArgsTest.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) rename src/main/java/chapter14/{ => args}/Args.java (99%) rename src/test/java/chapter14/{ => args}/ArgsTest.java (99%) diff --git a/src/main/java/chapter14/Application.java b/src/main/java/chapter14/Application.java index c1c30e3..e5bf584 100644 --- a/src/main/java/chapter14/Application.java +++ b/src/main/java/chapter14/Application.java @@ -1,6 +1,8 @@ package chapter14; -public class Application { +import chapter14.args.Args; + +class Application { public static void main(String[] args) { Args arg = new Args("l", args); diff --git a/src/main/java/chapter14/Args.java b/src/main/java/chapter14/args/Args.java similarity index 99% rename from src/main/java/chapter14/Args.java rename to src/main/java/chapter14/args/Args.java index f4a8687..6f75c8e 100644 --- a/src/main/java/chapter14/Args.java +++ b/src/main/java/chapter14/args/Args.java @@ -1,4 +1,4 @@ -package chapter14; +package chapter14.args; import java.util.HashMap; import java.util.Map; diff --git a/src/test/java/chapter14/ArgsTest.java b/src/test/java/chapter14/args/ArgsTest.java similarity index 99% rename from src/test/java/chapter14/ArgsTest.java rename to src/test/java/chapter14/args/ArgsTest.java index 64d7843..f1a2e4c 100644 --- a/src/test/java/chapter14/ArgsTest.java +++ b/src/test/java/chapter14/args/ArgsTest.java @@ -1,4 +1,4 @@ -package chapter14; +package chapter14.args; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test;