Dart: Add analysis_options

For now I've mostly tried to follow the same style guide as the flutter
repository, with many options disabled. Eventually, maybe it would make
sense to be far stricter.
This commit is contained in:
Vishesh Handa
2019-02-13 13:08:15 +01:00
parent ee34b60e53
commit acede95536
28 changed files with 295 additions and 176 deletions

124
analysis_options.yaml Normal file
View File

@ -0,0 +1,124 @@
# Specify analysis options.
#
# Until there are meta linter rules, each desired lint must be explicitly enabled.
# See: https://github.com/dart-lang/linter/issues/288
#
# For a list of lints, see: http://dart-lang.github.io/linter/lints/
#
analyzer:
strong-mode:
implicit-dynamic: true
errors:
missing_required_param: error
missing_return: error
todo: ignore
exclude:
- "bin/cache/**"
linter:
rules:
# these rules are documented on and in the same order as
# the Dart Lint rules page to make maintenance easier
# http://dart-lang.github.io/linter/lints/
# === error rules ===
- avoid_empty_else
- avoid_slow_async_io
- cancel_subscriptions
# - close_sinks # https://github.com/flutter/flutter/issues/5789
# - comment_references # blocked on https://github.com/dart-lang/dartdoc/issues/1153
- control_flow_in_finally
- empty_statements
- hash_and_equals
# - invariant_booleans # https://github.com/flutter/flutter/issues/5790
- iterable_contains_unrelated_type
- list_remove_unrelated_type
# - literal_only_boolean_expressions # https://github.com/flutter/flutter/issues/5791
- no_adjacent_strings_in_list
- no_duplicate_case_values
- test_types_in_equals
- throw_in_finally
- unrelated_type_equality_checks
- valid_regexps
# === style rules ===
- always_declare_return_types
# - always_put_control_body_on_new_line
- always_require_non_null_named_parameters
# - always_specify_types
- annotate_overrides
# - avoid_annotating_with_dynamic # not yet tested
# - avoid_as
# - avoid_catches_without_on_clauses # not yet tested
# - avoid_catching_errors # not yet tested
# - avoid_classes_with_only_static_members # not yet tested
# - avoid_function_literals_in_foreach_calls # not yet tested
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
# - avoid_positional_boolean_parameters # not yet tested
- avoid_return_types_on_setters
# - avoid_returning_null # not yet tested
# - avoid_returning_this # not yet tested
# - avoid_setters_without_getters # not yet tested
# - avoid_types_on_closure_parameters # not yet tested
- await_only_futures
- camel_case_types
# - cascade_invocations # not yet tested
# - constant_identifier_names # https://github.com/dart-lang/linter/issues/204
- directives_ordering
- empty_catches
- empty_constructor_bodies
- implementation_imports
# - join_return_with_assignment # not yet tested
- library_names
- library_prefixes
- non_constant_identifier_names
# - omit_local_variable_types # opposite of always_specify_types
# - one_member_abstracts # too many false positives
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
- overridden_fields
- package_api_docs
- package_prefixed_library_names
# - parameter_assignments # we do this commonly
- prefer_adjacent_string_concatenation
# - prefer_collection_literals
# - prefer_conditional_assignment # not yet tested
# - prefer_const_constructors
# - prefer_constructors_over_static_methods # not yet tested
- prefer_contains
- prefer_equal_for_default_values
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
# - prefer_final_fields # https://github.com/dart-lang/linter/issues/506
# - prefer_final_locals
# - prefer_foreach # not yet tested
# - prefer_function_declarations_over_variables # not yet tested
- prefer_initializing_formals
# - prefer_interpolation_to_compose_strings # not yet tested
- prefer_is_empty
- prefer_is_not_empty
- prefer_void_to_null
# - recursive_getters # https://github.com/dart-lang/linter/issues/452
- slash_for_doc_comments
# - sort_constructors_first
# - sort_unnamed_constructors_first
- super_goes_last
# - type_annotate_public_apis # subset of always_specify_types
- type_init_formals
# - unawaited_futures # https://github.com/flutter/flutter/issues/5793
- unnecessary_brace_in_string_interps
# - unnecessary_const
- unnecessary_getters_setters
# - unnecessary_lambdas # https://github.com/dart-lang/linter/issues/498
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_in_if_null_operators
# - unnecessary_overrides # https://github.com/dart-lang/linter/issues/626 and https://github.com/dart-lang/linter/issues/627
- unnecessary_statements
# - unnecessary_this
- use_rethrow_when_possible
# - use_setters_to_change_properties # not yet tested
# - use_string_buffers # https://github.com/dart-lang/linter/pull/664
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
# === pub rules ===
- package_names

View File

@ -11,7 +11,7 @@ Future<Directory> getGitBaseDirectory() async {
if (path == null) { if (path == null) {
return null; return null;
} }
return new Directory(path); return Directory(path);
} }
Future<void> gitClone(String cloneUrl, String folderName) async { Future<void> gitClone(String cloneUrl, String folderName) async {
@ -43,7 +43,7 @@ Future<String> generateSSHKeys({@required String comment}) async {
} }
try { try {
String publicKey = await _platform.invokeMethod('getSSHPublicKey', {}); String publicKey = await _platform.invokeMethod('getSSHPublicKey');
print("Public Key " + publicKey); print("Public Key " + publicKey);
return publicKey; return publicKey;
} on PlatformException catch (e) { } on PlatformException catch (e) {
@ -65,7 +65,7 @@ Future<void> setSshKeys({
}); });
} on PlatformException catch (e) { } on PlatformException catch (e) {
print("Failed to generateSSHKeys: '${e.message}'."); print("Failed to generateSSHKeys: '${e.message}'.");
throw e; rethrow;
} }
} }

View File

