OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /** A function that accepts 0..2 arguments and records calls. */ |
| 6 void poly([a, b]) { |
| 7 polyCount++; |
| 8 polyArg = a; |
| 9 } |
| 10 |
| 11 /** First argument of most recent call to [poly]. */ |
| 12 var polyArg = 0; |
| 13 |
| 14 /** Number of calls to [poly]. */ |
| 15 var polyCount = 0; |
| 16 |
| 17 // Four (Super)classes that declare an "assert" member. |
| 18 |
| 19 class SuperGet { |
| 20 /** Declare "assert" as a getter. */ |
| 21 get assert => poly; |
| 22 |
| 23 /** |
| 24 * A method that shold see an 'assert' declaration in scope and not |
| 25 * not act as an assertion. |
| 26 */ |
| 27 void lexicalAssert(x) { |
| 28 assert(x); |
| 29 } |
| 30 } |
| 31 |
| 32 class SuperMethod { |
| 33 /** Declare "assert" as a method. */ |
| 34 assert([a, b]) => poly(a, b); |
| 35 |
| 36 void lexicalAssert(x) { |
| 37 assert(x); |
| 38 } |
| 39 } |
| 40 |
| 41 class SuperField { |
| 42 /** Declare "assert" as a field. */ |
| 43 var assert; |
| 44 SuperField() : assert = poly; |
| 45 |
| 46 void lexicalAssert(x) { |
| 47 assert(x); |
| 48 } |
| 49 } |
| 50 |
| 51 class SuperNon { |
| 52 /** Implementation of "assert" calls on this. */ |
| 53 noSuchMethod(x, y) { |
| 54 switch (y.length) { |
| 55 case 0: return poly(); |
| 56 case 1: return poly(y[0]); |
| 57 case 2: return poly(y[0], y[1]); |
| 58 } |
| 59 } |
| 60 |
| 61 void lexicalAssert(x) { |
| 62 // Hack, since there is no lexically enclosing 'assert' declaration here, |
| 63 // so just act as if there was to avoid special casing it in the test. |
| 64 poly(x); |
| 65 } |
| 66 } |
| 67 |
| 68 // Corresponding sub-classes that read/call "assert" in different ways. |
| 69 // In every case except "assert(exp);" (in the "assert1" methods) this should |
| 70 // access the superclass member. |
| 71 |
| 72 class SubGet extends SuperGet { |
| 73 /** Read assert as a variable. */ |
| 74 void getAssert(x) { |
| 75 assert; |
| 76 } |
| 77 /** Call "assert" with zero arguments. */ |
| 78 void assert0(x) { |
| 79 assert(); |
| 80 } |
| 81 /** Make an actual assertion. */ |
| 82 void assert1(x) { |
| 83 assert(x); |
| 84 } |
| 85 /** Call "assert" with one argument in expression context. */ |
| 86 void assertExp(x) { |
| 87 var z = assert(x); |
| 88 } |
| 89 /** Call "assert" with two arguments. */ |
| 90 void assert2(x) { |
| 91 assert(x, x); |
| 92 } |
| 93 } |
| 94 |
| 95 class SubMethod extends SuperMethod { |
| 96 void getAssert(x) { |
| 97 assert; |
| 98 } |
| 99 void assert0(x) { |
| 100 assert(); |
| 101 } |
| 102 void assert1(x) { |
| 103 assert(x); |
| 104 } |
| 105 void assertExp(x) { |
| 106 var z = assert(x); |
| 107 } |
| 108 void assert2(x) { |
| 109 assert(x, x); |
| 110 } |
| 111 } |
| 112 |
| 113 class SubField extends SuperField { |
| 114 void getAssert(x) { |
| 115 assert; |
| 116 } |
| 117 void assert0(x) { |
| 118 assert(); |
| 119 } |
| 120 void assert1(x) { |
| 121 assert(x); |
| 122 } |
| 123 void assertExp(x) { |
| 124 var z = assert(x); |
| 125 } |
| 126 void assert2(x) { |
| 127 assert(x, x); |
| 128 } |
| 129 } |
| 130 |
| 131 class SubNon extends SuperNon { |
| 132 void getAssert(x) { |
| 133 assert; |
| 134 } |
| 135 assert0(x) { |
| 136 assert(); |
| 137 } |
| 138 void assert1(x) { |
| 139 assert(x); |
| 140 } |
| 141 void assertExp(x) { |
| 142 var z = assert(x); |
| 143 } |
| 144 void assert2(x) { |
| 145 assert(x, x); |
| 146 } |
| 147 } |
| 148 |
| 149 |
| 150 testAssertDeclared() { |
| 151 var get = new SubGet(); |
| 152 var method = new SubMethod(); |
| 153 var field = new SubField(); |
| 154 var non = new SubNon(); |
| 155 |
| 156 void expectCallsPoly(code, [bool noArgument = false]) { |
| 157 int oldPolyCount = polyCount; |
| 158 int newPolyArg = polyArg + 1; |
| 159 int expectedPolyArg = noArgument ? null : newPolyArg; |
| 160 code(newPolyArg); |
| 161 Expect.equals(oldPolyCount + 1, polyCount); |
| 162 Expect.equals(expectedPolyArg, polyArg); |
| 163 if (noArgument) polyArg = newPolyArg; |
| 164 } |
| 165 |
| 166 void expectAssert(code) { |
| 167 int oldPolyCount = polyCount; |
| 168 // Detect whether asserts are enabled. |
| 169 bool assertsEnabled = false; |
| 170 assert(assertsEnabled = true); |
| 171 try { |
| 172 code(polyArg + 1); |
| 173 // If asserts are enabled, we should not get here. |
| 174 // If they are not, the call does nothing. |
| 175 if (assertsEnabled) { |
| 176 Expect.fail("Didn't call assert with asserts enabled."); |
| 177 } |
| 178 } on AssertionError catch (e) { |
| 179 if (!assertsEnabled) Expect.fail("Called assert with asserts disabled?"); |
| 180 } |
| 181 Expect.equals(oldPolyCount, polyCount); |
| 182 } |
| 183 |
| 184 // Sanity check. |
| 185 expectCallsPoly(poly); |
| 186 |
| 187 // Doesn't fail to read "assert". |
| 188 get.getAssert(0); |
| 189 method.getAssert(0); |
| 190 field.getAssert(0); |
| 191 expectCallsPoly(non.getAssert, true); // Hits 'noSuchMethod' for the getter. |
| 192 |
| 193 // Check when 'assert' is a superclass member declaration (or, simulated with |
| 194 // noSuchMethod). |
| 195 void testSuperAssert(object) { |
| 196 expectCallsPoly(object.assert0, true); |
| 197 expectAssert(object.assert1); |
| 198 expectCallsPoly(object.assertExp); |
| 199 expectCallsPoly(object.assert2); |
| 200 expectCallsPoly(object.lexicalAssert); |
| 201 } |
| 202 |
| 203 testSuperAssert(get); |
| 204 testSuperAssert(method); |
| 205 testSuperAssert(field); |
| 206 testSuperAssert(non); |
| 207 |
| 208 // A local declaration will inhibit assert-behavior. |
| 209 |
| 210 expectCallsPoly((x) { |
| 211 // Declare "assert" as a local variable. |
| 212 var assert = poly; |
| 213 assert(x); |
| 214 }); |
| 215 |
| 216 expectCallsPoly((x) { |
| 217 // Declare "assert" as a local function. |
| 218 void assert(x) => poly(x); |
| 219 assert(x); |
| 220 }); |
| 221 } |
| 222 |
| 223 main() { |
| 224 testAssertDeclared(); |
| 225 } |
OLD | NEW |