Package org.pentaho.reporting.engine.classic.core.function

Source Code of org.pentaho.reporting.engine.classic.core.function.TotalPageFunctionsTest

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.function;

import java.awt.Color;
import java.util.List;
import javax.swing.table.TableModel;

import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.SimplePageDefinition;
import org.pentaho.reporting.engine.classic.core.TableDataFactory;
import org.pentaho.reporting.engine.classic.core.designtime.DesignTimeDataSchemaModel;
import org.pentaho.reporting.engine.classic.core.filter.types.TextFieldType;
import org.pentaho.reporting.engine.classic.core.filter.types.bands.GroupFooterType;
import org.pentaho.reporting.engine.classic.core.filter.types.bands.GroupHeaderType;
import org.pentaho.reporting.engine.classic.core.filter.types.bands.ItemBandType;
import org.pentaho.reporting.engine.classic.core.layout.ModelPrinter;
import org.pentaho.reporting.engine.classic.core.layout.model.LogicalPageBox;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderNode;
import org.pentaho.reporting.engine.classic.core.testsupport.DebugReportRunner;
import org.pentaho.reporting.engine.classic.core.testsupport.RelationalReportBuilder;
import org.pentaho.reporting.engine.classic.core.testsupport.selector.AndMatcher;
import org.pentaho.reporting.engine.classic.core.testsupport.selector.AttributeMatcher;
import org.pentaho.reporting.engine.classic.core.testsupport.selector.ElementTypeMatcher;
import org.pentaho.reporting.engine.classic.core.testsupport.selector.MatchFactory;
import org.pentaho.reporting.engine.classic.core.util.PageSize;
import org.pentaho.reporting.engine.classic.core.util.TypedTableModel;
import org.pentaho.reporting.libraries.base.util.DebugLog;


/**
* Tests the TotalPage* functions:
* <code>TotalPageSumFunction</code> and
* <code>TotalPageItemCountFunction</code>
*
* @noinspection HardCodedStringLiteral
*/
public class TotalPageFunctionsTest extends TestCase
{

  public static final String ROW_DIMENSION_A = "Row-Dimension-A";
  public static final String ROW_DIMENSION_B = "Row-Dimension-B";
  public static final String COLUMN_DIMENSION_A = "Column-Dimension-A";
  public static final String COLUMN_DIMENSION_B = "Column-Dimension-B";
  public static final String VALUE = "Value";

  public static final Color VALUE_BACKGROUND = new Color(178, 178, 255);
  public static final Color ROWA_BACKGROUND = new Color(255, 178, 255);
  public static final Color ROWA_VALIDATE_BACKGROUND = new Color(255, 208, 255);
  public static final Color ROWB_BACKGROUND = new Color(178, 255, 255);
  public static final Color ROWB_VALIDATE_BACKGROUND = new Color(208, 255, 255);

  public static final Color ROWC_BACKGROUND = new Color(178, 178, 208);
  public static final Color ROWC_VALIDATE_BACKGROUND = new Color(178, 208, 178);


  public TotalPageFunctionsTest()
  {
  }

  protected void setUp() throws Exception
  {
    ClassicEngineBoot.getInstance().start();
  }

  private TableModel createRelationalTableModel()
  {
    final TypedTableModel model = new TypedTableModel();
    model.addColumn(ROW_DIMENSION_A, String.class);
    model.addColumn(ROW_DIMENSION_B, String.class);
    model.addColumn(VALUE, String.class);
    model.addColumn("validate-row-b-sum", Integer.class);
    model.addColumn("validate-row-a-sum", Integer.class);
    model.addColumn("validate-no-group", Integer.class);

    model.addRow("RA", "r1", 1, 1, 5, 5);
    model.addRow("RA", "r2", 1, 1, 5, 5);
    model.addRow("RA", "r1", 1, 3, 5, 5);
    model.addRow("RA", "r1", 1, 3, 5, 5);
    model.addRow("RA", "r1", 1, 3, 5, 5);   // page break
    model.addRow("RA", "r2", 1, 3, 3, 7);
    model.addRow("RA", "r2", 1, 3, 3, 7);
    model.addRow("RA", "r2", 1, 3, 3, 7);
    model.addRow("RB", "r1", 1, 4, 4, 7);
    model.addRow("RB", "r1", 1, 4, 4, 7);
    model.addRow("RB", "r1", 1, 4, 4, 7);
    model.addRow("RB", "r1", 1, 4, 4, 7)// page break
    model.addRow("RB", "r1", 1, 1, 8, 8);
    model.addRow("RB", "r2", 1, 7, 8, 8);
    model.addRow("RB", "r2", 1, 7, 8, 8);
    model.addRow("RB", "r2", 1, 7, 8, 8);
    model.addRow("RB", "r2", 1, 7, 8, 8);
    model.addRow("RB", "r2", 1, 7, 8, 8);
    model.addRow("RB", "r2", 1, 7, 8, 8);
    model.addRow("RB", "r2", 1, 7, 8, 8);
    return model;
  }

