Files
sdk/pkg/js_ast/test/annotations_test.dart
T
Mayank Patke ed32d2456a [js_ast] Update pubspec to 3.7 and reformat.
Change-Id: I6d7d21b2d02f1f6cbaff81f75f900790f0e8c715
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400780
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Mayank Patke <fishythefish@google.com>
Auto-Submit: Mayank Patke <fishythefish@google.com>
2024-12-16 15:18:53 -08:00

153 lines
4.0 KiB
Dart

// Copyright (c) 2023, 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.
import 'package:expect/expect.dart';
import 'package:js_ast/js_ast.dart';
class Source implements JavaScriptNodeSourceInformation {
final Object tag;
Source(this.tag);
@override
String toString() => 'Source($tag)';
}
void check(Node node, expectedSource, expectedAnnotations) {
Expect.equals('$expectedSource', '${node.sourceInformation}', 'source');
Expect.equals('$expectedAnnotations', '${node.annotations}', 'annotations');
}
void simpleTests(Node node) {
check(node, null, []);
final s1 = node.withSourceInformation(Source(1));
check(node, null, []);
check(s1, Source(1), []);
final a1 = node.withAnnotation(1);
check(node, null, []);
check(s1, Source(1), []);
check(a1, null, [1]);
final a2 = node.withAnnotation(2);
check(node, null, []);
check(s1, Source(1), []);
check(a1, null, [1]);
check(a2, null, [2]);
final s1a3 = s1.withAnnotation(3);
check(node, null, []);
check(s1, Source(1), []);
check(s1, Source(1), []);
check(a2, null, [2]);
check(s1a3, Source(1), [3]);
final s1a3a4 = s1a3.withAnnotation(4);
check(node, null, []);
check(s1, Source(1), []);
check(s1, Source(1), []);
check(a2, null, [2]);
check(s1a3, Source(1), [3]);
check(s1a3a4, Source(1), [3, 4]);
final a2s5 = a2.withSourceInformation(Source(5));
check(node, null, []);
check(s1, Source(1), []);
check(s1, Source(1), []);
check(a2, null, [2]);
check(s1a3, Source(1), [3]);
check(s1a3a4, Source(1), [3, 4]);
check(a2s5, Source(5), [2]);
}
bool debugging = false;
/// Explore all combinations of withSourceInformation and withAnnotation.
void testGraph(Node root) {
// At each node in the graph, all the previous checks are re-run to ensure
// that source information or annotations do not change.
List<void Function(String state)> tests = [];
void explore(
String state,
Node node,
int sourceDepth,
int annotationDepth,
JavaScriptNodeSourceInformation? expectedSource,
List<Object> expectedAnnotations,
) {
void newCheck(String currentState) {
if (debugging) {
print(
'In state $currentState check $state:'
' source: $expectedSource, annotations: $expectedAnnotations',
);
}
Expect.equals(
'$expectedSource',
'${node.sourceInformation}',
' at state $currentState for node at state $state:'
' ${node.debugPrint()}',
);
Expect.equals(
'$expectedAnnotations',
'${node.annotations}',
' at state $currentState for node at state $state:'
' ${node.debugPrint()}',
);
}
tests.add(newCheck);
for (final test in tests) {
test(state);
}
if (sourceDepth < 3) {
final newSourceDepth = sourceDepth + 1;
final newSource = Source(newSourceDepth);
final newState = '$state-s$newSourceDepth';
final newNode = node.withSourceInformation(newSource);
explore(
newState,
newNode,
newSourceDepth,
annotationDepth,
newSource,
expectedAnnotations,
);
}
if (annotationDepth < 3) {
final newAnnotationDepth = annotationDepth + 1;
final newAnnotation = 'a:$newAnnotationDepth';
final newAnnotations = [...expectedAnnotations, newAnnotation];
final newState = '$state-a$newAnnotationDepth';
final newNode = node.withAnnotation(newAnnotation);
explore(
newState,
newNode,
sourceDepth,
newAnnotationDepth,
expectedSource,
newAnnotations,
);
}
}
explore('root', root, 0, 0, null, []);
}
void main() {
simpleTests(js('x + 1'));
simpleTests(js.statement('f()'));
testGraph(js('1'));
testGraph(js('x + 1'));
testGraph(js('f()'));
testGraph(js.statement('f()'));
testGraph(js.statement('break'));
}