| // 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(); |
| } |
| } |