dart-sdk/tests/language/string/interpolation_and_buffer_test.dart
Robert Nystrom 1b2454b85e Migrate language_2/string to null safety.
Change-Id: Ib09f268c8a8edffba007cdd4962550a5e78ff808
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151090
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Bob Nystrom <rnystrom@google.com>
Auto-Submit: Bob Nystrom <rnystrom@google.com>
2020-06-17 21:14:43 +00:00

60 lines
2.2 KiB
Dart

// Copyright (c) 2012, 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.
// Interpolation calls `toString`.
// The evaluation of the interpolation fails if `toString` throws or returns
// null. In Dart 2, any method overriding `Object.toString` must return a
// `String` or `null`. In particular, if `object.toString()` returns null, then
// `"$object"` must not evaluate to the string `"null"`.
//
// The specification states that the expression of an interpolation is
// evaluated as follows:
//
// 1. Evaluate $e_i$ to an object $o_i$.
// 2. Invoke the `toString` method on *o<sub>i</sub>* with no arguments,
// and let *r<sub>i</sub>*$ be the returned value.
// 3. If *r<sub>i</sub>* is not an instance of the built-in type `String`,
// throw an `Error`.
//
// (Then the resulting strings are concatenated with the literal string parts).
//
//
// Adding an object to a `StringBuffer` behaves the same as evaluating
// an expression in an interpolation. It must immediately fail if the
// object's toString throws or returns `null`.
//
// This ensures that implementing interpolation via a `StringBuffer`is
// a valid implementation choice.
import "package:expect/expect.dart";
class ToStringString {
String toString() => "String";
}
class ToStringThrows {
String toString() => throw "Throw";
}
void main() {
var s = ToStringString();
var t = ToStringThrows();
Expect.equals("$s$s", "StringString");
// Throws immediately when evaluating the first interpolated expression.
Expect.throws<String>(() => "$t${throw "unreachable"}", (e) => e == "Throw");
// Throws immediately when adding object that doesn't return a String.
Expect.equals(
(StringBuffer()..write(s)..write(s)).toString(), "StringString");
Expect.throws<String>(
() => StringBuffer()..write(t)..write(throw "unreachable"),
(e) => e == "Throw");
// Same behavior for constructor argument as if adding it to buffer later.
Expect.equals((StringBuffer(s)..write(s)).toString(), "StringString");
Expect.throws<String>(
() => StringBuffer(t)..write(throw "unreachable"), (e) => e == "Throw");
}