@@ -28,11 +28,11 @@ class BasicEscaping {
2828
2929 static Stream <Arguments > basicEscapingCases () {
3030 return Stream .of (
31- Arguments .of ("backslashes" , "path\\ to\\ file" , "path\\ \\ to\\ \\ file" ),
32- Arguments .of ("double quotes" , "He said \" hello\" " , "He said \\ \" hello\\ \" " ),
33- Arguments .of ("newlines" , "line1\n line2" , "line1\\ nline2" ),
34- Arguments .of ("carriage returns" , "line1\r line2" , "line1\\ rline2" ),
35- Arguments .of ("tabs" , "col1\t col2" , "col1\\ tcol2" ));
31+ Arguments .of ("backslashes" , "path\\ to\\ file" , "path\\ \\ to\\ \\ file" ),
32+ Arguments .of ("double quotes" , "He said \" hello\" " , "He said \\ \" hello\\ \" " ),
33+ Arguments .of ("newlines" , "line1\n line2" , "line1\\ nline2" ),
34+ Arguments .of ("carriage returns" , "line1\r line2" , "line1\\ rline2" ),
35+ Arguments .of ("tabs" , "col1\t col2" , "col1\\ tcol2" ));
3636 }
3737
3838 @ ParameterizedTest (name = "should escape {0}" )
@@ -49,10 +49,10 @@ class CombinedEscaping {
4949
5050 static Stream <Arguments > combinedEscapingCases () {
5151 return Stream .of (
52- Arguments .of ("multiple special characters" , "He said \" test\\ path\" \n Next line" ,
53- "He said \\ \" test\\ \\ path\\ \" \\ nNext line" ),
54- Arguments .of ("all control characters together" , "text\n \r \t " , "text\\ n\\ r\\ t" ),
55- Arguments .of ("backslash before quote" , "\\ \" " , "\\ \\ \\ \" " ));
52+ Arguments .of ("multiple special characters" , "He said \" test\\ path\" \n Next line" ,
53+ "He said \\ \" test\\ \\ path\\ \" \\ nNext line" ),
54+ Arguments .of ("all control characters together" , "text\n \r \t " , "text\\ n\\ r\\ t" ),
55+ Arguments .of ("backslash before quote" , "\\ \" " , "\\ \\ \\ \" " ));
5656 }
5757
5858 @ ParameterizedTest (name = "should escape {0}" )
@@ -76,9 +76,9 @@ void testEmptyString() {
7676 @ ParameterizedTest
7777 @ DisplayName ("should not modify strings without special characters" )
7878 @ ValueSource (strings = {
79- "hello world" ,
80- "Hello World 123 @#$%^&*()_+-=[]{}|;:',.<>?/" ,
81- "Hello 世界 🌍"
79+ "hello world" ,
80+ "Hello World 123 @#$%^&*()_+-=[]{}|;:',.<>?/" ,
81+ "Hello 世界 🌍"
8282 })
8383 void testStringsWithoutSpecialCharacters (String input ) {
8484 assertEquals (input , StringEscaper .escape (input ));
@@ -99,13 +99,13 @@ class RealWorldScenarios {
9999
100100 static Stream <Arguments > realWorldScenarios () {
101101 return Stream .of (
102- Arguments .of ("JSON string" , "{\" key\" : \" value\" }" , "{\\ \" key\\ \" : \\ \" value\\ \" }" ),
103- Arguments .of ("Windows file path" , "C:\\ Users\\ Documents\\ file.txt" ,
104- "C:\\ \\ Users\\ \\ Documents\\ \\ file.txt" ),
105- Arguments .of ("multi-line text" , "Line 1\n Line 2\n Line 3" , "Line 1\\ nLine 2\\ nLine 3" ),
106- Arguments .of ("SQL query" , "SELECT * FROM users WHERE name = \" John\" " ,
107- "SELECT * FROM users WHERE name = \\ \" John\\ \" " ),
108- Arguments .of ("regex pattern" , "\\ d+\\ .\\ d+" , "\\ \\ d+\\ \\ .\\ \\ d+" ));
102+ Arguments .of ("JSON string" , "{\" key\" : \" value\" }" , "{\\ \" key\\ \" : \\ \" value\\ \" }" ),
103+ Arguments .of ("Windows file path" , "C:\\ Users\\ Documents\\ file.txt" ,
104+ "C:\\ \\ Users\\ \\ Documents\\ \\ file.txt" ),
105+ Arguments .of ("multi-line text" , "Line 1\n Line 2\n Line 3" , "Line 1\\ nLine 2\\ nLine 3" ),
106+ Arguments .of ("SQL query" , "SELECT * FROM users WHERE name = \" John\" " ,
107+ "SELECT * FROM users WHERE name = \\ \" John\\ \" " ),
108+ Arguments .of ("regex pattern" , "\\ d+\\ .\\ d+" , "\\ \\ d+\\ \\ .\\ \\ d+" ));
109109 }
110110
111111 @ ParameterizedTest (name = "should escape {0}" )
@@ -122,11 +122,11 @@ class BasicUnescaping {
122122
123123 static Stream <Arguments > basicUnescapingCases () {
124124 return Stream .of (
125- Arguments .of ("backslashes" , "path\\ \\ to\\ \\ file" , "path\\ to\\ file" ),
126- Arguments .of ("double quotes" , "He said \\ \" hello\\ \" " , "He said \" hello\" " ),
127- Arguments .of ("newlines" , "line1\\ nline2" , "line1\n line2" ),
128- Arguments .of ("carriage returns" , "line1\\ rline2" , "line1\r line2" ),
129- Arguments .of ("tabs" , "col1\\ tcol2" , "col1\t col2" ));
125+ Arguments .of ("backslashes" , "path\\ \\ to\\ \\ file" , "path\\ to\\ file" ),
126+ Arguments .of ("double quotes" , "He said \\ \" hello\\ \" " , "He said \" hello\" " ),
127+ Arguments .of ("newlines" , "line1\\ nline2" , "line1\n line2" ),
128+ Arguments .of ("carriage returns" , "line1\\ rline2" , "line1\r line2" ),
129+ Arguments .of ("tabs" , "col1\\ tcol2" , "col1\t col2" ));
130130 }
131131
132132 @ ParameterizedTest (name = "should unescape {0}" )
@@ -172,13 +172,13 @@ class RoundTripEscaping {
172172
173173 static Stream <String > roundTripCases () {
174174 return Stream .of (
175- "simple text" ,
176- "path\\ to\\ file" ,
177- "He said \" hello\" " ,
178- "line1\n line2\n line3" ,
179- "col1\t col2\t col3" ,
180- "C:\\ Users\\ Documents" ,
181- "text\n \r \t \" \\ "
175+ "simple text" ,
176+ "path\\ to\\ file" ,
177+ "He said \" hello\" " ,
178+ "line1\n line2\n line3" ,
179+ "col1\t col2\t col3" ,
180+ "C:\\ Users\\ Documents" ,
181+ "text\n \r \t \" \\ "
182182 );
183183 }
184184
@@ -230,6 +230,7 @@ void testUnknownEscapeSequences() {
230230 void unquotesValueWhenStartsAndEndsWithQuote () {
231231 assertEquals ("abc" , StringEscaper .unescape ("\" abc\" " ));
232232 }
233+
233234 @ Test
234235 void unescapesBackslashSequences () {
235236 assertEquals ("a\" b" , StringEscaper .unescape ("a\\ \" b" ));
@@ -259,7 +260,7 @@ void throwsOnConstructor() throws NoSuchMethodException {
259260 constructor .setAccessible (true );
260261
261262 final InvocationTargetException thrown =
262- assertThrows (InvocationTargetException .class , constructor ::newInstance );
263+ assertThrows (InvocationTargetException .class , constructor ::newInstance );
263264
264265 final Throwable cause = thrown .getCause ();
265266 assertInstanceOf (UnsupportedOperationException .class , cause );
@@ -275,6 +276,7 @@ void testingValidateString_WithNull() {
275276 // Then
276277
277278 }
279+
278280 @ Test
279281 void testingValidateString_WithEmptyString () {
280282 // Given
@@ -284,14 +286,43 @@ void testingValidateString_WithEmptyString() {
284286 // Then
285287
286288 }
289+
287290 @ Test
288291 void testingValidateString_WithWildStringToThrowsException () {
289292 // Given
290293 String input = "\" te\\ st\" " ;
291294 // When // Then
292- assertThrows (IllegalArgumentException .class ,
293- ()->{
295+ final IllegalArgumentException thrown = assertThrows (IllegalArgumentException .class ,
296+ () -> {
297+ StringEscaper .validateString (input );
298+ });
299+
300+ assertEquals ("Invalid escape sequence: \\ s" , thrown .getMessage ());
301+ }
302+
303+ @ Test
304+ void testingValidateString_WithWildStringOnlyAtTheStartToThrowsException () {
305+ // Given
306+ String input = "\" te\\ st" ;
307+ // When // Then
308+ final IllegalArgumentException thrown = assertThrows (IllegalArgumentException .class ,
309+ () -> {
310+ StringEscaper .validateString (input );
311+ });
312+
313+ assertEquals ("Unterminated string" , thrown .getMessage ());
314+ }
315+
316+ @ Test
317+ void testingValidateString_WithWildStringOnlyAtTheStartAndEndToThrowsException () {
318+ // Given
319+ String input = "\" abc\\ \" " ;
320+ // When // Then
321+ final IllegalArgumentException thrown = assertThrows (IllegalArgumentException .class ,
322+ () -> {
294323 StringEscaper .validateString (input );
295324 });
325+
326+ assertEquals ("Invalid escape sequence: trailing backslash" , thrown .getMessage ());
296327 }
297328}
0 commit comments