package org.jsoup.select; import static org.junit.Assert.*; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.parser.Tag; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class CssTest { private Document html = null; private static String htmlString; @BeforeClass public static void initClass() { StringBuilder sb = new StringBuilder("<html><head></head><body>"); sb.append("<div id='pseudo'>"); for (int i = 1; i <= 10; i++) { sb.append(String.format("<p>%d</p>",i)); } sb.append("</div>"); sb.append("<div id='type'>"); for (int i = 1; i <= 10; i++) { sb.append(String.format("<p>%d</p>",i)); sb.append(String.format("<span>%d</span>",i)); sb.append(String.format("<em>%d</em>",i)); sb.append(String.format("<svg>%d</svg>",i)); } sb.append("</div>"); sb.append("<span id='onlySpan'><br /></span>"); sb.append("<p class='empty'><!-- Comment only is still empty! --></p>"); sb.append("<div id='only'>"); sb.append("Some text before the <em>only</em> child in this div"); sb.append("</div>"); sb.append("</body></html>"); htmlString = sb.toString(); } @Before public void init() { html = Jsoup.parse(htmlString); } @Test public void firstChild() { check(html.select("#pseudo :first-child"), "1"); check(html.select("html:first-child")); } @Test public void lastChild() { check(html.select("#pseudo :last-child"), "10"); check(html.select("html:last-child")); } @Test public void nthChild_simple() { for(int i = 1; i <=10; i++) { check(html.select(String.format("#pseudo :nth-child(%d)", i)), String.valueOf(i)); } } @Test public void nthOfType_unknownTag() { for(int i = 1; i <=10; i++) { check(html.select(String.format("#type svg:nth-of-type(%d)", i)), String.valueOf(i)); } } @Test public void nthLastChild_simple() { for(int i = 1; i <=10; i++) { check(html.select(String.format("#pseudo :nth-last-child(%d)", i)), String.valueOf(11-i)); } } @Test public void nthOfType_simple() { for(int i = 1; i <=10; i++) { check(html.select(String.format("#type p:nth-of-type(%d)", i)), String.valueOf(i)); } } @Test public void nthLastOfType_simple() { for(int i = 1; i <=10; i++) { check(html.select(String.format("#type :nth-last-of-type(%d)", i)), String.valueOf(11-i),String.valueOf(11-i),String.valueOf(11-i),String.valueOf(11-i)); } } @Test public void nthChild_advanced() { check(html.select("#pseudo :nth-child(-5)")); check(html.select("#pseudo :nth-child(odd)"), "1", "3", "5", "7", "9"); check(html.select("#pseudo :nth-child(2n-1)"), "1", "3", "5", "7", "9"); check(html.select("#pseudo :nth-child(2n+1)"), "1", "3", "5", "7", "9"); check(html.select("#pseudo :nth-child(2n+3)"), "3", "5", "7", "9"); check(html.select("#pseudo :nth-child(even)"), "2", "4", "6", "8", "10"); check(html.select("#pseudo :nth-child(2n)"), "2", "4", "6", "8", "10"); check(html.select("#pseudo :nth-child(3n-1)"), "2", "5", "8"); check(html.select("#pseudo :nth-child(-2n+5)"), "1", "3", "5"); check(html.select("#pseudo :nth-child(+5)"), "5"); } @Test public void nthOfType_advanced() { check(html.select("#type :nth-of-type(-5)")); check(html.select("#type p:nth-of-type(odd)"), "1", "3", "5", "7", "9"); check(html.select("#type em:nth-of-type(2n-1)"), "1", "3", "5", "7", "9"); check(html.select("#type p:nth-of-type(2n+1)"), "1", "3", "5", "7", "9"); check(html.select("#type span:nth-of-type(2n+3)"), "3", "5", "7", "9"); check(html.select("#type p:nth-of-type(even)"), "2", "4", "6", "8", "10"); check(html.select("#type p:nth-of-type(2n)"), "2", "4", "6", "8", "10"); check(html.select("#type p:nth-of-type(3n-1)"), "2", "5", "8"); check(html.select("#type p:nth-of-type(-2n+5)"), "1", "3", "5"); check(html.select("#type :nth-of-type(+5)"), "5", "5", "5", "5"); } @Test public void nthLastChild_advanced() { check(html.select("#pseudo :nth-last-child(-5)")); check(html.select("#pseudo :nth-last-child(odd)"), "2", "4", "6", "8", "10"); check(html.select("#pseudo :nth-last-child(2n-1)"), "2", "4", "6", "8", "10"); check(html.select("#pseudo :nth-last-child(2n+1)"), "2", "4", "6", "8", "10"); check(html.select("#pseudo :nth-last-child(2n+3)"), "2", "4", "6", "8"); check(html.select("#pseudo :nth-last-child(even)"), "1", "3", "5", "7", "9"); check(html.select("#pseudo :nth-last-child(2n)"), "1", "3", "5", "7", "9"); check(html.select("#pseudo :nth-last-child(3n-1)"), "3", "6", "9"); check(html.select("#pseudo :nth-last-child(-2n+5)"), "6", "8", "10"); check(html.select("#pseudo :nth-last-child(+5)"), "6"); } @Test public void nthLastOfType_advanced() { check(html.select("#type :nth-last-of-type(-5)")); check(html.select("#type p:nth-last-of-type(odd)"), "2", "4", "6", "8", "10"); check(html.select("#type em:nth-last-of-type(2n-1)"), "2", "4", "6", "8", "10"); check(html.select("#type p:nth-last-of-type(2n+1)"), "2", "4", "6", "8", "10"); check(html.select("#type span:nth-last-of-type(2n+3)"), "2", "4", "6", "8"); check(html.select("#type p:nth-last-of-type(even)"), "1", "3", "5", "7", "9"); check(html.select("#type p:nth-last-of-type(2n)"), "1", "3", "5", "7", "9"); check(html.select("#type p:nth-last-of-type(3n-1)"), "3", "6", "9"); check(html.select("#type span:nth-last-of-type(-2n+5)"), "6", "8", "10"); check(html.select("#type :nth-last-of-type(+5)"), "6", "6", "6", "6"); } @Test public void firstOfType() { check(html.select("div:not(#only) :first-of-type"), "1", "1", "1", "1", "1"); } @Test public void lastOfType() { check(html.select("div:not(#only) :last-of-type"), "10", "10", "10", "10", "10"); } @Test public void empty() { final Elements sel = html.select(":empty"); assertEquals(3, sel.size()); assertEquals("head", sel.get(0).tagName()); assertEquals("br", sel.get(1).tagName()); assertEquals("p", sel.get(2).tagName()); } @Test public void onlyChild() { final Elements sel = html.select("span :only-child"); assertEquals(1, sel.size()); assertEquals("br", sel.get(0).tagName()); check(html.select("#only :only-child"), "only"); } @Test public void onlyOfType() { final Elements sel = html.select(":only-of-type"); assertEquals(6, sel.size()); assertEquals("head", sel.get(0).tagName()); assertEquals("body", sel.get(1).tagName()); assertEquals("span", sel.get(2).tagName()); assertEquals("br", sel.get(3).tagName()); assertEquals("p", sel.get(4).tagName()); assertTrue(sel.get(4).hasClass("empty")); assertEquals("em", sel.get(5).tagName()); } protected void check(Elements result, String...expectedContent ) { assertEquals("Number of elements", expectedContent.length, result.size()); for (int i = 0; i < expectedContent.length; i++) { assertNotNull(result.get(i)); assertEquals("Expected element",expectedContent[i], result.get(i).ownText()); } } @Test public void root() { Elements sel = html.select(":root"); assertEquals(1, sel.size()); assertNotNull(sel.get(0)); assertEquals(Tag.valueOf("html"), sel.get(0).tag()); Elements sel2 = html.select("body").select(":root"); assertEquals(1, sel2.size()); assertNotNull(sel2.get(0)); assertEquals(Tag.valueOf("body"), sel2.get(0).tag()); } }