Initial commit
parent
e1da53cbf0
commit
e74aff4b2e
|
@ -1,2 +1,5 @@
|
||||||
# dart_mock
|
# Beispiel Programmieren gegen Interfaces
|
||||||
|
|
||||||
|
* `dart run` - Startet Programm mit Sqlite-Backend
|
||||||
|
* `dart test` - Testet mit Map-Backend
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# This file configures the analyzer, which statically analyzes Dart code to
|
||||||
|
# check for errors, warnings, and lints.
|
||||||
|
#
|
||||||
|
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||||
|
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||||
|
# invoked from the command line by running `flutter analyze`.
|
||||||
|
|
||||||
|
# The following line activates a set of recommended lints for Flutter apps,
|
||||||
|
# packages, and plugins designed to encourage good coding practices.
|
||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
linter:
|
||||||
|
# The lint rules applied to this project can be customized in the
|
||||||
|
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||||
|
# included above or to enable additional rules. A list of all available lints
|
||||||
|
# and their documentation is published at
|
||||||
|
# https://dart-lang.github.io/linter/lints/index.html.
|
||||||
|
#
|
||||||
|
# Instead of disabling a lint rule for the entire project in the
|
||||||
|
# section below, it can also be suppressed for a single line of code
|
||||||
|
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||||
|
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||||
|
# producing the lint.
|
||||||
|
rules:
|
||||||
|
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||||
|
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||||
|
|
||||||
|
# Additional information about this file can be found at
|
||||||
|
# https://dart.dev/guides/language/analysis-options
|
|
@ -0,0 +1,43 @@
|
||||||
|
import 'package:mock/person.dart';
|
||||||
|
import 'package:mock/business.dart';
|
||||||
|
import 'package:mock/person_data_access_map.dart';
|
||||||
|
import 'package:mock/person_data_access_sqlite.dart';
|
||||||
|
|
||||||
|
/*
|
||||||
|
@startuml
|
||||||
|
class Business {
|
||||||
|
- PersonDataAccessMap backend
|
||||||
|
}
|
||||||
|
PersonDataAccessMap <-left- Business : uses
|
||||||
|
|
||||||
|
class PersonDataAccessMap {
|
||||||
|
- Map<int, Person> map
|
||||||
|
+ store(Person p): void
|
||||||
|
+ retrieve(int id): Person
|
||||||
|
+ retrieveAll(): List<Person>
|
||||||
|
}
|
||||||
|
|
||||||
|
class PersonDataAccessSqlite implements PersonDataAccessMap {
|
||||||
|
- Sqlite db
|
||||||
|
+ store(Person p): void
|
||||||
|
+ retrieve(int id): Person
|
||||||
|
+ retrieveAll(): List<Person>
|
||||||
|
}
|
||||||
|
@enduml
|
||||||
|
*/
|
||||||
|
void main() {
|
||||||
|
PersonDataAccessMap backend = PersonDataAccessSqlite("sqlite3.db");
|
||||||
|
Business b = Business(backend);
|
||||||
|
|
||||||
|
List<Person> persons = b.getAllPersons();
|
||||||
|
int personCount = persons.length;
|
||||||
|
|
||||||
|
print("We know $personCount persons");
|
||||||
|
|
||||||
|
int nextPersonId = ++personCount;
|
||||||
|
b.addPerson(Person(nextPersonId, "A New Person"));
|
||||||
|
|
||||||
|
print("Now we know ${b.getAllPersons().length} persons");
|
||||||
|
|
||||||
|
backend.close();
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import 'person.dart';
|
||||||
|
import 'person_data_access_map.dart';
|
||||||
|
|
||||||
|
class Business {
|
||||||
|
final PersonDataAccessMap _backend;
|
||||||
|
|
||||||
|
Business(this._backend);
|
||||||
|
|
||||||
|
void addPerson(Person p) => _backend.store(p);
|
||||||
|
|
||||||
|
bool existsPersonId(int id) => _backend.retrieve(id) != null;
|
||||||
|
|
||||||
|
List<Person> getAllPersons() => _backend.retrieveAll();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
class Person {
|
||||||
|
final int id;
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
const Person(this.id, this.name);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => "Person: $name ($id)";
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import 'person.dart';
|
||||||
|
|
||||||
|
class PersonDataAccessMap {
|
||||||
|
final Map<int, Person> _persons = {};
|
||||||
|
|
||||||
|
void store(Person p) => _persons[p.id] = p;
|
||||||
|
|
||||||
|
Person? retrieve(int personId) => _persons[personId];
|
||||||
|
|
||||||
|
List<Person> retrieveAll() => _persons.values.toList();
|
||||||
|
|
||||||
|
void close() {}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import 'person.dart';
|
||||||
|
import 'package:sqlite3/sqlite3.dart';
|
||||||
|
|
||||||
|
import 'person_data_access_map.dart';
|
||||||
|
|
||||||
|
class PersonDataAccessSqlite implements PersonDataAccessMap {
|
||||||
|
final String fileName;
|
||||||
|
final Database db;
|
||||||
|
|
||||||
|
PersonDataAccessSqlite(this.fileName) : db = sqlite3.open(fileName) {
|
||||||
|
try {
|
||||||
|
// when select fails due to missing table ...
|
||||||
|
db.execute('SELECT count(*) from persons');
|
||||||
|
} catch (e) {
|
||||||
|
// ... create it
|
||||||
|
db.execute('''CREATE TABLE persons (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL);''');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void store(Person p) {
|
||||||
|
final stmt = db.prepare('INSERT INTO persons (id, name) VALUES (?, ?)');
|
||||||
|
stmt.execute([p.id, p.name]);
|
||||||
|
stmt.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Person? retrieve(int id) {
|
||||||
|
final ResultSet resultSet =
|
||||||
|
db.select('SELECT * FROM persons WHERE id = ?', [id]);
|
||||||
|
return resultSet.isEmpty
|
||||||
|
? null
|
||||||
|
: Person(resultSet.first['id'], resultSet.first['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Person> retrieveAll() {
|
||||||
|
final ResultSet resultSet = db.select('SELECT * FROM persons');
|
||||||
|
return resultSet.map((row) => Person(row['id'], row['name'])).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void close() {
|
||||||
|
db.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||||
|
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,21 @@
|
||||||
|
@startuml
|
||||||
|
class Business {
|
||||||
|
- PersonDataAccess backend
|
||||||
|
}
|
||||||
|
PersonDataAccess <-left- Business : uses
|
||||||
|
|
||||||
|
interface PersonDataAccess {
|
||||||
|
+ store(Person p): void
|
||||||
|
+ retrieve(int id): Person
|
||||||
|
+ retrieveAll(): List<Person>
|
||||||
|
}
|
||||||
|
|
||||||
|
class PersonDataAccessMap implements PersonDataAccess {
|
||||||
|
- Map<int, Person> map
|
||||||
|
}
|
||||||
|
|
||||||
|
class PersonDataAccessSqlite implements PersonDataAccess {
|
||||||
|
- Sqlite db
|
||||||
|
}
|
||||||
|
|
||||||
|
@enduml
|
|
@ -0,0 +1,13 @@
|
||||||
|
name: mock
|
||||||
|
description: A simple Mock example
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.18.0 <3.0.0'
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
lints: ^2.0.0
|
||||||
|
test:
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
sqlite3: ^1.2.0
|
|
@ -0,0 +1,39 @@
|
||||||
|
import 'package:mock/person_data_access_map.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:mock/person.dart';
|
||||||
|
import 'package:mock/business.dart';
|
||||||
|
|
||||||
|
class TestPersonBackend extends PersonDataAccessMap {
|
||||||
|
TestPersonBackend() {
|
||||||
|
store(Person(1, "Mr. X"));
|
||||||
|
store(Person(2, "Ms. Y"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('Backend', () {
|
||||||
|
PersonDataAccessMap? backend;
|
||||||
|
|
||||||
|
tearDownAll(() {
|
||||||
|
backend?.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Empty', () {
|
||||||
|
final PersonDataAccessMap backend = PersonDataAccessMap();
|
||||||
|
final Business business = Business(backend);
|
||||||
|
|
||||||
|
test('Initial size', () {
|
||||||
|
expect(business.getAllPersons().length, 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Filled', () {
|
||||||
|
final PersonDataAccessMap backend = TestPersonBackend();
|
||||||
|
final Business business = Business(backend);
|
||||||
|
|
||||||
|
test('Initial size', () {
|
||||||
|
expect(business.getAllPersons().length, 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:mock/person.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('Person properties', () {
|
||||||
|
final Person p1 = Person(1, "Dummy User");
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
// runs before each test;
|
||||||
|
print("Set up");
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() {
|
||||||
|
// runs after each test;
|
||||||
|
print("Tear down");
|
||||||
|
});
|
||||||
|
test('id', () {
|
||||||
|
expect(p1.id, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('name', () {
|
||||||
|
expect(p1.id, 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Comparing persons', () {
|
||||||
|
final Person p1 = Person(1, "One person");
|
||||||
|
final Person p2 = Person(2, "Another person");
|
||||||
|
test('Same object', () {
|
||||||
|
expect(p1 == p1, true);
|
||||||
|
});
|
||||||
|
test('Different objects', () {
|
||||||
|
expect(p1 != p2, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue