CSSIdentifierSerializer { public String serialize(String identifier) { if (StringUtils.isEmpty(identifier)) { return identifier; } int length = identifier.length(); int index = -1; StringBuilder result = new StringBuilder(); int firstCodeUnit = identifier.charAt(0); while (++index < length) { int codeUnit = identifier.charAt(index); if (codeUnit == 0x0000) { throw new IllegalArgumentException("Invalid character: the input contains U+0000."); } else if (shouldEscapeAsCodePoint(codeUnit, index, firstCodeUnit)) { result.append('\\').append(Integer.toHexString(codeUnit)).append(' '); } else if (index == 0 && length == 1 && codeUnit == 0x002D) { result.append('\\').append(identifier.charAt(index)); } else if (shouldNotEscape(codeUnit)) { result.append(identifier.charAt(index)); } else { result.append('\\').append(identifier.charAt(index)); } } return result.toString(); }  String serialize(String identifier);  }
@Test @DisplayName("Various CSS serialization tests") void serialize() { assertCssThrowsException("\u0000"); assertCssThrowsException("a\u0000"); assertCssThrowsException("\u0000b"); assertCssThrowsException("a\u0000b"); assertNull(this.cssIdentifierSerializer.serialize(null)); assertCss("", ""); assertCss("\u0001\u0002\u001E\u001F", "\\1 \\2 \\1e \\1f "); assertCss("0a", "\\30 a"); assertCss("1a", "\\31 a"); assertCss("2a", "\\32 a"); assertCss("3a", "\\33 a"); assertCss("4a", "\\34 a"); assertCss("5a", "\\35 a"); assertCss("6a", "\\36 a"); assertCss("7a", "\\37 a"); assertCss("8a", "\\38 a"); assertCss("9a", "\\39 a"); assertCss("a0b", "a0b"); assertCss("a1b", "a1b"); assertCss("a2b", "a2b"); assertCss("a3b", "a3b"); assertCss("a4b", "a4b"); assertCss("a5b", "a5b"); assertCss("a6b", "a6b"); assertCss("a7b", "a7b"); assertCss("a8b", "a8b"); assertCss("a9b", "a9b"); assertCss("-0a", "-\\30 a"); assertCss("-1a", "-\\31 a"); assertCss("-2a", "-\\32 a"); assertCss("-3a", "-\\33 a"); assertCss("-4a", "-\\34 a"); assertCss("-5a", "-\\35 a"); assertCss("-6a", "-\\36 a"); assertCss("-7a", "-\\37 a"); assertCss("-8a", "-\\38 a"); assertCss("-9a", "-\\39 a"); assertCss("-", "\\-"); assertCss("-a", "-a"); assertCss("--", "--"); assertCss("--a", "--a"); assertCss("\u0080\u002D\u005F\u00A9", "\u0080\u002D\u005F\u00A9"); assertCss("\u007F\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088" + "\u0089\u008A\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092" + "\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F", "\\7f \u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089" + "\u008A\u008B\u008C\u008D\u008E\u008F\u0090\u0091\u0092\u0093" + "\u0094\u0095\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F"); assertCss("\u00A0\u00A1\u00A2", "\u00A0\u00A1\u00A2"); assertCss("a0123456789b", "a0123456789b"); assertCss("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"); assertCss("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); assertCss("\u0020\u0021\u0078\u0079", "\\ \\!xy"); assertCss("\uD834\uDF06", "\uD834\uDF06"); assertCss("\uDF06", "\uDF06"); assertCss("\uD834", "\uD834"); assertCss("a#b.c d[e=f]g{h:i;j}k", "a\\#b\\.c\\ d\\[e\\=f\\]g\\{h\\:i\\;j\\}k"); }