From 5106c52c17c743a3b2ae33f2a6184e5bfb63d8ce Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Mon, 6 Dec 2021 10:34:53 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=EB=8C=80=EC=86=8C=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=20=EA=B5=AC=EB=B6=84=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20Attributes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 삽입, 조회시 강제로 대문자로 수정해서, 대소문자를 구분하지 않는 로직을 구현했습니다. --- .../webserver/http/attribute/Attributes.java | 14 ++++++++++---- .../http/attribute/AttributesTest.java | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/main/java/webserver/http/attribute/Attributes.java b/src/main/java/webserver/http/attribute/Attributes.java index eff3e46..78f34ea 100644 --- a/src/main/java/webserver/http/attribute/Attributes.java +++ b/src/main/java/webserver/http/attribute/Attributes.java @@ -30,21 +30,27 @@ public static Attributes from(String headerText) { } public Attributes add(String key, String value) { - attributes.put(key, value); + attributes.put(key.toUpperCase(), value); return this; } public Attributes addAll(Map attributes) { - this.attributes.putAll(attributes); + Map upperAttributes = new LinkedHashMap<>(); + + for (String key : attributes.keySet()) { + upperAttributes.put(key.toUpperCase(), attributes.get(key)); + } + + this.attributes.putAll(upperAttributes); return this; } public String get(String key) { - return attributes.get(key); + return attributes.get(key.toUpperCase()); } public String getOrDefault(String key, String defaultValue) { - return attributes.getOrDefault(key, defaultValue); + return attributes.getOrDefault(key.toUpperCase(), defaultValue); } public String toHeaderText() { diff --git a/src/test/java/webserver/http/attribute/AttributesTest.java b/src/test/java/webserver/http/attribute/AttributesTest.java index ce04955..416a334 100644 --- a/src/test/java/webserver/http/attribute/AttributesTest.java +++ b/src/test/java/webserver/http/attribute/AttributesTest.java @@ -1,5 +1,6 @@ package webserver.http.attribute; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -11,6 +12,8 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; class AttributesTest { @@ -40,12 +43,20 @@ void fromHeaderText() { } @Test + @DisplayName("add 테스트: key의 대소문자 관계 없이 Attributes를 꺼내올 수 있음") void add() { Attributes attributes = new Attributes(); attributes.add("key", "value"); + + assertAll( + () -> assertEquals("value", attributes.get("KEY")), + () -> assertEquals("value", attributes.get("key")), + () -> assertEquals("value", attributes.get("kEy")) + ); } @Test + @DisplayName("addAll 테스트: key의 대소문자 관계 없이 Attributes를 꺼내올 수 있음") void addAll() { Attributes attributes = new Attributes(); Map attributeMap = new LinkedHashMap<>(); @@ -55,7 +66,11 @@ void addAll() { Attributes expectedAttributes = new Attributes(); expectedAttributes.add("key", "value"); - assertThat(attributes).isEqualTo(expectedAttributes); + assertAll( + () -> assertEquals(expectedAttributes.get("key"), attributes.get("KEY")), + () -> assertEquals(expectedAttributes.get("KEY"), attributes.get("kEY")), + () -> assertEquals(expectedAttributes.get("kEy"), attributes.get("key")) + ); } @Test From 76a3235f16902181555250886e50df9d199e58f7 Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Thu, 9 Dec 2021 01:49:56 +0900 Subject: [PATCH 02/11] =?UTF-8?q?fix:=20=EB=8C=80=EC=86=8C=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EB=A5=BC=20=EA=B5=AC=EB=B6=84=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20Attributes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #67 기존 들어온 헤더 필드를 강제로 대문자로 변경 후 저장하는 구조였는데, 기존 테스트 케이스가 깨지고, 예상값도 대문자로 해줘야 하는 불편함이 있었습니다. 따라서, Attribute의 맵에 값을 추가할 때 대소문자 관계없이 해당 원소가 존재하는지 맵을 순차적 O(n)으로 비교하고 없을 경우 추가하는 방식으로 로직을 수정했습니다. --- .../webserver/http/attribute/Attributes.java | 33 +++++++++++++------ .../http/statusline/RequestStatusLine.java | 19 ++++++++--- .../webserver/http/statusline/StatusLine.java | 4 +++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/main/java/webserver/http/attribute/Attributes.java b/src/main/java/webserver/http/attribute/Attributes.java index 6f05d66..ec04469 100644 --- a/src/main/java/webserver/http/attribute/Attributes.java +++ b/src/main/java/webserver/http/attribute/Attributes.java @@ -16,42 +16,55 @@ public static Attributes from(Map attributes) { } public static Attributes from(String headerText) { - Map attributes = new LinkedHashMap<>(); + Attributes attributes = new Attributes(); String[] splittedHeaderTexts = headerText.split(Const.CRLF); for (String splittedHeaderText : splittedHeaderTexts) { HttpRequestUtils.Pair pair = HttpRequestUtils.parseHeader(splittedHeaderText); if (pair != null) { - attributes.put(pair.getKey(), pair.getValue()); + attributes.add(pair.getKey(), pair.getValue()); } } - return from(attributes); + return attributes; } public Attributes add(String key, String value) { - attributes.put(key.toUpperCase(), value); + for (String k : attributes.keySet()) { + if (k.equalsIgnoreCase(key)) { + return this; + } + } + + attributes.put(key, value); return this; } public Attributes addAll(Map attributes) { - Map upperAttributes = new LinkedHashMap<>(); - for (String key : attributes.keySet()) { - upperAttributes.put(key.toUpperCase(), attributes.get(key)); + add(key, attributes.get(key)); } - this.attributes.putAll(upperAttributes); return this; } public String get(String key) { - return attributes.get(key.toUpperCase()); + for (String k : attributes.keySet()) { + if (k.equalsIgnoreCase(key)) { + return attributes.get(k); + } + } + return null; } public String getOrDefault(String key, String defaultValue) { - return attributes.getOrDefault(key.toUpperCase(), defaultValue); + for (String k : attributes.keySet()) { + if (k.equalsIgnoreCase(key)) { + return attributes.get(k); + } + } + return defaultValue; } public String toHeaderText() { diff --git a/src/main/java/webserver/http/statusline/RequestStatusLine.java b/src/main/java/webserver/http/statusline/RequestStatusLine.java index de962b4..8895819 100644 --- a/src/main/java/webserver/http/statusline/RequestStatusLine.java +++ b/src/main/java/webserver/http/statusline/RequestStatusLine.java @@ -1,8 +1,13 @@ package webserver.http.statusline; +import webserver.http.attribute.Attributes; + import java.net.URI; import java.net.URISyntaxException; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.StringJoiner; public class RequestStatusLine extends StatusLine { @@ -13,12 +18,16 @@ public RequestStatusLine(Map statusLineAttributes) { super(statusLineAttributes); } + public RequestStatusLine(Attributes statusLineAttributes) { + super(statusLineAttributes); + } + public static RequestStatusLine from(List statusLine) { - Map statusLineAttributes = new HashMap<>(); + Attributes statusLineAttributes = new Attributes(); - statusLineAttributes.put(METHOD_KEY, statusLine.get(0)); - statusLineAttributes.put(PATH_KEY, statusLine.get(1)); - statusLineAttributes.put(PROTOCOL_VERSION_KEY, statusLine.get(2)); + statusLineAttributes.add(METHOD_KEY, statusLine.get(0)); + statusLineAttributes.add(PATH_KEY, statusLine.get(1)); + statusLineAttributes.add(PROTOCOL_VERSION_KEY, statusLine.get(2)); return new RequestStatusLine(statusLineAttributes); } diff --git a/src/main/java/webserver/http/statusline/StatusLine.java b/src/main/java/webserver/http/statusline/StatusLine.java index 57da869..1deca3e 100644 --- a/src/main/java/webserver/http/statusline/StatusLine.java +++ b/src/main/java/webserver/http/statusline/StatusLine.java @@ -13,6 +13,10 @@ public StatusLine(Map statusLineAttributes) { this.statusLineAttributes = Attributes.from(statusLineAttributes); } + public StatusLine(Attributes statusLineAttributes) { + this.statusLineAttributes = statusLineAttributes; + } + public String getProtocol() { return statusLineAttributes.get(PROTOCOL_VERSION_KEY); } From 0d3fa818e1edd3154873e7bb211fbfb0ab3b9188 Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Fri, 10 Dec 2021 11:07:24 +0900 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20Attributes.get()=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=ED=82=A4=EC=9D=98=20=EA=B2=BD=EC=9A=B0=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/webserver/http/attribute/Attributes.java | 11 +++++------ .../webserver/http/attribute/AttributesTest.java | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/webserver/http/attribute/Attributes.java b/src/main/java/webserver/http/attribute/Attributes.java index ec04469..8d2fcf8 100644 --- a/src/main/java/webserver/http/attribute/Attributes.java +++ b/src/main/java/webserver/http/attribute/Attributes.java @@ -55,16 +55,15 @@ public String get(String key) { return attributes.get(k); } } - return null; + throw new IllegalArgumentException("일치하는 키가 없습니다."); } public String getOrDefault(String key, String defaultValue) { - for (String k : attributes.keySet()) { - if (k.equalsIgnoreCase(key)) { - return attributes.get(k); - } + try { + return get(key); + } catch (IllegalArgumentException e) { + return defaultValue; } - return defaultValue; } public String toHeaderText() { diff --git a/src/test/java/webserver/http/attribute/AttributesTest.java b/src/test/java/webserver/http/attribute/AttributesTest.java index 416a334..bef7344 100644 --- a/src/test/java/webserver/http/attribute/AttributesTest.java +++ b/src/test/java/webserver/http/attribute/AttributesTest.java @@ -12,6 +12,7 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -81,6 +82,13 @@ void get() { assertThat(attributes.get("key")).isEqualTo("value"); } + @Test + @DisplayName("존재하지 않는 키를 조회하면 예외발생") + void getValueWithEmptyKey() { + Attributes attributes = new Attributes(); + assertThatIllegalArgumentException().isThrownBy(() -> attributes.get("emptyKey")); + } + @ParameterizedTest @MethodSource("getOrDefault") void getOrDefault(Attributes attributes, String defaultValue, String key, String expectedValue) { @@ -88,6 +96,13 @@ void getOrDefault(Attributes attributes, String defaultValue, String key, String assertThat(actualValue).isEqualTo(expectedValue); } + @Test + @DisplayName("존재하지 않는 키를 조회하면 주어진 기본값으로 대체") + void getDefaultValueWithEmptyKey() { + Attributes attributes = new Attributes(); + assertThat(attributes.getOrDefault("emptyKey", "happy")).isEqualTo("happy"); + } + static Stream getOrDefault() { return Stream.of( Arguments.of( From b0ee9ae7e83863c77bf44891c95e49c7378190ba Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Fri, 10 Dec 2021 11:11:35 +0900 Subject: [PATCH 04/11] =?UTF-8?q?refactor:=20Attributes=EC=9D=98=20?= =?UTF-8?q?=EB=B0=98=EB=B3=B5=EB=AC=B8=EC=97=90=EC=84=9C=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=A4=91=EC=9D=B8=20=EB=B3=80=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EB=AA=85=EC=8B=9C=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../webserver/http/attribute/Attributes.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/webserver/http/attribute/Attributes.java b/src/main/java/webserver/http/attribute/Attributes.java index 8d2fcf8..999a930 100644 --- a/src/main/java/webserver/http/attribute/Attributes.java +++ b/src/main/java/webserver/http/attribute/Attributes.java @@ -30,37 +30,37 @@ public static Attributes from(String headerText) { return attributes; } - public Attributes add(String key, String value) { - for (String k : attributes.keySet()) { - if (k.equalsIgnoreCase(key)) { + public Attributes add(String targetKey, String value) { + for (String currentKey : attributes.keySet()) { + if (currentKey.equalsIgnoreCase(targetKey)) { return this; } } - attributes.put(key, value); + attributes.put(targetKey, value); return this; } public Attributes addAll(Map attributes) { - for (String key : attributes.keySet()) { - add(key, attributes.get(key)); + for (String currentKey : attributes.keySet()) { + add(currentKey, attributes.get(currentKey)); } return this; } - public String get(String key) { - for (String k : attributes.keySet()) { - if (k.equalsIgnoreCase(key)) { - return attributes.get(k); + public String get(String targetKey) { + for (String currentKey : attributes.keySet()) { + if (currentKey.equalsIgnoreCase(targetKey)) { + return attributes.get(currentKey); } } throw new IllegalArgumentException("일치하는 키가 없습니다."); } - public String getOrDefault(String key, String defaultValue) { + public String getOrDefault(String targetKey, String defaultValue) { try { - return get(key); + return get(targetKey); } catch (IllegalArgumentException e) { return defaultValue; } From 0c06f6062fa7d3a007ac667fba80e91518283f02 Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Wed, 15 Dec 2021 10:08:09 +0900 Subject: [PATCH 05/11] =?UTF-8?q?refactor:=20RequestStatusLine=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20Att?= =?UTF-8?q?ribute=EB=A7=8C=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/statusline/RequestStatusLine.java | 5 -- .../http/header/RequestHeaderTest.java | 21 ++++---- .../statusline/RequestStatusLineTest.java | 50 +++++++++---------- 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/main/java/webserver/http/statusline/RequestStatusLine.java b/src/main/java/webserver/http/statusline/RequestStatusLine.java index 8895819..102b495 100644 --- a/src/main/java/webserver/http/statusline/RequestStatusLine.java +++ b/src/main/java/webserver/http/statusline/RequestStatusLine.java @@ -5,7 +5,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.StringJoiner; @@ -14,10 +13,6 @@ public class RequestStatusLine extends StatusLine { private static final String METHOD_KEY = "method"; private static final String PATH_KEY = "path"; - public RequestStatusLine(Map statusLineAttributes) { - super(statusLineAttributes); - } - public RequestStatusLine(Attributes statusLineAttributes) { super(statusLineAttributes); } diff --git a/src/test/java/webserver/http/header/RequestHeaderTest.java b/src/test/java/webserver/http/header/RequestHeaderTest.java index fbd8ef6..b95371d 100644 --- a/src/test/java/webserver/http/header/RequestHeaderTest.java +++ b/src/test/java/webserver/http/header/RequestHeaderTest.java @@ -116,6 +116,7 @@ void getStatusLineAttributes(String headerText, RequestStatusLine expectedReques .extracting("statusLine") .usingRecursiveFieldByFieldElementComparator() .contains(expectedRequestStatusLine); + } static Stream getStatusLineAttributes() { @@ -138,11 +139,11 @@ static Stream getStatusLineAttributes() { "Cookie: Idea-1c77831=5ced54c8-cabd-4355-ae5a-97b17f9d7443" + Const.CRLF + Const.CRLF, new RequestStatusLine( - new HashMap() {{ + Attributes.from(new HashMap() {{ put("method", "GET"); put("path", "/"); put("protocolVersion", "HTTP/1.1"); - }} + }}) ) ) ); @@ -217,10 +218,10 @@ static Stream getPath() { Arguments.of( "쿼리스트링이 없는 GET 메세지", new RequestStatusLine( - new HashMap() {{ - put("path", "/user/create"); - put("method", "GET"); - put("protocolVersion", "HTTP/1.1"); + new Attributes() {{ + add("path", "/user/create"); + add("method", "GET"); + add("protocolVersion", "HTTP/1.1"); }} ), "/user/create" @@ -228,10 +229,10 @@ static Stream getPath() { Arguments.of( "쿼리스트링이 포함된 GET 메세지 path를 출력할때도 쿼리스트링이 포함되지 않아야 함", new RequestStatusLine( - new HashMap() {{ - put("path", "/user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net"); - put("method", "GET"); - put("protocolVersion", "HTTP/1.1"); + new Attributes() {{ + add("path", "/user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net"); + add("method", "GET"); + add("protocolVersion", "HTTP/1.1"); }} ), "/user/create" diff --git a/src/test/java/webserver/http/statusline/RequestStatusLineTest.java b/src/test/java/webserver/http/statusline/RequestStatusLineTest.java index 62da272..8972426 100644 --- a/src/test/java/webserver/http/statusline/RequestStatusLineTest.java +++ b/src/test/java/webserver/http/statusline/RequestStatusLineTest.java @@ -3,8 +3,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import webserver.http.attribute.Attributes; -import java.util.HashMap; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -24,10 +24,10 @@ static Stream getMethod() { Arguments.of( "GET 메소드", new RequestStatusLine( - new HashMap() {{ - put("path", "/user/create"); - put("method", "GET"); - put("protocolVersion", "HTTP/1.1"); + new Attributes() {{ + add("path", "/user/create"); + add("method", "GET"); + add("protocolVersion", "HTTP/1.1"); }} ), "GET" @@ -48,20 +48,20 @@ static Stream getPath() { Arguments.of( "쿼리스트링이 없는 path", new RequestStatusLine( - new HashMap() {{ - put("path", "/user/create"); - put("method", "GET"); - put("protocolVersion", "HTTP/1.1"); + new Attributes() {{ + add("path", "/user/create"); + add("method", "GET"); + add("protocolVersion", "HTTP/1.1"); }} ), "/user/create" ), Arguments.of( "쿼리스트링이 있는 path", new RequestStatusLine( - new HashMap() {{ - put("path", "/user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net"); - put("method", "GET"); - put("protocolVersion", "HTTP/1.1"); + new Attributes() {{ + add("path", "/user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net"); + add("method", "GET"); + add("protocolVersion", "HTTP/1.1"); }} ), "/user/create" @@ -82,10 +82,10 @@ static Stream getProtocol() { Arguments.of( "HTTP/1.1", new RequestStatusLine( - new HashMap() {{ - put("path", "/user/create"); - put("method", "GET"); - put("protocolVersion", "HTTP/1.1"); + new Attributes() {{ + add("path", "/user/create"); + add("method", "GET"); + add("protocolVersion", "HTTP/1.1"); }} ), "HTTP/1.1" @@ -106,20 +106,20 @@ static Stream getQueryString() { Arguments.of( "쿼리스트링이 없는 path", new RequestStatusLine( - new HashMap() {{ - put("path", "/user/create"); - put("method", "GET"); - put("protocolVersion", "HTTP/1.1"); + new Attributes() {{ + add("path", "/user/create"); + add("method", "GET"); + add("protocolVersion", "HTTP/1.1"); }} ), "" ), Arguments.of( "쿼리스트링이 있는 path", new RequestStatusLine( - new HashMap() {{ - put("path", "/user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net"); - put("method", "GET"); - put("protocolVersion", "HTTP/1.1"); + new Attributes() {{ + add("path", "/user/create?userId=javajigi&password=password&name=%EB%B0%95%EC%9E%AC%EC%84%B1&email=javajigi%40slipp.net"); + add("method", "GET"); + add("protocolVersion", "HTTP/1.1"); }} ), "userId=javajigi&password=password&name=박재성&email=javajigi@slipp.net" From 780f6e929bd9e5382dbe15d9f2a47e3761bece27 Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Wed, 15 Dec 2021 10:20:51 +0900 Subject: [PATCH 06/11] =?UTF-8?q?refactor:=20AttributeTest=EC=9D=98=20add,?= =?UTF-8?q?=20addAll=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=A7=A4=EA=B0=9C?= =?UTF-8?q?=EB=B3=80=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/attribute/AttributesTest.java | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/src/test/java/webserver/http/attribute/AttributesTest.java b/src/test/java/webserver/http/attribute/AttributesTest.java index bef7344..3d7304a 100644 --- a/src/test/java/webserver/http/attribute/AttributesTest.java +++ b/src/test/java/webserver/http/attribute/AttributesTest.java @@ -13,8 +13,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; class AttributesTest { @@ -43,22 +41,42 @@ void fromHeaderText() { assertThat(actualAttributes).isEqualTo(expectedAttributes); } - @Test + + @ParameterizedTest @DisplayName("add 테스트: key의 대소문자 관계 없이 Attributes를 꺼내올 수 있음") - void add() { + @MethodSource("add") + void add(String expectedValue, String actualValue) { + assertThat(actualValue).isEqualTo(expectedValue); + } + + static Stream add() { Attributes attributes = new Attributes(); attributes.add("key", "value"); - assertAll( - () -> assertEquals("value", attributes.get("KEY")), - () -> assertEquals("value", attributes.get("key")), - () -> assertEquals("value", attributes.get("kEy")) + return Stream.of( + Arguments.of( + "value", + attributes.get("KEY") + ), + Arguments.of( + "value", + attributes.get("key") + ), + Arguments.of( + "value", + attributes.get("kEy") + ) ); } - @Test + @ParameterizedTest @DisplayName("addAll 테스트: key의 대소문자 관계 없이 Attributes를 꺼내올 수 있음") - void addAll() { + @MethodSource("addAll") + void addAll(String expectedValue, String actualValue) { + assertThat(actualValue).isEqualTo(expectedValue); + } + + static Stream addAll() { Attributes attributes = new Attributes(); Map attributeMap = new LinkedHashMap<>(); attributeMap.put("key", "value"); @@ -67,10 +85,19 @@ void addAll() { Attributes expectedAttributes = new Attributes(); expectedAttributes.add("key", "value"); - assertAll( - () -> assertEquals(expectedAttributes.get("key"), attributes.get("KEY")), - () -> assertEquals(expectedAttributes.get("KEY"), attributes.get("kEY")), - () -> assertEquals(expectedAttributes.get("kEy"), attributes.get("key")) + return Stream.of( + Arguments.of( + expectedAttributes.get("key"), + attributes.get("KEY") + ), + Arguments.of( + expectedAttributes.get("KEY"), + attributes.get("kEY") + ), + Arguments.of( + expectedAttributes.get("kEy"), + attributes.get("kEy") + ) ); } From dfe49f7cf3a5ac3204509aa1c68761ac1fb63c22 Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Wed, 15 Dec 2021 10:31:40 +0900 Subject: [PATCH 07/11] =?UTF-8?q?refactor:=20ResponseStatusLine=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=20Attribute=EB=A7=8C=20=EA=B0=80=EB=8A=A5=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/statusline/ResponseStatusLine.java | 14 +++++++------- .../java/webserver/http/statusline/StartLine.java | 6 ++---- .../webserver/http/header/ResponseHeaderTest.java | 4 ++-- .../http/statusline/ResponseStatusLineTest.java | 13 +++++++------ 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/main/java/webserver/http/statusline/ResponseStatusLine.java b/src/main/java/webserver/http/statusline/ResponseStatusLine.java index cbb4757..d1a1dd5 100644 --- a/src/main/java/webserver/http/statusline/ResponseStatusLine.java +++ b/src/main/java/webserver/http/statusline/ResponseStatusLine.java @@ -1,24 +1,24 @@ package webserver.http.statusline; -import java.util.HashMap; +import webserver.http.attribute.Attributes; + import java.util.List; -import java.util.Map; import java.util.StringJoiner; public class ResponseStatusLine extends StartLine { private static final String STATUS_CODE_KEY = "statusCode"; private static final String STATUS_TEXT_KEY = "statusText"; - public ResponseStatusLine(Map statusLineAttributes) { + public ResponseStatusLine(Attributes statusLineAttributes) { super(statusLineAttributes); } public static ResponseStatusLine from(List statusLine) { - Map statusLineAttributes = new HashMap<>(); + Attributes statusLineAttributes = new Attributes(); - statusLineAttributes.put(PROTOCOL_VERSION_KEY, statusLine.get(0)); - statusLineAttributes.put(STATUS_CODE_KEY, statusLine.get(1)); - statusLineAttributes.put(STATUS_TEXT_KEY, statusLine.get(2)); + statusLineAttributes.add(PROTOCOL_VERSION_KEY, statusLine.get(0)); + statusLineAttributes.add(STATUS_CODE_KEY, statusLine.get(1)); + statusLineAttributes.add(STATUS_TEXT_KEY, statusLine.get(2)); return new ResponseStatusLine(statusLineAttributes); } diff --git a/src/main/java/webserver/http/statusline/StartLine.java b/src/main/java/webserver/http/statusline/StartLine.java index 95859e0..07d1909 100644 --- a/src/main/java/webserver/http/statusline/StartLine.java +++ b/src/main/java/webserver/http/statusline/StartLine.java @@ -2,15 +2,13 @@ import webserver.http.attribute.Attributes; -import java.util.Map; - public abstract class StartLine { protected static final String PROTOCOL_VERSION_KEY = "protocolVersion"; private Attributes attributes; - public StartLine(Map attributes) { - this.attributes = Attributes.from(attributes); + public StartLine(Attributes attributes) { + this.attributes = attributes; } public String getProtocol() { diff --git a/src/test/java/webserver/http/header/ResponseHeaderTest.java b/src/test/java/webserver/http/header/ResponseHeaderTest.java index 5b6b8e3..0c619e6 100644 --- a/src/test/java/webserver/http/header/ResponseHeaderTest.java +++ b/src/test/java/webserver/http/header/ResponseHeaderTest.java @@ -57,11 +57,11 @@ static Stream getStatusLineAttributes() { "Content-Length: " + "Hello World".getBytes().length + Const.CRLF + Const.CRLF, new ResponseStatusLine( - new HashMap() {{ + Attributes.from(new HashMap() {{ put("protocolVersion", "HTTP/1.1"); put("statusText", "OK"); put("statusCode", "200"); - }} + }}) ) ) ); diff --git a/src/test/java/webserver/http/statusline/ResponseStatusLineTest.java b/src/test/java/webserver/http/statusline/ResponseStatusLineTest.java index aa9ca7d..4e354ea 100644 --- a/src/test/java/webserver/http/statusline/ResponseStatusLineTest.java +++ b/src/test/java/webserver/http/statusline/ResponseStatusLineTest.java @@ -3,6 +3,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import webserver.http.attribute.Attributes; import java.util.HashMap; import java.util.stream.Stream; @@ -24,11 +25,11 @@ static Stream getStatusCode() { Arguments.of( "200 OK", new ResponseStatusLine( - new HashMap() {{ + Attributes.from(new HashMap() {{ put("protocolVersion", "HTTP/1.1"); put("statusCode", "200"); put("statusText", "OK"); - }} + }}) ), "200" ) @@ -48,11 +49,11 @@ static Stream getStatusText() { Arguments.of( "200 OK", new ResponseStatusLine( - new HashMap() {{ + Attributes.from(new HashMap() {{ put("protocolVersion", "HTTP/1.1"); put("statusCode", "200"); put("statusText", "OK"); - }} + }}) ), "OK" ) @@ -72,11 +73,11 @@ static Stream getProtocol() { Arguments.of( "HTTP/1.1", new ResponseStatusLine( - new HashMap() {{ + Attributes.from(new HashMap() {{ put("protocolVersion", "HTTP/1.1"); put("statusCode", "200"); put("statusText", "OK"); - }} + }}) ), "HTTP/1.1" ) From 66dcf7c10b3ec3425e744b5a0313667ed454f29a Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Wed, 15 Dec 2021 10:40:10 +0900 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20StatusLine=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=EB=90=98=EC=84=9C=20?= =?UTF-8?q?=EC=83=9D=EA=B8=B4=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/webserver/http/startline/StatusLine.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/webserver/http/startline/StatusLine.java b/src/main/java/webserver/http/startline/StatusLine.java index 9b17e52..378eb5b 100644 --- a/src/main/java/webserver/http/startline/StatusLine.java +++ b/src/main/java/webserver/http/startline/StatusLine.java @@ -9,21 +9,13 @@ public class StatusLine extends StartLine { private static final String STATUS_CODE_KEY = "statusCode"; private static final String STATUS_TEXT_KEY = "statusText"; -<<<<<<<< HEAD:src/main/java/webserver/http/statusline/ResponseStatusLine.java - public ResponseStatusLine(Attributes statusLineAttributes) { - super(statusLineAttributes); - } - public static ResponseStatusLine from(List statusLine) { - Attributes statusLineAttributes = new Attributes(); -======== - public StatusLine(Map statusLineAttributes) { + public StatusLine(Attributes statusLineAttributes) { super(statusLineAttributes); } public static StatusLine from(List statusLine) { - Map statusLineAttributes = new HashMap<>(); ->>>>>>>> freddie-noel:src/main/java/webserver/http/startline/StatusLine.java + Attributes statusLineAttributes = new Attributes(); statusLineAttributes.add(PROTOCOL_VERSION_KEY, statusLine.get(0)); statusLineAttributes.add(STATUS_CODE_KEY, statusLine.get(1)); From f61aa7f4adf541074ffcec8867c12cd1047211e4 Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Wed, 22 Dec 2021 10:51:32 +0900 Subject: [PATCH 09/11] =?UTF-8?q?refactor:=20Attributes=20get()=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=98=88=EC=99=B8=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../webserver/http/attribute/Attributes.java | 22 ++++++++----------- .../http/attribute/AttributesTest.java | 4 ++-- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/main/java/webserver/http/attribute/Attributes.java b/src/main/java/webserver/http/attribute/Attributes.java index 999a930..66b139e 100644 --- a/src/main/java/webserver/http/attribute/Attributes.java +++ b/src/main/java/webserver/http/attribute/Attributes.java @@ -3,10 +3,7 @@ import util.HttpRequestUtils; import webserver.Const; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.StringJoiner; +import java.util.*; public class Attributes { private final Map attributes = new LinkedHashMap<>(); @@ -50,20 +47,19 @@ public Attributes addAll(Map attributes) { } public String get(String targetKey) { + return getOrDefault(targetKey, null); + } + + public String getOrDefault(String targetKey, String defaultValue) { + String findValue = null; + for (String currentKey : attributes.keySet()) { if (currentKey.equalsIgnoreCase(targetKey)) { - return attributes.get(currentKey); + findValue = attributes.get(currentKey); } } - throw new IllegalArgumentException("일치하는 키가 없습니다."); - } - public String getOrDefault(String targetKey, String defaultValue) { - try { - return get(targetKey); - } catch (IllegalArgumentException e) { - return defaultValue; - } + return findValue != null ? findValue : defaultValue; } public String toHeaderText() { diff --git a/src/test/java/webserver/http/attribute/AttributesTest.java b/src/test/java/webserver/http/attribute/AttributesTest.java index 3d7304a..a18236d 100644 --- a/src/test/java/webserver/http/attribute/AttributesTest.java +++ b/src/test/java/webserver/http/attribute/AttributesTest.java @@ -110,10 +110,10 @@ void get() { } @Test - @DisplayName("존재하지 않는 키를 조회하면 예외발생") + @DisplayName("존재하지 않는 키를 조회하면 null") void getValueWithEmptyKey() { Attributes attributes = new Attributes(); - assertThatIllegalArgumentException().isThrownBy(() -> attributes.get("emptyKey")); + assertThat(attributes.get("null")).isNull(); } @ParameterizedTest From 8dbb27252da41ba01bed6491c9fd0a43cbc72ce5 Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Wed, 22 Dec 2021 12:15:53 +0900 Subject: [PATCH 10/11] =?UTF-8?q?refactor:=20Attributes=20getOrDefault()?= =?UTF-8?q?=20=EB=A6=AC=ED=84=B4=EB=AC=B8=20=EC=9D=B8=EB=9D=BC=EC=9D=B8?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/http/attribute/Attributes.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/webserver/http/attribute/Attributes.java b/src/main/java/webserver/http/attribute/Attributes.java index 66b139e..725033e 100644 --- a/src/main/java/webserver/http/attribute/Attributes.java +++ b/src/main/java/webserver/http/attribute/Attributes.java @@ -51,15 +51,14 @@ public String get(String targetKey) { } public String getOrDefault(String targetKey, String defaultValue) { - String findValue = null; for (String currentKey : attributes.keySet()) { if (currentKey.equalsIgnoreCase(targetKey)) { - findValue = attributes.get(currentKey); + return attributes.get(currentKey); } } - return findValue != null ? findValue : defaultValue; + return defaultValue; } public String toHeaderText() { From 41592da3c3e0df34d1911b55f128c5f061aa8a54 Mon Sep 17 00:00:00 2001 From: sanhee <68936@naver.com> Date: Wed, 22 Dec 2021 12:26:56 +0900 Subject: [PATCH 11/11] =?UTF-8?q?test:=20Attributes=20value=EA=B0=80=20nul?= =?UTF-8?q?l=EC=9D=B8=20key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../webserver/http/attribute/Attributes.java | 5 +++++ .../http/attribute/AttributesTest.java | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/webserver/http/attribute/Attributes.java b/src/main/java/webserver/http/attribute/Attributes.java index 725033e..8fded54 100644 --- a/src/main/java/webserver/http/attribute/Attributes.java +++ b/src/main/java/webserver/http/attribute/Attributes.java @@ -83,4 +83,9 @@ public int hashCode() { return Objects.hash(attributes); } + + public int size(){ + return attributes.size(); + } + } diff --git a/src/test/java/webserver/http/attribute/AttributesTest.java b/src/test/java/webserver/http/attribute/AttributesTest.java index a18236d..68dfa1d 100644 --- a/src/test/java/webserver/http/attribute/AttributesTest.java +++ b/src/test/java/webserver/http/attribute/AttributesTest.java @@ -1,5 +1,6 @@ package webserver.http.attribute; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -13,6 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.assertAll; class AttributesTest { @@ -156,4 +158,19 @@ void toHeaderText() { assertThat(attributes.toHeaderText()).isEqualTo("key1: value1\r\nkey2: value2"); } + + @Test + @DisplayName("value가 null인 key") + void isNullWhenNullValue(){ + Attributes attributes = new Attributes(); + attributes.add("null", null); + attributes.add("null2", null); + + assertAll( + ()-> assertThat(attributes.size()).isEqualTo(2), + ()-> assertThat(attributes.get("null")).isNull(), + ()-> assertThat(attributes.get("null2")).isNull() + ); + + } }