/*
 * This software is distributed under following license based on modified BSD
 * style license.
 * ----------------------------------------------------------------------
 * 
 * Copyright 2009 The Nimbus2 Project. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE NIMBUS PROJECT ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE NIMBUS PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the Nimbus2 Project.
 */
package jp.ossc.nimbus.core;

import java.util.Iterator;
import org.w3c.dom.Element;

import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import static org.testng.Assert.*;

import static jp.ossc.nimbus.TestUtility.*;

/**
 * {@link MetaData}テストケース。<p>
 * 
 * @author M.Takata
 */
public class MetaDataTest{
    
    @Test
    public void testGetParent(){
        MetaData metaData = new MyMetaData();
        assertNull(metaData.getParent());
    }
    
    @DataProvider(name = "MetaData")
    public Object[][] dataMetaData(){
        return new Object[][]{
            {null},
            {new MyMetaData()}
        };
    }
    @Test(dataProvider = "MetaData",
          groups = {"jp.ossc.nimbus.core.MetaData#getParent()",
                    "jp.ossc.nimbus.core.MetaData#MetaData(MetaData)",
                    "Normal"})
    public void testGetParent(MetaData parent){
        MetaData metaData = new MyMetaData(parent);
        assertEquals(metaData.getParent(), parent);
    }
    
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#setParent(jp.ossc.nimbus.core.MetaData)",
                    "jp.ossc.nimbus.core.MetaData#MetaData()",
                    "Normal"},
          dataProvider = "MetaData")
    public void testSetParent(MetaData parent){
        MetaData metaData = new MyMetaData();
        metaData.setParent(parent);
        assertEquals(metaData.getParent(), parent);
    }
    
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getComment()",
                    "Normal"})
    public void testGetComment(){
        MetaData metaData = new MyMetaData();
        assertNull(metaData.getComment());
    }
    
    @DataProvider(name = "Comment")
    public Object[][] dataComment(){
        return new Object[][]{
            {null},
            {"test"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#setComment(java.lang.String)",
                    "Normal"},
          dataProvider = "Comment")
    public void testSetComment(String comment){
        MetaData metaData = new MyMetaData();
        metaData.setComment(comment);
        assertEquals(metaData.getComment(), comment);
    }
    
    @DataProvider(name = "ImportXML")
    public Object[][] dataImportXML() throws Exception{
        return new Object[][]{
            {createElement("<test></test>"), null},
            {createElement("<test><!--hoge--></test>"), null},
            {createElement("<test></test><!--hoge-->"), null},
            {createElement("<!----><test></test>"), ""},
            {createElement("<!--hoge--><test></test>"), "hoge"},
            {createElement("<!-- hoge --><test></test>"), "hoge"},
            {createElement("<!--\n    hoge\n    fuga\n--><test></test>"), "hoge\nfuga"},
            {createElement("<?xml version=\"1.0\" encoding=\"UTF-8\" ?><!--ほげ--><test></test>", "UTF-8"), "ほげ"},
            {createElement("<?xml version=\"1.0\" encoding=\"UTF-8\" ?><!--　ほげ　--><test></test>", "UTF-8"), "　ほげ　"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#importXML(org.w3c.dom.Element)",
                    "Normal"},
          dataProvider = "ImportXML")
    public void testImportXML(Element element, String comment) throws Exception{
        MetaData metaData = new MyMetaData();
        metaData.importXML(element);
        assertEquals(metaData.getComment(), comment);
    }
    
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getIfDefMetaData()",
                    "Normal"})
    public void testGetIfDefMetaData(){
        MetaData metaData = new MyMetaData();
        assertNull(metaData.getIfDefMetaData());
    }
    
    @DataProvider(name = "IfDefMetaData")
    public Object[][] dataIfDefMetaData(){
        return new Object[][]{
            {null},
            {new IfDefMetaData(null)}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#setIfDefMetaData(jp.ossc.nimbus.core.IfDefMetaData)",
                    "Normal"},
          dataProvider = "IfDefMetaData")
    public void testSetIfDefMetaData(IfDefMetaData ifDefMetaData){
        MetaData metaData = new MyMetaData();
        metaData.setIfDefMetaData(ifDefMetaData);
        assertEquals(metaData.getIfDefMetaData(), ifDefMetaData);
    }
    
    
    @DataProvider(name = "ToXML")
    public Object[][] dataToXML(){
        return new Object[][]{
            {null},
            {new StringBuilder()}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#toXML(java.lang.StringBuilder)",
                    "Normal"},
          dataProvider = "ToXML")
    public void testToXML(StringBuilder buf){
        MetaData metaData = new MyMetaData();
        StringBuilder result = metaData.toXML(buf);
        assertEquals(result, buf);
    }
    
    @DataProvider(name = "GetChildren")
    public Object[][] dataGetChildren() throws Exception{
        return new Object[][]{
            {null, null},
            {createElement("<test></test>"), new String[0]},
            {createElement("<test><hoge></hoge><fuga></fuga></test>"), new String[]{"hoge", "fuga"}}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getChildren(org.w3c.dom.Element)",
                    "Normal"},
          dataProvider = "GetChildren")
    public void testGetChildren(Element element, String[] tagNames){
        Iterator<Element> children = MetaData.getChildren(element);
        if(tagNames == null){
            assertNull(children);
        }else{
            assertNotNull(children);
            for(String tagName : tagNames){
                assertTrue(children.hasNext());
                assertEquals(children.next().getTagName(), tagName);
            }
            assertFalse(children.hasNext());
        }
    }
    
    @DataProvider(name = "GetChildrenByTagName")
    public Object[][] dataGetChildrenByTagName() throws Exception{
        return new Object[][]{
            {null, null, null},
            {createElement("<test><hoge></hoge><fuga></fuga></test>"), null, new String[0]},
            {createElement("<test></test>"), "hogehoge", new String[0]},
            {createElement("<test><hoge></hoge><fuga></fuga></test>"), "hogehoge", new String[0]},
            {createElement("<test><hoge></hoge><fuga></fuga></test>"), "hoge", new String[]{"hoge"}},
            {createElement("<test><hoge></hoge><fuga></fuga><hoge></hoge></test>"), "hoge", new String[]{"hoge", "hoge"}},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getChildrenByTagName(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dataProvider = "GetChildrenByTagName")
    public void testGetChildrenByTagName(Element element, String target, String[] tagNames){
        Iterator<Element> children = MetaData.getChildrenByTagName(element, target);
        if(tagNames == null){
            assertNull(children);
        }else{
            assertNotNull(children);
            for(String tagName : tagNames){
                assertTrue(children.hasNext());
                assertEquals(children.next().getTagName(), tagName);
            }
            assertFalse(children.hasNext());
        }
    }
    
    @DataProvider(name = "GetChildrenWithoutTagName")
    public Object[][] dataGetChildrenWithoutTagName() throws Exception{
        return new Object[][]{
            {null, null, null},
            {createElement("<test><hoge></hoge><fuga></fuga></test>"), null, new String[]{"hoge", "fuga"}},
            {createElement("<test></test>"), new String[]{"hoge"}, new String[0]},
            {createElement("<test><hoge></hoge><fuga></fuga></test>"), new String[]{"hogehoge"}, new String[]{"hoge", "fuga"}},
            {createElement("<test><hoge></hoge><fuga></fuga></test>"), new String[]{"hoge"}, new String[]{"fuga"}},
            {createElement("<test><hoge></hoge><fuga></fuga><hoge></hoge></test>"), new String[]{"fuga"}, new String[]{"hoge", "hoge"}},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getChildrenWithoutTagName(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dataProvider = "GetChildrenWithoutTagName")
    public void testGetChildrenWithoutTagName(Element element, String[] target, String[] tagNames){
        Iterator<Element> children = MetaData.getChildrenWithoutTagName(element, target);
        if(tagNames == null){
            assertNull(children);
        }else{
            assertNotNull(children);
            for(String tagName : tagNames){
                assertTrue(children.hasNext());
                assertEquals(children.next().getTagName(), tagName);
            }
            assertFalse(children.hasNext());
        }
    }
    
    @DataProvider(name = "GetUniqueChild")
    public Object[][] dataGetUniqueChild() throws Exception{
        return new Object[][]{
            {createElement("<test><hoge></hoge></test>"), "hoge"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getUniqueChild(org.w3c.dom.Element)",
                    "Normal"},
          dataProvider = "GetUniqueChild")
    public void testGetUniqueChild(Element element, String tagName) throws DeploymentException{
        Element child = MetaData.getUniqueChild(element);
        if(tagName == null){
            assertNull(child);
        }else{
            assertNotNull(child);
            assertEquals(child.getTagName(), tagName);
        }
    }
    
    @DataProvider(name = "GetUniqueChildError")
    public Object[][] dataGetUniqueChildError() throws Exception{
        return new Object[][]{
            {null},
            {createElement("<test></test>")},
            {createElement("<test><hoge></hoge><fuga></fuga></test>")},
            {createElement("<test><hoge></hoge><hoge></hoge></test>")},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getUniqueChild(org.w3c.dom.Element)",
                    "Error"},
          expectedExceptions = {NullPointerException.class, DeploymentException.class},
          dataProvider = "GetUniqueChildError")
    public void testGetUniqueChildError(Element element) throws DeploymentException{
        MetaData.getUniqueChild(element);
    }
    
    @DataProvider(name = "GetUniqueChild2")
    public Object[][] dataGetUniqueChild2() throws Exception{
        return new Object[][]{
            {createElement("<test><hoge></hoge></test>"), "hoge"},
            {createElement("<test><fuga></fuga><hoge></hoge><fuga></fuga></test>"), "hoge"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getUniqueChild(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getChildrenByTagName\\(org\\.w3c\\.dom\\.Element\\,java\\.lang\\.String\\)"},
          dataProvider = "GetUniqueChild2")
    public void testGetUniqueChild2(Element element, String tagName) throws DeploymentException{
        Element child = MetaData.getUniqueChild(element, tagName);
        if(tagName == null){
            assertNull(child);
        }else{
            assertNotNull(child);
            assertEquals(child.getTagName(), tagName);
        }
    }
    
    @DataProvider(name = "GetUniqueChild2Error")
    public Object[][] dataGetUniqueChild2Error() throws Exception{
        return new Object[][]{
            {null, null},
            {createElement("<test><hoge></hoge></test>"), null},
            {createElement("<test></test>"), "hoge"},
            {createElement("<test><hoge></hoge><fuga></fuga><hoge></hoge></test>"), "hoge"},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getUniqueChild(org.w3c.dom.Element,java.lang.String)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getChildrenByTagName\\(org\\.w3c\\.dom\\.Element\\,java\\.lang\\.String\\)"},
          expectedExceptions = {NullPointerException.class, DeploymentException.class},
          dataProvider = "GetUniqueChild2Error")
    public void testGetUniqueChild2Error(Element element, String tagName) throws DeploymentException{
        MetaData.getUniqueChild(element, tagName);
    }
    
    @DataProvider(name = "GetOptionalChild")
    public Object[][] dataGetOptionalChild() throws Exception{
        return new Object[][]{
            {null, null},
            {createElement("<test></test>"), null},
            {createElement("<test><hoge></hoge></test>"), "hoge"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChild(org.w3c.dom.Element)",
                    "Normal"},
          dataProvider = "GetOptionalChild")
    public void testGetOptionalChild(Element element, String tagName) throws DeploymentException{
        Element child = MetaData.getOptionalChild(element);
        if(tagName == null){
            assertNull(child);
        }else{
            assertNotNull(child);
            assertEquals(child.getTagName(), tagName);
        }
    }
    
    @DataProvider(name = "GetOptionalChildError")
    public Object[][] dataGetOptionalChildError() throws Exception{
        return new Object[][]{
            {createElement("<test><hoge></hoge><fuga></fuga></test>")},
            {createElement("<test><hoge></hoge><hoge></hoge></test>")},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChild(org.w3c.dom.Element)",
                    "Error"},
          expectedExceptions = DeploymentException.class,
          dataProvider = "GetOptionalChildError")
    public void testGetOptionalChildError(Element element) throws DeploymentException{
        MetaData.getOptionalChild(element);
    }
    
    @DataProvider(name = "GetOptionalChild2")
    public Object[][] dataGetOptionalChild2() throws Exception{
        return new Object[][]{
            {null, null, null},
            {createElement("<test></test>"), null, null},
            {createElement("<test><hoge></hoge></test>"), null, null},
            {createElement("<test><hoge></hoge></test>"), "hoge", "hoge"},
            {createElement("<test><fuga></fuga><hoge></hoge><fuga></fuga></test>"), "hoge", "hoge"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChild(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalChild\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String,org\\.w3c\\.dom\\.Element\\)"},
          dataProvider = "GetOptionalChild2")
    public void testGetOptionalChild2(Element element, String target, String tagName) throws DeploymentException{
        Element child = MetaData.getOptionalChild(element, target);
        if(tagName == null){
            assertNull(child);
        }else{
            assertNotNull(child);
            assertEquals(child.getTagName(), tagName);
        }
    }
    
    @DataProvider(name = "GetOptionalChild2Error")
    public Object[][] dataGetOptionalChild2Error() throws Exception{
        return new Object[][]{
            {createElement("<test><hoge></hoge><fuga></fuga><hoge></hoge></test>"), "hoge"},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChild(org.w3c.dom.Element,java.lang.String)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalChild\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String,org\\.w3c\\.dom\\.Element\\)"},
          expectedExceptions = DeploymentException.class,
          dataProvider = "GetOptionalChild2Error")
    public void testGetOptionalChild2Error(Element element, String tagName) throws DeploymentException{
        MetaData.getOptionalChild(element, tagName);
    }
    
    @DataProvider(name = "GetOptionalChild3")
    public Object[][] dataGetOptionalChild3() throws Exception{
        return new Object[][]{
            {null, null, null, null},
            {null, "hoge", null, null},
            {null, null, createElement("<default></default>"), null},
            {null, "hoge", createElement("<default></default>"), null},
            {createElement("<test></test>"), null, null, null},
            {createElement("<test></test>"), null, createElement("<default></default>"), null},
            {createElement("<test><hoge></hoge></test>"), null, null, null},
            {createElement("<test><hoge></hoge></test>"), null, createElement("<default></default>"), null},
            {createElement("<test><hoge></hoge></test>"), "hoge", createElement("<default></default>"), "hoge"},
            {createElement("<test><hoge></hoge></test>"), "fuga", null, null},
            {createElement("<test><hoge></hoge></test>"), "fuga", createElement("<default></default>"), null},
            {createElement("<test><fuga></fuga><hoge></hoge><fuga></fuga></test>"), "hoge", null, "hoge"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChild(org.w3c.dom.Element,java.lang.String,org.w3c.dom.Element)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getChildrenByTagName\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String\\)"},
          dataProvider = "GetOptionalChild3")
    public void testGetOptionalChild3(Element element, String target, Element defaultElement, String tagName) throws DeploymentException{
        Element child = MetaData.getOptionalChild(element, target, defaultElement);
        if(tagName == null){
            assertEquals(child, defaultElement);
        }else{
            assertNotNull(child);
            assertEquals(child.getTagName(), tagName);
        }
    }
    
    @DataProvider(name = "GetElementContent")
    public Object[][] dataGetElementContent() throws Exception{
        return new Object[][]{
            {null, null},
            {createElement("<test/>"), null},
            {createElement("<test></test>"), null},
            {createElement("<test>hoge</test>"), "hoge"},
            {createElement("<test>  hoge  </test>"), "hoge"},
            {createElement("<test>\n    hoge\n</test>"), "hoge"},
            {createElement("<test><hoge/><fuga></fuga></test>"), null},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getElementContent(org.w3c.dom.Element)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getElementContent\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String\\)"},
          dataProvider = "GetElementContent")
    public void testGetElementContent(Element element, String content){
        String result = MetaData.getElementContent(element);
        assertEquals(result, content);
    }
    
    @DataProvider(name = "GetElementContent2")
    public Object[][] dataGetElementContent2() throws Exception{
        return new Object[][]{
            {null, null, null},
            {null, "hoge", "hoge"},
            {createElement("<test></test>"), null, null},
            {createElement("<test></test>"), "fuga", "fuga"},
            {createElement("<test>hoge</test>"), "fuga", "hoge"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getElementContent(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#trim\\(java\\.lang\\.String\\)"},
          dataProvider = "GetElementContent2")
    public void testGetElementContent2(Element element, String defaultContent, String content){
        String result = MetaData.getElementContent(element, defaultContent);
        assertEquals(result, content);
    }
    
    @DataProvider(name = "Trim")
    public Object[][] dataTrim() throws Exception{
        return new Object[][]{
            {null, null},
            {"", ""},
            {" a ", "a"},
            {" a \n b ", "a \nb"},
            {"\ta\t\n\tb\t", "a\t\nb"},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#trim(java.lang.String)",
                    "Normal"},
          dataProvider = "Trim")
    public void testTrim(String target, String expected){
        String result = MetaData.trim(target);
        assertEquals(result, expected);
    }
    
    
    @DataProvider(name = "GetUniqueChildContent")
    public Object[][] dataGetUniqueChildContent() throws Exception{
        return new Object[][]{
            {createElement("<test><hoge></hoge></test>"), "hoge", null},
            {createElement("<test><hoge>\n\tfuga\n</hoge></test>"), "hoge", "fuga"},
            {createElement("<test><hoge>\n\tfuga\n\tfuga\n</hoge></test>"), "hoge", "fuga\nfuga"},
            {createElement("<test><fuga></fuga><hoge></hoge><fuga></fuga></test>"), "hoge", null},
            {createElement("<test><fuga></fuga><hoge>ho-ge</hoge><fuga></fuga></test>"), "hoge", "ho-ge"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getUniqueChildContent(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getElementContent\\(org\\.w3c\\.dom\\.Element\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getUniqueChild\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String\\)"},
          dataProvider = "GetUniqueChildContent")
    public void testGetUniqueChildContent(Element element, String tagName, String expected) throws DeploymentException{
        String content = MetaData.getUniqueChildContent(element, tagName);
        assertEquals(content, expected);
    }
    
    @DataProvider(name = "GetUniqueChildContentError")
    public Object[][] dataGetUniqueChildContentError() throws Exception{
        return new Object[][]{
            {null, null},
            {createElement("<test><hoge></hoge></test>"), null},
            {createElement("<test></test>"), "hoge"},
            {createElement("<test><hoge></hoge><fuga></fuga><hoge></hoge></test>"), "hoge"},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getUniqueChildContent(org.w3c.dom.Element,java.lang.String)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getElementContent\\(org\\.w3c\\.dom\\.Element\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getUniqueChild\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String\\)"},
          expectedExceptions = {NullPointerException.class, DeploymentException.class},
          dataProvider = "GetUniqueChildContentError")
    public void testGetUniqueChildContentError(Element element, String tagName) throws DeploymentException{
        MetaData.getUniqueChildContent(element, tagName);
    }
    
    @DataProvider(name = "GetOptionalChildContent")
    public Object[][] dataGetOptionalChildContent() throws Exception{
        return new Object[][]{
            {null, null, null},
            {createElement("<test></test>"), null, null},
            {createElement("<test><hoge></hoge></test>"), null, null},
            {createElement("<test><hoge></hoge></test>"), "hoge", null},
            {createElement("<test><hoge>fuga</hoge></test>"), "hoge", "fuga"},
            {createElement("<test><fuga></fuga><hoge></hoge><fuga></fuga></test>"), "hoge", null},
            {createElement("<test><fuga></fuga><hoge>ho-ge</hoge><fuga></fuga></test>"), "hoge", "ho-ge"}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChildContent(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getElementContent\\(org\\.w3c\\.dom\\.Element\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalChild\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String\\)"},
          dataProvider = "GetOptionalChildContent")
    public void testGetOptionalChildContent(Element element, String target, String expected) throws DeploymentException{
        String content = MetaData.getOptionalChildContent(element, target);
        assertEquals(content, expected);
    }
    
    @DataProvider(name = "GetOptionalChildContentError")
    public Object[][] dataGetOptionalChildContentError() throws Exception{
        return new Object[][]{
            {createElement("<test><hoge></hoge><fuga></fuga><hoge></hoge></test>"), "hoge"},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChildContent(org.w3c.dom.Element,java.lang.String)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getElementContent\\(org\\.w3c\\.dom\\.Element\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalChild\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String\\)"},
          expectedExceptions = DeploymentException.class,
          dataProvider = "GetOptionalChildContentError")
    public void testGetOptionalChildContentError(Element element, String tagName) throws DeploymentException{
        MetaData.getOptionalChildContent(element, tagName);
    }
    
    @DataProvider(name = "GetOptionalChildBooleanContent")
    public Object[][] dataGetOptionalChildBooleanContent() throws Exception{
        return new Object[][]{
            {null, null, false},
            {createElement("<test></test>"), null, false},
            {createElement("<test><hoge></hoge></test>"), null, false},
            {createElement("<test><hoge></hoge></test>"), "hoge", false},
            {createElement("<test><hoge>true</hoge></test>"), "hoge", true},
            {createElement("<test><hoge>True</hoge></test>"), "hoge", true},
            {createElement("<test><hoge>YeS</hoge></test>"), "hoge", true},
            {createElement("<test><hoge>ON</hoge></test>"), "hoge", true},
            {createElement("<test><fuga></fuga><hoge></hoge><fuga></fuga></test>"), "hoge", false},
            {createElement("<test><fuga></fuga><hoge>true</hoge><fuga></fuga></test>"), "hoge", true}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChildBooleanContent(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getElementContent\\(org\\.w3c\\.dom\\.Element\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalChild\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String\\)"},
          dataProvider = "GetOptionalChildBooleanContent")
    public void testGetOptionalChildBooleanContent(Element element, String target, boolean expected) throws DeploymentException{
        boolean bool = MetaData.getOptionalChildBooleanContent(element, target);
        assertTrue(bool == expected);
    }
    
    @DataProvider(name = "GetOptionalChildBooleanContentError")
    public Object[][] dataGetOptionalChildBooleanContentError() throws Exception{
        return new Object[][]{
            {createElement("<test><hoge></hoge><fuga></fuga><hoge></hoge></test>"), "hoge"},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalChildBooleanContent(org.w3c.dom.Element,java.lang.String)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getElementContent\\(org\\.w3c\\.dom\\.Element\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalChild\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String\\)"},
          expectedExceptions = DeploymentException.class,
          dataProvider = "GetOptionalChildBooleanContentError")
    public void testGetOptionalChildBooleanContentError(Element element, String tagName) throws DeploymentException{
        MetaData.getOptionalChildBooleanContent(element, tagName);
    }
    
    @DataProvider(name = "GetUniqueAttribute")
    public Object[][] dataGetUniqueAttribute() throws Exception{
        return new Object[][]{
            {createElement("<test name=\"hoge\"></test>"), "name", "hoge"},
            {createElement("<test name=\"\"></test>"), "name", ""}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getUniqueAttribute(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dataProvider = "GetUniqueAttribute")
    public void testGetUniqueAttribute(Element element, String attribute, String expected) throws DeploymentException{
        String result = MetaData.getUniqueAttribute(element, attribute);
        assertEquals(result, expected);
    }
    
    @DataProvider(name = "GetUniqueAttributeError")
    public Object[][] dataGetUniqueAttributeError() throws Exception{
        return new Object[][]{
            {null, null},
            {createElement("<test name=\"hoge\"></test>"), null},
            {createElement("<test></test>"), "name"},
            {createElement("<test name=\"hoge\"></test>"), "code"},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getUniqueAttribute(org.w3c.dom.Element,java.lang.String)",
                    "Error"},
          expectedExceptions = {NullPointerException.class, DeploymentException.class},
          dataProvider = "GetUniqueAttributeError")
    public void testGetUniqueAttributeError(Element element, String attribute) throws DeploymentException{
        MetaData.getUniqueAttribute(element, attribute);
    }
    
    @DataProvider(name = "GetOptionalAttribute")
    public Object[][] dataGetOptionalAttribute() throws Exception{
        return new Object[][]{
            {createElement("<test></test>"), "name", null},
            {createElement("<test name=\"hoge\"></test>"), "code", null},
            {createElement("<test name=\"hoge\"></test>"), "name", "hoge"},
            {createElement("<test name=\"\"></test>"), "name", ""}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalAttribute(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalAttribute\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String,java\\.lang\\.String\\)"},
          dataProvider = "GetOptionalAttribute")
    public void testGetOptionalAttribute(Element element, String attribute, String expected){
        String result = MetaData.getOptionalAttribute(element, attribute);
        assertEquals(result, expected);
    }
    
    @DataProvider(name = "GetOptionalAttributeError")
    public Object[][] dataGetOptionalAttributeError() throws Exception{
        return new Object[][]{
            {null, null},
            {createElement("<test name=\"hoge\"></test>"), null},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalAttribute(org.w3c.dom.Element,java.lang.String)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalAttribute\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String,java\\.lang\\.String\\)"},
          expectedExceptions = NullPointerException.class,
          dataProvider = "GetOptionalAttributeError")
    public void testGetOptionalAttributeError(Element element, String attribute){
        MetaData.getOptionalAttribute(element, attribute);
    }
    
    @DataProvider(name = "GetOptionalAttribute2")
    public Object[][] dataGetOptionalAttribute2() throws Exception{
        return new Object[][]{
            {createElement("<test></test>"), "name", null, null},
            {createElement("<test></test>"), "name", "default", "default"},
            {createElement("<test name=\"hoge\"></test>"), "code", null, null},
            {createElement("<test name=\"hoge\"></test>"), "code", "default", "default"},
            {createElement("<test name=\"hoge\"></test>"), "name", "default", "hoge"},
            {createElement("<test name=\"\"></test>"), "name", "default", ""}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalAttribute(org.w3c.dom.Element,java.lang.String,java.lang.String)",
                    "Normal"},
          dataProvider = "GetOptionalAttribute2")
    public void testGetOptionalAttribute2(Element element, String attribute, String defaultVal, String expected){
        String result = MetaData.getOptionalAttribute(element, attribute, defaultVal);
        assertEquals(result, expected);
    }
    
    @DataProvider(name = "GetOptionalAttribute2Error")
    public Object[][] dataGetOptionalAttribute2Error() throws Exception{
        return new Object[][]{
            {null, null, null},
            {createElement("<test name=\"hoge\"></test>"), null, null},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalAttribute(org.w3c.dom.Element,java.lang.String,java.lang.String)",
                    "Error"},
          expectedExceptions = NullPointerException.class,
          dataProvider = "GetOptionalAttribute2Error")
    public void testGetOptionalAttribute2Error(Element element, String attribute, String defaultVal){
        MetaData.getOptionalAttribute(element, attribute, defaultVal);
    }
    
    @DataProvider(name = "GetOptionalBooleanAttribute")
    public Object[][] dataGetOptionalBooleanAttribute() throws Exception{
        return new Object[][]{
            {createElement("<test></test>"), "name", false},
            {createElement("<test name=\"hoge\"></test>"), "close", false},
            {createElement("<test close=\"true\"></test>"), "close", true},
            {createElement("<test close=\"Yes\"></test>"), "close", true},
            {createElement("<test close=\"ON\"></test>"), "close", true},
            {createElement("<test close=\"\"></test>"), "name", false},
            {createElement("<test close=\"false\"></test>"), "name", false}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalBooleanAttribute(org.w3c.dom.Element,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalAttribute\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String,java\\.lang\\.String\\)"},
          dataProvider = "GetOptionalBooleanAttribute")
    public void testGetOptionalBooleanAttribute(Element element, String attribute, boolean expected){
        boolean result = MetaData.getOptionalBooleanAttribute(element, attribute);
        assertTrue(result == expected);
    }
    
    @DataProvider(name = "GetOptionalBooleanAttributeError")
    public Object[][] dataGetOptionalBooleanAttributeError() throws Exception{
        return new Object[][]{
            {null, null},
            {createElement("<test name=\"hoge\"></test>"), null},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalBooleanAttribute(org.w3c.dom.Element,java.lang.String)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalAttribute\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String,java\\.lang\\.String\\)"},
          expectedExceptions = NullPointerException.class,
          dataProvider = "GetOptionalBooleanAttributeError")
    public void testGetOptionalBooleanAttributeError(Element element, String attribute){
        MetaData.getOptionalBooleanAttribute(element, attribute);
    }
    
    @DataProvider(name = "GetOptionalBooleanAttribute2")
    public Object[][] dataGetOptionalBooleanAttribute2() throws Exception{
        return new Object[][]{
            {createElement("<test></test>"), "name", false, false},
            {createElement("<test></test>"), "name", true, true},
            {createElement("<test name=\"hoge\"></test>"), "close", false, false},
            {createElement("<test name=\"hoge\"></test>"), "close", true, true},
            {createElement("<test close=\"true\"></test>"), "close", false, true},
            {createElement("<test close=\"Yes\"></test>"), "close", false, true},
            {createElement("<test close=\"ON\"></test>"), "close", false, true},
            {createElement("<test close=\"\"></test>"), "name", false, false},
            {createElement("<test close=\"\"></test>"), "name", true, true},
            {createElement("<test close=\"false\"></test>"), "name", false, false},
            {createElement("<test close=\"false\"></test>"), "name", true, true}
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalBooleanAttribute(org.w3c.dom.Element,java.lang.String,java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalAttribute\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String,java\\.lang\\.String\\)"},
          dataProvider = "GetOptionalBooleanAttribute2")
    public void testGetOptionalBooleanAttribute2(Element element, String attribute, boolean defaultBool, boolean expected){
        boolean result = MetaData.getOptionalBooleanAttribute(element, attribute, defaultBool);
        assertTrue(result == expected);
    }
    
    @DataProvider(name = "GetOptionalBooleanAttribute2Error")
    public Object[][] dataGetOptionalBooleanAttribute2Error() throws Exception{
        return new Object[][]{
            {null, null, true},
            {createElement("<test name=\"hoge\"></test>"), null, true},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#getOptionalBooleanAttribute(org.w3c.dom.Element,java.lang.String,java.lang.String)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getOptionalAttribute\\(org\\.w3c\\.dom\\.Element,java\\.lang\\.String,java\\.lang\\.String\\)"},
          expectedExceptions = NullPointerException.class,
          dataProvider = "GetOptionalBooleanAttribute2Error")
    public void testGetOptionalBooleanAttribute2Error(Element element, String attribute, boolean defaultBool){
        MetaData.getOptionalBooleanAttribute(element, attribute, defaultBool);
    }
    
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#clone()",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#getParent\\(\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getComment\\(\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getIfDefMetaData\\(\\)"})
    public void testClone(){
        MetaData metaData = new MyMetaData();
        metaData.setParent(new MyMetaData());
        metaData.setComment("comment");
        metaData.setIfDefMetaData(new IfDefMetaData(null));
        MetaData clone = (MetaData)metaData.clone();
        assertTrue(clone != metaData);
        assertEquals(clone.getParent(), metaData.getParent());
        assertEquals(clone.getComment(), metaData.getComment());
        assertEquals(clone.getIfDefMetaData(), metaData.getIfDefMetaData());
    }
    
    @DataProvider(name = "AppendComment")
    public Object[][] dataAppendComment(){
        return new Object[][]{
            {null, null, null},
            {new StringBuilder(), null, ""},
            {new StringBuilder(), "", "<!--  -->" + System.getProperty("line.separator")},
            {new StringBuilder(), "hoge", "<!-- hoge -->" + System.getProperty("line.separator")},
            {new StringBuilder(), "hoge\nfuga", "<!--" + System.getProperty("line.separator") + "    hoge" + System.getProperty("line.separator") + "    fuga" + System.getProperty("line.separator") + "-->" + System.getProperty("line.separator")},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#appendComment(java.lang.StringBuilder)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#setComment\\(java\\.lang\\.String\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#getComment\\(\\)",
                             "jp\\.ossc\\.nimbus\\.core\\.MetaData#addIndent\\(java\\.lang\\.String\\)"},
          dataProvider = "AppendComment")
    public void testAppendComment(StringBuilder buf, String comment, String expected){
        MetaData metaData = new MyMetaData();
        metaData.setComment(comment);
        StringBuilder result = metaData.appendComment(buf);
        assertEquals(result == null ? null : result.toString(), expected);
    }
    
    @DataProvider(name = "AddIndent")
    public Object[][] dataAddIndent(){
        return new Object[][]{
            {new StringBuilder().append(""), "    "},
            {new StringBuilder().append("hoge"), "    hoge"},
            {new StringBuilder().append("    hoge    "), "        hoge    "},
            {new StringBuilder().append("hoge\nfuga"), "    hoge" + System.getProperty("line.separator") + "    fuga"},
            {new StringBuilder().append("\nhoge\nfuga\n"), "    " + System.getProperty("line.separator") + "    hoge" + System.getProperty("line.separator") + "    fuga" + System.getProperty("line.separator")},
            {new StringBuilder().append("\n"), "    " + System.getProperty("line.separator")},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#addIndent(java.lang.StringBuilder)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#setIndent\\(java\\.lang\\.StringBuilder,int\\)"},
          dataProvider = "AddIndent")
    public void testAddIndent(StringBuilder buf, String expected){
        MetaData metaData = new MyMetaData();
        StringBuilder result = metaData.addIndent(buf);
        assertEquals(result == null ? null : result.toString(), expected);
    }
    
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#addIndent(java.lang.StringBuilder)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#setIndent\\(java\\.lang\\.StringBuilder,int\\)"},
          expectedExceptions = NullPointerException.class)
    public void testAddIndentError(){
        MetaData metaData = new MyMetaData();
        metaData.addIndent((StringBuilder)null);
    }
    
    @DataProvider(name = "AddIndent2")
    public Object[][] dataAddIndent2(){
        return new Object[][]{
            {null, null},
            {"", "    "},
            {"hoge", "    hoge"},
            {"    hoge    ", "        hoge    "},
            {"hoge\nfuga", "    hoge" + System.getProperty("line.separator") + "    fuga"},
            {"\nhoge\nfuga\n", "    " + System.getProperty("line.separator") + "    hoge" + System.getProperty("line.separator") + "    fuga" + System.getProperty("line.separator")},
            {"\n", "    " + System.getProperty("line.separator")},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#addIndent(java.lang.String)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#setIndent\\(java\\.lang\\.String,int\\)"},
          dataProvider = "AddIndent2")
    public void testAddIndent2(String str, String expected){
        MetaData metaData = new MyMetaData();
        String result = metaData.addIndent(str);
        assertEquals(result, expected);
    }
    
    @DataProvider(name = "SetIndent")
    public Object[][] dataSetIndent(){
        return new Object[][]{
            {new StringBuilder().append(""), 1, "    "},
            {new StringBuilder().append("hoge"), -1, "hoge"},
            {new StringBuilder().append("hoge"), 0, "hoge"},
            {new StringBuilder().append("hoge"), 1, "    hoge"},
            {new StringBuilder().append("hoge"), 2, "        hoge"},
            {new StringBuilder().append("    hoge    "), 1, "        hoge    "},
            {new StringBuilder().append("hoge\nfuga"), 1, "    hoge" + System.getProperty("line.separator") + "    fuga"},
            {new StringBuilder().append("\nhoge\nfuga\n"), 1, "    " + System.getProperty("line.separator") + "    hoge" + System.getProperty("line.separator") + "    fuga" + System.getProperty("line.separator")},
            {new StringBuilder().append("\n"), 1, "    " + System.getProperty("line.separator")},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#setIndent(java.lang.StringBuilder,int)",
                    "Normal"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#setIndent\\(java\\.lang\\.String,int\\)"},
          dataProvider = "SetIndent")
    public void testSetIndent(StringBuilder buf, int indent, String expected){
        MetaData metaData = new MyMetaData();
        StringBuilder result = metaData.setIndent(buf, indent);
        assertEquals(result == null ? null : result.toString(), expected);
    }
    
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#setIndent(java.lang.StringBuilder,int)",
                    "Error"},
          dependsOnGroups = {"jp\\.ossc\\.nimbus\\.core\\.MetaData#setIndent\\(java\\.lang\\.String,int\\)"},
          expectedExceptions = NullPointerException.class)
    public void testSetIndentError(){
        MetaData metaData = new MyMetaData();
        metaData.setIndent((StringBuilder)null, 1);
    }
    
    @DataProvider(name = "SetIndent2")
    public Object[][] dataSetIndent2(){
        return new Object[][]{
            {null, 1, null},
            {"", 1, "    "},
            {"hoge", -1, "hoge"},
            {"hoge", 0, "hoge"},
            {"hoge", 1, "    hoge"},
            {"hoge", 2, "        hoge"},
            {"    hoge    ", 1, "        hoge    "},
            {"hoge\nfuga", 1, "    hoge" + System.getProperty("line.separator") + "    fuga"},
            {"\nhoge\nfuga\n", 1, "    " + System.getProperty("line.separator") + "    hoge" + System.getProperty("line.separator") + "    fuga" + System.getProperty("line.separator")},
            {"\n", 1, "    " + System.getProperty("line.separator")},
        };
    }
    @Test(groups = {"jp.ossc.nimbus.core.MetaData#setIndent(java.lang.String,int)",
                    "Normal"},
          dataProvider = "SetIndent2")
    public void testSetIndent2(String str, int indent, String expected){
        MetaData metaData = new MyMetaData();
        String result = metaData.setIndent(str, indent);
        assertEquals(result, expected);
    }
    
    private class MyMetaData extends MetaData{
        
        private static final long serialVersionUID = 1279498367436351474L;
        
        public MyMetaData(){
        }
        
        public MyMetaData(MetaData parent){
            super(parent);
        }
    }
}