@ -18,13 +18,13 @@ Future migrateGitRepo({
var fromBasePath = p.join(gitBasePath, fromGitBasePath); var fromBasePath = p.join(gitBasePath, fromGitBasePath);
var toBasePath = p.join(gitBasePath, toGitBasePath); var toBasePath = p.join(gitBasePath, toGitBasePath);
final dir = new Directory(fromBasePath); final dir = Directory(fromBasePath);
var lister = dir.list(recursive: false); var lister = dir.list(recursive: false);
await for (var fileEntity in lister) { await for (var fileEntity in lister) {
if (fileEntity is! File) { if (fileEntity is! File) {
continue; continue;
} }
var file = fileEntity as File; File file = fileEntity;
var fileName = p.basename(file.path); var fileName = p.basename(file.path);
var toPath = p.join(toBasePath, fileName); var toPath = p.join(toBasePath, fileName);

View File

@ -13,10 +13,10 @@ enum GitHostType {
GitHost createGitHost(GitHostType type) { GitHost createGitHost(GitHostType type) {
switch (type) { switch (type) {
case GitHostType.GitHub: case GitHostType.GitHub:
return new GitHub(); return GitHub();
case GitHostType.GitLab: case GitHostType.GitLab:
return new GitLab(); return GitLab();
default: default:
return null; return null;

View File

@ -25,7 +25,7 @@ class GitHub implements GitHost {
print("GitHub: Called onUrl with " + call.arguments.toString()); print("GitHub: Called onUrl with " + call.arguments.toString());
var url = call.arguments["URL"]; String url = call.arguments["URL"];
var uri = Uri.parse(url); var uri = Uri.parse(url);
var authCode = uri.queryParameters['code']; var authCode = uri.queryParameters['code'];
if (authCode == null) { if (authCode == null) {
@ -88,7 +88,7 @@ class GitHub implements GitHost {
} }
List<dynamic> list = jsonDecode(response.body); List<dynamic> list = jsonDecode(response.body);
var repos = new List<GitRepo>(); var repos = List<GitRepo>();
list.forEach((dynamic d) { list.forEach((dynamic d) {
var map = Map<String, dynamic>.from(d); var map = Map<String, dynamic>.from(d);
var repo = _repoFromJson(map); var repo = _repoFromJson(map);
@ -107,7 +107,7 @@ class GitHub implements GitHost {
} }
var url = "https://api.github.com/user/repos?access_token=$_accessCode"; var url = "https://api.github.com/user/repos?access_token=$_accessCode";
Map<String, dynamic> data = { var data = <String, dynamic>{
'name': name, 'name': name,
'private': true, 'private': true,
}; };
@ -134,11 +134,12 @@ class GitHub implements GitHost {
} }
print("GitHub createRepo: " + response.body); print("GitHub createRepo: " + response.body);
var map = json.decode(response.body); Map<String, dynamic> map = json.decode(response.body);
return _repoFromJson(map); return _repoFromJson(map);
} }
// FIXME: Proper error when the repo exists! // FIXME: Proper error when the repo exists!
@override
Future addDeployKey(String sshPublicKey, String repo) async { Future addDeployKey(String sshPublicKey, String repo) async {
if (_accessCode.isEmpty) { if (_accessCode.isEmpty) {
throw GitHostException.MissingAccessCode; throw GitHostException.MissingAccessCode;
@ -147,7 +148,7 @@ class GitHub implements GitHost {
var url = var url =
"https://api.github.com/repos/$repo/keys?access_token=$_accessCode"; "https://api.github.com/repos/$repo/keys?access_token=$_accessCode";
Map<String, dynamic> data = { var data = <String, dynamic>{
'title': "GitJournal", 'title': "GitJournal",
'key': sshPublicKey, 'key': sshPublicKey,
'read_only': false, 'read_only': false,
@ -172,7 +173,7 @@ class GitHub implements GitHost {
} }
GitRepo _repoFromJson(Map<String, dynamic> parsedJson) { GitRepo _repoFromJson(Map<String, dynamic> parsedJson) {
return new GitRepo( return GitRepo(
fullName: parsedJson['full_name'], fullName: parsedJson['full_name'],
cloneUrl: parsedJson['ssh_url'], cloneUrl: parsedJson['ssh_url'],
); );

View File

@ -80,7 +80,7 @@ class GitLab implements GitHost {
} }
List<dynamic> list = jsonDecode(response.body); List<dynamic> list = jsonDecode(response.body);
var repos = new List<GitRepo>(); var repos = List<GitRepo>();
list.forEach((dynamic d) { list.forEach((dynamic d) {
var map = Map<String, dynamic>.from(d); var map = Map<String, dynamic>.from(d);
var repo = _repoFromJson(map); var repo = _repoFromJson(map);
@ -99,7 +99,7 @@ class GitLab implements GitHost {
} }
var url = "https://gitlab.com/api/v4/projects?access_token=$_accessCode"; var url = "https://gitlab.com/api/v4/projects?access_token=$_accessCode";
Map<String, dynamic> data = { var data = <String, dynamic>{
'name': name, 'name': name,
'visibility': 'private', 'visibility': 'private',
}; };
@ -126,7 +126,7 @@ class GitLab implements GitHost {
} }
print("GitLab createRepo: " + response.body); print("GitLab createRepo: " + response.body);
var map = json.decode(response.body); Map<String, dynamic> map = json.decode(response.body);
return _repoFromJson(map); return _repoFromJson(map);
} }
@ -140,7 +140,7 @@ class GitLab implements GitHost {
var url = var url =
"https://gitlab.com/api/v4/projects/$repo/deploy_keys?access_token=$_accessCode"; "https://gitlab.com/api/v4/projects/$repo/deploy_keys?access_token=$_accessCode";
Map<String, dynamic> data = { var data = {
'title': "GitJournal", 'title': "GitJournal",
'key': sshPublicKey, 'key': sshPublicKey,
'can_push': true, 'can_push': true,
@ -165,7 +165,7 @@ class GitLab implements GitHost {
} }
GitRepo _repoFromJson(Map<String, dynamic> parsedJson) { GitRepo _repoFromJson(Map<String, dynamic> parsedJson) {
return new GitRepo( return GitRepo(
fullName: parsedJson['path_with_namespace'], fullName: parsedJson['path_with_namespace'],
cloneUrl: parsedJson['ssh_url_to_repo'], cloneUrl: parsedJson['ssh_url_to_repo'],
); );
@ -202,10 +202,10 @@ class GitLab implements GitHost {
} }
String _randomString(int length) { String _randomString(int length) {
var rand = new Random(); var rand = Random();
var codeUnits = new List.generate(length, (index) { var codeUnits = List.generate(length, (index) {
return rand.nextInt(33) + 89; return rand.nextInt(33) + 89;
}); });
return new String.fromCharCodes(codeUnits); return String.fromCharCodes(codeUnits);
} }

View File

@ -28,9 +28,9 @@ class JournalApp extends StatelessWidget {
stateContainer.completeGitHostSetup(); stateContainer.completeGitHostSetup();
}; };
return new MaterialApp( return MaterialApp(
title: 'GitJournal', title: 'GitJournal',
theme: new ThemeData( theme: ThemeData(
brightness: Brightness.light, brightness: Brightness.light,
primaryColor: Color(0xFF66bb6a), primaryColor: Color(0xFF66bb6a),
primaryColorLight: Color(0xFF98ee99), primaryColorLight: Color(0xFF98ee99),

View File

@ -6,11 +6,11 @@ const basePath = "journal";
String cloneUrl = "git@github.com:GitJournal/journal_test.git"; String cloneUrl = "git@github.com:GitJournal/journal_test.git";
class GitApp extends StatelessWidget { class GitApp extends StatelessWidget {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new MaterialApp( return MaterialApp(
title: 'Git App', title: 'Git App',
home: Scaffold( home: Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
@ -30,16 +30,16 @@ class GitApp extends StatelessWidget {
var text = "Success"; var text = "Success";
this._scaffoldKey.currentState this._scaffoldKey.currentState
..removeCurrentSnackBar() ..removeCurrentSnackBar()
..showSnackBar(new SnackBar(content: new Text(text))); ..showSnackBar(SnackBar(content: Text(text)));
} }
void _sendError(String text) { void _sendError(String text) {
this._scaffoldKey.currentState this._scaffoldKey.currentState
..removeCurrentSnackBar() ..removeCurrentSnackBar()
..showSnackBar(new SnackBar(content: new Text("ERROR: " + text))); ..showSnackBar(SnackBar(content: Text("ERROR: " + text)));
} }
_buildGitButtons() { List<Widget> _buildGitButtons() {
return <Widget>[ return <Widget>[
RaisedButton( RaisedButton(
child: Text("Generate Keys"), child: Text("Generate Keys"),

View File

@ -21,9 +21,9 @@ void main() async {
await FlutterCrashlytics().initialize(); await FlutterCrashlytics().initialize();
runZoned<Future<Null>>(() async { runZoned<Future<void>>(() async {
await runJournalApp(); await runJournalApp();
}, onError: (error, stackTrace) async { }, onError: (Error error, StackTrace stackTrace) async {
await FlutterCrashlytics() await FlutterCrashlytics()
.reportCrash(error, stackTrace, forceCrash: false); .reportCrash(error, stackTrace, forceCrash: false);
}); });
@ -60,7 +60,7 @@ Future runJournalApp() async {
await Settings.instance.load(); await Settings.instance.load();
runApp(new StateContainer( runApp(StateContainer(
localGitRepoConfigured: localGitRepoConfigured, localGitRepoConfigured: localGitRepoConfigured,
remoteGitRepoConfigured: remoteGitRepoConfigured, remoteGitRepoConfigured: remoteGitRepoConfigured,
localGitRepoPath: localGitRepoPath, localGitRepoPath: localGitRepoPath,

View File

@ -1,22 +1,18 @@
import 'package:journal/datetime_utils.dart'; import 'package:journal/datetime_utils.dart';
typedef NoteAdder(Note note); class Note implements Comparable<Note> {
typedef NoteRemover(Note note);
typedef NoteUpdator(Note note);
class Note implements Comparable {
String fileName; String fileName;
DateTime created; DateTime created;
String body; String body;
Map<String, dynamic> extraProperties = new Map<String, dynamic>(); Map<String, dynamic> extraProperties = Map<String, dynamic>();
Note({this.created, this.body, this.fileName, this.extraProperties}) { Note({this.created, this.body, this.fileName, this.extraProperties}) {
if (created == null) { if (created == null) {
created = DateTime(0, 0, 0, 0, 0, 0, 0, 0); created = DateTime(0, 0, 0, 0, 0, 0, 0, 0);
} }
if (extraProperties == null) { if (extraProperties == null) {
extraProperties = new Map<String, dynamic>(); extraProperties = Map<String, dynamic>();
} }
} }
@ -32,10 +28,12 @@ class Note implements Comparable {
var createdStr = json['created'].toString(); var createdStr = json['created'].toString();
try { try {
created = DateTime.parse(json['created']).toLocal(); created = DateTime.parse(json['created']).toLocal();
} catch (ex) {} } catch (ex) {
// Ignore it
}
if (created == null) { if (created == null) {
var regex = new RegExp( var regex = RegExp(
r"(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})\+(\d{2})\:(\d{2})"); r"(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})\+(\d{2})\:(\d{2})");
if (regex.hasMatch(createdStr)) { if (regex.hasMatch(createdStr)) {
// FIXME: Handle the timezone! // FIXME: Handle the timezone!
@ -57,7 +55,7 @@ class Note implements Comparable {
json.remove("body"); json.remove("body");
} }
return new Note( return Note(
fileName: fileName, fileName: fileName,
created: created, created: created,
body: body, body: body,
@ -96,7 +94,8 @@ class Note implements Comparable {
static bool _equalMaps(Map a, Map b) { static bool _equalMaps(Map a, Map b) {
if (a.length != b.length) return false; if (a.length != b.length) return false;
return a.keys.every((key) => b.containsKey(key) && a[key] == b[key]); return a.keys
.every((dynamic key) => b.containsKey(key) && a[key] == b[key]);
} }
@override @override
@ -105,7 +104,7 @@ class Note implements Comparable {
} }
@override @override
int compareTo(other) { int compareTo(Note other) {
if (other == null) { if (other == null) {
return -1; return -1;
} }

View File

@ -1,7 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:journal/note.dart'; import 'package:journal/note.dart';
import 'package:journal/state_container.dart'; import 'package:journal/state_container.dart';
import 'package:journal/widgets/note_header.dart'; import 'package:journal/widgets/note_header.dart';
@ -15,25 +14,24 @@ class NoteEditor extends StatefulWidget {
@override @override
NoteEditorState createState() { NoteEditorState createState() {
if (note == null) { if (note == null) {
return new NoteEditorState(); return NoteEditorState();
} else { } else {
return new NoteEditorState.fromNote(note); return NoteEditorState.fromNote(note);
} }
} }
} }
class NoteEditorState extends State<NoteEditor> { class NoteEditorState extends State<NoteEditor> {
Note note = new Note(); Note note = Note();
final bool newNote; final bool newNote;
TextEditingController _textController = new TextEditingController(); TextEditingController _textController = TextEditingController();
NoteEditorState() : newNote = true { NoteEditorState() : newNote = true {
note.created = new DateTime.now(); note.created = DateTime.now();
} }
NoteEditorState.fromNote(Note n) : newNote = false { NoteEditorState.fromNote(this.note) : newNote = false {
note = n; _textController = TextEditingController(text: note.body);
_textController = new TextEditingController(text: note.body);
} }
@override @override
@ -62,7 +60,7 @@ class NoteEditorState extends State<NoteEditor> {
autofocus: true, autofocus: true,
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,
maxLines: null, maxLines: null,
decoration: new InputDecoration( decoration: InputDecoration(
hintText: 'Write here', hintText: 'Write here',
border: InputBorder.none, border: InputBorder.none,
), ),
@ -71,10 +69,10 @@ class NoteEditorState extends State<NoteEditor> {
), ),
); );
var title = newNote ? "New Journal Entry" : "Edit Journal Entry"; var title = newNote ? "Journal Entry" : "Edit Journal Entry";
var newJournalScreen = new Scaffold( var newJournalScreen = Scaffold(
appBar: new AppBar( appBar: AppBar(
title: new Text(title), title: Text(title),
), ),
body: Padding( body: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
@ -108,18 +106,18 @@ class NoteEditorState extends State<NoteEditor> {
? "Do you want to discard the entry" ? "Do you want to discard the entry"
: "Do you want to discard the changes?"; : "Do you want to discard the changes?";
return new AlertDialog( return AlertDialog(
// FIXME: Change this to 'Save' vs 'Discard' // FIXME: Change this to 'Save' vs 'Discard'
title: new Text('Are you sure?'), title: Text('Are you sure?'),
content: new Text(title), content: Text(title),
actions: <Widget>[ actions: <Widget>[
new FlatButton( FlatButton(
onPressed: () => Navigator.of(context).pop(false), onPressed: () => Navigator.of(context).pop(false),
child: new Text('No'), child: Text('No'),
), ),
new FlatButton( FlatButton(
onPressed: () => Navigator.of(context).pop(true), onPressed: () => Navigator.of(context).pop(true),
child: new Text('Yes'), child: Text('Yes'),
), ),
], ],
); );

View File

@ -16,7 +16,7 @@ class NoteBrowsingScreen extends StatefulWidget {
@override @override
NoteBrowsingScreenState createState() { NoteBrowsingScreenState createState() {
return new NoteBrowsingScreenState(noteIndex: noteIndex); return NoteBrowsingScreenState(noteIndex: noteIndex);
} }
} }
@ -24,28 +24,28 @@ class NoteBrowsingScreenState extends State<NoteBrowsingScreen> {
PageController pageController; PageController pageController;
NoteBrowsingScreenState({@required int noteIndex}) { NoteBrowsingScreenState({@required int noteIndex}) {
pageController = new PageController(initialPage: noteIndex); pageController = PageController(initialPage: noteIndex);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var pageView = new PageView.builder( var pageView = PageView.builder(
controller: pageController, controller: pageController,
itemCount: widget.notes.length, itemCount: widget.notes.length,
itemBuilder: (BuildContext context, int pos) { itemBuilder: (BuildContext context, int pos) {
return new NoteViewer(note: widget.notes[pos]); return NoteViewer(note: widget.notes[pos]);
}, },
); );
return new Scaffold( return Scaffold(
appBar: new AppBar( appBar: AppBar(
title: new Text('TIMELINE'), title: Text('TIMELINE'),
), ),
body: pageView, body: pageView,
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
child: Icon(Icons.edit), child: Icon(Icons.edit),
onPressed: () { onPressed: () {
var route = new MaterialPageRoute(builder: (context) { var route = MaterialPageRoute<Widget>(builder: (context) {
int currentIndex = pageController.page.toInt(); int currentIndex = pageController.page.toInt();
assert(currentIndex >= 0); assert(currentIndex >= 0);
assert(currentIndex < widget.notes.length); assert(currentIndex < widget.notes.length);
@ -68,8 +68,8 @@ class NoteViewer extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var view = new SingleChildScrollView( var view = SingleChildScrollView(
child: new Column( child: Column(
children: <Widget>[ children: <Widget>[
NoteHeader(note), NoteHeader(note),
Text(note.body, style: _biggerFont), Text(note.body, style: _biggerFont),
@ -85,21 +85,21 @@ class NoteViewer extends StatelessWidget {
/* /*
Widget _buildFooter(BuildContext context) { Widget _buildFooter(BuildContext context) {
return new Padding( return Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8.0), padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: new Row( child: Row(
children: <Widget>[ children: <Widget>[
new IconButton( IconButton(
icon: new Icon(Icons.arrow_left), icon: Icon(Icons.arrow_left),
tooltip: 'Previous Entry', tooltip: 'Previous Entry',
onPressed: showPrevNoteFunc, onPressed: showPrevNoteFunc,
), ),
new Expanded( Expanded(
flex: 10, flex: 10,
child: new Text(''), child: Text(''),
), ),
new IconButton( IconButton(
icon: new Icon(Icons.arrow_right), icon: Icon(Icons.arrow_right),
tooltip: 'Next Entry', tooltip: 'Next Entry',
onPressed: showNextNoteFunc, onPressed: showNextNoteFunc,
), ),

View File

@ -5,7 +5,7 @@ import 'apis/githost_factory.dart';
class OAuthApp extends StatefulWidget { class OAuthApp extends StatefulWidget {
@override @override
OAuthAppState createState() { OAuthAppState createState() {
return new OAuthAppState(); return OAuthAppState();
} }
} }
@ -15,6 +15,7 @@ var key =
class OAuthAppState extends State<OAuthApp> { class OAuthAppState extends State<OAuthApp> {
GitHost githost; GitHost githost;
@override
void initState() { void initState() {
super.initState(); super.initState();
@ -26,7 +27,7 @@ class OAuthAppState extends State<OAuthApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new MaterialApp( return MaterialApp(
title: 'OAuth App', title: 'OAuth App',
home: Scaffold( home: Scaffold(
appBar: AppBar( appBar: AppBar(

View File

@ -14,7 +14,7 @@ class GitHostSetupAutoConfigure extends StatefulWidget {
@override @override
GitHostSetupAutoConfigureState createState() { GitHostSetupAutoConfigureState createState() {
return new GitHostSetupAutoConfigureState(); return GitHostSetupAutoConfigureState();
} }
} }

View File

@ -21,7 +21,7 @@ class GitHostSetupScreen extends StatefulWidget {
@override @override
GitHostSetupScreenState createState() { GitHostSetupScreenState createState() {
return new GitHostSetupScreenState(); return GitHostSetupScreenState();
} }
} }
@ -42,7 +42,7 @@ class GitHostSetupScreenState extends State<GitHostSetupScreen> {
var pageController = PageController(); var pageController = PageController();
int _currentPageIndex = 0; int _currentPageIndex = 0;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
String publicKey = ""; String publicKey = "";
bool _canLaunchDeployKeyPage = false; bool _canLaunchDeployKeyPage = false;
@ -283,16 +283,16 @@ class GitHostSetupScreenState extends State<GitHostSetupScreen> {
}, },
); );
var scaffold = new Scaffold( var scaffold = Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: new Container( body: Container(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Stack( child: Stack(
alignment: FractionalOffset.bottomCenter, alignment: FractionalOffset.bottomCenter,
children: <Widget>[ children: <Widget>[
pageView, pageView,
new DotsIndicator( DotsIndicator(
numberOfDot: pageCount, numberOfDot: pageCount,
position: _currentPageIndex, position: _currentPageIndex,
dotActiveColor: Theme.of(context).primaryColorDark, dotActiveColor: Theme.of(context).primaryColorDark,
@ -303,7 +303,7 @@ class GitHostSetupScreenState extends State<GitHostSetupScreen> {
), ),
); );
return new WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
if (_currentPageIndex != 0) { if (_currentPageIndex != 0) {
pageController.previousPage( pageController.previousPage(
@ -348,7 +348,7 @@ class GitHostSetupScreenState extends State<GitHostSetupScreen> {
var text = "Public Key copied to Clipboard"; var text = "Public Key copied to Clipboard";
this._scaffoldKey.currentState this._scaffoldKey.currentState
..removeCurrentSnackBar() ..removeCurrentSnackBar()
..showSnackBar(new SnackBar(content: new Text(text))); ..showSnackBar(SnackBar(content: Text(text)));
} }
void _launchDeployKeyPage() async { void _launchDeployKeyPage() async {
@ -423,8 +423,8 @@ class GitHostSetupScreenState extends State<GitHostSetupScreen> {
} }
Future _removeExistingClone(String baseDirPath) async { Future _removeExistingClone(String baseDirPath) async {
var baseDir = new Directory(p.join(baseDirPath, "journal")); var baseDir = Directory(p.join(baseDirPath, "journal"));
var dotGitDir = new Directory(p.join(baseDir.path, ".git")); var dotGitDir = Directory(p.join(baseDir.path, ".git"));
bool exists = await dotGitDir.exists(); bool exists = await dotGitDir.exists();
if (exists) { if (exists) {
print("Removing " + baseDir.path); print("Removing " + baseDir.path);
@ -498,7 +498,7 @@ class GitHostSetupCreateRepo extends StatefulWidget {
@override @override
GitHostSetupCreateRepoState createState() { GitHostSetupCreateRepoState createState() {
return new GitHostSetupCreateRepoState(); return GitHostSetupCreateRepoState();
} }
} }

View File

@ -9,7 +9,7 @@ class GitHostSetupUrl extends StatefulWidget {
@override @override
GitHostSetupUrlState createState() { GitHostSetupUrlState createState() {
return new GitHostSetupUrlState(); return GitHostSetupUrlState();
} }
} }
@ -51,7 +51,7 @@ class GitHostSetupUrlState extends State<GitHostSetupUrl> {
return 'Only SSH urls are currently accepted'; return 'Only SSH urls are currently accepted';
} }
RegExp regExp = new RegExp(r"[a-zA-Z0-9.]+@[a-zA-Z0-9.]+:.+"); RegExp regExp = RegExp(r"[a-zA-Z0-9.]+@[a-zA-Z0-9.]+:.+");
if (!regExp.hasMatch(value)) { if (!regExp.hasMatch(value)) {
return "Invalid Input"; return "Invalid Input";
} }

View File

@ -8,23 +8,23 @@ import 'package:journal/widgets/app_drawer.dart';
import 'package:journal/widgets/journal_list.dart'; import 'package:journal/widgets/journal_list.dart';
class HomeScreen extends StatelessWidget { class HomeScreen extends StatelessWidget {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final container = StateContainer.of(context); final container = StateContainer.of(context);
final appState = container.appState; final appState = container.appState;
var createButton = new FloatingActionButton( var createButton = FloatingActionButton(
onPressed: () => _newPost(context), onPressed: () => _newPost(context),
child: new Icon(Icons.add), child: Icon(Icons.add),
); );
var journalList = JournalList( var journalList = JournalList(
notes: appState.notes, notes: appState.notes,
noteSelectedFunction: (noteIndex) { noteSelectedFunction: (noteIndex) {
var route = new MaterialPageRoute( var route = MaterialPageRoute(
builder: (context) => new NoteBrowsingScreen( builder: (context) => NoteBrowsingScreen(
notes: appState.notes, notes: appState.notes,
noteIndex: noteIndex, noteIndex: noteIndex,
), ),
@ -41,10 +41,10 @@ class HomeScreen extends StatelessWidget {
}, },
); );
return new Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
appBar: new AppBar( appBar: AppBar(
title: new Text('GitJournal'), title: Text('GitJournal'),
leading: appBarMenuButton, leading: appBarMenuButton,
), ),
floatingActionButton: createButton, floatingActionButton: createButton,
@ -57,16 +57,16 @@ class HomeScreen extends StatelessWidget {
} on GitException catch (exp) { } on GitException catch (exp) {
_scaffoldKey.currentState _scaffoldKey.currentState
..removeCurrentSnackBar() ..removeCurrentSnackBar()
..showSnackBar(new SnackBar(content: new Text(exp.cause))); ..showSnackBar(SnackBar(content: Text(exp.cause)));
} }
}), }),
), ),
drawer: new AppDrawer(), drawer: AppDrawer(),
); );
} }
void _newPost(BuildContext context) { void _newPost(BuildContext context) {
var route = new MaterialPageRoute(builder: (context) => new NoteEditor()); var route = MaterialPageRoute(builder: (context) => NoteEditor());
Navigator.of(context).push(route); Navigator.of(context).push(route);
} }
} }

View File

@ -6,7 +6,7 @@ import 'package:package_info/package_info.dart';
class SettingsScreen extends StatelessWidget { class SettingsScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('Settings'), title: Text('Settings'),
leading: IconButton( leading: IconButton(
@ -24,7 +24,7 @@ class SettingsScreen extends StatelessWidget {
class SettingsList extends StatefulWidget { class SettingsList extends StatefulWidget {
@override @override
SettingsListState createState() { SettingsListState createState() {
return new SettingsListState(); return SettingsListState();
} }
} }
@ -142,7 +142,7 @@ class SettingsHeader extends StatelessWidget {
class VersionNumberTile extends StatefulWidget { class VersionNumberTile extends StatefulWidget {
@override @override
VersionNumberTileState createState() { VersionNumberTileState createState() {
return new VersionNumberTileState(); return VersionNumberTileState();
} }
} }

View File

@ -59,12 +59,12 @@ class StateContainerState extends State<StateContainer> {
assert(appState.localGitRepoConfigured); assert(appState.localGitRepoConfigured);
if (appState.remoteGitRepoConfigured) { if (appState.remoteGitRepoConfigured) {
noteRepo = new GitNoteRepository( noteRepo = GitNoteRepository(
baseDirectory: appState.gitBaseDirectory, baseDirectory: appState.gitBaseDirectory,
dirName: appState.remoteGitRepoPath, dirName: appState.remoteGitRepoPath,
); );
} else if (appState.localGitRepoConfigured) { } else if (appState.localGitRepoConfigured) {
noteRepo = new GitNoteRepository( noteRepo = GitNoteRepository(
baseDirectory: appState.gitBaseDirectory, baseDirectory: appState.gitBaseDirectory,
dirName: appState.localGitRepoPath, dirName: appState.localGitRepoPath,
); );
@ -80,9 +80,9 @@ class StateContainerState extends State<StateContainer> {
} }
void removeExistingRemoteClone() async { void removeExistingRemoteClone() async {
var remoteGitDir = new Directory( var remoteGitDir = Directory(
p.join(appState.gitBaseDirectory, appState.remoteGitRepoPath)); p.join(appState.gitBaseDirectory, appState.remoteGitRepoPath));
var dotGitDir = new Directory(p.join(remoteGitDir.path, ".git")); var dotGitDir = Directory(p.join(remoteGitDir.path, ".git"));
bool exists = await dotGitDir.exists(); bool exists = await dotGitDir.exists();
if (exists) { if (exists) {
@ -194,7 +194,7 @@ class StateContainerState extends State<StateContainer> {
gitBasePath: appState.gitBaseDirectory, gitBasePath: appState.gitBaseDirectory,
); );
noteRepo = new GitNoteRepository( noteRepo = GitNoteRepository(
baseDirectory: appState.gitBaseDirectory, baseDirectory: appState.gitBaseDirectory,
dirName: appState.remoteGitRepoPath, dirName: appState.remoteGitRepoPath,
); );

View File

@ -26,9 +26,9 @@ class FileStorage implements NoteRepository {
@override @override
Future<List<Note>> listNotes() async { Future<List<Note>> listNotes() async {
final dir = new Directory(baseDirectory); final dir = Directory(baseDirectory);
var notes = new List<Note>(); var notes = List<Note>();
var lister = dir.list(recursive: false); var lister = dir.list(recursive: false);
await for (var fileEntity in lister) { await for (var fileEntity in lister) {
Note note = await _loadNote(fileEntity); Note note = await _loadNote(fileEntity);
@ -63,7 +63,7 @@ class FileStorage implements NoteRepository {
var filePath = p.join(baseDirectory, note.fileName); var filePath = p.join(baseDirectory, note.fileName);
print("FileStorage: Adding note in " + filePath); print("FileStorage: Adding note in " + filePath);
var file = new File(filePath); var file = File(filePath);
if (file == null) { if (file == null) {
return NoteRepoResult(error: true); return NoteRepoResult(error: true);
} }
@ -77,7 +77,7 @@ class FileStorage implements NoteRepository {
Future<NoteRepoResult> removeNote(Note note) async { Future<NoteRepoResult> removeNote(Note note) async {
var filePath = p.join(baseDirectory, note.fileName); var filePath = p.join(baseDirectory, note.fileName);
var file = new File(filePath); var file = File(filePath);
await file.delete(); await file.delete();
return NoteRepoResult(noteFilePath: filePath, error: false); return NoteRepoResult(noteFilePath: filePath, error: false);
@ -94,12 +94,12 @@ class FileStorage implements NoteRepository {
} }
Future<Directory> saveNotes(List<Note> notes) async { Future<Directory> saveNotes(List<Note> notes) async {
final dir = new Directory(baseDirectory); final dir = Directory(baseDirectory);
for (var note in notes) { for (var note in notes) {
var filePath = p.join(dir.path, note.fileName); var filePath = p.join(dir.path, note.fileName);
var file = new File(filePath); var file = File(filePath);
var contents = noteSerializer.encode(note); var contents = noteSerializer.encode(note);
await file.writeAsString(contents); await file.writeAsString(contents);
} }

View File

@ -20,7 +20,7 @@ class GitNoteRepository implements NoteRepository {
@required this.dirName, @required this.dirName,
@required String baseDirectory, @required String baseDirectory,
}) : _fileStorage = FileStorage( }) : _fileStorage = FileStorage(
noteSerializer: new MarkdownYAMLSerializer(), noteSerializer: MarkdownYAMLSerializer(),
baseDirectory: p.join(baseDirectory, dirName), baseDirectory: p.join(baseDirectory, dirName),
); );
@ -92,8 +92,8 @@ class GitNoteRepository implements NoteRepository {
} }
if (!checkForCloned) { if (!checkForCloned) {
var baseDir = new Directory(_fileStorage.baseDirectory); var baseDir = Directory(_fileStorage.baseDirectory);
var dotGitDir = new Directory(p.join(baseDir.path, ".git")); var dotGitDir = Directory(p.join(baseDir.path, ".git"));
cloned = await dotGitDir.exists(); cloned = await dotGitDir.exists();
checkForCloned = true; checkForCloned = true;
} }
@ -116,7 +116,7 @@ class GitNoteRepository implements NoteRepository {
await gitPush(this.dirName); await gitPush(this.dirName);
} on GitException catch (ex) { } on GitException catch (ex) {
print(ex); print(ex);
throw ex; rethrow;
} }
return true; return true;

View File

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:yaml/yaml.dart';
import 'package:journal/note.dart'; import 'package:journal/note.dart';
import 'package:yaml/yaml.dart';
abstract class NoteSerializer { abstract class NoteSerializer {
String encode(Note note); String encode(Note note);
@ -12,7 +12,7 @@ class JsonNoteSerializer implements NoteSerializer {
@override @override
Note decode(String str) { Note decode(String str) {
final json = JsonDecoder().convert(str); final json = JsonDecoder().convert(str);
return new Note.fromJson(json); return Note.fromJson(json);
} }
@override @override
@ -28,18 +28,18 @@ class MarkdownYAMLSerializer implements NoteSerializer {
var parts = str.split("---\n"); var parts = str.split("---\n");
var yamlMap = loadYaml(parts[1]); var yamlMap = loadYaml(parts[1]);
var map = new Map<String, dynamic>(); var map = Map<String, dynamic>();
yamlMap.forEach((key, value) { yamlMap.forEach((key, value) {
map[key] = value; map[key] = value;
}); });
map['body'] = parts[2].trimLeft(); map['body'] = parts[2].trimLeft();
return new Note.fromJson(map); return Note.fromJson(map);
} }
var map = new Map<String, dynamic>(); var map = Map<String, dynamic>();
map['body'] = str; map['body'] = str;
return new Note.fromJson(map); return Note.fromJson(map);
} }
@override @override

View File

@ -4,13 +4,13 @@ import 'package:journal/state_container.dart';
class AppDrawer extends StatelessWidget { class AppDrawer extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget setupGitButton = new Container(); Widget setupGitButton = Container();
var appState = StateContainer.of(context).appState; var appState = StateContainer.of(context).appState;
if (!appState.remoteGitRepoConfigured) { if (!appState.remoteGitRepoConfigured) {
setupGitButton = ListTile( setupGitButton = ListTile(
title: new Text('Setup Git Host'), title: Text('Setup Git Host'),
trailing: new Icon( trailing: Icon(
Icons.priority_high, Icons.priority_high,
color: Colors.red, color: Colors.red,
), ),
@ -21,13 +21,13 @@ class AppDrawer extends StatelessWidget {
); );
} }
return new Drawer( return Drawer(
child: new ListView( child: ListView(
// Important: Remove any padding from the ListView. // Important: Remove any padding from the ListView.
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
children: <Widget>[ children: <Widget>[
new DrawerHeader( DrawerHeader(
decoration: new BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).buttonColor, color: Theme.of(context).buttonColor,
), ),
child: Padding( child: Padding(
@ -42,16 +42,16 @@ class AppDrawer extends StatelessWidget {
), ),
), ),
setupGitButton, setupGitButton,
new ListTile( ListTile(
title: new Text('Share App'), title: Text('Share App'),
onTap: () { onTap: () {
Navigator.pop(context); Navigator.pop(context);
// Update the state of the app // Update the state of the app
// ... // ...
}, },
), ),
new ListTile( ListTile(
title: new Text('Settings'), title: Text('Settings'),
onTap: () { onTap: () {
Navigator.pop(context); Navigator.pop(context);
Navigator.pushNamed(context, "/settings"); Navigator.pushNamed(context, "/settings");

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:journal/note.dart'; import 'package:journal/note.dart';
import 'package:journal/state_container.dart'; import 'package:journal/state_container.dart';
@ -20,24 +19,24 @@ class JournalList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new ListView.builder( return ListView.builder(
itemBuilder: (context, i) { itemBuilder: (context, i) {
if (i >= notes.length) { if (i >= notes.length) {
return null; return null;
} }
var note = notes[i]; var note = notes[i];
return new Dismissible( return Dismissible(
key: new Key(note.fileName), key: Key(note.fileName),
child: _buildRow(context, note, i), child: _buildRow(context, note, i),
background: new Container(color: Theme.of(context).accentColor), background: Container(color: Theme.of(context).accentColor),
onDismissed: (direction) { onDismissed: (direction) {
final stateContainer = StateContainer.of(context); final stateContainer = StateContainer.of(context);
stateContainer.removeNote(note); stateContainer.removeNote(note);
Scaffold.of(context).showSnackBar(new SnackBar( Scaffold.of(context).showSnackBar(SnackBar(
content: new Text("Note deleted"), content: Text("Note deleted"),
action: new SnackBarAction( action: SnackBarAction(
label: 'Undo', label: 'Undo',
onPressed: () => stateContainer.insertNote(i, note), onPressed: () => stateContainer.insertNote(i, note),
), ),
@ -49,22 +48,22 @@ class JournalList extends StatelessWidget {
} }
Widget _buildRow(BuildContext context, Note journal, int noteIndex) { Widget _buildRow(BuildContext context, Note journal, int noteIndex) {
var formatter = new DateFormat('dd MMM, yyyy'); var formatter = DateFormat('dd MMM, yyyy');
var title = formatter.format(journal.created); var title = formatter.format(journal.created);
var timeFormatter = new DateFormat('Hm'); var timeFormatter = DateFormat('Hm');
var time = timeFormatter.format(journal.created); var time = timeFormatter.format(journal.created);
var body = journal.body; var body = journal.body;
body = body.replaceAll("\n", " "); body = body.replaceAll("\n", " ");
return new ListTile( return ListTile(
isThreeLine: true, isThreeLine: true,
title: new Text( title: Text(
title, title,
style: _biggerFont, style: _biggerFont,
), ),
subtitle: new Text( subtitle: Text(
time + "\n" + body, time + "\n" + body,
maxLines: 3, maxLines: 3,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:journal/note.dart'; import 'package:journal/note.dart';
class NoteHeader extends StatelessWidget { class NoteHeader extends StatelessWidget {
@ -13,22 +12,22 @@ class NoteHeader extends StatelessWidget {
var dateStr = DateFormat('MMMM, yyyy').format(note.created); var dateStr = DateFormat('MMMM, yyyy').format(note.created);
var timeStr = DateFormat('EEEE HH:mm').format(note.created); var timeStr = DateFormat('EEEE HH:mm').format(note.created);
var bigNum = new Text( var bigNum = Text(
note.created.day.toString(), note.created.day.toString(),
style: TextStyle(fontSize: 40.0), style: TextStyle(fontSize: 40.0),
); );
var dateText = new Text( var dateText = Text(
dateStr, dateStr,
style: TextStyle(fontSize: 18.0), style: TextStyle(fontSize: 18.0),
); );
var timeText = new Text( var timeText = Text(
timeStr, timeStr,
style: TextStyle(fontSize: 18.0), style: TextStyle(fontSize: 18.0),
); );
var w = new Row( var w = Row(
children: <Widget>[ children: <Widget>[
bigNum, bigNum,
SizedBox(width: 8.0), SizedBox(width: 8.0),
@ -43,8 +42,8 @@ class NoteHeader extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
); );
return new Padding( return Padding(
padding: new EdgeInsets.only(top: 8.0, bottom: 18.0), padding: EdgeInsets.only(top: 8.0, bottom: 18.0),
child: w, child: w,
); );
} }

View File

@ -1,7 +1,7 @@
import 'package:test/test.dart';
import 'package:journal/datetime_utils.dart'; import 'package:journal/datetime_utils.dart';
import 'package:test/test.dart';
main() { void main() {
group('DateTime Utils', () { group('DateTime Utils', () {
test('Test random date', () { test('Test random date', () {
var dateTime = DateTime.utc(2011, 12, 23, 10, 15, 30); var dateTime = DateTime.utc(2011, 12, 23, 10, 15, 30);

View File

@ -1,18 +1,17 @@
import 'dart:io'; import 'dart:io';
import 'package:test/test.dart';
import 'package:path/path.dart' as p;
import 'package:journal/note.dart'; import 'package:journal/note.dart';
import 'package:journal/storage/file_storage.dart'; import 'package:journal/storage/file_storage.dart';
import 'package:journal/storage/serializers.dart'; import 'package:journal/storage/serializers.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
DateTime nowWithoutMicro() { DateTime nowWithoutMicro() {
var dt = DateTime.now(); var dt = DateTime.now();
return DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second); return DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
} }
main() { void main() {
group('FileStorage', () { group('FileStorage', () {
var notes = [ var notes = [
Note(fileName: "1.md", body: "test", created: nowWithoutMicro()), Note(fileName: "1.md", body: "test", created: nowWithoutMicro()),
@ -26,7 +25,7 @@ main() {
tempDir = await Directory.systemTemp.createTemp('__storage_test__'); tempDir = await Directory.systemTemp.createTemp('__storage_test__');
storage = FileStorage( storage = FileStorage(
baseDirectory: tempDir.path, baseDirectory: tempDir.path,
noteSerializer: new JsonNoteSerializer(), noteSerializer: JsonNoteSerializer(),
); );
}); });

View File

@ -1,6 +1,5 @@
import 'package:journal/note.dart'; import 'package:journal/note.dart';
import 'package:journal/storage/serializers.dart'; import 'package:journal/storage/serializers.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
DateTime nowWithoutMicro() { DateTime nowWithoutMicro() {
@ -8,13 +7,13 @@ DateTime nowWithoutMicro() {
return DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second); return DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
} }
main() { void main() {
group('Serializers', () { group('Serializers', () {
var note = Note( var note = Note(
fileName: "2", body: "This is the body", created: nowWithoutMicro()); fileName: "2", body: "This is the body", created: nowWithoutMicro());
test('JSON Serializer', () { test('JSON Serializer', () {
var serializer = new JsonNoteSerializer(); var serializer = JsonNoteSerializer();
var str = serializer.encode(note); var str = serializer.encode(note);
var note2 = serializer.decode(str); var note2 = serializer.decode(str);
@ -22,7 +21,7 @@ main() {
}); });
test('Markdown Serializer', () { test('Markdown Serializer', () {
var serializer = new MarkdownYAMLSerializer(); var serializer = MarkdownYAMLSerializer();
var str = serializer.encode(note); var str = serializer.encode(note);
var note2 = serializer.decode(str); var note2 = serializer.decode(str);
@ -42,7 +41,7 @@ foo: bar
Alright."""; Alright.""";
var serializer = new MarkdownYAMLSerializer(); var serializer = MarkdownYAMLSerializer();
var note = serializer.decode(str); var note = serializer.decode(str);
var actualStr = serializer.encode(note); var actualStr = serializer.encode(note);