blob: 2627c879074c1d344abae93c35c8cb35d1af7c9a [file] [edit]
// 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.
// ignore_for_file: deprecated_member_use_from_same_package
import 'dart:async';
import 'dart:io';
import 'package:cli_util/cli_util.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
void main() {
group('sdkPath & dartExecutable', () {
test('resolves in active VM environment', () {
final path = sdkPath;
if (path == null) {
markTestSkipped('sdkPath is not available in this environment');
return;
}
expect(Directory(path).existsSync(), isTrue);
expect(isValidSdkPath(path), isTrue);
expect(dartExecutable, isNotNull);
expect(File(dartExecutable!).existsSync(), isTrue);
});
test('isValidSdkPath validation', () {
expect(isValidSdkPath(''), isFalse);
if (sdkPath case final path?) {
expect(isValidSdkPath(path), isTrue);
}
final tempDir = Directory.systemTemp.createTempSync('invalid_sdk_test');
try {
expect(isValidSdkPath(tempDir.path), isFalse);
// Add dummy libraries.json
final libDir = Directory(p.join(tempDir.path, 'lib'))..createSync();
File(p.join(libDir.path, 'libraries.json')).writeAsStringSync('{}');
expect(
isValidSdkPath(tempDir.path),
isFalse,
); // Missing bin/dart or version
// Add dummy version file
File(p.join(tempDir.path, 'version')).writeAsStringSync('3.8.0');
expect(isValidSdkPath(tempDir.path), isTrue);
} finally {
tempDir.deleteSync(recursive: true);
}
});
test('DART_ROOT / DART_SDK environment overrides', () {
final mockSdk = Directory.systemTemp.createTempSync('mock_sdk');
try {
Directory(p.join(mockSdk.path, 'lib')).createSync();
File(
p.join(mockSdk.path, 'lib', 'libraries.json'),
).writeAsStringSync('{}');
File(p.join(mockSdk.path, 'version')).writeAsStringSync('3.8.0');
runZoned(
() {
expect(sdkPath, mockSdk.path);
},
zoneValues: {
environmentOverridesKey: <String, String>{
'DART_ROOT': mockSdk.path,
'_DART_RESOLVED_EXECUTABLE': '',
},
},
);
runZoned(
() {
expect(sdkPath, mockSdk.path);
},
zoneValues: {
environmentOverridesKey: <String, String>{
'DART_SDK': mockSdk.path,
'_DART_RESOLVED_EXECUTABLE': '',
},
},
);
} finally {
mockSdk.deleteSync(recursive: true);
}
});
test('PATH traversal with Flutter wrapper structure', () {
final tempDir = Directory.systemTemp.createTempSync('mock_path');
try {
final mockFlutter = Directory(p.join(tempDir.path, 'flutter'))
..createSync();
final mockFlutterBin = Directory(p.join(mockFlutter.path, 'bin'))
..createSync();
final mockDartSdk = Directory(
p.join(mockFlutter.path, 'bin', 'cache', 'dart-sdk'),
)..createSync(recursive: true);
Directory(p.join(mockDartSdk.path, 'lib')).createSync();
File(
p.join(mockDartSdk.path, 'lib', 'libraries.json'),
).writeAsStringSync('{}');
File(p.join(mockDartSdk.path, 'version')).writeAsStringSync('3.8.0');
File(p.join(mockFlutterBin.path, 'dart')).createSync();
File(p.join(mockFlutterBin.path, 'dart.bat')).createSync();
File(p.join(mockFlutterBin.path, 'dart.exe')).createSync();
runZoned(
() {
expect(sdkPath, mockDartSdk.resolveSymbolicLinksSync());
},
zoneValues: {
environmentOverridesKey: <String, String>{
'DART_ROOT': '',
'DART_SDK': '',
'FLUTTER_ROOT': '',
'_DART_RESOLVED_EXECUTABLE': '',
'PATH': mockFlutterBin.path,
},
},
);
} finally {
tempDir.deleteSync(recursive: true);
}
});
test('PATH traversal handles quoted directory entries', () {
final tempDir = Directory.systemTemp.createTempSync('mock_path_quoted');
try {
final mockSdk = Directory(p.join(tempDir.path, 'dart-sdk'))
..createSync();
Directory(p.join(mockSdk.path, 'lib')).createSync();
File(
p.join(mockSdk.path, 'lib', 'libraries.json'),
).writeAsStringSync('{}');
File(p.join(mockSdk.path, 'version')).writeAsStringSync('3.8.0');
final binDir = Directory(p.join(mockSdk.path, 'bin'))..createSync();
File(p.join(binDir.path, 'dart')).createSync();
File(p.join(binDir.path, 'dart.bat')).createSync();
File(p.join(binDir.path, 'dart.exe')).createSync();
runZoned(
() {
expect(sdkPath, mockSdk.resolveSymbolicLinksSync());
},
zoneValues: {
environmentOverridesKey: <String, String>{
'DART_ROOT': '',
'DART_SDK': '',
'FLUTTER_ROOT': '',
'_DART_RESOLVED_EXECUTABLE': '',
'PATH': ' "${binDir.path}" ',
},
},
);
} finally {
tempDir.deleteSync(recursive: true);
}
});
test('FLUTTER_ROOT fallback override', () {
final mockFlutter = Directory.systemTemp.createTempSync('mock_flutter');
try {
final mockDartSdk = Directory(
p.join(mockFlutter.path, 'bin', 'cache', 'dart-sdk'),
)..createSync(recursive: true);
Directory(p.join(mockDartSdk.path, 'lib')).createSync();
File(
p.join(mockDartSdk.path, 'lib', 'libraries.json'),
).writeAsStringSync('{}');
File(p.join(mockDartSdk.path, 'version')).writeAsStringSync('3.8.0');
runZoned(
() {
expect(sdkPath, mockDartSdk.path);
},
zoneValues: {
environmentOverridesKey: <String, String>{
'DART_ROOT': '',
'DART_SDK': '',
'_DART_RESOLVED_EXECUTABLE': '',
'PATH': '',
'FLUTTER_ROOT': mockFlutter.path,
},
},
);
} finally {
mockFlutter.deleteSync(recursive: true);
}
});
test('returns null when SDK is not found and environment is empty', () {
runZoned(
() {
expect(sdkPath, isNull);
expect(dartExecutable, isNull);
},
zoneValues: {
environmentOverridesKey: <String, String>{
'DART_ROOT': '',
'DART_SDK': '',
'FLUTTER_ROOT': '',
'PATH': '',
'_DART_RESOLVED_EXECUTABLE': '',
},
},
);
});
});
group('applicationConfigHome', () {
test('returns a non-empty string', () {
expect(applicationConfigHome('dart'), isNotEmpty);
});
test('has an ancestor folder that exists', () {
final path = p.split(applicationConfigHome('dart'));
// We expect that first two segments of the path exist. This is really
// just a dummy check that some part of the path exists.
expect(Directory(p.joinAll(path.take(2))).existsSync(), isTrue);
});
test('empty environment throws exception', () async {
expect(() {
runZoned(
() => applicationConfigHome('dart'),
zoneValues: {environmentOverridesKey: <String, String>{}},
);
}, throwsA(isA<EnvironmentNotFoundException>()));
});
});
}