diff --git a/script/coverage_metrics.py b/script/coverage_metrics.py index e9df8ab7..21d7b9b5 100755 --- a/script/coverage_metrics.py +++ b/script/coverage_metrics.py @@ -225,15 +225,17 @@ def emit_github_output( the original combined number for continuity if anyone wants it. """ pairs = [ + # Non-GUI headline: integer precision keeps badge text stable. ("line_cov", non_gui.line.percent_int()), ("branch_cov", non_gui.branch.percent_int()), ("method_cov", non_gui.method.percent_int()), - ("gui_line_cov", gui.line.percent_int()), - ("gui_branch_cov", gui.branch.percent_int()), - ("gui_method_cov", gui.method.percent_int()), - ("all_line_cov", total.line.percent_int()), - ("all_branch_cov", total.branch.percent_int()), - ("all_method_cov", total.method.percent_int()), + # GUI and combined: one-decimal so small test additions are visible. + ("gui_line_cov", gui.line.percent()), + ("gui_branch_cov", gui.branch.percent()), + ("gui_method_cov", gui.method.percent()), + ("all_line_cov", total.line.percent()), + ("all_branch_cov", total.branch.percent()), + ("all_method_cov", total.method.percent()), ("non_gui_lines_total", str(non_gui.line.total)), ("gui_lines_total", str(gui.line.total)), ("all_lines_total", str(total.line.total)), diff --git a/test/AllTests.java b/test/AllTests.java index e1da5fbb..b73d6e77 100644 --- a/test/AllTests.java +++ b/test/AllTests.java @@ -60,7 +60,10 @@ import org.aavso.tools.vstar.ui.dialog.DateToJdDialogTest; import org.aavso.tools.vstar.ui.dialog.DoubleFieldTest; import org.aavso.tools.vstar.ui.dialog.TextDialogTest; +import org.aavso.tools.vstar.ui.model.list.AbstractSyntheticObservationTableModelTest; +import org.aavso.tools.vstar.ui.model.list.PeriodAnalysisDataTableModelTest; import org.aavso.tools.vstar.ui.model.list.ValidObservationTableModelTest; +import org.aavso.tools.vstar.ui.model.list.WWZDataTableModelTest; import org.aavso.tools.vstar.ui.pane.list.VisibleSeriesRowFilterTest; import org.aavso.tools.vstar.vela.VeLaTest; @@ -125,6 +128,9 @@ public static Test suite() { // GUI-coverage tests (issue #579, prong C). suite.addTestSuite(ValidObservationTableModelTest.class); + suite.addTestSuite(PeriodAnalysisDataTableModelTest.class); + suite.addTestSuite(WWZDataTableModelTest.class); + suite.addTestSuite(AbstractSyntheticObservationTableModelTest.class); suite.addTestSuite(VisibleSeriesRowFilterTest.class); suite.addTestSuite(DateToJdDialogTest.class); suite.addTestSuite(TextDialogTest.class); diff --git a/test/org/aavso/tools/vstar/ui/model/list/AbstractSyntheticObservationTableModelTest.java b/test/org/aavso/tools/vstar/ui/model/list/AbstractSyntheticObservationTableModelTest.java new file mode 100644 index 00000000..a7ca5624 --- /dev/null +++ b/test/org/aavso/tools/vstar/ui/model/list/AbstractSyntheticObservationTableModelTest.java @@ -0,0 +1,322 @@ +/** + * VStar: a statistical analysis tool for variable star data. + * Copyright (C) 2009 AAVSO (http://www.aavso.org/) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.aavso.tools.vstar.ui.model.list; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +import org.aavso.tools.vstar.data.DateInfo; +import org.aavso.tools.vstar.data.Magnitude; +import org.aavso.tools.vstar.data.SeriesType; +import org.aavso.tools.vstar.data.ValidObservation; +import org.aavso.tools.vstar.util.prefs.NumericPrecisionPrefs; +import org.aavso.tools.vstar.util.stats.BinningResult; + +import junit.framework.TestCase; + +// Uses SeriesType.Visual as an arbitrary series for BinningResult construction. + +/** + * Tests for the four concrete subclasses of + * {@link AbstractSyntheticObservationTableModel}: + * + * + * These exercise the abstract base-class machinery (observation storage, + * row-index mapping, reverse lookup) through real production classes + * rather than an artificial stub. + * + * Part of issue #579 (GUI code coverage). + */ +public class AbstractSyntheticObservationTableModelTest extends TestCase { + + private ValidObservation ob1; + private ValidObservation ob2; + private List observations; + + @Override + protected void setUp() { + Locale.setDefault(Locale.ENGLISH); + + ob1 = new ValidObservation(); + ob1.setDateInfo(new DateInfo(2451545.0)); + ob1.setMagnitude(new Magnitude(5.5, 0.01)); + ob1.setStandardPhase(0.25); + + ob2 = new ValidObservation(); + ob2.setDateInfo(new DateInfo(2451546.0)); + ob2.setMagnitude(new Magnitude(6.0, 0.02)); + ob2.setStandardPhase(0.75); + + observations = new ArrayList<>(Arrays.asList(ob1, ob2)); + } + + // ----------------------------------------------------------- + // RawDataMeanObservationTableModel + // ----------------------------------------------------------- + + public void testRawMeanColumnCount() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + assertEquals(4, m.getColumnCount()); + } + + public void testRawMeanRowCount() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + assertEquals(2, m.getRowCount()); + } + + public void testRawMeanColumnNames() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + assertEquals("Julian Day", m.getColumnName(0)); + assertEquals("Calendar Date", m.getColumnName(1)); + assertEquals("Mean Magnitude", m.getColumnName(2)); + assertEquals("Standard Error of the Average", m.getColumnName(3)); + } + + public void testRawMeanColumnClasses() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + for (int col = 0; col < 4; col++) { + assertEquals(String.class, m.getColumnClass(col)); + } + } + + public void testRawMeanGetValueAtJD() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + String expected = NumericPrecisionPrefs.formatTime(2451545.0); + assertEquals(expected, m.getValueAt(0, 0)); + } + + public void testRawMeanGetValueAtMagnitude() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + String expected = NumericPrecisionPrefs.formatMag(5.5); + assertEquals(expected, m.getValueAt(0, 2)); + } + + public void testRawMeanGetValueAtStdErr() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + String expected = NumericPrecisionPrefs.formatMag(0.01); + assertEquals(expected, m.getValueAt(0, 3)); + } + + // ----------------------------------------------------------- + // PhasePlotMeanObservationTableModel + // ----------------------------------------------------------- + + public void testPhaseMeanColumnCount() { + PhasePlotMeanObservationTableModel m = + new PhasePlotMeanObservationTableModel(observations); + assertEquals(3, m.getColumnCount()); + } + + public void testPhaseMeanRowCount() { + PhasePlotMeanObservationTableModel m = + new PhasePlotMeanObservationTableModel(observations); + assertEquals(2, m.getRowCount()); + } + + public void testPhaseMeanColumnNames() { + PhasePlotMeanObservationTableModel m = + new PhasePlotMeanObservationTableModel(observations); + assertEquals("Phase", m.getColumnName(0)); + assertEquals("Mean Magnitude", m.getColumnName(1)); + assertEquals("Standard Error of the Average", m.getColumnName(2)); + } + + public void testPhaseMeanGetValueAtPhase() { + PhasePlotMeanObservationTableModel m = + new PhasePlotMeanObservationTableModel(observations); + String expected = NumericPrecisionPrefs.formatTime(0.25); + assertEquals(expected, m.getValueAt(0, 0)); + } + + public void testPhaseMeanGetValueAtMag() { + PhasePlotMeanObservationTableModel m = + new PhasePlotMeanObservationTableModel(observations); + String expected = NumericPrecisionPrefs.formatMag(5.5); + assertEquals(expected, m.getValueAt(0, 1)); + } + + // ----------------------------------------------------------- + // RawDataModelObservationTableModel + // ----------------------------------------------------------- + + public void testRawModelColumnCount() { + RawDataModelObservationTableModel m = + new RawDataModelObservationTableModel(observations, + SeriesType.Model); + assertEquals(3, m.getColumnCount()); + } + + public void testRawModelRowCount() { + RawDataModelObservationTableModel m = + new RawDataModelObservationTableModel(observations, + SeriesType.Model); + assertEquals(2, m.getRowCount()); + } + + public void testRawModelColumnNames() { + RawDataModelObservationTableModel m = + new RawDataModelObservationTableModel(observations, + SeriesType.Model); + assertEquals("Julian Day", m.getColumnName(0)); + assertEquals("Calendar Date", m.getColumnName(1)); + assertEquals("Magnitude", m.getColumnName(2)); + } + + public void testRawModelGetValueAtJD() { + RawDataModelObservationTableModel m = + new RawDataModelObservationTableModel(observations, + SeriesType.Model); + String expected = NumericPrecisionPrefs.formatTime(2451545.0); + assertEquals(expected, m.getValueAt(0, 0)); + } + + public void testRawModelGetValueAtMag() { + RawDataModelObservationTableModel m = + new RawDataModelObservationTableModel(observations, + SeriesType.Model); + String expected = NumericPrecisionPrefs.formatMag(5.5); + assertEquals(expected, m.getValueAt(0, 2)); + } + + public void testRawModelWithResidualsSeries() { + RawDataModelObservationTableModel m = + new RawDataModelObservationTableModel(observations, + SeriesType.Residuals); + assertEquals(2, m.getRowCount()); + } + + // ----------------------------------------------------------- + // PhasePlotModelObservationTableModel + // ----------------------------------------------------------- + + public void testPhaseModelColumnCount() { + PhasePlotModelObservationTableModel m = + new PhasePlotModelObservationTableModel(observations, + SeriesType.Model); + assertEquals(2, m.getColumnCount()); + } + + public void testPhaseModelRowCountIsDoubled() { + PhasePlotModelObservationTableModel m = + new PhasePlotModelObservationTableModel(observations, + SeriesType.Model); + assertEquals(4, m.getRowCount()); + } + + public void testPhaseModelColumnNames() { + PhasePlotModelObservationTableModel m = + new PhasePlotModelObservationTableModel(observations, + SeriesType.Model); + assertEquals("Phase", m.getColumnName(0)); + assertEquals("Magnitude", m.getColumnName(1)); + } + + public void testPhaseModelGetValueAtPhase() { + PhasePlotModelObservationTableModel m = + new PhasePlotModelObservationTableModel(observations, + SeriesType.Model); + String expected = NumericPrecisionPrefs.formatTime(0.25); + assertEquals(expected, m.getValueAt(0, 0)); + } + + public void testPhaseModelWrapsAroundForDoubledRows() { + PhasePlotModelObservationTableModel m = + new PhasePlotModelObservationTableModel(observations, + SeriesType.Model); + assertEquals(m.getValueAt(0, 0), m.getValueAt(2, 0)); + assertEquals(m.getValueAt(1, 0), m.getValueAt(3, 0)); + } + + // ----------------------------------------------------------- + // Base-class features via RawDataMeanObservationTableModel + // ----------------------------------------------------------- + + public void testGetObs() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + assertSame(ob1, m.getObs().get(0)); + assertSame(ob2, m.getObs().get(1)); + } + + public void testGetRowIndexFromObservation() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + assertEquals(Integer.valueOf(0), m.getRowIndexFromObservation(ob1)); + assertEquals(Integer.valueOf(1), m.getRowIndexFromObservation(ob2)); + } + + public void testGetRowIndexFromUnknownObservationReturnsNull() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + ValidObservation unknown = new ValidObservation(); + assertNull(m.getRowIndexFromObservation(unknown)); + } + + public void testEmptyModel() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(new ArrayList<>()); + assertEquals(0, m.getRowCount()); + assertTrue(m.getObs().isEmpty()); + } + + public void testMeanModelUpdateViaListener() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + assertEquals(2, m.getRowCount()); + + ValidObservation ob3 = new ValidObservation(); + ob3.setDateInfo(new DateInfo(2451547.0)); + ob3.setMagnitude(new Magnitude(7.0, 0.03)); + List newObs = Arrays.asList(ob3); + + BinningResult result = new BinningResult( + SeriesType.Visual, 1, newObs, null); + m.update(result); + + assertEquals(1, m.getRowCount()); + assertSame(ob3, m.getObs().get(0)); + assertEquals(Integer.valueOf(0), m.getRowIndexFromObservation(ob3)); + } + + public void testCanBeRemovedMean() { + RawDataMeanObservationTableModel m = + new RawDataMeanObservationTableModel(observations); + assertTrue(m.canBeRemoved()); + } + + public void testCanBeRemovedModel() { + RawDataModelObservationTableModel m = + new RawDataModelObservationTableModel(observations, + SeriesType.Model); + assertTrue(m.canBeRemoved()); + } +} diff --git a/test/org/aavso/tools/vstar/ui/model/list/PeriodAnalysisDataTableModelTest.java b/test/org/aavso/tools/vstar/ui/model/list/PeriodAnalysisDataTableModelTest.java new file mode 100644 index 00000000..c9d0921c --- /dev/null +++ b/test/org/aavso/tools/vstar/ui/model/list/PeriodAnalysisDataTableModelTest.java @@ -0,0 +1,139 @@ +/** + * VStar: a statistical analysis tool for variable star data. + * Copyright (C) 2009 AAVSO (http://www.aavso.org/) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.aavso.tools.vstar.ui.model.list; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.aavso.tools.vstar.util.period.PeriodAnalysisCoordinateType; +import org.aavso.tools.vstar.util.prefs.NumericPrecisionPrefs; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link PeriodAnalysisDataTableModel}. + * + * The model wraps period-analysis results (frequency, period, power, + * semi-amplitude columns) in an {@code AbstractTableModel}. No display + * or Mediator required — pure data logic. + * + * Part of issue #579 (GUI code coverage). + */ +public class PeriodAnalysisDataTableModelTest extends TestCase { + + private static final double FREQ = 0.123; + private static final double PERIOD = 1.0 / FREQ; + private static final double POWER = 42.7; + private static final double SEMI_AMP = 0.35; + + private PeriodAnalysisCoordinateType[] columnTypes; + private Map> data; + private PeriodAnalysisDataTableModel model; + + @Override + protected void setUp() { + Locale.setDefault(Locale.ENGLISH); + + columnTypes = new PeriodAnalysisCoordinateType[] { + PeriodAnalysisCoordinateType.FREQUENCY, + PeriodAnalysisCoordinateType.PERIOD, + PeriodAnalysisCoordinateType.POWER, + PeriodAnalysisCoordinateType.SEMI_AMPLITUDE + }; + + data = new LinkedHashMap<>(); + data.put(PeriodAnalysisCoordinateType.FREQUENCY, Arrays.asList(FREQ, 0.456)); + data.put(PeriodAnalysisCoordinateType.PERIOD, Arrays.asList(PERIOD, 1.0 / 0.456)); + data.put(PeriodAnalysisCoordinateType.POWER, Arrays.asList(POWER, 10.0)); + data.put(PeriodAnalysisCoordinateType.SEMI_AMPLITUDE, Arrays.asList(SEMI_AMP, 0.12)); + + model = new PeriodAnalysisDataTableModel(columnTypes, data); + } + + public void testColumnCount() { + assertEquals(4, model.getColumnCount()); + } + + public void testRowCount() { + assertEquals(2, model.getRowCount()); + } + + public void testColumnNames() { + assertEquals(PeriodAnalysisCoordinateType.FREQUENCY.getDescription(), + model.getColumnName(0)); + assertEquals(PeriodAnalysisCoordinateType.PERIOD.getDescription(), + model.getColumnName(1)); + assertEquals(PeriodAnalysisCoordinateType.POWER.getDescription(), + model.getColumnName(2)); + assertEquals(PeriodAnalysisCoordinateType.SEMI_AMPLITUDE.getDescription(), + model.getColumnName(3)); + } + + public void testColumnClassIsAlwaysString() { + for (int col = 0; col < model.getColumnCount(); col++) { + assertEquals(String.class, model.getColumnClass(col)); + } + } + + public void testGetValueAtReturnsFormattedString() { + String expected = NumericPrecisionPrefs.formatOther(FREQ); + assertEquals(expected, model.getValueAt(0, 0)); + } + + public void testGetValueAtPowerColumn() { + String expected = NumericPrecisionPrefs.formatOther(POWER); + assertEquals(expected, model.getValueAt(0, 2)); + } + + public void testGetPeriodValueInRow() { + String expected = NumericPrecisionPrefs.formatOther(PERIOD); + assertEquals(expected, model.getPeriodValueInRow(0)); + } + + public void testGetFrequencyValueInRow() { + assertEquals(FREQ, model.getFrequencyValueInRow(0), 1e-15); + } + + public void testGetDataPointFromRow() { + var dp = model.getDataPointFromRow(0); + assertNotNull(dp); + assertEquals(FREQ, dp.getFrequency(), 1e-15); + assertEquals(PERIOD, dp.getPeriod(), 1e-15); + assertEquals(POWER, dp.getPower(), 1e-15); + } + + public void testGetData() { + assertSame(data, model.getData()); + } + + public void testSetDataUpdatesModel() { + Map> newData = new LinkedHashMap<>(); + newData.put(PeriodAnalysisCoordinateType.FREQUENCY, Arrays.asList(0.9)); + newData.put(PeriodAnalysisCoordinateType.PERIOD, Arrays.asList(1.0 / 0.9)); + newData.put(PeriodAnalysisCoordinateType.POWER, Arrays.asList(5.0)); + newData.put(PeriodAnalysisCoordinateType.SEMI_AMPLITUDE, Arrays.asList(0.05)); + + model.setData(newData); + + assertEquals(1, model.getRowCount()); + assertSame(newData, model.getData()); + } +} diff --git a/test/org/aavso/tools/vstar/ui/model/list/WWZDataTableModelTest.java b/test/org/aavso/tools/vstar/ui/model/list/WWZDataTableModelTest.java new file mode 100644 index 00000000..c30fe472 --- /dev/null +++ b/test/org/aavso/tools/vstar/ui/model/list/WWZDataTableModelTest.java @@ -0,0 +1,133 @@ +/** + * VStar: a statistical analysis tool for variable star data. + * Copyright (C) 2009 AAVSO (http://www.aavso.org/) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.aavso.tools.vstar.ui.model.list; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +import org.aavso.tools.vstar.util.period.wwz.WWZCoordinateType; +import org.aavso.tools.vstar.util.period.wwz.WWZStatistic; +import org.aavso.tools.vstar.util.prefs.NumericPrecisionPrefs; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link WWZDataTableModel}. + * + * The model wraps WWZ time-frequency analysis results in an + * {@code AbstractTableModel}. No display or Mediator required. + * + * Part of issue #579 (GUI code coverage). + */ +public class WWZDataTableModelTest extends TestCase { + + private static final double TAU = 2451545.0; + private static final double FREQ = 0.25; + private static final double WWZ_VAL = 8.3; + private static final double AMP = 0.45; + private static final double MAVE = 10.2; + private static final double NEFF = 42.0; + + private WWZStatistic stat1; + private WWZStatistic stat2; + private List stats; + private WWZDataTableModel model; + + @Override + protected void setUp() { + Locale.setDefault(Locale.ENGLISH); + + stat1 = new WWZStatistic(TAU, FREQ, WWZ_VAL, AMP, MAVE, NEFF); + stat2 = new WWZStatistic(TAU + 1, 0.5, 3.1, 0.2, 11.0, 30.0); + stats = new ArrayList<>(Arrays.asList(stat1, stat2)); + + model = new WWZDataTableModel(stats, null); + } + + public void testColumnCount() { + assertEquals(WWZCoordinateType.values().length, model.getColumnCount()); + } + + public void testRowCount() { + assertEquals(2, model.getRowCount()); + } + + public void testColumnNames() { + assertEquals(WWZCoordinateType.TAU.toString(), model.getColumnName(0)); + assertEquals(WWZCoordinateType.FREQUENCY.toString(), model.getColumnName(1)); + assertEquals(WWZCoordinateType.PERIOD.toString(), model.getColumnName(2)); + assertEquals(WWZCoordinateType.WWZ.toString(), model.getColumnName(3)); + assertEquals(WWZCoordinateType.SEMI_AMPLITUDE.toString(), model.getColumnName(4)); + assertEquals(WWZCoordinateType.MEAN_MAG.toString(), model.getColumnName(5)); + assertEquals(WWZCoordinateType.EFFECTIVE_NUM_DATA.toString(), model.getColumnName(6)); + } + + public void testColumnClassIsAlwaysString() { + for (int col = 0; col < model.getColumnCount(); col++) { + assertEquals(String.class, model.getColumnClass(col)); + } + } + + public void testGetValueAtTauColumn() { + String expected = NumericPrecisionPrefs.formatOther(TAU); + assertEquals(expected, model.getValueAt(0, 0)); + } + + public void testGetValueAtFrequencyColumn() { + String expected = NumericPrecisionPrefs.formatOther(FREQ); + assertEquals(expected, model.getValueAt(0, 1)); + } + + public void testGetValueAtPeriodColumn() { + String expected = NumericPrecisionPrefs.formatOther(1.0 / FREQ); + assertEquals(expected, model.getValueAt(0, 2)); + } + + public void testGetValueAtWWZColumn() { + String expected = NumericPrecisionPrefs.formatOther(WWZ_VAL); + assertEquals(expected, model.getValueAt(0, 3)); + } + + public void testGetValueAtSemiAmplitudeColumn() { + String expected = NumericPrecisionPrefs.formatOther(AMP); + assertEquals(expected, model.getValueAt(0, 4)); + } + + public void testGetDataPointFromRow() { + WWZStatistic dp = model.getDataPointFromRow(0); + assertSame(stat1, dp); + } + + public void testGetDataPointFromSecondRow() { + WWZStatistic dp = model.getDataPointFromRow(1); + assertSame(stat2, dp); + } + + public void testGetStats() { + assertSame(stats, model.getStats()); + } + + public void testEmptyModel() { + WWZDataTableModel empty = new WWZDataTableModel( + new ArrayList<>(), null); + assertEquals(0, empty.getRowCount()); + assertEquals(WWZCoordinateType.values().length, empty.getColumnCount()); + } +}