package net.codjo.broadcast.server; import fakedb.FakeDriver; import java.io.PrintWriter; import java.io.StringWriter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import junit.framework.TestCase; import net.codjo.broadcast.common.ComputedFieldGenerator; import net.codjo.broadcast.common.Context; import net.codjo.broadcast.common.Preferences; import net.codjo.broadcast.common.PreferencesForTesting; import net.codjo.broadcast.common.columns.FileColumnGenerator; import net.codjo.broadcast.common.computed.ComputedField; import net.codjo.sql.builder.FieldInfo; import net.codjo.sql.builder.TableName; import net.codjo.test.common.LogString; /** * */ public class DefaultFileSectionGeneratorTest extends TestCase { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); private static final String DB_APPLICATION_USER = "APP_USER"; private static final String DB_APPLICATION_USER_VARIABLE = "dbApplicationUser"; private FakeColumnGenerator columnA; private FakeColumnGenerator columnB; private FakeComputedField computedField; private Context context; private FakeQueryBuilder queryBuilder; private DefaultFileSectionGenerator sectionGenerator; private PreferencesForTesting.FakeSelector selector; private Preferences preference; private Connection connection; private StringWriter result = new StringWriter(); private PrintWriter writer = new PrintWriter(result); private LogString logger; private Object[][] warningsRs; /** * Verifie la generation : Pas d'en-tete, avec separateur. */ public void test_generate_content_ColumnSeparator() throws Exception { sectionGenerator.setColumnSeparator("-"); sectionGenerator.generate(context, connection, writer); assertEquals("A1-B1" + LINE_SEPARATOR + "A2-B2" + LINE_SEPARATOR, result.toString()); } public void test_generate_content_ColumnSeparator_header() throws Exception { sectionGenerator.setColumnSeparator("-"); sectionGenerator.setColumnHeader(true); sectionGenerator.generate(context, connection, writer); assertEquals("A-B" + LINE_SEPARATOR + "A1-B1" + LINE_SEPARATOR + "A2-B2" + LINE_SEPARATOR, result.toString()); } /** * Verifie la generation : en-tete de colonne, pas de separateur. */ public void test_generate_content_columnHeader() throws Exception { sectionGenerator.setColumnHeader(true); sectionGenerator.generate(context, connection, writer); assertEquals("AB" + LINE_SEPARATOR + "A1B1" + LINE_SEPARATOR + "A2B2" + LINE_SEPARATOR, result.toString()); } /** * Verifie la generation : en-tete de section, pas de separateur. */ public void test_generate_content_sectionHeader() throws Exception { sectionGenerator.setSectionHeader("eau de $name$"); Map<String, Object> map = new HashMap<String, Object>(); map.put("name", "cristaline"); context = new Context(map); context.setComputedTableWasCreated(true); addVariables(context); sectionGenerator.generate(context, connection, writer); assertEquals("eau de cristaline" + LINE_SEPARATOR + "A1B1" + LINE_SEPARATOR + "A2B2" + LINE_SEPARATOR, result.toString()); } /** * Verifie la generation : Pas d'en-tete, pas de separateur. */ public void test_generate_content_simple() throws Exception { sectionGenerator.generate(context, connection, writer); assertEquals("A1B1" + LINE_SEPARATOR + "A2B2" + LINE_SEPARATOR, result.toString()); } /** * Assert the generate method is filling context with warnings. */ public void test_generate_fillContextWithWarnings() throws Exception { test_generate_fillContextWithWarnings(true); } /** * Assert the generate method doesn't try to find warnings when there is no computed field (because the COMPUTED * table is not created in this case). */ public void test_generate_noWarningsWhenNoComputedField() throws Exception { test_generate_fillContextWithWarnings(false); } /** * Assert the generate method is filling context with warnings. */ private void test_generate_fillContextWithWarnings(boolean atLeastOneComputedField) throws Exception { String expectedWarnings = null; String[] warnings = new String[0]; if (atLeastOneComputedField) { FakeDriver.getDriver().resetFakes(); String warning1 = "warning1"; String warning2 = "warning2"; String lineSeparator = System.getProperty("line.separator"); warnings = new String[]{warning1, warning2}; expectedWarnings = warning1 + lineSeparator + warning2; } fakeResultSetWith2RowsAndWarnings(atLeastOneComputedField, warnings); context.setComputedTableWasCreated(atLeastOneComputedField); // test sectionGenerator.generate(context, connection, writer); // assertions assertEquals("warnings not added into context", expectedWarnings, context.getWarnings()); assertEquals("computedTableWasCreated must remain unchanged", atLeastOneComputedField, context.getComputedTableWasCreated()); } /** * Verifie que les appels aux accointances sont faits. */ public void test_generate_section_calls() throws Exception { String sql = "drop table " + preference.getComputedTableName(); FakeDriver.getDriver().pushUpdateConstraint(context.replaceVariables(sql)); sectionGenerator.generate(context, connection, writer); assertTrue(selector.isProceedHasBeenCalled()); assertTrue(selector.isCleanupHasBeenCalled()); logger.assertContent("createComputedTable()", "fillComputedTable()"); assertEquals(2, columnA.calledNumber); assertEquals(2, columnB.calledNumber); assertTrue(queryBuilder.hasBeenCalled); assertTrue("Drop de la table des champs calcul�", FakeDriver.getDriver().isUpdateConstraintEmpty()); } public void test_generate_withTwoBreakForAllLines() throws Exception { DefaultFileSectionGenerator sectionWithBreakGenerator = initFileGenerator(true, true); sectionWithBreakGenerator.generate(context, connection, writer); assertEquals("AB" + LINE_SEPARATOR + "CD" + LINE_SEPARATOR + "A1B1" + LINE_SEPARATOR + "C1D1" + LINE_SEPARATOR + "A3B2" + LINE_SEPARATOR + "C2D2" + LINE_SEPARATOR, result.toString()); } public void test_generate_withFirstFieldBreakForAllLines() throws Exception { DefaultFileSectionGenerator sectionWithBreakGenerator = initFileGenerator(true, false); sectionWithBreakGenerator.generate(context, connection, writer); assertEquals("AB" + LINE_SEPARATOR + "CD" + LINE_SEPARATOR + "A1B1" + LINE_SEPARATOR + "C1D1" + LINE_SEPARATOR + "A3B1" + LINE_SEPARATOR + "C2D2" + LINE_SEPARATOR, result.toString()); } public void test_generate_withSecondFieldBreakForAllLines() throws Exception { DefaultFileSectionGenerator sectionWithBreakGenerator = initFileGenerator(false, true); sectionWithBreakGenerator.generate(context, connection, writer); assertEquals("AB" + LINE_SEPARATOR + "CD" + LINE_SEPARATOR + "A1B1" + LINE_SEPARATOR + "C1D1" + LINE_SEPARATOR + "A1B3" + LINE_SEPARATOR + "C2D2" + LINE_SEPARATOR, result.toString()); } public void test_generate_withOneBreakForTwoLines() throws Exception { DefaultFileSectionGenerator sectionWithBreakGenerator = initFileGenerator(false, false); sectionWithBreakGenerator.setColumnSeparator("-"); sectionWithBreakGenerator.generate(context, connection, writer); assertEquals("A-B" + LINE_SEPARATOR + "C-D" + LINE_SEPARATOR + "A1-B1" + LINE_SEPARATOR + "C1-D1" + LINE_SEPARATOR + "C2-D2" + LINE_SEPARATOR, result.toString()); } private DefaultFileSectionGenerator initFileGenerator(boolean isFirstBreakColumnChange, boolean isSecondBreakColumnChange) { columnA = new FakeColumnGenerator("A", true, isFirstBreakColumnChange); columnB = new FakeColumnGenerator("B", true, isSecondBreakColumnChange); FakeColumnGenerator columnC = new FakeColumnGenerator("C", false, true); FakeColumnGenerator columnD = new FakeColumnGenerator("D", false, true); DefaultFileSectionGenerator sectionWithBreakGenerator = new DefaultFileSectionGenerator(preference, "TU with break field", selector, computedField, queryBuilder, new FileColumnGenerator[]{ columnA, columnB, columnC, columnD}); sectionWithBreakGenerator.setColumnHeader(true); return sectionWithBreakGenerator; } @Override protected void setUp() throws SQLException { logger = new LogString(); preference = new PreferencesForTesting("$" + DB_APPLICATION_USER_VARIABLE + "$."); columnA = new FakeColumnGenerator("A", false, true); columnB = new FakeColumnGenerator("B", false, true); selector = new PreferencesForTesting.FakeSelector(); queryBuilder = new FakeQueryBuilder(preference); computedField = new FakeComputedField(logger); sectionGenerator = createFileSectionGenerator(true); context = new Context(); context.setComputedTableWasCreated(true); addVariables(context); fakeResultSetWith2Rows(); connection = FakeDriver.getDriver().connect("jdbc:fakeDriver", null); } private DefaultFileSectionGenerator createFileSectionGenerator(boolean atLeastOneComputedField) { String sectionName = "section pour TU"; FileColumnGenerator[] columns; if (atLeastOneComputedField) { columns = new FileColumnGenerator[]{columnA, columnB}; } else { columns = new FileColumnGenerator[0]; } return new DefaultFileSectionGenerator(preference, sectionName, selector, computedField, queryBuilder, columns); } private void addVariables(Context context) { context.putParameter(DB_APPLICATION_USER_VARIABLE, DB_APPLICATION_USER); } private void fakeResultSetWith2Rows() throws SQLException { fakeResultSetWith2RowsAndWarnings(true); } private void fakeResultSetWith2RowsAndWarnings(boolean selectWarnings, String... warnings) throws SQLException { // Note : push resultsets in reverse order of execution Object[][] rs = {{"A", "B"}, {"ligne 1"}, {"ligne 2"}}; FakeDriver.getDriver().pushResultSet(rs, "select * from APP_USER.COLUMNS_LIST"); if (selectWarnings) { String sql = "select WARNINGS from $dbApplicationUser$.COMPUTED"; sql = context.replaceVariables(sql); Object[][] rs2 = new Object[1 + warnings.length][]; rs2[0] = new Object[]{ComputedField.WARNINGS}; int i = 1; for (String warning : warnings) { rs2[i] = new Object[]{warning}; i++; } FakeDriver.getDriver().pushResultSet(rs2, sql); } } public static final class FakeColumnGenerator implements FileColumnGenerator { int calledNumber = 0; String value; boolean isBreakField; boolean isValueChange; /** * Constructeur de FakeColumnGenerator * * @param value Description of the Parameter */ FakeColumnGenerator(String value, boolean isBreakField, boolean isValueChange) { this.value = value; this.isBreakField = isBreakField; this.isValueChange = isValueChange; } public String buildColumnHeader() { return value; } public String proceedField(ResultSet rs) throws SQLException { if (isValueChange) { calledNumber++; } else { calledNumber = 1; } return value + calledNumber; } public FieldInfo getFieldInfo() { return new FieldInfo(new TableName("TABLE"), value, 0); } public boolean isBreakField() { return isBreakField; } } private static final class FakeComputedField implements ComputedFieldGenerator { private LogString logger; FakeComputedField(LogString logger) { this.logger = logger; } public void createComputedTable(Context ctxt, FileColumnGenerator[] fileColumnGenerator, Connection con) { logger.call("createComputedTable"); } public void fillComputedTable(Context ctxt, Connection con) throws SQLException { logger.call("fillComputedTable"); } } private static final class FakeQueryBuilder implements QueryBuilder { boolean hasBeenCalled = false; Preferences preference; FakeQueryBuilder(Preferences preference) { this.preference = preference; } public String buildQuery(FileColumnGenerator[] columns) { hasBeenCalled = true; return "select * from " + preference.getSelectionTableName(); } } }