blob: 7ebcef341b1d5472538f80a28ac00d5a3f6ed62d [file] [log] [blame]
// Copyright (c) 2015, 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.
@TestOn("vm")
import 'package:analyzer/analyzer.dart';
import 'package:test/test.dart';
import 'package:test/src/util/string_literal_iterator.dart';
final _offset = "final str = ".length;
void main() {
group("returns simple characters in", () {
test("a single simple string", () {
var iter = _parse('"abc"');
expect(iter.current, isNull);
expect(iter.offset, equals(_offset));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("a"));
expect(iter.offset, equals(_offset + 1));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("b"));
expect(iter.offset, equals(_offset + 2));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("c"));
expect(iter.offset, equals(_offset + 3));
expect(iter.moveNext(), isFalse);
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + 4));
});
test("a raw string", () {
var iter = _parse('r"abc"');
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + 1));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("a"));
expect(iter.offset, equals(_offset + 2));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("b"));
expect(iter.offset, equals(_offset + 3));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("c"));
expect(iter.offset, equals(_offset + 4));
expect(iter.moveNext(), isFalse);
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + 5));
});
test("a multiline string", () {
var iter = _parse('"""ab\ncd"""');
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + 2));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("a"));
expect(iter.offset, equals(_offset + 3));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("b"));
expect(iter.offset, equals(_offset + 4));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("\n"));
expect(iter.offset, equals(_offset + 5));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("c"));
expect(iter.offset, equals(_offset + 6));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("d"));
expect(iter.offset, equals(_offset + 7));
expect(iter.moveNext(), isFalse);
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + 8));
});
test("a raw multiline string", () {
var iter = _parse('r"""ab\ncd"""');
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + 3));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("a"));
expect(iter.offset, equals(_offset + 4));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("b"));
expect(iter.offset, equals(_offset + 5));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("\n"));
expect(iter.offset, equals(_offset + 6));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("c"));
expect(iter.offset, equals(_offset + 7));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("d"));
expect(iter.offset, equals(_offset + 8));
expect(iter.moveNext(), isFalse);
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + 9));
});
test("adjacent strings", () {
var iter = _parse('"ab" r"cd" """ef\ngh"""');
expect(iter.current, isNull);
expect(iter.offset, equals(_offset));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("a"));
expect(iter.offset, equals(_offset + 1));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("b"));
expect(iter.offset, equals(_offset + 2));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("c"));
expect(iter.offset, equals(_offset + 7));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("d"));
expect(iter.offset, equals(_offset + 8));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("e"));
expect(iter.offset, equals(_offset + 14));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("f"));
expect(iter.offset, equals(_offset + 15));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("\n"));
expect(iter.offset, equals(_offset + 16));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("g"));
expect(iter.offset, equals(_offset + 17));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("h"));
expect(iter.offset, equals(_offset + 18));
expect(iter.moveNext(), isFalse);
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + 19));
});
});
group("parses an escape sequence for", () {
test("a newline", () => _expectEscape(r"\n", "\n"));
test("a carriage return", () => _expectEscape(r"\r", "\r"));
test("a form feed", () => _expectEscape(r"\f", "\f"));
test("a backspace", () => _expectEscape(r"\b", "\b"));
test("a tab", () => _expectEscape(r"\t", "\t"));
test("a vertical tab", () => _expectEscape(r"\v", "\v"));
test("a quote", () => _expectEscape(r'\"', '"'));
test("a backslash", () => _expectEscape(r"\\", "\\"));
test("a hex character", () {
_expectEscape(r"\x62", "b");
_expectEscape(r"\x7A", "z");
_expectEscape(r"\x7a", "z");
});
test("a fixed-length unicode character",
() => _expectEscape(r"\u0062", "b"));
test("a short variable-length unicode character",
() => _expectEscape(r"\u{62}", "b"));
test("a long variable-length unicode character",
() => _expectEscape(r"\u{000062}", "b"));
});
group("throws an ArgumentError for", () {
test("interpolation", () {
expect(() => _parse(r'"$foo"'), throwsArgumentError);
});
test("interpolation in an adjacent string", () {
expect(() => _parse(r'"foo" "$bar" "baz"'), throwsArgumentError);
});
});
}
/// Asserts that [escape] is parsed as [value].
void _expectEscape(String escape, String value) {
var iter = _parse('"a${escape}b"');
expect(iter.current, isNull);
expect(iter.offset, equals(_offset));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("a"));
expect(iter.offset, equals(_offset + 1));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune(value));
expect(iter.offset, equals(_offset + 2));
expect(iter.moveNext(), isTrue);
expect(iter.current, _isRune("b"));
expect(iter.offset, equals(_offset + escape.length + 2));
expect(iter.moveNext(), isFalse);
expect(iter.current, isNull);
expect(iter.offset, equals(_offset + escape.length + 3));
}
/// Returns a matcher that asserts that the given rune is the rune for [char].
Matcher _isRune(String char) {
return predicate((rune) {
return rune is int && new String.fromCharCode(rune) == char;
}, 'is the rune "$char"');
}
/// Parses [dart], which should be a string literal, into a
/// [StringLiteralIterator].
StringLiteralIterator _parse(String dart) {
var declaration = parseCompilationUnit("final str = $dart;")
.declarations.single as TopLevelVariableDeclaration;
var literal = declaration.variables.variables.single.initializer;
return new StringLiteralIterator(literal);
}