PageRenderTime 47ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/core/src/spec/java/com/googlecode/instinct/internal/report/AnXmlResultMessageBuilder.java

http://instinct.googlecode.com/
Java | 231 lines | 197 code | 19 blank | 15 comment | 1 complexity | 22f812ac962478a75eaa110fe9b8d5f3 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, CPL-1.0, MPL-2.0-no-copyleft-exception
  1. /*
  2. * Copyright 2008 Jeremy Mawson
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.googlecode.instinct.internal.report;
  17. import static com.googlecode.instinct.expect.Expect.expect;
  18. import com.googlecode.instinct.integrate.junit4.InstinctRunner;
  19. import com.googlecode.instinct.internal.core.CompleteSpecificationMethod;
  20. import com.googlecode.instinct.internal.core.ContextClass;
  21. import com.googlecode.instinct.internal.core.ContextClassImpl;
  22. import com.googlecode.instinct.internal.core.LifecycleMethod;
  23. import com.googlecode.instinct.internal.core.PendingSpecificationMethod;
  24. import com.googlecode.instinct.internal.core.SpecificationMethod;
  25. import com.googlecode.instinct.internal.runner.ContextResult;
  26. import com.googlecode.instinct.internal.runner.ContextResultImpl;
  27. import com.googlecode.instinct.internal.runner.SpecificationFailureException;
  28. import com.googlecode.instinct.internal.runner.SpecificationResult;
  29. import com.googlecode.instinct.internal.runner.SpecificationResultImpl;
  30. import com.googlecode.instinct.internal.runner.SpecificationRunFailureStatus;
  31. import com.googlecode.instinct.internal.runner.SpecificationRunPendingStatus;
  32. import com.googlecode.instinct.internal.runner.SpecificationRunSuccessStatus;
  33. import com.googlecode.instinct.internal.util.AggregatingException;
  34. import com.googlecode.instinct.marker.annotate.BeforeSpecification;
  35. import com.googlecode.instinct.marker.annotate.Specification;
  36. import static com.googlecode.instinct.marker.annotate.Specification.SpecificationState.PENDING;
  37. import com.googlecode.instinct.marker.annotate.Subject;
  38. import com.googlecode.instinct.report.ResultMessageBuilder;
  39. import com.googlecode.instinct.report.ResultMessageBuilderException;
  40. import static com.googlecode.instinct.test.checker.ClassChecker.checkClass;
  41. import fj.data.List;
  42. import fj.data.Option;
  43. import java.io.StringReader;
  44. import java.net.InetAddress;
  45. import java.text.DateFormat;
  46. import java.text.SimpleDateFormat;
  47. import java.util.Date;
  48. import javax.xml.parsers.DocumentBuilder;
  49. import javax.xml.parsers.DocumentBuilderFactory;
  50. import javax.xml.xpath.XPath;
  51. import javax.xml.xpath.XPathConstants;
  52. import javax.xml.xpath.XPathFactory;
  53. import static org.junit.Assert.fail;
  54. import org.junit.runner.RunWith;
  55. import org.w3c.dom.Document;
  56. import org.w3c.dom.Node;
  57. import org.xml.sax.InputSource;
  58. @RunWith(InstinctRunner.class)
  59. public final class AnXmlResultMessageBuilder {
  60. private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
  61. @Subject private XmlResultMessageBuilder builder;
  62. private ContextResult successContextResult;
  63. private ContextResult failureContextResult;
  64. private SpecificationResult successSpecificationResult;
  65. private SpecificationResult failureSpecificationResult;
  66. @BeforeSpecification
  67. public void setUp() throws ResultMessageBuilderException {
  68. builder = new XmlResultMessageBuilder();
  69. try {
  70. final ContextClass successContextClass = new ContextClassImpl(ASuccess.class);
  71. successContextResult = new ContextResultImpl(successContextClass);
  72. final SpecificationMethod successSpecificationMethod = new CompleteSpecificationMethod(ASuccess.class,
  73. ASuccess.class.getDeclaredMethod("aPassingMethod"), List.<LifecycleMethod>nil(), List.<LifecycleMethod>nil());
  74. successSpecificationResult = new SpecificationResultImpl(successSpecificationMethod, new SpecificationRunSuccessStatus(), 2500L);
  75. successContextResult.addSpecificationResult(successSpecificationResult);
  76. failureContextResult = new ContextResultImpl(new ContextClassImpl(AFailure.class));
  77. final SpecificationMethod failureSpecificationMethod = new CompleteSpecificationMethod(AFailure.class,
  78. AFailure.class.getDeclaredMethod("aFailingMethod"), List.<LifecycleMethod>nil(), List.<LifecycleMethod>nil());
  79. failureSpecificationResult = new SpecificationResultImpl(failureSpecificationMethod, new SpecificationRunFailureStatus(
  80. new SpecificationFailureException("It went wrong",
  81. new AggregatingException("It just didn't work", List.<Throwable>single(new RuntimeException("Underlying cause")))),
  82. Option.<Throwable>none()), 500L);
  83. failureContextResult.addSpecificationResult(successSpecificationResult);
  84. failureContextResult.addSpecificationResult(failureSpecificationResult);
  85. } catch (NoSuchMethodException e) {
  86. fail(e.getMessage());
  87. }
  88. }
  89. @Specification
  90. public void conformsToClassTraits() {
  91. checkClass(builder.getClass(), ResultMessageBuilder.class);
  92. }
  93. @Specification(expectedException = IllegalArgumentException.class)
  94. public void doesNotPermitMessagesToBeBuiltAgainstNullContextResults() throws ResultMessageBuilderException {
  95. builder.buildMessage((ContextResult) null);
  96. }
  97. @Specification(expectedException = IllegalArgumentException.class)
  98. public void doesNotPermitMessagesToBeBuiltAgainstNullSpecificationResults() {
  99. builder.buildMessage((SpecificationResult) null);
  100. }
  101. @Specification
  102. public void buildsAnEmptyMessageOnSpecificationResultSuccess() {
  103. expect.that(builder.buildMessage(successSpecificationResult)).isEmpty();
  104. }
  105. @Specification
  106. public void buildsAnEmptyMessageOnSpecificationResultFailure() {
  107. expect.that(builder.buildMessage(failureSpecificationResult)).isEmpty();
  108. }
  109. @Specification
  110. public void buildsAnXmlReportOnContextResultSuccess() throws Exception {
  111. final Date startTime = nowIgnoringMilliseconds();
  112. final Document document = createDocumentFrom(builder.buildMessage(successContextResult));
  113. final Date endTime = nowIgnoringMilliseconds();
  114. expect.that(evaluateXpath(document, "/testsuite/@errors")).isEqualTo("0");
  115. expect.that(evaluateXpath(document, "/testsuite/@failures")).isEqualTo("0");
  116. expect.that(evaluateXpath(document, "/testsuite/@hostname")).isEqualTo(InetAddress.getLocalHost().getHostName());
  117. expect.that(evaluateXpath(document, "/testsuite/@name")).isEqualTo(ASuccess.class.getName());
  118. expect.that(evaluateXpath(document, "/testsuite/@tests")).isEqualTo("1");
  119. expect.that(evaluateXpath(document, "/testsuite/@time")).isEqualTo("2.500");
  120. final Date reportDate = DATE_FORMAT.parse(evaluateXpath(document, "/testsuite/@timestamp"));
  121. expect.that(reportDate).isGreaterThanOrEqualTo(startTime);
  122. expect.that(reportDate).isLessThanOrEqualTo(endTime);
  123. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@classname")).isEqualTo(ASuccess.class.getName());
  124. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@name")).isEqualTo("aPassingMethod");
  125. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@time")).isEqualTo("2.500");
  126. }
  127. @Specification
  128. public void buildsAnXmlReportOnContextResultFailure() throws Exception {
  129. final Date startTime = nowIgnoringMilliseconds();
  130. final Document document = createDocumentFrom(builder.buildMessage(failureContextResult));
  131. final Date endTime = nowIgnoringMilliseconds();
  132. expect.that(evaluateXpath(document, "/testsuite/@errors")).isEqualTo("0");
  133. expect.that(evaluateXpath(document, "/testsuite/@failures")).isEqualTo("1");
  134. expect.that(evaluateXpath(document, "/testsuite/@hostname")).isEqualTo(InetAddress.getLocalHost().getHostName());
  135. expect.that(evaluateXpath(document, "/testsuite/@name")).isEqualTo(AFailure.class.getName());
  136. expect.that(evaluateXpath(document, "/testsuite/@tests")).isEqualTo("2");
  137. expect.that(evaluateXpath(document, "/testsuite/@time")).isEqualTo("3.000");
  138. final Date reportDate = DATE_FORMAT.parse(evaluateXpath(document, "/testsuite/@timestamp"));
  139. expect.that(reportDate).isGreaterThanOrEqualTo(startTime);
  140. expect.that(reportDate).isLessThanOrEqualTo(endTime);
  141. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@classname")).isEqualTo(AFailure.class.getName());
  142. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@name")).isEqualTo("aPassingMethod");
  143. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@time")).isEqualTo("2.500");
  144. expect.that(nodeExists(document, "/testsuite/testcase[1]/failure")).isFalse();
  145. expect.that(evaluateXpath(document, "/testsuite/testcase[2]/@classname")).isEqualTo(AFailure.class.getName());
  146. expect.that(evaluateXpath(document, "/testsuite/testcase[2]/@name")).isEqualTo("aFailingMethod");
  147. expect.that(evaluateXpath(document, "/testsuite/testcase[2]/@time")).isEqualTo("0.500");
  148. expect.that(evaluateXpath(document, "/testsuite/testcase[2]/failure/@message")).isEqualTo("It went wrong");
  149. expect.that(evaluateXpath(document, "/testsuite/testcase[2]/failure/@type"))
  150. .isEqualTo("com.googlecode.instinct.internal.util.AggregatingException");
  151. expect.that(evaluateXpath(document, "/testsuite/testcase[2]/failure")).startsWith("It just didn't work");
  152. }
  153. @Specification
  154. public void buildsAnXmlReportIncludingAPendingSpecification() throws Exception {
  155. final ContextClass successContextClass = new ContextClassImpl(ASuccess.class);
  156. final ContextResult successContextResultWithPending = new ContextResultImpl(successContextClass);
  157. final SpecificationMethod pendingSpecificationMethod = new PendingSpecificationMethod(ASuccess.class,
  158. ASuccess.class.getDeclaredMethod("aPendingMethod"), List.<LifecycleMethod>nil(), List.<LifecycleMethod>nil());
  159. final SpecificationResult pendingSpecificationResult =
  160. new SpecificationResultImpl(pendingSpecificationMethod, new SpecificationRunPendingStatus(), 700L);
  161. successContextResultWithPending.addSpecificationResult(pendingSpecificationResult);
  162. final Date startTime = nowIgnoringMilliseconds();
  163. final Document document = createDocumentFrom(builder.buildMessage(successContextResultWithPending));
  164. final Date endTime = nowIgnoringMilliseconds();
  165. expect.that(evaluateXpath(document, "/testsuite/@errors")).isEqualTo("0");
  166. expect.that(evaluateXpath(document, "/testsuite/@failures")).isEqualTo("0");
  167. expect.that(evaluateXpath(document, "/testsuite/@hostname")).isEqualTo(InetAddress.getLocalHost().getHostName());
  168. expect.that(evaluateXpath(document, "/testsuite/@name")).isEqualTo(ASuccess.class.getName());
  169. expect.that(evaluateXpath(document, "/testsuite/@tests")).isEqualTo("1");
  170. expect.that(evaluateXpath(document, "/testsuite/@time")).isEqualTo("0.700");
  171. final Date reportDate = DATE_FORMAT.parse(evaluateXpath(document, "/testsuite/@timestamp"));
  172. expect.that(reportDate).isGreaterThanOrEqualTo(startTime);
  173. expect.that(reportDate).isLessThanOrEqualTo(endTime);
  174. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@classname")).isEqualTo(ASuccess.class.getName());
  175. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@name")).isEqualTo("aPendingMethod [PENDING - It's a whimsy]");
  176. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/@time")).isEqualTo("0.700");
  177. expect.that(nodeExists(document, "/testsuite/testcase[1]/failure")).isFalse();
  178. expect.that(evaluateXpath(document, "/testsuite/testcase[1]/pending")).isEqualTo("It's a whimsy");
  179. }
  180. private Boolean nodeExists(final Object document, final String expression) throws Exception {
  181. final XPath xpath = XPathFactory.newInstance().newXPath();
  182. final Node node = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);
  183. return node != null;
  184. }
  185. private Date nowIgnoringMilliseconds() {
  186. final Date date = new Date();
  187. date.setTime(date.getTime() - date.getTime() % 1000);
  188. return date;
  189. }
  190. private String evaluateXpath(final Object document, final String expression) throws Exception {
  191. final XPath xpath = XPathFactory.newInstance().newXPath();
  192. final Node node = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);
  193. return node.getTextContent();
  194. }
  195. private Document createDocumentFrom(final String xmlString) throws Exception {
  196. final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  197. factory.setValidating(false);
  198. final DocumentBuilder docBuilder = factory.newDocumentBuilder();
  199. return docBuilder.parse(new InputSource(new StringReader(xmlString)));
  200. }
  201. private class AFailure {
  202. public final void aFailingMethod() {
  203. }
  204. }
  205. private class ASuccess {
  206. public final void aPassingMethod() {
  207. }
  208. @Specification(state = PENDING, reason = "It's a whimsy")
  209. public final void aPendingMethod() {
  210. }
  211. }
  212. }