/*
 * Copyright 2004-2005 The Trix Development Team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.trix.cuery;

import java.util.Set;

import junit.framework.TestCase;

import org.w3c.dom.Element;

/**
 * DOCUMENT.
 * 
 * @author <a href="mailto:Teletha.T@gmail.com">Teletha Testarossa</a>
 * @version $ Id: CSSQueryTest.java,v 1.0 2005/07/25 1:23:03 Teletha Exp $
 */
public class CSSQueryTest extends TestCase {

    private static CSSQuery query;

    static {
        try {
            query = new CSSQuery("src/test/org/trix/cuery/cssQuery.xml");
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    /**
     * Test.
     * 
     * @throws Exception Test fails.
     */
    public void testOne() throws Exception {
        Set<Element> elements = query.select("html body h1");
        assertEquals(1, elements.size());

        elements = query.select("html > body > h1");
        assertEquals(1, elements.size());

        elements = query.select("h1");
        assertEquals(1, elements.size());

        elements = query.select("body h1");
        assertEquals(1, elements.size());

        elements = query.select("#heading1");
        assertEquals(1, elements.size());

        elements = query.select(".heading1");
        assertEquals(1, elements.size());
    }

    /**
     * Test.
     * 
     * @throws Exception Test fails.
     */
    public void testTwo() throws Exception {
        Set<Element> elements = query.select("p.one");
        assertEquals(2, elements.size());

        elements = query.select("*.one");
        assertEquals(4, elements.size());
    }

    /**
     * Test.
     * 
     * @throws Exception Test fails.
     */
    public void testThree() throws Exception {
        Set<Element> elements = query.select("body p#identified");
        assertEquals(1, elements.size());

        elements = query.select("body #first + p");
        assertEquals(1, elements.size());
    }

    /**
     * Test.
     * 
     * @throws Exception Test fails.
     */
    public void testFour() throws Exception {
        Set<Element> elements = query.select("p.one.two");
        assertEquals(1, elements.size());
    }

    /**
     * Test.
     * 
     * @throws Exception Test fails.
     */
    public void testFive() throws Exception {
        Set<Element> elements = query.select("[class]");
        assertEquals(6, elements.size());
    }

    /**
     * Test child selector.
     * 
     * @throws Exception Test fails.
     */
    public void testChildSelector() throws Exception {
        Set<Element> elements = query.select("div#child > h2");
        assertEquals(2, elements.size());

        elements = query.select("div#child > ul#number");
        assertEquals(1, elements.size());

        elements = query.select("div#child > ul > li");
        assertEquals(6, elements.size());

        elements = query.select("div#child > * > li");
        assertEquals(6, elements.size());

        elements = query.select("div#child > ul > li.first.top.one");
        assertEquals(1, elements.size());
    }

    /**
     * Test descendant selector.
     * 
     * @throws Exception Test fails.
     */
    public void testDescendantSelector() throws Exception {
        Set<Element> elements = query.select("span span");
        assertEquals(4, elements.size());
    }

    /**
     * Test child selector.
     * 
     * @throws Exception Test fails.
     */
    public void testSibling() throws Exception {
        Set<Element> elements = query.select("li + li");
        assertEquals(5, elements.size());

        elements = query.select("p + p");
        assertEquals(3, elements.size());

        elements = query.select("p + p + p");
        assertEquals(1, elements.size());

        elements = query.select("p + p + p + p");
        assertEquals(0, elements.size());

        elements = query.select("p ~ p");
        assertEquals(5, elements.size());

        elements = query.select("p ~ p ~ p");
        assertEquals(4, elements.size());

        elements = query.select("p ~ p + p");
        assertEquals(2, elements.size());
    }

    /**
     * Test child selector.
     * 
     * @throws Exception Test fails.
     */
    public void testAttribute() throws Exception {
        Set<Element> elements = query.select("li[class]");
        assertEquals(2, elements.size());

        elements = query.select("h2[title=\"head\"]");
        assertEquals(1, elements.size());

        elements = query.select("li[class~=\"first\"]");
        assertEquals(1, elements.size());

        elements = query.select("li[title|=\"item\"]");
        assertEquals(4, elements.size());

        elements = query.select("li[title^=\"i\"]");
        assertEquals(4, elements.size());

        elements = query.select("li[title$=\"2\"]");
        assertEquals(1, elements.size());

        elements = query.select("li[title*=\"em\"]");
        assertEquals(4, elements.size());
    }

    /**
     * Test child selector.
     * 
     * @throws Exception Test fails.
     */
    public void testLang() throws Exception {
        Set<Element> elements = query.select("p:lang(ja)");
        assertEquals(1, elements.size());
    }

    /**
     * Test child selector.
     * 
     * @throws Exception Test fails.
     */
    public void testPseudo() throws Exception {
        Set<Element> elements = query.select("body > h1:first-child");
        assertEquals(1, elements.size());

        elements = query.select("body > *:last-child");
        assertEquals(1, elements.size());

        elements = query.select("head > title:only-child");
        assertEquals(1, elements.size());

        elements = query.select("body > p:only-child");
        assertEquals(0, elements.size());

        elements = query.select("*:only-child");
        assertEquals(8, elements.size());

        elements = query.select("html:root");
        assertEquals(1, elements.size());

        elements = query.select("p:root");
        assertEquals(0, elements.size());

        elements = query.select("p:empty");
        assertEquals(1, elements.size());

        elements = query.select("p:first-of-type");
        assertEquals(1, elements.size());

        elements = query.select("p:last-of-type");
        assertEquals(1, elements.size());

        elements = query.select("em:only-of-type");
        assertEquals(2, elements.size());

        elements = query.select("em:contains(\"contains\")");
        assertEquals(3, elements.size());
    }

    /**
     * Test nth child selector.
     * 
     * @throws Exception Test fails.
     */
    public void testNthChild() throws Exception {
        Set<Element> elements = query.select("dl *:nth-child(10)");
        assertEquals(1, elements.size());

        elements = query.select("dl *:nth-child(2n)");
        assertEquals(10, elements.size());

        elements = query.select("dl *:nth-child(-n+4)");
        assertEquals(4, elements.size());

        elements = query.select("dl *:nth-child(+3n+10)");
        assertEquals(4, elements.size());

        elements = query.select("dl *:nth-child(odd)");
        assertEquals(10, elements.size());

        elements = query.select("dl *:nth-last-child(7)");
        assertEquals(1, elements.size());

        elements = query.select("dl *:nth-last-child(5n+4)");
        assertEquals(4, elements.size());

        elements = query.select("dl *:nth-last-child(8n+12)");
        assertEquals(2, elements.size());

        elements = query.select("dl *:nth-last-child(even)");
        assertEquals(10, elements.size());
    }

    /**
     * Test nth typed child selector.
     * 
     * @throws Exception Test fails.
     */
    public void testNthTypedChild() throws Exception {
        Set<Element> elements = query.select("dl dd:nth-of-type(4)");
        assertEquals(1, elements.size());

        elements = query.select("dl dd:nth-of-type(3n+1)");
        assertEquals(4, elements.size());

        elements = query.select("dl dt:nth-of-type(odd)");
        assertEquals(5, elements.size());

        elements = query.select("dl dd:nth-last-of-type(2)");
        assertEquals(1, elements.size());

        elements = query.select("dl dd:nth-last-of-type(-3n+8)");
        assertEquals(3, elements.size());

        elements = query.select("dl dt:nth-last-of-type(even)");
        assertEquals(5, elements.size());
    }
    
    /**
     * Test nth typed child selector.
     * 
     * @throws Exception Test fails.
     */
    public void testNot() throws Exception {
        Set<Element> elements = query.select("*:not(p)");
        assertEquals(49, elements.size());
        
        elements = query.select("*:not(*)");
        assertEquals(0, elements.size());
        
        elements = query.select("h2:not(p)");
        assertEquals(2, elements.size());
        
        elements = query.select("p:not(:contains(\"some\"))");
        assertEquals(4, elements.size());
    }
}
