summaryrefslogtreecommitdiffstats
path: root/tests/new/AroundHandler.java
blob: ac9e9e2e18d35c7b1c686f9bb503e9d56251c7d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import org.aspectj.testing.Tester;
import org.aspectj.testing.Tester; 

/*
  These test advice on handlers:
  1) can use before advice to skip handler by throwing Error
  2) can use after advice after running handler and  throw  Error
  3) can use around advice [skip | run] X [ throw Error or complete normally ]
    a) skip without throwing error
    b) skip with throwing error
    c) run without throwing error
    d) run with throwing error

 Rather than overload advice at join points,
 there is one method and one advice for each of the 6 test cases.
 */
/** @testcase VerifyError after around advice falls off end of tryCatch */
public class AroundHandler {
    /** if true, then run the around test cases */
    public static final boolean TEST_AROUND = true ;  
    public static void main(String[] args) {
        Target target = new Target();
        /** @testcase before advice skips handler by throwing Error */
        Tester.check(target.skipBeforeErrorHandler(), "target.skipBeforeErrorHandler()");
        /** @testcase after advice runs handler, throws Error */
        Tester.check(target.runAfterErrorHandler(), "target.runAfterErrorHandler()");
        if (TEST_AROUND) {
            /** @testcase around advice skips handler, no Error thrown */
            Tester.check(target.skipErrorHandler(), "target.skipErrorHandler()");
            /** @testcase around advice runs handler, no Error thrown */
            Tester.check(target.runErrorHandler(), "target.runErrorHandler()");
            /** @testcase around advice skips handler, throws exception from around advice */
            Tester.expectEvent("skipErrorHandlerGotError");
            try {
                target.skipErrorHandlerThrowError();
                Tester.check(false, "expecting Error thrown by around");
            } catch (Error e) {
                Target.isERR(e);
                Tester.event("skipErrorHandlerGotError");
            }
            /** @testcase around advice runs handler, throws exception from around advice */
            Tester.expectEvent("runErrorHandlerThrowError");
            Tester.expectEvent("runErrorHandlerGotError");
            try {
                target.runErrorHandlerThrowError();
                Tester.check(false, "expecting Error thrown by around");
            } catch (Error e) {
                Target.isERR(e);
                Tester.event("runErrorHandlerGotError");
            }
        } // TEST_AROUND
    }
}
class OuterError extends Error {
    public OuterError(String s) { super(s); }
}
class Target {
    public static String ERR = "goto Error";
    public static void isERR(Throwable throwable) {
        String message = (null == throwable ? "" : throwable.getMessage());
        Tester.check(Target.ERR.equals(message),
                    "\"" + ERR + "\".equals(\"" + message + "\")");
    } 

    /** advised by before */
    public boolean skipBeforeErrorHandler() {
        boolean ranHandler = false;
        boolean ranOuterHandler = false;
        try {
            try { throw new Error(ERR); } 
            catch (Error t) { ranHandler = true; }
        } catch (OuterError t) { ranOuterHandler = true; }
        Tester.check(!ranHandler, "!ranHandler"); 
        Tester.check(ranOuterHandler, "ranOuterHandler"); 
        return (!ranHandler && ranOuterHandler);
    }

    /** advised by after */
    public boolean runAfterErrorHandler() {
        boolean ranHandler = false;
        boolean ranOuterHandler = false;
        try {
            try { throw new Error(ERR); } 
            catch (Error t) { ranHandler = true; }
        } catch (OuterError t) { ranOuterHandler = true; }
        Tester.check(ranHandler, "!ranHandler"); 
        Tester.check(ranOuterHandler, "ranOuterHandler"); 
        return (ranHandler && ranOuterHandler);
    }

    //---------------- remainder all advised using around 
    public boolean skipErrorHandler() {
        boolean ranHandler = false;
        try { throw new Error(ERR); } 
        catch (Error t) { ranHandler = true; }
        Tester.check(!ranHandler, "!ranHandler"); 
        return !ranHandler;
    }

    public boolean runErrorHandler() {
        boolean ranHandler = false;
        try { throw new Error(ERR); } 
        catch (Error t) { ranHandler = true; }
        Tester.check(ranHandler, "ranHandler"); 
        return ranHandler;
    }    

    public boolean skipErrorHandlerThrowError() {
        try { throw new Error(ERR); } 
        catch (Error t) { 
            Tester.check(false, "skipErrorHandlerThrowError ran handler"); 
        }
        return false; // should never get here - Error thrown
    }

    public boolean runErrorHandlerThrowError() {
        try { throw new Error(ERR); } 
        catch (Error t) { 
            Tester.event("runErrorHandlerThrowError");
        }
        return false; // should never get here - Error thrown
    }
}

aspect A {
    /** @testcase use before to skip handler by throwing Error from advice */
     before(Error error) 
        : withincode(boolean Target.skipBeforeErrorHandler()) 
        && handler(Error) && args(error) 
        {
        Target.isERR(error);
        throw new OuterError(Target.ERR);
    }

    /** @testcase use after to run handler but throw Error from advice */
     after(Error error) 
        : withincode(boolean Target.runAfterErrorHandler()) 
        && handler(Error) && args(error) 
        {
        Target.isERR(error);
        throw new OuterError(Target.ERR);
    }

    // -------------------- around advice

    /** @testcase use around, run handler */
    Object around(Error error) 
        : withincode(boolean Target.runErrorHandler())
        && handler(Error) && args(error) 
        && if(AroundHandler.TEST_AROUND)
        {
        Target.isERR(error);
        return proceed(error);
    }

    /** @testcase use around to skip handler, throw no Error from around */
    Object around(Error error) 
        : withincode(boolean Target.skipErrorHandler()) 
        && handler(Error) && args(error) 
        && if(AroundHandler.TEST_AROUND)
        {
        Target.isERR(error);
        //Object ignore = proceed(error);
        //throw new Error(Target.ERR);
        return null;
    }

    /** @testcase use around to skip handler, but throw Error from around */
    Object around(Error error) 
        : withincode(boolean Target.skipErrorHandlerThrowError()) 
        && handler(Error) && args(error) 
        && if(AroundHandler.TEST_AROUND)
        {
        Target.isERR(error);
        //Object ignore = proceed(error);
        throw new OuterError(Target.ERR);
        //return null;
    }

     /** @testcase use around, run handler, but throw Error from around */
    Object around(Error error) 
        : withincode(boolean Target.runErrorHandlerThrowError()) 
        && handler(Error) && args(error) 
        && if(AroundHandler.TEST_AROUND)
        {
        Target.isERR(error);
        Object result = proceed(error);
        throw new OuterError(Target.ERR);
        // return result;
    }
}