import 'dart:io'; import 'package:pipe/pipe.dart'; import 'package:pipe/src/sdk.dart'; import 'package:test/test.dart'; /// A directory laid out like a Dart SDK: `bin/dart`, `lib/libraries.json`, /// `version`. Directory _fakeSdk(String label) { final sdk = Directory.systemTemp.createTempSync('pipe-$label'); File('${sdk.path}/version').writeAsStringSync('3.13.0\n'); File('${sdk.path}/lib/libraries.json') ..createSync(recursive: true) ..writeAsStringSync('{}'); File('${sdk.path}/bin/dart').createSync(recursive: true); return sdk; } void main() { test('an SDK that exists but cannot be read is a clear error', () { // macOS privacy protection (a Flutter SDK under ~/Documents) lets stat // succeed while every open fails, so discovery accepted the SDK and the // analyzer later died with a raw FileSystemException stack trace. final sdk = _fakeSdk('unreadable-sdk'); final version = File('${sdk.path}/version'); Process.runSync('chmod', ['000', version.path]); try { version.readAsStringSync(); markTestSkipped('chmod 000 does not restrict this process'); return; } on FileSystemException { // Expected: the restriction is real, so the check below is meaningful. } final resolution = resolveSdk(explicit: sdk.path); expect( () => requireReadableSdk(resolution), throwsA( isA() .having((e) => e.message, 'message', contains(sdk.path)) .having((e) => e.remedy, 'remedy', contains('--sdk')), ), ); }); test('a readable SDK passes the check', () { final sdk = _fakeSdk('readable-sdk'); expect( () => requireReadableSdk(resolveSdk(explicit: sdk.path)), returnsNormally, ); }); test('the running dart binary maps to its SDK root, not to bin/', () { // dirname(/bin/dart) is /bin, which never contains // lib/libraries.json, so this fallback could never succeed. final sdk = _fakeSdk('runtime-sdk'); expect(sdkFromExecutable('${sdk.path}/bin/dart'), sdk.path); expect(sdkFromExecutable('${sdk.path}/version'), isNull); }); }