  private AggregationFunction create(final String name,
                                     final String group,
                                     final Class aggFunction)
  {
    AggregationFunction detailsSum = null;

    if (aggFunction.equals(TotalPageItemCountFunction.class))
    {
      detailsSum = new TotalPageItemCountFunction();
    }
    else if (aggFunction.equals(TotalPageSumFunction.class))
    {
      detailsSum = new TotalPageSumFunction();
      ((TotalPageSumFunction)detailsSum).setField(VALUE);
    }

    detailsSum.setName(name);
    detailsSum.setGroup(group);
    detailsSum.setDependencyLevel(1);

    return detailsSum;
  }


  public void testTotalPageItemCountRelational() throws Exception
  {
    // http://jira.pentaho.com/browse/PRD-4216
    validateRelationalReport(TotalPageItemCountFunction.class);
  }

  /**
   * The VALUE field is defined with a '1' for each row in the model,
   * so it's possible to use the same expected values for both the
   * PageItemCount and PageSum functions.
   * @throws Exception
   */
  public void testTotalPageSumRelational() throws Exception
  {
    // http://jira.pentaho.com/browse/PRD-4217
    validateRelationalReport(TotalPageSumFunction.class);
  }

  private void validateRelationalReport(final Class aggFun) throws Exception
  {
    final TableModel tableModel = createRelationalTableModel();
    final MasterReport report = createRelationalReport(tableModel, aggFun);

    // Null means the result is undefined.
    final Integer[][] rowAHeaderValues = {
        {5, 5, 5, 5, 5}, // page 0
        {3, 3, 4, 4},         // page 1
        {8, 8, 8}           // page 2
    };
    final Integer[][] rowBHeaderValues = {
        {null, 1, 1, 3, 0}, // page 0
        {null, 3, null, 4},         // page 1
        {1, 1, 7}           // page 2
    };
    final Integer[][] noGrpHeaderValues = {
        {5, 5, 5, 5, 5}, // page 0
        {7 ,7 ,7 ,7},         // page 1
        {8, 8, 8}           // page 2
    };
    final Integer[][] rowAFooterValues = {
        {5, 5, 5, 5, 5}, // page 0
        {3, 3, 4, 4},         // page 1
        {8, 8, 8}           // page 2
    };
    final Integer[][] rowBFooterValues = {
        {1, 1, 3, 0, 0}, // page 0
        {3, null, 4, null},         // page 1
        {1, 7, null}           // page 2
    };
    final Integer[][] noGrpFooterValues = {
        {5, 5, 5, 5, 5}, // page 0
        {7 ,7 ,7 ,7},         // page 1
        {8, 8, 8}           // page 2
    };

    report.addExpression(create("row-b-sum", "::group-1", aggFun));
    report.addExpression(new ValidatePageFunctionResultExpression("#row-b-sum", null));

    report.addExpression(create("row-a-sum", "::group-0", aggFun));
    report.addExpression(new ValidatePageFunctionResultExpression("#row-a-sum", null));

    report.addExpression(create("no-group", null, aggFun));
    report.addExpression(new ValidatePageFunctionResultExpression("#no-group", null));

    DebugReportRunner.showDialog(report);

    List<LogicalPageBox> logicalPageBoxes = DebugReportRunner.layoutPages(report, 0, 1, 2);

    for (int page = 0; page < 3; page += 1)
    {
      final LogicalPageBox logicalPageBox = logicalPageBoxes.get(page);
      validateItemBands(logicalPageBox);
      validateHeader(rowAHeaderValues[page], rowBHeaderValues[page], noGrpHeaderValues[page], page, logicalPageBox);
      validateFooter(rowAFooterValues[page], rowBFooterValues[page], noGrpHeaderValues[page], page, logicalPageBox);
    }


    // DebugReportRunner.execGraphics2D(report);
  }

