mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-28 01:45:55 +08:00
Add a FileStorage class
With a test!
This commit is contained in:
51
lib/file_storage.dart
Normal file
51
lib/file_storage.dart
Normal file
@ -0,0 +1,51 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import './note.dart';
|
||||
|
||||
class FileStorage {
|
||||
final Future<Directory> Function() getDirectory;
|
||||
|
||||
FileStorage(this.getDirectory);
|
||||
|
||||
Future<List<Note>> loadNotes() async {
|
||||
final dir = await getDirectory();
|
||||
|
||||
var notes = new List<Note>();
|
||||
var lister = dir.list(recursive: false);
|
||||
await for (var fileEntity in lister) {
|
||||
Note note = await _loadNote(fileEntity);
|
||||
notes.add(note);
|
||||
}
|
||||
|
||||
return notes;
|
||||
}
|
||||
|
||||
Future<Note> _loadNote(FileSystemEntity entity) async {
|
||||
if (entity is! File) {
|
||||
return null;
|
||||
}
|
||||
var file = entity as File;
|
||||
final string = await file.readAsString();
|
||||
final json = JsonDecoder().convert(string);
|
||||
return new Note.fromJson(json);
|
||||
}
|
||||
|
||||
Future<Directory> saveNotes(List<Note> notes) async {
|
||||
final dir = await getDirectory();
|
||||
//await dir.delete(recursive: true);
|
||||
|
||||
for (var note in notes) {
|
||||
var filePath = p.join(dir.path, note.id);
|
||||
|
||||
var file = new File(filePath);
|
||||
var contents = JsonEncoder().convert(note.toJson());
|
||||
await file.writeAsString(contents);
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
}
|
@ -1,13 +1,43 @@
|
||||
class Note {
|
||||
class Note implements Comparable {
|
||||
final String id;
|
||||
final DateTime createdAt;
|
||||
final String body;
|
||||
|
||||
const Note({this.createdAt, this.body});
|
||||
const Note({this.createdAt, this.body, this.id});
|
||||
|
||||
factory Note.fromJson(Map<String, dynamic> json) {
|
||||
return new Note(
|
||||
id: json['id'],
|
||||
createdAt: DateTime.parse(json['createdAt']),
|
||||
body: json['body'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"createdAt": createdAt.toIso8601String(),
|
||||
"body": body,
|
||||
"id": id,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode ^ createdAt.hashCode ^ body.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is Note &&
|
||||
runtimeType == other.runtimeType &&
|
||||
id == other.id &&
|
||||
body == other.body &&
|
||||
createdAt == other.createdAt;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Note{id: $id, body: $body, createdAt: $createdAt}';
|
||||
}
|
||||
|
||||
@override
|
||||
int compareTo(other) => createdAt.compareTo(other.createdAt);
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ packages:
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
path:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -6,7 +6,7 @@ dependencies:
|
||||
sdk: flutter
|
||||
http: "^0.11.3+16"
|
||||
intl: "^0.15.6"
|
||||
|
||||
path: "^1.5.1"
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
40
test/file_storage_test.dart
Normal file
40
test/file_storage_test.dart
Normal file
@ -0,0 +1,40 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import '../lib/note.dart';
|
||||
import '../lib/file_storage.dart';
|
||||
|
||||
main() {
|
||||
group('FileStorage', () {
|
||||
var notes = [
|
||||
Note(id: "1", body: "test", createdAt: new DateTime.now()),
|
||||
Note(id: "2", body: "test2", createdAt: new DateTime.now()),
|
||||
];
|
||||
|
||||
final directory = Directory.systemTemp.createTemp('__storage_test__');
|
||||
final storage = FileStorage(() => directory);
|
||||
|
||||
tearDownAll(() async {
|
||||
final tempDirectory = await directory;
|
||||
tempDirectory.deleteSync(recursive: true);
|
||||
});
|
||||
|
||||
test('Should persist Notes to disk', () async {
|
||||
var dir = await storage.saveNotes(notes);
|
||||
expect(dir.listSync(recursive: true).length, 2);
|
||||
|
||||
expect(File(p.join(dir.path, "1")).existsSync(), isTrue);
|
||||
expect(File(p.join(dir.path, "2")).existsSync(), isTrue);
|
||||
});
|
||||
|
||||
test('Should load Notes from disk', () async {
|
||||
var loadedNotes = await storage.loadNotes();
|
||||
loadedNotes.sort();
|
||||
notes.sort();
|
||||
|
||||
expect(loadedNotes, notes);
|
||||
});
|
||||
});
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// This is a basic Flutter widget test.
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter
|
||||
// provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to
|
||||
// find child widgets in the widget tree, read text, and verify that the values of widget properties
|
||||
// are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:journal/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(new MyApp());
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user