title
JUnit νλ μμν¬μ μ€λΉλμ΄ μλ @ArgumentProvider ꡬν체λ₯Ό μ μ¬μ©νλ©΄ κ±°μ λͺ¨λ μλ리μ€λ₯Ό ν΄κ²°ν μ μλ€. μ΄ λ¬Έμμμλ μ§μ μ¬μ©ν μΌμ΄μ€λ§ λ€λ£¬λ€. νμνλ€λ©΄ javadocsμ λ€λ₯Έ μ°Έκ³ νμΌλ€λ μ§μ νμΈν΄λ³΄μ.

@ValueSource: κ°μ₯ μμ£Ό μ¬μ©νλ€. ν μ€νΈμ λ³μΈμ΄ λ§μΌλ©΄ μ€λͺ λ ₯μ΄ λ¨μ΄μ§λ€κ³ μκ°νκΈ° λλ¬Έμ, μλμ μΌλ‘ μΈμλ₯Ό νλλ‘ μ μ§νλ νΈμ΄λ€.@NullAndEmptySource: μμ μΌμ΄μ€λ‘ μ ν©νλ€. λμ²΄λ‘ κΈ°λ³Έκ°κ³Ό λμλλ κ²½μ°κ° λ§λ€.@MethodSource: μΌμ΄μ€λ₯Ό μ§μ μμ±νκΈ° μ΄λ €μ΄ κ²½μ°μ μ ν©νλ€. μΌμ΄μ€μ μκ° λ§κ±°λ 볡μ‘ν κ²½μ°, λ¨μ λμ΄μ λΉν΄ κ°λ μ±μ΄ λλ€.
[!example]
κΈ°λ³Έ ꡬλΆμμ κ·μΉμμ λΉ λ°°μ΄μ λ°ννλ μΌμ΄μ€λ
nullλλ λ¬Έμμ΄μ΄isEmptyμΈ κ²½μ° λΏμ΄λ€. κ·Έλ¬λ 컀μ€ν ꡬλΆμ κ·μΉμμλ λ¬Έμμ΄ μ λΆλΆμ κ·μΉμ΄ μΆκ°λλ€. λ°λΌμ, κ·μΉμ μ‘΄μ¬νμ§λ§, μ΄ν μ«μκ° λΉμ΄μλ μνλ₯Ό@ValueSourceλ‘ μΆκ°νλ€.@ParameterizedTest @NullAndEmptySource @ValueSource(strings = {"//.\\n"}) void testParse_empty(String expression) { var actual = delimiter.parse(expression); assertThat(actual).isEmpty(); }
16μ§μ 0xFλ 4κ°μ λΉνΈ(0b1111)λ‘ ννλλ€. λ°λΌμ, charκ° κ°μ§ μ μλ λͺ¨λ λ²μλ₯Ό νμνκΈ° μν΄μλ 2 Byteλ‘ ννν μ μλ, 0xFFFFκΉμ§μ λ¬Έμλ₯Ό νμΈνλ©΄ λλ€.1
[!example]
λ€μ ν μ€νΈλ
basic latinλ²μμ λν΄μλ@ParameterizedTest, κ·Έλ¦¬κ³ μ΄νλ‘λ μΌλ°@Testλ₯Ό νμ©νμ¬charλ²μ μ μμ λνparseλ©μλμ μ ν¨μ±μ νλ³νλ μμ μ΄λ€. 2private static IntStream basicLatin() { return IntStream.rangeClosed(0x00, 0x7F) // [0, 127] .filter(value -> value != ',' && value != ':') .filter(value -> value < '0' || '9' < value); } @ParameterizedTest @MethodSource(value = "basicLatin") void testParse_function(int code) { var expression = String.format("//%c\\n1%c2%c3", code, code, code); var actual = delimiter.parse(expression); assertThat(actual).isEqualTo(List.of(1, 2, 3)); } @Test void testParse_BMPWithoutBasicLatin() { var codes = IntStream.rangeClosed(0x80, 0xFFFF); codes.forEach(this::testParse_function); }
ν μ€νΈ μ€ λ¬Έμ κ° λλ λ¬Έμμ μ νμ ν¬κ² μΈ κ°μ§λ‘ λΆλ₯ν μ μμλ€.
- μꡬμ¬νμμ λͺ μν μμΈ μΌμ΄μ€: κΈ°λ³Έ ꡬλΆμλ 컀μ€ν ꡬλΆμκ° λ μ μλ€λ λλ©μΈ κ·μΉμ μν μμΈμ΄λ€.
- μ«μ (0 ~ 9): 10μ§λ²μ νμ©νλ€λ©΄ λλ€μμ μΌμ΄μ€μμ μ«μ λ¬Έμλ ꡬλΆμλ‘μμ μν μ μ λλ‘ μνν μ μλ€. λ°λΌμ, μ΄λ¬ν μΌμ΄μ€λ μμμ μΌλ‘ λ°°μ νμλ€.
[!example]
λ€μ ν μ€νΈλ μ«μ λλ κΈ°λ³Έ ꡬλΆμκ° μ¬μ©λλ©΄ μμΈκ° λ°μνλ€λ μ¬μ€μ νννλ€.
private static IntStream charRangeNumbers() { return IntStream.rangeClosed('0', '9'); } @ParameterizedTest @MethodSource(value = "charRangeNumbers") @ValueSource(ints = {',', ':'}) void testParse_invalidCustomDelimiterThrows(int code) { var expression = String.format("//%c\\n1%c2%c3", code, code, code); assertThrows(IllegalArgumentException.class, () -> delimiter.parse(expression)); }
- μ κ· ννμ λ¬Έλ²
- ννμ λ¬Έλ²μ μ¬μ©λλ λ¬Έμλ€μ λΉκ΅μμ λ°λ‘ μ½μ
νλ©΄ λ¬Έλ²μ μ€λ₯κ° λ°μν μ μλ€. λ°λΌμ,
Pattern.quoteλ‘ λνν νμκ° μλ€. - μΆκ°λ‘
DOTμ νμ©νλ κ²½μ°, μμΈμ μΌλ‘line terminatorλ¬Έμλ€μ νμ§ λμμμ μ μΈνλ€. μ΄ λΆλΆμDOTALLνλκ·Έλ₯Ό μ¬μ©νλ©΄ λμμ λ³κ²½ν μ μλ€. μμΈν λ΄μ©μ Pattern μ°Έκ³ .
- ννμ λ¬Έλ²μ μ¬μ©λλ λ¬Έμλ€μ λΉκ΅μμ λ°λ‘ μ½μ
νλ©΄ λ¬Έλ²μ μ€λ₯κ° λ°μν μ μλ€. λ°λΌμ,
Info: surrogate pair
[!info] Javaμ
charλ UTF-16 κΈ°λ°μ 2 Byte μλ£νμ΄λ€. μ΄ μμ μΈμ λͺ¨λ λ¬Έμλ₯Ό λ΄μ μ μμμ κΉ¨λ«κ³ ,surrogate pairλΌλ κ°λ μ νμ©ν΄μ νν λ²μλ₯Ό νμ₯νλ€.codePointAtμ UTF-16μ΄ κΈ°λ³Έμ΄μ§λ§, Stringμ μμ±μλ UTF-8μ΄ κΈ°λ³Έμ΄λ€. μΈμ½λ© νμ μ λ°λ₯Έ νμ© λ°©μμ μ°¨μ΄κ° λλ¬λλλ‘ ν μ€νΈλ₯Ό μμ±ν΄λ³΄μλ€.private static IntStream emoji() { Supplier<Integer> utf8Code = () -> { byte[] utf8Bytes = new byte[]{(byte) 0xF0, (byte) 0x9F, (byte) 0xA4, (byte) 0x94}; // String constructor use default charset UTF-8 return new String(utf8Bytes).codePointAt(0); }; return IntStream.of("π€".codePointAt(0), // internally treated as UTF-16 "\uD83E\uDD14".codePointAt(0), // UTF-16 0x0001_F914, // UTF-32 utf8Code.get() // UTF-8 ); } /** * BMP(Basic Multilingual Plane) μΈλΆ λ¬Έμμ surrogate pair λ§€μΉ μΌμ΄μ€ */ @ParameterizedTest @MethodSource("emoji") void testParse_withSurrogatePair(int code) { var expression = String.format("//%c\\n1%c2%c3", code, code, code); assertEquals("//π€\\n1π€2π€3", expression); var actual = delimiter.parse(expression); assertThat(actual).isEqualTo(List.of(1, 2, 3)); }
Footnotes
-
λ¬Όλ‘
0xFFFFκΉμ§ νμΈνλ κ²λ νλμ λ¬Έμμ λν κ²μ¦μΌλ‘ μμ νμ§λ μλ€. λ¬Έμλ€μ μΈμ½λ© λ°©μμ λ°λΌ λμΌν λ¬Έμλ λ€λ₯Έ λ°μ΄νΈ μ½λλ‘ μ λ ₯λ μ μκΈ° λλ¬Έμ΄λ€. link β© -
μΌλ°
Testμ νλΌλ―Έν° ν μ€νΈλ₯Ό νΌμ©ν κ²μ μλμ μ΄λ€. μ΄μ λ ν μ€νΈ κ²°κ³Όλ₯Ό νμΈνλ λ° μ§λμΉκ² μκ°μ΄ λ§μ΄ μμλκΈ° λλ¬Έ. νμ¬ κ°λ° νκ²½μμ0xFFFFκΉμ§ μ½ 6λ§ 5μ²κ°μ ν μ€νΈλ₯Ό μ²λ¦¬νλλ° μ½ 23μ΄κ° μμλλ€. ν μ€νΈ μ€νμ νμν μ€λΉ μμ λ€μ΄ μ§§λλΌλ, ν μ€νΈ κ°μκ° μ΄λ κ² λ§μΌλ©΄ μ€λ 걸릴 μ λ°μ μλ€. λ°λΌμ,basic latin planeμ΄νλ‘λ μ€λ²ν€λκ° μκΈ°μ§ μλλ‘ λ°λ³΅λ¬Έμ λλ Έλλ 600~800ms μ λ λμ¨λ€. λͺ»ν΄λ 30λ°° μ΄μ μ°¨μ΄λλ μ . β©