diff options
author | bvosburgh | 2007-09-01 00:16:34 +0000 |
---|---|---|
committer | bvosburgh | 2007-09-01 00:16:34 +0000 |
commit | 428159b00fa3b24516470491d21fffe7cf460351 (patch) | |
tree | ea7281299bf7865c03bce98aa10e92b9fd5946f9 /jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility | |
parent | 600fc0c48e2c2c59480c5843eb0285e053018286 (diff) | |
download | webtools.dali-428159b00fa3b24516470491d21fffe7cf460351.tar.gz webtools.dali-428159b00fa3b24516470491d21fffe7cf460351.tar.xz webtools.dali-428159b00fa3b24516470491d21fffe7cf460351.zip |
[201159] model rework - added "node" support
Diffstat (limited to 'jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility')
7 files changed, 1497 insertions, 0 deletions
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java index 436f10e901..7d7a7a0924 100644 --- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java +++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java @@ -12,6 +12,7 @@ package org.eclipse.jpt.utility.tests.internal; import org.eclipse.jpt.utility.internal.ClassTools; import org.eclipse.jpt.utility.tests.internal.iterators.JptUtilityIteratorsTests; import org.eclipse.jpt.utility.tests.internal.model.JptUtilityModelTests; +import org.eclipse.jpt.utility.tests.internal.node.JptUtilityNodeTests; import junit.framework.Test; import junit.framework.TestSuite; @@ -26,6 +27,7 @@ public class JptUtilityTests { suite.addTest(JptUtilityIteratorsTests.suite()); suite.addTest(JptUtilityModelTests.suite()); + suite.addTest(JptUtilityNodeTests.suite()); suite.addTestSuite(BitToolsTests.class); suite.addTestSuite(ClasspathTests.class); @@ -39,7 +41,11 @@ public class JptUtilityTests { suite.addTestSuite(JDBCTypeTests.class); suite.addTestSuite(NameToolsTests.class); suite.addTestSuite(ReverseComparatorTests.class); + suite.addTestSuite(SimpleStackTests.class); suite.addTestSuite(StringToolsTests.class); + suite.addTestSuite(SynchronizedBooleanTests.class); + suite.addTestSuite(SynchronizedObjectTests.class); + suite.addTestSuite(SynchronizedStackTests.class); suite.addTestSuite(XMLStringEncoderTests.class); return suite; diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java new file mode 100644 index 0000000000..f229797565 --- /dev/null +++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2007 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.utility.tests.internal; + +import java.util.EmptyStackException; + +import org.eclipse.jpt.utility.internal.SimpleStack; +import org.eclipse.jpt.utility.internal.Stack; + +import junit.framework.TestCase; + +public class SimpleStackTests extends TestCase { + + public SimpleStackTests(String name) { + super(name); + } + + public void testIsEmpty() { + Stack<String> stack = new SimpleStack<String>(); + assertTrue(stack.isEmpty()); + stack.push("first"); + assertFalse(stack.isEmpty()); + stack.push("second"); + assertFalse(stack.isEmpty()); + stack.pop(); + assertFalse(stack.isEmpty()); + stack.pop(); + assertTrue(stack.isEmpty()); + } + + public void testPushAndPop() { + Stack<String> stack = new SimpleStack<String>(); + String first = "first"; + String second = "second"; + + stack.push(first); + stack.push(second); + assertEquals(second, stack.pop()); + assertEquals(first, stack.pop()); + } + + public void testPushAndPeek() { + Stack<String> stack = new SimpleStack<String>(); + String first = "first"; + String second = "second"; + + stack.push(first); + stack.push(second); + assertEquals(second, stack.peek()); + assertEquals(second, stack.peek()); + assertEquals(second, stack.pop()); + assertEquals(first, stack.peek()); + assertEquals(first, stack.peek()); + assertEquals(first, stack.pop()); + } + + public void testEmptyStackExceptionPeek() { + Stack<String> stack = new SimpleStack<String>(); + String first = "first"; + String second = "second"; + + stack.push(first); + stack.push(second); + assertEquals(second, stack.peek()); + assertEquals(second, stack.pop()); + assertEquals(first, stack.peek()); + assertEquals(first, stack.pop()); + + boolean exCaught = false; + try { + stack.peek(); + } catch (EmptyStackException ex) { + exCaught = true; + } + assertTrue(exCaught); + } + + public void testEmptyStackExceptionPop() { + Stack<String> stack = new SimpleStack<String>(); + String first = "first"; + String second = "second"; + + stack.push(first); + stack.push(second); + assertEquals(second, stack.peek()); + assertEquals(second, stack.pop()); + assertEquals(first, stack.peek()); + assertEquals(first, stack.pop()); + + boolean exCaught = false; + try { + stack.pop(); + } catch (EmptyStackException ex) { + exCaught = true; + } + assertTrue(exCaught); + } + + public void testClone() { + SimpleStack<String> stack = new SimpleStack<String>(); + stack.push("first"); + stack.push("second"); + stack.push("third"); + + this.verifyClone(stack, stack.clone()); + } + + public void testSerialization() throws Exception { + SimpleStack<String> stack = new SimpleStack<String>(); + stack.push("first"); + stack.push("second"); + stack.push("third"); + + this.verifyClone(stack, TestTools.serialize(stack)); + } + + private void verifyClone(Stack<String> original, Stack<String> clone) { + assertNotSame(original, clone); + assertEquals(original.peek(), clone.peek()); + assertEquals(original.pop(), clone.pop()); + assertEquals(original.peek(), clone.peek()); + assertEquals(original.pop(), clone.pop()); + assertEquals(original.isEmpty(), clone.isEmpty()); + assertEquals(original.peek(), clone.peek()); + assertEquals(original.pop(), clone.pop()); + assertTrue(original.isEmpty()); + assertEquals(original.isEmpty(), clone.isEmpty()); + + original.push("fourth"); + assertFalse(original.isEmpty()); + // clone should still be empty + assertTrue(clone.isEmpty()); + } + +} diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java new file mode 100644 index 0000000000..4b42839081 --- /dev/null +++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2007 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.utility.tests.internal; + +import org.eclipse.jpt.utility.internal.SynchronizedBoolean; + +import junit.framework.TestCase; + +public class SynchronizedBooleanTests extends TestCase { + private volatile SynchronizedBoolean sb; + private volatile boolean exCaught; + private volatile boolean timeoutOccurred; + private volatile long startTime; + private volatile long endTime; + + + public SynchronizedBooleanTests(String name) { + super(name); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + this.sb = new SynchronizedBoolean(); + this.exCaught = false; + this.timeoutOccurred = false; + this.startTime = 0; + this.endTime = 0; + } + + @Override + protected void tearDown() throws Exception { + TestTools.clear(this); + super.tearDown(); + } + + public void testAccessors() throws Exception { + this.sb.setValue(false); + assertFalse(this.sb.value()); + assertFalse(this.sb.isTrue()); + assertTrue(this.sb.isFalse()); + + this.sb.setValue(true); + assertTrue(this.sb.value()); + assertTrue(this.sb.isTrue()); + assertFalse(this.sb.isFalse()); + + this.sb.setFalse(); + assertFalse(this.sb.value()); + assertFalse(this.sb.isTrue()); + assertTrue(this.sb.isFalse()); + + this.sb.setTrue(); + assertTrue(this.sb.value()); + assertTrue(this.sb.isTrue()); + assertFalse(this.sb.isFalse()); + + assertSame(this.sb, this.sb.mutex()); + } + + public void testEquals() throws Exception { + this.sb.setValue(false); + SynchronizedBoolean sb2 = new SynchronizedBoolean(false); + assertEquals(this.sb, sb2); + + this.sb.setValue(true); + assertFalse(this.sb.equals(sb2)); + + sb2.setValue(true); + assertEquals(this.sb, sb2); + } + + public void testHashCode() { + this.sb.setValue(false); + assertEquals(0, this.sb.hashCode()); + + this.sb.setValue(true); + assertEquals(1, this.sb.hashCode()); + } + + public void testWaitUntilTrue() throws Exception { + this.verifyWaitUntilTrue(0); + // no timeout occurs... + assertFalse(this.timeoutOccurred); + // ...and the value should be set to true by t2 + assertTrue(this.sb.value()); + // make a reasonable guess about how long t2 took + assertTrue(this.elapsedTime() > 150); + } + + public void testWaitUntilTrueTimeout() throws Exception { + this.verifyWaitUntilTrue(20); + // timeout occurs... + assertTrue(this.timeoutOccurred); + // ...and the value will eventually be set to true by t1 + assertTrue(this.sb.value()); + // make a reasonable guess about how long t2 took + assertTrue(this.elapsedTime() < 150); + } + + private void verifyWaitUntilTrue(long timeout) throws Exception { + this.sb.setFalse(); + Runnable r1 = this.buildRunnable(this.buildSetTrueCommand(), this.sb, 200); + Runnable r2 = this.buildRunnable(this.buildWaitUntilTrueCommand(timeout), this.sb, 0); + Thread t1 = new Thread(r1); + Thread t2 = new Thread(r2); + t1.start(); + t2.start(); + while (t1.isAlive() || t2.isAlive()) { + Thread.sleep(50); + } + assertFalse(this.exCaught); + } + + public void testWaitToSetFalse() throws Exception { + this.verifyWaitToSetFalse(0); + // no timeout occurs... + assertFalse(this.timeoutOccurred); + // ...and the value should be set to false by t2 + assertFalse(this.sb.value()); + // make a reasonable guess about how long t2 took + assertTrue(this.elapsedTime() > 150); + } + + public void testWaitToSetFalseTimeout() throws Exception { + this.verifyWaitToSetFalse(20); + // timeout occurs... + assertTrue(this.timeoutOccurred); + // ...and the value will eventually be set to true by t1 + assertTrue(this.sb.value()); + // make a reasonable guess about how long t2 took + assertTrue(this.elapsedTime() < 150); + } + + private void verifyWaitToSetFalse(long timeout) throws Exception { + this.sb.setFalse(); + Runnable r1 = this.buildRunnable(this.buildSetTrueCommand(), this.sb, 200); + Runnable r2 = this.buildRunnable(this.buildWaitToSetFalseCommand(timeout), this.sb, 0); + Thread t1 = new Thread(r1); + Thread t2 = new Thread(r2); + t1.start(); + t2.start(); + while (t1.isAlive() || t2.isAlive()) { + Thread.sleep(50); + } + assertFalse(this.exCaught); + } + + private Command buildSetTrueCommand() { + return new Command() { + public void execute(SynchronizedBoolean syncBool) { + syncBool.setTrue(); + } + }; + } + + private Command buildWaitUntilTrueCommand(final long timeout) { + return new Command() { + public void execute(SynchronizedBoolean syncBool) throws Exception { + SynchronizedBooleanTests.this.setStartTime(System.currentTimeMillis()); + SynchronizedBooleanTests.this.setTimeoutOccurred( ! syncBool.waitUntilTrue(timeout)); + SynchronizedBooleanTests.this.setEndTime(System.currentTimeMillis()); + } + }; + } + + private Command buildWaitToSetFalseCommand(final long timeout) { + return new Command() { + public void execute(SynchronizedBoolean syncBool) throws Exception { + SynchronizedBooleanTests.this.setStartTime(System.currentTimeMillis()); + SynchronizedBooleanTests.this.setTimeoutOccurred( ! syncBool.waitToSetFalse(timeout)); + SynchronizedBooleanTests.this.setEndTime(System.currentTimeMillis()); + } + }; + } + + private Runnable buildRunnable(final Command command, final SynchronizedBoolean syncBool, final long sleep) { + return new Runnable() { + public void run() { + try { + if (sleep != 0) { + Thread.sleep(sleep); + } + command.execute(syncBool); + } catch (Exception ex) { + SynchronizedBooleanTests.this.setExCaught(true); + } + } + }; + } + + void setExCaught(boolean exCaught) { + this.exCaught = exCaught; + } + + void setTimeoutOccurred(boolean timeoutOccurred) { + this.timeoutOccurred = timeoutOccurred; + } + + void setStartTime(long startTime) { + this.startTime = startTime; + } + + void setEndTime(long endTime) { + this.endTime = endTime; + } + + long elapsedTime() { + return this.endTime - this.startTime; + } + + + // ********** Command interface ********** + + private interface Command { + void execute(SynchronizedBoolean syncBool) throws Exception; + } + +} diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java new file mode 100644 index 0000000000..1eba5ba39b --- /dev/null +++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright (c) 2007 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.utility.tests.internal; + +import org.eclipse.jpt.utility.internal.SynchronizedObject; + +import junit.framework.TestCase; + +public class SynchronizedObjectTests extends TestCase { + private volatile SynchronizedObject<Object> so; + private volatile boolean exCaught; + private volatile boolean timeoutOccurred; + volatile Object value = new Object(); + private volatile long startTime; + private volatile long endTime; + private volatile Object soValue; + + + public SynchronizedObjectTests(String name) { + super(name); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + this.so = new SynchronizedObject<Object>(); + this.exCaught = false; + this.timeoutOccurred = false; + this.startTime = 0; + this.endTime = 0; + this.soValue = null; + } + + @Override + protected void tearDown() throws Exception { + TestTools.clear(this); + super.tearDown(); + } + + public void testAccessors() throws Exception { + this.so.setValue(null); + assertNull(this.so.value()); + assertFalse(this.so.isNotNull()); + assertTrue(this.so.isNull()); + + this.so.setValue(this.value); + assertEquals(this.value, this.so.value()); + assertTrue(this.so.isNotNull()); + assertFalse(this.so.isNull()); + + this.so.setNull(); + assertNull(this.so.value()); + assertFalse(this.so.isNotNull()); + assertTrue(this.so.isNull()); + + assertSame(this.so, this.so.mutex()); + } + + public void testEquals() throws Exception { + this.so.setValue(null); + SynchronizedObject<Object> so2 = new SynchronizedObject<Object>(null); + assertEquals(this.so, so2); + + this.so.setValue(this.value); + assertFalse(this.so.equals(so2)); + + so2.setValue(this.value); + assertEquals(this.so, so2); + } + + public void testHashCode() { + this.so.setValue(this.value); + assertEquals(this.value.hashCode(), this.so.hashCode()); + + this.so.setValue(null); + assertEquals(0, this.so.hashCode()); + } + + /** + * t2 will wait indefinitely until t1 sets the value to null + */ + public void testWaitUntilNull() throws Exception { + this.verifyWaitUntilNull(0); + // no timeout occurs... + assertFalse(this.timeoutOccurred); + // ...and the value should be set to null by t2 + assertNull(this.so.value()); + // make a reasonable guess about how long t2 took + long time = this.elapsedTime(); + assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150); + } + + /** + * t2 will time out waiting for t1 to set the value to null + */ + public void testWaitUntilNullTimeout() throws Exception { + this.verifyWaitUntilNull(20); + // timeout occurs... + assertTrue(this.timeoutOccurred); + // ...and the value will eventually be set to null by t1 + assertNull(this.so.value()); + // make a reasonable guess about how long t2 took + long time = this.elapsedTime(); + assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150); + } + + private void verifyWaitUntilNull(long t2Timeout) throws Exception { + this.executeThreads(this.buildSetNullCommand(), this.buildWaitUntilNullCommand(t2Timeout)); + } + + /** + * t2 will wait indefinitely until t1 sets the value to null; + * then t2 will set the value to an object + */ + public void testWaitToSetValue() throws Exception { + this.verifyWaitToSetValue(0); + // no timeout occurs... + assertFalse(this.timeoutOccurred); + // ...and the value should be set to an object by t2 + assertTrue(this.so.isNotNull()); + // make a reasonable guess about how long t2 took + long time = this.elapsedTime(); + assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150); + } + + /** + * t2 will time out waiting for t1 to set the value to null + */ + public void testWaitToSetValueTimeout() throws Exception { + this.verifyWaitToSetValue(20); + // timeout occurs... + assertTrue(this.timeoutOccurred); + // ...and the value will eventually be set to null by t1 + assertTrue(this.so.isNull()); + // make a reasonable guess about how long t2 took + long time = this.elapsedTime(); + assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150); + } + + private void verifyWaitToSetValue(long t2Timeout) throws Exception { + this.executeThreads(this.buildSetNullCommand(), this.buildWaitToSetValueCommand(t2Timeout)); + } + + /** + * t2 will wait until t1 is finished "initializing" the value; + * then t2 will get the newly-initialized value ("foo") + */ + public void testExecute() throws Exception { + this.so.setValue(null); + Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.so, 0); + // give t1 a head start of 100 ms + Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.so, 100); + Thread t1 = new Thread(r1); + Thread t2 = new Thread(r2); + t1.start(); + t2.start(); + while (t1.isAlive() || t2.isAlive()) { + Thread.sleep(50); + } + assertFalse(this.exCaught); + assertEquals("foo", this.so.value()); + assertEquals("foo", this.soValue); + // make a reasonable guess about how long t2 took + long time = this.elapsedTime(); + assertTrue("t2 finished a bit early (expected value should be > 100): " + time, time > 300); + } + + private void executeThreads(Command t1Command, Command t2Command) throws Exception { + this.so.setValue(this.value); + Runnable r1 = this.buildRunnable(t1Command, this.so, 200); + Runnable r2 = this.buildRunnable(t2Command, this.so, 0); + Thread t1 = new Thread(r1); + Thread t2 = new Thread(r2); + t1.start(); + t2.start(); + while (t1.isAlive() || t2.isAlive()) { + Thread.sleep(50); + } + assertFalse(this.exCaught); + } + + private Command buildSetNullCommand() { + return new Command() { + public void execute(SynchronizedObject<Object> sObject) { + sObject.setNull(); + } + }; + } + + private Command buildWaitUntilNullCommand(final long timeout) { + return new Command() { + public void execute(SynchronizedObject<Object> sObject) throws Exception { + SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis()); + SynchronizedObjectTests.this.setTimeoutOccurred( ! sObject.waitUntilNull(timeout)); + SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis()); + } + }; + } + + private Command buildWaitToSetValueCommand(final long timeout) { + return new Command() { + public void execute(SynchronizedObject<Object> sObject) throws Exception { + SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis()); + SynchronizedObjectTests.this.setTimeoutOccurred( ! sObject.waitToSetValue(SynchronizedObjectTests.this.value, timeout)); + SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis()); + } + }; + } + + private Command buildInitializeValueCommand() { + return new Command() { + public void execute(final SynchronizedObject<Object> sObject) throws Exception { + sObject.execute( + new org.eclipse.jpt.utility.internal.Command() { + public void execute() { + // pretend to perform some long initialization process + try { + Thread.sleep(500); + } catch (Exception ex) { + SynchronizedObjectTests.this.setExCaught(true); + } + sObject.setValue("foo"); + } + } + ); + } + }; + } + + private Command buildGetValueCommand() { + return new Command() { + public void execute(SynchronizedObject<Object> sObject) throws Exception { + SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis()); + SynchronizedObjectTests.this.setSOValue(sObject.value()); + SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis()); + } + }; + } + + private Runnable buildRunnable(final Command command, final SynchronizedObject<Object> sObject, final long sleep) { + return new Runnable() { + public void run() { + try { + if (sleep != 0) { + Thread.sleep(sleep); + } + command.execute(sObject); + } catch (Exception ex) { + SynchronizedObjectTests.this.setExCaught(true); + } + } + }; + } + + void setExCaught(boolean exCaught) { + this.exCaught = exCaught; + } + + void setTimeoutOccurred(boolean timeoutOccurred) { + this.timeoutOccurred = timeoutOccurred; + } + + void setStartTime(long startTime) { + this.startTime = startTime; + } + + void setEndTime(long endTime) { + this.endTime = endTime; + } + + private long elapsedTime() { + return this.endTime - this.startTime; + } + + void setSOValue(Object soValue) { + this.soValue = soValue; + } + + + // ********** Command interface ********** + + private interface Command { + void execute(SynchronizedObject<Object> so) throws Exception; + } + +} diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java new file mode 100644 index 0000000000..adb83d9f83 --- /dev/null +++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2007 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.utility.tests.internal; + +import java.util.EmptyStackException; + +import org.eclipse.jpt.utility.internal.SimpleStack; +import org.eclipse.jpt.utility.internal.Stack; +import org.eclipse.jpt.utility.internal.SynchronizedStack; + +public class SynchronizedStackTests extends SimpleStackTests { + private volatile SynchronizedStack<String> ss; + private volatile boolean exCaught; + private volatile boolean timeoutOccurred; + private volatile long startTime; + private volatile long endTime; + private volatile Object poppedObject; + + static final String ITEM_1 = new String(); + static final String ITEM_2 = new String(); + + public SynchronizedStackTests(String name) { + super(name); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + this.ss = new SynchronizedStack<String>(); + this.exCaught = false; + this.timeoutOccurred = false; + this.startTime = 0; + this.endTime = 0; + this.poppedObject = null; + } + + /** + * test first with an unsynchronized stack, + * then with a synchronized stack + */ + public void testConcurrentAccess() throws Exception { + this.verifyConcurrentAccess(new SlowSimpleStack<String>(), "second"); + this.verifyConcurrentAccess(new SlowSynchronizedStack<String>(), "first"); + } + + private void verifyConcurrentAccess(SlowStack<String> slowStack, String expected) throws Exception { + slowStack.push("first"); + slowStack.push("second"); + + new Thread(this.buildRunnable(slowStack)).start(); + Thread.sleep(200); + + assertEquals(expected, slowStack.pop()); + } + + private Runnable buildRunnable(final SlowStack<String> slowStack) { + return new Runnable() { + public void run() { + slowStack.slowPop(); + } + }; + } + + + private interface SlowStack<E> extends Stack<E> { + Object slowPop(); + } + + private class SlowSimpleStack<E> extends SimpleStack<E> implements SlowStack<E> { + SlowSimpleStack() { + super(); + } + public Object slowPop() { + try { + Thread.sleep(500); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } + return this.pop(); + } + + } + + private class SlowSynchronizedStack<E> extends SynchronizedStack<E> implements SlowStack<E> { + SlowSynchronizedStack() { + super(); + } + public synchronized Object slowPop() { + try { + Thread.sleep(100); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } + return this.pop(); + } + + } + + + // ********** waits ********** + + public void testWaitToPop() throws Exception { + this.verifyWaitToPop(0); + // no timeout occurs... + assertFalse(this.timeoutOccurred); + // ...and an item should have been popped by t2... + assertSame(ITEM_1, this.poppedObject); + // ...and the stack should be empty + assertTrue(this.ss.isEmpty()); + // make a reasonable guess about how long t2 took + assertTrue(this.elapsedTime() > 150); + } + + public void testWaitToPopTimeout() throws Exception { + this.verifyWaitToPop(20); + // timeout occurs... + assertTrue(this.timeoutOccurred); + // ...and the stack was never popped... + assertNull(this.poppedObject); + // ...and it still holds the item + assertSame(ITEM_1, this.ss.peek()); + // make a reasonable guess about how long t2 took + assertTrue(this.elapsedTime() < 150); + } + + private void verifyWaitToPop(long timeout) throws Exception { + Runnable r1 = this.buildRunnable(this.buildPushCommand(), this.ss, 200); + Runnable r2 = this.buildRunnable(this.buildWaitToPopCommand(timeout), this.ss, 0); + Thread t1 = new Thread(r1); + Thread t2 = new Thread(r2); + t1.start(); + t2.start(); + while (t1.isAlive() || t2.isAlive()) { + Thread.sleep(50); + } + assertFalse(this.exCaught); + } + + public void testWaitToPush() throws Exception { + this.verifyWaitToPush(0); + // no timeout occurs... + assertFalse(this.timeoutOccurred); + // ...and the stack gets popped by t1... + assertSame(ITEM_1, this.poppedObject); + // ...and an item is pushed on to the stack by t2 + assertFalse(this.ss.isEmpty()); + assertSame(ITEM_2, this.ss.peek()); + // make a reasonable guess about how long t2 took + assertTrue(this.elapsedTime() > 150); + } + + public void testWaitToPushTimeout() throws Exception { + this.verifyWaitToPush(20); + // timeout occurs... + assertTrue(this.timeoutOccurred); + // ...and the stack is eventually popped by t1... + assertSame(ITEM_1, this.poppedObject); + // ...but nothing is pushed on to the stack by t2 + assertTrue(this.ss.isEmpty()); + // make a reasonable guess about how long t2 took + assertTrue(this.elapsedTime() < 150); + } + + private void verifyWaitToPush(long timeout) throws Exception { + this.ss.push(ITEM_1); + Runnable r1 = this.buildRunnable(this.buildPopCommand(), this.ss, 200); + Runnable r2 = this.buildRunnable(this.buildWaitToPushCommand(timeout), this.ss, 0); + Thread t1 = new Thread(r1); + Thread t2 = new Thread(r2); + t1.start(); + t2.start(); + while (t1.isAlive() || t2.isAlive()) { + Thread.sleep(50); + } + assertFalse(this.exCaught); + } + + private Command buildPushCommand() { + return new Command() { + public void execute(SynchronizedStack<String> synchronizedStack) { + synchronizedStack.push(ITEM_1); + } + }; + } + + private Command buildWaitToPopCommand(final long timeout) { + return new Command() { + public void execute(SynchronizedStack<String> synchronizedStack) throws Exception { + SynchronizedStackTests.this.setStartTime(System.currentTimeMillis()); + try { + SynchronizedStackTests.this.setPoppedObject(synchronizedStack.waitToPop(timeout)); + } catch (EmptyStackException ex) { + SynchronizedStackTests.this.setTimeoutOccurred(true); + } + SynchronizedStackTests.this.setEndTime(System.currentTimeMillis()); + } + }; + } + + private Command buildPopCommand() { + return new Command() { + public void execute(SynchronizedStack<String> synchronizedStack) { + SynchronizedStackTests.this.setPoppedObject(synchronizedStack.pop()); + } + }; + } + + private Command buildWaitToPushCommand(final long timeout) { + return new Command() { + public void execute(SynchronizedStack<String> synchronizedStack) throws Exception { + SynchronizedStackTests.this.setStartTime(System.currentTimeMillis()); + SynchronizedStackTests.this.setTimeoutOccurred( ! synchronizedStack.waitToPush(ITEM_2, timeout)); + SynchronizedStackTests.this.setEndTime(System.currentTimeMillis()); + } + }; + } + + private Runnable buildRunnable(final Command command, final SynchronizedStack<String> synchronizedStack, final long sleep) { + return new Runnable() { + public void run() { + try { + if (sleep != 0) { + Thread.sleep(sleep); + } + command.execute(synchronizedStack); + } catch (Exception ex) { + SynchronizedStackTests.this.setExCaught(true); + } + } + }; + } + + void setExCaught(boolean exCaught) { + this.exCaught = exCaught; + } + + void setTimeoutOccurred(boolean timeoutOccurred) { + this.timeoutOccurred = timeoutOccurred; + } + + void setStartTime(long startTime) { + this.startTime = startTime; + } + + void setEndTime(long endTime) { + this.endTime = endTime; + } + + void setPoppedObject(Object poppedObject) { + this.poppedObject = poppedObject; + } + + long elapsedTime() { + return this.endTime - this.startTime; + } + + + // ********** Command interface ********** + + private interface Command { + void execute(SynchronizedStack<String> synchronizedStack) throws Exception; + } + +} diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java new file mode 100644 index 0000000000..5af287fcfe --- /dev/null +++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java @@ -0,0 +1,528 @@ +/******************************************************************************* + * Copyright (c) 2007 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.utility.tests.internal.node; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jpt.utility.internal.CollectionTools; +import org.eclipse.jpt.utility.internal.HashBag; +import org.eclipse.jpt.utility.internal.Range; +import org.eclipse.jpt.utility.internal.iterators.CloneIterator; +import org.eclipse.jpt.utility.internal.node.AbstractNodeModel; +import org.eclipse.jpt.utility.internal.node.Node; +import org.eclipse.jpt.utility.internal.node.Problem; +import org.eclipse.jpt.utility.tests.internal.TestTools; + +import junit.framework.TestCase; + +public class AbstractNodeModelTests extends TestCase { + private TestWorkbenchModel root; + + public AbstractNodeModelTests(String name) { + super(name); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + this.root = this.buildRoot(); + } + + private TestWorkbenchModel buildRoot() { + TestWorkbenchModel r = new RootTestWorkbenchModel("root"); + TestWorkbenchModel node1 = r.addTestChildNamed("node 1"); + TestWorkbenchModel node1_1 = node1.addTestChildNamed("node 1.1"); + node1_1.addTestChildNamed("node 1.1.1"); + node1_1.addTestChildNamed("node 1.1.2"); + node1_1.addTestChildNamed("node 1.1.3"); + node1.addTestChildNamed("node 1.2"); + TestWorkbenchModel node2 = r.addTestChildNamed("node 2"); + node2.addTestChildNamed("node 2.1"); + node2.addTestChildNamed("node 2.2"); + r.addTestChildNamed("node 3"); + r.addTestChildNamed("node 4"); + + // mark the entire tree clean + r.markEntireBranchClean(); + return r; + } + + @Override + protected void tearDown() throws Exception { + TestTools.clear(this); + super.tearDown(); + } + + public void testTestWorkbenchModel() { + // make sure our test class works OK... + assertNull(this.root.testChildNamed("")); + assertNotNull(this.root.testChildNamed("node 1")); + assertTrue(this.root.testChildNamed("node 1").isClean()); + assertTrue(this.root.testChildNamed("node 1").isCleanBranch()); + assertNotNull(this.root.testChildNamed("node 2")); + assertTrue(this.root.testChildNamed("node 2").isClean()); + assertTrue(this.root.testChildNamed("node 2").isCleanBranch()); + assertNull(this.root.testChildNamed("node 2.1")); + + assertNull(this.root.testDescendantNamed("")); + assertNotNull(this.root.testDescendantNamed("node 1")); + assertNotNull(this.root.testDescendantNamed("node 2")); + assertNotNull(this.root.testDescendantNamed("node 2.1")); + assertTrue(this.root.testDescendantNamed("node 2.1").isClean()); + assertTrue(this.root.testDescendantNamed("node 2.1").isCleanBranch()); + assertNotNull(this.root.testDescendantNamed("node 1.1.3")); + assertTrue(this.root.testDescendantNamed("node 1.1.3").isClean()); + assertTrue(this.root.testDescendantNamed("node 1.1.3").isCleanBranch()); + } + + public void testParentAndChildren() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + assertEquals("node 1.1.3", node.getName()); + assertEquals(0, CollectionTools.size(node.children())); + + node = (TestWorkbenchModel) node.parent(); + assertEquals("node 1.1", node.getName()); + assertEquals(3, CollectionTools.size(node.children())); + + node = (TestWorkbenchModel) node.parent(); + assertEquals("node 1", node.getName()); + assertEquals(2, CollectionTools.size(node.children())); + + node = (TestWorkbenchModel) node.parent(); + assertEquals("root", node.getName()); + assertEquals(4, CollectionTools.size(node.children())); + + node = (TestWorkbenchModel) node.parent(); + assertNull(node); + } + + public void testDirty() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setSize(42); + assertTrue(node.isDirty()); + + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + assertTrue(parent.isClean()); + assertTrue(this.root.isClean()); + } + + public void testDirtyUnchangedAttribute() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setSize(42); + assertTrue(node.isDirty()); + + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + assertTrue(parent.isClean()); + assertTrue(this.root.isClean()); + + this.root.markEntireBranchClean(); + // set size to same number - should stay clean + node.setSize(42); + assertTrue(node.isClean()); + assertTrue(parent.isClean()); + assertTrue(this.root.isClean()); + } + + public void testDirtyBranch() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setSize(42); + assertTrue(node.isDirtyBranch()); + + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + assertTrue(parent.isDirtyBranch()); + assertTrue(this.root.isDirtyBranch()); + + parent.setSize(77); + assertTrue(parent.isDirty()); + assertTrue(parent.isDirtyBranch()); + + node.markEntireBranchClean(); + assertTrue(parent.isDirty()); + assertTrue(parent.isDirtyBranch()); + } + + public void testDirtyBranchCleanChildDirtyParent() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setSize(42); + + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + parent.setSize(77); + assertTrue(parent.isDirty()); + assertTrue(parent.isDirtyBranch()); + + // now, clean the child, but leave the parent dirty + node.markEntireBranchClean(); + assertTrue(parent.isDirty()); + assertTrue(parent.isDirtyBranch()); + } + + public void testDirtyBranchCleanChildDirtyChild() { + TestWorkbenchModel node1 = this.root.testDescendantNamed("node 1.1.1"); + node1.setSize(41); + TestWorkbenchModel node2 = this.root.testDescendantNamed("node 1.1.2"); + node2.setSize(42); + + TestWorkbenchModel parent = (TestWorkbenchModel) node1.parent(); + assertTrue(parent.isClean()); + assertTrue(parent.isDirtyBranch()); + + // now, clean the first child, but leave the second child dirty + node1.markEntireBranchClean(); + assertTrue(parent.isClean()); + assertTrue(parent.isDirtyBranch()); + } + + public void testDirtyBranchForced() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + + assertTrue(node.isClean()); + assertTrue(node.isCleanBranch()); + assertTrue(parent.isClean()); + assertTrue(parent.isCleanBranch()); + assertTrue(this.root.isClean()); + assertTrue(this.root.isCleanBranch()); + + this.root.markEntireBranchDirty(); + + assertTrue(node.isDirty()); + assertTrue(node.isDirtyBranch()); + assertTrue(parent.isDirty()); + assertTrue(parent.isDirtyBranch()); + assertTrue(this.root.isDirty()); + assertTrue(this.root.isDirtyBranch()); + } + + public void testDirtyTransientAttribute() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setName("BOGUS"); + assertTrue(node.isDirty()); + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + assertTrue(parent.isClean()); + assertTrue(parent.isDirtyBranch()); + assertTrue(this.root.isClean()); + assertTrue(this.root.isDirtyBranch()); + + this.root.markEntireBranchClean(); + + this.root.validateBranch(); + + assertTrue(this.root.problemsSize() == 0); + assertTrue(node.branchProblems().hasNext()); + assertTrue(parent.problemsSize() == 0); + assertTrue(parent.branchProblems().hasNext()); + assertTrue(node.problemsSize() > 0); + + // since problems are transient, everything should still be clean + assertTrue(node.isClean()); + assertTrue(node.isCleanBranch()); + assertTrue(parent.isClean()); + assertTrue(parent.isCleanBranch()); + assertTrue(this.root.isClean()); + assertTrue(this.root.isCleanBranch()); + } + + public void testProblems() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setName("BOGUS"); + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + + this.root.validateBranch(); + + assertEquals(0, this.root.problemsSize()); + assertTrue(node.branchProblems().hasNext()); + assertEquals(0, parent.problemsSize()); + assertTrue(parent.branchProblems().hasNext()); + assertEquals(1, node.problemsSize()); + Problem problem1 = node.problems().next(); + + // now create another problem that should remove the old problem + node.setName("STILL BOGUS"); + this.root.validateBranch(); + + assertEquals(0, this.root.problemsSize()); + assertTrue(node.branchProblems().hasNext()); + assertEquals(0, parent.problemsSize()); + assertTrue(parent.branchProblems().hasNext()); + assertEquals(1, node.problemsSize()); + Problem problem2 = node.problems().next(); + assertFalse(problem1 == problem2); + problem1 = problem2; + + // now create another problem that should replace the old problem + node.setName("STILL BOGUS"); + this.root.validateBranch(); + + assertEquals(0, this.root.problemsSize()); + assertTrue(node.branchProblems().hasNext()); + assertEquals(0, parent.problemsSize()); + assertTrue(parent.branchProblems().hasNext()); + assertEquals(1, node.problemsSize()); + problem2 = node.problems().next(); + // the same problem should be there + assertTrue(problem1.equals(problem2)); + } + + public void testBranchProblems() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setName("BOGUS"); + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + parent.setName("BOGUS TOO"); + this.root.setName("BOGUS TOO TOO"); + + this.root.validateBranch(); + + assertEquals(1, this.root.problemsSize()); + assertEquals(3, this.root.branchProblemsSize()); + assertEquals(1, parent.problemsSize()); + assertEquals(2, parent.branchProblemsSize()); + assertEquals(1, node.problemsSize()); + assertEquals(1, node.branchProblemsSize()); + + node.setName("okie-dokie"); + + this.root.validateBranch(); + + assertEquals(1, this.root.problemsSize()); + assertEquals(2, this.root.branchProblemsSize()); + assertEquals(1, parent.problemsSize()); + assertEquals(1, parent.branchProblemsSize()); + assertEquals(0, node.problemsSize()); + assertEquals(0, node.branchProblemsSize()); + } + + public void testClearAllBranchProblems() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setName("BOGUS"); + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + parent.setName("BOGUS TOO"); + this.root.setName("BOGUS TOO TOO"); + + this.root.validateBranch(); + + assertEquals(1, this.root.problemsSize()); + assertEquals(3, this.root.branchProblemsSize()); + assertEquals(1, parent.problemsSize()); + assertEquals(2, parent.branchProblemsSize()); + assertEquals(1, node.problemsSize()); + assertEquals(1, node.branchProblemsSize()); + + parent.clearAllBranchProblems(); + + assertEquals(1, this.root.problemsSize()); + assertEquals(1, this.root.branchProblemsSize()); + assertEquals(0, parent.problemsSize()); + assertEquals(0, parent.branchProblemsSize()); + assertEquals(0, node.problemsSize()); + assertEquals(0, CollectionTools.size(node.branchProblems())); + } + + public void testRemovedBranchProblems() { + TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3"); + node.setName("BOGUS"); + TestWorkbenchModel parent = (TestWorkbenchModel) node.parent(); + parent.setName("BOGUS TOO"); + this.root.setName("BOGUS TOO TOO"); + + this.root.validateBranch(); + + assertEquals(1, this.root.problemsSize()); + assertEquals(3, CollectionTools.size(this.root.branchProblems())); + assertEquals(1, parent.problemsSize()); + assertEquals(2, parent.branchProblemsSize()); + assertEquals(1, node.problemsSize()); + assertEquals(1, CollectionTools.size(node.branchProblems())); + + // completely remove a node that has problems - + // the entire tree should recalculate its "branch" problems + parent.removeTestChild(node); + + this.root.validateBranch(); + + assertEquals(1, this.root.problemsSize()); + assertEquals(2, CollectionTools.size(this.root.branchProblems())); + assertEquals(1, parent.problemsSize()); + assertEquals(1, parent.branchProblemsSize()); + } + + public void testSort() { + List<TestWorkbenchModel> nodes = this.buildSortedNodes(); + assertTrue(new Range(0, 1).includes(this.indexOf(nodes, "aaa"))); + assertTrue(new Range(0, 1).includes(this.indexOf(nodes, "AAA"))); + assertTrue(new Range(2, 3).includes(this.indexOf(nodes, "bbb"))); + assertTrue(new Range(2, 3).includes(this.indexOf(nodes, "BBB"))); + assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "ccc"))); + assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "CCC"))); + assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "���"))); + } + + private int indexOf(List<TestWorkbenchModel> nodes, String nodeName) { + for (int i = nodes.size(); i-- > 0; ) { + if (nodes.get(i).getName().equals(nodeName)) { + return i; + } + } + throw new IllegalArgumentException(); + } + + private List<TestWorkbenchModel> buildSortedNodes() { + List<TestWorkbenchModel> result = new ArrayList<TestWorkbenchModel>(); + result.add(new RootTestWorkbenchModel("AAA")); + result.add(new RootTestWorkbenchModel("BBB")); + result.add(new RootTestWorkbenchModel("CCC")); + result.add(new RootTestWorkbenchModel("���")); + result.add(new RootTestWorkbenchModel("ccc")); + result.add(new RootTestWorkbenchModel("bbb")); + result.add(new RootTestWorkbenchModel("aaa")); + return CollectionTools.sort(result); + } + + + // ********** inner classes ********** + + private class TestWorkbenchModel extends AbstractNodeModel { + private String name; + public static final String NAME_PROPERTY = "name"; + private int size; + public static final String SIZE_PROPERTY = "size"; + private Collection<TestWorkbenchModel> testChildren; + public static final String TEST_CHILDREN_COLLECTION = "children"; + + // ********** construction/initialization ********** + public TestWorkbenchModel(TestWorkbenchModel parent, String name) { + super(parent); + if (name == null) { + throw new NullPointerException(); + } + this.name = name; + } + @Override + protected void initialize() { + super.initialize(); + this.size = 0; + this.testChildren = new HashBag<TestWorkbenchModel>(); + } + + @Override + protected void checkParent(Node parent) { + // do nothing + } + + + // ********** accessors ********** + public String getName() { + return this.name; + } + public void setName(String name) { + Object old = this.name; + this.name = name; + this.firePropertyChanged(NAME_PROPERTY, old, name); + } + + public int getSize() { + return this.size; + } + public void setSize(int size) { + int old = this.size; + this.size = size; + this.firePropertyChanged(SIZE_PROPERTY, old, size); + } + + public Iterator<TestWorkbenchModel> testChildren() { + return new CloneIterator<TestWorkbenchModel>(this.testChildren) { + @Override + protected void remove(TestWorkbenchModel current) { + TestWorkbenchModel.this.removeTestChild(current); + } + }; + } + public int testChildrenSize() { + return this.testChildren.size(); + } + private TestWorkbenchModel addTestChild(TestWorkbenchModel testChild) { + this.addItemToCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION); + return testChild; + } + public TestWorkbenchModel addTestChildNamed(String childName) { + if (this.testChildNamed(childName) != null) { + throw new IllegalArgumentException(childName); + } + return this.addTestChild(new TestWorkbenchModel(this, childName)); + } + public void removeTestChild(TestWorkbenchModel testChild) { + this.removeItemFromCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION); + } + + // ********** queries ********** + public String displayString() { + return this.name; + } + public TestWorkbenchModel testChildNamed(String childName) { + for (TestWorkbenchModel testChild : this.testChildren) { + if (testChild.getName().equals(childName)) { + return testChild; + } + } + return null; + } + public TestWorkbenchModel testDescendantNamed(String descendantName) { + for (TestWorkbenchModel testDescendant : this.testChildren) { + if (testDescendant.getName().equals(descendantName)) { + return testDescendant; + } + // recurse... + testDescendant = testDescendant.testDescendantNamed(descendantName); + if (testDescendant != null) { + return testDescendant; + } + } + return null; + } + + // ********** behavior ********** + @Override + protected void addChildrenTo(List<Node> children) { + super.addChildrenTo(children); + children.addAll(this.testChildren); + } + @Override + protected void addProblemsTo(List<Problem> currentProblems) { + super.addProblemsTo(currentProblems); + // names must be all lowercase... + for (int i = this.name.length(); i-- > 0; ) { + char c = this.name.charAt(i); + if (Character.isLetter(c) && ! Character.isLowerCase(c)) { + currentProblems.add(this.buildProblem("NAME_MUST_BE_LOWERCASE", this.name)); + return; + } + } + } + @Override + public void toString(StringBuffer sb) { + sb.append(this.name); + } + } + + + private class RootTestWorkbenchModel extends TestWorkbenchModel { + public RootTestWorkbenchModel(String name) { + super(null, name); + } + @Override + public Validator validator() { + return Node.NULL_VALIDATOR; + } + } + +} + diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java new file mode 100644 index 0000000000..e16c3baecd --- /dev/null +++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.utility.tests.internal.node; + +import org.eclipse.jpt.utility.internal.ClassTools; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class JptUtilityNodeTests { + + public static Test suite() { + TestSuite suite = new TestSuite(ClassTools.packageNameFor(JptUtilityNodeTests.class)); + + suite.addTestSuite(AbstractNodeModelTests.class); + + return suite; + } + + private JptUtilityNodeTests() { + super(); + } + +} |