• R/O
  • SSH
  • HTTPS

jpicosheet: Commit


Commit MetaInfo

Revision80 (tree)
Time2015-06-18 22:03:24
Authorki-chi

Log Message

テーブル、グループに対する循環参照エラー検知を修正、ErrorTypeの循環参照エラーのつづりを修正。

Change Summary

Incremental Difference

--- trunk/src/test/CellTest.java (revision 79)
+++ trunk/src/test/CellTest.java (revision 80)
@@ -365,7 +365,7 @@
365365 c1.setValue("=c1+1");
366366 assertEquals(CellType.FORMULA, c1.getCellType());
367367 assertEquals(Element.ElementType.ERROR, c1.getValue().getType());
368- assertEquals(Element.ErrorType.CIRCULER_REFERENCE, c1.getValue().getErrorType());
368+ assertEquals(Element.ErrorType.CIRCULAR_REFERENCE, c1.getValue().getErrorType());
369369 c1.setValue("=c2+1");
370370 assertEquals(CellType.FORMULA, c1.getCellType());
371371 assertEquals(Element.ElementType.NUMBER, c1.getValue().getType());
--- trunk/src/test/TableTest.java (revision 79)
+++ trunk/src/test/TableTest.java (revision 80)
@@ -29,6 +29,9 @@
2929 import com.nissy_ki_chi.jpicosheet.core.ReferenceNotFoundException;
3030 import com.nissy_ki_chi.jpicosheet.core.Sheet;
3131 import com.nissy_ki_chi.jpicosheet.core.Table;
32+import com.nissy_ki_chi.jpicosheet.core.Cell.CellStatus;
33+import com.nissy_ki_chi.jpicosheet.core.Element.ElementType;
34+import com.nissy_ki_chi.jpicosheet.core.Element.ErrorType;
3235
3336 import junit.framework.TestCase;
3437
@@ -671,4 +674,47 @@
671674
672675 }
673676
677+
678+ public void testCircularReferenceTable1() {
679+
680+ Table t1 = sheet.addTable("circular1#", 2, 2);
681+ t1.getCell(0, 1).setNumberValue("100");
682+ t1.getCell(1, 0).setNumberValue("200");
683+ t1.getCell(1, 1).setNumberValue("300");
684+ Table t2 = sheet.addTable("circular2#", 2, 2);
685+ t2.getCell(0, 1).setNumberValue("1");
686+ t2.getCell(1, 0).setNumberValue("2");
687+ t2.getCell(1, 1).setNumberValue("3");
688+ Cell t1r0c0 = sheet.getCell("circular1#R0C0").setFormula("SUM(circular2#)");
689+ assertTrue(t1r0c0.getStatus() == CellStatus.CALCULATED);
690+
691+ Cell t1r0c1 = sheet.getCell("circular1#R0C1").setFormula("SUM(circular1#)");
692+ assertTrue((t1r0c1.getStatus() == CellStatus.ERROR) &&
693+ (t1r0c1.getValueType() == ElementType.ERROR) &&
694+ (t1r0c1.getValue().getErrorType() == ErrorType.CIRCULAR_REFERENCE));
695+
696+ }
697+
698+ public void testCircularReferenceTable2() {
699+
700+ Table t1 = sheet.addTable("circular1#", 2, 2);
701+ t1.getCell(0, 1).setNumberValue("100");
702+ t1.getCell(1, 0).setNumberValue("200");
703+ t1.getCell(1, 1).setNumberValue("300");
704+ Table t2 = sheet.addTable("circular2#", 2, 2);
705+ t2.getCell(0, 1).setNumberValue("1");
706+ t2.getCell(1, 0).setNumberValue("2");
707+ t2.getCell(1, 1).setNumberValue("3");
708+ Cell t1r0c0 = sheet.getCell("circular1#R0C0").setFormula("SUM(circular2#)");
709+ assertTrue(t1r0c0.getStatus() == CellStatus.CALCULATED);
710+
711+ Cell t2r0c0 = sheet.getCell("circular2#R0C0").setFormula("SUM(circular1#)");
712+ assertTrue((t2r0c0.getStatus() == CellStatus.ERROR) &&
713+ (t2r0c0.getValueType() == ElementType.ERROR) &&
714+ (t2r0c0.getValue().getErrorType() == ErrorType.CIRCULAR_REFERENCE));
715+
716+ assertTrue((t1r0c0.getStatus() == CellStatus.ERROR) &&
717+ (t1r0c0.getValueType() == ElementType.ERROR) &&
718+ (t1r0c0.getValue().getErrorType() == ErrorType.CIRCULAR_REFERENCE));
719+ }
674720 }
--- trunk/src/test/ElementTest.java (revision 79)
+++ trunk/src/test/ElementTest.java (revision 80)
@@ -418,8 +418,8 @@
418418 elem = Element.newElement(ElementType.BOOLEAN, new Boolean(false));
419419 assertEquals("BOOLEAN:false", elem.toString());
420420
421- elem = Element.newElement(ElementType.ERROR, Element.ErrorType.CIRCULER_REFERENCE );
422- assertEquals("ERROR:CIRCULER_REFERENCE", elem.toString());
421+ elem = Element.newElement(ElementType.ERROR, Element.ErrorType.CIRCULAR_REFERENCE );
422+ assertEquals("ERROR:CIRCULAR_REFERENCE", elem.toString());
423423
424424 elem = Element.newElement(ElementType.FUNCTION, "myFunction");
425425 assertEquals("FUNCTION:myFunction", elem.toString());
--- trunk/src/test/GroupTest.java (revision 79)
+++ trunk/src/test/GroupTest.java (revision 80)
@@ -138,21 +138,54 @@
138138 assertEquals(sheet.getCell("calc1").getValue().getNumber(), new BigDecimal(1+2+3+4+5+6));
139139 }
140140
141-// Groups in Group はしばらく実装中止
142-// public void testCircurationGroup() {
143-// // グループの循環参照はチェックされエラーとならなければならない。
144-//
145-// Cell c1 = sheet.addCell("cell1").setNumberValue("123");
146-// Group group1 = sheet.addGroup("group1@").addCell(c1);
147-// Group group2 = sheet.addGroup("group2@").addGroup(group1);
148-//
149-// group1.addGroup(group2);
150-//
151-// Cell c2 = sheet.addCell("cell2").setFormula("SUM(group2@)");
152-// assertEquals(ElementType.ERROR, c2.getValue().getType());
153-// assertEquals(ErrorType.CIRCULER_REFERENCE, c2.getValue().getErrorType());
154-// }
155141
142+ public void testCircularReferenceGroup1() {
143+
144+ // グループの循環参照はチェックされエラーとならなければならない。
145+ Cell a = sheet.addCell("a").setNumberValue("100");
146+ Cell b = sheet.addCell("b").setNumberValue("200");
147+ Cell c = sheet.addCell("c").setNumberValue("300");
148+ sheet.addGroup("group1@").addCell(a).addCell(b).addCell(c);
149+
150+ Cell sum1 = sheet.addCell("sum1").setFormula("SUM(group1@)");
151+ assertTrue(sum1.getStatus() == CellStatus.CALCULATED);
152+
153+ // group1@に含まれるセルaに、group1@を使った式をセット
154+ a.setFormula("SUM(group1@)");
155+ assertTrue((a.getStatus() == CellStatus.ERROR) &&
156+ (a.getValueType() == ElementType.ERROR) &&
157+ (a.getValue().getErrorType() == ErrorType.CIRCULAR_REFERENCE) );
158+
159+ }
160+
161+ public void testCircularReferenceGroup2() {
162+
163+ // グループが他のグループを使った計算を行うことはOKだが、お互いを参照すると循環参照
164+ Cell a = sheet.addCell("a").setNumberValue("100");
165+ Cell b = sheet.addCell("b").setNumberValue("200");
166+ Cell c = sheet.addCell("c").setNumberValue("300");
167+ Group group1 = sheet.addGroup("group1@").addCell(a).addCell(b).addCell(c);
168+ Cell x = sheet.addCell("x").setNumberValue("1");
169+ Cell y = sheet.addCell("y").setNumberValue("2");
170+ Cell z = sheet.addCell("z").setNumberValue("3");
171+ Group group2 = sheet.addGroup("group2@").addCell(x).addCell(y).addCell(z);
172+
173+ Cell d = sheet.addCell("d").setFormula("SUM(group2@)");
174+ group1.addCell(d);
175+ assertTrue((d.getStatus() == CellStatus.CALCULATED));
176+
177+ Cell w = sheet.addCell("w").setFormula("SUM(group1@)");
178+ group2.addCell(w);
179+ // d,wともに循環参照エラー
180+ assertTrue((w.getStatus() == CellStatus.ERROR) &&
181+ (w.getValueType() == ElementType.ERROR) &&
182+ (w.getValue().getErrorType() == ErrorType.CIRCULAR_REFERENCE) );
183+ assertTrue((d.getStatus() == CellStatus.ERROR) &&
184+ (d.getValueType() == ElementType.ERROR) &&
185+ (d.getValue().getErrorType() == ErrorType.CIRCULAR_REFERENCE) );
186+
187+ }
188+
156189 public void testValueChanged() throws IllegalStateException, ReferenceNotFoundException {
157190 // グループ中の値が変更された場合、そのグループを参照しているセルの内容は再計算されなければならない
158191 Group group1 = sheet.addGroup("group1@")
--- trunk/src/test/CalculationTest.java (revision 79)
+++ trunk/src/test/CalculationTest.java (revision 80)
@@ -799,20 +799,20 @@
799799 sheet.addCell("cell1").setFormula("cell2");
800800 sheet.addCell("cell2").setFormula("cell3");
801801 sheet.addCell("cell3").setFormula("cell1");
802- assertEquals("ERROR:CIRCULER_REFERENCE", sheet.getCell("cell1").getValueString());
803- assertEquals("ERROR:CIRCULER_REFERENCE", sheet.getCell("cell2").getValueString());
804- assertEquals("ERROR:CIRCULER_REFERENCE", sheet.getCell("cell3").getValueString());
802+ assertEquals("ERROR:CIRCULAR_REFERENCE", sheet.getCell("cell1").getValueString());
803+ assertEquals("ERROR:CIRCULAR_REFERENCE", sheet.getCell("cell2").getValueString());
804+ assertEquals("ERROR:CIRCULAR_REFERENCE", sheet.getCell("cell3").getValueString());
805805 sheet.addCell("cell3").setNumberValue("11");
806806 assertEquals("11", sheet.getCell("cell1").getValueString());
807807 assertEquals("11", sheet.getCell("cell2").getValueString());
808808 assertEquals("11", sheet.getCell("cell3").getValueString());
809809 sheet.addCell("cell3").setFormula("cell1");
810- assertEquals("ERROR:CIRCULER_REFERENCE", sheet.getCell("cell1").getValueString());
811- assertEquals("ERROR:CIRCULER_REFERENCE", sheet.getCell("cell2").getValueString());
812- assertEquals("ERROR:CIRCULER_REFERENCE", sheet.getCell("cell3").getValueString());
810+ assertEquals("ERROR:CIRCULAR_REFERENCE", sheet.getCell("cell1").getValueString());
811+ assertEquals("ERROR:CIRCULAR_REFERENCE", sheet.getCell("cell2").getValueString());
812+ assertEquals("ERROR:CIRCULAR_REFERENCE", sheet.getCell("cell3").getValueString());
813813
814814 sheet.addCell("cell2_1").setFormula("cell2");
815- assertEquals("ERROR:CIRCULER_REFERENCE", sheet.getCell("cell2_1").getValueString());
815+ assertEquals("ERROR:CIRCULAR_REFERENCE", sheet.getCell("cell2_1").getValueString());
816816 sheet.addCell("cell3").setNumberValue("11");
817817 assertEquals("11", sheet.getCell("cell1").getValueString());
818818 assertEquals("11", sheet.getCell("cell2").getValueString());
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/Calculator.java (revision 79)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/Calculator.java (revision 80)
@@ -267,7 +267,16 @@
267267 // TODO:セル参照のたびにCollectionを得てすべてのセルの再計算チェックするのは非効率
268268 Collection<Cell> cells;
269269 cells = _book.getResolver().getCellsFromGroup(token.getGroupReference());
270- recalcIfRequired(cells);
270+ // 各セルに対し、必要に応じ再計算を行う
271+ for (Cell groupCell: cells) {
272+ recalcIfRequired(groupCell);
273+ // エラーの場合、得た値をセル値としてセットし、このセルのステータスをエラーにして計算を中断する
274+ if (groupCell.getValue().getType() == ElementType.ERROR) {
275+ cell.setValue(groupCell.getValue());
276+ cell.setStatus(CellStatus.ERROR);
277+ return;
278+ }
279+ }
271280 calcStack.push(token);
272281 } catch (ReferenceNotFoundException e) {
273282 // エレメントが示すグループが存在しなかった場合、このセルのステータスをエラーにして計算を中断する
@@ -283,7 +292,16 @@
283292 // TODO:セル参照のたびにCollectionを得てすべてのセルの再計算チェックするのは非効率
284293 Collection<Cell> cells;
285294 cells = _book.getResolver().getCellsFromTable(token.getTableReference());
286- recalcIfRequired(cells);
295+ // 各セルに対し、必要に応じ再計算を行う
296+ for (Cell groupCell: cells) {
297+ recalcIfRequired(groupCell);
298+ // エラーの場合、得た値をセル値としてセットし、このセルのステータスをエラーにして計算を中断する
299+ if (groupCell.getValue().getType() == ElementType.ERROR) {
300+ cell.setValue(groupCell.getValue());
301+ cell.setStatus(CellStatus.ERROR);
302+ return;
303+ }
304+ }
287305 calcStack.push(token);
288306 } catch (ReferenceNotFoundException e) {
289307 // エレメントが示すテーブルが存在しなかった場合、このセルのステータスをエラーにして計算を中断する
@@ -412,22 +430,15 @@
412430
413431
414432 /**
415- * 渡されたセルのコレクションのステータスをチェックし、必要な場合再計算を行います
416- * @param cells チェックするセルのコレクション
433+ * 渡されたセルのステータスが計算必要である場合、そのセルに対し計算を行います。<br>
434+ * 渡されたセルのステータスが計算中であった場合、そのセルに対し循環参照エラーをセットします。
435+ * @param cell 対象とするセル
417436 */
418- private void recalcIfRequired(Collection<Cell> cells) {
419-
420- // 渡されたセルオブジェクトの中に計算が必要なセルがある場合、計算を行う
421- for (Cell cell: cells) {
422- recalcIfRequired(cell);
423- }
424- }
425-
426437 private void recalcIfRequired(Cell cell) {
427438 // 参照するセルのステータスが計算中の場合、循環参照している
428439 if (cell.getStatus() == CellStatus.UNDER_CALCULATION) {
429440 // 循環参照エラーの値をセットする
430- cell.setValue(Element.newElement(ElementType.ERROR, ErrorType.CIRCULER_REFERENCE));
441+ cell.setValue(Element.newElement(ElementType.ERROR, ErrorType.CIRCULAR_REFERENCE));
431442 cell.setStatus(CellStatus.ERROR);
432443 }
433444
--- trunk/src/com/nissy_ki_chi/jpicosheet/core/Element.java (revision 79)
+++ trunk/src/com/nissy_ki_chi/jpicosheet/core/Element.java (revision 80)
@@ -123,7 +123,7 @@
123123 /**
124124 * 循環参照
125125 */
126- CIRCULER_REFERENCE,
126+ CIRCULAR_REFERENCE,
127127
128128 /**
129129 * 不正なパラメータ
Show on old repository browser