/*************************GO-LICENSE-START*********************************
* Copyright 2014 ThoughtWorks, Inc.
*
* 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.
*************************GO-LICENSE-END***********************************/
package com.thoughtworks.go.util;
import org.junit.After;
import org.junit.Test;
import org.xml.sax.InputSource;
import javax.xml.xpath.XPathExpressionException;
import java.io.*;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
public class XpathUtilsTest {
private File testFile;
private static final String XML = "<root>\n"
+ "<son>\n"
+ "<grandson name=\"someone\"/>\n"
+ "<grandson name=\"anyone\" address=\"\"></grandson>\n"
+ "</son>\n"
+ "</root>";
@After
public void tearDown() throws Exception {
if (testFile != null && testFile.exists()) {
testFile.delete();
}
}
@Test
public void shouldEvaluateXpath() throws Exception {
String xpath = "/root/son/grandson/@name";
String value = XpathUtils.evaluate(getTestFile(), xpath);
assertThat(value, is("someone"));
}
@Test
public void shouldEvaluateAnotherXpath() throws Exception {
String xpath = "//son/grandson[2]/@name";
String value = XpathUtils.evaluate(getTestFile(), xpath);
assertThat(value, is("anyone"));
}
@Test
public void shouldEvaluateTextValueXpath() throws Exception {
String xpath = "//son/grandson[2]/text()";
String value = XpathUtils.evaluate(getTestFile(), xpath);
assertThat(value, is(""));
}
@Test(expected = XPathExpressionException.class)
public void shouldThrowExceptionForIllegalXpath() throws Exception {
XpathUtils.evaluate(getTestFile(), "//");
}
@Test
public void shouldCheckIfNodeExists() throws Exception {
String attribute = "//son/grandson[@name=\"anyone\"]/@address";
assertThat(XpathUtils.evaluate(getTestFile(), attribute), is(""));
assertThat(XpathUtils.nodeExists(getTestFile(), attribute), is(true));
String textNode = "//son/grandson[2]/text()";
assertThat(XpathUtils.nodeExists(getTestFile(), textNode), is(false));
}
@Test
public void shouldthrowExceptionForBadXML() {
String attribute = "//badxpath";
try {
XpathUtils.evaluate(getTestFile("NOT XML"), attribute);
fail("Should throw exception if xml is valid");
} catch (Exception ignored) {
}
}
@Test
public void shouldReturnEmptyStringWhenMatchedNodeIsNotTextNode() throws Exception {
String xpath = "/root/son";
String value = XpathUtils.evaluate(getTestFile(), xpath);
assertThat(value, is(""));
}
@Test
public void shouldParseUTFFilesWithBOM() throws Exception {
String xpath = "//son/grandson[@name=\"anyone\"]/@address";
boolean exists = XpathUtils.nodeExists(getTestFileUsingUTFWithBOM(), xpath);
assertThat(exists, is(true));
}
private File getTestFileUsingUTFWithBOM() throws IOException {
testFile = TestFileUtil.createTempFile("testXml" + System.nanoTime());
saveUtfFileWithBOM(testFile, XML);
return testFile;
}
public static void saveUtfFileWithBOM(File file, String content) throws IOException {
BufferedWriter bw = null;
OutputStreamWriter osw = null;
FileOutputStream fos = new FileOutputStream(file);
try {
// write UTF8 BOM mark if file is empty
if (file.length() < 1) {
final byte[] bom = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
fos.write(bom);
}
osw = new OutputStreamWriter(fos, "UTF-8");
bw = new BufferedWriter(osw);
if (content != null) {
bw.write(content);
}
} catch (IOException ex) {
throw ex;
} finally {
try {
bw.close();
fos.close();
} catch (Exception ex) {
}
}
}
@Test
public void shouldEvaluateXpathOfCustomer() throws Exception {
String xpath = "//coverageReport2/project/@coverage";
File file = new File("../../common/test-resources/unit/data/customer/CoverageSummary.xml");
InputSource inputSource = new InputSource(file.getPath());
assertThat(XpathUtils.nodeExists(inputSource, xpath), is(true));
String value = XpathUtils.evaluate(file, xpath);
assertThat(value, is("27.7730732"));
}
private File getTestFile() throws IOException {
return getTestFile(XML);
}
private File getTestFile(String xml) throws IOException {
testFile = TestFileUtil.createTempFile("testXml");
FileUtil.writeContentToFile(xml, testFile);
return testFile;
}
}