0001: /*
0002: * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
0003: *
0004: * Redistribution and use in source and binary forms, with or without
0005: * modification, are permitted provided that the following conditions are met:
0006: *
0007: * o Redistributions of source code must retain the above copyright notice,
0008: * this list of conditions and the following disclaimer.
0009: *
0010: * o Redistributions in binary form must reproduce the above copyright notice,
0011: * this list of conditions and the following disclaimer in the documentation
0012: * and/or other materials provided with the distribution.
0013: *
0014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
0015: * its contributors may be used to endorse or promote products derived
0016: * from this software without specific prior written permission.
0017: *
0018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
0022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
0025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
0026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
0027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
0028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029: */
0030:
0031: package com.jgoodies.binding.tests;
0032:
0033: import java.util.ArrayList;
0034: import java.util.LinkedList;
0035: import java.util.List;
0036:
0037: import junit.framework.TestCase;
0038:
0039: import com.jgoodies.binding.beans.PropertyAdapter;
0040: import com.jgoodies.binding.tests.beans.TestBean;
0041: import com.jgoodies.binding.tests.event.PropertyChangeReport;
0042: import com.jgoodies.binding.tests.value.CloningValueHolder;
0043: import com.jgoodies.binding.tests.value.ToUpperCaseStringHolder;
0044: import com.jgoodies.binding.value.BufferedValueModel;
0045: import com.jgoodies.binding.value.Trigger;
0046: import com.jgoodies.binding.value.ValueHolder;
0047: import com.jgoodies.binding.value.ValueModel;
0048:
0049: /**
0050: * Tests class {@link BufferedValueModel}.
0051: * Critical are state changes to and from the state
0052: * where buffered value == subject value.
0053: *
0054: * @author Jeanette Winzenburg
0055: * @author Karsten Lentzsch
0056: * @version $Revision: 1.19 $
0057: *
0058: * @see BufferedValueModel
0059: */
0060: public final class BufferedValueModelTest extends TestCase {
0061:
0062: private static final Object INITIAL_VALUE = "initial value";
0063: private static final Object RESET_VALUE = "reset value";
0064:
0065: /**
0066: * Holds a subject that can be reused by tests.
0067: */
0068: private ValueModel subject;
0069:
0070: /**
0071: * Holds a trigger channel that can be reused by tests
0072: * and changed by invoking #commit and #flush.
0073: */
0074: private Trigger triggerChannel;
0075:
0076: // Testing Proper Values **************************************************
0077:
0078: /**
0079: * Tests that the BufferedValueModel returns the subject's values
0080: * as long as no value has been assigned.
0081: */
0082: public void testReturnsSubjectValueIfNoValueAssigned() {
0083: BufferedValueModel buffer = createDefaultBufferedValueModel();
0084: assertEquals(
0085: "Buffer value equals the subject value before any changes.",
0086: buffer.getValue(), subject.getValue());
0087:
0088: subject.setValue("change1");
0089: assertEquals(
0090: "Buffer value equals the subject value changes as long as no value has been assigned.",
0091: buffer.getValue(), subject.getValue());
0092:
0093: subject.setValue(null);
0094: assertEquals(
0095: "Buffer value equals the subject value changes as long as no value has been assigned.",
0096: buffer.getValue(), subject.getValue());
0097:
0098: subject.setValue("change2");
0099: assertEquals(
0100: "Buffer value equals the subject value changes as long as no value has been assigned.",
0101: buffer.getValue(), subject.getValue());
0102: }
0103:
0104: /**
0105: * Tests that the BufferedValueModel returns the buffered values
0106: * once a value has been assigned.
0107: */
0108: public void testReturnsBufferedValueIfValueAssigned() {
0109: BufferedValueModel buffer = createDefaultBufferedValueModel();
0110:
0111: Object newValue1 = subject.getValue();
0112: buffer.setValue(newValue1);
0113: subject.setValue("subject1");
0114: assertSame(
0115: "Buffer value == new value once a value has been assigned.",
0116: buffer.getValue(), newValue1);
0117:
0118: Object newValue2 = "change1";
0119: buffer.setValue(newValue2);
0120: subject.setValue("subject2");
0121: assertSame(
0122: "Buffer value == new value once a value has been assigned.",
0123: buffer.getValue(), newValue2);
0124:
0125: Object newValue3 = null;
0126: buffer.setValue(newValue3);
0127: subject.setValue(null);
0128: assertSame(
0129: "Buffer value == new value once a value has been assigned.",
0130: buffer.getValue(), newValue3);
0131:
0132: Object newValue4 = "change2";
0133: buffer.setValue(newValue4);
0134: assertSame(
0135: "Buffer value == new value once a value has been assigned.",
0136: buffer.getValue(), newValue4);
0137: }
0138:
0139: /**
0140: * Tests that the BufferedValueModel returns the buffered values
0141: * once a value has been assigned and ignores subject value changes.
0142: */
0143: public void testIgnoresSubjectValuesIfValueAssigned() {
0144: BufferedValueModel buffer = createDefaultBufferedValueModel();
0145:
0146: Object newValue1 = "change1";
0147: buffer.setValue(newValue1);
0148: subject.setValue("change3");
0149: assertSame(
0150: "Buffer value == new value once a value has been assigned.",
0151: buffer.getValue(), newValue1);
0152: subject.setValue(newValue1);
0153: assertSame(
0154: "Buffer value == new value once a value has been assigned.",
0155: buffer.getValue(), newValue1);
0156: subject.setValue(null);
0157: assertSame(
0158: "Buffer value == new value once a value has been assigned.",
0159: buffer.getValue(), newValue1);
0160: }
0161:
0162: /**
0163: * Tests that the BufferedValueModel returns the subject's values
0164: * after a commit.
0165: */
0166: public void testReturnsSubjectValueAfterCommit() {
0167: BufferedValueModel buffer = createDefaultBufferedValueModel();
0168: buffer.setValue("change1"); // shall buffer now
0169: commit();
0170: assertEquals(
0171: "Buffer value equals the subject value after a commit.",
0172: buffer.getValue(), subject.getValue());
0173:
0174: subject.setValue("change2");
0175: assertEquals(
0176: "Buffer value equals the subject value after a commit.",
0177: buffer.getValue(), subject.getValue());
0178:
0179: subject.setValue(buffer.getValue());
0180: assertEquals(
0181: "Buffer value equals the subject value after a commit.",
0182: buffer.getValue(), subject.getValue());
0183: }
0184:
0185: /**
0186: * Tests that the BufferedValueModel returns the subject's values
0187: * after a flush.
0188: */
0189: public void testReturnsSubjectValueAfterFlush() {
0190: BufferedValueModel buffer = createDefaultBufferedValueModel();
0191: buffer.setValue("change1"); // shall buffer now
0192: flush();
0193: assertEquals(
0194: "Buffer value equals the subject value after a flush.",
0195: subject.getValue(), buffer.getValue());
0196:
0197: subject.setValue("change2");
0198: assertEquals(
0199: "Buffer value equals the subject value after a flush.",
0200: subject.getValue(), buffer.getValue());
0201: }
0202:
0203: // Testing Proper Value Commit and Flush **********************************
0204:
0205: /**
0206: * Tests the core of the buffering feature: buffer modifications
0207: * do not affect the subject before a commit.
0208: */
0209: public void testSubjectValuesUnchangedBeforeCommit() {
0210: BufferedValueModel buffer = createDefaultBufferedValueModel();
0211: Object oldSubjectValue = subject.getValue();
0212: buffer.setValue("changedBuffer1");
0213: assertEquals(
0214: "Buffer changes do not change the subject value before a commit.",
0215: subject.getValue(), oldSubjectValue);
0216: buffer.setValue(null);
0217: assertEquals(
0218: "Buffer changes do not change the subject value before a commit.",
0219: subject.getValue(), oldSubjectValue);
0220: buffer.setValue(oldSubjectValue);
0221: assertEquals(
0222: "Buffer changes do not change the subject value before a commit.",
0223: subject.getValue(), oldSubjectValue);
0224: buffer.setValue("changedBuffer2");
0225: assertEquals(
0226: "Buffer changes do not change the subject value before a commit.",
0227: subject.getValue(), oldSubjectValue);
0228: }
0229:
0230: /**
0231: * Tests the core of a commit: buffer changes are written through on commit
0232: * and change the subject value.
0233: */
0234: public void testCommitChangesSubjectValue() {
0235: BufferedValueModel buffer = createDefaultBufferedValueModel();
0236: Object oldSubjectValue = subject.getValue();
0237: Object newValue1 = "change1";
0238: buffer.setValue(newValue1);
0239: assertEquals(
0240: "Subject value is unchanged before the first commit.",
0241: subject.getValue(), oldSubjectValue);
0242: commit();
0243: assertEquals(
0244: "Subject value is the new value after the first commit.",
0245: subject.getValue(), newValue1);
0246:
0247: // Set the buffer to the current subject value to check whether
0248: // the starts buffering, even if there's no value difference.
0249: Object newValue2 = subject.getValue();
0250: buffer.setValue(newValue2);
0251: commit();
0252: assertEquals(
0253: "Subject value is the new value after the second commit.",
0254: subject.getValue(), newValue2);
0255: }
0256:
0257: /**
0258: * Tests the core of a flush action: buffer changes are overridden
0259: * by subject changes after a flush.
0260: */
0261: public void testFlushResetsTheBufferedValue() {
0262: BufferedValueModel buffer = createDefaultBufferedValueModel();
0263: Object newValue1 = "new value1";
0264: buffer.setValue(newValue1);
0265: assertSame(
0266: "Buffer value reflects changes before the first flush.",
0267: buffer.getValue(), newValue1);
0268: flush();
0269: assertEquals(
0270: "Buffer value is the subject value after the first flush.",
0271: buffer.getValue(), subject.getValue());
0272:
0273: // Set the buffer to the current subject value to check whether
0274: // the starts buffering, even if there's no value difference.
0275: Object newValue2 = subject.getValue();
0276: buffer.setValue(newValue2);
0277: assertSame("Buffer value reflects changes before the flush.",
0278: buffer.getValue(), newValue2);
0279: flush();
0280: assertEquals(
0281: "Buffer value is the subject value after the second flush.",
0282: buffer.getValue(), subject.getValue());
0283: }
0284:
0285: // Tests a Proper Buffering State *****************************************
0286:
0287: /**
0288: * Tests that a buffer isn't buffering as long as no value has been assigned.
0289: */
0290: public void testIsNotBufferingIfNoValueAssigned() {
0291: BufferedValueModel buffer = createDefaultBufferedValueModel();
0292: assertFalse("Initially the buffer does not buffer.", buffer
0293: .isBuffering());
0294:
0295: Object newValue = "change1";
0296: subject.setValue(newValue);
0297: assertFalse(
0298: "Subject changes do not affect the buffering state.",
0299: buffer.isBuffering());
0300:
0301: subject.setValue(null);
0302: assertFalse(
0303: "Subject change to null does not affect the buffering state.",
0304: buffer.isBuffering());
0305: }
0306:
0307: /**
0308: * Tests that the buffer is buffering once a value has been assigned,
0309: * even if the buffered value is equal to the subject's value.
0310: */
0311: public void testIsBufferingIfValueAssigned() {
0312: BufferedValueModel buffer = createDefaultBufferedValueModel();
0313: buffer.setValue("change1");
0314: assertTrue(
0315: "Setting a value (even the subject's value) turns on buffering.",
0316: buffer.isBuffering());
0317:
0318: buffer.setValue("change2");
0319: assertTrue(
0320: "Changing the value doesn't affect the buffering state.",
0321: buffer.isBuffering());
0322:
0323: buffer.setValue(subject.getValue());
0324: assertTrue(
0325: "Resetting the value to the subject's value doesn't affect buffering.",
0326: buffer.isBuffering());
0327: }
0328:
0329: /**
0330: * Tests that the buffer is not buffering after a commit.
0331: */
0332: public void testIsNotBufferingAfterCommit() {
0333: BufferedValueModel buffer = createDefaultBufferedValueModel();
0334: buffer.setValue("change1");
0335: commit();
0336: assertFalse("The buffer does not buffer after a commit.",
0337: buffer.isBuffering());
0338:
0339: Object newValue = "change1";
0340: subject.setValue(newValue);
0341: assertFalse(
0342: "The buffer does not buffer after a commit and subject change1.",
0343: buffer.isBuffering());
0344:
0345: subject.setValue(null);
0346: assertFalse(
0347: "The buffer does not buffer after a commit and subject change2.",
0348: buffer.isBuffering());
0349: }
0350:
0351: /**
0352: * Tests that the buffer is not buffering after a flush.
0353: */
0354: public void testIsNotBufferingAfterFlush() {
0355: BufferedValueModel buffer = createDefaultBufferedValueModel();
0356: buffer.setValue("change1");
0357: flush();
0358: assertFalse("The buffer does not buffer after a flush.", buffer
0359: .isBuffering());
0360:
0361: Object newValue = "change1";
0362: subject.setValue(newValue);
0363: assertFalse(
0364: "The buffer does not buffer after a flush and subject change1.",
0365: buffer.isBuffering());
0366:
0367: subject.setValue(null);
0368: assertFalse(
0369: "The buffer does not buffer after a flush and subject change2.",
0370: buffer.isBuffering());
0371: }
0372:
0373: /**
0374: * Tests that changing the buffering state fires changes of
0375: * the <i>buffering</i> property.
0376: */
0377: public void testFiresBufferingChanges() {
0378: Trigger trigger2 = new Trigger();
0379: BufferedValueModel buffer = new BufferedValueModel(subject,
0380: trigger2);
0381: PropertyChangeReport changeReport = new PropertyChangeReport();
0382: buffer.addPropertyChangeListener("buffering", changeReport);
0383:
0384: assertEquals("Initial state.", 0, changeReport.eventCount());
0385: buffer.getValue();
0386: assertEquals("Reading initial value.", 0, changeReport
0387: .eventCount());
0388: buffer.setSubject(new ValueHolder());
0389: assertEquals("After subject change.", 0, changeReport
0390: .eventCount());
0391: buffer.setTriggerChannel(triggerChannel);
0392: assertEquals("After trigger channel change.", 0, changeReport
0393: .eventCount());
0394:
0395: buffer.setValue("now buffering");
0396: assertEquals("After setting the first value.", 1, changeReport
0397: .eventCount());
0398: buffer.setValue("still buffering");
0399: assertEquals("After setting the second value.", 1, changeReport
0400: .eventCount());
0401: buffer.getValue();
0402: assertEquals("Reading buffered value.", 1, changeReport
0403: .eventCount());
0404:
0405: commit();
0406: assertEquals("After committing.", 2, changeReport.eventCount());
0407: buffer.getValue();
0408: assertEquals("Reading unbuffered value.", 2, changeReport
0409: .eventCount());
0410:
0411: buffer.setValue("buffering again");
0412: assertEquals("After second buffering switch.", 3, changeReport
0413: .eventCount());
0414: flush();
0415: assertEquals("After flushing.", 4, changeReport.eventCount());
0416: buffer.getValue();
0417: assertEquals("Reading unbuffered value.", 4, changeReport
0418: .eventCount());
0419: }
0420:
0421: // Tests Subject Changes **************************************************
0422:
0423: /**
0424: * Checks that #setSubject changes the subject.
0425: */
0426: public void testSubjectChange() {
0427: ValueHolder subject1 = new ValueHolder();
0428: ValueHolder subject2 = new ValueHolder();
0429:
0430: BufferedValueModel buffer = new BufferedValueModel(null,
0431: triggerChannel);
0432: assertNull("Subject is null if not set in constructor.", buffer
0433: .getSubject());
0434:
0435: buffer.setSubject(subject1);
0436: assertSame("Subject has been changed.", buffer.getSubject(),
0437: subject1);
0438:
0439: buffer.setSubject(subject2);
0440: assertSame("Subject has been changed.", buffer.getSubject(),
0441: subject2);
0442:
0443: buffer.setSubject(null);
0444: assertNull("Subject has been changed to null.", buffer
0445: .getSubject());
0446: }
0447:
0448: public void testSetValueSendsProperValueChangeEvents() {
0449: Object obj1 = new Integer(1);
0450: Object obj2a = new Integer(2);
0451: Object obj2b = new Integer(2);
0452: testSetValueFiresProperEvents(null, obj1, true);
0453: testSetValueFiresProperEvents(obj1, null, true);
0454: testSetValueFiresProperEvents(obj1, obj1, false);
0455: testSetValueFiresProperEvents(obj1, obj2a, true);
0456: testSetValueFiresProperEvents(obj2a, obj2b, true); // identity test
0457: testSetValueFiresProperEvents(null, null, false);
0458: }
0459:
0460: public void testSetValueFiresProperValueChangeEvents() {
0461: Object obj1 = new Integer(1);
0462: Object obj2a = new Integer(2);
0463: Object obj2b = new Integer(2);
0464: testValueChangeSendsProperEvents(null, obj1, true);
0465: testValueChangeSendsProperEvents(obj1, null, true);
0466: testValueChangeSendsProperEvents(obj1, obj1, false);
0467: testValueChangeSendsProperEvents(obj1, obj2a, true);
0468: testValueChangeSendsProperEvents(obj2a, obj2b, true); // identity test
0469: testValueChangeSendsProperEvents(null, null, false);
0470: }
0471:
0472: public void testSetValueFiresIfNewValueAndSubjectChange() {
0473: Object initialValue = new Integer(0);
0474: Object oldValue = new Integer(1);
0475: Object newValue = new Integer(2);
0476: subject.setValue(initialValue);
0477: BufferedValueModel buffer = new BufferedValueModel(subject,
0478: new Trigger());
0479: PropertyChangeReport changeReport = new PropertyChangeReport();
0480: buffer.addValueChangeListener(changeReport);
0481: buffer.setValue(oldValue);
0482: assertTrue("Buffer is now buffering", buffer.isBuffering());
0483: assertEquals("Buffer fired a value change.", 1, changeReport
0484: .eventCount());
0485: subject.setValue(newValue);
0486: assertEquals(
0487: "Setting the subject in buffered state fires no value change.",
0488: 1, changeReport.eventCount());
0489:
0490: assertEquals("The buffered value is 1.", oldValue, buffer
0491: .getValue());
0492: // Setting the buffer from 1 to 2 should fire a value change.
0493: buffer.setValue(newValue);
0494: assertEquals("The value is now 2.", newValue, buffer.getValue());
0495: assertTrue("The buffer is still buffering", buffer
0496: .isBuffering());
0497: assertEquals(
0498: "Setting the buffer from 1 to 2 fires a value change.",
0499: 2, changeReport.eventCount());
0500: }
0501:
0502: /**
0503: * Checks that the buffer reports the current subject's value if unbuffered.
0504: */
0505: public void testReturnsCurrentSubjectValue() {
0506: Object value1_1 = "value1.1";
0507: Object value1_2 = "value1.2";
0508: Object value1_3 = "value1.3";
0509: Object value2_1 = "value2.1";
0510: Object value2_2 = "value2.2";
0511:
0512: ValueHolder subject1 = new ValueHolder(value1_1);
0513: ValueHolder subject2 = new ValueHolder(value2_1);
0514:
0515: BufferedValueModel buffer = new BufferedValueModel(subject1,
0516: triggerChannel);
0517:
0518: assertSame(
0519: "Buffer returns the subject value of the current subject1.",
0520: buffer.getValue(), subject1.getValue());
0521:
0522: subject1.setValue(value1_2);
0523: assertSame(
0524: "Buffer returns the new subject value of the current subject1.",
0525: buffer.getValue(), subject1.getValue());
0526:
0527: buffer.setSubject(subject2);
0528: assertSame(
0529: "Buffer returns the subject value of the current subject2.",
0530: buffer.getValue(), subject2.getValue());
0531:
0532: subject1.setValue(value1_3);
0533: subject2.setValue(value2_2);
0534: assertSame(
0535: "Buffer returns the new subject value of the current subject2.",
0536: buffer.getValue(), subject2.getValue());
0537: }
0538:
0539: /**
0540: * Checks that the buffer listens to changes of the current subject
0541: * and moves the value change handler if the subject changes.
0542: */
0543: public void testListensToCurrentSubject() {
0544: Object value1_1 = "value1.1";
0545: Object value1_2 = "value1.2";
0546: Object value2_1 = "value2.1";
0547: Object value2_2 = "value2.2";
0548:
0549: ValueHolder subject1 = new ValueHolder(null);
0550: ValueHolder subject2 = new ValueHolder(null);
0551:
0552: BufferedValueModel buffer = new BufferedValueModel(subject1,
0553: triggerChannel);
0554: PropertyChangeReport changeReport = new PropertyChangeReport();
0555: buffer.addValueChangeListener(changeReport);
0556:
0557: subject1.setValue(value1_1);
0558: assertEquals("Value change.", 1, changeReport.eventCount());
0559:
0560: subject2.setValue(value2_1);
0561: assertEquals("No value change.", 1, changeReport.eventCount());
0562:
0563: buffer.setSubject(subject2);
0564: assertEquals("Value changed because of subject change.", 2,
0565: changeReport.eventCount());
0566:
0567: subject1.setValue(value1_2);
0568: assertEquals("No value change.", 2, changeReport.eventCount());
0569:
0570: subject2.setValue(value2_2);
0571: assertEquals("Value change.", 3, changeReport.eventCount());
0572: }
0573:
0574: // Trigger Channel Tests *************************************************
0575:
0576: /**
0577: * Checks that the trigger channel is non-null.
0578: */
0579: public void testRejectNullTriggerChannel() {
0580: try {
0581: new BufferedValueModel(subject, null);
0582: fail("The constructor must reject a null trigger channel.");
0583: } catch (NullPointerException e) {
0584: // The expected behavior
0585: }
0586: BufferedValueModel buffer = createDefaultBufferedValueModel();
0587: try {
0588: buffer.setTriggerChannel(null);
0589: fail("The trigger channel setter must reject null values.");
0590: } catch (NullPointerException e) {
0591: // The expected behavior
0592: }
0593: }
0594:
0595: /**
0596: * Checks that #setTriggerChannel changes the trigger channel.
0597: */
0598: public void testTriggerChannelChange() {
0599: ValueHolder trigger1 = new ValueHolder();
0600: ValueHolder trigger2 = new ValueHolder();
0601:
0602: BufferedValueModel buffer = new BufferedValueModel(subject,
0603: trigger1);
0604: assertSame("Trigger channel has been changed.", buffer
0605: .getTriggerChannel(), trigger1);
0606:
0607: buffer.setTriggerChannel(trigger2);
0608: assertSame("Trigger channel has been changed.", buffer
0609: .getTriggerChannel(), trigger2);
0610: }
0611:
0612: /**
0613: * Checks and verifies that commit and flush events are driven
0614: * by the current trigger channel.
0615: */
0616: public void testListensToCurrentTriggerChannel() {
0617: ValueHolder trigger1 = new ValueHolder();
0618: ValueHolder trigger2 = new ValueHolder();
0619:
0620: BufferedValueModel buffer = new BufferedValueModel(subject,
0621: trigger1);
0622: buffer.setValue("change1");
0623: Object subjectValue = subject.getValue();
0624: Object bufferedValue = buffer.getValue();
0625: trigger2.setValue(true);
0626: assertEquals(
0627: "Changing the unrelated trigger2 to true has no effect on the subject.",
0628: subject.getValue(), subjectValue);
0629: assertSame(
0630: "Changing the unrelated trigger2 to true has no effect on the buffer.",
0631: buffer.getValue(), bufferedValue);
0632:
0633: trigger2.setValue(false);
0634: assertEquals(
0635: "Changing the unrelated trigger2 to false has no effect on the subject.",
0636: subject.getValue(), subjectValue);
0637: assertSame(
0638: "Changing the unrelated trigger2 to false has no effect on the buffer.",
0639: buffer.getValue(), bufferedValue);
0640:
0641: // Change the trigger channel to trigger2.
0642: buffer.setTriggerChannel(trigger2);
0643: assertSame("Trigger channel has been changed.", buffer
0644: .getTriggerChannel(), trigger2);
0645:
0646: trigger1.setValue(true);
0647: assertEquals(
0648: "Changing the unrelated trigger1 to true has no effect on the subject.",
0649: subject.getValue(), subjectValue);
0650: assertSame(
0651: "Changing the unrelated trigger1 to true has no effect on the buffer.",
0652: buffer.getValue(), bufferedValue);
0653:
0654: trigger1.setValue(false);
0655: assertEquals(
0656: "Changing the unrelated trigger1 to false has no effect on the subject.",
0657: subject.getValue(), subjectValue);
0658: assertSame(
0659: "Changing the unrelated trigger1 to false has no effect on the buffer.",
0660: buffer.getValue(), bufferedValue);
0661:
0662: // Commit using trigger2.
0663: trigger2.setValue(true);
0664: assertEquals(
0665: "Changing the current trigger2 to true commits the buffered value.",
0666: buffer.getValue(), subject.getValue());
0667:
0668: buffer.setValue("change2");
0669: subjectValue = subject.getValue();
0670: trigger2.setValue(false);
0671: assertEquals(
0672: "Changing the current trigger2 to false flushes the buffered value.",
0673: buffer.getValue(), subject.getValue());
0674: assertEquals(
0675: "Changing the current trigger2 to false flushes the buffered value.",
0676: buffer.getValue(), subjectValue);
0677: }
0678:
0679: // Tests Proper Update Notifications **************************************
0680:
0681: /**
0682: * Checks that subject changes fire value changes
0683: * if no value has been assigned.
0684: */
0685: public void testPropagatesSubjectChangesIfNoValueAssigned() {
0686: BufferedValueModel buffer = createDefaultBufferedValueModel();
0687: PropertyChangeReport changeReport = new PropertyChangeReport();
0688: buffer.addValueChangeListener(changeReport);
0689:
0690: subject.setValue("change1");
0691: assertEquals("Value change.", 1, changeReport.eventCount());
0692:
0693: subject.setValue(null);
0694: assertEquals("Value change.", 2, changeReport.eventCount());
0695:
0696: subject.setValue("change2");
0697: assertEquals("Value change.", 3, changeReport.eventCount());
0698:
0699: subject.setValue(buffer.getValue());
0700: assertEquals("No value change.", 3, changeReport.eventCount());
0701: }
0702:
0703: /**
0704: * Tests that subject changes are not propagated once a value has
0705: * been assigned, i.e. the buffer is buffering.
0706: */
0707: public void testIgnoresSubjectChangesIfValueAssigned() {
0708: BufferedValueModel buffer = createDefaultBufferedValueModel();
0709: PropertyChangeReport changeReport = new PropertyChangeReport();
0710: buffer.setValue("new buffer");
0711: buffer.addValueChangeListener(changeReport);
0712:
0713: subject.setValue("change1");
0714: assertEquals("Value change.", 0, changeReport.eventCount());
0715:
0716: subject.setValue(null);
0717: assertEquals("Value change.", 0, changeReport.eventCount());
0718:
0719: subject.setValue("change2");
0720: assertEquals("Value change.", 0, changeReport.eventCount());
0721:
0722: subject.setValue(buffer.getValue());
0723: assertEquals("No value change.", 0, changeReport.eventCount());
0724: }
0725:
0726: /**
0727: * Checks and verifies that a commit fires no value change.
0728: */
0729: public void testCommitFiresNoChangeOnSameOldAndNewValues() {
0730: BufferedValueModel buffer = createDefaultBufferedValueModel(new ValueHolder());
0731: buffer.setValue("value1");
0732: PropertyChangeReport changeReport = new PropertyChangeReport();
0733: buffer.addValueChangeListener(changeReport);
0734:
0735: assertEquals("No initial change.", 0, changeReport.eventCount());
0736: commit();
0737: assertEquals("First commit: no change.", 0, changeReport
0738: .eventCount());
0739:
0740: buffer.setValue("value2");
0741: assertEquals("Setting a value: a change.", 1, changeReport
0742: .eventCount());
0743: commit();
0744: assertEquals("Second commit: no change.", 1, changeReport
0745: .eventCount());
0746: }
0747:
0748: public void testCommitFiresChangeOnDifferentOldAndNewValues() {
0749: BufferedValueModel buffer = createDefaultBufferedValueModel(new ToUpperCaseStringHolder());
0750: buffer.setValue("initialValue");
0751: PropertyChangeReport changeReport = new PropertyChangeReport();
0752: buffer.addValueChangeListener(changeReport);
0753: buffer.setValue("value1");
0754: assertEquals("One event fired", 1, changeReport.eventCount());
0755: assertEquals("First value set.", "value1", changeReport
0756: .lastNewValue());
0757: commit();
0758: assertEquals("Commit fires if the subject modifies the value.",
0759: 2, changeReport.eventCount());
0760: assertEquals("Old value is the buffered value.", "value1",
0761: changeReport.lastOldValue());
0762: assertEquals("New value is the modified value.", "VALUE1",
0763: changeReport.lastNewValue());
0764: }
0765:
0766: /**
0767: * Tests that a flush event fires a value change if and only if
0768: * the flushed value does not equal the buffered value.
0769: */
0770: public void testFlushFiresTrueValueChanges() {
0771: BufferedValueModel buffer = createDefaultBufferedValueModel(new ValueHolder());
0772: PropertyChangeReport changeReport = new PropertyChangeReport();
0773:
0774: buffer.setValue("new buffer");
0775: subject.setValue("new subject");
0776: buffer.addValueChangeListener(changeReport);
0777: flush();
0778: assertEquals("First flush changes value.", 1, changeReport
0779: .eventCount());
0780:
0781: buffer.setValue(subject.getValue());
0782: assertEquals("Resetting value: no change.", 1, changeReport
0783: .eventCount());
0784: flush();
0785: assertEquals("Second flush: no change.", 1, changeReport
0786: .eventCount());
0787:
0788: buffer.setValue("new buffer2");
0789: assertEquals("Second value change.", 2, changeReport
0790: .eventCount());
0791: subject.setValue("new subject2");
0792: assertEquals("Setting new subject value: no change.", 2,
0793: changeReport.eventCount());
0794: buffer.setValue(subject.getValue());
0795: assertEquals("Third value change.", 3, changeReport
0796: .eventCount());
0797: flush();
0798: assertEquals("Third flush: no change.", 3, changeReport
0799: .eventCount());
0800: }
0801:
0802: public void testFlushChecksIdentity() {
0803: List<Object> list1 = new ArrayList<Object>();
0804: List<Object> list2 = new LinkedList<Object>();
0805: BufferedValueModel buffer = createDefaultBufferedValueModel(new ValueHolder());
0806: subject.setValue(list1);
0807: buffer.setValue(list2);
0808: assertSame("Buffered value is list2.", list2, buffer.getValue());
0809: PropertyChangeReport changeReport = new PropertyChangeReport();
0810: buffer.addValueChangeListener(changeReport);
0811: flush();
0812: assertSame("After flush, the value is list1.", list1, buffer
0813: .getValue());
0814: assertEquals(
0815: "Flush fires an event for different subject value and buffer.",
0816: 1, changeReport.eventCount());
0817: assertSame("The event's old value is list2.", list2,
0818: changeReport.lastOldValue());
0819: assertSame("The event's new value is list1.", list1,
0820: changeReport.lastNewValue());
0821: }
0822:
0823: public void testValueNoficationAfterSubjectChanged() {
0824: ValueModel initialSubject = new ValueHolder("initial value");
0825: BufferedValueModel buffer = new BufferedValueModel(
0826: initialSubject, new Trigger());
0827: PropertyChangeReport changeReport = new PropertyChangeReport();
0828: buffer.addValueChangeListener(changeReport);
0829: int eventCount = 0;
0830: Object newValue = "changed";
0831: initialSubject.setValue(newValue);
0832: assertEquals("Value changed on original subject", ++eventCount,
0833: changeReport.eventCount());
0834: ValueModel subjectWithSame = new ValueHolder(newValue);
0835: buffer.setSubject(subjectWithSame);
0836: assertEquals("Subject changed but same value as old",
0837: eventCount, changeReport.eventCount());
0838: ValueModel subject2 = new ValueHolder(
0839: "changedSubjectWithDifferentValue");
0840: buffer.setSubject(subject2);
0841: assertEquals(
0842: "Value changed by changing the subject with different value",
0843: ++eventCount, changeReport.eventCount());
0844: }
0845:
0846: // Rejecting Access If Subject == null ************************************
0847:
0848: public void testRejectGetValueWhenSubjectIsNull() {
0849: BufferedValueModel buffer = new BufferedValueModel(null,
0850: triggerChannel);
0851: try {
0852: buffer.getValue();
0853: fail("The Buffer must reject attempts to read unbuffered values when the subject is null.");
0854: } catch (NullPointerException ex) {
0855: // The expected behavior
0856: }
0857: buffer.setSubject(subject);
0858: buffer.setValue("now buffering");
0859: buffer.setSubject(null);
0860: try {
0861: buffer.getValue();
0862: fail("The Buffer must reject attempts to read buffered values when the subject is null.");
0863: } catch (NullPointerException ex) {
0864: // The expected behavior
0865: }
0866: }
0867:
0868: public void testRejectSetValueWhenSubjectIsNull() {
0869: BufferedValueModel buffer = new BufferedValueModel(null,
0870: triggerChannel);
0871: try {
0872: Object value = "valuewithoutsubject??";
0873: buffer.setValue(value);
0874: fail("The Buffer must reject attempts to set values when the subject is null.");
0875: } catch (NullPointerException ex) {
0876: // The expected behavior
0877: }
0878: buffer.setSubject(subject);
0879: buffer.setValue("now buffering");
0880: buffer.setSubject(null);
0881: try {
0882: buffer.setValue("a new value");
0883: fail("The Buffer must reject attempts to set values when the subject is null - even if buffering.");
0884: } catch (NullPointerException ex) {
0885: // The expected behavior
0886: }
0887: }
0888:
0889: public void testRejectCommitWhenSubjectIsNull() {
0890: BufferedValueModel buffer = new BufferedValueModel(null,
0891: triggerChannel);
0892: try {
0893: commit();
0894: fail("The Buffer must reject attempts to commit when the subject is null.");
0895: } catch (NullPointerException ex) {
0896: // The expected behavior
0897: }
0898: buffer.setSubject(subject);
0899: buffer.setValue("now buffering");
0900: buffer.setSubject(null);
0901: try {
0902: commit();
0903: fail("The Buffer must reject attempts to commit when the subject is null - even if buffering.");
0904: } catch (NullPointerException ex) {
0905: // The expected behavior
0906: }
0907: }
0908:
0909: public void testRejectFlushWhenSubjectIsNull() {
0910: BufferedValueModel buffer = new BufferedValueModel(null,
0911: triggerChannel);
0912: try {
0913: flush();
0914: fail("The Buffer must reject attempts to commit when the subject is null.");
0915: } catch (NullPointerException ex) {
0916: // The expected behavior
0917: }
0918: buffer.setSubject(subject);
0919: buffer.setValue("now buffering");
0920: buffer.setSubject(null);
0921: try {
0922: flush();
0923: fail("The Buffer must reject attempts to commit when the subject is null - even if buffering.");
0924: } catch (NullPointerException ex) {
0925: // The expected behavior
0926: }
0927: }
0928:
0929: // Misc Tests *************************************************************
0930:
0931: /**
0932: * Tests read actions on a read-only model.
0933: */
0934: public void testReadOnly() {
0935: TestBean bean = new TestBean();
0936: bean.readOnlyObjectProperty = "testString";
0937: PropertyAdapter<TestBean> readOnlyModel = new PropertyAdapter<TestBean>(
0938: bean, "readOnlyObjectProperty");
0939: BufferedValueModel buffer = new BufferedValueModel(
0940: readOnlyModel, triggerChannel);
0941:
0942: assertSame("Can read values from a read-only model.", buffer
0943: .getValue(), readOnlyModel.getValue());
0944:
0945: Object newValue1 = "new value";
0946: buffer.setValue(newValue1);
0947: assertSame(
0948: "Can read values from a read-only model when buffering.",
0949: buffer.getValue(), newValue1);
0950:
0951: flush();
0952: assertSame(
0953: "Can read values from a read-only model after a flush.",
0954: buffer.getValue(), bean.readOnlyObjectProperty);
0955:
0956: buffer.setValue("new value2");
0957: try {
0958: commit();
0959: fail("Cannot commit to a read-only model.");
0960: } catch (Exception e) {
0961: // The expected behavior
0962: }
0963: }
0964:
0965: /**
0966: * Tests write actions on a write-only model.
0967: */
0968: public void testWriteOnly() {
0969: TestBean bean = new TestBean();
0970: bean.writeOnlyObjectProperty = "testString";
0971: PropertyAdapter<TestBean> writeOnlyModel = new PropertyAdapter<TestBean>(
0972: bean, "writeOnlyObjectProperty");
0973: BufferedValueModel buffer = new BufferedValueModel(
0974: writeOnlyModel, triggerChannel);
0975:
0976: Object newValue1 = "new value";
0977: buffer.setValue(newValue1);
0978: assertSame("Can buffer a value on a write-only model.", buffer
0979: .getValue(), newValue1);
0980:
0981: commit();
0982: writeOnlyModel.setValue("new value2");
0983: try {
0984: flush();
0985: fail("Cannot flush a value from a write-only model.");
0986: } catch (Exception e) {
0987: // The expected behavior
0988: }
0989: }
0990:
0991: // Test Implementations ***************************************************
0992:
0993: private void testSetValueFiresProperEvents(Object oldValue,
0994: Object newValue, boolean eventExpected) {
0995: BufferedValueModel valueModel = new BufferedValueModel(
0996: new ValueHolder(oldValue), new Trigger());
0997: testFiresProperEvents(valueModel, oldValue, newValue,
0998: eventExpected);
0999: }
1000:
1001: private void testValueChangeSendsProperEvents(Object oldValue,
1002: Object newValue, boolean eventExpected) {
1003: BufferedValueModel defaultModel = createDefaultBufferedValueModel();
1004: defaultModel.setValue(oldValue);
1005: testFiresProperEvents(defaultModel, oldValue, newValue,
1006: eventExpected);
1007: }
1008:
1009: private void testFiresProperEvents(BufferedValueModel valueModel,
1010: Object oldValue, Object newValue, boolean eventExpected) {
1011: PropertyChangeReport changeReport = new PropertyChangeReport();
1012: valueModel.addValueChangeListener(changeReport);
1013: int expectedEventCount = eventExpected ? 1 : 0;
1014:
1015: valueModel.setValue(newValue);
1016: assertEquals("Expected event count after ( " + oldValue
1017: + " -> " + newValue + ").", expectedEventCount,
1018: changeReport.eventCount());
1019: if (eventExpected) {
1020: assertEquals("Event's old value.", oldValue, changeReport
1021: .lastOldValue());
1022: assertEquals("Event's new value.", newValue, changeReport
1023: .lastNewValue());
1024: }
1025: }
1026:
1027: // Helper Code ************************************************************
1028:
1029: private void commit() {
1030: triggerChannel.triggerCommit();
1031: }
1032:
1033: private void flush() {
1034: triggerChannel.triggerFlush();
1035: }
1036:
1037: private BufferedValueModel createDefaultBufferedValueModel() {
1038: subject.setValue(RESET_VALUE);
1039: return new BufferedValueModel(subject, triggerChannel);
1040: }
1041:
1042: private BufferedValueModel createDefaultBufferedValueModel(
1043: ValueModel aSubject) {
1044: this .subject = aSubject;
1045: subject.setValue(RESET_VALUE);
1046: return new BufferedValueModel(subject, triggerChannel);
1047: }
1048:
1049: // Setup / Teardown *******************************************************
1050:
1051: /**
1052: * @throws Exception in case of an unexpected problem
1053: */
1054: @Override
1055: protected void setUp() throws Exception {
1056: super .setUp();
1057: subject = new CloningValueHolder(INITIAL_VALUE);
1058: triggerChannel = new Trigger();
1059: }
1060:
1061: /**
1062: * @throws Exception in case of an unexpected problem
1063: */
1064: @Override
1065: protected void tearDown() throws Exception {
1066: super.tearDown();
1067: subject = null;
1068: triggerChannel = null;
1069: }
1070:
1071: }
|