OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015, 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 // Test that JS printer callbacks occur when expected. |
| 6 |
| 7 library js_ast.printer.callback_test; |
| 8 |
| 9 import 'package:js_ast/js_ast.dart'; |
| 10 import 'package:unittest/unittest.dart'; |
| 11 |
| 12 enum TestMode { |
| 13 NONE, |
| 14 ENTER, |
| 15 DELIMITER, |
| 16 EXIT, |
| 17 } |
| 18 |
| 19 const DATA = const [ |
| 20 const { |
| 21 TestMode.NONE: """ |
| 22 function(a, b) { |
| 23 return null; |
| 24 }""", |
| 25 TestMode.ENTER: """ |
| 26 @0function(@1a, @2b) @3{ |
| 27 @4return @5null; |
| 28 }""", |
| 29 TestMode.DELIMITER: """ |
| 30 function(a, b) { |
| 31 return null; |
| 32 @0}""", |
| 33 TestMode.EXIT: """ |
| 34 function(a@1, b@2) { |
| 35 return null@5; |
| 36 @4}@3@0""" |
| 37 }, |
| 38 |
| 39 const { |
| 40 TestMode.NONE: """ |
| 41 function() { |
| 42 if (true) { |
| 43 foo1(); |
| 44 foo2(); |
| 45 } else { |
| 46 bar1(); |
| 47 bar2(); |
| 48 } |
| 49 while (false) { |
| 50 baz3(); |
| 51 baz4(); |
| 52 } |
| 53 }""", |
| 54 TestMode.ENTER: """ |
| 55 @0function() @1{ |
| 56 @2if (@3true) @4{ |
| 57 @5@6@7foo1(); |
| 58 @8@9@10foo2(); |
| 59 } else @11{ |
| 60 @12@13@14bar1(); |
| 61 @15@16@17bar2(); |
| 62 } |
| 63 @18while (@19false) @20{ |
| 64 @21@22@23baz3(); |
| 65 @24@25@26baz4(); |
| 66 } |
| 67 }""", |
| 68 TestMode.DELIMITER: """ |
| 69 function() { |
| 70 if (true) { |
| 71 foo1(); |
| 72 foo2(); |
| 73 } else { |
| 74 bar1(); |
| 75 bar2(); |
| 76 } |
| 77 while (false) { |
| 78 baz3(); |
| 79 baz4(); |
| 80 } |
| 81 @0}""", |
| 82 TestMode.EXIT: """ |
| 83 function() { |
| 84 if (true@3) { |
| 85 foo1@7()@6; |
| 86 @5 foo2@10()@9; |
| 87 @8 }@4 else { |
| 88 bar1@14()@13; |
| 89 @12 bar2@17()@16; |
| 90 @15 }@11 |
| 91 @2 while (false@19) { |
| 92 baz3@23()@22; |
| 93 @21 baz4@26()@25; |
| 94 @24 }@20 |
| 95 @18}@1@0""", |
| 96 }, |
| 97 ]; |
| 98 |
| 99 void check(Map<TestMode, String> map) { |
| 100 String code = map[TestMode.NONE]; |
| 101 JavaScriptPrintingOptions options = new JavaScriptPrintingOptions(); |
| 102 Node node = js.parseForeignJS(code).instantiate({}); |
| 103 map.forEach((TestMode mode, String expectedOutput) { |
| 104 Context context = new Context(mode); |
| 105 new Printer(options, context).visit(node); |
| 106 expect(context.getText(), equals(expectedOutput), |
| 107 reason: "Unexpected output for $code in $mode"); |
| 108 }); |
| 109 } |
| 110 |
| 111 class Context extends SimpleJavaScriptPrintingContext { |
| 112 final TestMode mode; |
| 113 final Map<Node, int> idMap = {}; |
| 114 final Map<int, List<String>> tagMap = {}; |
| 115 |
| 116 Context(this.mode); |
| 117 |
| 118 int id(Node node) => idMap.putIfAbsent(node, () => idMap.length); |
| 119 |
| 120 String tag(int value) => '@$value'; |
| 121 |
| 122 void enterNode(Node node, int startPosition) { |
| 123 int value = id(node); |
| 124 if (mode == TestMode.ENTER) { |
| 125 tagMap.putIfAbsent(startPosition, () => []).add(tag(value)); |
| 126 } |
| 127 } |
| 128 |
| 129 void exitNode(Node node, |
| 130 int startPosition, |
| 131 int endPosition, |
| 132 int delimiterPosition) { |
| 133 int value = id(node); |
| 134 if (mode == TestMode.DELIMITER && delimiterPosition != null) { |
| 135 tagMap.putIfAbsent(delimiterPosition, () => []).add(tag(value)); |
| 136 } else if (mode == TestMode.EXIT) { |
| 137 tagMap.putIfAbsent(endPosition, () => []).add(tag(value)); |
| 138 } |
| 139 } |
| 140 |
| 141 String getText() { |
| 142 String text = super.getText(); |
| 143 int offset = 0; |
| 144 StringBuffer sb = new StringBuffer(); |
| 145 for (int position in tagMap.keys.toList()..sort()) { |
| 146 if (offset < position) { |
| 147 sb.write(text.substring(offset, position)); |
| 148 } |
| 149 tagMap[position].forEach((String tag) => sb.write(tag)); |
| 150 offset = position; |
| 151 } |
| 152 if (offset < text.length) { |
| 153 sb.write(text.substring(offset)); |
| 154 } |
| 155 return sb.toString(); |
| 156 } |
| 157 } |
| 158 |
| 159 void main() { |
| 160 DATA.forEach(check); |
| 161 } |
OLD | NEW |