  /**
   * Compares the header by their order of occurrence on the page. Each footer has text-fields which
   * carry their currently calculated value in their attributes. (This is done by a CopyValueAsTextExpression,
   * which is set up by the RelationalReportBuilder.)
   *
   * Each test maintains a human-provided list of expected values per page.
   *
   * @param rowAHeaderValue
   * @param rowBHeaderValue
   * @param noGrpValue
   * @param page
   * @param logicalPageBox
   */
  private void validateHeader(final Integer[] rowAHeaderValue,
                              final Integer[] rowBHeaderValue,
                              final Integer[] noGrpValue, final int page,
                              final LogicalPageBox logicalPageBox)
  {
    final RenderNode[] groupHeaders =
        MatchFactory.findElementsByElementType(logicalPageBox, GroupHeaderType.INSTANCE);
    for (int i = 0; i < groupHeaders.length; i++)
    {
      final RenderNode groupHeader = groupHeaders[i];
      final RenderNode rowASum = findTextFieldsWithField("row-a-sum", groupHeader);
      final RenderNode rowBSum = findTextFieldsWithField("row-b-sum", groupHeader);
      final RenderNode noGrp = findTextFieldsWithField("no-group", groupHeader);

      final Integer expectedA = rowAHeaderValue[i];
      final Object valueA = rowASum.getAttributes().getAttribute("test-run", "test-value");

      final Integer expectedB = rowBHeaderValue[i];
      final Object valueB = rowBSum.getAttributes().getAttribute("test-run", "test-value");

      final Integer expectedC = noGrpValue[i];
      final Object valueC = noGrp.getAttributes().getAttribute("test-run", "test-value");

      try
      {
        if (expectedA != null)
        {
          assertEquals("Row-A", String.valueOf(expectedA), valueA);
        }
        if (expectedB != null)
        {
          assertEquals("Row-B", String.valueOf(expectedB), valueB);
        }
        if (expectedC != null)
        {
          assertEquals("No group", String.valueOf(expectedC), valueC);
        }
      }
      catch (AssertionFailedError afe)
      {
        DebugLog.log("Failed on page " + page);
        ModelPrinter.INSTANCE.print(groupHeader);
        throw afe;
      }
    }
  }

  /**
   * Compares the footer by their order of occurrence on the page. Each footer has text-fields which
   * carry their currently calculated value in their attributes. (This is done by a CopyValueAsTextExpression,
   * which is set up by the RelationalReportBuilder.)
   *
   * Each test maintains a human-provided list of expected values per page.
   *
   * @param rowAHeaderValue
   * @param rowBHeaderValue
   * @param noGrpValue
   * @param page
   * @param logicalPageBox
   */
  private void validateFooter(final Integer[] rowAHeaderValue,
                              final Integer[] rowBHeaderValue,
                              final Integer[] noGrpValue, final int page,
                              final LogicalPageBox logicalPageBox)
  {
    final RenderNode[] groupFooters =
        MatchFactory.findElementsByElementType(logicalPageBox, GroupFooterType.INSTANCE);
    for (int i = 0; i < groupFooters.length; i++)
    {
      final RenderNode groupFooter = groupFooters[i];
      final RenderNode rowASum = findTextFieldsWithField("row-a-sum", groupFooter);
      final RenderNode rowBSum = findTextFieldsWithField("row-b-sum", groupFooter);
      final RenderNode noGrp = findTextFieldsWithField("no-group", groupFooter);

      final Integer expectedA = rowAHeaderValue[i];
      final Object valueA = rowASum.getAttributes().getAttribute("test-run", "test-value");

      final Integer expectedB = rowBHeaderValue[i];
      final Object valueB = rowBSum.getAttributes().getAttribute("test-run", "test-value");

      final Integer expectedC = noGrpValue[i];
      final Object valueC = noGrp.getAttributes().getAttribute("test-run", "test-value");


      try
      {
        if (expectedA != null)
        {
          assertEquals("Row-A", String.valueOf(expectedA), valueA);
        }
        if (expectedB != null)
        {
          assertEquals("Row-B", String.valueOf(expectedB), valueB);
        }
        if (expectedC != null)
        {
          assertEquals("No group", String.valueOf(expectedC), valueC);
        }
      }
      catch (AssertionFailedError afe)
      {
        DebugLog.log("Failed on page " + page);
        ModelPrinter.INSTANCE.print(groupFooter);
        throw afe;
      }
    }
  }

