| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:convert'; |
| import 'dart:io'; |
| |
| import 'package:path/path.dart' as path; |
| import 'package:process/process.dart'; |
| import 'package:test/fake.dart'; |
| import 'package:test/test.dart'; |
| import 'package:xdg_directories/xdg_directories.dart' as xdg; |
| |
| void main() { |
| final Map<String, String> fakeEnv = <String, String>{}; |
| late Directory tmpDir; |
| |
| String testRootPath() { |
| final String basePath = tmpDir.path; |
| return Platform.isWindows |
| // Strip the drive specifier when running tests on Windows since |
| // environment variables use : as a path list separator. |
| ? basePath.substring(basePath.indexOf(':') + 1) |
| : basePath; |
| } |
| |
| String testPath(String subdir) => path.join(testRootPath(), subdir); |
| |
| setUp(() { |
| tmpDir = Directory.systemTemp.createTempSync('xdg_test'); |
| fakeEnv.clear(); |
| fakeEnv['HOME'] = testRootPath(); |
| fakeEnv['XDG_CACHE_HOME'] = testPath('.test_cache'); |
| fakeEnv['XDG_CONFIG_DIRS'] = testPath('etc/test_xdg'); |
| fakeEnv['XDG_CONFIG_HOME'] = testPath('.test_config'); |
| fakeEnv['XDG_DATA_DIRS'] = |
| '${testPath('usr/local/test_share')}:${testPath('usr/test_share')}'; |
| fakeEnv['XDG_DATA_HOME'] = testPath('.local/test_share'); |
| fakeEnv['XDG_RUNTIME_DIR'] = testPath('.local/test_runtime'); |
| Directory(fakeEnv['XDG_CONFIG_HOME']!).createSync(recursive: true); |
| Directory(fakeEnv['XDG_CACHE_HOME']!).createSync(recursive: true); |
| Directory(fakeEnv['XDG_DATA_HOME']!).createSync(recursive: true); |
| Directory(fakeEnv['XDG_RUNTIME_DIR']!).createSync(recursive: true); |
| File(path.join(fakeEnv['XDG_CONFIG_HOME']!, 'user-dirs.dirs')) |
| .writeAsStringSync(r''' |
| XDG_DESKTOP_DIR="$HOME/Desktop" |
| XDG_DOCUMENTS_DIR="$HOME/Documents" |
| XDG_DOWNLOAD_DIR="$HOME/Downloads" |
| XDG_MUSIC_DIR="$HOME/Music" |
| XDG_PICTURES_DIR="$HOME/Pictures" |
| XDG_PUBLICSHARE_DIR="$HOME/Public" |
| XDG_TEMPLATES_DIR="$HOME/Templates" |
| XDG_VIDEOS_DIR="$HOME/Videos" |
| '''); |
| xdg.xdgEnvironmentOverride = (String key) => fakeEnv[key]; |
| }); |
| |
| tearDown(() { |
| tmpDir.deleteSync(recursive: true); |
| // Stop overriding the environment accessor. |
| xdg.xdgEnvironmentOverride = null; |
| }); |
| void expectDirList(List<Directory> values, List<String> expected) { |
| final List<String> valueStr = |
| values.map<String>((Directory directory) => directory.path).toList(); |
| expect(valueStr, orderedEquals(expected)); |
| } |
| |
| test('Default fallback values work', () { |
| fakeEnv.clear(); |
| fakeEnv['HOME'] = testRootPath(); |
| expect(xdg.cacheHome.path, equals(testPath('.cache'))); |
| expect(xdg.configHome.path, equals(testPath('.config'))); |
| expect(xdg.dataHome.path, equals(testPath('.local/share'))); |
| expect(xdg.runtimeDir, isNull); |
| |
| expectDirList(xdg.configDirs, <String>['/etc/xdg']); |
| expectDirList(xdg.dataDirs, <String>['/usr/local/share', '/usr/share']); |
| }); |
| |
| test('Values pull from environment', () { |
| expect(xdg.cacheHome.path, equals(testPath('.test_cache'))); |
| expect(xdg.configHome.path, equals(testPath('.test_config'))); |
| expect(xdg.dataHome.path, equals(testPath('.local/test_share'))); |
| expect(xdg.runtimeDir, isNotNull); |
| expect(xdg.runtimeDir!.path, equals(testPath('.local/test_runtime'))); |
| |
| expectDirList(xdg.configDirs, <String>[testPath('etc/test_xdg')]); |
| expectDirList(xdg.dataDirs, <String>[ |
| testPath('usr/local/test_share'), |
| testPath('usr/test_share'), |
| ]); |
| }); |
| |
| test('Can get userDirs', () { |
| final Map<String, String> expected = <String, String>{ |
| 'DESKTOP': testPath('Desktop'), |
| 'DOCUMENTS': testPath('Documents'), |
| 'DOWNLOAD': testPath('Downloads'), |
| 'MUSIC': testPath('Music'), |
| 'PICTURES': testPath('Pictures'), |
| 'PUBLICSHARE': testPath('Public'), |
| 'TEMPLATES': testPath('Templates'), |
| 'VIDEOS': testPath('Videos'), |
| }; |
| xdg.xdgProcessManager = FakeProcessManager(expected); |
| final Set<String> userDirs = xdg.getUserDirectoryNames(); |
| expect(userDirs, equals(expected.keys.toSet())); |
| for (final String key in userDirs) { |
| expect(xdg.getUserDirectory(key)!.path, equals(expected[key]), |
| reason: 'Path $key value not correct'); |
| } |
| xdg.xdgProcessManager = const LocalProcessManager(); |
| }); |
| |
| test('Returns null when xdg-user-dir executable is not present', () { |
| xdg.xdgProcessManager = FakeProcessManager( |
| <String, String>{}, |
| canRunExecutable: false, |
| ); |
| expect(xdg.getUserDirectory('DESKTOP'), isNull, |
| reason: 'Found xdg user directory without access to xdg-user-dir'); |
| xdg.xdgProcessManager = const LocalProcessManager(); |
| }); |
| |
| test('Throws StateError when HOME not set', () { |
| fakeEnv.clear(); |
| expect(() { |
| xdg.configHome; |
| }, throwsStateError); |
| }); |
| } |
| |
| class FakeProcessManager extends Fake implements ProcessManager { |
| FakeProcessManager(this.expected, {this.canRunExecutable = true}); |
| |
| Map<String, String> expected; |
| final bool canRunExecutable; |
| |
| @override |
| ProcessResult runSync( |
| List<dynamic> command, { |
| String? workingDirectory, |
| Map<String, String>? environment, |
| bool includeParentEnvironment = true, |
| bool runInShell = false, |
| Encoding stdoutEncoding = systemEncoding, |
| Encoding stderrEncoding = systemEncoding, |
| }) { |
| return ProcessResult(0, 0, expected[command[1]], ''); |
| } |
| |
| @override |
| bool canRun(dynamic executable, {String? workingDirectory}) { |
| return canRunExecutable; |
| } |
| } |