You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestBuildFile.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.poi.ss.excelant;
  19. import static org.apache.poi.POITestCase.assertContains;
  20. import static org.apache.poi.POITestCase.assertNotContained;
  21. import static org.junit.jupiter.api.Assertions.assertEquals;
  22. import static org.junit.jupiter.api.Assertions.assertNotNull;
  23. import static org.junit.jupiter.api.Assertions.assertThrows;
  24. import static org.junit.jupiter.api.Assertions.assertTrue;
  25. import java.io.File;
  26. import org.apache.poi.POIDataSamples;
  27. import org.apache.tools.ant.BuildEvent;
  28. import org.apache.tools.ant.BuildException;
  29. import org.apache.tools.ant.BuildListener;
  30. import org.apache.tools.ant.Project;
  31. import org.apache.tools.ant.ProjectHelper;
  32. import org.junit.jupiter.api.AfterEach;
  33. import org.junit.jupiter.api.BeforeEach;
  34. import org.junit.jupiter.api.Test;
  35. /**
  36. * JUnit test for the ExcelAnt tasks.
  37. * Leverages Ant's test framework.
  38. */
  39. public class TestBuildFile {
  40. protected Project project;
  41. private final StringBuilder logBuffer = new StringBuilder();
  42. @BeforeEach
  43. void setUp() {
  44. String filename = TestBuildFile.getDataDir() + "/../poi-excelant/src/test/resources/tests.xml";
  45. int logLevel = Project.MSG_DEBUG;
  46. logBuffer.setLength(0);
  47. project = new Project();
  48. project.init();
  49. project.setNewProperty("data.dir.name", getDataDir());
  50. File antFile = new File(System.getProperty("root"), filename);
  51. project.setUserProperty("ant.file", antFile.getAbsolutePath());
  52. project.addBuildListener(new AntTestListener(logLevel));
  53. ProjectHelper.configureProject(project, antFile);
  54. }
  55. /**
  56. * Automatically calls the target called "tearDown"
  57. * from the build file tested if it exits.
  58. * <p>
  59. * This allows to use Ant tasks directly in the build file
  60. * to clean up after each test. Note that no "setUp" target
  61. * is automatically called, since it's trivial to have a
  62. * test target depend on it.
  63. */
  64. @AfterEach
  65. void tearDown() {
  66. if (project == null) {
  67. /*
  68. * Maybe the BuildFileTest was subclassed and there is
  69. * no initialized project. So we could avoid getting a
  70. * NPE.
  71. * If there is an initialized project getTargets() does
  72. * not return null as it is initialized by an empty
  73. * HashSet.
  74. */
  75. return;
  76. }
  77. final String tearDown = "tearDown";
  78. if (project.getTargets().containsKey(tearDown)) {
  79. project.executeTarget(tearDown);
  80. }
  81. }
  82. /**
  83. * Assert that the given substring is in the log messages.
  84. */
  85. void assertLogContaining(String substring) {
  86. assertContains(getLog(), substring);
  87. }
  88. /**
  89. * Assert that the given substring is not in the log messages.
  90. */
  91. void assertLogNotContaining(String substring) {
  92. assertNotContained(getLog(), substring);
  93. }
  94. /**
  95. * Gets the log the BuildFileTest object.
  96. * Only valid if configureProject() has been called.
  97. *
  98. * @return The log value
  99. */
  100. public String getLog() {
  101. return logBuffer.toString();
  102. }
  103. /**
  104. * Executes a target we have set up
  105. *
  106. * @param targetName target to run
  107. */
  108. void executeTarget(String targetName) {
  109. project.executeTarget(targetName);
  110. }
  111. /**
  112. * Runs a target, wait for a build exception.
  113. *
  114. * @param target target to run
  115. * @param cause information string to reader of report
  116. * @param msg the message value of the build exception we are waiting
  117. * for set to null for any build exception to be valid
  118. */
  119. void expectBuildException(String target, String cause, String msg) {
  120. BuildException be = assertThrows(BuildException.class, () -> executeTarget(target));
  121. if (msg != null) {
  122. assertEquals(msg, be.getMessage(), cause);
  123. }
  124. }
  125. public static String getDataDir() {
  126. String dataDirName = System.getProperty(POIDataSamples.TEST_PROPERTY);
  127. return dataDirName == null ? "test-data" : dataDirName;
  128. }
  129. /**
  130. * Our own personal build listener.
  131. */
  132. private class AntTestListener implements BuildListener {
  133. private final int logLevel;
  134. /**
  135. * Constructs a test listener which will ignore log events
  136. * above the given level.
  137. */
  138. public AntTestListener(int logLevel) {
  139. this.logLevel = logLevel;
  140. }
  141. /**
  142. * Fired before any targets are started.
  143. */
  144. @Override
  145. public void buildStarted(BuildEvent event) { }
  146. /**
  147. * Fired after the last target has finished. This event
  148. * will still be thrown if an error occurred during the build.
  149. *
  150. * @see BuildEvent#getException()
  151. */
  152. @Override
  153. public void buildFinished(BuildEvent event) { }
  154. /**
  155. * Fired when a target is started.
  156. *
  157. * @see BuildEvent#getTarget()
  158. */
  159. @Override
  160. public void targetStarted(BuildEvent event) { }
  161. /**
  162. * Fired when a target has finished. This event will
  163. * still be thrown if an error occurred during the build.
  164. *
  165. * @see BuildEvent#getException()
  166. */
  167. @Override
  168. public void targetFinished(BuildEvent event) { }
  169. /**
  170. * Fired when a task is started.
  171. *
  172. * @see BuildEvent#getTask()
  173. */
  174. @Override
  175. public void taskStarted(BuildEvent event) { }
  176. /**
  177. * Fired when a task has finished. This event will still
  178. * be throw if an error occurred during the build.
  179. *
  180. * @see BuildEvent#getException()
  181. */
  182. @Override
  183. public void taskFinished(BuildEvent event) { }
  184. /**
  185. * Fired whenever a message is logged.
  186. *
  187. * @see BuildEvent#getMessage()
  188. * @see BuildEvent#getPriority()
  189. */
  190. @Override
  191. public void messageLogged(BuildEvent event) {
  192. if (event.getPriority() > logLevel) {
  193. // ignore event
  194. return;
  195. }
  196. if (event.getPriority() == Project.MSG_INFO ||
  197. event.getPriority() == Project.MSG_WARN ||
  198. event.getPriority() == Project.MSG_ERR) {
  199. logBuffer.append(event.getMessage());
  200. }
  201. }
  202. }
  203. @Test
  204. void testMissingFilename() {
  205. expectBuildException("test-nofile", "required argument not specified", "fileName attribute must be set!");
  206. }
  207. @Test
  208. void testFileNotFound() {
  209. expectBuildException("test-filenotfound", "required argument not specified",
  210. "Cannot load file invalid.xls. Make sure the path and file permissions are correct.");
  211. }
  212. @Test
  213. void testEvaluate() {
  214. executeTarget("test-evaluate");
  215. assertLogContaining("Using input file: " + TestBuildFile.getDataDir() + "/spreadsheet/excelant.xls");
  216. assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4.");
  217. }
  218. @Test
  219. void testEvaluateNoDetails() {
  220. executeTarget("test-evaluate-nodetails");
  221. assertLogContaining("Using input file: " + TestBuildFile.getDataDir() + "/spreadsheet/excelant.xls");
  222. assertLogNotContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4.");
  223. }
  224. @Test
  225. void testPrecision() {
  226. executeTarget("test-precision");
  227. assertLogContaining("Using input file: " + TestBuildFile.getDataDir() + "/spreadsheet/excelant.xls");
  228. assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4. " +
  229. "It evaluated to 2285.5761494145568 when the value of 2285.576149 with precision of 1.0E-4");
  230. assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4. " +
  231. "It evaluated to 2285.5761494145568 when the value of 2285.576149 with precision of 1.0E-5");
  232. assertLogContaining("Failed to evaluate cell 'MortgageCalculator'!$B$4. " +
  233. "It evaluated to 2285.5761494145568 when the value of 2285.576149 with precision of 1.0E-10 was expected.");
  234. assertLogContaining("2/3 tests passed");
  235. }
  236. @Test
  237. void testPrecisionFail() {
  238. expectBuildException("test-precision-fails", "precision not matched",
  239. "\tFailed to evaluate cell 'MortgageCalculator'!$B$4. It evaluated to 2285.5761494145568 " +
  240. "when the value of 2285.576149 with precision of 1.0E-10 was expected.");
  241. }
  242. @Test
  243. void testPassOnError() {
  244. executeTarget("test-passonerror");
  245. assertLogContaining("Using input file: " + TestBuildFile.getDataDir() + "/spreadsheet/excelant.xls");
  246. assertLogContaining("Test named failonerror failed because 1 of 0 evaluations failed to evaluate correctly.");
  247. }
  248. @Test
  249. void testFailOnError() {
  250. expectBuildException("test-failonerror", "fail on error", null);
  251. assertLogContaining("Using input file: " + TestBuildFile.getDataDir() + "/spreadsheet/excelant.xls");
  252. assertLogNotContaining("failed because 1 of 0 evaluations failed to evaluate correctly. " +
  253. "Failed to evaluate cell 'MortageCalculatorFunction'!$D$3");
  254. }
  255. @Test
  256. void testFailOnErrorNoDetails() {
  257. expectBuildException("test-failonerror-nodetails", "fail on error", null);
  258. assertLogNotContaining("Using input file: " + TestBuildFile.getDataDir() + "/spreadsheet/excelant.xls");
  259. assertLogNotContaining("failed because 1 of 0 evaluations failed to evaluate correctly. " +
  260. "Failed to evaluate cell 'MortageCalculatorFunction'!$D$3");
  261. }
  262. @Test
  263. void testUdf() {
  264. executeTarget("test-udf");
  265. assertLogContaining("1/1 tests passed");
  266. }
  267. @Test
  268. void testSetText() {
  269. executeTarget("test-settext");
  270. assertLogContaining("1/1 tests passed");
  271. }
  272. @Test
  273. void testAddHandler() {
  274. executeTarget("test-addhandler");
  275. assertLogContaining("Using input file: " + TestBuildFile.getDataDir() + "/spreadsheet/excelant.xls");
  276. assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4.");
  277. assertNotNull(MockExcelAntWorkbookHandler.instance.workbook, "The workbook should have been passed to the handler");
  278. assertTrue(MockExcelAntWorkbookHandler.instance.executed, "The handler should have been executed");
  279. }
  280. @Test
  281. void testAddHandlerWrongClass() {
  282. executeTarget("test-addhandler-wrongclass");
  283. assertLogContaining("Using input file: " + TestBuildFile.getDataDir() + "/spreadsheet/excelant.xls");
  284. assertLogContaining("Succeeded when evaluating 'MortgageCalculator'!$B$4.");
  285. }
  286. @Test
  287. void testAddHandlerFails() {
  288. expectBuildException("test-addhandler-fails", "NullPointException", null);
  289. }
  290. }