// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. // This library defines a set of test functions 'xxxAsBoolean" and a check // combinator called `check` which test the runtime behavior of conversions // of values in boolean condional positions (e.g. the condition of a conditional // statement). // // For example: calling `check(dynamicAsBoolean, value, expectation)` tests that // using `value` as the condition in a number of different syntactic constructs // with static type `dynamic` behaves as expected by `expectation`, where // `expectation` should be one of: // Expect.throwsAssertionError if a null conversion error is expected // Expect.throwsTypeError if an implicit cast error is expected // expectOk if no runtime error is expected. void expectOk(void Function() f) { f(); } final int constructsTested = 11; void check(void Function(T, int) test, T value, void Function(void Function()) expectation) { for (int i = 0; i < constructsTested; i++) { expectation(() => test(value, i)); } } void neverAsBoolean(Never value, int index) { // Check that values of type `Never` are boolean converted appropriately // In strong checking mode, this code is unreachable. In weak checking mode, // we may get passed `null` for `value`, and so we check that the `null` value // causes an assertion error to be thrown appropriately. switch (index) { case 0: if (value) {} break; case 1: [if (value) 3]; break; case 2: value ? 3 : 4; break; case 3: while (value) { break; } break; case 4: var done = false; do { if (done) break; done = true; } while (value); break; case 5: value || true; break; case 6: value && true; break; case 7: false || value; break; case 8: true && value; break; case 9: for (int i = 0; value; i++) { break; } break; case 10: [for (int i = 0; value; i++) 3]; break; default: throw "Invalid index"; } } void booleanAsBoolean(bool value, int index) { // Check that values of type `boolean` are boolean converted appropriately switch (index) { case 0: if (value) {} break; case 1: [if (value) 3]; break; case 2: value ? 3 : 4; break; case 3: while (value) { break; } break; case 4: var done = false; do { if (done) break; done = true; } while (value); break; case 5: value || true; break; case 6: value && true; break; case 7: false || value; break; case 8: true && value; break; case 9: for (int i = 0; value; i++) { break; } break; case 10: [for (int i = 0; value; value = false) 3]; break; default: throw "Invalid index"; } } void dynamicAsBoolean(dynamic value, int index) { // Check that values of type `dynamic` are boolean converted appropriately switch (index) { case 0: if (value) {} break; case 1: [if (value) 3]; break; case 2: value ? 3 : 4; break; case 3: while (value) { break; } break; case 4: var done = false; do { if (done) break; done = true; } while (value); break; case 5: value || true; break; case 6: value && true; break; case 7: false || value; break; case 8: true && value; break; case 9: for (int i = 0; value; i++) { break; } break; case 10: [for (int i = 0; value; value = false) 3]; break; default: throw "Invalid index"; } }