blob: 7b730ca76553f4a58cd0c6673d6e3ab60d5ca842 [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.
@TestOn('vm') // Uses dart:io
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:cross_file/cross_file.dart';
import 'package:test/test.dart';
final String pathPrefix =
Directory.current.path.endsWith('test') ? './assets/' : './test/assets/';
final String path = '${pathPrefix}hello.txt';
const String expectedStringContents = 'Hello, world!';
final Uint8List bytes = Uint8List.fromList(utf8.encode(expectedStringContents));
final File textFile = File(path);
final String textFilePath = textFile.path;
void main() {
group('Create with a path', () {
test('Can be read as a string', () async {
final XFile file = XFile(textFilePath);
expect(await file.readAsString(), equals(expectedStringContents));
});
test('Can be read as bytes', () async {
final XFile file = XFile(textFilePath);
expect(await file.readAsBytes(), equals(bytes));
});
test('Can be read as a stream', () async {
final XFile file = XFile(textFilePath);
expect(await file.openRead().first, equals(bytes));
});
test('Stream can be sliced', () async {
final XFile file = XFile(textFilePath);
expect(await file.openRead(2, 5).first, equals(bytes.sublist(2, 5)));
});
test('saveTo(..) creates file', () async {
final XFile file = XFile(textFilePath);
final Directory tempDir = Directory.systemTemp.createTempSync();
final File targetFile = File('${tempDir.path}/newFilePath.txt');
if (targetFile.existsSync()) {
await targetFile.delete();
}
await file.saveTo(targetFile.path);
expect(targetFile.existsSync(), isTrue);
expect(targetFile.readAsStringSync(), 'Hello, world!');
await tempDir.delete(recursive: true);
});
test('saveTo(..) does not load the file into memory', () async {
final TestXFile file = TestXFile(textFilePath);
final Directory tempDir = Directory.systemTemp.createTempSync();
final File targetFile = File('${tempDir.path}/newFilePath.txt');
if (targetFile.existsSync()) {
await targetFile.delete();
}
await file.saveTo(targetFile.path);
expect(file.hasBeenRead, isFalse);
await tempDir.delete(recursive: true);
});
test('nullability is correct', () async {
expect(_ensureNonnullPathArgument('a/path'), isNotNull);
});
});
group('Create with data', () {
final XFile file = XFile.fromData(bytes);
test('Can be read as a string', () async {
expect(await file.readAsString(), equals(expectedStringContents));
});
test('Can be read as bytes', () async {
expect(await file.readAsBytes(), equals(bytes));
});
test('Can be read as a stream', () async {
expect(await file.openRead().first, equals(bytes));
});
test('Stream can be sliced', () async {
expect(await file.openRead(2, 5).first, equals(bytes.sublist(2, 5)));
});
test('Function saveTo(..) creates file', () async {
final Directory tempDir = Directory.systemTemp.createTempSync();
final File targetFile = File('${tempDir.path}/newFilePath.txt');
if (targetFile.existsSync()) {
await targetFile.delete();
}
await file.saveTo(targetFile.path);
expect(targetFile.existsSync(), isTrue);
expect(targetFile.readAsStringSync(), 'Hello, world!');
await tempDir.delete(recursive: true);
});
});
}
// This is to create an analysis error if the version of XFile in
// interface.dart, which should never actually be used but is what the analyzer
// runs against, has the nullability of `path` changed.
XFile _ensureNonnullPathArgument(String? path) {
return XFile(path!);
}
/// An XFile subclass that tracks reads, for testing purposes.
class TestXFile extends XFile {
TestXFile(super.path);
bool hasBeenRead = false;
@override
Future<Uint8List> readAsBytes() {
hasBeenRead = true;
return super.readAsBytes();
}
}