| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.test.source.embedder_test; | 5 library analyzer.test.source.embedder_test; |
| 6 | 6 |
| 7 import 'dart:core' hide Resource; |
| 8 |
| 9 import 'package:analyzer/file_system/file_system.dart'; |
| 7 import 'package:analyzer/file_system/memory_file_system.dart'; | 10 import 'package:analyzer/file_system/memory_file_system.dart'; |
| 8 import 'package:analyzer/source/embedder.dart'; | 11 import 'package:analyzer/source/embedder.dart'; |
| 9 import 'package:analyzer/src/generated/java_io.dart'; | |
| 10 import 'package:analyzer/src/generated/source.dart'; | 12 import 'package:analyzer/src/generated/source.dart'; |
| 13 import 'package:analyzer/src/util/absolute_path.dart'; |
| 14 import 'package:path/path.dart' as path; |
| 11 import 'package:unittest/unittest.dart'; | 15 import 'package:unittest/unittest.dart'; |
| 12 | 16 |
| 13 import '../utils.dart'; | 17 import '../utils.dart'; |
| 14 | 18 |
| 15 main() { | 19 main() { |
| 16 initializeTestEnvironment(); | 20 initializeTestEnvironment(path.context); |
| 17 group('EmbedderUriResolverTest', () { | 21 group('EmbedderUriResolverTest', () { |
| 18 setUp(() { | 22 setUp(() { |
| 19 buildResourceProvider(); | 23 buildResourceProvider(); |
| 20 }); | 24 }); |
| 21 tearDown(() { | 25 tearDown(() { |
| 22 clearResourceProvider(); | 26 clearResourceProvider(); |
| 23 }); | 27 }); |
| 24 test('test_NullEmbedderYamls', () { | 28 test('test_NullEmbedderYamls', () { |
| 25 var resolver = new EmbedderUriResolver(null); | 29 var resolver = new EmbedderUriResolver(null); |
| 26 expect(resolver.length, equals(0)); | 30 expect(resolver.length, equals(0)); |
| 27 }); | 31 }); |
| 28 test('test_NoEmbedderYamls', () { | 32 test('test_NoEmbedderYamls', () { |
| 29 var locator = new EmbedderYamlLocator({ | 33 var locator = new EmbedderYamlLocator({ |
| 30 'fox': [resourceProvider.getResource('/empty')] | 34 'fox': [pathTranslator.getResource('/empty')] |
| 31 }); | 35 }); |
| 32 expect(locator.embedderYamls.length, equals(0)); | 36 expect(locator.embedderYamls.length, equals(0)); |
| 33 }); | 37 }); |
| 34 test('test_EmbedderYaml', () { | 38 test('test_EmbedderYaml', () { |
| 35 var locator = new EmbedderYamlLocator({ | 39 var locator = new EmbedderYamlLocator({ |
| 36 'fox': [resourceProvider.getResource('/tmp')] | 40 'fox': [pathTranslator.getResource('/tmp')] |
| 37 }); | 41 }); |
| 38 var resolver = new EmbedderUriResolver(locator.embedderYamls); | 42 var resolver = new EmbedderUriResolver(locator.embedderYamls); |
| 39 | 43 |
| 40 expectResolved(dartUri, filePath) { | 44 expectResolved(dartUri, posixPath) { |
| 41 Source source = resolver.resolveAbsolute(Uri.parse(dartUri)); | 45 Source source = resolver.resolveAbsolute(Uri.parse(dartUri)); |
| 42 expect(source, isNotNull, reason: dartUri); | 46 expect(source, isNotNull, reason: dartUri); |
| 43 expect(source.fullName, filePath.replaceAll('/', JavaFile.separator)); | 47 expect(source.fullName, posixToOSPath(posixPath)); |
| 44 } | 48 } |
| 45 | 49 |
| 46 // We have four mappings. | 50 // We have four mappings. |
| 47 expect(resolver.length, equals(4)); | 51 expect(resolver.length, equals(4)); |
| 48 // Check that they map to the correct paths. | 52 // Check that they map to the correct paths. |
| 49 expectResolved('dart:fox', '/tmp/slippy.dart'); | 53 expectResolved('dart:fox', '/tmp/slippy.dart'); |
| 50 expectResolved('dart:bear', '/tmp/grizzly.dart'); | 54 expectResolved('dart:bear', '/tmp/grizzly.dart'); |
| 51 expectResolved('dart:relative', '/relative.dart'); | 55 expectResolved('dart:relative', '/relative.dart'); |
| 52 expectResolved('dart:deep', '/tmp/deep/directory/file.dart'); | 56 expectResolved('dart:deep', '/tmp/deep/directory/file.dart'); |
| 53 }); | 57 }); |
| 54 test('test_BadYAML', () { | 58 test('test_BadYAML', () { |
| 55 var locator = new EmbedderYamlLocator(null); | 59 var locator = new EmbedderYamlLocator(null); |
| 56 locator.addEmbedderYaml(null, r'''{{{,{{}}},}}'''); | 60 locator.addEmbedderYaml(null, r'''{{{,{{}}},}}'''); |
| 57 expect(locator.embedderYamls.length, equals(0)); | 61 expect(locator.embedderYamls.length, equals(0)); |
| 58 }); | 62 }); |
| 59 test('test_restoreAbsolute', () { | 63 test('test_restoreAbsolute', () { |
| 60 var locator = new EmbedderYamlLocator({ | 64 var locator = new EmbedderYamlLocator({ |
| 61 'fox': [resourceProvider.getResource('/tmp')] | 65 'fox': [pathTranslator.getResource('/tmp')] |
| 62 }); | 66 }); |
| 63 var resolver = new EmbedderUriResolver(locator.embedderYamls); | 67 var resolver = new EmbedderUriResolver(locator.embedderYamls); |
| 64 | 68 |
| 65 expectRestore(String dartUri, [String expected]) { | 69 expectRestore(String dartUri, [String expected]) { |
| 66 var source = resolver.resolveAbsolute(Uri.parse(dartUri)); | 70 var source = resolver.resolveAbsolute(Uri.parse(dartUri)); |
| 67 expect(source, isNotNull); | 71 expect(source, isNotNull); |
| 68 // Restore source's uri. | 72 // Restore source's uri. |
| 69 var restoreUri = resolver.restoreAbsolute(source); | 73 var restoreUri = resolver.restoreAbsolute(source); |
| 70 expect(restoreUri, isNotNull, reason: dartUri); | 74 expect(restoreUri, isNotNull, reason: dartUri); |
| 71 // Verify that it is 'dart:fox'. | 75 // Verify that it is 'dart:fox'. |
| 72 expect(restoreUri.toString(), equals(expected ?? dartUri)); | 76 expect(restoreUri.toString(), equals(expected ?? dartUri)); |
| 73 List<String> split = (expected ?? dartUri).split(':'); | 77 List<String> split = (expected ?? dartUri).split(':'); |
| 74 expect(restoreUri.scheme, equals(split[0])); | 78 expect(restoreUri.scheme, equals(split[0])); |
| 75 expect(restoreUri.path, equals(split[1])); | 79 expect(restoreUri.path, equals(split[1])); |
| 76 } | 80 } |
| 77 | 81 |
| 78 try { | 82 expectRestore('dart:deep'); |
| 79 expectRestore('dart:deep'); | 83 expectRestore('dart:deep/file.dart', 'dart:deep'); |
| 80 expectRestore('dart:deep/file.dart', 'dart:deep'); | 84 expectRestore('dart:deep/part.dart'); |
| 81 expectRestore('dart:deep/part.dart'); | 85 expectRestore('dart:deep/deep/file.dart'); |
| 82 expectRestore('dart:deep/deep/file.dart'); | |
| 83 if (JavaFile.separator == '\\') { | |
| 84 // See https://github.com/dart-lang/sdk/issues/25498 | |
| 85 fail('expected to fail on Windows'); | |
| 86 } | |
| 87 } catch (_) { | |
| 88 // Test is broken on Windows, but should run elsewhere | |
| 89 if (JavaFile.separator != '\\') { | |
| 90 rethrow; | |
| 91 } | |
| 92 } | |
| 93 }); | 86 }); |
| 94 | 87 |
| 95 test('test_EmbedderSdk_fromFileUri', () { | 88 test('test_EmbedderSdk_fromFileUri', () { |
| 96 var locator = new EmbedderYamlLocator({ | 89 var locator = new EmbedderYamlLocator({ |
| 97 'fox': [resourceProvider.getResource('/tmp')] | 90 'fox': [pathTranslator.getResource('/tmp')] |
| 98 }); | 91 }); |
| 99 var resolver = new EmbedderUriResolver(locator.embedderYamls); | 92 var resolver = new EmbedderUriResolver(locator.embedderYamls); |
| 100 var sdk = resolver.dartSdk; | 93 var sdk = resolver.dartSdk; |
| 101 | 94 |
| 102 expectSource(String filePath, String dartUri) { | 95 expectSource(String posixPath, String dartUri) { |
| 103 var uri = Uri.parse(filePath); | 96 var uri = Uri.parse(posixToOSFileUri(posixPath)); |
| 104 var source = sdk.fromFileUri(uri); | 97 var source = sdk.fromFileUri(uri); |
| 105 expect(source, isNotNull, reason: filePath); | 98 expect(source, isNotNull, reason: posixPath); |
| 106 expect(source.uri.toString(), dartUri); | 99 expect(source.uri.toString(), dartUri); |
| 107 expect(source.fullName, filePath.replaceAll('/', JavaFile.separator)); | 100 expect(source.fullName, posixPath); |
| 108 } | 101 } |
| 109 | 102 |
| 110 expectSource('/tmp/slippy.dart', 'dart:fox'); | 103 expectSource('/tmp/slippy.dart', 'dart:fox'); |
| 111 expectSource('/tmp/deep/directory/file.dart', 'dart:deep'); | 104 expectSource('/tmp/deep/directory/file.dart', 'dart:deep'); |
| 112 expectSource('/tmp/deep/directory/part.dart', 'dart:deep/part.dart'); | 105 expectSource('/tmp/deep/directory/part.dart', 'dart:deep/part.dart'); |
| 113 }); | 106 }); |
| 114 test('test_EmbedderSdk_getSdkLibrary', () { | 107 test('test_EmbedderSdk_getSdkLibrary', () { |
| 115 var locator = new EmbedderYamlLocator({ | 108 var locator = new EmbedderYamlLocator({ |
| 116 'fox': [resourceProvider.getResource('/tmp')] | 109 'fox': [pathTranslator.getResource('/tmp')] |
| 117 }); | 110 }); |
| 118 var resolver = new EmbedderUriResolver(locator.embedderYamls); | 111 var resolver = new EmbedderUriResolver(locator.embedderYamls); |
| 119 var sdk = resolver.dartSdk; | 112 var sdk = resolver.dartSdk; |
| 120 var lib = sdk.getSdkLibrary('dart:fox'); | 113 var lib = sdk.getSdkLibrary('dart:fox'); |
| 121 expect(lib, isNotNull); | 114 expect(lib, isNotNull); |
| 122 expect(lib.path, '/tmp/slippy.dart'); | 115 expect(lib.path, posixToOSPath('/tmp/slippy.dart')); |
| 123 expect(lib.shortName, 'fox'); | 116 expect(lib.shortName, 'fox'); |
| 124 }); | 117 }); |
| 125 test('test_EmbedderSdk_mapDartUri', () { | 118 test('test_EmbedderSdk_mapDartUri', () { |
| 126 var locator = new EmbedderYamlLocator({ | 119 var locator = new EmbedderYamlLocator({ |
| 127 'fox': [resourceProvider.getResource('/tmp')] | 120 'fox': [pathTranslator.getResource('/tmp')] |
| 128 }); | 121 }); |
| 129 var resolver = new EmbedderUriResolver(locator.embedderYamls); | 122 var resolver = new EmbedderUriResolver(locator.embedderYamls); |
| 130 var sdk = resolver.dartSdk; | 123 var sdk = resolver.dartSdk; |
| 131 | 124 |
| 132 expectSource(String dartUri, String filePath) { | 125 expectSource(String dartUri, String posixPath) { |
| 133 var source = sdk.mapDartUri(dartUri); | 126 var source = sdk.mapDartUri(dartUri); |
| 134 expect(source, isNotNull, reason: filePath); | 127 expect(source, isNotNull, reason: posixPath); |
| 135 expect(source.uri.toString(), dartUri); | 128 expect(source.uri.toString(), dartUri); |
| 136 expect(source.fullName, filePath.replaceAll('/', JavaFile.separator)); | 129 expect(source.fullName, posixToOSPath(posixPath)); |
| 137 } | 130 } |
| 138 | 131 |
| 139 expectSource('dart:fox', '/tmp/slippy.dart'); | 132 expectSource('dart:fox', '/tmp/slippy.dart'); |
| 140 expectSource('dart:deep', '/tmp/deep/directory/file.dart'); | 133 expectSource('dart:deep', '/tmp/deep/directory/file.dart'); |
| 141 expectSource('dart:deep/part.dart', '/tmp/deep/directory/part.dart'); | 134 expectSource('dart:deep/part.dart', '/tmp/deep/directory/part.dart'); |
| 142 }); | 135 }); |
| 143 }); | 136 }); |
| 144 } | 137 } |
| 145 | 138 |
| 146 MemoryResourceProvider resourceProvider; | 139 ResourceProvider resourceProvider; |
| 140 TestPathTranslator pathTranslator; |
| 147 | 141 |
| 148 buildResourceProvider() { | 142 buildResourceProvider() { |
| 149 resourceProvider = new MemoryResourceProvider(); | 143 var rawProvider = new MemoryResourceProvider(isWindows: isWindows); |
| 150 resourceProvider.newFolder('/empty'); | 144 resourceProvider = new TestResourceProvider(rawProvider); |
| 151 resourceProvider.newFolder('/tmp'); | 145 pathTranslator = new TestPathTranslator(rawProvider) |
| 152 resourceProvider.newFile( | 146 ..newFolder('/empty') |
| 153 '/tmp/_embedder.yaml', | 147 ..newFolder('/tmp') |
| 154 r''' | 148 ..newFile( |
| 149 '/tmp/_embedder.yaml', |
| 150 r''' |
| 155 embedder_libs: | 151 embedder_libs: |
| 156 "dart:fox": "slippy.dart" | 152 "dart:fox": "slippy.dart" |
| 157 "dart:bear": "grizzly.dart" | 153 "dart:bear": "grizzly.dart" |
| 158 "dart:relative": "../relative.dart" | 154 "dart:relative": "../relative.dart" |
| 159 "dart:deep": "deep/directory/file.dart" | 155 "dart:deep": "deep/directory/file.dart" |
| 160 "fart:loudly": "nomatter.dart" | 156 "fart:loudly": "nomatter.dart" |
| 161 '''); | 157 '''); |
| 162 } | 158 } |
| 163 | 159 |
| 164 clearResourceProvider() { | 160 clearResourceProvider() { |
| 165 resourceProvider = null; | 161 resourceProvider = null; |
| 162 pathTranslator = null; |
| 166 } | 163 } |
| 164 |
| 165 // TODO(danrubel) if this approach works well for running tests |
| 166 // in a platform specific way, then move all of the following functionality |
| 167 // into a separate test utility library. |
| 168 |
| 169 bool get isWindows => path.Style.platform == path.Style.windows; |
| 170 |
| 171 /** |
| 172 * Translate the given posixPath to a path appropriate for the |
| 173 * platform on which the tests are executing. |
| 174 */ |
| 175 String posixToOSPath(String posixPath) { |
| 176 if (posixPath.contains('\\')) { |
| 177 fail('Expected posix path, but found $posixPath'); |
| 178 } |
| 179 if (isWindows) { |
| 180 String windowsPath = posixPath.replaceAll('/', '\\'); |
| 181 if (posixPath.startsWith('/')) { |
| 182 return 'C:$windowsPath'; |
| 183 } |
| 184 return windowsPath; |
| 185 } |
| 186 return posixPath; |
| 187 } |
| 188 |
| 189 /** |
| 190 * Translate the given posixPath to a file URI appropriate for the |
| 191 * platform on which the tests are executing. |
| 192 */ |
| 193 String posixToOSFileUri(String posixPath) { |
| 194 expect(posixPath, startsWith('/'), reason: 'Expected absolute posix path'); |
| 195 return isWindows ? 'file://C:$posixPath' : 'file://$posixPath'; |
| 196 } |
| 197 |
| 198 /** |
| 199 * A convenience utility for setting up a test [MemoryResourceProvider]. |
| 200 * All supplied paths are assumed to be in [path.posix] format |
| 201 * and are automatically translated to [path.context]. |
| 202 * |
| 203 * This class intentionally does not implement [ResourceProvider] |
| 204 * directly or indirectly so that it cannot be used as a resource provider. |
| 205 * We do not want functionality under test to interact with a resource provider |
| 206 * that automatically translates paths. |
| 207 */ |
| 208 class TestPathTranslator { |
| 209 final MemoryResourceProvider _provider; |
| 210 |
| 211 TestPathTranslator(this._provider); |
| 212 |
| 213 Resource getResource(String posixPath) => |
| 214 _provider.getResource(posixToOSPath(posixPath)); |
| 215 |
| 216 File newFile(String posixPath, String content) => |
| 217 _provider.newFile(posixToOSPath(posixPath), content); |
| 218 |
| 219 Folder newFolder(String posixPath) => |
| 220 _provider.newFolder(posixToOSPath(posixPath)); |
| 221 } |
| 222 |
| 223 /** |
| 224 * A resource provider for testing that asserts that any supplied paths |
| 225 * are appropriate for the OS platform on which the tests are running. |
| 226 */ |
| 227 class TestResourceProvider implements ResourceProvider { |
| 228 final ResourceProvider _provider; |
| 229 |
| 230 TestResourceProvider(this._provider) { |
| 231 expect(_provider.absolutePathContext.separator, isWindows ? '\\' : '/'); |
| 232 } |
| 233 |
| 234 @override |
| 235 AbsolutePathContext get absolutePathContext => _provider.absolutePathContext; |
| 236 |
| 237 @override |
| 238 File getFile(String path) => _provider.getFile(_assertPath(path)); |
| 239 |
| 240 @override |
| 241 Folder getFolder(String path) => _provider.getFolder(_assertPath(path)); |
| 242 |
| 243 @override |
| 244 Resource getResource(String path) => _provider.getResource(_assertPath(path)); |
| 245 |
| 246 @override |
| 247 Folder getStateLocation(String pluginId) => |
| 248 _provider.getStateLocation(pluginId); |
| 249 |
| 250 @override |
| 251 path.Context get pathContext => _provider.pathContext; |
| 252 |
| 253 /** |
| 254 * Assert that the given path is valid for the OS platform on which the |
| 255 * tests are running. |
| 256 */ |
| 257 String _assertPath(String path) { |
| 258 if (isWindows) { |
| 259 if (path.contains('/')) { |
| 260 fail('Expected windows path, but found: $path'); |
| 261 } |
| 262 } else { |
| 263 if (path.contains('\\')) { |
| 264 fail('Expected posix path, but found: $path'); |
| 265 } |
| 266 } |
| 267 return path; |
| 268 } |
| 269 } |
| OLD | NEW |