  /**
   * Compares the expression result directly with the result of the validation expression as found in the
   * detail band. For all Total*Page functions, this should always match.
   *
   * @param logicalPageBox
   */
  private void validateItemBands(final LogicalPageBox logicalPageBox)
  {
    final RenderNode[] itemBands = MatchFactory.findElementsByElementType(logicalPageBox, ItemBandType.INSTANCE);
    for (int i = 0; i < itemBands.length; i++)
    {
      final RenderNode itemBand = itemBands[i];
      final RenderNode rowASum = findTextFieldsWithField("row-a-sum", itemBand);
      final RenderNode rowBSum = findTextFieldsWithField("row-b-sum", itemBand);
      final RenderNode noGrp = findTextFieldsWithField("no-group", itemBand);
      final RenderNode rowAValidate = findTextFieldsWithField("#row-a-sum", itemBand);
      final RenderNode rowBValidate = findTextFieldsWithField("#row-b-sum", itemBand);
      final RenderNode noGrpValidate = findTextFieldsWithField("#no-group", itemBand);

      assertEquals(rowAValidate.getAttributes().getAttribute("test-run", "test-value"),
          rowASum.getAttributes().getAttribute("test-run", "test-value"));
      assertEquals(rowBValidate.getAttributes().getAttribute("test-run", "test-value"),
          rowBSum.getAttributes().getAttribute("test-run", "test-value"));
      assertEquals(noGrpValidate.getAttributes().getAttribute("test-run", "test-value"),
          noGrp.getAttributes().getAttribute("test-run", "test-value"));
    }
  }

  private RenderNode findTextFieldsWithField(String field, RenderNode itemBand)
  {
    final ElementTypeMatcher typeMatcher = new ElementTypeMatcher(TextFieldType.INSTANCE.getMetaData().getName());
    final AttributeMatcher attributeMatcher = new AttributeMatcher(AttributeNames.Core.NAMESPACE, AttributeNames.Core.FIELD, field);
    final AndMatcher m = new AndMatcher(typeMatcher, attributeMatcher);
    return MatchFactory.match(itemBand, m);
  }

  private MasterReport createRelationalReport(final TableModel tableModel, final Class aggFun)
  {
    final MasterReport report = new MasterReport();
    report.setPageDefinition(new SimplePageDefinition(new PageSize(800, 300)));
    report.setDataFactory(new TableDataFactory("query", tableModel));
    report.setQuery("query");

    final DesignTimeDataSchemaModel dataSchemaModel = new DesignTimeDataSchemaModel(report);
    final RelationalReportBuilder builder = new RelationalReportBuilder(dataSchemaModel);
    builder.addGroup(ROW_DIMENSION_A);
    builder.addGroup(ROW_DIMENSION_B);
    builder.addDetails(VALUE, aggFun, VALUE_BACKGROUND);
    builder.addDetails("row-a-sum", null, ROWA_BACKGROUND);
    builder.addDetails("#row-a-sum", null, ROWA_VALIDATE_BACKGROUND);
    builder.addDetails("row-b-sum", null, ROWB_BACKGROUND);
    builder.addDetails("#row-b-sum", null, ROWB_VALIDATE_BACKGROUND);
    builder.addDetails("no-group", null, ROWC_BACKGROUND);
    builder.addDetails("#no-group", null, ROWC_VALIDATE_BACKGROUND);


    report.setRootGroup(builder.create());


    return report;
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.function.TotalPageFunctionsTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.