Home | History | Annotate | Download | only in table
      1 /*******************************************************************************
      2  * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  *
      8  * Contributors:
      9  *    Marc R. Hoffmann - initial API and implementation
     10  *
     11  *******************************************************************************/
     12 package org.jacoco.report.internal.html.table;
     13 
     14 import static org.junit.Assert.assertEquals;
     15 import static org.junit.Assert.fail;
     16 
     17 import java.io.IOException;
     18 import java.util.Arrays;
     19 import java.util.Comparator;
     20 import java.util.List;
     21 
     22 import org.jacoco.core.analysis.CounterComparator;
     23 import org.jacoco.core.analysis.CoverageNodeImpl;
     24 import org.jacoco.core.analysis.ICoverageNode;
     25 import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
     26 import org.jacoco.core.analysis.ICoverageNode.ElementType;
     27 import org.jacoco.core.internal.analysis.CounterImpl;
     28 import org.jacoco.report.MemoryMultiReportOutput;
     29 import org.jacoco.report.internal.ReportOutputFolder;
     30 import org.jacoco.report.internal.html.HTMLDocument;
     31 import org.jacoco.report.internal.html.HTMLElement;
     32 import org.jacoco.report.internal.html.HTMLSupport;
     33 import org.jacoco.report.internal.html.resources.Resources;
     34 import org.junit.After;
     35 import org.junit.Before;
     36 import org.junit.Test;
     37 import org.w3c.dom.Document;
     38 
     39 /**
     40  * Unit tests for {@link Table}.
     41  */
     42 public class TableTest {
     43 
     44 	private MemoryMultiReportOutput output;
     45 
     46 	private ReportOutputFolder root;
     47 
     48 	private Resources resources;
     49 
     50 	private HTMLDocument doc;
     51 
     52 	private HTMLElement body;
     53 
     54 	private Table table;
     55 
     56 	@Before
     57 	public void setup() throws IOException {
     58 		output = new MemoryMultiReportOutput();
     59 		root = new ReportOutputFolder(output);
     60 		resources = new Resources(root);
     61 		doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8");
     62 		doc.head().title();
     63 		body = doc.body();
     64 		table = new Table();
     65 	}
     66 
     67 	@After
     68 	public void teardown() throws IOException {
     69 		output.close();
     70 		output.assertAllClosed();
     71 	}
     72 
     73 	@Test
     74 	public void testCallbackSequence() throws IOException {
     75 		final IColumnRenderer recorder = new StubRenderer(
     76 				CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)) {
     77 
     78 			private final StringBuilder store = new StringBuilder();
     79 
     80 			@Override
     81 			public boolean init(List<? extends ITableItem> items,
     82 					ICoverageNode total) {
     83 				store.append("init-");
     84 				return true;
     85 			}
     86 
     87 			@Override
     88 			public void footer(HTMLElement td, ICoverageNode total,
     89 					Resources resources, ReportOutputFolder base) {
     90 				store.append("footer-");
     91 			}
     92 
     93 			@Override
     94 			public void item(HTMLElement td, ITableItem item,
     95 					Resources resources, ReportOutputFolder base) {
     96 				store.append("item").append(item.getLinkLabel()).append("-");
     97 			}
     98 
     99 			@Override
    100 			public String toString() {
    101 				return store.toString();
    102 			}
    103 
    104 		};
    105 		final List<ITableItem> items = Arrays.asList(createItem("A", 1),
    106 				createItem("B", 2), createItem("C", 3));
    107 		table.add("Header", null, recorder, false);
    108 		table.render(body, items, createTotal("Sum", 6), resources, root);
    109 		doc.close();
    110 		assertEquals("init-footer-itemA-itemB-itemC-", recorder.toString());
    111 	}
    112 
    113 	@Test
    114 	public void testInvisible() throws IOException {
    115 		final IColumnRenderer column = new StubRenderer(
    116 				CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)) {
    117 
    118 			@Override
    119 			public boolean init(List<? extends ITableItem> items,
    120 					ICoverageNode total) {
    121 				return false;
    122 			}
    123 
    124 			@Override
    125 			public void footer(HTMLElement td, ICoverageNode total,
    126 					Resources resources, ReportOutputFolder base) {
    127 				fail();
    128 			}
    129 
    130 			@Override
    131 			public void item(HTMLElement td, ITableItem item,
    132 					Resources resources, ReportOutputFolder base) {
    133 				fail();
    134 			}
    135 		};
    136 		final List<ITableItem> items = Arrays.asList(createItem("A", 1));
    137 		table.add("Header", null, column, false);
    138 		table.render(body, items, createTotal("Sum", 1), resources, root);
    139 		doc.close();
    140 	}
    141 
    142 	@Test(expected = IllegalStateException.class)
    143 	public void testTwoDefaultSorts() throws IOException {
    144 		doc.close();
    145 		table.add("Header1", null, new StubRenderer(
    146 				CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true);
    147 		table.add("Header2", null, new StubRenderer(
    148 				CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true);
    149 	}
    150 
    151 	@Test
    152 	public void testSortIds() throws Exception {
    153 		final List<ITableItem> items = Arrays.asList(createItem("C", 3),
    154 				createItem("E", 4), createItem("A", 1), createItem("D", 2));
    155 		table.add("Forward", null, new StubRenderer(
    156 				CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), false);
    157 		table.add(
    158 				"Reverse",
    159 				null,
    160 				new StubRenderer(CounterComparator.TOTALITEMS.reverse().on(
    161 						CounterEntity.CLASS)), false);
    162 		table.render(body, items, createTotal("Sum", 6), resources, root);
    163 		doc.close();
    164 
    165 		final HTMLSupport support = new HTMLSupport();
    166 		final Document doc = support.parse(output.getFile("Test.html"));
    167 
    168 		// The elements in Column 1 are sorted in forward order:
    169 		assertEquals("sortable",
    170 				support.findStr(doc, "/html/body/table/thead/tr/td[1]/@class"));
    171 		assertEquals("a",
    172 				support.findStr(doc, "/html/body/table/thead/tr/td[1]/@id"));
    173 		assertEquals("a2",
    174 				support.findStr(doc, "/html/body/table/tbody/tr[1]/td[1]/@id"));
    175 		assertEquals("a3",
    176 				support.findStr(doc, "/html/body/table/tbody/tr[2]/td[1]/@id"));
    177 		assertEquals("a0",
    178 				support.findStr(doc, "/html/body/table/tbody/tr[3]/td[1]/@id"));
    179 		assertEquals("a1",
    180 				support.findStr(doc, "/html/body/table/tbody/tr[4]/td[1]/@id"));
    181 
    182 		// The elements in Column 2 are sorted in reverse order:
    183 		assertEquals("sortable",
    184 				support.findStr(doc, "/html/body/table/thead/tr/td[2]/@class"));
    185 		assertEquals("b",
    186 				support.findStr(doc, "/html/body/table/thead/tr/td[2]/@id"));
    187 		assertEquals("b1",
    188 				support.findStr(doc, "/html/body/table/tbody/tr[1]/td[2]/@id"));
    189 		assertEquals("b0",
    190 				support.findStr(doc, "/html/body/table/tbody/tr[2]/td[2]/@id"));
    191 		assertEquals("b3",
    192 				support.findStr(doc, "/html/body/table/tbody/tr[3]/td[2]/@id"));
    193 		assertEquals("b2",
    194 				support.findStr(doc, "/html/body/table/tbody/tr[4]/td[2]/@id"));
    195 	}
    196 
    197 	@Test
    198 	public void testDefaultSorting() throws Exception {
    199 		final List<ITableItem> items = Arrays.asList(createItem("C", 3),
    200 				createItem("E", 5), createItem("A", 1), createItem("D", 4),
    201 				createItem("B", 2));
    202 		table.add("Forward", null, new StubRenderer(
    203 				CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true);
    204 		table.render(body, items, createTotal("Sum", 1), resources, root);
    205 		doc.close();
    206 
    207 		final HTMLSupport support = new HTMLSupport();
    208 		final Document doc = support.parse(output.getFile("Test.html"));
    209 
    210 		assertEquals("down sortable",
    211 				support.findStr(doc, "/html/body/table/thead/tr/td[1]/@class"));
    212 		assertEquals("A",
    213 				support.findStr(doc, "/html/body/table/tbody/tr[1]/td[1]"));
    214 		assertEquals("B",
    215 				support.findStr(doc, "/html/body/table/tbody/tr[2]/td[1]"));
    216 		assertEquals("C",
    217 				support.findStr(doc, "/html/body/table/tbody/tr[3]/td[1]"));
    218 		assertEquals("D",
    219 				support.findStr(doc, "/html/body/table/tbody/tr[4]/td[1]"));
    220 		assertEquals("E",
    221 				support.findStr(doc, "/html/body/table/tbody/tr[5]/td[1]"));
    222 	}
    223 
    224 	private ITableItem createItem(final String name, final int count) {
    225 		final ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, name) {
    226 			{
    227 				this.classCounter = CounterImpl.getInstance(count, 0);
    228 			}
    229 		};
    230 		return new ITableItem() {
    231 			public String getLinkLabel() {
    232 				return name;
    233 			}
    234 
    235 			public String getLink(ReportOutputFolder base) {
    236 				return name + ".html";
    237 			}
    238 
    239 			public String getLinkStyle() {
    240 				return Resources.getElementStyle(node.getElementType());
    241 			}
    242 
    243 			public ICoverageNode getNode() {
    244 				return node;
    245 			}
    246 		};
    247 	}
    248 
    249 	private ICoverageNode createTotal(final String name, final int count) {
    250 		return new CoverageNodeImpl(ElementType.GROUP, name) {
    251 			{
    252 				this.classCounter = CounterImpl.getInstance(count, 0);
    253 			}
    254 		};
    255 	}
    256 
    257 	private static class StubRenderer implements IColumnRenderer {
    258 
    259 		private final Comparator<ITableItem> comparator;
    260 
    261 		StubRenderer(Comparator<ICoverageNode> comparator) {
    262 			this.comparator = new TableItemComparator(comparator);
    263 		}
    264 
    265 		public boolean init(List<? extends ITableItem> items,
    266 				ICoverageNode total) {
    267 			return true;
    268 		}
    269 
    270 		public void footer(HTMLElement td, ICoverageNode total,
    271 				Resources resources, ReportOutputFolder base) {
    272 		}
    273 
    274 		public void item(HTMLElement td, ITableItem item, Resources resources,
    275 				ReportOutputFolder base) throws IOException {
    276 			td.text(item.getLinkLabel());
    277 		}
    278 
    279 		public Comparator<ITableItem> getComparator() {
    280 			return comparator;
    281 		}
    282 
    283 	}
    284 
    285 }
    286