From: ehilsdal
Sample Exercise: The main point of this exercise +is to make sure your configuration works. We have provided the +answer to this exercise below, so XXX. You need not go through the +thought process of fixing this
+ + Task: Signal a warning for calls to
+System.out.println
.
+
The way that we are all taught to print "hello world" from Java is
to use System.out.println()
, so that is what we typically
use for one-off debugging traces. It's a common mistake to leave
@@ -135,8 +144,8 @@ users who bind System.out to a static field to save typing.
Problem: Add warnings for assignments outside of setter methods. -
+Task: Signal a warning for assignments outside +of setter methods.
Tools: set
, withincode
,
signature void set*(..)
@@ -157,30 +166,26 @@ aspect A {
where the pointcut picks out join points of private field sets
outside of setter methods. "Outside", here, means that the code for
-the assignment is outside the text of the setter (a setter is
-a method that looks like "void set*(..)"), so check out the quick
-reference for set
and withincode
primitive
-pointcuts. )
Make sure your program still passes the JUnit test
tests.Test
before continuing, and that you see all of the
following warning messages. Make sure you get 11 warnings from this.
-Wait to fix them until the next exercise.
-
Problem: Allow assignmnents inside of constructors. +
Task: Allow assignmnents inside of constructors.
Tools: signature new(..)
Look at some of the warnings. Notice that a lot of them are from
-within constructors. Actually, the common coding convention is that
-no private field should be set outside of setter methods
Look at some of the warnings from the previous exercise. Notice +that a lot of them are from within constructors. Actually, the common +coding convention is that no private field should be set outside of +setter methods or constructors. Modify your answer (in a new +file) to signal an actual error at compile time (rather than just a +warning) when such an illegal assignment expression exists.
You'll want to add another withincode
primitive
pointcut to deal with the constructors.
@@ -219,13 +224,16 @@ them.
Problem: Pass tests.Test2a
.
-
Sample Exercise: The main point of this exercise +is to make sure your configuration works. We have provided the +answer to this exercise below, so XXX. You need not go through the +thought process of fixing this
- Tools: args
, before
+
+
Task: Pass tests.Test2a
.
THERE IS AN ANSWER BELOW. LOOK AT IT. TYPE IT IN. +
Tools: args
, before
Write an aspect to throw an IllegalArgumentException
@@ -275,45 +283,33 @@ import figures.*;
aspect Answer2a {
before(int newValue): set(int Point.*) && args(newValue) {
- if (newValue < FigureElement.MIN_VALUE) {
+ if (newValue < 0) {
throw new IllegalArgumentException("too small");
- } else if (newValue > FigureElement.MAX_VALUE) {
- throw new IllegalArgumentException("too large");
- }
+ }
}
}
Task: Pass tests.Test2b
.
Group
is a FigureElement
class that
encapsulates groups of other figure elements. As such, only actual
-figure element objects should be added to Group
objects. Write
-an aspect to throw an IllegalArgumentException
whenever
-Group.add()
is called with a
-null
value. If you look at the source code for
-tests/Test2b.java, you'll see an example of the desired behavior,
-i.e.
Group
objects.
+Write an aspect to throw an IllegalArgumentException
+whenever Group.add()
is called with a null
+value.
-- public void testNull() { - try { - g.add(null); - fail("should have thrown IllegalArgumentException"); - } catch (IllegalArgumentException ea) { - } - } -+
Look at tests/Test2b.java
to see exactly what we're
+testing for.
For each of these exercises, you'll find that the corresponding -test case provides that most concrete example of the desired behavior -for your aspect. Please avail yourself of this resource.
+ With this aspect in place, your code should pass
-tests.Test2b
.
-
Task: Pass tests.Test2c
.
Tools: target
+
Another constraint on a well-formed group is that it should not
contain itself as a member (though it may contain other groups). Write
@@ -326,10 +322,71 @@ an attempt is made to call Group.add()
on a
call.
With this aspect in place, your code should pass
-tests.Test2c
.
+XXX RENUMBER LATER
+
+
Task: Pass tests.Test2g
.
Tools: around advice +
+ + Instead of throwing an exception when one of Point
's
+int
fields are set to an out-of-bounds value, write an
+aspect to trim the value into an in-bounds one. You'll want to use
+around
advice that exposes the new value of the field
+assignment with an args
pointcut, and
+proceed
with the trimmed value.
Task: Pass tests.Test2e
+
Tools: around advice +
+ + A postcondition of a Point
's move
+operation is that the Point
's coordinates should change.
+If a call to move move didn't actually move a point by the desired
+offset, then the point is in an illegal state and so an
+IllegalStateException
should be thrown.
+
Note that because we're dealing with how the coordinates change +during move, we need some way of getting access to the coordinates +both before and after the move, in one piece of advice.
+ + Task: Pass tests.Test2f
+
Tools: the Rectangle(Rectangle)
+constructor, the Rectangle.translate(int, int)
method.
+
FigureElement
objects have a getBounds()
+method that returns a java.awt.Rectangle
representing the
+bounds of the object. An important postcondition of the general
+move
operation on a figure element is that the figure
+element's bounds rectangle should move by the same amount as the
+figure itself. Write an aspect to check for this postcondition --
+throw an IllegalStateException
if it is violated.
At this point, check the people to your left and right. If +they're stuck somewhere, see if you can help them.
+ + + +One of the simplest postconditions to check is that a setter @@ -352,6 +409,7 @@ when it returns normally, or both?
tests.Test2d
.
+
There is a method on the Make sure to pass the JUnit test Instead of throwing an exception when one of Make sure to pass the JUnit test Answer:
- Note that because we're dealing with how the bounds changes during
-move, we need some way of getting access to the bounds both before
-and after the move, in one piece of advice. Also, note that
-you can create a copy of a figure element's bounds rectangle with
- Make sure to pass the JUnit test At this point, check the people to your left and right. If
-they're stuck somewhere, see if you can help them. The crosscutting feature you will be adding in part (4) will be
support for caching the bound objects of Box
class, void
@@ -398,77 +456,7 @@ causes the VM to abort.)
tests.Test2f
before continuing. g. Assure input
-
-Point
's
-int
fields are set to an out-of-bounds value, write an
-aspect to trim the value into an in-bounds one. You'll want to use
-around
advice that exposes the new value of the field
-assignment with an args
pointcut, and
-proceed
with the trimmed value. Becuase this is tricky,
-type in the below aspect... the trick for this exercise is not to come
-up with an answer, but to understand the answer. tests.Test2g
-before continuing.
-
-
-
-package answers;
-
-import figures.*;
-
-aspect Answer2g {
- int around(int val):
- (set(int Point._x) || set(int Point._y))
- && args(val) {
- return proceed(trim(val));
- }
-
- private int trim(int val) {
- return Math.max(Math.min(val, FigureElement.MAX_VALUE),
- FigureElement.MIN_VALUE);
- }
-}
-
h. Check another invariant
-
-FigureElement
objects have a getBounds()
-method that returns a java.awt.Rectangle
representing the
-bounds of the object. An important postcondition of the
-move
operation is that the figure element's bounds
-rectangle should move by the same amount as the figure itself. Write
-an aspect to check for this postcondition -- throw an
-IllegalStateException
if it is violated. new Rectangle(fe.getBounds())
, and you can move a bounds
-rectangle rect
with rect.translate(dx,
-dy)
. tests.Test2h
-before continuing. Help Yourself by Helping Others
-
-
-
-
-3. Logging
+==================================================
Group
figure
diff --git a/docs/teaching/exercises/tests/Test2a.java b/docs/teaching/exercises/tests/Test2a.java
index 0b737020b..4bc6dd28a 100644
--- a/docs/teaching/exercises/tests/Test2a.java
+++ b/docs/teaching/exercises/tests/Test2a.java
@@ -16,18 +16,16 @@ import figures.*;
import junit.framework.*;
-public class Test2a extends Test {
+public class Test2a extends TestCase {
public Test2a(String name) { super(name); }
public static void main(String[] args) {
+ junit.textui.TestRunner.run(Test.class);
junit.textui.TestRunner.run(Test2a.class);
}
- public void setUp() {
- super.setUp();
- }
-
public void testTooSmall() {
+ Point p1 = new Point(10, 100);
try {
p1.setX(-10);
fail("should have thrown IllegalArgumentException");
@@ -35,17 +33,13 @@ public class Test2a extends Test {
}
}
-
- public void testTooBig() {
- try {
- p1.setY(1000);
- fail("should have thrown IllegalArgumentException");
- } catch (IllegalArgumentException ea) {
- }
+ public void testNotTooSmall() {
+ Point p1 = new Point(10, 100);
+ p1.setX(0);
}
-
public void testMove() {
+ Line l1 = new Line(new Point(10, 100), new Point(20, 200));
try {
l1.move(-500, -500);
fail("should have thrown IllegalArgumentException");
diff --git a/docs/teaching/exercises/tests/Test2b.java b/docs/teaching/exercises/tests/Test2b.java
index e127b5cc4..822c8de74 100644
--- a/docs/teaching/exercises/tests/Test2b.java
+++ b/docs/teaching/exercises/tests/Test2b.java
@@ -16,22 +16,31 @@ import figures.*;
import junit.framework.*;
-public class Test2b extends Test {
+public class Test2b extends TestCase {
public Test2b(String name) { super(name); }
public static void main(String[] args) {
+ junit.textui.TestRunner.run(Test.class);
junit.textui.TestRunner.run(Test2b.class);
}
- public void setUp() {
- super.setUp();
- }
-
public void testNull() {
+ Point p1 = new Point(10, 100);
+ Group g = new Group(p1);
+
try {
g.add(null);
fail("should have thrown IllegalArgumentException");
} catch (IllegalArgumentException ea) {
}
}
+
+ public void testNonNull() {
+ Point p1 = new Point(10, 100);
+ Group g = new Group(p1);
+ Point p2 = new Point(20, 200);
+
+ g.add(p2);
+ }
+
}
diff --git a/docs/teaching/exercises/tests/Test2c.java b/docs/teaching/exercises/tests/Test2c.java
index 153739fc0..01c4978e4 100644
--- a/docs/teaching/exercises/tests/Test2c.java
+++ b/docs/teaching/exercises/tests/Test2c.java
@@ -16,30 +16,31 @@ import figures.*;
import junit.framework.*;
-public class Test2c extends Test {
+public class Test2c extends TestCase {
public Test2c(String name) { super(name); }
public static void main(String[] args) {
+ junit.textui.TestRunner.run(Test.class);
+ junit.textui.TestRunner.run(Test2b.class);
junit.textui.TestRunner.run(Test2c.class);
}
- public void setUp() {
- super.setUp();
- }
+ public void testSelf() {
+ Point p1 = new Point(10, 100);
+ Group g = new Group(p1);
- public void testNull() {
try {
- g.add(null);
+ g.add(g);
fail("should have thrown IllegalArgumentException");
} catch (IllegalArgumentException ea) {
}
}
- public void testSelf() {
- try {
- g.add(g);
- fail("should have thrown IllegalArgumentException");
- } catch (IllegalArgumentException ea) {
- }
+ public void testNotSelf() {
+ Point p1 = new Point(10, 100);
+ Group g1 = new Group(p1);
+ Group g2 = new Group(p1);
+
+ g1.add(g2);
}
}
diff --git a/docs/teaching/exercises/tests/Test2d.java b/docs/teaching/exercises/tests/Test2d.java
index b8056fbf3..cc8d7f51c 100644
--- a/docs/teaching/exercises/tests/Test2d.java
+++ b/docs/teaching/exercises/tests/Test2d.java
@@ -16,22 +16,31 @@ import figures.*;
import junit.framework.*;
-public class Test2d extends Test {
+public class Test2d extends TestCase {
public Test2d(String name) { super(name); }
public static void main(String[] args) {
+ junit.textui.TestRunner.run(Test.class);
junit.textui.TestRunner.run(Test2d.class);
}
- public void setUp() {
- super.setUp();
+ public void testOutOfBounds() {
+ Point p1 = new Point(10, 100);
+
+ p1.setX(-10);
+ p1.setY(-100);
+
+ assertEquals(0, p1.getX());
+ assertEquals(0, p1.getY());
}
- public void testSetting() {
- try {
- sloth1.setX(10);
- fail("should have thrown RuntimeException");
- } catch (RuntimeException ea) {
- }
+ public void testInBounds() {
+ Point p1 = new Point(10, 100);
+
+ p1.setX(30);
+ p1.setY(300);
+
+ assertEquals(30, p1.getX());
+ assertEquals(300, p1.getY());
}
}
diff --git a/docs/teaching/exercises/tests/Test2e.java b/docs/teaching/exercises/tests/Test2e.java
index dfa456138..09ab65790 100644
--- a/docs/teaching/exercises/tests/Test2e.java
+++ b/docs/teaching/exercises/tests/Test2e.java
@@ -16,27 +16,24 @@ import figures.*;
import junit.framework.*;
-public class Test2e extends Test {
+public class Test2e extends TestCase {
public Test2e(String name) { super(name); }
public static void main(String[] args) {
+ junit.textui.TestRunner.run(Test.class);
junit.textui.TestRunner.run(Test2e.class);
}
- public void setUp() {
- super.setUp();
- }
-
- public void testEasy() {
- Box sq = new Box(0, 0, 10, 10);
- sq.move(5,5);
- assertEquals(sq.getP0().getX(), 5);
- assertEquals(sq.getP0().getY(), 5);
-
+ public void testSloth() {
+ Point sp = new SlothfulPoint(10, 10);
try {
- sq.getP0().setX(100);
- sq.move(37, 1);
+ sp.move(10, 10);
fail("should have thrown IllegalStateException");
} catch (IllegalStateException e) { }
}
+
+ public void testNonSloth() {
+ Point p1 = new Point(10, 100);
+ p1.move(3, 30);
+ }
}
diff --git a/docs/teaching/exercises/tests/Test2f.java b/docs/teaching/exercises/tests/Test2f.java
index a11e16781..1b90d268a 100644
--- a/docs/teaching/exercises/tests/Test2f.java
+++ b/docs/teaching/exercises/tests/Test2f.java
@@ -20,23 +20,23 @@ public class Test2f extends Test {
public Test2f(String name) { super(name); }
public static void main(String[] args) {
+ junit.textui.TestRunner.run(Test.class);
junit.textui.TestRunner.run(Test2f.class);
}
- public void setUp() {
- super.setUp();
- }
-
- public void testEasy() {
- Box sq = new Box(0, 0, 10, 10);
- sq.move(5,5);
- assertEquals(sq.getP0().getX(), 5);
- assertEquals(sq.getP0().getY(), 5);
-
+ public void testSloth() {
+ FigureElement fe = new SlothfulPoint(10, 10);
try {
- sq.getP0().setX(100);
- sq.getP1();
+ fe.move(10, 10);
fail("should have thrown IllegalStateException");
} catch (IllegalStateException e) { }
}
+
+ public void testNonSloth() {
+ Point p1 = new Point(10, 100);
+ Point p2 = new Point(20, 200);
+ Line l1 = new Line(p1, p2);
+
+ l1.move(3, 30);
+ }
}
diff --git a/docs/teaching/exercises/tests/Test2g.java b/docs/teaching/exercises/tests/Test2g.java
deleted file mode 100644
index f4a7a1949..000000000
--- a/docs/teaching/exercises/tests/Test2g.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
-package tests;
-
-import figures.*;
-
-import junit.framework.*;
-
-public class Test2g extends Test {
- public Test2g(String name) { super(name); }
-
- public static void main(String[] args) {
- junit.textui.TestRunner.run(Test2g.class);
- }
-
- public void setUp() {
- super.setUp();
- }
-
- public void testBounds() {
- p1.setX(FigureElement.MAX_VALUE + 1);
- assertEquals(FigureElement.MAX_VALUE, p1.getX());
- p1.setY(FigureElement.MIN_VALUE - 1);
- assertEquals(FigureElement.MIN_VALUE, p1.getY());
- }
-
- public void testBox() {
- Box s = new Box(50, 50, 20000, 20000);
- assertEquals(FigureElement.MAX_VALUE, s.getP2().getX());
- assertEquals(FigureElement.MAX_VALUE, s.getP2().getY());
- }
-}
diff --git a/docs/teaching/exercises/tests/Test2h.java b/docs/teaching/exercises/tests/Test2h.java
deleted file mode 100644
index 339322519..000000000
--- a/docs/teaching/exercises/tests/Test2h.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
-package tests;
-
-import figures.*;
-
-import junit.framework.*;
-
-public class Test2h extends Test {
- public Test2h(String name) { super(name); }
-
- public static void main(String[] args) {
- junit.textui.TestRunner.run(Test2h.class);
- }
-
- public void setUp() {
- super.setUp();
- }
-
- public void testSloth() {
- FigureElement fe = new SlothfulPoint(10, 10);
- try {
- fe.move(10, 10);
- fail("should have thrown IllegalStateException");
- } catch (IllegalStateException e) { }
- }
-
- public void movePoints() {
- p1.move(30, 45);
- p2.move(10, 33);
- }
-}