blob: b3c95d3df7f839919638ee025033bf78881f764c [file] [log] [blame]
// 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;
}
}