/* GanttProject is an opensource project management tool. License: GPL3 Copyright (C) 2012 GanttProject Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package biz.ganttproject.impex.csv; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; import junit.framework.TestCase; import net.sourceforge.ganttproject.util.collect.Pair; import static biz.ganttproject.impex.csv.SpreadsheetFormat.CSV; import static biz.ganttproject.impex.csv.SpreadsheetFormat.XLS; /** * Tests for spreadsheet (CSV and XLS) import. * * @author dbarashev (Dmitry Barashev) */ public class CsvImportTest extends TestCase { private Supplier<InputStream> createSupplier(final byte[] data) { return () -> new ByteArrayInputStream(data); } public void testBasic() throws Exception { String header = "A, B"; String data = "a1, b1"; for (Pair<SpreadsheetFormat, Supplier<InputStream>> pair : createPairs(header, data)) { final AtomicBoolean wasCalled = new AtomicBoolean(false); RecordGroup recordGroup = new RecordGroup("AB", ImmutableSet.of("A", "B")) { @Override protected boolean doProcess(SpreadsheetRecord record) { if (!super.doProcess(record)) { return false; } wasCalled.set(true); assertEquals("a1", record.get("A")); assertEquals("b1", record.get("B")); return true; } }; GanttCSVOpen importer = new GanttCSVOpen(pair.second(), pair.first(), recordGroup); importer.load(); assertTrue(wasCalled.get()); } } public void testSkipEmptyLine() throws Exception { String header = "A, B"; String data = "a1, b1"; for (Pair<SpreadsheetFormat, Supplier<InputStream>> pair : createPairs(header, "", data)) { final AtomicBoolean wasCalled = new AtomicBoolean(false); RecordGroup recordGroup = new RecordGroup("AB", ImmutableSet.of("A", "B")) { @Override protected boolean doProcess(SpreadsheetRecord record) { if (!super.doProcess(record)) { return false; } wasCalled.set(true); assertEquals("a1", record.get("A")); assertEquals("b1", record.get("B")); return true; } }; GanttCSVOpen importer = new GanttCSVOpen(pair.second(), pair.first(), recordGroup); importer.load(); assertTrue(wasCalled.get()); } } public void testTwoGroups() throws Exception { String header1 = "A, B"; String data1 = "a1, b1"; String header2 = "C, D, E"; String data2 = "c1, d1, e1"; for (Pair<SpreadsheetFormat, Supplier<InputStream>> pair : createPairs(header1, data1, "", header2, data2)) { final AtomicBoolean wasCalled1 = new AtomicBoolean(false); RecordGroup recordGroup1 = new RecordGroup("AB", ImmutableSet.of("A", "B")) { @Override protected boolean doProcess(SpreadsheetRecord record) { if (!super.doProcess(record)) { return false; } assertEquals("a1", record.get("A")); assertEquals("b1", record.get("B")); wasCalled1.set(true); return true; } }; final AtomicBoolean wasCalled2 = new AtomicBoolean(false); RecordGroup recordGroup2 = new RecordGroup("CDE", ImmutableSet.of("C", "D", "E")) { @Override protected boolean doProcess(SpreadsheetRecord record) { if (!super.doProcess(record)) { return false; } assertEquals("c1", record.get("C")); assertEquals("d1", record.get("D")); assertEquals("e1", record.get("E")); wasCalled2.set(true); return true; } }; GanttCSVOpen importer = new GanttCSVOpen(pair.second(), pair.first(), recordGroup1, recordGroup2); importer.load(); assertTrue(wasCalled1.get() && wasCalled2.get()); } } public void testIncompleteHeader() throws Exception { String header = "A, B"; String data = "a1, b1"; for (Pair<SpreadsheetFormat, Supplier<InputStream>> pair : createPairs(header, data)) { final AtomicBoolean wasCalled = new AtomicBoolean(false); RecordGroup recordGroup = new RecordGroup("ABC", ImmutableSet.of("A", "B", "C"), // all fields ImmutableSet.of("A", "B")) { // mandatory fields @Override protected boolean doProcess(SpreadsheetRecord record) { if (!super.doProcess(record)) { return false; } wasCalled.set(true); assertEquals("a1", record.get("A")); assertEquals("b1", record.get("B")); return true; } }; GanttCSVOpen importer = new GanttCSVOpen(pair.second(), pair.first(), recordGroup); importer.load(); assertTrue(wasCalled.get()); } } public void testSkipUntilFirstHeader() throws Exception { String notHeader = "FOO, BAR, A"; String header = "A, B"; String data = "a1, b1"; for (Pair<SpreadsheetFormat, Supplier<InputStream>> pair : createPairs(notHeader, header, data)) { final AtomicBoolean wasCalled = new AtomicBoolean(false); RecordGroup recordGroup = new RecordGroup("ABC", ImmutableSet.of("A", "B")) { @Override protected boolean doProcess(SpreadsheetRecord record) { if (!super.doProcess(record)) { return false; } wasCalled.set(true); assertEquals("a1", record.get("A")); assertEquals("b1", record.get("B")); return true; } }; GanttCSVOpen importer = new GanttCSVOpen(pair.second(), pair.first(), recordGroup); importer.load(); assertTrue(wasCalled.get()); assertEquals(1, importer.getSkippedLineCount()); } } public void testSkipLinesWithEmptyMandatoryFields() throws Exception { String header = "A, B, C"; String data1 = "a1,,c1"; String data2 = "a2,b2,c2"; String data3 = ",b3,c3"; for (Pair<SpreadsheetFormat, Supplier<InputStream>> pair : createPairs(header, data1, data2, data3)) { final AtomicBoolean wasCalled = new AtomicBoolean(false); RecordGroup recordGroup = new RecordGroup("ABC", ImmutableSet.of("A", "B", "C"), ImmutableSet.of("A", "B")) { @Override protected boolean doProcess(SpreadsheetRecord record) { if (!super.doProcess(record)) { return false; } if (!hasMandatoryFields(record)) { return false; } wasCalled.set(true); assertEquals("a2", record.get("A")); assertEquals("b2", record.get("B")); return true; } }; GanttCSVOpen importer = new GanttCSVOpen(pair.second(), pair.first(), recordGroup); importer.load(); assertTrue(wasCalled.get()); assertEquals(2, importer.getSkippedLineCount()); } } private List<Pair<SpreadsheetFormat, Supplier<InputStream>>> createPairs(String... data) throws Exception { List<Pair<SpreadsheetFormat, Supplier<InputStream>>> pairs = new ArrayList<>(); pairs.add(Pair.create(CSV, createSupplier(Joiner.on('\n').join(data).getBytes(Charsets.UTF_8)))); pairs.add(Pair.create(XLS, createSupplier(createXls(data)))); return pairs; } private byte[] createXls(String... rows) throws Exception { ByteArrayOutputStream stream = new ByteArrayOutputStream(); try (SpreadsheetWriter writer = new XlsWriterImpl(stream)) { for (String row : rows) { for (String cell : row.split(",", -1)) { writer.print(cell.trim()); } writer.println(); } } return stream.toByteArray(); } }