mirror of
https://github.com/chenasraf/dart_todo.git
synced 2026-05-17 17:58:10 +00:00
first commit
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Files and directories created by pub
|
||||
.dart_tool/
|
||||
.packages
|
||||
|
||||
# Conventional directory for build outputs
|
||||
build/
|
||||
|
||||
# Directory created by dartdoc
|
||||
doc/api/
|
||||
17
.vscode/launch.json
vendored
Normal file
17
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "dart_todo",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/bin/todo.dart",
|
||||
"args": [
|
||||
"${workspaceFolder}/example.todo"
|
||||
],
|
||||
"type": "dart"
|
||||
}
|
||||
]
|
||||
}
|
||||
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.0.0
|
||||
|
||||
- Initial version, created by Stagehand
|
||||
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
A sample command-line application with an entrypoint in `bin/`, library code
|
||||
in `lib/`, and example unit test in `test/`.
|
||||
|
||||
Created from templates made available by Stagehand under a BSD-style
|
||||
[license](https://github.com/dart-lang/stagehand/blob/master/LICENSE).
|
||||
14
analysis_options.yaml
Normal file
14
analysis_options.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
# Defines a default set of lint rules enforced for
|
||||
# projects at Google. For details and rationale,
|
||||
# see https://github.com/dart-lang/pedantic#enabled-lints.
|
||||
include: package:pedantic/analysis_options.yaml
|
||||
|
||||
# For lint rules and documentation, see http://dart-lang.github.io/linter/lints.
|
||||
# Uncomment to specify additional rules.
|
||||
# linter:
|
||||
# rules:
|
||||
# - camel_case_types
|
||||
|
||||
analyzer:
|
||||
# exclude:
|
||||
# - path/to/excluded/files/**
|
||||
10
bin/todo.dart
Normal file
10
bin/todo.dart
Normal file
@@ -0,0 +1,10 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dart_todo/gui.dart';
|
||||
import 'package:dart_todo/todo.dart';
|
||||
|
||||
void main(List<String> arguments) async {
|
||||
final project = Project(File(arguments.elementAt(0)));
|
||||
await project.loadTodos();
|
||||
GUI(project: project);
|
||||
}
|
||||
6
example.todo
Normal file
6
example.todo
Normal file
@@ -0,0 +1,6 @@
|
||||
- [ ] Come up with plan
|
||||
- [ ] Destroy the world
|
||||
- [ ] Create solution
|
||||
- [ ] Charge lots of $$$ for solution
|
||||
- [ ] test
|
||||
- [ ] another test
|
||||
1
lib/file_handler.dart
Normal file
1
lib/file_handler.dart
Normal file
@@ -0,0 +1 @@
|
||||
part of 'todo.dart';
|
||||
155
lib/gui.dart
Normal file
155
lib/gui.dart
Normal file
@@ -0,0 +1,155 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dart_console/dart_console.dart';
|
||||
import 'package:dart_todo/todo.dart';
|
||||
|
||||
class GUI {
|
||||
final Project project;
|
||||
final Console console;
|
||||
|
||||
bool frozen = false;
|
||||
int activeIndex = 0;
|
||||
|
||||
GUI({this.project}) : console = Console() {
|
||||
stdin.echoMode = false;
|
||||
stdin.lineMode = false;
|
||||
stdin.listen(_stdinListener);
|
||||
_paint();
|
||||
}
|
||||
|
||||
int get lines => stdout.terminalLines;
|
||||
int get width => stdout.terminalColumns;
|
||||
int get maxLines => project.todos.length;
|
||||
String get verticalBorder => '-' * (width - 3);
|
||||
|
||||
Todo get currentTodo => project.todos.elementAt(activeIndex);
|
||||
|
||||
void _paint() {
|
||||
if (frozen) {
|
||||
return;
|
||||
}
|
||||
console.clearScreen();
|
||||
_print(verticalBorder);
|
||||
_print('');
|
||||
|
||||
for (var i = 0; i < project.todos.length; i++) {
|
||||
final todo = project.todos.elementAt(i);
|
||||
final selected = i == activeIndex;
|
||||
final indent = 4;
|
||||
final line = [
|
||||
' ' * (selected ? indent - 1 : indent),
|
||||
selected ? '> ' : ' ',
|
||||
(todo.done ? '√' : '×').padRight(3),
|
||||
todo.title,
|
||||
].where((s) => s.isNotEmpty).join(' ');
|
||||
_print(line);
|
||||
}
|
||||
final spareLines = lines - project.todos.length - 6;
|
||||
if (spareLines > 0) {
|
||||
for (var i = 0; i < spareLines; i++) {
|
||||
_print('');
|
||||
}
|
||||
}
|
||||
_print((' ' * 10) + '[enter/space] - toggle | [esc/q] - quit');
|
||||
_print(verticalBorder);
|
||||
}
|
||||
|
||||
String _ensureLength(String message) =>
|
||||
'|' + message.padRight(width - '||\n'.length, ' ') + '|\n';
|
||||
void _print(String message) => console.write(_ensureLength(message));
|
||||
|
||||
void _stdinListener(List<int> charCodes) {
|
||||
if (!frozen) {
|
||||
_handleGUIInput(keyMap[charCodes.last]);
|
||||
} else {
|
||||
final title = String.fromCharCodes(charCodes);
|
||||
project.addTodo(Todo(title: title));
|
||||
_exitTextInputMode();
|
||||
}
|
||||
_paint();
|
||||
}
|
||||
|
||||
void _handleGUIInput(Key key) {
|
||||
switch (key) {
|
||||
case Key.down:
|
||||
activeIndex++;
|
||||
if (activeIndex >= maxLines) {
|
||||
activeIndex = 0;
|
||||
}
|
||||
break;
|
||||
case Key.up:
|
||||
activeIndex--;
|
||||
if (activeIndex < 0) {
|
||||
activeIndex = maxLines - 1;
|
||||
}
|
||||
break;
|
||||
case Key.enter:
|
||||
case Key.space:
|
||||
currentTodo.toggle();
|
||||
break;
|
||||
case Key.c:
|
||||
case Key.a:
|
||||
_enterTextInputMode();
|
||||
console.write('Enter title: ');
|
||||
break;
|
||||
case Key.e:
|
||||
//TODO: edit current todo
|
||||
break;
|
||||
case Key.d:
|
||||
case Key.backspace:
|
||||
project.removeTodo(currentTodo);
|
||||
break;
|
||||
case Key.q:
|
||||
case Key.esc:
|
||||
exit(0);
|
||||
break;
|
||||
case Key.left:
|
||||
case Key.right:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _enterTextInputMode() {
|
||||
frozen = true;
|
||||
stdin.echoMode = true;
|
||||
stdin.lineMode = true;
|
||||
}
|
||||
|
||||
void _exitTextInputMode() {
|
||||
frozen = false;
|
||||
stdin.echoMode = false;
|
||||
stdin.lineMode = false;
|
||||
}
|
||||
|
||||
final keyMap = <int, Key>{
|
||||
32: Key.space,
|
||||
65: Key.up,
|
||||
66: Key.down,
|
||||
67: Key.right,
|
||||
68: Key.left,
|
||||
10: Key.enter,
|
||||
27: Key.esc,
|
||||
113: Key.q,
|
||||
123: Key.backspace,
|
||||
97: Key.a,
|
||||
99: Key.c,
|
||||
100: Key.d,
|
||||
101: Key.e,
|
||||
};
|
||||
}
|
||||
|
||||
enum Key {
|
||||
up,
|
||||
right,
|
||||
down,
|
||||
left,
|
||||
enter,
|
||||
esc,
|
||||
space,
|
||||
backspace,
|
||||
q,
|
||||
a,
|
||||
c,
|
||||
d,
|
||||
e,
|
||||
}
|
||||
128
lib/todo.dart
Normal file
128
lib/todo.dart
Normal file
@@ -0,0 +1,128 @@
|
||||
import 'dart:io';
|
||||
part 'file_handler.dart';
|
||||
|
||||
class Todo {
|
||||
String _title;
|
||||
bool _done;
|
||||
final void Function() onUpdate;
|
||||
|
||||
Todo({
|
||||
String title,
|
||||
bool done,
|
||||
this.onUpdate,
|
||||
}) : _title = title,
|
||||
_done = done ?? false;
|
||||
|
||||
Todo.parseLine(String line, {this.onUpdate}) {
|
||||
final genericException = FormatException('Todo is malformed', line, 0);
|
||||
final checkedException = FormatException(
|
||||
'Todo does not contain "checked" token (v/x)',
|
||||
line,
|
||||
line.indexOf(RegExp(r'\[')) + 1);
|
||||
final pattern = RegExp(r'^- \[[ x]\]');
|
||||
try {
|
||||
final match = pattern.matchAsPrefix(line);
|
||||
|
||||
if (match == null) {
|
||||
throw genericException;
|
||||
}
|
||||
|
||||
final split = [
|
||||
line.substring(0, match.end),
|
||||
line.substring(match.end + 1),
|
||||
];
|
||||
|
||||
if (split.any((i) => i?.isNotEmpty != true)) {
|
||||
throw genericException;
|
||||
}
|
||||
|
||||
switch (split[0].replaceAll(' ', '')) {
|
||||
case '-[]':
|
||||
_done = false;
|
||||
break;
|
||||
case '-[x]':
|
||||
_done = true;
|
||||
break;
|
||||
default:
|
||||
throw checkedException;
|
||||
}
|
||||
|
||||
_title = split[1];
|
||||
} on RangeError catch (_) {
|
||||
throw genericException;
|
||||
}
|
||||
}
|
||||
|
||||
String get title => _title;
|
||||
set title(String value) => _update(_title = value);
|
||||
|
||||
bool get done => _done;
|
||||
set done(bool value) => _update(_done = value);
|
||||
|
||||
void _update([dynamic _expr]) {
|
||||
if (_expr is void Function()) {
|
||||
_expr.call();
|
||||
}
|
||||
onUpdate?.call();
|
||||
}
|
||||
|
||||
void toggle() {
|
||||
done = !done;
|
||||
}
|
||||
|
||||
Todo copyWith({
|
||||
String title,
|
||||
bool done,
|
||||
final void Function() onUpdate,
|
||||
}) =>
|
||||
Todo(
|
||||
title: title ?? this.title,
|
||||
done: done ?? this.done ?? false,
|
||||
onUpdate: onUpdate ?? this.onUpdate,
|
||||
);
|
||||
|
||||
String toMarkdown() => '- [${done ? "x" : " "}] $title';
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType($title, done: $done)';
|
||||
}
|
||||
|
||||
class Project {
|
||||
List<Todo> todos = [];
|
||||
File file;
|
||||
|
||||
Project(this.file);
|
||||
|
||||
void _dumpToFile() {
|
||||
file.writeAsString(toMarkdown());
|
||||
}
|
||||
|
||||
void create(String name) {
|
||||
_checkAndCreateFile(File('$name.todo'));
|
||||
}
|
||||
|
||||
void loadTodos() async {
|
||||
final content = await file.readAsLinesSync();
|
||||
for (final line in content) {
|
||||
todos.add(Todo.parseLine(line, onUpdate: _dumpToFile));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _checkAndCreateFile(File file) async {
|
||||
if (await file.exists() == false) {
|
||||
await file.create();
|
||||
}
|
||||
}
|
||||
|
||||
String toMarkdown() => todos.map((t) => t.toMarkdown()).join('\r\n');
|
||||
|
||||
void addTodo(Todo todo) {
|
||||
todos.add(todo.copyWith(onUpdate: _dumpToFile));
|
||||
_dumpToFile();
|
||||
}
|
||||
|
||||
void removeTodo(Todo todo) {
|
||||
todos.removeWhere((t) => t.title == todo.title);
|
||||
_dumpToFile();
|
||||
}
|
||||
}
|
||||
383
pubspec.lock
Normal file
383
pubspec.lock
Normal file
@@ -0,0 +1,383 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "14.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.41.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.14.13"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.14.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
dart_console:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dart_console
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.2"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.2.1"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
intl:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: intl
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.16.1"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.2"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.9"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.4"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.12"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
path:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
pedantic:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.9+1"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.9"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.6"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.7"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.18+1"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.11+4"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7+15"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.4"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.4"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
sdks:
|
||||
dart: ">=2.10.0 <3.0.0"
|
||||
14
pubspec.yaml
Normal file
14
pubspec.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
name: dart_todo
|
||||
description: A fully fledged, simple to use to do terminal app
|
||||
version: 1.0.0
|
||||
# homepage: https://www.example.com
|
||||
environment:
|
||||
sdk: ">=2.10.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
dart_console: ^0.6.2
|
||||
path: ^1.7.0
|
||||
|
||||
dev_dependencies:
|
||||
pedantic: ^1.9.0
|
||||
test: ^1.14.4
|
||||
27
test/dart_todo_test.dart
Normal file
27
test/dart_todo_test.dart
Normal file
@@ -0,0 +1,27 @@
|
||||
import 'package:dart_todo/todo.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('create todo done', () {
|
||||
final correctDone = '- [x] I did this';
|
||||
final todoDone = Todo.parseLine(correctDone);
|
||||
|
||||
expect(todoDone.done, equals(true));
|
||||
expect(todoDone.title, equals('I did this'));
|
||||
});
|
||||
test('create todo not done', () {
|
||||
final correctNotDone = '- [ ] I did not do this';
|
||||
final todoNotDone = Todo.parseLine(correctNotDone);
|
||||
|
||||
expect(todoNotDone.done, equals(false));
|
||||
expect(todoNotDone.title, equals('I did not do this'));
|
||||
});
|
||||
test('create todo with bad format - throws', () {
|
||||
final incorrect1 = "I don't know if I did this";
|
||||
final incorrect2 = '- [ ]';
|
||||
final incorrect3 = "[] I don't know if I did this";
|
||||
expect(() => Todo.parseLine(incorrect1), throwsFormatException);
|
||||
expect(() => Todo.parseLine(incorrect2), throwsFormatException);
|
||||
expect(() => Todo.parseLine(incorrect3), throwsFormatException);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user