org.jopendocument.dom.style.data.DataStyleTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jOpenDocument Show documentation
Show all versions of jOpenDocument Show documentation
jOpenDocument is a free library for developers looking to use
Open Document files without OpenOffice.org.
The newest version!
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008-2013 jOpenDocument, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU
* General Public License Version 3 only ("GPL").
* You may not use this file except in compliance with the License.
* You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
* See the License for the specific language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*
*/
package org.jopendocument.dom.style.data;
import org.jopendocument.dom.ODEpoch;
import org.jopendocument.dom.ODPackage;
import org.jopendocument.dom.ODValueType;
import org.jopendocument.dom.Style;
import org.jopendocument.dom.spreadsheet.CellStyle;
import org.jopendocument.dom.spreadsheet.MutableCell;
import org.jopendocument.dom.spreadsheet.Sheet;
import org.jopendocument.dom.spreadsheet.SpreadSheet;
import org.jopendocument.dom.style.data.DataStyle.DataStyleDesc;
import org.jopendocument.util.TimeUtils;
import java.awt.Color;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import javax.xml.datatype.Duration;
import junit.framework.TestCase;
import org.jdom.Element;
import org.jdom.Namespace;
public class DataStyleTest extends TestCase {
public void testDays() throws Exception {
final ODEpoch epoch = ODEpoch.getDefaultEpoch();
final Calendar cal = Calendar.getInstance();
// do we get the same number than OO
cal.clear();
cal.set(2011, 2, 27, 12, 0);
assertEquals(new BigDecimal("40629.5"), epoch.getDays(cal));
assertEquals(cal, epoch.getDate(epoch.getDays(cal)));
cal.clear();
cal.set(1909, 8, 4, 0, 0);
final BigDecimal days = BigDecimal.valueOf(3535);
assertEquals(cal, epoch.getDate(days));
assertEquals(days, epoch.getDays(cal));
// if we pass different Calendar (these aren't even in the same day),
final Calendar gmtMinus12 = epoch.getDate(days, Calendar.getInstance(TimeZone.getTimeZone("GMT-12:00")));
final Calendar gmtPlus13 = epoch.getDate(days, Calendar.getInstance(TimeZone.getTimeZone("GMT+13:00")));
// we get different times,
assertFalse(gmtMinus12.getTimeInMillis() == gmtPlus13.getTimeInMillis());
// but they have the same local time
assertTrue(TimeUtils.normalizeLocalTime(gmtMinus12) == TimeUtils.normalizeLocalTime(gmtPlus13));
assertTrue(TimeUtils.normalizeLocalTime(cal) == TimeUtils.normalizeLocalTime(gmtPlus13));
// test before epoch (DST didn't exist)
for (int i = -10; i < 500; i++) {
final BigDecimal bd = BigDecimal.valueOf(i);
assertEquals(bd, epoch.getDays(epoch.getDate(bd)));
}
final Calendar franceCal = Calendar.getInstance(Locale.FRANCE);
// test winter and summer
// DST is at two
franceCal.set(Calendar.HOUR_OF_DAY, 2);
franceCal.set(Calendar.MINUTE, 30);
for (int i = 0; i < 500; i++) {
final BigDecimal bd = epoch.getDays(franceCal);
assertEquals(franceCal, epoch.getDate(bd));
franceCal.add(Calendar.DAY_OF_YEAR, -1);
}
}
public void testFormat() throws Exception {
final ODPackage pkg = new ODPackage(this.getClass().getResourceAsStream("cellFormat.ods"));
final Sheet sheet = pkg.getSpreadSheet().getSheet(0);
// * test that the framework format as OpenOffice
final int lastRow = sheet.getCurrentRegion(0, 0).getEndPoint().y;
for (int i = 0; i <= lastRow; i++) {
final MutableCell cell = sheet.getCellAt(0, i);
final String byOO = cell.getTextValue();
final ODValueType origType = cell.getValueType();
final Object cellValue = cell.getValue();
// like OO, we should allow any value without removing the data style
cell.setValue("string");
cell.setValue(12.3);
cell.setValue(new Date());
cell.setValue(true);
cell.clearValue();
if (origType != null)
cell.setValue(cellValue, origType, false, false);
assertEquals(byOO, cell.getTextValue());
assertEquals(origType, cell.getValueType());
}
// test DEFAULT_DECIMAL_PLACES
{
assertNull(Style.getStyleStyleDesc(CellStyle.class, pkg.getVersion()).getDefaultStyle(pkg, true).getTableCellProperties(null).getRawDecimalPlaces());
final MutableCell a3 = sheet.getCellAt("A3");
final String officeVal = a3.getTextValue();
assertEquals("0," + "33333333333333333333333333333".substring(0, DataStyle.DEFAULT_DECIMAL_PLACES), officeVal);
// we format the same than LibreOffice
a3.setValue(a3.getValue());
assertEquals(officeVal, a3.getTextValue());
}
// test that the new value is used to find the data style
final MutableCell a16 = sheet.getCellAt("A17");
// >=1 with 2 decimal digits
assertEquals(12.34321d, ((Number) a16.getValue()).doubleValue());
assertEquals("12,34", a16.getTextValue());
// <0 without decimal part
a16.setValue(-12.34321d);
assertEquals(-12.34321d, ((Number) a16.getValue()).doubleValue());
assertEquals("-12", a16.getTextValue());
// in between standard format (with optional decimal digits)
a16.setValue(0.34321d);
assertEquals("0,34321", a16.getTextValue());
// test boolean conversion
{
// type not changed, thus "false"
a16.setValue(Boolean.FALSE, false);
assertEquals(ODValueType.BOOLEAN, a16.getValueType());
assertEquals(Boolean.FALSE, a16.getValue());
assertEquals(BooleanStyle.toString(false, Locale.getDefault(), true), a16.getTextValue());
// now allow type change
a16.setValue(Boolean.FALSE, true);
assertEquals(ODValueType.FLOAT, a16.getValueType());
assertEquals(0, ((Number) a16.getValue()).intValue());
// 0 use standard format
assertEquals("0", a16.getTextValue());
a16.setValue(Boolean.TRUE, true);
assertEquals(ODValueType.FLOAT, a16.getValueType());
assertEquals(1, ((Number) a16.getValue()).intValue());
assertEquals("1,00", a16.getTextValue());
final MutableCell a17 = sheet.getCellAt("A18");
// type not changed, thus "17"
a17.setValue(17, false);
assertEquals(ODValueType.FLOAT, a17.getValueType());
assertEquals(BigDecimal.valueOf(17), a17.getValue());
assertEquals("17", a17.getTextValue());
// now allow type change
a17.setValue(17, true);
assertEquals(ODValueType.BOOLEAN, a17.getValueType());
assertTrue((Boolean) a17.getValue());
assertEquals("VERDADEIRO", a17.getTextValue());
}
// test date conversion
{
// duration
a16.setValue(TimeUtils.getTypeFactory().newDuration(true, 0, 0, 1, 36, 0, 0), false);
assertEquals(ODValueType.TIME, a16.getValueType());
assertEquals(36, ((Duration) a16.getValue()).getHours());
assertEquals("60:00:00", a16.getTextValue());
a16.setValue(TimeUtils.getTypeFactory().newDuration(true, 0, 0, 0, 36, 0, 0), true);
assertEquals(ODValueType.FLOAT, a16.getValueType());
assertEquals(1.5d, ((Number) a16.getValue()).doubleValue());
assertEquals("1,50", a16.getTextValue());
a16.setValue(TimeUtils.getTypeFactory().newDuration(true, 0, 0, 180, 2, 24, 0), true);
assertEquals(ODValueType.FLOAT, a16.getValueType());
assertEquals(180.1d, ((Number) a16.getValue()).doubleValue());
assertEquals("180,10", a16.getTextValue());
// calendar
final Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(2011, 8, 25, 12, 0);
a16.setValue(cal, true);
assertEquals(ODValueType.FLOAT, a16.getValueType());
assertEquals(new BigDecimal("40811.5"), a16.getValue());
assertEquals("40811,50", a16.getTextValue());
}
// like OO, we should retain the data style, even if we set an incompatible value
final MutableCell a1 = sheet.getCellAt("A1");
assertEquals(ODValueType.FLOAT, a1.getValueType());
assertTrue(a1.getDataStyle() instanceof NumberStyle);
a1.setValue("toto");
assertEquals("toto", a1.getValue());
assertEquals("toto", a1.getTextValue());
assertEquals(ODValueType.STRING, a1.getValueType());
assertTrue(a1.getDataStyle() instanceof NumberStyle);
a1.setValue(1.6);
// number style was retained
assertEquals("02", a1.getTextValue());
// should retain type when possible
final MutableCell a8 = sheet.getCellAt("A8");
assertEquals(ODValueType.PERCENTAGE, a8.getValueType());
a8.setValue(0.35d);
assertEquals(new BigDecimal("0.35"), a8.getValue());
assertEquals(ODValueType.PERCENTAGE, a8.getValueType());
a8.setValue(new Date(), false);
assertEquals(ODValueType.DATE, a8.getValueType());
// this used to fail since the conversion for condition evaluation was confused with the
// conversion for data style
final MutableCell a12 = sheet.getCellAt("A12");
assertEquals(ODValueType.DATE, a12.getValueType());
a12.setValue(40000, true);
assertEquals(ODValueType.DATE, a12.getValueType());
assertEquals(sheet.getODDocument().getEpoch().getDate(BigDecimal.valueOf(40000)).getTime(), a12.getValue());
a12.setValue(new Date());
assertEquals(ODValueType.DATE, a12.getValueType());
// test non-lenient
a1.setValue(Boolean.TRUE, ODValueType.BOOLEAN, false, false);
assertEquals(Boolean.TRUE, a1.getValue());
assertEquals(ODValueType.BOOLEAN, a1.getValueType());
// the language is used even if the data style is not compatible
assertFalse(a1.getDataStyle() instanceof BooleanStyle);
assertEquals("WAHR", a1.getTextValue());
final MutableCell b1 = sheet.getCellAt("B1");
b1.setValue(0.0912645d, ODValueType.PERCENTAGE, false, false);
assertEquals(new BigDecimal("0.0912645"), b1.getValue());
assertEquals(0.0912645d, ((Number) b1.getValue()).doubleValue());
assertEquals(ODValueType.PERCENTAGE, b1.getValueType());
// test type inference
final Date now = new Date();
b1.setValue(now);
assertEquals(now, b1.getValue());
assertEquals(ODValueType.DATE, b1.getValueType());
// test embedded-text
{
final DataStyleDesc desc = DataStyle.getDesc(NumberStyle.class, sheet.getODDocument().getVersion());
final Namespace numberNS = desc.getElementNS();
// create data style
final NumberStyle numberStyle = desc.createAutoStyle(pkg, "embedded-text test");
final Element number = new Element("number", numberNS);
// LO needs both attributes
number.setAttribute("min-integer-digits", "3", numberNS);
number.setAttribute("decimal-places", "4", numberNS);
number.addContent(new Element("embedded-text", numberNS).setAttribute("position", "2", numberNS).setText("inTxt"));
// should prepend if greater than digit count
number.addContent(new Element("embedded-text", numberNS).setAttribute("position", "9", numberNS).setText("other"));
numberStyle.getElement().addContent(number);
sheet.ensureRowCount(19);
final MutableCell a19 = sheet.getCellAt(0, 18);
a19.getPrivateStyle().getElement().setAttribute("data-style-name", numberStyle.getName(), pkg.getVersion().getSTYLE());
sheet.setValueAt("embbeded-text test", a19.getX() + 1, a19.getY());
a19.setValue(53.1);
assertEquals("other0inTxt53,1000", a19.getTextValue());
number.removeContent();
a19.setValue(42.19);
assertEquals("042,1900", a19.getTextValue());
}
// test condition
final MutableCell neg = sheet.getCellAt("A11");
final MutableCell pos = sheet.getCellAt("C11");
// both have the same cell style
assertEquals(neg.getStyleName(), pos.getStyleName());
// but their data style differ
final DataStyle negDataStyle = neg.getDataStyle();
final DataStyle posDataStyle = pos.getDataStyle();
assertFalse(negDataStyle.getName().equals(posDataStyle.getName()));
assertEquals(Color.RED, negDataStyle.getTextProperties().getColor());
assertEquals(Color.BLACK, posDataStyle.getTextProperties().getColor());
}
}